diff --git a/.env b/.env index 040441b..8517822 100644 --- a/.env +++ b/.env @@ -1,6 +1,8 @@ -url = 'https://panti-asuhan.s-keytech.com/' -api_url = 'https://panti-asuhan.s-keytech.com/api/' +# url = 'https://panti-asuhan.s-keytech.com/' +# api_url = 'https://panti-asuhan.s-keytech.com/api/' # url = 'http://172.29.85.181/panti_asuhan2/' # api_url = 'http://172.29.85.181/panti_asuhan2/api/' # url = 'http://20.20.20.25/panti_asuhan2/' -# api_url = 'http://20.20.20.25/panti_asuhan2/api/' \ No newline at end of file +# api_url = 'http://20.20.20.25/panti_asuhan2/api/' +url = 'https://localhost.kicap-karan.com/panti_asuhan/' +api_url = 'https://localhost.kicap-karan.com/panti_asuhan/api/' \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a67e0fc..ac38be1 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,26 +1,13 @@ - + - - + + + - + @@ -28,8 +15,6 @@ - + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4..05b24db 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b7..05b24db 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 09d4391..05b24db 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d..05b24db 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 4d6372e..05b24db 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/lib/app/app.dart b/lib/app/app.dart index 66fcb8f..e221dd2 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -1,13 +1,16 @@ -import 'package:panti_asuhan/ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart'; import 'package:stacked_services/stacked_services.dart'; import 'package:stacked/stacked_annotations.dart'; import '../services/http_services.dart'; import '../services/my_easyloading.dart'; +import '../services/other_function.dart'; import '../ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart'; +import '../ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view.dart'; +import '../ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view.dart'; import '../ui/views/admin_index_tracking/admin_index_tracking_view.dart'; import '../ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart'; import '../ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart'; +import '../ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart'; import '../ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart'; import '../ui/views/admin_index_tracking/filter_dialog/filter_dialog_view.dart'; import '../ui/views/admin_index_tracking/profil/profil_view.dart'; @@ -31,11 +34,14 @@ import '../ui/views/user_index_tracking/user_index_tracking_view.dart'; children: [ // MaterialRoute(page: AdminIndexView, initial: true), MaterialRoute(page: DanaSosialAdminView), + MaterialRoute(page: DanaSosialKhususView), MaterialRoute(page: DataSiswaView), MaterialRoute(page: ProfilView), MaterialRoute(page: VisiMisiView), MaterialRoute(page: SejarahView), - MaterialRoute(page: StrukturOrganisasiView), + MaterialRoute( + page: StrukturOrganisasiView, + ), ], ), MaterialRoute(page: TambahDanaSosialView), @@ -46,6 +52,7 @@ import '../ui/views/user_index_tracking/user_index_tracking_view.dart'; children: [ // MaterialRoute(page: AdminIndexView, initial: true), MaterialRoute(page: DanaSosialAdminView), + MaterialRoute(page: DanaSosialKhususView), MaterialRoute(page: DataSiswaView), MaterialRoute(page: ProfilView), ], @@ -55,6 +62,7 @@ import '../ui/views/user_index_tracking/user_index_tracking_view.dart'; children: [ // MaterialRoute(page: AdminIndexView, initial: true), MaterialRoute(page: DanaSosialAdminView), + MaterialRoute(page: DanaSosialKhususView), MaterialRoute(page: DataSiswaView), MaterialRoute(page: ProfilView), MaterialRoute(page: VisiMisiView), @@ -67,7 +75,8 @@ import '../ui/views/user_index_tracking/user_index_tracking_view.dart'; StackedDialog(classType: AddSiswaDialogView), StackedDialog(classType: FilterDialogView), StackedDialog(classType: EditStrukrurOrganisasiDialogView), - StackedDialog(classType: EditDialogSiswaView) + StackedDialog(classType: EditDialogSiswaView), + StackedDialog(classType: AddDonaturDialogView), ], dependencies: [ LazySingleton(classType: NavigationService), @@ -78,6 +87,7 @@ import '../ui/views/user_index_tracking/user_index_tracking_view.dart'; LazySingleton(classType: MyEasyLoading), LazySingleton(classType: MyHttpServices), + LazySingleton(classType: OtherFunction), ], logger: StackedLogger(), ) diff --git a/lib/app/app.dialogs.dart b/lib/app/app.dialogs.dart index b40740a..c12a233 100644 --- a/lib/app/app.dialogs.dart +++ b/lib/app/app.dialogs.dart @@ -8,6 +8,7 @@ import 'package:stacked_services/stacked_services.dart'; import 'app.locator.dart'; import '../ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart'; +import '../ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view.dart'; import '../ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart'; import '../ui/views/admin_index_tracking/filter_dialog/filter_dialog_view.dart'; import '../ui/views/admin_index_tracking/struktur_organisasi/edit_strukrur_organisasi_dialog/edit_strukrur_organisasi_dialog_view.dart'; @@ -17,6 +18,7 @@ enum DialogType { filterDialogView, editStrukrurOrganisasiDialogView, editDialogSiswaView, + addDonaturDialogView, } void setupDialogUi() { @@ -32,6 +34,8 @@ void setupDialogUi() { request: request, completer: completer), DialogType.editDialogSiswaView: (context, request, completer) => EditDialogSiswaView(request: request, completer: completer), + DialogType.addDonaturDialogView: (context, request, completer) => + AddDonaturDialogView(request: request, completer: completer), }; dialogService.registerCustomDialogBuilders(builders); diff --git a/lib/app/app.locator.dart b/lib/app/app.locator.dart index 57e7a42..ba6bb39 100644 --- a/lib/app/app.locator.dart +++ b/lib/app/app.locator.dart @@ -14,6 +14,7 @@ import 'package:stacked_shared/stacked_shared.dart'; import '../services/http_services.dart'; import '../services/my_easyloading.dart'; +import '../services/other_function.dart'; final locator = StackedLocator.instance; @@ -32,4 +33,5 @@ Future setupLocator({ locator.registerLazySingleton(() => BottomSheetService()); locator.registerLazySingleton(() => MyEasyLoading()); locator.registerLazySingleton(() => MyHttpServices()); + locator.registerLazySingleton(() => OtherFunction()); } diff --git a/lib/app/app.router.dart b/lib/app/app.router.dart index 55da282..473c49e 100644 --- a/lib/app/app.router.dart +++ b/lib/app/app.router.dart @@ -11,18 +11,20 @@ import 'package:panti_asuhan/ui/views/admin_index_tracking/admin_index_tracking_ as _i4; import 'package:panti_asuhan/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart' as _i11; -import 'package:panti_asuhan/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart' +import 'package:panti_asuhan/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view.dart' as _i12; +import 'package:panti_asuhan/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart' + as _i13; import 'package:panti_asuhan/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart' as _i6; import 'package:panti_asuhan/ui/views/admin_index_tracking/profil/profil_view.dart' - as _i13; -import 'package:panti_asuhan/ui/views/admin_index_tracking/sejarah/sejarah_view.dart' - as _i15; -import 'package:panti_asuhan/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart' - as _i16; -import 'package:panti_asuhan/ui/views/admin_index_tracking/visi_misi/visi_misi_view.dart' as _i14; +import 'package:panti_asuhan/ui/views/admin_index_tracking/sejarah/sejarah_view.dart' + as _i16; +import 'package:panti_asuhan/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart' + as _i17; +import 'package:panti_asuhan/ui/views/admin_index_tracking/visi_misi/visi_misi_view.dart' + as _i15; import 'package:panti_asuhan/ui/views/detail_dana_sosial/detail_dana_sosial_view.dart' as _i7; import 'package:panti_asuhan/ui/views/login_screen/login_screen_view.dart' @@ -36,7 +38,7 @@ import 'package:panti_asuhan/ui/views/tambah_dana_sosial/tambah_dana_sosial_view import 'package:panti_asuhan/ui/views/user_index_tracking/user_index_tracking_view.dart' as _i9; import 'package:stacked/stacked.dart' as _i1; -import 'package:stacked_services/stacked_services.dart' as _i17; +import 'package:stacked_services/stacked_services.dart' as _i18; class Routes { static const splashScreenView = '/'; @@ -126,8 +128,12 @@ class StackedRouter extends _i1.RouterBase { ); }, _i5.TambahDanaSosialView: (data) { + final args = data.getArgs( + orElse: () => const TambahDanaSosialViewArguments(), + ); return _i10.MaterialPageRoute( - builder: (context) => const _i5.TambahDanaSosialView(), + builder: (context) => + _i5.TambahDanaSosialView(key: args.key, isKhusus: args.isKhusus), settings: data, maintainState: false, ); @@ -144,8 +150,8 @@ class StackedRouter extends _i1.RouterBase { _i7.DetailDanaSosialView: (data) { final args = data.getArgs(nullOk: false); return _i10.MaterialPageRoute( - builder: (context) => - _i7.DetailDanaSosialView(key: args.key, id: args.id), + builder: (context) => _i7.DetailDanaSosialView( + key: args.key, id: args.id, isKhusus: args.isKhusus), settings: data, maintainState: false, ); @@ -172,6 +178,22 @@ class StackedRouter extends _i1.RouterBase { Map get pagesMap => _pagesMap; } +class TambahDanaSosialViewArguments { + const TambahDanaSosialViewArguments({ + this.key, + this.isKhusus = false, + }); + + final _i10.Key? key; + + final bool isKhusus; + + @override + String toString() { + return '{"key": "$key", "isKhusus": "$isKhusus"}'; + } +} + class EditSiswaViewArguments { const EditSiswaViewArguments({ required this.idSiswa, @@ -192,21 +214,26 @@ class DetailDanaSosialViewArguments { const DetailDanaSosialViewArguments({ this.key, required this.id, + this.isKhusus = false, }); final _i10.Key? key; final int id; + final bool isKhusus; + @override String toString() { - return '{"key": "$key", "id": "$id"}'; + return '{"key": "$key", "id": "$id", "isKhusus": "$isKhusus"}'; } } class AdminIndexTrackingViewRoutes { static const danaSosialAdminView = 'dana-sosial-admin-view'; + static const danaSosialKhususView = 'dana-sosial-khusus-view'; + static const dataSiswaView = 'data-siswa-view'; static const profilView = 'profil-view'; @@ -219,6 +246,7 @@ class AdminIndexTrackingViewRoutes { static const all = { danaSosialAdminView, + danaSosialKhususView, dataSiswaView, profilView, visiMisiView, @@ -233,25 +261,29 @@ class AdminIndexTrackingViewRouter extends _i1.RouterBase { AdminIndexTrackingViewRoutes.danaSosialAdminView, page: _i11.DanaSosialAdminView, ), + _i1.RouteDef( + AdminIndexTrackingViewRoutes.danaSosialKhususView, + page: _i12.DanaSosialKhususView, + ), _i1.RouteDef( AdminIndexTrackingViewRoutes.dataSiswaView, - page: _i12.DataSiswaView, + page: _i13.DataSiswaView, ), _i1.RouteDef( AdminIndexTrackingViewRoutes.profilView, - page: _i13.ProfilView, + page: _i14.ProfilView, ), _i1.RouteDef( AdminIndexTrackingViewRoutes.visiMisiView, - page: _i14.VisiMisiView, + page: _i15.VisiMisiView, ), _i1.RouteDef( AdminIndexTrackingViewRoutes.sejarahView, - page: _i15.SejarahView, + page: _i16.SejarahView, ), _i1.RouteDef( AdminIndexTrackingViewRoutes.strukturOrganisasiView, - page: _i16.StrukturOrganisasiView, + page: _i17.StrukturOrganisasiView, ), ]; @@ -263,37 +295,44 @@ class AdminIndexTrackingViewRouter extends _i1.RouterBase { maintainState: false, ); }, - _i12.DataSiswaView: (data) { + _i12.DanaSosialKhususView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i12.DataSiswaView(), + builder: (context) => const _i12.DanaSosialKhususView(), settings: data, maintainState: false, ); }, - _i13.ProfilView: (data) { + _i13.DataSiswaView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i13.ProfilView(), + builder: (context) => const _i13.DataSiswaView(), settings: data, maintainState: false, ); }, - _i14.VisiMisiView: (data) { + _i14.ProfilView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i14.VisiMisiView(), + builder: (context) => const _i14.ProfilView(), settings: data, maintainState: false, ); }, - _i15.SejarahView: (data) { + _i15.VisiMisiView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i15.SejarahView(), + builder: (context) => const _i15.VisiMisiView(), settings: data, maintainState: false, ); }, - _i16.StrukturOrganisasiView: (data) { + _i16.SejarahView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i16.StrukturOrganisasiView(), + builder: (context) => const _i16.SejarahView(), + settings: data, + maintainState: false, + ); + }, + _i17.StrukturOrganisasiView: (data) { + return _i10.MaterialPageRoute( + builder: (context) => const _i17.StrukturOrganisasiView(), settings: data, maintainState: false, ); @@ -309,12 +348,15 @@ class AdminIndexTrackingViewRouter extends _i1.RouterBase { class PimpinanIndexTrackingViewRoutes { static const danaSosialAdminView = 'dana-sosial-admin-view'; + static const danaSosialKhususView = 'dana-sosial-khusus-view'; + static const dataSiswaView = 'data-siswa-view'; static const profilView = 'profil-view'; static const all = { danaSosialAdminView, + danaSosialKhususView, dataSiswaView, profilView, }; @@ -326,13 +368,17 @@ class PimpinanIndexTrackingViewRouter extends _i1.RouterBase { PimpinanIndexTrackingViewRoutes.danaSosialAdminView, page: _i11.DanaSosialAdminView, ), + _i1.RouteDef( + PimpinanIndexTrackingViewRoutes.danaSosialKhususView, + page: _i12.DanaSosialKhususView, + ), _i1.RouteDef( PimpinanIndexTrackingViewRoutes.dataSiswaView, - page: _i12.DataSiswaView, + page: _i13.DataSiswaView, ), _i1.RouteDef( PimpinanIndexTrackingViewRoutes.profilView, - page: _i13.ProfilView, + page: _i14.ProfilView, ), ]; @@ -344,16 +390,23 @@ class PimpinanIndexTrackingViewRouter extends _i1.RouterBase { maintainState: false, ); }, - _i12.DataSiswaView: (data) { + _i12.DanaSosialKhususView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i12.DataSiswaView(), + builder: (context) => const _i12.DanaSosialKhususView(), settings: data, maintainState: false, ); }, - _i13.ProfilView: (data) { + _i13.DataSiswaView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i13.ProfilView(), + builder: (context) => const _i13.DataSiswaView(), + settings: data, + maintainState: false, + ); + }, + _i14.ProfilView: (data) { + return _i10.MaterialPageRoute( + builder: (context) => const _i14.ProfilView(), settings: data, maintainState: false, ); @@ -369,6 +422,8 @@ class PimpinanIndexTrackingViewRouter extends _i1.RouterBase { class UserIndexTrackingViewRoutes { static const danaSosialAdminView = 'dana-sosial-admin-view'; + static const danaSosialKhususView = 'dana-sosial-khusus-view'; + static const dataSiswaView = 'data-siswa-view'; static const profilView = 'profil-view'; @@ -381,6 +436,7 @@ class UserIndexTrackingViewRoutes { static const all = { danaSosialAdminView, + danaSosialKhususView, dataSiswaView, profilView, visiMisiView, @@ -395,25 +451,29 @@ class UserIndexTrackingViewRouter extends _i1.RouterBase { UserIndexTrackingViewRoutes.danaSosialAdminView, page: _i11.DanaSosialAdminView, ), + _i1.RouteDef( + UserIndexTrackingViewRoutes.danaSosialKhususView, + page: _i12.DanaSosialKhususView, + ), _i1.RouteDef( UserIndexTrackingViewRoutes.dataSiswaView, - page: _i12.DataSiswaView, + page: _i13.DataSiswaView, ), _i1.RouteDef( UserIndexTrackingViewRoutes.profilView, - page: _i13.ProfilView, + page: _i14.ProfilView, ), _i1.RouteDef( UserIndexTrackingViewRoutes.visiMisiView, - page: _i14.VisiMisiView, + page: _i15.VisiMisiView, ), _i1.RouteDef( UserIndexTrackingViewRoutes.sejarahView, - page: _i15.SejarahView, + page: _i16.SejarahView, ), _i1.RouteDef( UserIndexTrackingViewRoutes.strukturOrganisasiView, - page: _i16.StrukturOrganisasiView, + page: _i17.StrukturOrganisasiView, ), ]; @@ -425,37 +485,44 @@ class UserIndexTrackingViewRouter extends _i1.RouterBase { maintainState: false, ); }, - _i12.DataSiswaView: (data) { + _i12.DanaSosialKhususView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i12.DataSiswaView(), + builder: (context) => const _i12.DanaSosialKhususView(), settings: data, maintainState: false, ); }, - _i13.ProfilView: (data) { + _i13.DataSiswaView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i13.ProfilView(), + builder: (context) => const _i13.DataSiswaView(), settings: data, maintainState: false, ); }, - _i14.VisiMisiView: (data) { + _i14.ProfilView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i14.VisiMisiView(), + builder: (context) => const _i14.ProfilView(), settings: data, maintainState: false, ); }, - _i15.SejarahView: (data) { + _i15.VisiMisiView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i15.SejarahView(), + builder: (context) => const _i15.VisiMisiView(), settings: data, maintainState: false, ); }, - _i16.StrukturOrganisasiView: (data) { + _i16.SejarahView: (data) { return _i10.MaterialPageRoute( - builder: (context) => const _i16.StrukturOrganisasiView(), + builder: (context) => const _i16.SejarahView(), + settings: data, + maintainState: false, + ); + }, + _i17.StrukturOrganisasiView: (data) { + return _i10.MaterialPageRoute( + builder: (context) => const _i17.StrukturOrganisasiView(), settings: data, maintainState: false, ); @@ -468,7 +535,7 @@ class UserIndexTrackingViewRouter extends _i1.RouterBase { Map get pagesMap => _pagesMap; } -extension NavigatorStateExtension on _i17.NavigationService { +extension NavigatorStateExtension on _i18.NavigationService { Future navigateToSplashScreenView([ int? routerId, bool preventDuplicates = true, @@ -511,14 +578,17 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } - Future navigateToTambahDanaSosialView([ + Future navigateToTambahDanaSosialView({ + _i10.Key? key, + bool isKhusus = false, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { + }) async { return navigateTo(Routes.tambahDanaSosialView, + arguments: TambahDanaSosialViewArguments(key: key, isKhusus: isKhusus), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, @@ -545,6 +615,7 @@ extension NavigatorStateExtension on _i17.NavigationService { Future navigateToDetailDanaSosialView({ _i10.Key? key, required int id, + bool isKhusus = false, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -552,7 +623,8 @@ extension NavigatorStateExtension on _i17.NavigationService { transition, }) async { return navigateTo(Routes.detailDanaSosialView, - arguments: DetailDanaSosialViewArguments(key: key, id: id), + arguments: + DetailDanaSosialViewArguments(key: key, id: id, isKhusus: isKhusus), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, @@ -602,6 +674,22 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } + Future + navigateToNestedDanaSosialKhususViewInAdminIndexTrackingViewRouter([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo( + AdminIndexTrackingViewRoutes.danaSosialKhususView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future navigateToNestedDataSiswaViewInAdminIndexTrackingViewRouter([ int? routerId, bool preventDuplicates = true, @@ -690,6 +778,22 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } + Future + navigateToNestedDanaSosialKhususViewInPimpinanIndexTrackingViewRouter([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo( + PimpinanIndexTrackingViewRoutes.danaSosialKhususView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future navigateToNestedDataSiswaViewInPimpinanIndexTrackingViewRouter([ int? routerId, @@ -734,6 +838,21 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } + Future + navigateToNestedDanaSosialKhususViewInUserIndexTrackingViewRouter([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return navigateTo(UserIndexTrackingViewRoutes.danaSosialKhususView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future navigateToNestedDataSiswaViewInUserIndexTrackingViewRouter([ int? routerId, bool preventDuplicates = true, @@ -848,14 +967,17 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } - Future replaceWithTambahDanaSosialView([ + Future replaceWithTambahDanaSosialView({ + _i10.Key? key, + bool isKhusus = false, int? routerId, bool preventDuplicates = true, Map? parameters, Widget Function(BuildContext, Animation, Animation, Widget)? transition, - ]) async { + }) async { return replaceWith(Routes.tambahDanaSosialView, + arguments: TambahDanaSosialViewArguments(key: key, isKhusus: isKhusus), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, @@ -882,6 +1004,7 @@ extension NavigatorStateExtension on _i17.NavigationService { Future replaceWithDetailDanaSosialView({ _i10.Key? key, required int id, + bool isKhusus = false, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -889,7 +1012,8 @@ extension NavigatorStateExtension on _i17.NavigationService { transition, }) async { return replaceWith(Routes.detailDanaSosialView, - arguments: DetailDanaSosialViewArguments(key: key, id: id), + arguments: + DetailDanaSosialViewArguments(key: key, id: id, isKhusus: isKhusus), id: routerId, preventDuplicates: preventDuplicates, parameters: parameters, @@ -940,6 +1064,22 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } + Future + replaceWithNestedDanaSosialKhususViewInAdminIndexTrackingViewRouter([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith( + AdminIndexTrackingViewRoutes.danaSosialKhususView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future replaceWithNestedDataSiswaViewInAdminIndexTrackingViewRouter([ int? routerId, bool preventDuplicates = true, @@ -1028,6 +1168,22 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } + Future + replaceWithNestedDanaSosialKhususViewInPimpinanIndexTrackingViewRouter([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith( + PimpinanIndexTrackingViewRoutes.danaSosialKhususView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future replaceWithNestedDataSiswaViewInPimpinanIndexTrackingViewRouter([ int? routerId, @@ -1072,6 +1228,22 @@ extension NavigatorStateExtension on _i17.NavigationService { transition: transition); } + Future + replaceWithNestedDanaSosialKhususViewInUserIndexTrackingViewRouter([ + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + ]) async { + return replaceWith( + UserIndexTrackingViewRoutes.danaSosialKhususView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future replaceWithNestedDataSiswaViewInUserIndexTrackingViewRouter([ int? routerId, bool preventDuplicates = true, diff --git a/lib/app/core/custom_base_view_model.dart b/lib/app/core/custom_base_view_model.dart index f57e713..f9965da 100755 --- a/lib/app/core/custom_base_view_model.dart +++ b/lib/app/core/custom_base_view_model.dart @@ -2,6 +2,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; +import '../../services/other_function.dart'; import '../app.locator.dart'; class CustomBaseViewModel extends BaseViewModel { @@ -10,6 +11,7 @@ class CustomBaseViewModel extends BaseViewModel { final bottomSheetService = locator(); final snackbarService = locator(); final Future prefs = SharedPreferences.getInstance(); + final otherFunction = locator(); void back() { navigationService.back(); diff --git a/lib/main.dart b/lib/main.dart index 71842e3..997bc02 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; @@ -10,6 +12,7 @@ import 'app/themes/app_theme.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); + HttpOverrides.global = MyHttpOverrides(); await dotenv.load(fileName: ".env"); await setupAllLocator(); runApp(const MyApp()); @@ -38,3 +41,12 @@ Future setupAllLocator() async { // setupBottomsheetUi(); // setupSnackbarUi(); } + +class MyHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + return super.createHttpClient(context) + ..badCertificateCallback = + (X509Certificate cert, String host, int port) => true; + } +} diff --git a/lib/model/dana_sosial_model.dart b/lib/model/dana_sosial_model.dart index f2546f5..e503bcd 100644 --- a/lib/model/dana_sosial_model.dart +++ b/lib/model/dana_sosial_model.dart @@ -7,6 +7,9 @@ class DanaSosialModel { String? keterangan; String? jenisDonasi; String? status; + String? jenisBarang; + String? satuan; + String? jumlahBarang; String? createdAt; String? updatedAt; @@ -20,6 +23,9 @@ class DanaSosialModel { this.keterangan, this.jenisDonasi, this.status, + this.jenisBarang, + this.satuan, + this.jumlahBarang, this.createdAt, this.updatedAt}); @@ -33,6 +39,9 @@ class DanaSosialModel { jenisDonasi = json['jenis']; status = json['status'] == '0' ? 'Belum Dikonfirmasi' : 'Sudah Dikonfirmasi'; + jenisBarang = json['jenis_barang'] ?? ''; + satuan = json['satuan'] ?? ''; + jumlahBarang = json['jumlah_barang'] ?? ''; createdAt = json['created_at']; updatedAt = json['updated_at']; } @@ -47,6 +56,9 @@ class DanaSosialModel { data['ket'] = keterangan; data['jenis'] = jenisDonasi; data['status'] = status; + data['jenis_barang'] = jenisBarang; + data['satuan'] = satuan; + data['jumlah_barang'] = jumlahBarang; data['created_at'] = createdAt; data['updated_at'] = updatedAt; return data; diff --git a/lib/services/http_services.dart b/lib/services/http_services.dart index b925102..0bbfa21 100644 --- a/lib/services/http_services.dart +++ b/lib/services/http_services.dart @@ -32,7 +32,8 @@ class MyHttpServices { return await _dio.post(path, data: formData); } on DioError catch (e) { log.e(e.message); - log.e(e.response); + log.e(e.response!.statusCode); + log.e(e.response!.statusMessage); rethrow; } } diff --git a/lib/services/other_function.dart b/lib/services/other_function.dart index 73af85c..87ac57f 100644 --- a/lib/services/other_function.dart +++ b/lib/services/other_function.dart @@ -46,4 +46,61 @@ class OtherFunction { return ''; } } + + String changeMonthYear(String s) { + // get the last 2 digits + String month = s.substring(s.length - 2); + // get the first 4 digits + String year = s.substring(0, 4); + // return the month and year + switch (month) { + case '01': + return 'Januari $year'; + case '02': + return 'Februari $year'; + case '03': + return 'Maret $year'; + case '04': + return 'April $year'; + case '05': + return 'Mei $year'; + case '06': + return 'Juni $year'; + case '07': + return 'Juli $year'; + case '08': + return 'Agustus $year'; + case '09': + return 'September $year'; + case '10': + return 'Oktober $year'; + case '11': + return 'November $year'; + case '12': + return 'Desember $year'; + default: + return ''; + } + } + + String getDayOfWeek(String date) { + DateTime dateTime = DateTime.parse(date); + List daysOfWeek = [ + 'Senin', + 'Selasa', + 'Rabu', + 'Kamis', + 'Jumat', + 'Sabtu', + 'Minggu' + ]; + return daysOfWeek[dateTime.weekday - 1]; + } + + String capitalizeEachWord(String s) { + return s + .split(' ') + .map((word) => word[0].toUpperCase() + word.substring(1)) + .join(' '); + } } diff --git a/lib/ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart b/lib/ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart index 1295c9d..8aeb199 100644 --- a/lib/ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart +++ b/lib/ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_view.dart @@ -53,7 +53,7 @@ class AddSiswaDialogView extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - 'Tambah Siswa', + 'Tambah Anak Panti', style: boldTextStyle.copyWith( fontSize: 16, ), diff --git a/lib/ui/views/admin_index_tracking/admin_index_tracking_view.dart b/lib/ui/views/admin_index_tracking/admin_index_tracking_view.dart index 1520b98..39a2f43 100644 --- a/lib/ui/views/admin_index_tracking/admin_index_tracking_view.dart +++ b/lib/ui/views/admin_index_tracking/admin_index_tracking_view.dart @@ -67,12 +67,13 @@ class AdminIndexTrackingView extends StatelessWidget { ? sixthGrey : backgroundColor), title: Text( - item['name'], + model.otherFunction.capitalizeEachWord(item['name']), style: regularTextStyle.copyWith( color: model.currentIndex == model.bottomNavBarList.indexOf(item) ? sixthGrey : Colors.grey, + overflow: TextOverflow.ellipsis, ), ), backgroundColor: model.currentIndex == diff --git a/lib/ui/views/admin_index_tracking/admin_index_tracking_view_model.dart b/lib/ui/views/admin_index_tracking/admin_index_tracking_view_model.dart index 0793fdc..aa4722a 100644 --- a/lib/ui/views/admin_index_tracking/admin_index_tracking_view_model.dart +++ b/lib/ui/views/admin_index_tracking/admin_index_tracking_view_model.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:panti_asuhan/services/other_function.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; @@ -12,14 +13,16 @@ class AdminIndexTrackingViewModel extends IndexTrackingViewModel { final _navigationService = locator(); final _dialogService = locator(); final Future _prefs = SharedPreferences.getInstance(); + final otherFunction = locator(); final _bottomNavBarList = [ { - 'name': 'Siswa', + 'name': 'List', 'icon': Icons.people_alt_outlined, - 'header': 'List Siswa' + 'header': 'List Anak Panti' }, {'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial'}, + // {'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial Khusus'}, { 'name': 'Profil', 'icon': Icons.person_4_outlined, @@ -39,6 +42,7 @@ class AdminIndexTrackingViewModel extends IndexTrackingViewModel { final List _views = [ AdminIndexTrackingViewRoutes.dataSiswaView, AdminIndexTrackingViewRoutes.danaSosialAdminView, + // AdminIndexTrackingViewRoutes.danaSosialKhususView, AdminIndexTrackingViewRoutes.profilView, AdminIndexTrackingViewRoutes.visiMisiView, AdminIndexTrackingViewRoutes.sejarahView, diff --git a/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart b/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart index 638ff9d..506d57a 100644 --- a/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart +++ b/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart @@ -22,86 +22,18 @@ class DanaSosialAdminView extends StatelessWidget { Widget? child, ) { return Scaffold( - body: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 15, vertical: 10), - width: double.infinity, - decoration: BoxDecoration( - color: mainColor, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: mainGrey.withOpacity(0.5), - spreadRadius: 5, - blurRadius: 7, - offset: const Offset( - 0, 3), // changes position of shadow - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Dana Sosial Bulan Ini', - style: boldTextStyle.copyWith( - color: Colors.white, - fontSize: 20, - ), - ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Total Dana Sosial', - style: regularTextStyle.copyWith( - color: Colors.white, - fontSize: 15, - ), - ), - Text( - 'Rp. ${OtherFunction().commaFormat(model.jumlahDonasi)}', - style: regularTextStyle.copyWith( - color: Colors.white, - fontSize: 15, - ), - ), - ], - ), - ], - ), - ), - ), - const SizedBox(width: 10), - Container( - width: 50, - height: 50, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: mainColor, - ), - child: IconButton( - icon: const Icon( - Icons.filter_list, - color: Colors.white, - ), - onPressed: () { - model.filterDialog(context); - }, - ), - ), - ], - ), - const SizedBox(height: 25), - Expanded( - child: Container( + body: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 10), + Text( + "Laporan Harian", + style: + boldTextStyle.copyWith(fontSize: 15, color: Colors.black), + ), + Container( + padding: const EdgeInsets.all(10), + height: MediaQuery.of(context).size.height * 0.45, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), @@ -124,25 +56,384 @@ class DanaSosialAdminView extends StatelessWidget { ), ), ) - : const TheData(), + : const TheDataNewly(), ), - ), - ], + const SizedBox( + height: 30, + ), + Text( + "Laporan Bulanan", + style: + boldTextStyle.copyWith(fontSize: 15, color: Colors.black), + ), + Container( + padding: const EdgeInsets.all(15), + width: double.infinity, + height: MediaQuery.of(context).size.height * 0.25, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: + const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: model.monthIncomeOutcome.isEmpty + ? const Center( + child: Text( + 'Tidak ada data', + )) + : const HasilIncomeOutcome(), + ), + const SizedBox( + height: 30, + ), + Text( + "Laporan Tahunan", + style: + boldTextStyle.copyWith(fontSize: 15, color: Colors.black), + ), + Container( + padding: const EdgeInsets.all(15), + width: double.infinity, + height: MediaQuery.of(context).size.height * 0.25, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: + const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: model.yearIncomeOutcome.isNotEmpty + ? const TahunanWidget() + : const Center( + child: Text( + 'Tidak ada data', + ), + ), + ), + const SizedBox( + height: 30, + ), + Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: + const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Total Pemasukan :', + ), + const Expanded(child: SizedBox()), + Text( + 'Rp. ${OtherFunction().commaFormat(model.totalIncome)}', + ) + ], + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Total Pengeluaran :', + ), + const Expanded(child: SizedBox()), + Text( + 'Rp. ${OtherFunction().commaFormat(model.totalOutcome)}', + ) + ], + ), + ], + ), + ), + const SizedBox( + height: 30, + ), + ], + ), ), - floatingActionButton: model.role == 'admin' - ? FloatingActionButton( + floatingActionButton: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (model.role == 'admin') + FloatingActionButton( + mini: true, + heroTag: 'btn11', onPressed: () { model.goToTambahDanaSosial(); }, child: const Icon(Icons.add), - ) - : null, + ), + const SizedBox(width: 5), + FloatingActionButton( + mini: true, + heroTag: 'btn22', + onPressed: () { + model.filterDialog(context); + }, + child: const Icon(Icons.filter_list), + ), + ], + ), + floatingActionButtonLocation: FloatingActionButtonLocation.miniEndTop, ); }, ); } } +class TahunanWidget extends ViewModelWidget { + const TahunanWidget({ + super.key, + }); + + @override + Widget build(BuildContext context, DanaSosialAdminViewModel viewModel) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < viewModel.yearIncomeOutcome.length; i++) + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Tahun ${viewModel.yearIncomeOutcome[i]['tahun']}", + style: boldTextStyle.copyWith( + decoration: TextDecoration.underline, + fontSize: 17, + ), + ), + const SizedBox( + width: 10, + ), + if (viewModel.role == 'admin' || + viewModel.role == 'pimpinan') + Container( + alignment: Alignment.center, + width: 30, + height: 30, + decoration: BoxDecoration( + color: mainColor, + borderRadius: BorderRadius.circular(50), + ), + child: IconButton( + onPressed: () async { + // sini untuk laporan bulanan + await viewModel.goToLaporanTahunan( + viewModel.yearIncomeOutcome[i]['tahun']); + }, + icon: const Icon( + Icons.list_alt_outlined, + color: Colors.white, + size: 15, + ), + ), + ) + ], + ), + ), + const SizedBox( + height: 5, + ), + Table( + border: TableBorder.all( + color: Colors.grey, + ), + children: [ + const TableRow(children: [ + TableCell( + child: Center( + child: Text( + 'Pemasukan', + style: boldTextStyle, + ))), + TableCell( + child: Center( + child: Text( + 'Pengeluaran', + style: boldTextStyle, + ))) + ]), + TableRow(children: [ + TableCell( + child: Center( + child: Text( + 'Rp. ${OtherFunction().commaFormat(viewModel.yearIncomeOutcome[i]['pemasukan'])}', + style: italicTextStyle, + ))), + TableCell( + child: Center( + child: Text( + 'Rp. ${OtherFunction().commaFormat(viewModel.yearIncomeOutcome[i]['pengeluaran'])}', + style: italicTextStyle, + ))) + ]), + ], + ), + const SizedBox( + height: 5, + ), + const Divider( + color: Colors.grey, + thickness: 1, + ), + const SizedBox( + height: 5, + ), + ], + ) + ], + ), + ); + } +} + +class HasilIncomeOutcome extends ViewModelWidget { + const HasilIncomeOutcome({ + super.key, + }); + + @override + Widget build(BuildContext context, DanaSosialAdminViewModel viewModel) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < viewModel.monthIncomeOutcome.length; i++) + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + viewModel.otherFunction.changeMonthYear( + viewModel.monthIncomeOutcome[i]['month']), + style: boldTextStyle.copyWith( + decoration: TextDecoration.underline, + fontSize: 17, + ), + ), + const SizedBox( + width: 10, + ), + if (viewModel.role == 'admin' || + viewModel.role == 'pimpinan') + Container( + alignment: Alignment.center, + width: 30, + height: 30, + decoration: BoxDecoration( + color: mainColor, + borderRadius: BorderRadius.circular(50), + ), + child: IconButton( + onPressed: () async { + // sini untuk laporan bulanan + await viewModel.goToLaporanBulanan( + viewModel.monthIncomeOutcome[i]['month']); + }, + icon: const Icon( + Icons.list_alt_outlined, + color: Colors.white, + size: 15, + ), + ), + ) + ], + ), + ), + const SizedBox( + height: 5, + ), + Table( + border: TableBorder.all( + color: Colors.grey, + ), + children: [ + const TableRow(children: [ + TableCell( + child: Center( + child: Text( + 'Pemasukan', + style: boldTextStyle, + ))), + TableCell( + child: Center( + child: Text( + 'Pengeluaran', + style: boldTextStyle, + ))) + ]), + TableRow(children: [ + TableCell( + child: Center( + child: Text( + 'Rp. ${OtherFunction().commaFormat(viewModel.monthIncomeOutcome[i]['income'])}', + style: italicTextStyle, + ))), + TableCell( + child: Center( + child: Text( + 'Rp. ${OtherFunction().commaFormat(viewModel.monthIncomeOutcome[i]['outcome'])}', + style: italicTextStyle, + ))) + ]), + ], + ), + const SizedBox( + height: 5, + ), + const Divider( + color: Colors.grey, + thickness: 1, + ), + const SizedBox( + height: 5, + ), + ], + ) + ], + ), + ); + } +} + class TheData extends ViewModelWidget { const TheData({ super.key, @@ -154,6 +445,8 @@ class TheData extends ViewModelWidget { padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), itemCount: viewModel.danaSosialModelList.length, itemBuilder: (context, index) { + // viewModel.log.i(viewModel.danaSosialModelList[index].tanggal); + String jumlahDonasi = viewModel .danaSosialModelList[index].jenisDonasi != 'Barang' @@ -278,3 +571,329 @@ class TheData extends ViewModelWidget { ); } } + +class TheDataNewly extends ViewModelWidget { + const TheDataNewly({ + super.key, + }); + + @override + Widget build(BuildContext context, DanaSosialAdminViewModel viewModel) { + return ListView.builder( + itemCount: viewModel.filteredByDateData.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.only(bottom: 30), + child: Container( + padding: const EdgeInsets.all(5), + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(10)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${viewModel.otherFunction.changeMonthYear(viewModel.filteredByDateData[index]['month'])} ', + style: boldTextStyle.copyWith( + decoration: TextDecoration.underline, + fontSize: 17, + ), + ), + const SizedBox(height: 10), + for (int i = 0; + i < viewModel.filteredByDateData[index]['data'].length; + i++) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '${viewModel.filteredByDateData[index]['data'][i]['date']} : ${viewModel.otherFunction.getDayOfWeek(viewModel.filteredByDateData[index]['data'][i]['date'])}', + style: italicTextStyle.copyWith( + fontWeight: FontWeight.bold, fontSize: 15), + ), + const SizedBox( + width: 10, + ), + if (viewModel.role == 'admin' || + viewModel.role == 'pimpinan') + Container( + alignment: Alignment.center, + width: 35, + height: 35, + decoration: BoxDecoration( + color: mainColor, + borderRadius: BorderRadius.circular(35), + ), + child: IconButton( + onPressed: () { + viewModel.getLaporanHarian( + viewModel.filteredByDateData[index] + ['data'][i]['date'], + viewModel.otherFunction.getDayOfWeek( + viewModel.filteredByDateData[index] + ['data'][i]['date'])); + }, + icon: const Icon( + Icons.list_alt_outlined, + color: Colors.white, + size: 20, + ), + ), + ) + ], + ), + const SizedBox( + height: 10, + ), + Table( + border: TableBorder.all( + color: Colors.grey, + ), + columnWidths: viewModel.role == 'admin' + ? const { + 0: FlexColumnWidth( + 1), // 1/3 of the available width + 1: FlexColumnWidth( + 1.5), // 2/3 of the available width + 2: FlexColumnWidth( + 2.5), // 2/3 of the available width + 3: FlexColumnWidth( + 3), // 2/3 of the available width + 4: FlexColumnWidth( + 2), // 2/3 of the available width + } + : const { + 0: FlexColumnWidth( + 1), // 1/3 of the available width + 1: FlexColumnWidth( + 2), // 2/3 of the available width + 2: FlexColumnWidth( + 2), // 2/3 of the available width + 3: FlexColumnWidth( + 3), // 2/3 of the available width + }, + children: [ + TableRow( + children: [ + const TableCell( + child: Center( + child: Text( + 'No', + style: boldTextStyle, + ), + ), + ), + const TableCell( + child: Center( + child: Text( + 'Jenis', + style: boldTextStyle, + ))), + const TableCell( + child: Center( + child: Text( + 'Donatur', + style: boldTextStyle, + ))), + const TableCell( + child: Center( + child: Text( + 'Jumlah /\nKeterangan', + style: boldTextStyle, + ), + ), + ), + if (viewModel.role == 'admin') + const TableCell( + child: Center( + child: Text( + 'Aksi', + style: boldTextStyle, + ), + ), + ) + ], + ), + for (int j = 0; + j < + viewModel + .filteredByDateData[index]['data'][i] + ['data_dana'] + .length; + j++) + TableRow( + children: [ + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + child: Text( + '${j + 1}', + style: regularTextStyle, + ), + ), + ), + ), + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + // circle icon + child: viewModel + .filteredByDateData[index] + ['data'][i]['data_dana'] + [j] + .bentuk == + 'Pemasukan' + ? const JenisIconContainer( + color: Colors.green, + icon: Icons.arrow_upward, + ) + : const JenisIconContainer( + color: Colors.red, + icon: Icons.arrow_downward, + )), + ), + ), + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + child: Text( + '${viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].nama == '' ? '-' : viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].nama}', + style: regularTextStyle, + )), + )), + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + child: Text( + viewModel + .filteredByDateData[index] + ['data'][i]['data_dana'] + [j] + .jenisDonasi == + 'Uang' + ? 'Rp. ${viewModel.otherFunction.commaFormat(int.parse(viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].jumlah))}' + : viewModel + .filteredByDateData[index] + ['data'][i]['data_dana'][j] + .keterangan, + style: regularTextStyle, + ), + ), + ), + ), + if (viewModel.role == 'admin') + TableCell( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Wrap( + spacing: 5, + runSpacing: 10, + children: [ + GestureDetector( + onTap: () { + viewModel.goToEditDanaSosial( + int.parse(viewModel + .filteredByDateData[ + index]['data'][i] + ['data_dana'][j] + .idDanaSosial)); + }, + child: JenisIconContainer( + color: Colors.blue[600]!, + icon: Icons.edit, + ), + ), + GestureDetector( + onTap: () { + viewModel.deleteData( + int.parse(viewModel + .filteredByDateData[index] + ['data'][i] + ['data_dana'][j] + .idDanaSosial!), + ); + }, + child: const JenisIconContainer( + color: Colors.red, + icon: Icons.delete, + ), + ), + ], + ), + ), + ), + ) + ], + ), + ], + ), + const SizedBox(height: 10), + // create a horizontal line + const Divider( + color: Colors.grey, + thickness: 1.0, + ), + const SizedBox(height: 10), + ], + ), + ], + ), + ), + ); + }, + ); + } +} + +class JenisIconContainer extends StatelessWidget { + const JenisIconContainer({ + super.key, + required this.color, + required this.icon, + }); + + final Color color; + final IconData icon; + + @override + Widget build(BuildContext context) { + return Container( + width: 20, + height: 20, + alignment: Alignment.center, + decoration: BoxDecoration( + color: color, + shape: BoxShape.circle, + ), + child: Icon( + icon, + color: Colors.white, + size: 15, + ), + ); + } +} diff --git a/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view_model.dart b/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view_model.dart index 2d644a1..4853f5c 100644 --- a/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view_model.dart +++ b/lib/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view_model.dart @@ -1,5 +1,7 @@ import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_file_downloader/flutter_file_downloader.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../../app/app.dialogs.dart'; @@ -16,15 +18,23 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { final log = getLogger('DanaSosialAdminViewModel'); final _httpService = locator(); final easyLoading = locator(); + // final otherF + String url = dotenv.env['url']!; int bulan = DateTime.now().month; List danaSosialModelList = []; + List> filteredByDateData = []; // newly added + List> monthIncomeOutcome = []; // newly added + List> yearIncomeOutcome = []; // newly added + int totalIncome = 0; // newly added + int totalOutcome = 0; // newly added String? role; bool? isLogin; int jumlahDonasi = 0; + int jumlahPengeluaran = 0; Future init() async { await getData(); @@ -41,15 +51,16 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { easyLoading.showLoading(); // get the month var bulan = DateTime.now().month; - log.i(bulan); + // log.i(bulan); // change bulan to string and add 0 if it is less than 10 String bulanString = bulan.toString().length == 1 ? '0$bulan' : '$bulan'; - log.i(bulanString); + // log.i(bulanString); try { var response = await _httpService.get('pemasukan?bulan=$bulanString'); - log.i(response.data['jumlah']); + // log.i(response.data['jumlah']); // var theJumlahDonasi = response.data['jumlah']; jumlahDonasi = response.data['jumlah']; + jumlahPengeluaran = response.data['jumlah_pengeluaran']; } catch (e) { log.e(e); } finally { @@ -74,17 +85,110 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { } } - setBusy(false); + changeByDate(danaSosialModelList); + getTahunan(); notifyListeners(); - log.i(danaSosialModelList); + // log.i(danaSosialModelList.length); } catch (e) { log.e(e); - setBusy(false); } finally { + setBusy(false); easyLoading.dismissLoading(); } } + getTahunan() async { + try { + var response = await _httpService.get('data_tahunan'); + + var datanya = response.data['data']; + log.i(datanya.length); + for (int i = 0; i < datanya.length; i++) { + log.i(datanya[i]); + yearIncomeOutcome.add(datanya[i]); + } + notifyListeners(); + } catch (e) { + log.e(e); + } + } + + //newly added + changeByDate(List data) { + filteredByDateData = []; + + for (var item in data) { + var monthKey = + item.tanggal!.substring(0, 7); // Extracting the year and month + var dateKey = item.tanggal; // The full date + + var monthData = filteredByDateData.firstWhere( + (element) => element['month'] == monthKey, + orElse: () => { + 'month': monthKey, + 'data': [], + }); + + var dateData = + monthData['data'].firstWhere((element) => element['date'] == dateKey, + orElse: () => { + 'date': dateKey, + 'data_dana': [], + }); + + dateData['data_dana'].add(item); + + if (!monthData['data'].contains(dateData)) { + monthData['data'].add(dateData); + } + + if (!filteredByDateData.contains(monthData)) { + filteredByDateData.add(monthData); + } + } + filteredByDateData.sort((a, b) => a['month'].compareTo(b['month'])); + // log.i(filteredByDateData); + + // group the data by month + + monthIncomeOutcome = []; + + for (var item in filteredByDateData) { + var income = 0; + var outcome = 0; + + for (var dateData in item['data']) { + for (var danaSosialModel in dateData['data_dana']) { + if (danaSosialModel.bentuk == 'Pemasukan' && + danaSosialModel.jenisDonasi == 'Uang') { + income += int.parse(danaSosialModel.jumlah ?? '0'); + } else if (danaSosialModel.bentuk == 'Pengeluaran' && + danaSosialModel.jenisDonasi == 'Uang') { + outcome += int.parse(danaSosialModel.jumlah ?? '0'); + } + } + } + + monthIncomeOutcome.add({ + 'month': item['month'], + 'income': income, + 'outcome': outcome, + }); + } + + // log.i(monthIncomeOutcome); + totalIncome = 0; + totalOutcome = 0; + + for (var item in monthIncomeOutcome) { + totalIncome += int.parse(item['income'].toString()); + totalOutcome += int.parse(item['outcome'].toString()); + } + + log.i(totalIncome); + log.i(totalOutcome); + } + goToTambahDanaSosial() { navigationService.navigateTo(Routes.tambahDanaSosialView); } @@ -104,6 +208,8 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { danaSosialModelList = []; var datanya = response.data['data']; + jumlahDonasi = response.data['jumlah_donasi']; + jumlahPengeluaran = response.data['jumlah_pengeluaran']; // log.i(datanya.length); if (datanya.length > 0) { for (var item in datanya) { @@ -112,8 +218,9 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { } setBusy(false); + changeByDate(danaSosialModelList); notifyListeners(); - log.i(danaSosialModelList); + // log.i(danaSosialModelList); } catch (e) { log.e(e); setBusy(false); @@ -163,7 +270,7 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { sql = sql.substring(0, sql.length - 4); } - log.i(sql); + // log.i(sql); getFilter(sql); } @@ -194,12 +301,12 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { easyLoading.showLoading(); setBusy(true); try { - var response = await _httpService.postWithFormData( + await _httpService.postWithFormData( 'hapus_dana_sosial', FormData.fromMap({ 'id_dana_sosial': parse, })); - log.i(response.data); + // log.i(response.data); easyLoading.dismissLoading(); easyLoading.showSuccess('Data berhasil dihapus'); getData(); @@ -213,10 +320,152 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel { easyLoading.dismissLoading(); } } else { - log.i('cancel'); + // log.i('cancel'); return; } }, ); } + + goToLaporanBulanan(data) async { + // seeperate by "-", the first index is year, the second index is month + String year = data.substring(0, data.indexOf('-')); + String month = data.substring(data.indexOf('-') + 1); + + try { + setBusy(true); + easyLoading.customLoading("Mengunduh Laporan Bulanan..."); + await _httpService.get('laporan_bulanan?tahun=$year&bulan=$month'); + + // if (response.data) { + + String urlPdf = '${url}assets/pdf/laporan_bulanan_$month,$year.pdf'; + log.i(urlPdf); + FileDownloader.downloadFile( + url: urlPdf, + // name: "THE FILE NAME AFTER DOWNLOADING", //(optional) + onProgress: (fileName, progress) { + // change progress to 0-1 + double progressPercent = progress / 100; + + easyLoading.showProgress( + progressPercent, + "Downloading: $progress%", + ); + }, + onDownloadCompleted: (String path) { + easyLoading.dismissLoading(); + snackbarService.showSnackbar( + message: "Laporan Bulanan Berhasil Tersimpan di $path", + duration: const Duration(seconds: 3), + ); + }, + onDownloadError: (String error) { + // log.i('DOWNLOAD ERROR: $error'); + snackbarService.showSnackbar( + message: "Laporan Bulanan Gagal Tersimpan: $error", + duration: const Duration(seconds: 3), + ); + }); + // } + } catch (e) { + log.e(e); + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } + + getLaporanHarian(String filteredByDateData, String dayOfWeek) async { + String date = filteredByDateData; + String day = dayOfWeek; + + try { + setBusy(true); + easyLoading.customLoading("Mengunduh Laporan Harian..."); + await _httpService.get('laporan_harian?tanggal=$date&hari=$day'); + + String urlPdf = '${url}assets/pdf/laporan_harian_$day,$date.pdf'; + log.i(urlPdf); + + FileDownloader.downloadFile( + url: urlPdf, + // name: "THE FILE NAME AFTER DOWNLOADING", //(optional) + onProgress: (fileName, progress) { + // change progress to 0-1 + double progressPercent = progress / 100; + + easyLoading.showProgress( + progressPercent, + "Downloading: $progress%", + ); + }, + onDownloadCompleted: (String path) { + easyLoading.dismissLoading(); + snackbarService.showSnackbar( + message: "Laporan Harian Berhasil Tersimpan di $path", + duration: const Duration(seconds: 3), + ); + }, + onDownloadError: (String error) { + // log.i('DOWNLOAD ERROR: $error'); + snackbarService.showSnackbar( + message: "Laporan Harian Gagal Tersimpan: $error", + duration: const Duration(seconds: 3), + ); + }); + } catch (e) { + log.e(e); + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } + + goToLaporanTahunan(String yearIncomeOutcome) async { + // log.i(yearIncomeOutcome); + + try { + setBusy(true); + easyLoading.customLoading("Mengunduh Laporan Tahun..."); + await _httpService.get('laporan_tahunan?tahun=$yearIncomeOutcome'); + + // if (response.data) { + + String urlPdf = '${url}assets/pdf/laporan_tahunan_$yearIncomeOutcome.pdf'; + log.i(urlPdf); + FileDownloader.downloadFile( + url: urlPdf, + // name: "THE FILE NAME AFTER DOWNLOADING", //(optional) + onProgress: (fileName, progress) { + // change progress to 0-1 + double progressPercent = progress / 100; + + easyLoading.showProgress( + progressPercent, + "Downloading: $progress%", + ); + }, + onDownloadCompleted: (String path) { + easyLoading.dismissLoading(); + snackbarService.showSnackbar( + message: "Laporan Tahunan Berhasil Tersimpan di $path", + duration: const Duration(seconds: 3), + ); + }, + onDownloadError: (String error) { + // log.i('DOWNLOAD ERROR: $error'); + snackbarService.showSnackbar( + message: "Laporan Tahunan Gagal Tersimpan: $error", + duration: const Duration(seconds: 3), + ); + }); + // } + } catch (e) { + log.e(e); + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } } diff --git a/lib/ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view.dart b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view.dart new file mode 100644 index 0000000..f15d0da --- /dev/null +++ b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; +import 'package:stacked_services/stacked_services.dart'; +import 'package:validatorless/validatorless.dart'; + +import '../../../../widgets/my_button.dart'; +import '../../../../widgets/my_textformfield.dart'; +import './add_donatur_dialog_view_model.dart'; + +class AddDonaturDialogView extends StatelessWidget { + final DialogRequest? request; + final Function(DialogResponse)? completer; + + const AddDonaturDialogView({ + Key? key, + this.request, + this.completer, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => AddDonaturDialogViewModel(), + onViewModelReady: (AddDonaturDialogViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + AddDonaturDialogViewModel model, + Widget? child, + ) { + return Dialog( + child: Container( + padding: const EdgeInsets.all(20), + child: Form( + key: model.formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + 'Tambah Donatur', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 20), + MyTextFormField( + controller: model.namaController, + hintText: 'Masukkan Nama Donatur', + labelText: 'Nama Donatur', + validator: Validatorless.required( + 'Nama Donatur tidak boleh kosong'), + ), + const SizedBox(height: 20), + SizedBox( + width: 200, + child: MyButton( + text: 'Tambah', + onPressed: () async { + if (model.formKey.currentState!.validate()) { + // hide keyboard + FocusScope.of(context).unfocus(); + bool res = await model.addDonatur(); + if (res) { + completer!(DialogResponse(confirmed: true)); + } + } + }, + ), + ), + ], + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view_model.dart b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view_model.dart new file mode 100644 index 0000000..31ea2bc --- /dev/null +++ b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/add_donatur_dialog/add_donatur_dialog_view_model.dart @@ -0,0 +1,39 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../app/app.locator.dart'; +import '../../../../../app/app.logger.dart'; +import '../../../../../app/core/custom_base_view_model.dart'; +import '../../../../../services/http_services.dart'; +import '../../../../../services/my_easyloading.dart'; + +class AddDonaturDialogViewModel extends CustomBaseViewModel { + final log = getLogger('AddDonaturDialogViewModel'); + final _httpService = locator(); + final easyLoading = locator(); + + final formKey = GlobalKey(); + TextEditingController namaController = TextEditingController(); + + Future init() async {} + + Future addDonatur() async { + setBusy(true); + easyLoading.showLoading(); + try { + await _httpService.postWithFormData( + 'donatur', + FormData.fromMap({ + 'nama_donatur': namaController.text, + })); + + return true; + } catch (e) { + log.e(e); + return false; + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } +} diff --git a/lib/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view.dart b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view.dart new file mode 100644 index 0000000..8272453 --- /dev/null +++ b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view.dart @@ -0,0 +1,737 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; + +import '../../../../app/themes/app_colors.dart'; +import '../../../../app/themes/app_text.dart'; +import '../../../../services/other_function.dart'; +import '../dana_sosial_admin/dana_sosial_admin_view.dart'; +import './dana_sosial_khusus_view_model.dart'; + +class DanaSosialKhususView extends StatelessWidget { + const DanaSosialKhususView({super.key}); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => DanaSosialKhususViewModel(), + onViewModelReady: (DanaSosialKhususViewModel model) async { + await model.init(); + }, + builder: ( + BuildContext context, + DanaSosialKhususViewModel model, + Widget? child, + ) { + return Scaffold( + body: Column( + children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Expanded( + // child: Container( + // padding: const EdgeInsets.symmetric( + // horizontal: 15, vertical: 10), + // width: double.infinity, + // decoration: BoxDecoration( + // color: mainColor, + // borderRadius: BorderRadius.circular(10), + // boxShadow: [ + // BoxShadow( + // color: mainGrey.withOpacity(0.5), + // spreadRadius: 5, + // blurRadius: 7, + // offset: const Offset( + // 0, 3), // changes position of shadow + // ), + // ], + // ), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // 'Dana Sosial Bulan Ini', + // style: boldTextStyle.copyWith( + // color: Colors.white, + // fontSize: 20, + // ), + // ), + // const SizedBox(height: 10), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // 'Total Dana Sosial', + // style: regularTextStyle.copyWith( + // color: Colors.white, + // fontSize: 15, + // ), + // ), + // Text( + // 'Rp. ${OtherFunction().commaFormat(model.jumlahDonasi)}', + // style: regularTextStyle.copyWith( + // color: Colors.white, + // fontSize: 15, + // ), + // ), + // ], + // ), + // const SizedBox(height: 10), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // 'Pengeluaran Dana Sosial', + // style: regularTextStyle.copyWith( + // color: Colors.white, + // fontSize: 15, + // ), + // ), + // Text( + // 'Rp. ${OtherFunction().commaFormat(model.jumlahPengeluaran)}', + // style: regularTextStyle.copyWith( + // color: Colors.white, + // fontSize: 15, + // ), + // ), + // ], + // ), + // ], + // ), + // ), + // ), + // const SizedBox(width: 10), + // Container( + // width: 50, + // height: 50, + // decoration: const BoxDecoration( + // shape: BoxShape.circle, + // color: mainColor, + // ), + // child: IconButton( + // icon: const Icon( + // Icons.filter_list, + // color: Colors.white, + // ), + // onPressed: () { + // model.filterDialog(context); + // }, + // ), + // ), + // ], + // ), + const SizedBox(height: 10), + Expanded( + flex: 4, + child: Container( + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: + const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: (model.danaSosialModelList.isEmpty) + ? Center( + child: Text( + 'Tidak ada data', + style: boldTextStyle.copyWith( + fontSize: 20, + ), + ), + ) + : const TheDataNewly(), + ), + ), + const SizedBox( + height: 20, + ), + Expanded( + flex: 2, + child: Container( + padding: const EdgeInsets.all(15), + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: + const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: model.monthIncomeOutcome.isEmpty + ? const Center( + child: Text( + 'Tidak ada data', + )) + : const HasilIncomeOutcome(), + ), + ), + const SizedBox( + height: 20, + ), + Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Total Pemasukan :', + ), + const Expanded(child: SizedBox()), + Text( + 'Rp. ${OtherFunction().commaFormat(model.totalIncome)}', + ) + ], + ), + ), + ], + ), + floatingActionButton: model.role == 'admin' + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (model.role == 'admin') + FloatingActionButton( + heroTag: 'btn1', + onPressed: () { + model.goToTambahDanaSosial(); + }, + child: const Icon(Icons.add), + ), + if (model.role == 'admin') const SizedBox(width: 10), + if (model.role == 'admin') + FloatingActionButton( + heroTag: 'btn2', + onPressed: () async { + bool res = await model.addDonatur(); + model.log.i(res); + }, + child: const Icon(Icons.person_add_alt), + ), + const SizedBox(width: 10), + FloatingActionButton( + heroTag: 'btn3', + onPressed: () { + model.filterDialog(context); + }, + child: const Icon(Icons.filter_list), + ), + ], + ) + : null, + floatingActionButtonLocation: FloatingActionButtonLocation.miniEndTop, + ); + }, + ); + } +} + +class TheData extends ViewModelWidget { + const TheData({ + super.key, + }); + + @override + Widget build(BuildContext context, DanaSosialKhususViewModel viewModel) { + return ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + itemCount: viewModel.danaSosialModelList.length, + itemBuilder: (context, index) { + String jumlahDonasi = viewModel + .danaSosialModelList[index].jenisDonasi != + 'Barang' + ? OtherFunction().commaFormat( + int.parse(viewModel.danaSosialModelList[index].jumlah ?? '0')) + : '0'; + return Card( + child: ListTile( + title: Text(viewModel.danaSosialModelList[index].tanggal ?? '', + style: boldTextStyle.copyWith(fontSize: 13, color: mainColor)), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + viewModel.danaSosialModelList[index].bentuk == 'Pemasukan' + ? 'Pemasukan' + : 'Pengeluaran', + style: boldTextStyle.copyWith( + fontSize: 14, + color: viewModel.danaSosialModelList[index].bentuk == + 'Pemasukan' + ? Colors.green + : Colors.red, + ), + ), + Text( + viewModel.danaSosialModelList[index].nama ?? '-', + style: regularTextStyle.copyWith( + fontSize: 13, + color: viewModel.danaSosialModelList[index].bentuk == + 'Pemasukan' + ? Colors.green + : Colors.red, + ), + ), + Text( + // viewModel.danaSosialModelList[index].jenisDonasi == 'Uang' + // ? (viewModel.isLogin == true ? 'Rp. $jumlahDonasi' : '-') + // : 'Donasi Barang', + viewModel.danaSosialModelList[index].bentuk == 'Pemasukan' + ? (viewModel.danaSosialModelList[index].jenisDonasi == + 'Uang' + ? (viewModel.isLogin == true + ? 'Rp. $jumlahDonasi' + : '-') + : 'Donasi Barang') + : (viewModel.danaSosialModelList[index].jenisDonasi == + 'Uang' + ? (viewModel.isLogin == true + ? 'Rp. $jumlahDonasi' + : '-') + : 'Pengeluaran Barang'), + style: regularTextStyle.copyWith( + fontSize: 13, + color: viewModel.danaSosialModelList[index].bentuk == + 'Pemasukan' + ? Colors.green + : Colors.red, + ), + ), + Text( + viewModel.danaSosialModelList[index].status ?? '', + style: regularTextStyle.copyWith( + fontSize: 13, + color: viewModel.danaSosialModelList[index].status == + 'Belum Dikonfirmasi' + ? Colors.red + : Colors.green, + ), + ), + ], + ), + trailing: viewModel.isLogin == null + ? null + : (viewModel.isLogin == true + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: mainColor, + borderRadius: BorderRadius.circular(50), + ), + child: IconButton( + onPressed: () { + viewModel.goToEditDanaSosial(int.parse(viewModel + .danaSosialModelList[index].idDanaSosial!)); + }, + icon: const Icon( + Icons.edit, + color: Colors.white, + ), + ), + ), + const SizedBox(width: 10), + Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(50), + ), + child: IconButton( + onPressed: () { + viewModel.deleteData(int.parse(viewModel + .danaSosialModelList[index].idDanaSosial!)); + }, + icon: const Icon( + Icons.delete, + color: Colors.white, + ), + ), + ), + ], + ) + : null), + ), + ); + }, + ); + } +} + +class TheDataNewly extends ViewModelWidget { + const TheDataNewly({ + super.key, + }); + + @override + Widget build(BuildContext context, DanaSosialKhususViewModel viewModel) { + return ListView.builder( + itemCount: viewModel.filteredByDateData.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.only(bottom: 30), + child: Container( + padding: const EdgeInsets.all(5), + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: mainGrey.withOpacity(0.2), + spreadRadius: 5, + blurRadius: 7, + offset: const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${viewModel.otherFunction.changeMonthYear(viewModel.filteredByDateData[index]['month'])} ', + style: boldTextStyle.copyWith( + decoration: TextDecoration.underline, + fontSize: 17, + ), + ), + const SizedBox(height: 10), + for (int i = 0; + i < viewModel.filteredByDateData[index]['data'].length; + i++) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${viewModel.filteredByDateData[index]['data'][i]['date']} : ${viewModel.otherFunction.getDayOfWeek(viewModel.filteredByDateData[index]['data'][i]['date'])}', + style: italicTextStyle.copyWith( + fontWeight: FontWeight.bold, fontSize: 15), + ), + const SizedBox( + height: 10, + ), + Table( + border: TableBorder.all( + color: Colors.grey, + ), + columnWidths: viewModel.role == 'admin' + ? const { + 0: FlexColumnWidth( + 1), // 1/3 of the available width + 1: FlexColumnWidth( + 1.5), // 2/3 of the available width + 2: FlexColumnWidth( + 2.5), // 2/3 of the available width + 3: FlexColumnWidth( + 3), // 2/3 of the available width + 4: FlexColumnWidth( + 2), // 2/3 of the available width + } + : const { + 0: FlexColumnWidth( + 1), // 1/3 of the available width + 1: FlexColumnWidth( + 2), // 2/3 of the available width + 2: FlexColumnWidth( + 2), // 2/3 of the available width + 3: FlexColumnWidth( + 3), // 2/3 of the available width + }, + children: [ + TableRow( + children: [ + const TableCell( + child: Center( + child: Text( + 'No', + style: boldTextStyle, + ), + ), + ), + const TableCell( + child: Center( + child: Text( + 'Jenis', + style: boldTextStyle, + ))), + const TableCell( + child: Center( + child: Text( + 'Donatur', + style: boldTextStyle, + ))), + const TableCell( + child: Center( + child: Text( + 'Jumlah /\nKeterangan', + style: boldTextStyle, + ), + ), + ), + if (viewModel.role == 'admin') + const TableCell( + child: Center( + child: Text( + 'Aksi', + style: boldTextStyle, + ), + ), + ) + ], + ), + for (int j = 0; + j < + viewModel + .filteredByDateData[index]['data'][i] + ['data_dana'] + .length; + j++) + TableRow( + children: [ + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + child: Text( + '${j + 1}', + style: regularTextStyle, + ), + ), + ), + ), + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + // circle icon + child: viewModel + .filteredByDateData[index] + ['data'][i]['data_dana'] + [j] + .bentuk == + 'Pemasukan' + ? const JenisIconContainer( + color: Colors.green, + icon: Icons.arrow_upward, + ) + : const JenisIconContainer( + color: Colors.red, + icon: Icons.arrow_downward, + )), + ), + ), + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + child: Text( + '${viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].nama == '' ? '-' : viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].nama}', + style: regularTextStyle, + )), + )), + TableCell( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Center( + child: Text( + viewModel + .filteredByDateData[index] + ['data'][i]['data_dana'] + [j] + .jenisDonasi == + 'Uang' + ? 'Rp. ${viewModel.otherFunction.commaFormat(int.parse(viewModel.filteredByDateData[index]['data'][i]['data_dana'][j].jumlah))}' + : viewModel + .filteredByDateData[index] + ['data'][i]['data_dana'][j] + .keterangan, + style: regularTextStyle, + ), + ), + ), + ), + if (viewModel.role == 'admin') + TableCell( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + child: Wrap( + runSpacing: 10, + spacing: 5, + children: [ + GestureDetector( + onTap: () { + viewModel.goToEditDanaSosial( + int.parse(viewModel + .filteredByDateData[ + index]['data'][i] + ['data_dana'][j] + .idDanaSosial)); + }, + child: JenisIconContainer( + color: Colors.blue[600]!, + icon: Icons.edit, + ), + ), + GestureDetector( + onTap: () { + viewModel.deleteData( + int.parse(viewModel + .filteredByDateData[index] + ['data'][i] + ['data_dana'][j] + .idDanaSosial!), + ); + }, + child: const JenisIconContainer( + color: Colors.red, + icon: Icons.delete, + ), + ), + ], + ), + ), + ), + ) + ], + ), + ], + ), + const SizedBox(height: 10), + // create a horizontal line + const Divider( + color: Colors.grey, + thickness: 1.0, + ), + const SizedBox(height: 10), + ], + ), + ], + ), + ), + ); + }, + ); + } +} + +class HasilIncomeOutcome extends ViewModelWidget { + const HasilIncomeOutcome({ + super.key, + }); + + @override + Widget build(BuildContext context, DanaSosialKhususViewModel viewModel) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < viewModel.monthIncomeOutcome.length; i++) + Column( + children: [ + Text( + viewModel.otherFunction.changeMonthYear( + viewModel.monthIncomeOutcome[i]['month']), + style: boldTextStyle.copyWith( + decoration: TextDecoration.underline, + fontSize: 17, + ), + ), + const SizedBox( + height: 5, + ), + Table( + border: TableBorder.all( + color: Colors.grey, + ), + children: [ + const TableRow(children: [ + TableCell( + child: Center( + child: Text( + 'Pemasukan', + style: boldTextStyle, + ))), + TableCell( + child: Center( + child: Text( + 'Pengeluaran', + style: boldTextStyle, + ))) + ]), + TableRow(children: [ + TableCell( + child: Center( + child: Text( + 'Rp. ${OtherFunction().commaFormat(viewModel.monthIncomeOutcome[i]['income'])}', + style: italicTextStyle, + ))), + TableCell( + child: Center( + child: Text( + 'Rp. ${OtherFunction().commaFormat(viewModel.monthIncomeOutcome[i]['outcome'])}', + style: italicTextStyle, + ))) + ]), + ], + ), + const SizedBox( + height: 5, + ), + const Divider( + color: Colors.grey, + thickness: 1, + ), + const SizedBox( + height: 5, + ), + ], + ) + ], + ), + ); + } +} diff --git a/lib/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view_model.dart b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view_model.dart new file mode 100644 index 0000000..224b57b --- /dev/null +++ b/lib/ui/views/admin_index_tracking/dana_sosial_khusus/dana_sosial_khusus_view_model.dart @@ -0,0 +1,327 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../../../../app/app.dialogs.dart'; +import '../../../../app/app.locator.dart'; +import '../../../../app/app.logger.dart'; +import '../../../../app/app.router.dart'; +import '../../../../app/core/custom_base_view_model.dart'; +import '../../../../model/dana_sosial_model.dart'; +import '../../../../services/http_services.dart'; +import '../../../../services/my_easyloading.dart'; +import '../../../../services/other_function.dart'; + +class DanaSosialKhususViewModel extends CustomBaseViewModel { + final log = getLogger('DanaSosialKhususViewModel'); + final _httpService = locator(); + final easyLoading = locator(); + + int bulan = DateTime.now().month; + + List danaSosialModelList = []; + List> filteredByDateData = []; // newly added + List> monthIncomeOutcome = []; // newly added + int totalIncome = 0; // newly added + int totalOutcome = 0; // newly added + + String? role; + bool? isLogin; + + int jumlahDonasi = 0; + int jumlahPengeluaran = 0; + + Future init() async { + await getData(); + await getJumlahDonasi(); + prefs.then((SharedPreferences prefs) { + role = prefs.getString('role'); + isLogin = prefs.getBool('isLogin'); + }); + // log.i(bulan); + } + + getJumlahDonasi() async { + setBusy(true); + easyLoading.showLoading(); + // get the month + var bulan = DateTime.now().month; + log.i(bulan); + // change bulan to string and add 0 if it is less than 10 + String bulanString = bulan.toString().length == 1 ? '0$bulan' : '$bulan'; + log.i(bulanString); + try { + var response = + await _httpService.get('pemasukan_khusus?bulan=$bulanString'); + log.i(response.data['jumlah']); + // var theJumlahDonasi = response.data['jumlah']; + jumlahDonasi = response.data['jumlah']; + jumlahPengeluaran = response.data['jumlah_pengeluaran']; + } catch (e) { + log.e(e); + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } + + getData() async { + setBusy(true); + easyLoading.showLoading(); + try { + var response = await _httpService.get('dana_sosial_khusus'); + // log.i(response.data); + danaSosialModelList = []; + + var datanya = response.data['data']; + // log.i(datanya.length); + if (datanya.length > 0) { + for (var item in datanya) { + danaSosialModelList.add(DanaSosialModel.fromJson(item)); + } + } + + setBusy(false); + notifyListeners(); + // log.i(danaSosialModelList.length); + changeByDate(danaSosialModelList); + } catch (e) { + log.e(e); + setBusy(false); + } finally { + easyLoading.dismissLoading(); + } + } + + //newly added + changeByDate(List data) { + filteredByDateData = []; + + for (var item in data) { + var monthKey = + item.tanggal!.substring(0, 7); // Extracting the year and month + var dateKey = item.tanggal; // The full date + + var monthData = filteredByDateData.firstWhere( + (element) => element['month'] == monthKey, + orElse: () => { + 'month': monthKey, + 'data': [], + }); + + var dateData = + monthData['data'].firstWhere((element) => element['date'] == dateKey, + orElse: () => { + 'date': dateKey, + 'data_dana': [], + }); + + dateData['data_dana'].add(item); + + if (!monthData['data'].contains(dateData)) { + monthData['data'].add(dateData); + } + + if (!filteredByDateData.contains(monthData)) { + filteredByDateData.add(monthData); + } + } + filteredByDateData.sort((a, b) => a['month'].compareTo(b['month'])); + // log.i(filteredByDateData); + + // group the data by month + + monthIncomeOutcome = []; + + for (var item in filteredByDateData) { + var income = 0; + var outcome = 0; + + for (var dateData in item['data']) { + for (var danaSosialModel in dateData['data_dana']) { + if (danaSosialModel.bentuk == 'Pemasukan' && + danaSosialModel.jenisDonasi == 'Uang') { + income += int.parse(danaSosialModel.jumlah ?? '0'); + } else if (danaSosialModel.bentuk == 'Pengeluaran' && + danaSosialModel.jenisDonasi == 'Uang') { + outcome += int.parse(danaSosialModel.jumlah ?? '0'); + } + } + } + + monthIncomeOutcome.add({ + 'month': item['month'], + 'income': income, + 'outcome': outcome, + }); + } + + // log.i(monthIncomeOutcome); + totalIncome = 0; + totalOutcome = 0; + + for (var item in monthIncomeOutcome) { + totalIncome += int.parse(item['income'].toString()); + totalOutcome += int.parse(item['outcome'].toString()); + } + + log.i(totalIncome); + log.i(totalOutcome); + } + + goToTambahDanaSosial() { + navigationService.navigateTo( + Routes.tambahDanaSosialView, + arguments: const TambahDanaSosialViewArguments(isKhusus: true), + ); + } + + getFilter(String sql) async { + setBusy(true); + easyLoading.showLoading(); + FormData formData = FormData.fromMap({ + 'sql': sql, + }); + try { + var response = await _httpService.postWithFormData( + 'filter_dana_khusus', + formData, + ); + // log.i(response.data); + danaSosialModelList = []; + + var datanya = response.data['data']; + jumlahDonasi = response.data['jumlah_donasi']; + jumlahPengeluaran = response.data['jumlah_pengeluaran']; + // log.i(datanya.length); + if (datanya.length > 0) { + for (var item in datanya) { + danaSosialModelList.add(DanaSosialModel.fromJson(item)); + } + } + + setBusy(false); + notifyListeners(); + log.i(danaSosialModelList); + } catch (e) { + log.e(e); + setBusy(false); + } finally { + easyLoading.dismissLoading(); + } + } + + filterDialog(BuildContext context) async { + // create a dialog + final res = await dialogService.showCustomDialog( + variant: DialogType.filterDialogView, + ); + + if (res!.confirmed) { + String jenisDonasi = res.data['jenisDonasi'] == 'Semua' + ? '' + : "jenis = '${res.data['jenisDonasi']}' and "; + String bulan = res.data['bulan'] == 'Semua' + ? '' + : "tanggal like '%-${OtherFunction().changeMonth(res.data['bulan'])}-%' and "; + String tahun = res.data['tahun'] == 'Semua' + ? '' + : 'tanggal like "%${res.data['tahun']}-%" and '; + String status = res.data['status'] == 'Semua' + ? '' + : (res.data['status'] == 'Belum Dikonfirmasi') + ? 'status = 0' + : 'status = 1'; + + if (jenisDonasi == 'Semua' && + bulan == 'Semua' && + tahun == 'Semua' && + status == 'Semua') { + getData(); + return; + } + + String sql = + 'Select * from tb_dana_sosial_khusus where $jenisDonasi$bulan$tahun$status'; + + // check the last 3 character if it is 'or ' then remove it + // if (sql.substring(sql.length - 3) == 'or ') { + // sql = sql.substring(0, sql.length - 3); + // } + if (sql.substring(sql.length - 4) == 'and ') { + sql = sql.substring(0, sql.length - 4); + } + + log.i(sql); + + getFilter(sql); + } + } + + goToEditDanaSosial(int id) async { + navigationService.navigateTo( + Routes.detailDanaSosialView, + arguments: DetailDanaSosialViewArguments( + id: id, + isKhusus: true, + ), + ); + } + + deleteData(int parse) async { + await dialogService + .showDialog( + title: 'Hapus Data', + description: 'Apakah anda yakin ingin menghapus data ini?', + buttonTitle: 'Hapus', + cancelTitle: 'Batal', + buttonTitleColor: Colors.red, + cancelTitleColor: Colors.green, + ) + .then( + (value) async { + if (value!.confirmed) { + easyLoading.showLoading(); + setBusy(true); + try { + var response = await _httpService.postWithFormData( + 'hapus_dana_sosial_khusus', + FormData.fromMap({ + 'id_dana_sosial': parse, + })); + log.i(response.data); + easyLoading.dismissLoading(); + easyLoading.showSuccess('Data berhasil dihapus'); + getData(); + getJumlahDonasi(); + } on DioError catch (e) { + // easyLoading.dismissLoading(); + log.e(e); + easyLoading.showError('Terjadi kesalahan'); + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } else { + log.i('cancel'); + return; + } + }, + ); + } + + Future addDonatur() async { + var res = await dialogService.showCustomDialog( + variant: DialogType.addDonaturDialogView, + ); + + if (res!.confirmed) { + snackbarService.showSnackbar( + message: 'Berhasil menambahkan donatur', + duration: const Duration(seconds: 2), + ); + return true; + } + return false; + } +} diff --git a/lib/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart b/lib/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart index 6efae95..78df016 100644 --- a/lib/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart +++ b/lib/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart @@ -44,7 +44,7 @@ class DataSiswaView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - 'Total Siswa', + 'Total Anak Panti', style: regularTextStyle.copyWith( color: Colors.white, fontSize: 15, @@ -93,8 +93,23 @@ class DataSiswaView extends StatelessWidget { itemBuilder: (context, index) { return Card( child: ListTile( + leading: Container( + alignment: Alignment.center, + width: 25, + height: 25, + decoration: BoxDecoration( + color: mainColor, + borderRadius: BorderRadius.circular(50), + ), + child: Text( + '${index + 1}', + style: regularTextStyle.copyWith( + color: Colors.white), + ), + ), title: Text( - model.siswaModelList[index].nama ?? '', + model.otherFunction.capitalizeEachWord( + model.siswaModelList[index].nama!), style: boldTextStyle.copyWith( fontSize: 13, color: mainColor)), subtitle: Text( diff --git a/lib/ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart b/lib/ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart index 6b6ed0d..799610e 100644 --- a/lib/ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart +++ b/lib/ui/views/admin_index_tracking/edit_siswa/edit_dialog_siswa/edit_dialog_siswa_view.dart @@ -49,7 +49,7 @@ class EditDialogSiswaView extends StatelessWidget { children: [ const Center( child: Text( - 'Edit Data Siswa', + 'Edit Data Anak Panti', style: boldTextStyle, ), ), diff --git a/lib/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart b/lib/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart index 7c6d30a..ea942ff 100644 --- a/lib/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart +++ b/lib/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart @@ -29,7 +29,7 @@ class EditSiswaView extends StatelessWidget { return Scaffold( appBar: AppBar( title: const Text( - "Informasi Data Siswa", + "Informasi Data Anak Panti", style: TextStyle( color: Colors.white, fontSize: 20, diff --git a/lib/ui/views/admin_index_tracking/filter_dialog/filter_dialog_view_model.dart b/lib/ui/views/admin_index_tracking/filter_dialog/filter_dialog_view_model.dart index 7714d26..eed7c57 100644 --- a/lib/ui/views/admin_index_tracking/filter_dialog/filter_dialog_view_model.dart +++ b/lib/ui/views/admin_index_tracking/filter_dialog/filter_dialog_view_model.dart @@ -16,6 +16,7 @@ class FilterDialogViewModel extends CustomBaseViewModel { 'April', 'Mei', 'Juni', + 'Juli', 'Agustus', 'September', 'Oktober', @@ -26,6 +27,7 @@ class FilterDialogViewModel extends CustomBaseViewModel { String tahun = 'Semua'; List tahunList = [ 'Semua', + '2024', '2023', '2022', ]; diff --git a/lib/ui/views/admin_index_tracking/profil/profil_view.dart b/lib/ui/views/admin_index_tracking/profil/profil_view.dart index 1821fb7..2476572 100644 --- a/lib/ui/views/admin_index_tracking/profil/profil_view.dart +++ b/lib/ui/views/admin_index_tracking/profil/profil_view.dart @@ -47,7 +47,7 @@ class ProfilView extends StatelessWidget { SizedBox(width: 15), Expanded( child: Text( - "081 343 434 343", + "085 298 962 023", textAlign: TextAlign.justify, style: regularTextStyle, ), diff --git a/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart b/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart index 9d74c1f..ca08d4f 100644 --- a/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart +++ b/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart @@ -56,6 +56,13 @@ class StrukturOrganisasiView extends StatelessWidget { const SizedBox( height: 20, ), + FirstWidget( + title: 'Wakil Bendahara', + data: model.dataWakilBendahara, + ), + const SizedBox( + height: 20, + ), SecondWidget( title: 'Seksi Pengasuh', data: model.dataPengasuh, diff --git a/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view_model.dart b/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view_model.dart index b0e1650..ed094d6 100644 --- a/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view_model.dart +++ b/lib/ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view_model.dart @@ -16,6 +16,7 @@ class StrukturOrganisasiViewModel extends CustomBaseViewModel { Map dataKetua = {}; Map dataSekretaris = {}; Map dataBendahara = {}; + Map dataWakilBendahara = {}; Map dataPengasuh = {}; int dataPengasuhLength = 0; @@ -63,6 +64,7 @@ class StrukturOrganisasiViewModel extends CustomBaseViewModel { getData('Ketua', false, null); getData('Sekretaris', false, null); getData('Bendahara', false, null); + getData('Wakil Bendahara', false, null); getData('Seksi Pengasuh', true, dataPengasuhLength); getData('Seksi Ibadah', true, dataIbadahLength); getData('Seksi Pendidikan', true, dataPendidikanLength); @@ -108,6 +110,8 @@ class StrukturOrganisasiViewModel extends CustomBaseViewModel { dataSekretaris = data; } else if (jabatan == 'Bendahara') { dataBendahara = data; + } else if (jabatan == 'Wakil Bendahara') { + dataWakilBendahara = data; } else if (jabatan == 'Seksi Pengasuh') { dataPengasuh = data; dataPengasuhLength = length!; diff --git a/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view.dart b/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view.dart index fee79e2..60697fb 100644 --- a/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view.dart +++ b/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view.dart @@ -9,14 +9,18 @@ import './detail_dana_sosial_view_model.dart'; class DetailDanaSosialView extends StatelessWidget { final int id; - const DetailDanaSosialView({Key? key, required this.id}) : super(key: key); + final bool isKhusus; + + const DetailDanaSosialView( + {Key? key, required this.id, this.isKhusus = false}) + : super(key: key); @override Widget build(BuildContext context) { return ViewModelBuilder.reactive( viewModelBuilder: () => DetailDanaSosialViewModel(), onViewModelReady: (DetailDanaSosialViewModel model) async { - await model.init(id); + await model.init(id, isKhusus); }, builder: ( BuildContext context, @@ -37,7 +41,7 @@ class DetailDanaSosialView extends StatelessWidget { child: CircularProgressIndicator(), ) : (model.danaSosialModel!.bentuk == 'Pemasukan' - ? const PemasukanWidget() + ? const SafeArea(child: PemasukanWidget()) : const PengeluaranWidget()), ), ); @@ -205,147 +209,183 @@ class PemasukanWidget extends ViewModelWidget { @override Widget build(BuildContext context, DetailDanaSosialViewModel viewModel) { - return Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Align( - alignment: Alignment.centerLeft, - child: Text( - "Nama Donator", - style: regularTextStyle.copyWith(color: mainColor), - ), - ), - MyTextFormField( - controller: viewModel.namaController, - maxLines: 1, - readOnly: true, - ), - const SizedBox( - height: 15, - ), - Align( - alignment: Alignment.centerLeft, - child: Text( - "Tanggal", - style: regularTextStyle.copyWith(color: mainColor), - ), - ), - MyTextFormField( - controller: viewModel.tanggalController, - maxLines: 1, - readOnly: true, - ), - const SizedBox( - height: 15, - ), - Align( - alignment: Alignment.centerLeft, - child: Text( - "Jenis", - style: regularTextStyle.copyWith(color: mainColor), - ), - ), - MyTextFormField( - controller: viewModel.jenisController, - maxLines: 1, - readOnly: true, - ), - Visibility( - visible: viewModel.jenisBool, - child: const SizedBox( - height: 15, - ), - ), - Visibility( - visible: viewModel.jenisBool, - child: Align( - alignment: Alignment.centerLeft, - child: Text( - "Jumlah", - style: regularTextStyle.copyWith(color: mainColor), + return SingleChildScrollView( + child: SizedBox( + height: MediaQuery.of(context).size.height, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + "Nama Donator", + style: regularTextStyle.copyWith(color: mainColor), + ), ), - ), - ), - Visibility( - visible: viewModel.jenisBool, - child: MyTextFormField( - controller: viewModel.jumlahController, - maxLines: 1, - readOnly: true, - ), - ), - Visibility( - visible: !viewModel.jenisBool, - child: const SizedBox( - height: 15, - ), - ), - Visibility( - visible: !viewModel.jenisBool, - child: Align( - alignment: Alignment.centerLeft, - child: Text( - "Keterangan", - style: regularTextStyle.copyWith(color: mainColor), + MyTextFormField( + controller: viewModel.namaController, + maxLines: 1, + readOnly: true, ), - ), - ), - Visibility( - visible: !viewModel.jenisBool, - child: MyTextFormField( - controller: viewModel.keteranganController, - maxLines: 2, - readOnly: true, - ), - ), - const SizedBox( - height: 15, - ), - Expanded( - child: Align( - alignment: Alignment.centerRight, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Tanda Tangan", + const SizedBox( + height: 15, + ), + Align( + alignment: Alignment.centerLeft, + child: Text( + "Tanggal", + style: regularTextStyle.copyWith(color: mainColor), + ), + ), + MyTextFormField( + controller: viewModel.tanggalController, + maxLines: 1, + readOnly: true, + ), + const SizedBox( + height: 15, + ), + Align( + alignment: Alignment.centerLeft, + child: Text( + "Jenis", + style: regularTextStyle.copyWith(color: mainColor), + ), + ), + MyTextFormField( + controller: viewModel.jenisController, + maxLines: 1, + readOnly: true, + ), + Visibility( + visible: viewModel.jenisBool, + child: const SizedBox( + height: 15, + ), + ), + Visibility( + visible: viewModel.jenisBool, + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "Jumlah", style: regularTextStyle.copyWith(color: mainColor), ), - SizedBox( - height: 150, - width: 150, - child: viewModel.danaSosialModel == null - ? Container( - decoration: BoxDecoration( - border: Border.all(color: mainColor), - ), - ) - : (viewModel.danaSosialModel!.status! == - 'Belum Dikonfirmasi' - ? const TtdWidget() - : Image.asset( - 'assets/qrcode.png', - fit: BoxFit.cover, - )), - ), - const SizedBox( - height: 10, - ), - Text( - "Dr. Andi Fitriani D, S.Ag, M.Pd", - style: regularTextStyle.copyWith( - color: mainColor, - fontWeight: FontWeight.bold, - ), - ), - // create a horizontal line - ], + ), ), - ), + Visibility( + visible: viewModel.jenisBool, + child: MyTextFormField( + controller: viewModel.jumlahController, + maxLines: 1, + readOnly: true, + ), + ), + Visibility( + visible: !viewModel.jenisBool, + child: const SizedBox( + height: 15, + ), + ), + if (!viewModel.jenisBool) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Jenis Barang", + style: regularTextStyle.copyWith(color: mainColor), + ), + MyTextFormField( + controller: viewModel.jenisBarangController, + maxLines: 1, + readOnly: true, + ), + const SizedBox( + height: 15, + ), + Text( + "Jumlah Barang", + style: regularTextStyle.copyWith(color: mainColor), + ), + MyTextFormField( + controller: viewModel.jumlahBarangController, + maxLines: 1, + readOnly: true, + ), + const SizedBox( + height: 15, + ), + ], + ), + Visibility( + visible: !viewModel.jenisBool, + child: Align( + alignment: Alignment.centerLeft, + child: Text( + "Keterangan", + style: regularTextStyle.copyWith(color: mainColor), + ), + ), + ), + Visibility( + visible: !viewModel.jenisBool, + child: MyTextFormField( + controller: viewModel.keteranganController, + maxLines: 2, + readOnly: true, + ), + ), + const SizedBox( + height: 15, + ), + Expanded( + child: Align( + alignment: Alignment.centerRight, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Tanda Tangan", + style: regularTextStyle.copyWith(color: mainColor), + ), + SizedBox( + height: 150, + width: 150, + child: viewModel.danaSosialModel == null + ? Container( + decoration: BoxDecoration( + border: Border.all(color: mainColor), + ), + ) + : (viewModel.danaSosialModel!.status! == + 'Belum Dikonfirmasi' + ? const TtdWidget() + : Image.asset( + 'assets/qrcode.png', + fit: BoxFit.cover, + )), + ), + const SizedBox( + height: 10, + ), + Text( + "DRA. HJ. CIA", + style: regularTextStyle.copyWith( + color: mainColor, + fontWeight: FontWeight.bold, + ), + ), + // create a horizontal line + ], + ), + ), + ), + ], ), - ], + ), ); } } @@ -361,7 +401,7 @@ class TtdWidget extends ViewModelWidget { decoration: BoxDecoration( border: Border.all(color: mainColor), ), - child: viewModel.role == 'pimpinan' + child: viewModel.role == 'pimpinan' || viewModel.role == 'admin' ? InkWell( onTap: () { viewModel.handleTtd(); diff --git a/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view_model.dart b/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view_model.dart index afa01cf..6d75447 100644 --- a/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view_model.dart +++ b/lib/ui/views/detail_dana_sosial/detail_dana_sosial_view_model.dart @@ -15,6 +15,8 @@ class DetailDanaSosialViewModel extends CustomBaseViewModel { final _httpService = locator(); final easyLoading = locator(); + bool isKhusus = false; + int? idDanaSosial; DanaSosialModel? danaSosialModel; bool jenisBool = true; @@ -29,8 +31,14 @@ class DetailDanaSosialViewModel extends CustomBaseViewModel { TextEditingController bentukController = TextEditingController(); - Future init(int id) async { + // my revision syntax + TextEditingController jenisBarangController = TextEditingController(); + TextEditingController jumlahBarangController = TextEditingController(); + // TextEditingController satuanController = TextEditingController(); + + Future init(int id, bool isKhusus) async { log.i('init and id: $id'); + this.isKhusus = isKhusus; getData(id); idDanaSosial = id; prefs.then((SharedPreferences prefs) { @@ -42,7 +50,10 @@ class DetailDanaSosialViewModel extends CustomBaseViewModel { setBusy(true); easyLoading.showLoading(); try { - var response = await _httpService.get('dana_sosial_detail?id=$id'); + String url = isKhusus + ? 'dana_sosial_khusus_detail?id=$id' + : 'dana_sosial_detail?id=$id'; + var response = await _httpService.get(url); log.i(response.data['data']); danaSosialModel = DanaSosialModel.fromJson(response.data['data']); namaController.text = danaSosialModel!.nama!; @@ -54,6 +65,12 @@ class DetailDanaSosialViewModel extends CustomBaseViewModel { bentukController.text = danaSosialModel!.bentuk!; + // my revision syntax + jenisBarangController.text = danaSosialModel!.jenisBarang!; + jumlahBarangController.text = + '${danaSosialModel!.jumlahBarang!} ${danaSosialModel!.satuan!}'; + // satuanController.text = danaSosialModel!.satuan! ; + if (danaSosialModel!.jenisDonasi == 'Uang') { jenisBool = true; } else { @@ -86,8 +103,9 @@ class DetailDanaSosialViewModel extends CustomBaseViewModel { FormData formData = FormData.fromMap({ 'id': idDanaSosial, }); - var response = - await _httpService.postWithFormData('dana_sosial_ttd', formData); + String url = isKhusus ? 'dana_sosial_khusus_ttd' : 'dana_sosial_ttd'; + + var response = await _httpService.postWithFormData(url, formData); log.i(response.data); getData(idDanaSosial!); diff --git a/lib/ui/views/pimpinan_index_tracking/pimpinan_index_tracking/pimpinan_index_tracking_view_model.dart b/lib/ui/views/pimpinan_index_tracking/pimpinan_index_tracking/pimpinan_index_tracking_view_model.dart index 74ec8bf..b72c1af 100644 --- a/lib/ui/views/pimpinan_index_tracking/pimpinan_index_tracking/pimpinan_index_tracking_view_model.dart +++ b/lib/ui/views/pimpinan_index_tracking/pimpinan_index_tracking/pimpinan_index_tracking_view_model.dart @@ -18,11 +18,12 @@ class PimpinanIndexTrackingViewModel extends IndexTrackingViewModel { final _bottomNavBarList = [ { - 'name': 'Siswa', + 'name': 'List', 'icon': Icons.people_alt_outlined, - 'header': 'List Siswa' + 'header': 'List Anak Panti' }, {'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial'}, + // {'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial Khusus'}, { 'name': 'Profil', 'icon': Icons.person_4_outlined, @@ -34,6 +35,7 @@ class PimpinanIndexTrackingViewModel extends IndexTrackingViewModel { final List _views = [ PimpinanIndexTrackingViewRoutes.dataSiswaView, PimpinanIndexTrackingViewRoutes.danaSosialAdminView, + // PimpinanIndexTrackingViewRoutes.danaSosialKhususView, PimpinanIndexTrackingViewRoutes.profilView, ]; Future init() async { diff --git a/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart b/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart index 7946892..e022159 100644 --- a/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart +++ b/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart @@ -9,14 +9,19 @@ import '../../widgets/my_textformfield.dart'; import './tambah_dana_sosial_view_model.dart'; class TambahDanaSosialView extends StatelessWidget { - const TambahDanaSosialView({super.key}); + final bool isKhusus; + + const TambahDanaSosialView({ + Key? key, + this.isKhusus = false, + }) : super(key: key); @override Widget build(BuildContext context) { return ViewModelBuilder.reactive( viewModelBuilder: () => TambahDanaSosialViewModel(), onViewModelReady: (TambahDanaSosialViewModel model) async { - await model.init(); + await model.init(isKhusus); }, builder: ( BuildContext context, @@ -66,6 +71,7 @@ class TambahDanaSosialView extends StatelessWidget { // model.setSelectedbentukDonasi(newValue!); model.log.i(newValue); model.bentukDonasi = newValue!; + model.notifyListeners(); }, items: model.bentukDonasiList.map((String value) { @@ -91,7 +97,8 @@ class TambahDanaSosialView extends StatelessWidget { ), ), Visibility( - visible: model.bentukDonasi == 'Pemasukan', + visible: model.bentukDonasi == 'Pemasukan' && + isKhusus == false, child: MyTextFormField( hintText: "Nama Donatur", controller: model.namaController, @@ -100,6 +107,51 @@ class TambahDanaSosialView extends StatelessWidget { // 'Nama Donatur tidak boleh kosong'), ), ), + Visibility( + visible: model.bentukDonasi == 'Pemasukan' && + isKhusus == true, + child: Container( + width: double.infinity, + height: 60, + padding: const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + border: Border.all( + color: mainColor, + ), + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: model.donaturSelected, + onChanged: (String? newValue) { + // model.setSelectedjenisDonasi(newValue!); + model.log.i(newValue); + model.donaturSelected = newValue!; + // check where is the index and get the ['id_donatur'] + + var index = model.listDonatur.indexWhere( + (element) => element == newValue, + ); + model.donaturSelectedIndex = int.parse( + model.listDonaturMap[index]['id_donatur'], + ); + model.log.i(model.donaturSelectedIndex); + }, + items: model.listDonatur.map((String value) { + return DropdownMenuItem( + value: value, + child: Text( + value, + style: regularTextStyle.copyWith( + fontSize: 16, + ), + ), + ); + }).toList(), + ), + ), + ), + ), Visibility( visible: model.bentukDonasi == 'Pemasukan', child: const SizedBox(height: 20), @@ -141,6 +193,130 @@ class TambahDanaSosialView extends StatelessWidget { ), ), ), + // ini jika barang + if (model.jenisDonasi == 'Barang') + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + Text( + "Jenis Barang", + style: + regularTextStyle.copyWith(color: mainColor), + ), + Container( + width: double.infinity, + height: 60, + padding: + const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + border: Border.all( + color: mainColor, + ), + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: model.jenisBarangSelected, + onChanged: (String? newValue) { + // model.setSelectedjenisDonasi(newValue!); + model.log.i(newValue); + model.jenisBarangSelected = newValue!; + model.changeSatuan(newValue); + model.notifyListeners(); + }, + items: + model.jenisBarangList.map((String value) { + return DropdownMenuItem( + value: value, + child: Text( + value, + style: regularTextStyle.copyWith( + fontSize: 16, + ), + ), + ); + }).toList(), + ), + ), + ), + ], + ), + // ini jika barang dan jenis barang beras dll + if (model.jenisDonasi == 'Barang' && + (model.jenisBarangSelected == 'Beras' || + model.jenisBarangSelected == 'Mi Instan' || + model.jenisBarangSelected == 'Telur' || + model.jenisBarangSelected == 'Gula')) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + Text( + "Pilih Satuan ${model.jenisBarangSelected}", + style: + regularTextStyle.copyWith(color: mainColor), + ), + Container( + width: double.infinity, + height: 60, + padding: + const EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + border: Border.all( + color: mainColor, + ), + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: model.satuanSelected, + onChanged: (String? newValue) { + // model.setSelectedjenisDonasi(newValue!); + model.log.i(newValue); + model.satuanSelected = newValue!; + model.notifyListeners(); + }, + items: model.satuanList.map((String value) { + return DropdownMenuItem( + value: value, + child: Text( + value, + style: regularTextStyle.copyWith( + fontSize: 16, + ), + ), + ); + }).toList(), + ), + ), + ), + ], + ), + + // ini jika barang dan jenis barang dll + if (model.jenisDonasi == 'Barang') + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 20), + Text( + "Jumlah ${model.satuanSelected}", + style: + regularTextStyle.copyWith(color: mainColor), + ), + MyTextFormField( + hintText: "Jumlah ${model.satuanSelected}", + controller: model.jumlahBarangController, + maxLines: 1, + keyboardType: TextInputType.number, + maxLength: 3, + // validator: Validatorless.required( + // 'Nama Donatur tidak boleh kosong'), + ), + ], + ), + Visibility( visible: model.jenisDonasi == 'Uang', child: const SizedBox(height: 20), @@ -212,6 +388,15 @@ class TambahDanaSosialView extends StatelessWidget { MyButton( text: "Simpan Data", onPressed: () { + if (isKhusus && + model.donaturSelected == '-Tiada Donatur-') { + model.snackbarService.showSnackbar( + message: 'Donatur harus diisi terlebih dahulu', + title: 'Gagal', + duration: const Duration(seconds: 2), + ); + return; + } if (model.formKey.currentState!.validate()) { model.log.i('Form Valid'); model.addData(); diff --git a/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view_model.dart b/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view_model.dart index a8bca20..fc0216b 100644 --- a/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view_model.dart +++ b/lib/ui/views/tambah_dana_sosial/tambah_dana_sosial_view_model.dart @@ -23,10 +23,77 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel { TextEditingController namaController = TextEditingController(); TextEditingController jumlahController = TextEditingController(); + TextEditingController jumlahBarangController = TextEditingController(); TextEditingController tanggalController = TextEditingController(); TextEditingController keteranganController = TextEditingController(); - Future init() async {} + // my revision syntax + List jenisBarangList = [ + 'Beras', + 'Minyak', + 'Mi Instan', + 'Telur', + 'Gula', + 'Susu', + 'Pakaian' + ]; + + String jenisBarangSelected = 'Beras'; + String satuanSelected = 'Kg'; + // TextEditingController jumlahBarangController = TextEditingController(); + + bool isJenisBarangSelected = true; + List satuanLiterKg = ['Liter', 'Kg']; + List satuanBungkusDos = ['Bungkus', 'Dos']; + List satuanButirRak = ['Butir', 'Rak']; + List satuanList = ['Liter', 'Kg']; + + // end of my revision syntax + + // the new revision syntax + bool isKhusus = false; + List listDonatur = ['-Tiada Donatur-']; + List> listDonaturMap = []; + String donaturSelected = '-Tiada Donatur-'; + int donaturSelectedIndex = 0; + // end of the new revision syntax + + Future init(bool isKhusus) async { + this.isKhusus = isKhusus; + + if (isKhusus) { + bentukDonasiList = ['Pemasukan']; + getDonatur(); + } + } + + getDonatur() async { + setBusy(true); + easyLoading.customLoading('Mengambil data...'); + + try { + var response = await _httpService.get('donatur'); + Map data = response.data; + // log.i(data); + int jumlah = data['jumlah']; + if (jumlah > 0) { + listDonatur.clear(); + for (var i = 0; i < data['data'].length; i++) { + listDonatur.add(data['data'][i]['nama_donatur']); + listDonaturMap.add(data['data'][i]); + } + // get the [id_donatur] of the first [donatur + donaturSelected = listDonatur[0]; + donaturSelectedIndex = int.parse(listDonaturMap[0]['id_donatur']); + log.i(donaturSelectedIndex); + } + } catch (e) { + log.e(e); + } finally { + setBusy(false); + easyLoading.dismissLoading(); + } + } void changeDate(BuildContext context) async { // get today's date @@ -46,6 +113,7 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel { void addData() async { easyLoading.customLoading('Menambahkan data...'); + log.i(donaturSelectedIndex); try { var formData = FormData.fromMap({ 'bentuk': bentukDonasi, @@ -54,9 +122,17 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel { 'tanggal': tanggalController.text, 'ket': keteranganController.text, 'jenis': jenisDonasi, + 'jenis_barang': jenisDonasi == 'Barang' ? jenisBarangSelected : null, + 'satuan': jenisDonasi == 'Barang' ? satuanSelected : null, + 'jumlah_barang': + jenisDonasi == 'Barang' ? jumlahBarangController.text : null, + 'donatur': isKhusus ? donaturSelectedIndex : null, }); + var response = - await _httpService.postWithFormData('dana_sosial', formData); + // await _httpService.postWithFormData('dana_sosial', formData); + await _httpService.postWithFormData( + !isKhusus ? 'dana_sosial' : 'dana_sosial_khusus', formData); log.i(response.data); easyLoading.showSuccess(" Data berhasil ditambahkan"); navigationService.navigateTo(Routes.adminIndexTrackingView); @@ -71,4 +147,49 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel { easyLoading.dismissLoading(); } } + + // my revision syntax + changeSatuan(String value) { + jenisBarangSelected = value; + switch (value) { + case 'Beras': + isJenisBarangSelected = true; + satuanSelected = 'Kg'; + satuanList = satuanLiterKg; + + break; + case 'Minyak': + isJenisBarangSelected = false; + satuanSelected = 'Liter'; + break; + case 'Mi Instan': + isJenisBarangSelected = true; + satuanSelected = 'Bungkus'; + satuanList = satuanBungkusDos; + break; + case 'Telur': + isJenisBarangSelected = true; + satuanSelected = 'Butir'; + satuanList = satuanButirRak; + break; + case 'Gula': + isJenisBarangSelected = true; + satuanSelected = 'Kg'; + satuanList = satuanLiterKg; + break; + case 'Susu': + isJenisBarangSelected = false; + satuanSelected = 'Liter'; + break; + case 'Pakaian': + isJenisBarangSelected = false; + satuanSelected = 'Helai'; + // satuanList = satuanButirRak; + break; + default: + satuanSelected = ''; + } + + // notifyListeners(); + } } diff --git a/lib/ui/views/user_index_tracking/user_index_tracking_view_model.dart b/lib/ui/views/user_index_tracking/user_index_tracking_view_model.dart index be379d3..6f37e77 100644 --- a/lib/ui/views/user_index_tracking/user_index_tracking_view_model.dart +++ b/lib/ui/views/user_index_tracking/user_index_tracking_view_model.dart @@ -15,11 +15,12 @@ class UserIndexTrackingViewModel extends IndexTrackingViewModel { final _bottomNavBarList = [ { - 'name': 'Siswa', + 'name': 'List', 'icon': Icons.people_alt_outlined, - 'header': 'List Siswa' + 'header': 'List Anak Panti' }, {'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial'}, + // {'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial Khusus'}, { 'name': 'Profil', 'icon': Icons.person_4_outlined, @@ -39,6 +40,7 @@ class UserIndexTrackingViewModel extends IndexTrackingViewModel { final List _views = [ UserIndexTrackingViewRoutes.dataSiswaView, UserIndexTrackingViewRoutes.danaSosialAdminView, + // UserIndexTrackingViewRoutes.danaSosialKhususView, UserIndexTrackingViewRoutes.profilView, UserIndexTrackingViewRoutes.visiMisiView, UserIndexTrackingViewRoutes.sejarahView, diff --git a/lib/ui/widgets/my_textformfield.dart b/lib/ui/widgets/my_textformfield.dart index 9682beb..fe069bb 100644 --- a/lib/ui/widgets/my_textformfield.dart +++ b/lib/ui/widgets/my_textformfield.dart @@ -20,6 +20,7 @@ class MyTextFormField extends StatelessWidget { this.keyboardType = TextInputType.text, this.initialValue, this.enabled = true, + this.maxLength, }) : super(key: key); final String? labelText; @@ -37,10 +38,12 @@ class MyTextFormField extends StatelessWidget { final TextInputType keyboardType; final String? initialValue; final bool enabled; + final int? maxLength; @override Widget build(BuildContext context) { return TextFormField( + maxLength: maxLength, enabled: enabled, initialValue: initialValue, onEditingComplete: onEditingComplete, diff --git a/pubspec.lock b/pubspec.lock index c8cb5d8..14f53d7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -254,6 +254,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.5" + flutter_file_downloader: + dependency: "direct main" + description: + name: flutter_file_downloader + sha256: e36f1a23937c83b96003ecc48f3227acbd468a1ff26be87959cecd057222632a + url: "https://pub.dev" + source: hosted + version: "1.2.1" flutter_holo_date_picker: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 483a173..87ba588 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,6 +53,7 @@ dependencies: shared_preferences: # flutter_hooks: http_parser: + flutter_file_downloader: ^1.2.1 dev_dependencies: flutter_test: