diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index a9c6aed0fdbbc40721ef89d4224fe8c2a6c5afe7..16ae7ecc84f23125b2679c6ff794cc3a052da8c5 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"geolocator","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-5.3.2+2/","dependencies":["location_permissions"]},{"name":"google_maps_flutter","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_maps_flutter-0.5.33/","dependencies":[]},{"name":"google_sign_in","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_sign_in-4.5.6/","dependencies":[]},{"name":"image_picker","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+14/","dependencies":[]},{"name":"location","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location-2.5.4/","dependencies":[]},{"name":"location_permissions","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location_permissions-3.0.0+1/","dependencies":[]},{"name":"path_provider","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.24/","dependencies":[]},{"name":"share","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/share-0.6.5+4/","dependencies":[]},{"name":"shared_preferences","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.6+3/","dependencies":[]},{"name":"sqflite","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.1+2/","dependencies":[]}],"android":[{"name":"flutter_plugin_android_lifecycle","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.11/","dependencies":[]},{"name":"geolocator","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-5.3.2+2/","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_api_availability-2.0.4/","dependencies":[]},{"name":"google_maps_flutter","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_maps_flutter-0.5.33/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"google_sign_in","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_sign_in-4.5.6/","dependencies":[]},{"name":"image_picker","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+14/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location-2.5.4/","dependencies":[]},{"name":"location_permissions","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location_permissions-3.0.0+1/","dependencies":[]},{"name":"path_provider","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.24/","dependencies":[]},{"name":"share","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/share-0.6.5+4/","dependencies":[]},{"name":"shared_preferences","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.6+3/","dependencies":[]},{"name":"sqflite","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.1+2/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+6/","dependencies":[]},{"name":"shared_preferences_macos","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+11/","dependencies":[]},{"name":"sqflite","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.1+2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]}],"web":[{"name":"google_sign_in_web","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_sign_in_web-0.9.2/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"google_maps_flutter","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"google_sign_in","dependencies":["google_sign_in_web"]},{"name":"google_sign_in_web","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"share","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-12-10 16:31:32.096784","version":"1.20.3"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"geolocator","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-5.3.2+2/","dependencies":["location_permissions"]},{"name":"google_maps_flutter","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_maps_flutter-0.5.33/","dependencies":[]},{"name":"google_sign_in","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_sign_in-4.5.6/","dependencies":[]},{"name":"image_picker","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+14/","dependencies":[]},{"name":"location","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location-2.5.4/","dependencies":[]},{"name":"location_permissions","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location_permissions-3.0.0+1/","dependencies":[]},{"name":"path_provider","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.24/","dependencies":[]},{"name":"share","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/share-0.6.5+4/","dependencies":[]},{"name":"shared_preferences","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.6+3/","dependencies":[]},{"name":"sqflite","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.1+2/","dependencies":[]}],"android":[{"name":"flutter_plugin_android_lifecycle","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.11/","dependencies":[]},{"name":"geolocator","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-5.3.2+2/","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_api_availability-2.0.4/","dependencies":[]},{"name":"google_maps_flutter","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_maps_flutter-0.5.33/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"google_sign_in","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_sign_in-4.5.6/","dependencies":[]},{"name":"image_picker","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+14/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location-2.5.4/","dependencies":[]},{"name":"location_permissions","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/location_permissions-3.0.0+1/","dependencies":[]},{"name":"path_provider","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.24/","dependencies":[]},{"name":"share","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/share-0.6.5+4/","dependencies":[]},{"name":"shared_preferences","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.6+3/","dependencies":[]},{"name":"sqflite","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.1+2/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+6/","dependencies":[]},{"name":"shared_preferences_macos","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+11/","dependencies":[]},{"name":"sqflite","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.3.1+2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]}],"web":[{"name":"google_sign_in_web","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/google_sign_in_web-0.9.2/","dependencies":[]},{"name":"shared_preferences_web","path":"/Users/suryanirvana/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"geolocator","dependencies":["google_api_availability","location_permissions"]},{"name":"google_api_availability","dependencies":[]},{"name":"google_maps_flutter","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"google_sign_in","dependencies":["google_sign_in_web"]},{"name":"google_sign_in_web","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","dependencies":[]},{"name":"location_permissions","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"share","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-12-28 22:03:53.783202","version":"1.20.3"} \ No newline at end of file diff --git a/lib/bloc/komentar_bloc.dart b/lib/bloc/komentar_bloc.dart index eb41c953beb30c96363f69db201e74b91e5d1f2d..2546e81b7945e83bddb16d15e4c6845dfe57e0ae 100644 --- a/lib/bloc/komentar_bloc.dart +++ b/lib/bloc/komentar_bloc.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/network/data/network_model.dart'; import 'package:bisaGo/repository/komentar_repository.dart'; +import 'package:get_it/get_it.dart'; import 'package:http/http.dart'; class KomentarBloc { @@ -17,7 +18,7 @@ class KomentarBloc { KomentarBloc(String namaLokasi) { _komentarListController = StreamController<NetworkModel<KomentarList>>(); - _komentarRepository = KomentarRepository(); + _komentarRepository = GetIt.instance.get<BaseKomentarRepository>(); fetchKomentarList(namaLokasi); } @@ -31,6 +32,16 @@ class KomentarBloc { } } + Future<Response> updateKomentar(Map<String, dynamic> newKomentarData, + String namaLokasi, int id, String token) async { + try { + return await _komentarRepository.updateKomentar( + newKomentarData, namaLokasi, id, token); + } catch (e) { + return Response('Failed to update komentar', 400); + } + } + Future<void> fetchKomentarList(String namaLokasi) async { komentarListSink.add(NetworkModel.loading('Getting Komentar')); try { @@ -44,19 +55,19 @@ class KomentarBloc { } } - // void filterKomentarList( - // String tag, bool value, List<KomentarModel> currentList) { - // if (value) { - // for (var komentar in allKomentarFromApi) { - // if (komentar.tag.contains(tag)) { - // currentList.add(komentar); - // } - // } - // } else { - // currentList.removeWhere((komentar) => komentar.tag.contains(tag)); - // } - // komentarListSink.add(NetworkModel.completed(KomentarList(currentList))); - // } + void filterKomentarList(String tag) { + try { + List<KomentarModel> komentarList; + for (final komentar in allKomentarFromApi) { + if (komentar.disabilitas.contains(tag)) { + komentarList.add(komentar); + } + } + komentarListSink.add(NetworkModel.completed(KomentarList(komentarList))); + } catch (e) { + komentarListSink.add(NetworkModel.error(e.toString())); + } + } void sortKomentarList(int option, List<KomentarModel> currentList) { currentList.sort((nextKomentar, prevKomentar) => diff --git a/lib/bloc/komentar_posting_bloc.dart b/lib/bloc/komentar_posting_bloc.dart index eb7092096c60b8ade9bb7a1ecd659ba691500ddc..e838f6b81eb570b899f97e22e15daa972e31ac0f 100644 --- a/lib/bloc/komentar_posting_bloc.dart +++ b/lib/bloc/komentar_posting_bloc.dart @@ -2,6 +2,8 @@ import 'dart:async'; import 'package:bisaGo/model/komentar_posting.dart'; import 'package:bisaGo/network/data/network_model.dart'; import 'package:bisaGo/repository/komentar_posting_repository.dart'; +import 'package:get_it/get_it.dart'; +import 'package:http/http.dart'; class KomentarPostingBloc { KomentarPostingRepository _komentarPostingRepository; @@ -16,7 +18,8 @@ class KomentarPostingBloc { KomentarPostingBloc(String namaLokasi, int id) { _komentarPostingListController = StreamController<NetworkModel<KomentarPostingList>>(); - _komentarPostingRepository = KomentarPostingRepository(); + _komentarPostingRepository = + GetIt.instance.get<BaseKomentarPostingRepository>(); fetchKomentarPostingList(namaLokasi, id); } @@ -35,6 +38,18 @@ class KomentarPostingBloc { } } + Future<dynamic> addKomentarPosting( + Map<String, dynamic> newKomentarPostingData, + String namaLokasi, + int id) async { + try { + return await _komentarPostingRepository.createKomentarPosting( + newKomentarPostingData, namaLokasi, id); + } catch (e) { + return Response('Failed to add komentar', 400); + } + } + void resetKomentarPostingList() { komentarPostingListSink.add( NetworkModel.completed(KomentarPostingList(allKomentarPositngFromApi))); diff --git a/lib/bloc/lokasi_response_bloc.dart b/lib/bloc/lokasi_response_bloc.dart index b62c271614e1d2b8b323e674fa2040331d939785..97527c283d7314f52de6efe14da6a1874e6aaf71 100644 --- a/lib/bloc/lokasi_response_bloc.dart +++ b/lib/bloc/lokasi_response_bloc.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:bisaGo/model/lokasi.dart'; import 'package:bisaGo/network/data/network_model.dart'; import 'package:bisaGo/repository/lokasi_repository.dart'; +import 'package:get_it/get_it.dart'; import 'package:http/http.dart'; class LokasiResponseBloc { @@ -25,7 +26,7 @@ class LokasiResponseBloc { StreamController<NetworkModel<LokasiListResponse>>(); _recentSearchController = StreamController<NetworkModel<LokasiListResponse>>(); - _lokasiRepository = LokasiRepository(); + _lokasiRepository = GetIt.instance.get<BaseLokasiRepository>(); fetchLokasiList(); fetchRecentSearch(); } @@ -58,6 +59,14 @@ class LokasiResponseBloc { } } + Future<Response> updateLokasi(Lokasi lokasi, String token) async { + try { + return await _lokasiRepository.updateLokasi(lokasi, token); + } catch (e) { + return Response('Failed to update lokasi', 400); + } + } + Future<void> saveRecentSearch(Lokasi search) async { await _lokasiRepository.saveRecentSearch(search); } diff --git a/lib/bloc/sekolah_bloc.dart b/lib/bloc/sekolah_bloc.dart index b40e3084f42839d4061ed705605e1e4547087d5c..02f7f1de7fcccc617c4a6af225271139e4dd1d11 100644 --- a/lib/bloc/sekolah_bloc.dart +++ b/lib/bloc/sekolah_bloc.dart @@ -32,53 +32,6 @@ class SekolahBloc { } } - // void filterbyKecamatan( - // String kecamatan, bool value, List<SekolahModel> currentList) { - // if (value) { - // for (var sekolah in allSekolahFromApi) { - // if (sekolah.alamat.toLowerCase().contains(kecamatan.toLowerCase())) { - // currentList.add(sekolah); - // } - // } - // } else { - // currentList.removeWhere((sekolah) => - // sekolah.alamat.toLowerCase().contains(kecamatan.toLowerCase())); - // } - // sekolahListSink.add(NetworkModel.completed(SekolahList(currentList))); - // } - // - // void filterbyKategoriSekolah( - // String kategori, bool val, List<SekolahModel> currentList) { - // if (val) { - // for (var sekolah in allSekolahFromApi) { - // if (sekolah.jenis_sekolah.contains(kategori)) { - // currentList.add(sekolah); - // } - // } - // } else { - // currentList.removeWhere((sekolah) => - // sekolah.jenis_sekolah.contains(kategori)); - // } - // sekolahListSink.add(NetworkModel.completed(SekolahList(currentList))); - // } - // - // void filterbyTingkatSekolah( - // String tingkatSekolah, bool val, List<SekolahModel> currentList) { - // if (val) { - // for (var sekolah in allSekolahFromApi) { - // if (sekolah.name.toLowerCase().startsWith(tingkatSekolah - // .toLowerCase())) { - // currentList.add(sekolah); - // } - // } - // } else { - // currentList.removeWhere((sekolah) => - // sekolah.name.toLowerCase().startsWith(tingkatSekolah - // .toLowerCase())); - // } - // sekolahListSink.add(NetworkModel.completed(SekolahList(currentList))); - // } - void resetSekolahList() { sekolahListSink.add(NetworkModel.completed(SekolahList(allSekolahFromApi))); } diff --git a/lib/component/bisago_appbar.dart b/lib/component/bisago_appbar.dart index 1322324e702782066100d0e9094658ec3d004adb..e629232818e61059f0ef3a05b77561a7c1697314 100644 --- a/lib/component/bisago_appbar.dart +++ b/lib/component/bisago_appbar.dart @@ -22,10 +22,13 @@ class BisaGoAppBar extends StatelessWidget implements PreferredSizeWidget { mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: <Widget>[ - Padding( - padding: EdgeInsets.all(doubleSpace), + SizedBox( + width: MediaQuery.of(context).size.width * 0.55, child: Text( title, + overflow: TextOverflow.fade, + softWrap: false, + textAlign: TextAlign.center, style: TextStyle( fontSize: 25, fontFamily: 'Comfortaa', diff --git a/lib/component/bisago_drawer.dart b/lib/component/bisago_drawer.dart index 8018ac1b0db41328716ed8aa4b9cf4a05ed4868e..397d6c9e86f47dea04226f22e7849440a24ec05d 100644 --- a/lib/component/bisago_drawer.dart +++ b/lib/component/bisago_drawer.dart @@ -190,7 +190,7 @@ class BisaGoDrawer extends StatelessWidget { } else if (page == 'Riwayat Pencarian') { route = MaterialPageRoute(builder: (_) => Pencarian()); } else if (page == 'Tentang Aplikasi') { - route = MaterialPageRoute(builder: (_) => AboutUs()); + route = MaterialPageRoute(builder: (_) => const AboutUs()); } else if (page == 'Tentang Disabilitas') { route = MaterialPageRoute(builder: (_) => TentangDisabilitas()); } else if (page == 'Layanan Disabilitas') { diff --git a/lib/component/image_holder.dart b/lib/component/image_holder.dart index baa7f033e9031801e10c4fad9f95e515bca53221..deef1a5546e4e0d40e54e2773db443dab4a25f30 100644 --- a/lib/component/image_holder.dart +++ b/lib/component/image_holder.dart @@ -15,7 +15,10 @@ class ImageHolder extends StatelessWidget { imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), - image: DecorationImage(image: imageProvider, fit: BoxFit.fitWidth)), + image: DecorationImage( + image: imageProvider, + fit: BoxFit.cover, + )), ), placeholder: (context, _) => const Center( child: CircularProgressIndicator( diff --git a/lib/config/styles.dart b/lib/config/styles.dart index 2e50c2241fa427127bd45ca1b459bd5e55ba272a..4f910d3f7ac3946cd7458db972a1b83fa8064986 100644 --- a/lib/config/styles.dart +++ b/lib/config/styles.dart @@ -7,6 +7,7 @@ const Color greenPale = Color(0xff4FBA4F); const Color darkGreen = Color(0xff347D34); const Color redPrimary = Color(0xffC60000); const Color grayPrimary = Color(0xff645C5C); +const Color gray = Color(0xffE1E1E1); const Color purple = Color(0xff6A2C57); const Color red = Color(0xffDF3535); const Color greenDM = Color(0xff008A00); diff --git a/lib/get_it.dart b/lib/get_it.dart index b8125b9a08045318d834e6c5df30ba78e94c9a21..2b1c169390834c46cf81ba5147a44efd51004d1c 100644 --- a/lib/get_it.dart +++ b/lib/get_it.dart @@ -1,4 +1,7 @@ +import 'package:bisaGo/repository/komentar_posting_repository.dart'; +import 'package:bisaGo/repository/komentar_repository.dart'; import 'package:bisaGo/repository/komunitas_repository.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; import 'package:bisaGo/repository/sekolah_repository.dart'; import 'package:bisaGo/repository/user_repository.dart'; import 'package:get_it/get_it.dart'; @@ -12,5 +15,11 @@ class AppGetIt { () => KomunitasRepository()); _getIt.registerLazySingleton<BaseSekolahRepository>( () => SekolahRepository()); + _getIt.registerLazySingleton<BaseKomentarRepository>( + () => KomentarRepository()); + _getIt.registerLazySingleton<BaseKomentarPostingRepository>( + () => KomentarPostingRepository()); + _getIt + .registerLazySingleton<BaseLokasiRepository>(() => LokasiRepository()); } } diff --git a/lib/model/lokasi.dart b/lib/model/lokasi.dart index 4d0ceae86cb2f8ca391d7780eb9ae5bdfd89e5cf..f59854f966fbd609f4b0856b5e2070eb1311a2cf 100644 --- a/lib/model/lokasi.dart +++ b/lib/model/lokasi.dart @@ -18,6 +18,7 @@ class Lokasi { String image; @JsonKey(name: 'no_telp') String noTelp; + int counter; Lokasi(); diff --git a/lib/model/lokasi.g.dart b/lib/model/lokasi.g.dart index db24e41d47c153abdcd04295e9a484e2639e698c..03a6c75170c081a4af638adaa9094a56744b8364 100644 --- a/lib/model/lokasi.g.dart +++ b/lib/model/lokasi.g.dart @@ -28,7 +28,8 @@ Lokasi _$LokasiFromJson(Map<String, dynamic> json) { ..longitude = (json['longitude'] as num)?.toDouble() ..alamat = json['alamat'] as String ..image = json['image'] as String - ..noTelp = json['no_telp'] as String; + ..noTelp = json['no_telp'] as String + ..counter = json['counter'] as int; } Map<String, dynamic> _$LokasiToJson(Lokasi instance) => <String, dynamic>{ @@ -39,4 +40,5 @@ Map<String, dynamic> _$LokasiToJson(Lokasi instance) => <String, dynamic>{ 'alamat': instance.alamat, 'image': instance.image, 'no_telp': instance.noTelp, + 'counter': instance.counter, }; diff --git a/lib/page/aboutUs/about_us.dart b/lib/page/aboutUs/about_us.dart index 771bccc2ee031dd8357b12c8a56f33e493af41e2..516f780c16cbc65c51d0695bbc8eee876148304e 100644 --- a/lib/page/aboutUs/about_us.dart +++ b/lib/page/aboutUs/about_us.dart @@ -4,7 +4,7 @@ import 'package:bisaGo/component/bisago_drawer.dart'; import 'package:bisaGo/config/styles.dart'; class AboutUs extends StatefulWidget { - AboutUs({Key key}) : super(key: key); + const AboutUs({Key key}) : super(key: key); @override _AboutUsState createState({Key key}) => _AboutUsState(); } diff --git a/lib/page/addLokasi/add_lokasi.dart b/lib/page/addLokasi/add_lokasi.dart index ecf6821942e4ed32645ad0e46bc6ce2202ddc7fe..a1975236fc186d58f9902046e8eee5f52bb23aea 100644 --- a/lib/page/addLokasi/add_lokasi.dart +++ b/lib/page/addLokasi/add_lokasi.dart @@ -17,7 +17,7 @@ import 'package:bisaGo/config/styles.dart'; import 'package:shared_preferences/shared_preferences.dart'; class AddLokasi extends StatefulWidget { - AddLokasi({Key key}) : super(key: key); + const AddLokasi({Key key}) : super(key: key); @override _AddLokasiState createState({Key key}) => _AddLokasiState(); } diff --git a/lib/page/add_informasi/add_informasi.dart b/lib/page/add_informasi/add_informasi.dart index 0b871706c1b6b322f358a93e223a94187befab3e..1dc47c3b3ef26f788074c3b14c7c9ed775f34eab 100644 --- a/lib/page/add_informasi/add_informasi.dart +++ b/lib/page/add_informasi/add_informasi.dart @@ -31,7 +31,6 @@ class AddInformasiState extends State<AddInformasi> { Map<String, dynamic> newKomentarData = {}; KomentarBloc _bloc; TextEditingController deskripsiController = TextEditingController(); - TextEditingController jumlahFasilitasController = TextEditingController(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final picker = ImagePicker(); File _image; @@ -80,7 +79,7 @@ class AddInformasiState extends State<AddInformasi> { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ - SizedBox(height: tripleSpace), + SizedBox(height: doubleSpace), Text( widget.nama, key: Key('Text Location Name'), @@ -91,7 +90,6 @@ class AddInformasiState extends State<AddInformasi> { fontFamily: 'Comfortaa', ), ), - SizedBox(height: doubleSpace), // GridView.count( // key: Key('Input Gambar'), // shrinkWrap: true, @@ -123,6 +121,7 @@ class AddInformasiState extends State<AddInformasi> { // ) // ], // ), + SizedBox(height: doubleSpace), CustomDropdown( title: 'Fasilitas / Layanan', key: Key('Dropdown Fasilitas Layanan'), @@ -134,13 +133,13 @@ class AddInformasiState extends State<AddInformasi> { _jenisFasilitas = value; }); }), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), Text( 'Jumlah fasilitas / layanan', style: TextStyle(fontSize: 18), textAlign: TextAlign.left, ), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), Row( children: [ iconButton( @@ -178,7 +177,7 @@ class AddInformasiState extends State<AddInformasi> { ), SizedBox(height: _isCounterValid == true ? 0 : regularSpace), FieldValidator.validateCustomFieldAlert(_isCounterValid), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), CustomDeskripsiField( title: 'Cara menggunakan', key: Key('Text Field Informasi'), @@ -187,7 +186,7 @@ class AddInformasiState extends State<AddInformasi> { validator: FieldValidator.validateInfo, controller: deskripsiController, ), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -206,26 +205,25 @@ class AddInformasiState extends State<AddInformasi> { }); }, child: Container( - height: 40, width: MediaQuery.of(context).size.width * 0.45, - padding: EdgeInsets.only(left: 10.0), + padding: const EdgeInsets.all(9.0), alignment: Alignment.centerLeft, decoration: BoxDecoration( boxShadow: regularShadow, - borderRadius: BorderRadius.circular(5.0), + borderRadius: BorderRadius.circular(10.0), color: greenPrimary), child: Row( children: [ Icon( MdiIcons.imagePlus, color: Colors.white, - size: 16.0, + size: 14.0, ), SizedBox(width: regularSpace), Text( 'Pilih foto', style: TextStyle( - color: Colors.white, fontSize: 16.0), + color: Colors.white, fontSize: 14.0), ), ], ), @@ -234,19 +232,19 @@ class AddInformasiState extends State<AddInformasi> { ], ), _showImagePreview(), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), Text( 'Jenis Disabilitas', style: TextStyle(fontSize: 18), textAlign: TextAlign.left, ), FieldValidator.validateCustomFieldAlert(_isDisabilitasValid), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ DisabilitasIconButton( - key: Key('Button Disabiltias Fisik'), + key: const Key('Button Disabilitas Fisik'), disabilitas: 'Disabilitas Fisik', imageUrl: _fisikClicked ? 'assets/images/DF.png' @@ -261,7 +259,7 @@ class AddInformasiState extends State<AddInformasi> { }, ), DisabilitasIconButton( - key: Key('Button Disabiltias Intelektual'), + key: const Key('Button Disabilitas Intelektual'), disabilitas: 'Disabilitas Intelektual', imageUrl: _intelektualClicked ? 'assets/images/DI.png' @@ -278,12 +276,12 @@ class AddInformasiState extends State<AddInformasi> { }, ), ]), - SizedBox(height: doubleSpace), + const SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ DisabilitasIconButton( - key: Key('Button Disabiltias Mental'), + key: const Key('Button Disabilitas Mental'), disabilitas: 'Disabilitas Mental', imageUrl: _mentalClicked ? 'assets/images/DM.png' @@ -298,7 +296,7 @@ class AddInformasiState extends State<AddInformasi> { }, ), DisabilitasIconButton( - key: Key('Button Disabiltias Sensorik'), + key: const Key('Button Disabilitas Sensorik'), disabilitas: 'Disabilitas Sensorik', imageUrl: _sensorikClicked ? 'assets/images/DS.png' @@ -440,7 +438,7 @@ class AddInformasiState extends State<AddInformasi> { void successDialog(BuildContext context) { var alertDialog = AlertDialog( - title: Text('Tambah Informasi berhasil'), + title: const Text('Tambah informasi berhasil'), content: Icon(FontAwesomeIcons.checkCircle), ); showDialog( @@ -451,11 +449,12 @@ class AddInformasiState extends State<AddInformasi> { } void failedDialog(BuildContext context, String message) { + var newMessage = message; if (message == 'default') { - message = 'Gagal menambahkan informasi'; + newMessage = 'Gagal menambahkan informasi'; } var alertDialog = AlertDialog( - title: Text(message), + title: Text(newMessage), content: Icon(FontAwesomeIcons.exclamationCircle), ); showDialog( @@ -467,14 +466,15 @@ class AddInformasiState extends State<AddInformasi> { Widget _showImagePreview() { return _image == null - ? SizedBox(height: 0) + ? const SizedBox(height: 0) : Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ - SizedBox(height: doubleSpace), + const SizedBox(height: doubleSpace), Container( - padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0), - decoration: BoxDecoration( + padding: + const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0), + decoration: const BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(20.0), topRight: Radius.circular(20.0), @@ -485,9 +485,9 @@ class AddInformasiState extends State<AddInformasi> { ), child: Image.file(_image), ), - SizedBox(height: regularSpace), + const SizedBox(height: regularSpace), FlatButton( - key: Key('Button Hapus Foto'), + key: const Key('Button Hapus Foto'), padding: EdgeInsets.zero, onPressed: () async { setState(() { @@ -495,17 +495,16 @@ class AddInformasiState extends State<AddInformasi> { }); }, child: Container( - height: 40, width: MediaQuery.of(context).size.width * 0.3, - padding: EdgeInsets.only(left: 10.0), + padding: const EdgeInsets.all(9.0), alignment: Alignment.centerLeft, decoration: BoxDecoration( boxShadow: regularShadow, - borderRadius: BorderRadius.circular(5.0), + borderRadius: BorderRadius.circular(10.0), color: greenPrimary), - child: Text( + child: const Text( 'Hapus foto', - style: TextStyle(color: Colors.white, fontSize: 16.0), + style: TextStyle(color: Colors.white, fontSize: 14.0), ), ), ), diff --git a/lib/page/dashboard/dashboard.dart b/lib/page/dashboard/dashboard.dart index e500bb7b695444ca7708b703dbc527aded1e14c6..77bf59ea6eb4cc9d78d3df3360b203b8661efc5f 100644 --- a/lib/page/dashboard/dashboard.dart +++ b/lib/page/dashboard/dashboard.dart @@ -1,4 +1,7 @@ -import 'package:bisaGo/page/informasi/list_sekolah.dart'; +import 'package:bisaGo/bloc/lokasi_response_bloc.dart'; +import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/network/data/network_model.dart'; +import 'package:bisaGo/utils/custom_dashboard_location_button.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; @@ -19,6 +22,8 @@ class DashboardState extends State<Dashboard> { LatLng currentLocation; Set<Marker> markers = {}; + LokasiResponseBloc bloc = LokasiResponseBloc(); + @override void initState() { super.initState(); @@ -31,61 +36,127 @@ class DashboardState extends State<Dashboard> { Navigator.of(context).push(route); } - void _navigateToInformasiLayananDisabilitasPage(BuildContext context) { - final route = MaterialPageRoute(builder: (_) => ListSekolah()); - Navigator.of(context).push(route); - } + // void _navigateToInformasiLayananDisabilitasPage(BuildContext context) { + // final route = MaterialPageRoute(builder: (_) => ListSekolah()); + // Navigator.of(context).push(route); + // } static const textFieldKey = Key('Text Field Mau Kemana'); @override Widget build(BuildContext context) { return Scaffold( drawer: BisaGoDrawer(), - body: Stack(key: const Key('Stack'), children: <Widget>[ - _buildGoogleMap(context), - InkWell( - key: const Key('Navigate to Pencarian'), - onTap: () => _navigateToPencarianPage(context), - child: Container( - key: const Key('Container Text Field'), - margin: EdgeInsets.only( - left: doubleSpace, right: doubleSpace, top: doubleSpace), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: doubleBorderRadius, - boxShadow: regularShadow), - child: TextFormField( - enabled: false, - key: const Key('Text Field Mau Kemana'), - decoration: InputDecoration( - prefixIcon: Icon( - Icons.search, - color: greenPrimary, - size: 25, - ), - border: InputBorder.none, - fillColor: Colors.white, - labelText: 'Kamu mau kemana?', - labelStyle: TextStyle( - color: greenPrimary, - fontSize: 20, - fontFamily: 'Muli', - fontWeight: FontWeight.w700), + body: Stack( + key: const Key('Stack'), + alignment: AlignmentDirectional.bottomStart, + children: <Widget>[ + _buildGoogleMap(context), + Container( + height: 285, + alignment: Alignment.bottomCenter, + decoration: const BoxDecoration( + color: white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), ), ), + padding: const EdgeInsets.symmetric( + horizontal: doubleSpace, vertical: doubleSpace), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + key: const Key('Navigate to Pencarian'), + onTap: () => _navigateToPencarianPage(context), + child: Container( + key: const Key('Container Text Field'), + padding: EdgeInsets.zero, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: regularBorderRadius, + border: Border.all(color: greenPrimary), + boxShadow: regularShadow), + child: TextFormField( + enabled: false, + key: const Key('Text Field Mau Kemana'), + decoration: InputDecoration( + prefixIcon: Icon( + Icons.search, + color: greenPrimary, + size: 25, + ), + border: InputBorder.none, + fillColor: Colors.white, + labelText: 'Tekan untuk mencari tempat', + labelStyle: TextStyle( + color: greenPrimary, + fontSize: 20, + fontFamily: 'Muli', + fontWeight: FontWeight.w700), + ), + ), + ), + ), + SizedBox(height: doubleSpace), + const Text( + 'Paling sering dicari', + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 10), + StreamBuilder<NetworkModel<LokasiListResponse>>( + stream: bloc.lokasiListStream, + builder: (context, snapshot) { + if (snapshot.hasData) { + switch (snapshot.data.status) { + case Status.loading: + return Container( + height: 130, + child: Center( + child: const CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation<Color>( + greenPrimary), + ), + ), + ); + break; + case Status.completed: + final places = + _sortLocation(snapshot.data.data.listLokasi); + return _buildLokasiWidget(places); + break; + case Status.error: + return Container( + height: 130, + child: const Center( + child: Text('Gagal untuk mendapatkan tempat'), + ), + ); + break; + } + return Container(); + } + return Container(); + }), + ], + ), ), - ), - ]), - floatingActionButton: FloatingActionButton.extended( - key: const Key('FloatingActionButton'), - onPressed: () { - _navigateToInformasiLayananDisabilitasPage(context); - }, - label: Text('Informasi Layanan Disabilitas'), - icon: Icon(Icons.search), - backgroundColor: greenPrimary, + ], ), - floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + // floatingActionButton: FloatingActionButton.extended( + // key: const Key('FloatingActionButton'), + // onPressed: () { + // _navigateToInformasiLayananDisabilitasPage(context); + // }, + // label: Text('Informasi Layanan Disabilitas'), + // icon: Icon(Icons.search), + // backgroundColor: greenPrimary, + // ), + // floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, appBar: PreferredSize( preferredSize: const Size.fromHeight(55), child: BisaGoAppBar(), @@ -94,6 +165,31 @@ class DashboardState extends State<Dashboard> { ); } + Widget _buildLokasiWidget(List<Lokasi> lokasilistresponse) { + return Container( + height: 130, + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + Row( + children: lokasilistresponse + .map<Widget>((k) => LocationIconButton( + location: k, + )) + .toList()), + ], + ), + ); + } + + List<Lokasi> _sortLocation(List<Lokasi> lokasi) { + lokasi.sort((a, b) => a.counter.compareTo(b.counter)); + if (lokasi.length >= 3) { + return lokasi.reversed.toList().sublist(0, 3); + } + return lokasi.reversed.toList(); + } + Widget _buildGoogleMap(BuildContext context) { if (currentLocation == null) { return const Center( diff --git a/lib/page/filter_fasilitas/fasilitas.dart b/lib/page/filter_fasilitas/fasilitas.dart index 223197a76dce69d281032a05e59a0bc3bd3c2923..11d28f48d0e98e8a2ffde7b9d53308b62fc27015 100644 --- a/lib/page/filter_fasilitas/fasilitas.dart +++ b/lib/page/filter_fasilitas/fasilitas.dart @@ -1,3 +1,4 @@ +import 'package:bisaGo/bloc/lokasi_response_bloc.dart'; import 'package:bisaGo/model/lokasi.dart'; import 'package:flutter/material.dart'; import 'package:bisaGo/bloc/komentar_bloc.dart'; @@ -37,11 +38,14 @@ class _FasilitasState extends State<Fasilitas> { var showUrutan = true; List<KomentarModel> allKomentarFromApi; KomentarBloc _bloc; + LokasiResponseBloc _lokasiBloc; @override void initState() { allKomentarFromApi = []; _bloc = KomentarBloc(widget.lokasi.name); + _lokasiBloc = LokasiResponseBloc(); + _updateLokasi(); super.initState(); } @@ -57,7 +61,7 @@ class _FasilitasState extends State<Fasilitas> { crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ SizedBox( - height: 200, child: ImageHolder(url: widget.lokasi.image)), + height: 150, child: ImageHolder(url: widget.lokasi.image)), Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ @@ -120,7 +124,7 @@ class _FasilitasState extends State<Fasilitas> { Container( margin: EdgeInsets.only( top: doubleSpace, - bottom: doubleSpace, + bottom: smallSpace, left: smallSpace), decoration: BoxDecoration(boxShadow: regularShadow), child: SizedBox( @@ -139,61 +143,97 @@ class _FasilitasState extends State<Fasilitas> { onPressed: () { checkLoginStatus(); }, - child: Text( - 'Tambah Review', - style: TextStyle(fontSize: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + const Icon( + Icons.add, + size: 20, + ), + Text( + 'Tambah Informasi', + style: TextStyle(fontSize: 20), + ), + ], ), ), ), ), + // Container( + // margin: const EdgeInsets.only( + // bottom: smallSpace, left: regularSpace), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: <Widget>[ + // Text( + // 'Filter', + // style: TextStyle( + // fontSize: 15, + // fontWeight: FontWeight.w800, + // color: Colors.black, + // fontFamily: 'Muli', + // ), + // ), + // Container( + // // decoration: BoxDecoration(boxShadow: regularShadow), + // child: SizedBox( + // width: 220, + // child: FlatButton( + // key: Key('FilterButton'), + // textColor: Colors.green[700], + // disabledColor: Colors.grey, + // disabledTextColor: Colors.black, + // padding: EdgeInsets.all(8), + // shape: RoundedRectangleBorder( + // borderRadius: regularBorderRadius, + // side: BorderSide(color: Colors.green[700]), + // ), + // splashColor: Colors.lightGreen, + // onPressed: () { + // print('temporary print'); + // }, + // // => showModalBottomSheet( + // // context: context, + // // builder: (context) => InsideFilter(), + // // backgroundColor: Colors.transparent, + // // isScrollControlled: true), + // child: Stack( + // alignment: Alignment.centerRight, + // children: <Widget>[ + // Container( + // alignment: Alignment.centerLeft, + // child: Text( + // 'Semua Disabilitas', + // style: TextStyle(fontSize: 13), + // ), + // ), + // Icon( + // Icons.filter_list, + // color: Colors.green[700], + // size: 20, + // ), + // ], + // ), + // ), + // ), + // ), + // ], + // ), + // ), Container( - margin: EdgeInsets.only(bottom: doubleSpace), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: <Widget>[ - Text( - 'Review Fasilitas', - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.w800, - color: Colors.black, - fontFamily: 'Muli', - ), - ), - Container( - decoration: BoxDecoration(boxShadow: regularShadow), - child: FlatButton( - key: Key('FilterButton'), - color: Colors.green[700], - textColor: Colors.white, - disabledColor: Colors.grey, - disabledTextColor: Colors.black, - padding: EdgeInsets.all(8), - shape: RoundedRectangleBorder( - borderRadius: regularBorderRadius, - side: BorderSide(color: Colors.transparent)), - splashColor: Colors.lightGreen, - onPressed: () { - print('temporary print'); - }, - // => showModalBottomSheet( - // context: context, - // builder: (context) => InsideFilter(), - // backgroundColor: Colors.transparent, - // isScrollControlled: true), - child: Row( - children: <Widget>[ - Icon(Icons.filter_list, - color: Colors.white, size: 20), - Text( - 'Filter Review', - style: TextStyle(fontSize: 13), - ), - ], - ), - ), - ), - ], + margin: const EdgeInsets.only( + bottom: doubleSpace, + left: regularSpace, + top: regularSpace, + ), + child: const Text( + 'Fasilitas atau layanan yang disediakan', + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w800, + color: Colors.black, + fontFamily: 'Muli', + ), ), ), StreamBuilder( @@ -225,6 +265,7 @@ class _FasilitasState extends State<Fasilitas> { return Center( child: Text(snapshot.data.data.toString()), ); + break; } } @@ -962,6 +1003,12 @@ class _FasilitasState extends State<Fasilitas> { super.dispose(); } + Future<void> _updateLokasi() async { + final sharedPreferences = await SharedPreferences.getInstance(); + final token = 'token ${sharedPreferences.getString('token')}'; + await _lokasiBloc.updateLokasi(widget.lokasi, token); + } + void checkLoginStatus() async { final sharedPreferences = await SharedPreferences.getInstance(); if (sharedPreferences.getString('token') == null) { diff --git a/lib/page/filter_fasilitas/komentar.dart b/lib/page/filter_fasilitas/komentar.dart index 10b0c3fb62045d4b9e22e2fa5c5ac336bd70a521..e9e6bfeacbd5d1e745eef156344fb3856a102859 100644 --- a/lib/page/filter_fasilitas/komentar.dart +++ b/lib/page/filter_fasilitas/komentar.dart @@ -1,13 +1,14 @@ +import 'package:bisaGo/config/strings.dart'; import 'package:bisaGo/model/lokasi.dart'; import 'package:flutter/material.dart'; import 'package:bisaGo/component/image_holder.dart'; import 'package:bisaGo/config/styles.dart'; import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:bisaGo/network/network_interface.dart'; -import 'package:bisaGo/page/login/login.dart'; +// import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +// import 'package:shared_preferences/shared_preferences.dart'; +// import 'package:bisaGo/network/network_interface.dart'; +// import 'package:bisaGo/page/login/login.dart'; class Komentar extends StatefulWidget { final Lokasi lokasi; @@ -33,25 +34,26 @@ class _KomentarState extends State<Komentar> { @override Widget build(BuildContext context) { return InkWell( - onTap: () { - Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (BuildContext context) => DetailPostPage( - lokasi: widget.lokasi, - komentar: KomentarModel( - creator: widget.komentar.creator, - dateTime: widget.komentar.dateTime, - deskripsi: widget.komentar.deskripsi, - id: widget.komentar.id, - image: widget.komentar.image, - isVerified: widget.komentar.isVerified, - namaLokasi: widget.komentar.namaLokasi, - tag: widget.komentar.tag, - disabilitas: widget.komentar.disabilitas, - jumlah: widget.komentar.jumlah, - ), - ))); - }, - child: Container( + key: Key('Fasilitas ${fasilitas[widget.komentar.tag]}'), + onTap: () { + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (BuildContext context) => DetailPostPage( + lokasi: widget.lokasi, + komentar: KomentarModel( + creator: widget.komentar.creator, + dateTime: widget.komentar.dateTime, + deskripsi: widget.komentar.deskripsi, + id: widget.komentar.id, + image: widget.komentar.image, + isVerified: widget.komentar.isVerified, + namaLokasi: widget.komentar.namaLokasi, + tag: widget.komentar.tag, + disabilitas: widget.komentar.disabilitas, + jumlah: widget.komentar.jumlah, + ), + ))); + }, + child: Container( margin: EdgeInsets.only(bottom: regularSpace), padding: EdgeInsets.all(doubleSpace), decoration: BoxDecoration( @@ -62,102 +64,126 @@ class _KomentarState extends State<Komentar> { ), color: Colors.white, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: Stack( children: <Widget>[ - Container( - margin: EdgeInsets.only(bottom: regularSpace), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: <Widget>[ - Text( - widget.komentar.creator, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w800, - color: Colors.black, - fontFamily: 'Muli', + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: <Widget>[ + SizedBox( + width: 20, + height: 20, + child: Container( + decoration: BoxDecoration( + color: red, borderRadius: doubleBorderRadius), + alignment: Alignment.center, + child: Text( + '${widget.komentar.jumlah}', + style: TextStyle( + color: white, fontWeight: FontWeight.bold), ), ), - Row( + ), + ], + ), + Column( + // crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + Container( + margin: EdgeInsets.only(bottom: regularSpace), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ - Container( - margin: EdgeInsets.only(right: regularSpace), - child: InkWell( - onTap: () => checkLoginStatus('like'), - child: Row( - children: <Widget>[ - Icon(Icons.thumb_up, - color: Colors.green[800], size: 20), - Text( - 'suka', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Colors.green[800], - ), - ), - ], - ), + Text( + fasilitas[widget.komentar.tag], + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w800, + color: Colors.black, + fontFamily: 'Muli', ), ), - Container( - margin: EdgeInsets.only(right: regularSpace), - child: InkWell( - onTap: () => checkLoginStatus('dislike'), - child: Row( - children: <Widget>[ - Icon(Icons.thumb_down, - color: redPrimary, size: 20), - const Text( - 'tidak suka', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w600, - color: redPrimary, - ), - ), - ], - ), + // Row( + // children: <Widget>[ + // Container( + // margin: EdgeInsets.only(right: regularSpace), + // child: InkWell( + // onTap: () => checkLoginStatus('like'), + // child: Row( + // children: <Widget>[ + // Icon(Icons.thumb_up, + // color: Colors.green[800], size: 20), + // Text( + // 'suka', + // style: TextStyle( + // fontSize: 12, + // fontWeight: FontWeight.w600, + // color: Colors.green[800], + // ), + // ), + // ], + // ), + // ), + // ), + // Container( + // margin: EdgeInsets.only(right: regularSpace), + // child: InkWell( + // onTap: () => checkLoginStatus('dislike'), + // child: Row( + // children: <Widget>[ + // Icon(Icons.thumb_down, + // color: redPrimary, size: 20), + // const Text( + // 'tidak suka', + // style: TextStyle( + // fontSize: 12, + // fontWeight: FontWeight.w600, + // color: redPrimary, + // ), + // ), + // ], + // ), + // ), + // ), + // ], + // ) + ], + ), + ), + Container( + margin: EdgeInsets.only(bottom: regularSpace), + child: SizedBox( + height: 160, + child: ImageHolder(url: widget.komentar.image))), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, + children: <Widget>[ + Flexible( + child: Text( + 'ditambahkan oleh ${widget.komentar.creator}', + softWrap: true, + style: TextStyle( + fontSize: 12, + color: Colors.black, + fontFamily: 'Muli', + fontStyle: FontStyle.italic, ), ), - ], - ) - ], - ), - ), - Container( - margin: EdgeInsets.only(bottom: regularSpace), - child: SizedBox( - height: 160, - child: ImageHolder(url: widget.komentar.image))), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: <Widget>[ - Flexible( - child: Text( - widget.komentar.deskripsi, - softWrap: true, - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 15, - color: Colors.black, - fontFamily: 'Muli', ), - ), + ], ), + // Wrap( + // children: <Widget>[ + // ...widget.komentar.tag.map<Widget>((tag) { + // return _tag(tag); + // }).toList() + // ], + // ), ], ), - // Wrap( - // children: <Widget>[ - // ...widget.komentar.tag.map<Widget>((tag) { - // return _tag(tag); - // }).toList() - // ], - // ), ], - )), - ); + ), + )); } // Widget _tag(String tag) { @@ -184,225 +210,226 @@ class _KomentarState extends State<Komentar> { // ); // } - void saveLikeDislike(String operation) async { - final namaTempat = widget.komentar.namaLokasi.replaceAll(' ', '%20'); - final idString = widget.komentar.id.toString(); - var response = await NetworkInterface().put( - url: - '/informasi-fasilitas/lokasi/like-fasilitas/$namaTempat/$idString/$operation/', - ); - if (response['response'] == 'You have successfuly liked this facility') { - likeSuccess(context); - } else if (response['response'] == 'You have already liked this facility') { - alreadyLike(context); - } else if (response['response'] == - 'You have successfuly disliked this facility') { - dislikeSuccess(context); - } else if (response['response'] == - 'You have already disliked this facility') { - alreadyDislike(context); - } else { - likeDislikeFailed(context); - } - } - - void alreadyLike(BuildContext context) { - var alertDialog = AlertDialog( - backgroundColor: greenPale, - title: Text( - 'Anda sudah pernah Like Post ini', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - actions: <Widget>[ - FlatButton( - child: Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - setState(() { - alreadyLikeFlag = 1; - }); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } - - void alreadyDislike(BuildContext context) { - var alertDialog = AlertDialog( - backgroundColor: greenPale, - title: Text( - 'Anda sudah pernah Dislike Post ini', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - actions: <Widget>[ - FlatButton( - child: Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - setState(() { - alreadyDislikeFlag = 1; - }); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } - - void likeSuccess(BuildContext context) { - var alertDialog = AlertDialog( - backgroundColor: greenPrimary, - title: Text( - 'Like komentar berhasil', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - content: Icon(FontAwesomeIcons.checkCircle, color: Colors.white), - actions: <Widget>[ - FlatButton( - child: Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - setState(() { - if (alreadyDislikeFlag == 1) { - dislike = dislike - 1; - like = like + 1; - alreadyLikeFlag = 1; - } else { - like = like + 1; - alreadyLikeFlag = 1; - } - }); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } - - void dislikeSuccess(BuildContext context) { - var alertDialog = AlertDialog( - backgroundColor: greenPrimary, - title: Text( - 'Dislike komentar berhasil', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - content: Icon(FontAwesomeIcons.checkCircle, color: Colors.white), - actions: <Widget>[ - FlatButton( - child: Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - setState(() { - if (alreadyLikeFlag == 1) { - like = like - 1; - dislike = dislike + 1; - alreadyDislikeFlag = 1; - } else { - dislike = dislike + 1; - alreadyDislikeFlag = 1; - } - }); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } - - void likeDislikeFailed(BuildContext context) { - var alertDialog = AlertDialog( - backgroundColor: redPrimary, - title: Text( - 'Like atau dislike komentar tidak berhasil', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - content: Icon(Icons.close, color: Colors.white), - actions: <Widget>[ - FlatButton( - child: Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } + // void saveLikeDislike(String operation) async { + // final namaTempat = widget.komentar.namaLokasi.replaceAll(' ', '%20'); + // final idString = widget.komentar.id.toString(); + // var response = await NetworkInterface().put( + // url: + // '/informasi-fasilitas/lokasi/like-fasilitas/$namaTempat/$idString/$operation/', + // ); + // if (response['response'] == 'You have successfuly liked this facility') { + // likeSuccess(context); + // } else if (response['response'] == + // 'You have already liked this facility') { + // alreadyLike(context); + // } else if (response['response'] == + // 'You have successfuly disliked this facility') { + // dislikeSuccess(context); + // } else if (response['response'] == + // 'You have already disliked this facility') { + // alreadyDislike(context); + // } else { + // likeDislikeFailed(context); + // } + // } + // + // void alreadyLike(BuildContext context) { + // var alertDialog = AlertDialog( + // backgroundColor: greenPale, + // title: Text( + // 'Anda sudah pernah Like Post ini', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w600, + // ), + // ), + // actions: <Widget>[ + // FlatButton( + // child: Text('OK', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w400, + // )), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ); + // setState(() { + // alreadyLikeFlag = 1; + // }); + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return alertDialog; + // }); + // } + // + // void alreadyDislike(BuildContext context) { + // var alertDialog = AlertDialog( + // backgroundColor: greenPale, + // title: Text( + // 'Anda sudah pernah Dislike Post ini', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w600, + // ), + // ), + // actions: <Widget>[ + // FlatButton( + // child: Text('OK', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w400, + // )), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ); + // setState(() { + // alreadyDislikeFlag = 1; + // }); + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return alertDialog; + // }); + // } + // + // void likeSuccess(BuildContext context) { + // var alertDialog = AlertDialog( + // backgroundColor: greenPrimary, + // title: Text( + // 'Like komentar berhasil', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w600, + // ), + // ), + // content: Icon(FontAwesomeIcons.checkCircle, color: Colors.white), + // actions: <Widget>[ + // FlatButton( + // child: Text('OK', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w400, + // )), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ); + // setState(() { + // if (alreadyDislikeFlag == 1) { + // dislike = dislike - 1; + // like = like + 1; + // alreadyLikeFlag = 1; + // } else { + // like = like + 1; + // alreadyLikeFlag = 1; + // } + // }); + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return alertDialog; + // }); + // } + // + // void dislikeSuccess(BuildContext context) { + // var alertDialog = AlertDialog( + // backgroundColor: greenPrimary, + // title: Text( + // 'Dislike komentar berhasil', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w600, + // ), + // ), + // content: Icon(FontAwesomeIcons.checkCircle, color: Colors.white), + // actions: <Widget>[ + // FlatButton( + // child: Text('OK', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w400, + // )), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ); + // setState(() { + // if (alreadyLikeFlag == 1) { + // like = like - 1; + // dislike = dislike + 1; + // alreadyDislikeFlag = 1; + // } else { + // dislike = dislike + 1; + // alreadyDislikeFlag = 1; + // } + // }); + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return alertDialog; + // }); + // } + // + // void likeDislikeFailed(BuildContext context) { + // var alertDialog = AlertDialog( + // backgroundColor: redPrimary, + // title: Text( + // 'Like atau dislike komentar tidak berhasil', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w600, + // ), + // ), + // content: Icon(Icons.close, color: Colors.white), + // actions: <Widget>[ + // FlatButton( + // child: Text('OK', + // style: TextStyle( + // color: Colors.white, + // fontFamily: 'Muli', + // fontWeight: FontWeight.w400, + // )), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + // ], + // ); + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return alertDialog; + // }); + // } - void checkLoginStatus(String operation) async { - final sharedPreferences = await SharedPreferences.getInstance(); - if (sharedPreferences.getString('token') == null) { - await Navigator.of(context).pushAndRemoveUntil( - MaterialPageRoute(builder: (BuildContext context) => Login()), - (Route<dynamic> route) => false); - } else { - saveLikeDislike(operation); - } - } + // void checkLoginStatus(String operation) async { + // final sharedPreferences = await SharedPreferences.getInstance(); + // if (sharedPreferences.getString('token') == null) { + // await Navigator.of(context).pushAndRemoveUntil( + // MaterialPageRoute(builder: (BuildContext context) => Login()), + // (Route<dynamic> route) => false); + // } else { + // saveLikeDislike(operation); + // } + // } } diff --git a/lib/page/filter_fasilitas/postingan/add_komentar.dart b/lib/page/filter_fasilitas/postingan/add_komentar.dart deleted file mode 100644 index ba6329c53a0f16cfea1c039738a0214c003197a7..0000000000000000000000000000000000000000 --- a/lib/page/filter_fasilitas/postingan/add_komentar.dart +++ /dev/null @@ -1,198 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:bisaGo/component/tambah_komentar_appbar.dart'; -import 'package:bisaGo/config/styles.dart'; -import 'package:bisaGo/model/komentar.dart'; -import 'package:bisaGo/network/network_interface.dart'; -import 'package:bisaGo/utils/custom_button.dart'; -import 'package:bisaGo/utils/custom_komentar_field.dart'; -import 'package:bisaGo/utils/validator.dart'; - -class AddKomentar extends StatefulWidget { - final KomentarModel komentar; - const AddKomentar(this.komentar, {Key key}) : super(key: key); - @override - AddKomentarState createState() => AddKomentarState(); -} - -class AddKomentarState extends State<AddKomentar> { - TextEditingController textFieldController = TextEditingController(); - GlobalKey<FormState> formKey = GlobalKey<FormState>(); - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: PreferredSize( - preferredSize: const Size.fromHeight(55), - child: TambahKomentarAppBar(), - ), - body: ListView(children: <Widget>[ - Container( - padding: const EdgeInsets.only( - top: tripleSpace, - bottom: regularSpace, - right: doubleSpace, - left: doubleSpace), - child: Text( - widget.komentar.namaLokasi, - style: const TextStyle( - fontSize: 30, - fontWeight: FontWeight.w600, - color: Colors.black, - fontFamily: 'Muli', - ), - ), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: <Widget>[ - Container( - padding: const EdgeInsets.only( - bottom: doubleSpace, - right: regularSpace, - left: doubleSpace), - child: const Text('Postingan oleh', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w600, - color: Colors.black, - fontFamily: 'Muli', - )), - ), - Container( - padding: const EdgeInsets.only( - bottom: doubleSpace, right: regularSpace), - child: Text(widget.komentar.creator, - style: const TextStyle( - fontSize: 20, - fontWeight: FontWeight.w600, - color: Colors.black, - fontFamily: 'Muli', - ))), - ], - ), - Form( - key: formKey, - child: Column( - children: <Widget>[ - Container( - padding: const EdgeInsets.only( - bottom: tripleSpace, - right: doubleSpace, - left: doubleSpace), - child: CustomKomentarField( - title: 'Komentar Informasi', - hint: 'Tulis disini...', - validator: FieldValidator.validateInfo, - controller: textFieldController, - ), - ), - Container( - padding: const EdgeInsets.only( - bottom: tripleSpace, - right: doubleSpace, - left: doubleSpace), - alignment: Alignment.center, - child: ButtonTheme( - minWidth: double.infinity, - height: 40, - child: submitButton('Kirim', _validateKomentarInput), - )) - ], - )), - ])); - } - - Future<void> _validateKomentarInput() async { - final form = formKey.currentState; - if (formKey.currentState.validate()) { - form.save(); - await saveKomentar(textFieldController.text); - } - } - - Future<void> saveKomentar(String komentar) async { - final data = {'deskripsi': komentar}; - final namaTempat = widget.komentar.namaLokasi; - final idString = widget.komentar.id.toString(); - final response = await NetworkInterface().post( - url: '/informasi-fasilitas/lokasi/add-komentar/$namaTempat/$idString/', - bodyParams: data); - if (response['response'] == 'komentar added') { - inputData(context); - } else { - inputDataFail(context); - } - } - - void inputData(BuildContext context) { - final alertDialog = AlertDialog( - backgroundColor: greenPrimary, - title: const Text( - 'Tambah Komentar berhasil. Silahkan kembali ke halaman sebelumnya', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - content: const Icon(FontAwesomeIcons.checkCircle, color: Colors.white), - actions: <Widget>[ - FlatButton( - child: const Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } - - void inputDataFail(BuildContext context) { - final alertDialog = AlertDialog( - backgroundColor: redPrimary, - title: const Text( - 'Tambah Komentar tidak berhasil', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w600, - ), - ), - content: const Icon(FontAwesomeIcons.cross, color: Colors.white), - actions: <Widget>[ - FlatButton( - child: const Text('OK', - style: TextStyle( - color: Colors.white, - fontFamily: 'Muli', - fontWeight: FontWeight.w400, - )), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - showDialog( - context: context, - builder: (BuildContext context) { - return alertDialog; - }); - } -} diff --git a/lib/page/filter_fasilitas/postingan/detail_post.dart b/lib/page/filter_fasilitas/postingan/detail_post.dart index 065f029686d04638398118ed1db59821577cbb17..9e06b1b70409b905a8022d86e3db42e87ae20220 100644 --- a/lib/page/filter_fasilitas/postingan/detail_post.dart +++ b/lib/page/filter_fasilitas/postingan/detail_post.dart @@ -1,7 +1,13 @@ +import 'dart:async'; + import 'package:bisaGo/config/strings.dart'; import 'package:bisaGo/model/lokasi.dart'; import 'package:bisaGo/page/filter_fasilitas/fasilitas.dart'; +import 'package:bisaGo/page/updateInformasi/update_informasi.dart'; +import 'package:bisaGo/utils/validator.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:bisaGo/bloc/komentar_posting_bloc.dart'; import 'package:bisaGo/component/image_holder.dart'; @@ -10,7 +16,6 @@ import 'package:bisaGo/config/styles.dart'; import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/model/komentar_posting.dart'; import 'package:bisaGo/network/data/network_model.dart'; -import 'package:bisaGo/page/filter_fasilitas/postingan/add_komentar.dart'; import 'package:bisaGo/page/login/login.dart'; import 'package:share/share.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -18,14 +23,19 @@ import 'package:shared_preferences/shared_preferences.dart'; class DetailPostPage extends StatefulWidget { final Lokasi lokasi; final KomentarModel komentar; - DetailPostPage({@required this.komentar, @required this.lokasi}); + const DetailPostPage( + {@required this.komentar, @required this.lokasi, Key key}) + : super(key: key); @override _DetailPostPageState createState() => _DetailPostPageState(); } class _DetailPostPageState extends State<DetailPostPage> { + Map<String, dynamic> newKomentarPostingData = {}; KomentarPostingBloc _bloc; List<KomentarPostingModel> allKomentarPostingFromApi; + TextEditingController komentarController = TextEditingController(); + final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); int like; int dislike; int alreadyLikeFlag; @@ -48,52 +58,88 @@ class _DetailPostPageState extends State<DetailPostPage> { key: Key('appbar-text-${widget.komentar.namaLokasi}'), actions: <Widget>[ InkWell( - child: Icon(Icons.share), + child: const Icon(Icons.share), onTap: () => Share.share( - 'Review fasilitas disabilitas di ${widget.lokasi.name}, oleh: ${widget.komentar.creator}\n\"${widget.komentar.deskripsi}\"\n\nDapatkan info fasilitas ramah disabilitas dari aplikasi bisaGo!\nDownload bisaGo sekarang di: https://bit.ly/DownloadbisaGo')) + 'Review fasilitas disabilitas di ${widget.lokasi.name}, ' + 'oleh: ${widget.komentar.creator}\n\"${widget.komentar.deskripsi}\"\n\nDapatkan info fasilitas ramah ' + 'disabilitas dari aplikasi bisaGo!\nDownload bisaGo ' + 'sekarang di: https://bit.ly/DownloadbisaGo')) ], ), body: SingleChildScrollView( child: Column( children: <Widget>[ - SizedBox(height: regularSpace), Container( - key: Key('Text Jenis Fasilitas'), - margin: EdgeInsets.all(doubleSpace), + key: const Key('Text Jenis Fasilitas'), + margin: const EdgeInsets.symmetric( + vertical: 10.0, horizontal: 15.0), alignment: Alignment.centerLeft, - child: Text( - fasilitas[widget.komentar.tag], - style: TextStyle( - fontSize: 28, - fontWeight: FontWeight.w800, - color: Colors.black, - fontFamily: 'Comfortaa', - ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.6, + child: Text( + fasilitas[widget.komentar.tag], + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.w800, + letterSpacing: -0.3, + color: Colors.black, + fontFamily: 'Comfortaa', + ), + ), + ), + PopupMenuButton( + key: const Key('Button Ubah Informasi'), + elevation: 4.0, + offset: const Offset(0.0, 40.0), + itemBuilder: (BuildContext context) { + final choices = ['Ubah Informasi']; + return choices.map((String choice) { + return PopupMenuItem( + key: Key(choice), + child: RaisedButton( + padding: EdgeInsets.zero, + color: Colors.white, + elevation: 0, + onPressed: _updateInformasi, + child: SizedBox( + width: double.infinity, + child: Text(choice), + ), + ), + ); + }).toList(); + }, + ), + ], ), ), Container( - key: Key('Text Jumlah'), + key: const Key('Text Jumlah'), width: MediaQuery.of(context).size.width, color: red, - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( vertical: regularSpace, horizontal: doubleSpace), child: Text( - 'Tersedia sebanyak ${widget.komentar.jumlah} unit fasilitas.', - style: TextStyle( + 'Tersedia sebanyak ${widget.komentar.jumlah} ' + 'unit fasilitas.', + style: const TextStyle( fontSize: 16, color: Colors.white, fontFamily: 'Comfortaa', ), )), Container( - margin: EdgeInsets.all(doubleSpace), + margin: const EdgeInsets.all(doubleSpace), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ SizedBox( - height: 200, + height: 150, child: ImageHolder(url: widget.komentar.image)), - SizedBox( + const SizedBox( height: 10, ), // Wrap( @@ -108,7 +154,7 @@ class _DetailPostPageState extends State<DetailPostPage> { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ - Text( + const Text( 'Dapat digunakan oleh', style: TextStyle(fontSize: 16), textAlign: TextAlign.left, @@ -125,114 +171,90 @@ class _DetailPostPageState extends State<DetailPostPage> { ], ), Container( - key: Key('desc'), + key: const Key('desc'), decoration: BoxDecoration( - color: Colors.white, + color: gray, boxShadow: regularShadow, - border: Border.all(color: greenPale), borderRadius: regularBorderRadius), - padding: EdgeInsets.all(doubleSpace), - margin: EdgeInsets.symmetric(vertical: regularSpace), + padding: const EdgeInsets.all(doubleSpace), + margin: + const EdgeInsets.symmetric(vertical: doubleSpace), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Row( children: <Widget>[ - Expanded( + const Expanded( child: Text( - 'Informasi', + 'Cara menggunakan', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w800), ), ), - // Expanded( - // child: ButtonTheme( - // height: 15, - // minWidth: 10, - // child: RaisedButton( - // child: Text('Ubah Informasi', - // style: TextStyle(fontSize: 15)), - // onPressed: updateInformasi, - // padding: EdgeInsets.symmetric( - // vertical: 5, - // horizontal: 5, - // ), - // color: Colors.white, - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.all( - // Radius.circular(10)), - // side: BorderSide( - // color: Color(0xff3A903A))), - // ), - // ), - // ), ], ), Container( - margin: - EdgeInsets.symmetric(vertical: regularSpace), + margin: const EdgeInsets.symmetric( + vertical: regularSpace), child: Text( widget.komentar.deskripsi, - style: TextStyle(fontSize: 18), + key: const Key('Text Cara Menggunakan'), + style: const TextStyle(fontSize: 16), ), ), - Container( - margin: - EdgeInsets.symmetric(vertical: regularSpace), - child: Text( - 'Diposting oleh', - style: TextStyle(fontSize: 18), - ), + ], + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + const Text( + 'informasi ditambahkan oleh ', + style: TextStyle( + fontSize: 12, + fontStyle: FontStyle.italic, + fontWeight: FontWeight.w200, ), - Text( - '${widget.komentar.creator}', - style: TextStyle(fontSize: 18), + ), + Container( + padding: EdgeInsets.zero, + constraints: BoxConstraints( + maxWidth: + MediaQuery.of(context).size.width * 0.3), + child: Text( + '${widget.komentar.creator} ', key: Key('creator-${widget.komentar.creator}'), + overflow: TextOverflow.fade, + softWrap: false, + style: const TextStyle( + fontSize: 12, + fontStyle: FontStyle.italic, + ), ), - Text( - '${DateFormat('dd MMMM yyy hh:mm').format(widget.komentar.dateTime)}', - style: - TextStyle(color: grayPrimary, fontSize: 16), - key: Key('timestamp'), + ), + Text( + '(${DateFormat('dd MMM yyy').format(widget.komentar.dateTime)})', + key: const Key('timestamp'), + style: const TextStyle( + fontSize: 12, + fontStyle: FontStyle.italic, ), - ], - ), + ), + ], + ), + const SizedBox( + height: regularSpace, + ), + const Divider( + color: grayPrimary, + thickness: 1.0, ), - // Container( - // key: Key('rating'), - // decoration: BoxDecoration( - // color: Colors.white, - // boxShadow: regularShadow, - // border: Border.all(color: greenPale), - // borderRadius: regularBorderRadius), - // padding: EdgeInsets.all(doubleSpace), - // child: Column( - // children: <Widget>[ - // Text( - // 'Rating', - // style: TextStyle( - // fontWeight: FontWeight.w800, - // ), - // ), - // Row( - // children: <Widget>[ - // Text('${widget.komentar.rating}/5'), - // ...List<Widget>.generate( - // widget.komentar.rating, - // (number) => Icon( - // Icons.star, - // color: Colors.yellow, - // )) - // ], - // ) - // ], - // ), - // ), Container( - key: Key('Komentar'), - padding: EdgeInsets.symmetric(vertical: regularSpace), - child: Text( + key: const Key('Komentar'), + padding: const EdgeInsets.symmetric( + vertical: regularSpace), + child: const Text( 'Komentar', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w800), @@ -243,7 +265,7 @@ class _DetailPostPageState extends State<DetailPostPage> { if (snapshot.hasData) { switch (snapshot.data.status) { case Status.loading: - return Center( + return const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation<Color>( greenPrimary), @@ -254,7 +276,7 @@ class _DetailPostPageState extends State<DetailPostPage> { allKomentarPostingFromApi = snapshot.data.data.allKomentar; if (allKomentarPostingFromApi.isEmpty) { - return Center( + return const Center( child: Text('Tidak ada Komentar')); } else { return Column( @@ -274,35 +296,87 @@ class _DetailPostPageState extends State<DetailPostPage> { } return Container(); }), - Container( - key: Key('tambah komentar'), - padding: EdgeInsets.only(top: doubleSpace), - alignment: Alignment.center, - child: ButtonTheme( - minWidth: double.infinity, - height: 40, - child: RaisedButton( - padding: EdgeInsets.symmetric(vertical: 15), - highlightElevation: 0.0, - splashColor: greenPrimary, - highlightColor: Colors.white, - elevation: 0.0, - color: greenPrimary, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.all(Radius.circular(10)), - ), - child: Text( - 'Tambah Komentar', - style: TextStyle( - fontSize: 20, - color: Colors.white, - fontWeight: FontWeight.bold), + const SizedBox(height: regularSpace), + Form( + key: _formKey, + child: Column( + children: <Widget>[ + TextFormField( + key: const Key('Text Field Komentar'), + keyboardType: TextInputType.multiline, + maxLines: null, + minLines: 3, + validator: FieldValidator.validateInfo, + controller: komentarController, + style: const TextStyle( + fontSize: 18, + ), + decoration: InputDecoration( + hintStyle: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 15), + hintText: 'Tulis komentar...', + 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, + ), + ), + ), ), - onPressed: () { - checkLoginStatus(); - }, - ), + Container( + key: const Key('tambah komentar'), + padding: + const EdgeInsets.only(top: doubleSpace), + alignment: Alignment.center, + child: ButtonTheme( + minWidth: double.infinity, + height: 40, + child: RaisedButton( + key: const Key('Button Tambah Komentar'), + padding: const EdgeInsets.symmetric( + vertical: 13), + highlightElevation: 0.0, + splashColor: greenPrimary, + highlightColor: Colors.white, + elevation: 0.0, + color: greenPrimary, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(10)), + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + const Icon( + Icons.add, + size: 30, + color: Colors.white, + ), + const SizedBox(width: 5.0), + const Text( + 'Tambah Komentar', + style: TextStyle( + fontSize: 20, + color: Colors.white, + fontWeight: FontWeight.bold), + ), + ], + ), + onPressed: () { + _checkLoginStatus(); + }, + ), + )), + ], )), ], ), @@ -318,39 +392,72 @@ class _DetailPostPageState extends State<DetailPostPage> { )))); } - // Widget _createTagContainer(String tag) { - // return Container( - // key: Key('tag-$tag'), - // padding: EdgeInsets.all(smallSpace), - // margin: EdgeInsets.all(smallSpace), - // decoration: BoxDecoration( - // color: Colors.white, - // borderRadius: regularBorderRadius, - // border: Border.all(color: greenPale), - // boxShadow: regularShadow), - // child: Text( - // '#$tag', - // style: TextStyle( - // fontWeight: FontWeight.w800, fontSize: 16, color: greenPrimary), - // ), - // ); - // } - - void checkLoginStatus() async { + Future<void> _checkLoginStatus() async { final sharedPreferences = await SharedPreferences.getInstance(); if (sharedPreferences.getString('token') == null) { await Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (BuildContext context) => Login()), (Route<dynamic> route) => false); } else { - await Navigator.of(context).push(MaterialPageRoute( - builder: (BuildContext context) => AddKomentar(widget.komentar))); + await _validateKomentarInput(); + } + } + + Future<void> _validateKomentarInput() async { + final form = _formKey.currentState; + if (_formKey.currentState.validate()) { + form.save(); + await _submitKomentar(komentarController.text); + } + } + + Future<void> _submitKomentar(String komentar) async { + final _namaLokasi = widget.komentar.namaLokasi.replaceAll(' ', '%20'); + newKomentarPostingData['deskripsi'] = komentar; + newKomentarPostingData['namaLokasi'] = _namaLokasi; + newKomentarPostingData['id'] = widget.komentar.id; + + _bloc = KomentarPostingBloc(_namaLokasi, widget.komentar.id); + final response = await _bloc.addKomentarPosting( + newKomentarPostingData, _namaLokasi, widget.komentar.id); + if (response['response'] == 'komentar added') { + successDialog(context); + Timer(const Duration(seconds: 2), () { + Navigator.pop(context); + }); await _bloc.fetchKomentarPostingList( widget.komentar.namaLokasi, widget.komentar.id); + komentarController.clear(); + } else { + failedDialog(context); } } - Widget komentarPlaceHolder(String nama, DateTime date, String description) { + void successDialog(BuildContext context) { + const alertDialog = AlertDialog( + title: Text('Tambah komentar berhasil'), + content: Icon(FontAwesomeIcons.checkCircle), + ); + showDialog( + context: context, + builder: (BuildContext context) { + return alertDialog; + }); + } + + void failedDialog(BuildContext context) { + const alertDialog = AlertDialog( + title: Text('Gagal menambahkan komentar'), + content: Icon(FontAwesomeIcons.exclamationCircle), + ); + showDialog( + context: context, + builder: (BuildContext context) { + return alertDialog; + }); + } + + Widget komentarPlaceHolder(String name, DateTime date, String description) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ @@ -358,7 +465,12 @@ class _DetailPostPageState extends State<DetailPostPage> { children: <Widget>[ CircleAvatar( backgroundColor: greenPrimary, - child: Text('Test'), + child: Text( + _creatorInitials(name), + style: const TextStyle( + color: Colors.white, + ), + ), ), Padding( padding: const EdgeInsets.all(regularSpace), @@ -366,26 +478,38 @@ class _DetailPostPageState extends State<DetailPostPage> { crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( - nama, - style: TextStyle(fontSize: 18), + name, + style: const TextStyle(fontSize: 18), ), Text('${DateFormat('dd MMMM yyy hh:mm').format(date)}', - style: TextStyle(color: grayPrimary, fontSize: 16)) + style: const TextStyle(color: grayPrimary, fontSize: 14)) ], ), ) ], ), Container( - margin: EdgeInsets.only(bottom: regularSpace), - child: Text(description)), - Divider( + margin: const EdgeInsets.only(bottom: regularSpace, left: 13.0), + child: Text( + description, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + )), + const Divider( color: grayPrimary, + thickness: 1.0, ) ], ); } + String _creatorInitials(String name) { + var initials = ''; + for (final i in name.split(' ')) { + initials += '${i[0].toUpperCase()}'; + } + return initials; + } + Widget _showIfContains(String disabilitas) { String imageUrl; switch (disabilitas) { @@ -405,27 +529,34 @@ class _DetailPostPageState extends State<DetailPostPage> { imageUrl = 'assets/images/DS_I.png'; break; } - return widget.komentar.disabilitas.toList().contains(disabilitas) - ? Image.asset( - imageUrl, - height: 40, - key: Key('Icon $disabilitas'), + return widget.komentar.disabilitas.toString().contains(disabilitas) + ? Row( + children: [ + const SizedBox( + width: regularSpace, + ), + Image.asset( + imageUrl, + height: 40, + key: Key('Icon $disabilitas'), + ), + ], ) - : SizedBox(width: 0); + : const SizedBox(width: 0); } - // void updateInformasi() async { - // final sharedPreferences = await SharedPreferences.getInstance(); - // if (sharedPreferences.getString('token') == null) { - // await Navigator.of(context).pushAndRemoveUntil( - // MaterialPageRoute(builder: (BuildContext context) => Login()), - // (Route<dynamic> route) => false); - // } else { - // await Navigator.of(context).push(MaterialPageRoute( - // builder: (BuildContext context) => - // UpdateInformasi(komentar: widget.komentar))); - // } - // } + Future<void> _updateInformasi() async { + final sharedPreferences = await SharedPreferences.getInstance(); + if (sharedPreferences.getString('token') == null) { + await Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (BuildContext context) => Login()), + (Route<dynamic> route) => false); + } else { + await Navigator.of(context).push(MaterialPageRoute( + builder: (BuildContext context) => UpdateInformasi( + komentar: widget.komentar, lokasi: widget.lokasi))); + } + } @override void dispose() { diff --git a/lib/page/login/login.dart b/lib/page/login/login.dart index e0d60161a465d641251e66700545a625c9261d90..c3b94cc326c49cf5d9d9b6df0c5f544f142e942a 100644 --- a/lib/page/login/login.dart +++ b/lib/page/login/login.dart @@ -219,7 +219,7 @@ class LoginState extends State<Login> { final response = _userBloc.userFromApi.first; if (response.disabilitas == '-') { newUser = NewUser( - name: '', + name: response.name, password: '', email: emailController.text.toString(), phoneNumber: response.phoneNumber, @@ -323,7 +323,7 @@ class LoginState extends State<Login> { void failedDialog(BuildContext context) { var alertDialog = AlertDialog( - title: Text('Email atau Password anda salah'), + title: const Text('Email atau Password anda salah'), content: Icon(FontAwesomeIcons.exclamationCircle), ); showDialog( diff --git a/lib/page/pencarian/pencarian.dart b/lib/page/pencarian/pencarian.dart index 6ee10cf3528a298e3adb1570c0c164f5aba6f9e0..63b8390f574f441812465acfc1581ca0e371b8ea 100644 --- a/lib/page/pencarian/pencarian.dart +++ b/lib/page/pencarian/pencarian.dart @@ -1,3 +1,4 @@ +import 'package:bisaGo/page/dashboard/dashboard.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:bisaGo/page/addLokasi/add_lokasi.dart'; @@ -14,7 +15,7 @@ class Pencarian extends StatefulWidget { PencarianState createState() => PencarianState(); } -/// State of Pencacrian page +/// State of Pencarian page class PencarianState extends State<Pencarian> { /// Controller for textFormField TextEditingController myController = TextEditingController(); @@ -79,7 +80,8 @@ class PencarianState extends State<Pencarian> { leading: IconButton( icon: Icon(Icons.arrow_back_ios, size: 25), key: Key('Back Icon Key'), - onPressed: () => Navigator.pop(context, 'Take me back')), + onPressed: () => Navigator.of(context) + .push(MaterialPageRoute(builder: (_) => Dashboard()))), title: Container( margin: EdgeInsets.only(top: doubleSpace, bottom: doubleSpace), decoration: BoxDecoration( @@ -99,7 +101,7 @@ class PencarianState extends State<Pencarian> { ), border: InputBorder.none, fillColor: Colors.white, - labelText: 'Kamu mau kemana?', + labelText: 'Tekan untuk mencari tempat', labelStyle: TextStyle( color: greenPrimary, fontSize: 18, @@ -208,7 +210,7 @@ class PencarianState extends State<Pencarian> { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (BuildContext context) => - AddLokasi())); + const AddLokasi())); }, child: Text( 'Tambah Lokasi', diff --git a/lib/page/profile/edit_profile.dart b/lib/page/profile/edit_profile.dart index e13afea4cc5458e5a564f11378eaa742e403424d..3c97b4473fa4c506bf64ad7dee04d818655f7faf 100644 --- a/lib/page/profile/edit_profile.dart +++ b/lib/page/profile/edit_profile.dart @@ -105,7 +105,7 @@ class _EditProfileState extends State<EditProfile> { padding: EdgeInsets.only(top: doubleSpace), child: Text( 'Halo, ${name.split(' ')[0]}!', - style: TextStyle( + style: const TextStyle( fontSize: 26, fontWeight: FontWeight.w900, color: Colors.black, diff --git a/lib/page/registrasi/registrasi.dart b/lib/page/registrasi/registrasi.dart index b29c7cccc67ac54169bd498fa4062c19e30d85ce..e4441bbc92bcf7e95d8c59ed89ca29cf93a9bdf6 100644 --- a/lib/page/registrasi/registrasi.dart +++ b/lib/page/registrasi/registrasi.dart @@ -149,7 +149,7 @@ class RegistrasiState extends State<Registrasi> { key: Key('Button Tanggal Lahir'), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0)), - padding: EdgeInsets.all(9.0), + padding: const EdgeInsets.all(9.0), onPressed: () { DatePicker.showDatePicker(context, maxTime: DateTime.now(), onChanged: (date) { @@ -161,7 +161,8 @@ class RegistrasiState extends State<Registrasi> { }, child: Text( tanggalLahir, - style: TextStyle(fontSize: 12.0, color: Colors.white), + style: const TextStyle( + fontSize: 12.0, color: Colors.white), ), color: greenPrimary, ), @@ -203,8 +204,8 @@ class RegistrasiState extends State<Registrasi> { return null; }, ), - SizedBox(height: doubleSpace), - Text( + const SizedBox(height: doubleSpace), + const Text( '*Wajib', textAlign: TextAlign.center, style: TextStyle( diff --git a/lib/page/registrasi_penyandang_disabilitas/registrasi_informasi_layanan_disabilitas.dart b/lib/page/registrasi_penyandang_disabilitas/registrasi_informasi_layanan_disabilitas.dart index 341a12816266a9eb1c100ce17d5685f9a990dda3..58d1e13e7ea23d81975bd48dce86326b3d91291d 100644 --- a/lib/page/registrasi_penyandang_disabilitas/registrasi_informasi_layanan_disabilitas.dart +++ b/lib/page/registrasi_penyandang_disabilitas/registrasi_informasi_layanan_disabilitas.dart @@ -11,7 +11,7 @@ import 'package:bisaGo/utils/validator.dart'; import 'package:bisaGo/network/network_interface.dart'; class RegistrasiInformasiLayananDisabilitas extends StatefulWidget { - RegistrasiInformasiLayananDisabilitas({Key key}) : super(key: key); + const RegistrasiInformasiLayananDisabilitas({Key key}) : super(key: key); @override _RegistrasiInformasiLayananDisabilitasState createState() => _RegistrasiInformasiLayananDisabilitasState(); diff --git a/lib/page/updateInformasi/update_informasi.dart b/lib/page/updateInformasi/update_informasi.dart index f5d1a49f82e8b19cd99641182e12def1a49c09d5..2297fa93f5e9e3348491fc2faec5059fd9254fad 100644 --- a/lib/page/updateInformasi/update_informasi.dart +++ b/lib/page/updateInformasi/update_informasi.dart @@ -1,76 +1,60 @@ +import 'dart:async'; import 'dart:io'; -import 'package:http/http.dart' as http; +import 'package:bisaGo/bloc/komentar_bloc.dart'; +import 'package:bisaGo/component/image_holder.dart'; +import 'package:bisaGo/config/strings.dart'; +import 'package:bisaGo/config/styles.dart'; +import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart'; +import 'package:bisaGo/utils/custom_alert_dialog.dart'; +import 'package:bisaGo/utils/custom_disabilitas_button.dart'; +import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/utils/custom_deskripsi_field.dart'; import 'package:bisaGo/utils/custom_button.dart'; import 'package:bisaGo/utils/validator.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:smooth_star_rating/smooth_star_rating.dart'; +import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:image_picker/image_picker.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:bisaGo/flavor/flavor.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class UpdateInformasi extends StatefulWidget { final KomentarModel komentar; + final Lokasi lokasi; @override UpdateInformasiState createState() => UpdateInformasiState(); - const UpdateInformasi({this.komentar, Key key}) : super(key: key); + const UpdateInformasi({this.komentar, this.lokasi, Key key}) + : super(key: key); } class UpdateInformasiState extends State<UpdateInformasi> { - var rating = 0.0; - var tag = ''; + Map<String, dynamic> newKomentarData = {}; + KomentarBloc _bloc; TextEditingController deskripsiController = TextEditingController(); + File _image; + String _existingImageUrl = ''; + final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final picker = ImagePicker(); + @override void initState() { super.initState(); deskripsiController = TextEditingController(text: widget.komentar.deskripsi); + _jumlahFasilitas = widget.komentar.jumlah; + _fisikClicked = widget.komentar.disabilitas.toString().contains('DF'); + _intelektualClicked = widget.komentar.disabilitas.toString().contains('DI'); + _mentalClicked = widget.komentar.disabilitas.toString().contains('DM'); + _sensorikClicked = widget.komentar.disabilitas.toString().contains('DS'); + _isDisabilitasValid = true; + _existingImageUrl = widget.komentar.image; } - File _image; - final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); - Map<String, bool> fasilitas = { - 'Kursi Roda': false, - 'Lift Disabilitas': false, - 'Toilet Disabilitas': false, - 'Masjid/Mushola': false, - 'Guiding Block': false, - 'Bidang Miring': false, - 'Teman Disabilitas': false, - 'Juru Bahasa Isyarat': false, - 'Tongkat Disabilitas Netra': false, - 'Kursi Umum Disabilitas': false, - 'Tempat Parkir Disabilitas': false, - 'Running Text': false, - 'Tempat Parkir Biasa': false, - }; - - Map<String, String> tags = { - 'Kursi Roda': 'KD', - 'Lift Disabilitas': 'LF', - 'Toilet Disabilitas': 'TD', - 'Masjid/Mushola': 'MM', - 'Guiding Block': 'GB', - 'Bidang Miring': 'BM', - 'Teman Disabilitas': 'CP', - 'Juru Bahasa Isyarat': 'JI', - 'Tongkat Disabilitas Netra': 'TN', - 'Kursi Umum Disabilitas': 'KD', - 'Tempat Parkir Disabilitas': 'PK', - 'Running Text': 'RT', - 'Tempat Parkir Biasa': 'TB', - }; - Future _getImage() async { final image = await picker.getImage(source: ImageSource.gallery); - - setState(() { - _image = File(image.path); - }); + return _image = File(image.path); } Future _clearImage() async { @@ -79,13 +63,6 @@ class UpdateInformasiState extends State<UpdateInformasi> { }); } - Future _clearCheckBox() async { - fasilitas.forEach((k, v) { - final key = k; - fasilitas[key] = false; - }); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -103,86 +80,254 @@ class UpdateInformasiState extends State<UpdateInformasi> { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ - const SizedBox(height: 20), + const SizedBox(height: doubleSpace), + Text( + widget.komentar.namaLokasi, + key: const Key('Text Location Name'), + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.w800, + color: Colors.black, + fontFamily: 'Comfortaa', + ), + ), + const SizedBox(height: doubleSpace), + // const Text( + // 'Foto Fasilitas', + // style: TextStyle(fontSize: 18), + // textAlign: TextAlign.left, + // ), + // GridView.count( + // key: const Key('Input Gambar'), + // shrinkWrap: true, + // primary: false, + // padding: const EdgeInsets.all(10), + // crossAxisSpacing: 10, + // crossAxisCount: 2, + // children: <Widget>[ + // GestureDetector( + // onTap: _getImage, + // child: Container( + // padding: const EdgeInsets.symmetric( + // horizontal: 20.0, vertical: 2.0), + // decoration: const BoxDecoration( + // borderRadius: BorderRadius.only( + // topLeft: Radius.circular(20.0), + // topRight: Radius.circular(20.0), + // bottomLeft: Radius.circular(20.0), + // bottomRight: Radius.circular(20.0), + // ), + // color: Colors.black12, + // ), + // child: _image == null + // ? const Icon(FontAwesomeIcons.plus) + // : Image.file(_image), + // ), + // ) + // ], + // ), const Text( - 'Foto Fasilitas', + 'Jenis fasilitas / layanan', style: TextStyle(fontSize: 18), textAlign: TextAlign.left, ), - GridView.count( - key: const Key('Input Gambar'), - shrinkWrap: true, - primary: false, - padding: const EdgeInsets.all(10), - crossAxisSpacing: 10, - crossAxisCount: 2, - children: <Widget>[ - GestureDetector( - onTap: _getImage, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 20.0, vertical: 2.0), - decoration: const BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20.0), - topRight: Radius.circular(20.0), - bottomLeft: Radius.circular(20.0), - bottomRight: Radius.circular(20.0), - ), - color: Colors.black12, - ), - child: _image == null - ? const Icon(FontAwesomeIcons.plus) - : Image.file(_image), + const SizedBox(height: 10), + Container( + key: const Key('Text Jenis Fasilitas Layanan'), + padding: const EdgeInsets.all(8.0), + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + color: white, + borderRadius: BorderRadius.circular(10.0), + border: Border.all(color: greenPrimary, width: 2.0), + ), + child: Text( + fasilitas[widget.komentar.tag], + style: const TextStyle( + fontSize: 15, + color: grayPrimary, + ), + textAlign: TextAlign.left, + ), + ), + const SizedBox(height: 10), + const Text( + 'Jumlah fasilitas / layanan', + style: TextStyle(fontSize: 18), + textAlign: TextAlign.left, + ), + const SizedBox(height: regularSpace), + Row( + children: [ + iconButton( + const Key('Button Decrement'), + const Icon(MdiIcons.minus, + color: Colors.black, size: 18), + _decrementCount, + 30, + 30), + const SizedBox(width: regularSpace), + Container( + key: const Key('Counter Fasilitas Layanan'), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + boxShadow: regularShadow, + borderRadius: BorderRadius.circular(5.0), + border: Border.all(color: greenPrimary)), + height: 30, + width: 45, + child: Text( + _jumlahFasilitas.toString(), + style: const TextStyle(fontSize: 18.0), ), - ) + ), + const SizedBox(width: regularSpace), + iconButton( + const Key('Button Increment'), + const Icon(MdiIcons.plus, + color: Colors.black, size: 18), + _incrementCount, + 30, + 30), ], ), + const SizedBox(height: 10), CustomDeskripsiField( - title: 'Informasi Fasilitas', + title: 'Cara menggunakan', key: const Key('Text Field Informasi'), - onSaved: (input) {}, validator: FieldValidator.validateInfo, controller: deskripsiController, ), - const SizedBox(height: 20), - const Text( - 'Tag Pencarian', - style: TextStyle(fontSize: 18), - textAlign: TextAlign.left, - ), - ListView( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - key: const Key('Checkbox Fasilitas'), - children: fasilitas.keys.map((String key) { - return CheckboxListTile( - title: Text(key), - value: fasilitas[key], - onChanged: (bool value) { + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Foto', + style: TextStyle(fontSize: 18), + textAlign: TextAlign.left, + ), + FlatButton( + key: const Key('Button Input Foto'), + padding: EdgeInsets.zero, + onPressed: () async { + final imageSelected = await _getImage(); setState(() { - fasilitas[key] = value; + _image = imageSelected; }); }, - ); - }).toList(), + child: Container( + width: MediaQuery.of(context).size.width * 0.45, + 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( + 'Pilih foto', + style: TextStyle( + color: Colors.white, fontSize: 14.0), + ), + ], + ), + ), + ) + ], ), - const SizedBox(height: 20), - Container( - alignment: Alignment.center, - key: const Key('Star Rating'), - child: SmoothStarRating( - allowHalfRating: false, - onRated: (v) { - rating = v; - setState(() {}); - }, - rating: rating, - size: 40.0, - color: Colors.green, - borderColor: Colors.green, - ), + if (_existingImageUrl == '/media/') + _showImagePreview() + else + _showExistingImage(), + const SizedBox(height: 10), + const Text( + 'Jenis Disabilitas', + style: TextStyle(fontSize: 18), + textAlign: TextAlign.left, ), + FieldValidator.validateCustomFieldAlert(_isDisabilitasValid), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + DisabilitasIconButton( + key: const Key('Button Disabilitas Fisik'), + disabilitas: 'Disabilitas Fisik', + imageUrl: _fisikClicked + ? 'assets/images/DF.png' + : 'assets/images/DF_F.png', + textColor: _fisikClicked ? Colors.white : Colors.black, + buttonColor: _fisikClicked ? blue : Colors.white, + borderColor: _fisikClicked ? blue : Colors.grey, + onPressed: () { + setState(() { + _fisikClicked = !_fisikClicked; + }); + }, + ), + DisabilitasIconButton( + key: const Key('Button Disabilitas Intelektual'), + disabilitas: 'Disabilitas Intelektual', + imageUrl: _intelektualClicked + ? 'assets/images/DI.png' + : 'assets/images/DI_F.png', + textColor: + _intelektualClicked ? Colors.white : Colors.black, + buttonColor: + _intelektualClicked ? purple : Colors.white, + borderColor: _intelektualClicked ? purple : Colors.grey, + onPressed: () { + setState(() { + _intelektualClicked = !_intelektualClicked; + }); + }, + ), + ]), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + DisabilitasIconButton( + key: const Key('Button Disabilitas Mental'), + disabilitas: 'Disabilitas Mental', + imageUrl: _mentalClicked + ? 'assets/images/DM.png' + : 'assets/images/DM_F.png', + textColor: _mentalClicked ? Colors.white : Colors.black, + buttonColor: _mentalClicked ? greenDM : Colors.white, + borderColor: _mentalClicked ? greenDM : Colors.grey, + onPressed: () { + setState(() { + _mentalClicked = !_mentalClicked; + }); + }, + ), + DisabilitasIconButton( + key: const Key('Button Disabilitas Sensorik'), + disabilitas: 'Disabilitas Sensorik', + imageUrl: _sensorikClicked + ? 'assets/images/DS.png' + : 'assets/images/DS_F.png', + textColor: + _sensorikClicked ? Colors.white : Colors.black, + buttonColor: _sensorikClicked ? red : Colors.white, + borderColor: _sensorikClicked ? red : Colors.grey, + onPressed: () { + setState(() { + _sensorikClicked = !_sensorikClicked; + }); + }, + ) + ]), Container( margin: const EdgeInsets.fromLTRB(0, 30, 0, 10), alignment: Alignment.center, @@ -190,7 +335,7 @@ class UpdateInformasiState extends State<UpdateInformasi> { children: <Widget>[ Expanded( child: ButtonTheme( - key: const Key('Batal Button'), + key: const Key('Button Batal'), minWidth: double.infinity, height: 40, child: RaisedButton( @@ -213,6 +358,7 @@ class UpdateInformasiState extends State<UpdateInformasi> { ), onPressed: () { _resetInput(); + Navigator.of(context).pop(); }), ), ), @@ -221,7 +367,7 @@ class UpdateInformasiState extends State<UpdateInformasi> { ), Expanded( child: ButtonTheme( - key: const Key('Simpan Button'), + key: const Key('Button Simpan'), minWidth: double.infinity, height: 40, child: @@ -231,43 +377,82 @@ class UpdateInformasiState extends State<UpdateInformasi> { ], ), ), + const SizedBox(height: doubleSpace), ], ), ), ))); } - void addInfo(String tag, String deskripsi, String rating) async { - for (var me in fasilitas.entries) { - if (me.value == true) { - tag = '$tag ${tags[me.key]} '; - } - } - final data = { - 'tag': tag, - 'deskripsi': deskripsi, - }; + int _jumlahFasilitas; + bool _fisikClicked; + bool _intelektualClicked; + bool _mentalClicked; + bool _sensorikClicked; + bool _isDisabilitasValid; + String _disabilitas = ''; + void _showConfirmationPopUp() { + showDialog( + context: context, + builder: (BuildContext context) { + return CustomAlertDialog( + key: const Key('Pop Up Konfirmasi'), + title: + 'Apakah kamu sudah yakin informasi yang diberikan sudah benar?', + leftText: 'Tidak', + leftIcon: MdiIcons.close, + leftFunction: () { + Navigator.of(context).pop(true); + _resetInput(); + }, + rightText: 'Ya', + rightIcon: MdiIcons.check, + rightFunction: () async { + Navigator.of(context).pop(true); + await submitInfo(); + }, + ); + }); + } + + Future<void> submitInfo() async { final sharedPreferences = await SharedPreferences.getInstance(); + _bloc = KomentarBloc(widget.komentar.namaLokasi); - final namaTempat = widget.komentar.namaLokasi.replaceAll(' ', '%20'); - final idFasilitas = widget.komentar.id; - final response = await http.put( - '${ApiFlavor.getBaseUrl()}/informasi-fasilitas/lokasi/update-fasilitas/$namaTempat/$idFasilitas/', - headers: { - 'Authorization': 'token ${sharedPreferences.getString('token')}' - }, - body: data); + final namaLokasi = widget.komentar.namaLokasi.replaceAll(' ', '%20'); + final response = await _bloc.updateKomentar(newKomentarData, namaLokasi, + widget.komentar.id, 'token ${sharedPreferences.getString('token')}'); if (response.statusCode == 201 || response.statusCode == 202) { - inputData(context); + final newKomentar = KomentarModel( + id: widget.komentar.id, + namaLokasi: widget.komentar.namaLokasi, + deskripsi: newKomentarData['deskripsi'], + creator: widget.komentar.creator, + dateTime: widget.komentar.dateTime, + tag: widget.komentar.tag, + disabilitas: newKomentarData['disabilitas'].split(' '), + isVerified: widget.komentar.isVerified, + jumlah: newKomentarData['jumlah'], + rating: widget.komentar.rating, + image: newKomentarData['image']); + final route = MaterialPageRoute( + builder: (_) => + DetailPostPage(komentar: newKomentar, lokasi: widget.lokasi)); + successDialog(context); + Timer(const Duration(seconds: 2), () { + Navigator.of(context).pop(Navigator.pop(context)); + Navigator.pop(context); + Navigator.of(context).push(route); + }); } else { - gagalInputData(context); + failedDialog(context); } } - void inputData(BuildContext context) { + void successDialog(BuildContext context) { const alertDialog = AlertDialog( - title: Text('Update Informasi berhasil'), + title: Text('Update informasi berhasil'), content: Icon(FontAwesomeIcons.checkCircle), ); showDialog( @@ -277,10 +462,10 @@ class UpdateInformasiState extends State<UpdateInformasi> { }); } - void gagalInputData(BuildContext context) { + void failedDialog(BuildContext context) { const alertDialog = AlertDialog( - title: - Text('Update informasi gagal, pastikan ini adalah info buatan anda'), + title: Text('Gagal menambahkan informasi'), + content: Icon(FontAwesomeIcons.checkCircle), ); showDialog( context: context, @@ -289,20 +474,161 @@ class UpdateInformasiState extends State<UpdateInformasi> { }); } - void _validateInformationInput() async { + Future<void> _validateInformationInput() async { final form = _formKey.currentState; - if (_formKey.currentState.validate()) { + if (_validatePilihDisabilitas() && _formKey.currentState.validate()) { form.save(); - final ratingInt = rating.toInt(); - await addInfo( - tag, deskripsiController.text.toString(), ratingInt.toString()); + await _setKomentarData(); + _showConfirmationPopUp(); + } + } + + Future<void> _setKomentarData() async { + newKomentarData['deskripsi'] = deskripsiController.text.toString(); + _setJenisDisabilitas(); + newKomentarData['disabilitas'] = _disabilitas; + newKomentarData['jumlah'] = _jumlahFasilitas; + newKomentarData['image'] = ''; + if (_image != null) { + final fileName = _image.path.split('/').last; + newKomentarData['image'] = await MultipartFile.fromFile( + _image.path, + filename: fileName, + ); + } + } + + void _setJenisDisabilitas() { + _disabilitas = ''; + if (_fisikClicked == true && !_disabilitas.contains('DF')) { + _disabilitas += 'DF '; + } + if (_intelektualClicked == true && !_disabilitas.contains('DI')) { + _disabilitas += 'DI '; + } + if (_mentalClicked == true && !_disabilitas.contains('DM')) { + _disabilitas += 'DM '; + } + if (_sensorikClicked == true && !_disabilitas.contains('DS')) { + _disabilitas += 'DS '; + } + } + + bool _validatePilihDisabilitas() { + if (_fisikClicked || + _intelektualClicked || + _mentalClicked || + _sensorikClicked) { + setState(() { + _isDisabilitasValid = true; + }); + return true; + } else { + setState(() { + _isDisabilitasValid = false; + }); + return false; } } - void _resetInput() async { + Widget _showImagePreview() { + return _image == null + ? const SizedBox(height: 0) + : Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const SizedBox(height: doubleSpace), + Container( + padding: + const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20.0), + topRight: Radius.circular(20.0), + bottomLeft: Radius.circular(20.0), + bottomRight: Radius.circular(20.0), + ), + color: Colors.black12, + ), + child: Image.file(_image), + ), + const SizedBox(height: regularSpace), + FlatButton( + key: const Key('Button Hapus Foto'), + padding: EdgeInsets.zero, + onPressed: () async { + setState(() { + _image = null; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.3, + padding: const EdgeInsets.all(9.0), + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + boxShadow: regularShadow, + borderRadius: BorderRadius.circular(10.0), + color: greenPrimary), + child: const Text( + 'Hapus foto', + style: TextStyle(color: Colors.white, fontSize: 14.0), + ), + ), + ), + ], + ); + } + + Widget _showExistingImage() { + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const SizedBox(height: doubleSpace), + SizedBox(height: 200, child: ImageHolder(url: widget.komentar.image)), + const SizedBox(height: regularSpace), + FlatButton( + key: const Key('Button Hapus Foto'), + padding: EdgeInsets.zero, + onPressed: () async { + setState(() { + _existingImageUrl = '/media/'; + _image = null; + }); + }, + child: Container( + width: MediaQuery.of(context).size.width * 0.3, + padding: const EdgeInsets.all(9.0), + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + boxShadow: regularShadow, + borderRadius: BorderRadius.circular(10.0), + color: greenPrimary), + child: const Text( + 'Hapus foto', + style: TextStyle(color: Colors.white, fontSize: 14.0), + ), + ), + ), + ], + ); + } + + Future<void> _resetInput() async { deskripsiController.clear(); - rating = 0.0; await _clearImage(); - await _clearCheckBox(); + } + + void _incrementCount() { + setState(() { + _jumlahFasilitas = _jumlahFasilitas + 1; + }); + } + + void _decrementCount() { + if (_jumlahFasilitas > 1) { + setState(() { + _jumlahFasilitas = _jumlahFasilitas - 1; + }); + } } } diff --git a/lib/repository/komentar_posting_repository.dart b/lib/repository/komentar_posting_repository.dart index 37f58bfa64fa3a68be24509028996e7a36f80931..4bdf3f0fa3b585da2ece24d7e13392dbfbd1864f 100644 --- a/lib/repository/komentar_posting_repository.dart +++ b/lib/repository/komentar_posting_repository.dart @@ -1,9 +1,16 @@ import 'package:bisaGo/model/komentar_posting.dart'; import 'package:bisaGo/network/network_interface.dart'; -class KomentarPostingRepository { +abstract class BaseKomentarPostingRepository { + Future<KomentarPostingList> fetchKomentarPosting(String namaLokasi, int id); + Future<dynamic> createKomentarPosting( + Map<String, dynamic> newKomentarPostingData, String namaLokasi, int id); +} + +class KomentarPostingRepository implements BaseKomentarPostingRepository { final NetworkInterface _network = NetworkInterface(); + @override Future<KomentarPostingList> fetchKomentarPosting( String namaLokasi, int id) async { final nama = namaLokasi.replaceAll(' ', '%20'); @@ -16,4 +23,16 @@ class KomentarPostingRepository { (komentarPosting) => KomentarPostingModel.fromJson(komentarPosting)) .toList()); } + + @override + Future<dynamic> createKomentarPosting( + Map<String, dynamic> newKomentarPostingData, + String namaLokasi, + int id) async { + final response = await _network.post( + url: + '/informasi-fasilitas/lokasi/add-komentar/$namaLokasi/${id.toString()}/', + bodyParams: newKomentarPostingData); + return response; + } } diff --git a/lib/repository/komentar_repository.dart b/lib/repository/komentar_repository.dart index 8e027764da0b2fbaa719cb479def7272d2ef9f8a..4285655a4015d8c09f3ace6f0776fddd0ef2326b 100644 --- a/lib/repository/komentar_repository.dart +++ b/lib/repository/komentar_repository.dart @@ -1,9 +1,19 @@ +import 'dart:convert'; +import 'package:bisaGo/flavor/flavor.dart'; import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/network/network_interface.dart'; +import 'package:http/http.dart' as http; -class KomentarRepository { +abstract class BaseKomentarRepository { + Future<KomentarList> fetchKomentar(String namaLokasi); + Future<dynamic> createKomentar( + Map<String, dynamic> newKomentarData, String namaLokasi); +} + +class KomentarRepository implements BaseKomentarRepository { final NetworkInterface _network = NetworkInterface(); + @override Future<KomentarList> fetchKomentar(String namaLokasi) async { final nama = namaLokasi.replaceAll(' ', '%20'); final url = '/informasi-fasilitas/lokasi/list-fasilitas/$nama'; @@ -14,6 +24,7 @@ class KomentarRepository { .toList()); } + @override Future<dynamic> createKomentar( Map<String, dynamic> newKomentarData, String namaLokasi) async { final response = await _network.post( @@ -22,4 +33,13 @@ class KomentarRepository { ); return response; } + + Future<dynamic> updateKomentar(Map<String, dynamic> newKomentarData, + String namaLokasi, int id, String token) async { + final response = await http.put( + '${ApiFlavor.getBaseUrl()}/informasi-fasilitas/lokasi/update-fasilitas/$namaLokasi/${id.toString()}/', + headers: {'Authorization': token, 'content-type': 'application/json'}, + body: json.encode(newKomentarData)); + return response; + } } diff --git a/lib/repository/lokasi_repository.dart b/lib/repository/lokasi_repository.dart index 9bbcee440e1110d4f27e577a1e49075c1844a566..509b25e122d01e6126d8deda910fa1a9e6cad5e7 100644 --- a/lib/repository/lokasi_repository.dart +++ b/lib/repository/lokasi_repository.dart @@ -1,10 +1,24 @@ +import 'dart:convert'; + +import 'package:bisaGo/flavor/flavor.dart'; import 'package:bisaGo/model/lokasi.dart'; import 'package:bisaGo/network/cookies_interface.dart'; import 'package:bisaGo/network/network_interface.dart'; +import 'package:http/http.dart' as http; + +abstract class BaseLokasiRepository { + Future<LokasiListResponse> fetchLokasi(); + Future<LokasiListResponse> fetchRecentSearch(); + Future<void> saveRecentSearch(Lokasi recentSearch); + Future<dynamic> addNewLokasi(Map<String, dynamic> lokasi); + Future<dynamic> updateLokasi(Lokasi lokasi, String token); +} -class LokasiRepository { +class LokasiRepository implements BaseLokasiRepository { final _network = NetworkInterface(); final _cookie = CookiesInterface(); + + @override Future<LokasiListResponse> fetchLokasi() async { final response = await _network.get( url: '/informasi-fasilitas/lokasi/list/', isLogin: false); @@ -13,20 +27,32 @@ class LokasiRepository { response.map<Lokasi>((lokasi) => Lokasi.fromJson(lokasi)).toList()); } + @override Future<LokasiListResponse> fetchRecentSearch() async { final response = await CookiesInterface().getSearchHistory(); return LokasiListResponse( response.map<Lokasi>((lokasi) => Lokasi.fromJson(lokasi)).toList()); } + @override Future<void> saveRecentSearch(Lokasi recentSearch) async { final searchToMap = recentSearch.toJson(); await _cookie.createSearchHistoryCookie(recentSearch: searchToMap); } + @override Future<dynamic> addNewLokasi(Map<String, dynamic> lokasi) async { final response = await _network.post( url: '/informasi-fasilitas/lokasi/add/', bodyParams: lokasi); return response; } + + @override + Future<dynamic> updateLokasi(Lokasi lokasi, String token) async { + final response = await http.put( + '${ApiFlavor.getBaseUrl()}/informasi-fasilitas/lokasi/update-detail/${lokasi.name}/', + headers: {'Authorization': token, 'content-type': 'application/json'}, + body: json.encode(lokasi)); + return response; + } } diff --git a/lib/utils/custom_dashboard_location_button.dart b/lib/utils/custom_dashboard_location_button.dart new file mode 100644 index 0000000000000000000000000000000000000000..b31c94f45378fc44a506a2ef6ca3b907eb3a0d6e --- /dev/null +++ b/lib/utils/custom_dashboard_location_button.dart @@ -0,0 +1,89 @@ +import 'package:bisaGo/config/styles.dart'; +import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/page/filter_fasilitas/fasilitas.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class LocationIconButton extends StatefulWidget { + const LocationIconButton({ + this.key, + this.location, + this.onPressed, + }) : super(key: key); + final Lokasi location; + + @override + final Key key; + final Function onPressed; + + @override + _LocationIconButtonState createState() => _LocationIconButtonState(); +} + +class _LocationIconButtonState extends State<LocationIconButton> { + void _navigateToDetailLokasiPage(BuildContext context) { + final route = + MaterialPageRoute(builder: (_) => Fasilitas(lokasi: widget.location)); + Navigator.of(context).push(route); + } + + @override + Widget build(BuildContext context) { + return FlatButton( + padding: EdgeInsets.zero, + onPressed: () { + _navigateToDetailLokasiPage(context); + }, + child: Container( + height: 130, + width: 130, + alignment: Alignment.center, + margin: const EdgeInsets.only(right: regularSpace), + decoration: BoxDecoration( + color: white, + borderRadius: BorderRadius.circular(10), + boxShadow: smallShadow, + border: Border.all(color: greenPrimary)), + padding: EdgeInsets.zero, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + Container( + key: Key('Image ${widget.location}'), + height: 60.0, + margin: const EdgeInsets.symmetric(vertical: 15.0), + child: const Icon( + Icons.location_on, + size: 70, + color: darkGreen, + ), + ), + Container( + width: 130, + alignment: Alignment.center, + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(5.0), + topRight: Radius.circular(5.0), + bottomLeft: Radius.circular(10.0), + bottomRight: Radius.circular(10.0)), + color: greenPrimary, + ), + padding: const EdgeInsets.all(regularSpace), + child: Text( + widget.location.name, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + softWrap: false, + style: const TextStyle( + fontSize: 14, + color: white, + fontFamily: 'Comfortaa', + ), + ), + ) + ], + )), + ); + } +} diff --git a/lib/utils/custom_deskripsi_field.dart b/lib/utils/custom_deskripsi_field.dart index 49398cea454c309e7b874edda80decff40594e77..c3ddfebe64f83cacb85b3f410162fd88e13579c3 100644 --- a/lib/utils/custom_deskripsi_field.dart +++ b/lib/utils/custom_deskripsi_field.dart @@ -37,6 +37,7 @@ class CustomDeskripsiField extends StatelessWidget { TextFormField( keyboardType: TextInputType.multiline, maxLines: null, + minLines: 3, onSaved: onSaved, validator: validator, controller: controller, diff --git a/lib/utils/custom_dropdown.dart b/lib/utils/custom_dropdown.dart index 834be2257975dfe40767803fab8d5eab2b84fecf..54e911004f0073987298e94a170afa323c697f42 100644 --- a/lib/utils/custom_dropdown.dart +++ b/lib/utils/custom_dropdown.dart @@ -65,7 +65,7 @@ class _CustomDropdownState extends State<CustomDropdown> { fontFamily: 'Muli'), children: <TextSpan>[ if (widget.required) - TextSpan(text: '*', style: TextStyle(color: red)), + const TextSpan(text: '*', style: TextStyle(color: red)), ], ), ), diff --git a/lib/utils/custom_text_field.dart b/lib/utils/custom_text_field.dart index 874c377b6832ce76bd8d309b0ad8718cb733c08a..66172e9e8c7a8536eb2330f2656b2c45b69a4bf2 100644 --- a/lib/utils/custom_text_field.dart +++ b/lib/utils/custom_text_field.dart @@ -41,7 +41,8 @@ class CustomTextField extends StatelessWidget { style: const TextStyle( fontSize: 18, color: Colors.black, fontFamily: 'Muli'), children: <TextSpan>[ - if (required) TextSpan(text: '*', style: TextStyle(color: red)), + if (required) + const TextSpan(text: '*', style: TextStyle(color: red)), ], ), ), diff --git a/lib/utils/validator.dart b/lib/utils/validator.dart index 2e7aff696a4d217a543e638d653691af4ad03286..db903835f8e2b0302be3ecfdc3838c67a22a3bf2 100644 --- a/lib/utils/validator.dart +++ b/lib/utils/validator.dart @@ -97,7 +97,7 @@ class FieldValidator { static Widget validateCustomFieldAlert(bool value) { return value - ? SizedBox(height: 0) + ? const SizedBox(height: 0) : Padding( padding: const EdgeInsets.only(left: 8.0), child: Text( diff --git a/test/add_informasi_test.dart b/test/add_informasi_test.dart index aa970fe1d2eb94e8ea8f268600fa1e423aee1e98..7c888552bea7eded4968a3f2d62b799feafcc87b 100644 --- a/test/add_informasi_test.dart +++ b/test/add_informasi_test.dart @@ -1,10 +1,128 @@ +import 'package:bisaGo/model/komentar.dart'; +import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/page/add_informasi/add_informasi.dart'; +import 'package:bisaGo/page/filter_fasilitas/fasilitas.dart'; +import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart'; +import 'package:bisaGo/repository/komentar_posting_repository.dart'; +import 'package:bisaGo/repository/komentar_repository.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; +import 'package:bisaGo/utils/custom_alert_dialog.dart'; import 'package:bisaGo/utils/custom_disabilitas_button.dart'; +import 'package:bisaGo/utils/validator.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:bisaGo/utils/validator.dart'; -import 'package:bisaGo/page/add_informasi/add_informasi.dart'; +import 'package:get_it/get_it.dart'; +import 'package:http/http.dart'; +import 'package:mockito/mockito.dart'; + +class MockKomentarRepository extends Fake implements KomentarRepository { + final mockFasilitas = { + 'id': 119, + 'nama_lokasi': 'Margo City', + 'deskripsi': 'loremipsum ipsmum', + 'creator': 'Putra Novial', + 'date_time': '12-11-2020 02:56:49', + 'tag': 'JI', + 'disabilitas': ['DS'], + 'image': '/media/', + 'is_verified': false, + 'jumlah': 2, + 'rating': 5 + }; + + @override + Future<KomentarList> fetchKomentar(String namaLokasi) async { + return Future.value(KomentarList([KomentarModel.fromJson(mockFasilitas)])); + } +} + +class MockKomentarPostingRepository extends Fake + implements KomentarPostingRepository {} + +class MockLokasiRepository extends Fake implements LokasiRepository { + final mockLokasi = { + 'id': 3, + 'name': 'Margo City', + 'latitude': 6.373, + 'longitude': 106.8348, + 'alamat': + 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423', + 'image': '/media/', + 'no_telp': '02178870888', + 'counter': 69, + }; + + @override + Future<LokasiListResponse> fetchLokasi() async { + return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)])); + } + + @override + Future<dynamic> updateLokasi(Lokasi lokasi, String token) async { + return Future.value(Response('Update lokasi berhasil', 200)); + } +} void main() { + final mockLokasi = { + 'id': 3, + 'name': 'Margo City', + 'latitude': 6.373, + 'longitude': 106.8348, + 'alamat': + 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423', + 'image': '/media/', + 'no_telp': '02178870888', + 'counter': 69, + }; + + setUpAll(() { + final _getIt = GetIt.instance; + _getIt.registerLazySingleton<BaseKomentarRepository>( + () => MockKomentarRepository()); + _getIt.registerLazySingleton<BaseKomentarPostingRepository>( + () => MockKomentarPostingRepository()); + _getIt.registerLazySingleton<BaseLokasiRepository>( + () => MockLokasiRepository()); + }); + + testWidgets('Test Fasilitas in Lokasi - Positive', + (WidgetTester tester) async { + final fasilitasKey = Key('Fasilitas Juru Bahasa Isyarat'); + + await tester.pumpWidget( + MaterialApp(home: Fasilitas(lokasi: Lokasi.fromJson(mockLokasi)))); + await tester.pump(); + expect(find.byType(Fasilitas), findsOneWidget); + expect(find.text('Margo City'), findsOneWidget); + expect(find.text('Tambah Informasi'), findsOneWidget); + expect(find.text('Fasilitas atau layanan yang disediakan'), findsOneWidget); + expect(find.byKey(fasilitasKey), findsOneWidget); + expect(find.text('Juru Bahasa Isyarat'), findsOneWidget); + expect(find.text('2'), findsOneWidget); + expect(find.text('ditambahkan oleh Putra Novial'), findsOneWidget); + + await tester.tap(find.text('Tambah Informasi')); + await tester.pump(Duration(seconds: 10)); + }); + + testWidgets('Test Fasilitas in Lokasi - Negative', + (WidgetTester tester) async { + final fasilitasKey = Key('Juru Bahasa Isyarat'); + + await tester.pumpWidget( + MaterialApp(home: Fasilitas(lokasi: Lokasi.fromJson(mockLokasi)))); + await tester.pump(); + expect(find.byType(DetailPostPage), findsNothing); + expect(find.text('Margo'), findsNothing); + expect(find.text('Tambah Review'), findsNothing); + expect(find.text('Fasilitas yang disediakan'), findsNothing); + expect(find.byKey(fasilitasKey), findsNothing); + expect(find.text('Juru Bahasa'), findsNothing); + expect(find.text('1'), findsNothing); + expect(find.text('ditambahkan oleh Putra'), findsNothing); + }); + testWidgets('Tambah Informasi Title Test -- Positive', (WidgetTester tester) async { await tester @@ -28,6 +146,8 @@ void main() { final textFieldKey = Key('Text Field Informasi'); final inputFotoButtonKey = Key('Button Input Foto'); final simpanButtonKey = Key('Button Simpan'); + final buttonIncrementKey = Key('Button Increment'); + final buttonDFKey = Key('Button Disabilitas Fisik'); await tester .pumpWidget(MaterialApp(home: AddInformasi(nama: 'Test Lokasi'))); @@ -38,6 +158,24 @@ void main() { expect(find.byKey(inputFotoButtonKey), findsOneWidget); expect(find.byType(DisabilitasIconButton), findsNWidgets(4)); expect(find.byKey(simpanButtonKey), findsOneWidget); + + await tester.tap(find.byKey(fasilitasDropdownKey)); + await tester.pumpAndSettle(); + await tester.tap(find.text('Kursi Roda').last); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(fasilitasDropdownKey)); + await tester.pumpAndSettle(); + await tester.tap(find.byKey(buttonIncrementKey)); + await tester.enterText(find.byKey(textFieldKey), 'Test Add Informasi'); + await tester + .ensureVisible(find.byKey(Key('Button Simpan'), skipOffstage: false)); + await tester.tap(find.byKey(buttonDFKey)); + await tester.tap(find.byKey(simpanButtonKey)); + await tester.pump(); + expect(find.byType(CustomAlertDialog), findsOneWidget); + + await tester.tap(find.text('Tidak')); + await tester.pumpAndSettle(); }); test('Cara Menggunakan Information Test -- Positive', () { diff --git a/test/add_komentar_test.dart b/test/add_komentar_test.dart deleted file mode 100644 index 7e3aacf31a4d5b15cd50915ea916114f104c8d5f..0000000000000000000000000000000000000000 --- a/test/add_komentar_test.dart +++ /dev/null @@ -1,52 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:bisaGo/model/komentar.dart'; -import 'package:bisaGo/page/filter_fasilitas/postingan/add_komentar.dart'; - -void main() { - Widget buildTestableWidget(Widget widget) { - // https://docs.flutter.io/flutter/widgets/MediaQuery-class.html - return MediaQuery(data: MediaQueryData(), child: MaterialApp(home: widget)); - } - - final detailPostData = { - 'nama_lokasi': 'Margo City', - 'deskripsi': - 'Ada toilet khusus disabilitas terletak di lantai 2 dekat kintan, kondisinya bagus dan bersih layak pakai.\r\n\r\nAda kursi roda juga di customer service lantai dasar, saya tidak ingat jumlahnya ada berapa, tapi ada lumayan banyak.', - 'creator': '', - 'date_time': '12-04-2020 14:33:54', - 'rating': 3, - 'tag': 'KR', - 'disabilitas': ['DF'], - 'image': 'static/img/2669211407.jpg', - 'is_verified': false - }; - - testWidgets('Widget test for addKomentar page', (WidgetTester tester) async { - // Provide the childWidget to the Container. - await tester.pumpWidget(buildTestableWidget( - AddKomentar(KomentarModel.fromJson(detailPostData)))); - // Search for the childWidget in the tree and verify it exists. - expect(find.byType(Scaffold), findsOneWidget); - expect(find.byType(ListView), findsOneWidget); - //expect(find.byType(Container), findsNWidgets(7)); - expect(find.byType(Row), findsNWidgets(2)); - expect(find.byType(Text), findsNWidgets(7)); - expect(find.byType(Form), findsOneWidget); - }); - - testWidgets('Widget negative test for addKomentar page', - (WidgetTester tester) async { - await tester.pumpWidget(buildTestableWidget( - AddKomentar(KomentarModel.fromJson(detailPostData)))); - expect(find.byKey(Key('appbar-text')), findsNothing); - expect(find.byKey(Key('creator')), findsNothing); - }); -} diff --git a/test/add_lokasi_test.dart b/test/add_lokasi_test.dart index 6fac9a832271be1b8efd429e4be7f00f8dd2dae4..41db3d13d2df9081e37e7b23187741e38431f051 100644 --- a/test/add_lokasi_test.dart +++ b/test/add_lokasi_test.dart @@ -1,11 +1,38 @@ import 'package:bisaGo/component/bisago_appbar.dart'; +import 'package:bisaGo/model/lokasi.dart'; import 'package:bisaGo/page/addLokasi/add_lokasi.dart'; import 'package:bisaGo/page/pencarian/pencarian.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:get_it/get_it.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mockito/mockito.dart'; + +class MockLokasiRepository extends Fake implements LokasiRepository { + final mockLokasi = { + 'id': 3, + 'name': 'Coolidge', + 'latitude': -23.7169139, + 'longitude': -46.8498038, + 'alamat': '74809 Hooker Drive', + 'image': 'static/img/2669211407.jpg', + 'telepon': '+55 956 836 5799', + 'counter': 69, + }; + + @override + Future<LokasiListResponse> fetchLokasi() async { + return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)])); + } +} void main() { + setUpAll(() { + final _getIt = GetIt.instance; + _getIt.registerLazySingleton<BaseLokasiRepository>( + () => MockLokasiRepository()); + }); Widget buildTestableWidget(Widget widget) { // https://docs.flutter.io/flutter/widgets/MediaQuery-class.html return MediaQuery(data: MediaQueryData(), child: MaterialApp(home: widget)); diff --git a/test/bloc_test.dart b/test/bloc_test.dart deleted file mode 100644 index bc927613396de283e01cb41df147d3af0b8fc786..0000000000000000000000000000000000000000 --- a/test/bloc_test.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:bisaGo/bloc/komentar_bloc.dart'; -import 'package:bisaGo/model/komentar.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - final komentarData = { - 'nama_lokasi': 'Margo City', - 'deskripsi': - 'Ada toilet khusus disabilitas terletak di lantai 2 dekat kintan, kondisinya bagus dan bersih layak pakai.\r\n\r\nAda kursi roda juga di customer service lantai dasar, saya tidak ingat jumlahnya ada berapa, tapi ada lumayan banyak.', - 'creator': '', - 'date_time': '12-04-2020 14:33:54', - 'rating': 3, - 'tag': 'KR', - 'disabilitas': ['DF'], - 'image': 'static/img/2669211407.jpg', - 'is_verified': false - }; - // final sekolahData = { - // 'name': 'SMA Tanjung Barat', - // 'alamat': 'Kecamatan Tanjung Barat', - // 'no_telp': '0213425367', - // 'website': 'www.tanjungbarat.co.id', - // 'jumlah_siswa': 200, - // 'status': 'IT', - // 'jenis_sekolah': 'IK', - // 'akreditasi': 'A', - // }; - // final komunitasData = { - // 'name': 'Yayasan Wisma Cheshire', - // 'alamat': - // 'Jl. Wijaya Kusuma No.15, RT.5/RW.9, Cilandak Bar., Kec. Cilandak, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta', - // 'no_telp': '0217692059', - // 'website': 'www.wismacheshire.com', - // 'jenis_komunitas': 'NGO', - // }; - - var komentarList = <KomentarModel>[KomentarModel.fromJson(komentarData)]; - final komentarBloc = KomentarBloc('Margo City'); - komentarBloc.allKomentarFromApi = komentarList; - // var sekolahList = [SekolahModel.fromJson(sekolahData)]; - // final sekolahBloc = SekolahBloc(); - // sekolahBloc.allSekolahFromApi = sekolahList; - // - // var komunitasList = [KomunitasModel.fromJson(komunitasData)]; - // final komunitasBloc = KomunitasBloc(); - // komunitasBloc.allKomunitasFromApi = komunitasList; - - test('Sort Komentar Bloc', () { - komentarBloc.sortKomentarList(0, komentarList); - komentarBloc.sortKomentarList(1, komentarList); - komentarBloc.sortKomentarList(2, komentarList); - }); - - test('Reset Komentar List Bloc', () { - komentarBloc.resetKomentarList(); - }); - - // test('Reset Sekolah List Bloc', () { - // sekolahBloc.resetSekolahList(); - // }); -} diff --git a/test/custom_dashboard_location_button_test.dart b/test/custom_dashboard_location_button_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..bd68ecf05e28656d008c1ba0a4d315465fb570da --- /dev/null +++ b/test/custom_dashboard_location_button_test.dart @@ -0,0 +1,42 @@ +import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/utils/custom_dashboard_location_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + final mockLokasi = { + 'id': 3, + 'name': 'Margo City', + 'latitude': 6.373, + 'longitude': 106.8348, + 'alamat': + 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423', + 'image': 'static/img/2669211407.jpg', + 'no_telp': '02178870888' + }; + + testWidgets('Renders Button', (WidgetTester tester) async { + await tester.pumpWidget( + StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return MaterialApp( + home: Material( + child: Center( + child: LocationIconButton( + key: Key('Button Disabiltias Fisik'), + location: Lokasi.fromJson(mockLokasi), + // textColor: Colors.black, + // buttonColor: Colors.white, + // borderColor: Colors.grey, + onPressed: () {}, + )), + ), + ); + }, + ), + ); + + expect(find.byType(LocationIconButton), findsOneWidget); + expect(find.text('Margo City'), findsOneWidget); + }); +} diff --git a/test/detail_post_test.dart b/test/detail_post_test.dart index fec56dacd9e4b65db54dd514925e87dc5d263ae2..dfa7ce0e8a970ee1283394df4c54c98923e90a7f 100644 --- a/test/detail_post_test.dart +++ b/test/detail_post_test.dart @@ -1,14 +1,14 @@ import 'package:bisaGo/model/lokasi.dart'; -import 'package:flutter/material.dart'; +// import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:bisaGo/config/strings.dart'; import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart'; void main() { - Widget buildTestableWidget(Widget widget) { - return MediaQuery(data: MediaQueryData(), child: MaterialApp(home: widget)); - } + // Widget buildTestableWidget(Widget widget) { + // return MediaQuery(data: MediaQueryData(), child: MaterialApp(home: widget)); + // } final detailPostData = { 'nama_lokasi': 'Margo City', @@ -34,31 +34,34 @@ void main() { 'image': '/media/test.jpg' }), ); - testWidgets('Detail post positive test', (WidgetTester tester) async { - // Provide the childWidget to the Container. - await tester.pumpWidget(buildTestableWidget(detailPostPage)); - expect(find.byKey(Key('appbar-text-${detailPostData['nama_lokasi']}')), - findsOneWidget); - expect(find.byKey(Key('desc')), findsOneWidget); - expect(find.byKey(Key('creator-${detailPostData['creator']}')), - findsOneWidget); - expect(find.byKey(Key('timestamp')), findsOneWidget); - expect(find.byKey(Key('tambah komentar')), findsOneWidget); - expect(find.byKey(Key('Komentar')), findsOneWidget); - expect(find.text('${fasilitas[detailPostData['tag']]}'), findsOneWidget); - expect(find.byKey(Key('Text Jumlah')), findsOneWidget); - expect(find.byKey(Key('Icon DF')), findsOneWidget); - }); - - testWidgets('Detail post negative test', (WidgetTester tester) async { - // Provide the childWidget to the Container. - await tester.pumpWidget(buildTestableWidget(detailPostPage)); - expect(find.byKey(Key('appbar-text')), findsNothing); - expect(find.byKey(Key('creator')), findsNothing); - expect(find.byKey(Key('komentar')), findsNothing); - expect(find.text('Bidang Miring'), findsNothing); - expect(find.byKey(Key('Icon DS')), findsNothing); - }); + // testWidgets('Detail post positive test', (WidgetTester tester) async { + // // Provide the childWidget to the Container. + // await tester.pumpWidget(buildTestableWidget(detailPostPage)); + // expect(find.byKey(Key('appbar-text-${detailPostData['nama_lokasi']}')), + // findsOneWidget); + // expect(find.byKey(Key('desc')), findsOneWidget); + // expect(find.byKey(Key('creator-${detailPostData['creator']}')), + // findsOneWidget); + // expect(find.byKey(Key('timestamp')), findsOneWidget); + // expect(find.byKey(Key('tambah komentar')), findsOneWidget); + // expect(find.byKey(Key('Komentar')), findsOneWidget); + // expect(find.text('${fasilitas[detailPostData['tag']]}'), findsOneWidget); + // expect(find.byKey(Key('Text Jumlah')), findsOneWidget); + // expect(find.byKey(Key('Icon DF')), findsOneWidget); + // expect(find.byKey(Key('Button Ubah Informasi')), findsOneWidget); + // expect(find.byKey(Key('Text Cara Menggunakan')), findsOneWidget); + // expect(find.byKey(Key('Text Field Komentar')), findsOneWidget); + // }); + // + // testWidgets('Detail post negative test', (WidgetTester tester) async { + // // Provide the childWidget to the Container. + // await tester.pumpWidget(buildTestableWidget(detailPostPage)); + // expect(find.byKey(Key('appbar-text')), findsNothing); + // expect(find.byKey(Key('creator')), findsNothing); + // expect(find.byKey(Key('komentar')), findsNothing); + // expect(find.text('Bidang Miring'), findsNothing); + // expect(find.byKey(Key('Icon DS')), findsNothing); + // }); testWidgets('Create a komentar placeholder', (WidgetTester tester) async { final detailPostState = detailPostPage.createState(); diff --git a/test/fasilitas_test.dart b/test/fasilitas_test.dart index 7850d5d545170bec6de22dc661d078191c880d4c..c159f8a24ad4a77020228083d6c40f12d44db9df 100644 --- a/test/fasilitas_test.dart +++ b/test/fasilitas_test.dart @@ -1,105 +1,210 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - +import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/page/filter_fasilitas/fasilitas.dart'; +import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart'; +import 'package:bisaGo/page/updateInformasi/update_informasi.dart'; +import 'package:bisaGo/repository/komentar_posting_repository.dart'; +import 'package:bisaGo/repository/komentar_repository.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; +import 'package:bisaGo/utils/custom_alert_dialog.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:bisaGo/globalnetwork.dart'; -import 'package:bisaGo/page/filter_fasilitas/fasilitas.dart'; +import 'package:get_it/get_it.dart'; +import 'package:http/http.dart'; +import 'package:mockito/mockito.dart'; -void main() { +class MockKomentarRepository extends Fake implements KomentarRepository { final mockFasilitas = { - '2': { - 'id': 2, - 'nama_lokasi': 'Margo City', - 'deskripsi': - 'Ada toilet khusus disabilitas terletak di lantai 2 dekat kintan, kondisinya bagus dan bersih layak pakai.\r\n\r\nAda kursi roda juga di customer service lantai dasar, saya tidak ingat jumlahnya ada berapa, tapi ada lumayan banyak.', - 'creator': '', - 'date_time': '2020-04-12 14:33:54.44', - 'like': 20, - 'dislike': 1, - 'rating': 3, - 'tag': ['KR', 'TD'], - 'image': 'static/img/2669211407.jpg', - 'is_verified': false - } + 'id': 119, + 'nama_lokasi': 'Margo City', + 'deskripsi': 'loremipsum ipsmum', + 'creator': 'Putra Novial', + 'date_time': '12-11-2020 02:56:49', + 'tag': 'JI', + 'disabilitas': ['DS'], + 'image': 'static/img/2669211407.jpg', + 'is_verified': false, + 'jumlah': 2, + 'rating': 5 }; - Widget buildTestableWidget(Widget widget) { - // https://docs.flutter.io/flutter/widgets/MediaQuery-class.html - return MediaQuery(data: MediaQueryData(), child: MaterialApp(home: widget)); + + @override + Future<KomentarList> fetchKomentar(String namaLokasi) async { + return Future.value(KomentarList([KomentarModel.fromJson(mockFasilitas)])); } - setUp(() { - getDioInstance('test'); - mockLokasiDependencies(); - mockFasilitasDependencies(mockFasilitas); + @override + Future<dynamic> updateKomentar(Map<String, dynamic> newKomentarData, + String namaLokasi, int id, String token) async { + final responseBody = {'response': 'Fasilitas updated'}; + final statusCode = 202; + return Future.value(Response(responseBody.toString(), statusCode)); + } +} + +class MockLokasiRepository extends Fake implements LokasiRepository { + final mockLokasi = { + 'id': 3, + 'name': 'Margo City', + 'latitude': 6.373, + 'longitude': 106.8348, + 'alamat': + 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423', + 'image': 'static/img/2669211407.jpg', + 'no_telp': '02178870888', + 'counter': 69, + }; + + @override + Future<LokasiListResponse> fetchLokasi() async { + return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)])); + } + + @override + Future<dynamic> updateLokasi(Lokasi lokasi, String token) async { + return Future.value(Response('Update lokasi berhasil', 200)); + } +} + +class MockKomentarPostingRepository extends Fake + implements KomentarPostingRepository {} + +void main() { + final mockLokasi = { + 'id': 3, + 'name': 'Margo City', + 'latitude': 6.373, + 'longitude': 106.8348, + 'alamat': + 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423', + 'image': 'static/img/2669211407.jpg', + 'no_telp': '02178870888', + 'counter': 69, + }; + + final mockFasilitas = { + 'id': 119, + 'nama_lokasi': 'Margo City', + 'deskripsi': 'loremipsum ipsmum', + 'creator': 'Putra Novial', + 'date_time': '12-11-2020 02:56:49', + 'tag': 'JI', + 'disabilitas': ['DS'], + 'image': 'static/img/2669211407.jpg', + 'is_verified': false, + 'jumlah': 2, + 'rating': 5 + }; + + setUpAll(() { + final _getIt = GetIt.instance; + _getIt.registerLazySingleton<BaseKomentarRepository>( + () => MockKomentarRepository()); + _getIt.registerLazySingleton<BaseKomentarPostingRepository>( + () => MockKomentarPostingRepository()); + _getIt.registerLazySingleton<BaseLokasiRepository>( + () => MockLokasiRepository()); + // SharedPreferences.setMockInitialValues({'token': 'token'}); }); - // testWidgets('find inside filter page', (WidgetTester tester) async { - // // Provide the childWidget to the Container. - // await tester.pumpWidget(buildTestableWidget(Fasilitas( - // lokasi: Lokasi.fromJson({ - // 'id': 1, - // 'name': 'Soppeng', - // 'latitude': 100039203300.0, - // 'longitude': 100000000000.0, - // 'alamat': 'Jalan Margonda Raya', - // 'no_telp': '081111111111', - // 'image': '/media/test.jpg' - // }), - // ))); - // await tester.tap(find.byKey(Key('FilterButton'))); - // await tester.pump(Duration(seconds: 1)); - // inside filter - // expect(find.byKey(Key('Urutan')), findsOneWidget); - // expect(find.byKey(Key('Jenis Fasilitas')), findsOneWidget); - // expect(find.byKey(Key('Komentar Terbaru')), findsOneWidget); - // expect(find.byKey(Key('Komentar Terpopuler')), findsOneWidget); - // expect(find.byKey(Key('Komentar dengan Rating Tertinggi')), findsOneWidget); - // expect(find.byKey(Key('Kursi Roda')), findsOneWidget); - // expect(find.byKey(Key('Lift')), findsOneWidget); - // expect(find.byKey(Key('Toilet Disabilitas')), findsOneWidget); - // expect(find.byKey(Key('Tempat Ibadah')), findsOneWidget); - // await tester.drag(find.byKey(Key('Tempat Ibadah')), Offset(0, -200)); - // await tester.pump(); - // // expect(find.byKey(Key('Guiding Block')), findsOneWidget); - // //expect(find.byKey(Key('Bidang Miring (Ramp)')), findsOneWidget); - // //expect(find.byKey(Key('Juru Bahasa Isyarat')), findsOneWidget); - // //expect(find.byKey(Key('Tongkat Disabilitas Netra')), findsOneWidget); - // //expect(find.byKey(Key('Kursi Umum Disabilitas')), findsOneWidget); - // //expect(find.byKey(Key('Parkir Umum')), findsOneWidget); - // //expect(find.byKey(Key('Runing Text')), findsOneWidget); - // //expect(find.byKey(Key('Parkir Disabilitas')), findsOneWidget); - // // filter - // await tester.tap(find.byKey(Key('Alamat'))); - // await tester.pump(); - // }); - - testWidgets('find fasilitas page', (WidgetTester tester) async { - // Provide the childWidget to the Container. - await tester.pumpWidget(buildTestableWidget(Fasilitas( - lokasi: Lokasi.fromJson({ - 'id': 1, - 'name': 'Soppeng', - 'latitude': 100039203300.0, - 'longitude': 100000000000.0, - 'alamat': 'Jalan Margonda Raya', - 'no_telp': '081111111111', - 'image': '/media/test.jpg' - }), - ))); - expect(find.text('081111111111'), findsOneWidget); - expect(find.text('Soppeng'), findsOneWidget); - expect(find.text('Jalan Margonda Raya'), findsOneWidget); + testWidgets('Test Fasilitas in Lokasi - Positive', + (WidgetTester tester) async { + final fasilitasKey = Key('Fasilitas Juru Bahasa Isyarat'); + final iconDSKey = Key('Icon DS'); + final buttonDFKey = Key('Button Disabilitas Fisik'); + final informasiKey = Key('Text Field Informasi'); + final buttonSimpan = find.byKey(Key('Button Simpan')); + + await tester.pumpWidget( + MaterialApp(home: Fasilitas(lokasi: Lokasi.fromJson(mockLokasi)))); + await tester.pump(); + expect(find.byType(Fasilitas), findsOneWidget); + expect(find.text('Margo City'), findsOneWidget); + expect(find.text('Tambah Informasi'), findsOneWidget); + expect(find.text('Fasilitas atau layanan yang disediakan'), findsOneWidget); + expect(find.byKey(fasilitasKey), findsOneWidget); + expect(find.text('Juru Bahasa Isyarat'), findsOneWidget); + expect(find.text('2'), findsOneWidget); + expect(find.text('ditambahkan oleh Putra Novial'), findsOneWidget); + + await tester.pumpWidget(MaterialApp( + home: DetailPostPage( + komentar: KomentarModel.fromJson(mockFasilitas), + lokasi: Lokasi.fromJson(mockLokasi)))); await tester.pump(); - // expect(find.text(mockFasilitas['2']['deskripsi']), findsOneWidget); - await tester.tap(find.byKey(Key('Alamat'))); + expect(find.byType(DetailPostPage), findsOneWidget); + expect(find.text('Juru Bahasa Isyarat'), findsOneWidget); + expect(find.text('Tersedia sebanyak 2 unit fasilitas.'), findsOneWidget); + expect(find.byKey(iconDSKey), findsOneWidget); + expect(find.text('loremipsum ipsmum'), findsOneWidget); + expect(find.text('Putra Novial '), findsOneWidget); + expect(find.text('Komentar'), findsOneWidget); + expect(find.text('Tambah Komentar'), findsOneWidget); + + await tester.pumpWidget(MaterialApp( + home: UpdateInformasi( + komentar: KomentarModel.fromJson(mockFasilitas), + lokasi: Lokasi.fromJson(mockLokasi)), + )); await tester.pump(); + expect(find.byType(UpdateInformasi), findsOneWidget); + + await tester.enterText(find.byKey(informasiKey), 'Test Update Informasi'); + await tester + .ensureVisible(find.byKey(Key('Button Simpan'), skipOffstage: false)); + await tester.tap(find.byKey(buttonDFKey)); + await tester.tap(buttonSimpan); + await tester.pump(); + expect(find.byType(CustomAlertDialog), findsOneWidget); + + await tester.tap(find.text('Ya')); + }); + + testWidgets('Test Fasilitas in Lokasi - Negative', + (WidgetTester tester) async { + final fasilitasKey = Key('Juru Bahasa Isyarat'); + final iconDSKey = Key('DS'); + final buttonSimpan = Key('Button Simpan'); + + await tester.pumpWidget( + MaterialApp(home: Fasilitas(lokasi: Lokasi.fromJson(mockLokasi)))); + await tester.pump(); + expect(find.byType(DetailPostPage), findsNothing); + expect(find.text('Margo'), findsNothing); + expect(find.text('Tambah Review'), findsNothing); + expect(find.text('Fasilitas yang disediakan'), findsNothing); + expect(find.byKey(fasilitasKey), findsNothing); + expect(find.text('Juru Bahasa'), findsNothing); + expect(find.text('1'), findsNothing); + expect(find.text('ditambahkan oleh Putra'), findsNothing); + + await tester.pumpWidget(MaterialApp( + home: DetailPostPage( + komentar: KomentarModel.fromJson(mockFasilitas), + lokasi: Lokasi.fromJson(mockLokasi)))); + await tester.pump(); + expect(find.byType(UpdateInformasi), findsNothing); + expect(find.text('Juru Bahasa'), findsNothing); + expect(find.text('Tersedia sebanyak 1 unit fasilitas.'), findsNothing); + expect(find.byKey(iconDSKey), findsNothing); + expect(find.text('lorem ipsum'), findsNothing); + expect(find.text('Putra'), findsNothing); + expect(find.text('Komentar Posting'), findsNothing); + expect(find.text('Tambah Komentar Posting'), findsNothing); + + await tester.pumpWidget(MaterialApp( + home: UpdateInformasi( + komentar: KomentarModel.fromJson(mockFasilitas), + lokasi: Lokasi.fromJson(mockLokasi)), + )); + await tester.pump(); + expect(find.byType(Fasilitas), findsNothing); + + await tester + .ensureVisible(find.byKey(Key('Button Simpan'), skipOffstage: false)); + await tester.tap(find.byKey(buttonSimpan)); await tester.pump(); + await tester.tap(find.text('Tidak')); await tester.pump(); }); } diff --git a/test/layanan_disabilitas_test.dart b/test/layanan_disabilitas_test.dart index 9dab4ff80f43d0c8e939c669d6e6b28c48deb14a..c66a3b213e0c0678cd3c8c5850bce4ec8c1f00a6 100644 --- a/test/layanan_disabilitas_test.dart +++ b/test/layanan_disabilitas_test.dart @@ -21,7 +21,7 @@ void main() { expect(find.byType(Icon), findsNWidgets(5)); expect(find.byType(Row), findsNWidgets(3)); expect(find.byType(Scaffold), findsOneWidget); - expect(find.byType(SizedBox), findsNWidgets(8)); + expect(find.byType(SizedBox), findsNWidgets(9)); expect(find.byType(FlatButton), findsNWidgets(2)); expect(find.byKey(scaffoldTextFieldKey), findsOneWidget); diff --git a/test/mock_test.dart b/test/mock_test.dart index d86c1d8ab98209ba1032e6d2e34a1bfb514d7857..8742008de4a4dd55c1a29c63c8d8f185efdbb4c3 100644 --- a/test/mock_test.dart +++ b/test/mock_test.dart @@ -1,10 +1,12 @@ +import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; import 'package:flutter/material.dart'; +import 'package:get_it/get_it.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:bisaGo/network/network_interface.dart'; import 'package:bisaGo/page/dashboard/dashboard.dart'; import 'package:http/http.dart' as http; -import 'package:pedantic/pedantic.dart'; class MockNavigatorObserver extends Mock implements NavigatorObserver {} @@ -12,12 +14,35 @@ class MockNetwork extends Mock implements NetworkInterface {} class MockHttp extends Mock implements http.Client {} +class MockLokasiRepository extends Fake implements LokasiRepository { + final mockLokasi = { + 'id': 3, + 'name': 'Coolidge', + 'latitude': -23.7169139, + 'longitude': -46.8498038, + 'alamat': '74809 Hooker Drive', + 'image': 'static/img/2669211407.jpg', + 'telepon': '+55 956 836 5799', + 'counter': 69, + }; + + @override + Future<LokasiListResponse> fetchLokasi() async { + return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)])); + } + + @override + Future<dynamic> updateLokasi(Lokasi lokasi, String token) async { + return Future.value(http.Response('Update lokasi berhasil', 200)); + } +} + void main() { group('Dashboard navigation tests', () { NavigatorObserver mockObserver; NetworkInterface mockNetwork; MockHttp mockHttp; - setUp(() { + setUpAll(() { mockObserver = MockNavigatorObserver(); mockNetwork = MockNetwork(); mockHttp = MockHttp(); @@ -36,6 +61,9 @@ void main() { } ]); }); + final _getIt = GetIt.instance; + _getIt.registerLazySingleton<BaseLokasiRepository>( + () => MockLokasiRepository()); }); Future<Null> _buildDashboardPage(WidgetTester tester) async { @@ -58,13 +86,6 @@ void main() { await tester.pump(); } - Future<Null> _navigateToInformasiLayananDisabilitas( - WidgetTester tester) async { - final buttonKey = Key('FloatingActionButton'); - await tester.press(find.byKey(buttonKey)); - await tester.pump(); - } - testWidgets( 'when tapping text form field, should navigate to pencarian page', (WidgetTester tester) async { @@ -82,22 +103,18 @@ void main() { await _buildDashboardPage(tester); await _navigateToPencarianPage(tester); await tester.pump(); - final Route pushedRoute = - verify(mockObserver.didPush(captureAny, any)).captured.single; - String popResult; - unawaited(pushedRoute.popped.then((result) => popResult = result)); await tester.tap(find.byKey(backIconKey)); await tester.pump(); - expect(popResult, 'Take me back'); + expect(find.byType(Dashboard), findsOneWidget); }); - testWidgets( - 'when press info layanan komunitas button, redirect to info layanan komunitas page', - (WidgetTester tester) async { - await _buildDashboardPage(tester); - await _navigateToInformasiLayananDisabilitas(tester); - - expect(find.text('Informasi Layanan Disabilitas'), findsOneWidget); - }); + // testWidgets( + // 'when press info layanan komunitas button, redirect to info layanan komunitas page', + // (WidgetTester tester) async { + // await _buildDashboardPage(tester); + // await _navigateToInformasiLayananDisabilitas(tester); + // + // expect(find.text('Informasi Layanan Disabilitas'), findsOneWidget); + // }); }); } diff --git a/test/model_test.dart b/test/model_test.dart index e3a089074ebefcb0da28d856a39c5d2aa2498dae..ae1aba6a7fb364ee69d8f378ba44b96fdc330289 100644 --- a/test/model_test.dart +++ b/test/model_test.dart @@ -1,6 +1,5 @@ import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/model/komentar_posting.dart'; -import 'package:bisaGo/model/lokasi.dart'; import 'package:bisaGo/model/new_user.dart'; import 'package:bisaGo/model/user.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -59,15 +58,6 @@ void main() { 'image': 'static/img/2669211407.jpg', 'is_verified': false }; - final lokasiData = { - 'id': 1, - 'name': 'test', - 'latitude': 0.0, - 'longitude': 0.0, - 'alamat': 'This is a test', - 'image': 'This is a test', - 'no_telp': '082139314123' - }; final newUserData = { 'name': 'test', 'email': 'test@gmail.com', @@ -118,15 +108,4 @@ void main() { final komentarModel = KomentarModel.fromJson(komentarData); expect(komentarModel.toJson(), returnKomentarData); }); - - test('Lokasi Model toJson', () { - final lokasiModel = Lokasi.fromJson(lokasiData); - expect(lokasiModel.toJson(), lokasiData); - }); - - test('Lokasi Model List', () { - final lokasiModel = [Lokasi.fromJson(lokasiData)]; - final lokasiListModel = LokasiListResponse(lokasiModel); - expect(lokasiListModel, isInstanceOf<LokasiListResponse>()); - }); } diff --git a/test/pencarian_test.dart b/test/pencarian_test.dart index e1239fb44299070dafcda1531442c999d9a23d5f..2e2324825392880bfeec6b4e0b7c1352187809ca 100644 --- a/test/pencarian_test.dart +++ b/test/pencarian_test.dart @@ -1,21 +1,34 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - import 'dart:io'; import 'package:bisaGo/model/lokasi.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:get_it/get_it.dart'; import 'package:mockito/mockito.dart'; import 'package:bisaGo/page/pencarian/pencarian.dart'; import 'package:bisaGo/network/network_interface.dart'; class MockNetwork extends Mock implements NetworkInterface {} +class MockLokasiRepository extends Fake implements LokasiRepository { + final mockLokasi = { + 'id': 3, + 'name': 'Coolidge', + 'latitude': -23.7169139, + 'longitude': -46.8498038, + 'alamat': '74809 Hooker Drive', + 'image': 'static/img/2669211407.jpg', + 'telepon': '+55 956 836 5799', + 'counter': 69, + }; + + @override + Future<LokasiListResponse> fetchLokasi() async { + return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)])); + } +} + void main() { MockNetwork mockNetwork; var mockLokasi = { @@ -26,32 +39,24 @@ void main() { 'telepon': '+55 956 836 5799' }; var lokasiList = [Lokasi.fromJson(mockLokasi)]; - setUp(() { + setUpAll(() { + final _getIt = GetIt.instance; mockNetwork = MockNetwork(); when(mockNetwork.get(isLogin: false, url: anyNamed('url'))) .thenAnswer((_) async { await Future.delayed(Duration(milliseconds: 50)); return Future<dynamic>.value([mockLokasi]); }); + _getIt.registerLazySingleton<BaseLokasiRepository>( + () => MockLokasiRepository()); }); testWidgets('display list view in pencarian', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: Pencarian())); expect(find.byKey(const Key('Text Field Mau Kemana')), findsOneWidget); - //var textField = find.byKey(const Key('Text Field Mau Kemana')); - //await tester.tap(textField); await tester.enterText( find.byKey(const Key('Text Field Mau Kemana')), 'Coolidge'); await tester.pump(); expect(find.text('Hasil Pencarian'), findsOneWidget); - - //expect(find.byType(CircleAvatar), findsWidgets); - - //expect(find.byKey(const Key('api-Coolidge')), findsOneWidget); - // [TODO] tiap item itu punya key unik - // Search for the childWidget in the tree and verify it exists. - //expect(find.byType(ListView), findsNWidgets); - //expect(find.byType(Container), findsWidgets); - //expect(find.byType(Icon), findsWidgets); }); testWidgets('finds a text field in pencarian', (WidgetTester tester) async { diff --git a/test/tentang_disabilitas_fisik_test.dart b/test/tentang_disabilitas_fisik_test.dart index 07622f4387d23221fb18a424938b5afdf90421f0..a00e1af15e8cc7178ca65b56dc4e341802cee4d3 100644 --- a/test/tentang_disabilitas_fisik_test.dart +++ b/test/tentang_disabilitas_fisik_test.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { - testWidgets('Test Tentang Disabilitas Sensorik Page Individually', - (WidgetTester tester) async { + testWidgets('Test Tentang Disabilitas Fisik Page Individually', + (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: TentangDisabilitasFisik())); final title = find.byKey(Key('Title Disabilitas Fisik')); expect(title, findsOneWidget); @@ -17,7 +17,8 @@ void main() { expect(descTunanetra, findsOneWidget); final titleTunarunguKey = Key('Title Lumpuh Layuh'); - await tester.ensureVisible(find.byKey(titleTunarunguKey, skipOffstage: false)); + await tester + .ensureVisible(find.byKey(titleTunarunguKey, skipOffstage: false)); await tester.pumpAndSettle(); expect(find.byKey(titleTunarunguKey), findsOneWidget); final descTunarunguKey = Key('Description Lumpuh Layuh'); @@ -31,4 +32,4 @@ void main() { final extraInfo = find.byKey(Key('Extra Information')); expect(extraInfo, findsOneWidget); }); -} \ No newline at end of file +} diff --git a/test/update_informasi_test.dart b/test/update_informasi_test.dart index 2af3e1c87a4b6772ba5c2183ad556919ada9ae8f..fcd42444e498b775749b24689f4a2a31b91b6820 100644 --- a/test/update_informasi_test.dart +++ b/test/update_informasi_test.dart @@ -1,19 +1,41 @@ import 'package:bisaGo/model/komentar.dart'; import 'package:bisaGo/page/updateInformasi/update_informasi.dart'; +import 'package:bisaGo/repository/komentar_repository.dart'; +import 'package:bisaGo/utils/custom_disabilitas_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:get_it/get_it.dart'; +import 'package:http/http.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class MockKomentarRepository extends Fake implements KomentarRepository { + @override + Future<dynamic> updateKomentar(Map<String, dynamic> newKomentarData, + String namaLokasi, int id, String token) async { + final responseBody = {'response': 'Fasilitas updated'}; + final statusCode = 201; + return Future.value(Response(responseBody.toString(), statusCode)); + } +} void main() { + setUpAll(() { + final _getIt = GetIt.instance; + _getIt.registerLazySingleton<KomentarRepository>( + () => MockKomentarRepository()); + SharedPreferences.setMockInitialValues({'token': 'token'}); + }); + final komentarData = { 'nama_lokasi': 'Margo City', - 'deskripsi': - 'Ada toilet khusus disabilitas terletak di lantai 2 dekat kintan, kondisinya bagus dan bersih layak pakai.\r\n\r\nAda kursi roda juga di customer service lantai dasar, saya tidak ingat jumlahnya ada berapa, tapi ada lumayan banyak.', - 'creator': '', + 'deskripsi': 'Ini deskripsi', + 'creator': 'John Doe', 'date_time': '12-04-2020 14:33:54', - 'rating': 3, + 'jumlah': 3, 'tag': 'KR', 'disabilitas': ['DF'], - 'image': 'static/img/2669211407.jpg', + 'image': '/media/', 'is_verified': false }; @@ -23,13 +45,80 @@ void main() { testWidgets('Test Update Informasi Page', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: updateInformasiPage)); - await tester.tap(find.byKey(Key('Simpan Button'))); + await tester.tap(find.byKey(Key('Button Simpan'))); await tester.pump(Duration(seconds: 100)); }); - testWidgets('Test Add Informasi On Update Informasi Page', + testWidgets('Update Informasi Title Test -- Positive', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: updateInformasiPage)); + + expect(find.text('Ubah Informasi'), findsOneWidget); + }); + + testWidgets('Update Informasi Title Test -- Negative', (WidgetTester tester) async { - UpdateInformasiState().addInfo('KD', 'Kursi Roda', '5.0'); await tester.pumpWidget(MaterialApp(home: updateInformasiPage)); + + expect(find.text('Tambah Informasi'), findsNothing); + }); + + testWidgets('Update Informasi Fields Test', (WidgetTester tester) async { + final locationNameKey = Key('Text Location Name'); + final jenisFasilitasKey = Key('Text Jenis Fasilitas Layanan'); + final jumlahCounterKey = Key('Counter Fasilitas Layanan'); + final textFieldKey = Key('Text Field Informasi'); + final inputFotoButtonKey = Key('Button Input Foto'); + final simpanButtonKey = Key('Button Simpan'); + final batalButtonKey = Key('Button Batal'); + await tester.pumpWidget(MaterialApp(home: updateInformasiPage)); + + expect(find.byKey(locationNameKey), findsOneWidget); + expect(find.byKey(jenisFasilitasKey), findsOneWidget); + expect(find.byKey(jumlahCounterKey), findsOneWidget); + expect(find.byKey(textFieldKey), findsOneWidget); + expect(find.byKey(inputFotoButtonKey), findsOneWidget); + expect(find.byType(DisabilitasIconButton), findsNWidgets(4)); + expect(find.byKey(simpanButtonKey), findsOneWidget); + expect(find.byKey(batalButtonKey), findsOneWidget); + }); + + testWidgets('Press Buttons Test', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: updateInformasiPage)); + + final buttonDF = find.byKey(Key('Button Disabilitas Fisik')); + final buttonDI = find.byKey(Key('Button Disabilitas Intelektual')); + final buttonDM = find.byKey(Key('Button Disabilitas Mental')); + final buttonDS = find.byKey(Key('Button Disabilitas Sensorik')); + final buttonFoto = find.byKey(Key('Button Input Foto')); + final buttonBatal = find.byKey(Key('Button Batal')); + final buttonIncrement = find.byKey(Key('Button Increment')); + final buttonDecrement = find.byKey(Key('Button Decrement')); + final buttonSimpan = find.byKey(Key('Button Simpan')); + + await tester.ensureVisible( + find.byKey(Key('Button Increment'), skipOffstage: false)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + await tester.tap(buttonIncrement); + await tester.tap(buttonDecrement); + await tester.ensureVisible( + find.byKey(Key('Button Disabilitas Fisik'), skipOffstage: false)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + await tester.tap(buttonDF); + await tester.tap(buttonDI); + await tester.ensureVisible( + find.byKey(Key('Button Disabilitas Fisik'), skipOffstage: false)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + await tester.tap(buttonDM); + await tester.tap(buttonDS); + await tester.ensureVisible( + find.byKey(Key('Button Input Foto'), skipOffstage: false)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + await tester.tap(buttonFoto); + await tester + .ensureVisible(find.byKey(Key('Button Simpan'), skipOffstage: false)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + await tester.tap(buttonSimpan); + await tester.tap(buttonBatal); }); } diff --git a/test/widget_test.dart b/test/widget_test.dart index 2700b948d505e2acdfa0d1ac8984b45786692773..8f4f411f5d46f21063f41800ec7d0e19d8acb7d0 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -1,6 +1,8 @@ import 'package:bisaGo/model/komunitas.dart'; +import 'package:bisaGo/model/lokasi.dart'; import 'package:bisaGo/model/sekolah.dart'; import 'package:bisaGo/repository/komunitas_repository.dart'; +import 'package:bisaGo/repository/lokasi_repository.dart'; import 'package:bisaGo/repository/sekolah_repository.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -27,6 +29,25 @@ class MockKomunitasRepository extends Fake implements KomunitasRepository { } } +class MockLokasiRepository extends Fake implements LokasiRepository { + final mockLokasi = { + 'id': 3, + 'name': 'Margo City', + 'latitude': 6.373, + 'longitude': 106.8348, + 'alamat': + 'Jl. Margonda Raya No.358, Kemiri Muka, Kecamatan Beji, Kota Depok, Jawa Barat 16423', + 'image': 'static/img/2669211407.jpg', + 'no_telp': '02178870888', + 'counter': 69, + }; + + @override + Future<LokasiListResponse> fetchLokasi() async { + return Future.value(LokasiListResponse([Lokasi.fromJson(mockLokasi)])); + } +} + class MockSekolahRepository extends Fake implements SekolahRepository { final sekolahData = { 'name': 'SMA Tanjung Barat', @@ -52,6 +73,8 @@ void main() { () => MockKomunitasRepository()); _getIt.registerLazySingleton<BaseSekolahRepository>( () => MockSekolahRepository()); + _getIt.registerLazySingleton<BaseLokasiRepository>( + () => MockLokasiRepository()); }); testWidgets('finds a text field in dashboard', (WidgetTester tester) async { final containerTextField = Key('Container Text Field'); @@ -63,8 +86,8 @@ void main() { expect(find.byType(Scaffold), findsOneWidget); expect(find.byKey(Key('Stack')), findsOneWidget); expect(find.byType(TextFormField), findsOneWidget); - expect(find.byType(Icon), findsNWidgets(3)); - expect(find.text('Kamu mau kemana?'), findsOneWidget); + expect(find.byType(Icon), findsNWidgets(2)); + expect(find.text('Tekan untuk mencari tempat'), findsOneWidget); expect(find.text('Kamu mau kmn?'), findsNothing); expect(find.byKey(containerTextField), findsOneWidget); expect(find.byKey(textFieldKey), findsOneWidget); @@ -88,19 +111,19 @@ void main() { testWidgets('finds a google map in dashboard', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp(home: Dashboard())); await tester.pump(); - expect(find.byType(Container), findsNWidgets(4)); + expect(find.byType(Container), findsNWidgets(9)); }); - testWidgets('finds a floating in dashboard', (WidgetTester tester) async { - final floatingActionButtonKey = Key('FloatingActionButton'); - final scaffoldTextFieldKey = Key('Scaffold Text Field'); - await tester.pumpWidget(MaterialApp(home: Dashboard())); - expect(find.byKey(floatingActionButtonKey), findsOneWidget); - expect(find.byKey(Key('FloatingActionButtonnnn')), findsNothing); - await tester.tap(find.byKey(floatingActionButtonKey)); - await tester.pump(Duration(seconds: 10)); - expect(find.byKey(scaffoldTextFieldKey), findsOneWidget); - }); + // testWidgets('finds a floating in dashboard', (WidgetTester tester) async { + // final floatingActionButtonKey = Key('FloatingActionButton'); + // final scaffoldTextFieldKey = Key('Scaffold Text Field'); + // await tester.pumpWidget(MaterialApp(home: Dashboard())); + // expect(find.byKey(floatingActionButtonKey), findsOneWidget); + // expect(find.byKey(Key('FloatingActionButtonnnn')), findsNothing); + // await tester.tap(find.byKey(floatingActionButtonKey)); + // await tester.pump(Duration(seconds: 10)); + // expect(find.byKey(scaffoldTextFieldKey), findsOneWidget); + // }); testWidgets('finds a marker in google map', (WidgetTester tester) async { final dashboardPage = Dashboard();