Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ppl-fasilkom-ui
PPL Sosial
bisago
bisago-fe
Commits
be04391b
Commit
be04391b
authored
May 17, 2021
by
Yoga Pratama
Browse files
[GREEN] Implement add kegiatan page
parent
b9648864
Pipeline
#77382
passed with stages
in 13 minutes and 15 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
lib/bloc/kegiatan_bloc.dart
View file @
be04391b
...
...
@@ -4,6 +4,7 @@ import 'package:bisaGo/model/kegiatan.dart';
import
'package:bisaGo/network/data/network_model.dart'
;
import
'package:bisaGo/repository/kegiatan_repository.dart'
;
import
'package:get_it/get_it.dart'
;
import
'package:http/http.dart'
;
import
'package:rxdart/rxdart.dart'
;
class
KegiatanBloc
{
...
...
@@ -12,9 +13,9 @@ class KegiatanBloc {
List
<
KegiatanModel
>
allKegiatanFromApi
;
StreamSink
<
NetworkModel
<
KegiatanList
>>
get
kegiatanListSink
=
>
_kegiatanListController
.
sink
;
_kegiatanListController
.
sink
;
Stream
<
NetworkModel
<
KegiatanList
>>
get
kegiatanListStream
=
>
_kegiatanListController
.
stream
;
_kegiatanListController
.
stream
;
KegiatanBloc
(
String
placeId
)
{
_kegiatanListController
=
BehaviorSubject
<
NetworkModel
<
KegiatanList
>>();
...
...
@@ -25,8 +26,8 @@ class KegiatanBloc {
Future
<
void
>
fetchKegiatanList
(
String
placeId
)
async
{
kegiatanListSink
.
add
(
NetworkModel
.
loading
(
'Getting Kegiatan'
));
try
{
final
kegiatanListResponse
=
await
_kegiatanRepository
.
fetchKegiatan
(
placeId
);
final
kegiatanListResponse
=
await
_kegiatanRepository
.
fetchKegiatan
(
placeId
);
allKegiatanFromApi
=
List
.
from
(
kegiatanListResponse
.
allKegiatan
);
kegiatanListSink
.
add
(
NetworkModel
.
completed
(
kegiatanListResponse
));
}
catch
(
e
)
{
...
...
@@ -34,12 +35,21 @@ class KegiatanBloc {
}
}
Future
<
dynamic
>
addNewKegiatan
(
Map
<
String
,
dynamic
>
newKegiatanData
,
String
placeId
)
async
{
try
{
return
await
_kegiatanRepository
.
createKegiatan
(
newKegiatanData
,
placeId
);
}
catch
(
e
)
{
return
Response
(
'Failed to register komentar'
,
400
);
}
}
void
resetKegiatanList
()
{
kegiatanListSink
.
add
(
NetworkModel
.
completed
(
KegiatanList
(
allKegiatanFromApi
)));
.
add
(
NetworkModel
.
completed
(
KegiatanList
(
allKegiatanFromApi
)));
}
void
dispose
()
{
_kegiatanListController
?.
close
();
}
}
\ No newline at end of file
}
lib/page/filter_fasilitas/add_kegiatan.dart
0 → 100644
View file @
be04391b
import
'dart:async'
;
import
'dart:io'
;
import
'package:bisaGo/bloc/kegiatan_bloc.dart'
;
import
'package:bisaGo/component/bisago_appbar.dart'
;
import
'package:bisaGo/component/image_preview_holder.dart'
;
import
'package:bisaGo/config/styles.dart'
;
import
'package:bisaGo/model/kegiatan.dart'
;
import
'package:bisaGo/utils/custom_button.dart'
;
import
'package:bisaGo/utils/custom_text_field.dart'
;
import
'package:bisaGo/utils/validator.dart'
;
import
'package:dio/dio.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_datetime_picker/flutter_datetime_picker.dart'
;
import
'package:font_awesome_flutter/font_awesome_flutter.dart'
;
import
'package:image_picker/image_picker.dart'
;
import
'package:intl/intl.dart'
;
import
'package:material_design_icons_flutter/material_design_icons_flutter.dart'
;
class
AddKegiatan
extends
StatefulWidget
{
AddKegiatan
({
Key
key
,
@required
this
.
nama
,
@required
this
.
placeId
,
})
:
super
(
key:
key
);
final
String
nama
;
final
String
placeId
;
@override
_AddKegiatanState
createState
()
=
>
_AddKegiatanState
();
}
class
_AddKegiatanState
extends
State
<
AddKegiatan
>
{
final
GlobalKey
<
FormState
>
_formKey
=
GlobalKey
<
FormState
>();
TextEditingController
nameController
=
TextEditingController
();
TextEditingController
phoneController
=
TextEditingController
();
TextEditingController
penyelenggaraController
=
TextEditingController
();
TextEditingController
narahubungController
=
TextEditingController
();
TextEditingController
deskripsiController
=
TextEditingController
();
String
tanggalKegiatan
=
'
${DateFormat('yyyy-MM-dd hh:mm').format(DateTime.now())}
'
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
PreferredSize
(
preferredSize:
const
Size
.
fromHeight
(
55
),
child:
BisaGoAppBar
(
title:
'Tambah Kegiatan'
,
leading:
InkWell
(
onTap:
()
=
>
Navigator
.
pop
(
context
,
'Take me back'
),
child:
const
Icon
(
Icons
.
arrow_back_ios
),
),
),
),
body:
SingleChildScrollView
(
child:
Form
(
key:
_formKey
,
child:
Stack
(
children:
<
Widget
>[
Container
(
key:
const
Key
(
'Body Add Kegiatan Page'
),
alignment:
Alignment
.
topCenter
,
padding:
EdgeInsets
.
only
(
top:
MediaQuery
.
of
(
context
)
.
size
.
height
*
.
04
,
left:
tripleSpace
,
right:
tripleSpace
,
bottom:
tripleSpace
),
child:
ListBody
(
children:
<
Widget
>[
CustomTextField
(
title:
'Nama Kegiatan'
,
required
:
true
,
key:
const
Key
(
'Text Field Nama'
),
validator:
FieldValidator
.
validateName
,
controller:
nameController
,
),
CustomTextField
(
title:
'Penyelenggara'
,
required
:
true
,
key:
const
Key
(
'Text Field Penyelenggara'
),
validator:
FieldValidator
.
validateName
,
controller:
penyelenggaraController
,
),
CustomTextField
(
title:
'Nomor Telepon Narahubung'
,
required
:
true
,
key:
const
Key
(
'Text Field Nomor Telepon Narahubung'
),
validator:
FieldValidator
.
validateName
,
controller:
narahubungController
,
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
<
Widget
>[
const
Text
(
'Tanggal Kegiatan'
,
style:
TextStyle
(
fontSize:
18
),
textAlign:
TextAlign
.
left
,
),
const
SizedBox
(
height:
10.0
),
TextButton
(
key:
const
Key
(
'Button Tanggal Kegiatan'
),
style:
TextButton
.
styleFrom
(
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
10.0
)),
padding:
const
EdgeInsets
.
all
(
13.0
),
backgroundColor:
greenPrimary
,
),
onPressed:
()
{
DatePicker
.
showDateTimePicker
(
context
,
currentTime:
DateTime
.
parse
(
tanggalKegiatan
),
onChanged:
(
date
)
{
setState
(()
{
tanggalKegiatan
=
'
${DateFormat('yyyy-MM-dd hh:mm').format(date)}
'
;
});
},
);
},
child:
Text
(
tanggalKegiatan
,
style:
const
TextStyle
(
fontSize:
15.0
,
color:
Colors
.
white
),
),
),
],
),
SizedBox
(
height:
16
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
const
Text
(
'Foto'
,
style:
TextStyle
(
fontSize:
18
),
textAlign:
TextAlign
.
left
,
),
TextButton
(
key:
const
Key
(
'Button Input Foto Gallery'
),
style:
TextButton
.
styleFrom
(
padding:
EdgeInsets
.
zero
),
onPressed:
()
async
{
final
imageSelected
=
await
_getImage
();
setState
(()
{
_image
=
imageSelected
;
});
},
child:
Container
(
width:
MediaQuery
.
of
(
context
)
.
size
.
width
*
0.35
,
padding:
const
EdgeInsets
.
all
(
9.0
),
alignment:
Alignment
.
centerLeft
,
decoration:
BoxDecoration
(
boxShadow:
regularShadow
,
borderRadius:
BorderRadius
.
circular
(
10.0
),
color:
greenPrimary
),
child:
Row
(
children:
[
const
Icon
(
MdiIcons
.
imagePlus
,
color:
Colors
.
white
,
size:
14.0
,
),
const
SizedBox
(
width:
regularSpace
),
const
Text
(
'Dari Gallery'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
14.0
),
),
],
),
),
),
TextButton
(
key:
const
Key
(
'Button Input Foto Camera'
),
style:
TextButton
.
styleFrom
(
padding:
EdgeInsets
.
zero
),
onPressed:
()
async
{
final
imageSelected
=
await
_getCameraImage
();
setState
(()
{
_image
=
imageSelected
;
});
},
child:
Container
(
width:
MediaQuery
.
of
(
context
)
.
size
.
width
*
0.35
,
padding:
const
EdgeInsets
.
all
(
9.0
),
alignment:
Alignment
.
centerLeft
,
decoration:
BoxDecoration
(
boxShadow:
regularShadow
,
borderRadius:
BorderRadius
.
circular
(
10.0
),
color:
greenPrimary
),
child:
Row
(
children:
[
const
Icon
(
MdiIcons
.
imagePlus
,
color:
Colors
.
white
,
size:
14.0
,
),
const
SizedBox
(
width:
regularSpace
),
const
Text
(
'Dari Kamera'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
14.0
),
),
],
),
),
)
],
),
_showImagePreview
(),
SizedBox
(
height:
16
),
TextFormField
(
key:
const
Key
(
'Text Field Deskripsi'
),
keyboardType:
TextInputType
.
multiline
,
maxLines:
null
,
minLines:
3
,
validator:
FieldValidator
.
validateInfo
,
controller:
deskripsiController
,
style:
const
TextStyle
(
fontSize:
18
,
),
decoration:
InputDecoration
(
hintStyle:
const
TextStyle
(
fontWeight:
FontWeight
.
bold
,
fontSize:
15
),
hintText:
'Tulis deskripsi...'
,
contentPadding:
const
EdgeInsets
.
all
(
8.0
),
enabledBorder:
OutlineInputBorder
(
borderRadius:
BorderRadius
.
circular
(
10
),
borderSide:
BorderSide
(
color:
Theme
.
of
(
context
)
.
primaryColor
,
),
),
border:
OutlineInputBorder
(
borderRadius:
BorderRadius
.
circular
(
10
),
borderSide:
BorderSide
(
color:
Theme
.
of
(
context
)
.
primaryColor
,
),
),
),
),
Container
(
margin:
const
EdgeInsets
.
fromLTRB
(
0
,
tripleSpace
,
0
,
regularSpace
),
alignment:
Alignment
.
center
,
child:
ButtonTheme
(
key:
const
Key
(
'Button Simpan'
),
minWidth:
double
.
infinity
,
height:
40
,
child:
submitButton
(
'Simpan'
,
_validateLoginInput
),
)),
],
),
),
],
),
),
),
);
}
Future
<
void
>
_validateLoginInput
()
async
{
final
form
=
_formKey
.
currentState
;
if
(
_formKey
.
currentState
.
validate
())
{
form
.
save
();
final
fileName
=
_image
.
path
.
split
(
'/'
)
.
last
;
final
_imageFile
=
await
MultipartFile
.
fromFile
(
_image
.
path
,
filename:
fileName
,
);
final
newKegiatan
=
KegiatanModel
(
namaKegiatan:
nameController
.
text
,
deskripsi:
deskripsiController
.
text
,
narahubung:
narahubungController
.
text
,
penyelenggara:
penyelenggaraController
.
text
,
timeStart:
DateTime
.
parse
(
tanggalKegiatan
),
timeEnd:
DateTime
.
parse
(
tanggalKegiatan
)
.
add
(
Duration
(
days:
1
),
),
);
final
newKegiatanData
=
newKegiatan
.
toJson
();
newKegiatanData
[
'images'
]
=
_imageFile
;
final
_bloc
=
KegiatanBloc
(
widget
.
placeId
);
await
_bloc
.
addNewKegiatan
(
newKegiatanData
,
widget
.
placeId
,
);
successDialog
(
context
);
Timer
(
const
Duration
(
seconds:
2
),
()
{
Navigator
.
pop
(
context
);
Navigator
.
pop
(
context
);
});
}
else
{
failedDialog
(
context
,
''
);
}
}
Widget
_showImagePreview
()
{
return
_image
==
null
?
const
SizedBox
(
height:
0
)
:
ImagePreviewHolder
(
image:
Image
.
file
(
_image
),
onPressed:
()
async
{
setState
(()
{
_image
=
null
;
});
},
);
}
void
successDialog
(
BuildContext
context
)
{
const
alertDialog
=
AlertDialog
(
title:
Text
(
'Tambah informasi berhasil'
),
content:
Icon
(
FontAwesomeIcons
.
checkCircle
),
);
showDialog
(
context:
context
,
builder:
(
BuildContext
context
)
{
return
alertDialog
;
});
}
void
failedDialog
(
BuildContext
context
,
String
message
)
{
var
newMessage
=
message
;
if
(
message
==
'default'
)
{
newMessage
=
'Gagal menambahkan informasi'
;
}
final
alertDialog
=
AlertDialog
(
title:
Text
(
newMessage
),
content:
const
Icon
(
FontAwesomeIcons
.
exclamationCircle
,
),
);
showDialog
(
context:
context
,
builder:
(
BuildContext
context
)
{
return
alertDialog
;
});
}
final
picker
=
ImagePicker
();
File
_image
;
Future
_getImage
()
async
{
final
image
=
await
picker
.
getImage
(
source
:
ImageSource
.
gallery
)
;
return
File
(
image
.
path
);
}
Future
_getCameraImage
()
async
{
final
image
=
await
picker
.
getImage
(
source
:
ImageSource
.
camera
,
imageQuality:
50
)
;
return
File
(
image
.
path
);
}
}
lib/page/filter_fasilitas/fasilitas.dart
View file @
be04391b
...
...
@@ -3,6 +3,7 @@ import 'package:bisaGo/bloc/lokasi_response_bloc.dart';
import
'package:bisaGo/component/image_holder.dart'
;
import
'package:bisaGo/model/kegiatan.dart'
;
import
'package:bisaGo/model/lokasi.dart'
;
import
'package:bisaGo/page/filter_fasilitas/add_kegiatan.dart'
;
import
'package:flutter/material.dart'
;
import
'package:bisaGo/bloc/komentar_bloc.dart'
;
import
'package:bisaGo/component/bisago_appbar.dart'
;
...
...
@@ -229,7 +230,7 @@ class _FasilitasState extends State<Fasilitas> {
color:
Colors
.
transparent
))),
),
onPressed:
()
{
checkLoginStatus
();
checkLoginStatus
(
'informasi'
);
},
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
...
...
@@ -353,7 +354,7 @@ class _FasilitasState extends State<Fasilitas> {
color:
Colors
.
transparent
))),
),
onPressed:
()
{
checkLoginStatus
();
checkLoginStatus
(
'kegiatan'
);
},
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
...
...
@@ -467,13 +468,13 @@ class _FasilitasState extends State<Fasilitas> {
super
.
dispose
();
}
void
checkLoginStatus
()
async
{
void
checkLoginStatus
(
String
type
)
async
{
final
sharedPreferences
=
await
SharedPreferences
.
getInstance
();
if
(
sharedPreferences
.
getString
(
'token'
)
==
null
)
{
await
Navigator
.
of
(
context
)
.
pushAndRemoveUntil
(
MaterialPageRoute
(
builder:
(
BuildContext
context
)
=
>
const
Login
()),
(
Route
<
dynamic
>
route
)
=
>
false
);
}
else
{
}
else
if
(
type
==
'informasi'
)
{
await
Navigator
.
of
(
context
)
.
push
(
MaterialPageRoute
(
builder:
(
BuildContext
context
)
=
>
AddInformasi
(
...
...
@@ -482,6 +483,18 @@ class _FasilitasState extends State<Fasilitas> {
)))
.
then
((
value
)
=
>
_komentarBloc
.
fetchKomentarList
(
widget
.
lokasi
.
placeId
));
}
else
{
await
Navigator
.
of
(
context
)
.
push
(
MaterialPageRoute
(
builder:
(
BuildContext
context
)
=
>
AddKegiatan
(
nama:
widget
.
lokasi
.
name
,
placeId:
widget
.
lokasi
.
placeId
,
)))
.
then
(
(
value
)
=
>
_kegiatanBloc
.
fetchKegiatanList
(
widget
.
lokasi
.
placeId
,
),
);
}
}
...
...
lib/repository/kegiatan_repository.dart
View file @
be04391b
...
...
@@ -5,6 +5,8 @@ import 'package:bisaGo/network/network_interface.dart';
abstract
class
BaseKegiatanRepository
{
Future
<
KegiatanList
>
fetchKegiatan
(
String
placeId
);
Future
<
List
<
String
>>
fetchImages
(
String
placeId
,
int
id
);
Future
<
dynamic
>
createKegiatan
(
Map
<
String
,
dynamic
>
newKegiatanData
,
String
placeId
);
}
class
KegiatanRepository
implements
BaseKegiatanRepository
{
...
...
@@ -32,11 +34,25 @@ class KegiatanRepository implements BaseKegiatanRepository {
final
response
=
await
_network
.
get
(
url:
url
,
isLogin:
false
);
var
allImages
=
[];
for
(
var
_index
=
0
;
_index
<
response
.
length
;
_index
++
)
{
var
fotoUrl
=
ApiFlavor
.
getBaseUrl
()
+
response
.
values
.
toList
()[
_index
][
'foto'
];
for
(
var
_index
=
0
;
_index
<
response
.
length
;
_index
++
)
{
var
fotoUrl
=
ApiFlavor
.
getBaseUrl
()
+
response
.
values
.
toList
()[
_index
][
'foto'
];
allImages
.
add
(
fotoUrl
);
}
allImages
=
allImages
.
cast
<
String
>();
return
allImages
;
}
}
\ No newline at end of file
@override
Future
<
dynamic
>
createKegiatan
(
Map
<
String
,
dynamic
>
newKegiatanData
,
String
placeId
,
)
async
{
print
(
newKegiatanData
);
final
response
=
await
_network
.
post
(
url:
'/informasi-fasilitas/lokasi/add-kegiatan/
$placeId
/'
,
bodyParams:
newKegiatanData
,
);
return
response
;
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment