added user page, pimpinan page, e signature

This commit is contained in:
kicap
2023-08-03 17:58:40 +08:00
parent 30131e5ffe
commit 914e24706b
35 changed files with 2341 additions and 327 deletions

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/themes/app_text.dart';
import 'package:panti_asuhan/ui/widgets/my_textformfield.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:validatorless/validatorless.dart';
import '../../../../../app/themes/app_colors.dart';
import '../../../../../app/themes/app_text.dart';
import '../../../../widgets/my_textformfield.dart';
import './add_siswa_dialog_view_model.dart';
class DataSiswa {

View File

@ -36,12 +36,21 @@ class AdminIndexTrackingView extends StatelessWidget {
backgroundColor: mainColor,
elevation: 0,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
model.logout();
},
icon: const Icon(Icons.logout, color: Colors.white),
),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: ExtendedNavigator(
navigatorKey: StackedService.nestedNavigationKey(3),
router: AdminIndexTrackingViewRouter(),
initialRoute: AdminIndexTrackingViewRoutes.danaSosialAdminView,
),
),
bottomNavigationBar: StylishBottomBar(

View File

@ -1,14 +1,17 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/app.router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../app/app.locator.dart';
import '../../../app/app.logger.dart';
import '../../../app/app.router.dart';
class AdminIndexTrackingViewModel extends IndexTrackingViewModel {
final log = getLogger('AdminIndexTrackingViewModel');
final _navigationService = locator<NavigationService>();
final _dialogService = locator<DialogService>();
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final _bottomNavBarList = [
{
@ -47,11 +50,11 @@ class AdminIndexTrackingViewModel extends IndexTrackingViewModel {
Future<void> init() async {
setIndex(1);
// await 2 seconds to make sure the view is loaded
await Future.delayed(const Duration(milliseconds: 500));
_navigationService.navigateTo(
_views[1],
id: 3,
);
// await Future.delayed(const Duration(milliseconds: 500));
// _navigationService.navigateTo(
// _views[1],
// id: 3,
// );
}
void handleNavigation(int index) {
@ -67,4 +70,26 @@ class AdminIndexTrackingViewModel extends IndexTrackingViewModel {
id: 3,
);
}
logout() {
_dialogService
.showConfirmationDialog(
title: 'Logout',
description: 'Apakah anda yakin ingin logout?',
cancelTitle: 'Ya',
confirmationTitle: 'Tidak',
// barrierDismissible: true,
)
.then((value) {
if (!value!.confirmed) {
_prefs.then((SharedPreferences prefs) {
prefs.setBool('isLogin', false);
prefs.remove('role');
_navigationService.clearStackAndShow(Routes.loginScreenView);
});
} else {
_navigationService.back();
}
});
}
}

View File

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/themes/app_colors.dart';
import 'package:panti_asuhan/services/other_function.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_view_model.dart';
class DanaSosialAdminView extends StatelessWidget {
@ -24,54 +24,80 @@ class DanaSosialAdminView extends StatelessWidget {
return Scaffold(
body: Column(
children: [
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,
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. 1.000.000',
style: regularTextStyle.copyWith(
color: Colors.white,
fontSize: 15,
),
),
],
),
],
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Total Dana Sosial',
style: regularTextStyle.copyWith(
color: Colors.white,
fontSize: 15,
),
),
Text(
'Rp. 1.000.000',
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(
@ -98,65 +124,93 @@ class DanaSosialAdminView extends StatelessWidget {
),
),
)
: ListView.builder(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
itemCount: model.danaSosialModelList.length,
itemBuilder: (context, index) {
String jumlahDonasi = OtherFunction().commaFormat(
int.parse(
model.danaSosialModelList[index].jumlah ??
'0'));
return Card(
child: ListTile(
title: Text(
model.danaSosialModelList[index].tanggal ??
'',
style: boldTextStyle.copyWith(
fontSize: 13, color: mainColor)),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
model.danaSosialModelList[index].nama ??
'',
style: regularTextStyle.copyWith(
fontSize: 13, color: mainColor)),
Text('Rp. $jumlahDonasi',
style: regularTextStyle.copyWith(
fontSize: 13, color: mainColor)),
],
),
trailing: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: mainColor,
borderRadius: BorderRadius.circular(50),
),
child: IconButton(
onPressed: () {
// model.goToTambahDanaSosial();
},
icon: const Icon(
Icons.edit,
color: Colors.white,
),
),
),
),
);
},
),
: const TheData(),
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
model.goToTambahDanaSosial();
},
child: const Icon(Icons.add),
floatingActionButton: model.role == 'admin'
? FloatingActionButton(
onPressed: () {
model.goToTambahDanaSosial();
},
child: const Icon(Icons.add),
)
: null,
);
},
);
}
}
class TheData extends ViewModelWidget<DanaSosialAdminViewModel> {
const TheData({
super.key,
});
@override
Widget build(BuildContext context, DanaSosialAdminViewModel 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].nama ?? '',
style: regularTextStyle.copyWith(
fontSize: 13, color: mainColor)),
Text(
viewModel.danaSosialModelList[index].jenisDonasi == 'Uang'
? (viewModel.isLogin == true ? 'Rp. $jumlahDonasi' : '-')
: 'Donasi Barang',
style:
regularTextStyle.copyWith(fontSize: 13, color: mainColor),
),
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
? 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,
),
),
)
: null),
),
);
},

View File

@ -1,3 +1,8 @@
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';
@ -5,6 +10,7 @@ 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 DanaSosialAdminViewModel extends CustomBaseViewModel {
final log = getLogger('DanaSosialAdminViewModel');
@ -13,8 +19,15 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
List<DanaSosialModel> danaSosialModelList = [];
String? role;
bool? isLogin;
Future<void> init() async {
await getData();
prefs.then((SharedPreferences prefs) {
role = prefs.getString('role');
isLogin = prefs.getBool('isLogin');
});
}
getData() async {
@ -47,4 +60,93 @@ class DanaSosialAdminViewModel extends CustomBaseViewModel {
goToTambahDanaSosial() {
navigationService.navigateTo(Routes.tambahDanaSosialView);
}
getFilter(String sql) async {
setBusy(true);
easyLoading.showLoading();
FormData formData = FormData.fromMap({
'sql': sql,
});
try {
var response = await _httpService.postWithFormData(
'filter_dana',
formData,
);
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);
} 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 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,
),
);
}
}

View File

@ -127,12 +127,14 @@ class DataSiswaView extends StatelessWidget {
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
model.addSiswa();
},
child: const Icon(Icons.add),
),
floatingActionButton: model.role == 'admin'
? FloatingActionButton(
onPressed: () {
model.addSiswa();
},
child: const Icon(Icons.add),
)
: null,
);
},
);

View File

@ -1,4 +1,5 @@
import 'package:panti_asuhan/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.locator.dart';
@ -16,8 +17,13 @@ class DataSiswaViewModel extends CustomBaseViewModel {
List<SiswaModel> siswaModelList = [];
String? role;
Future<void> init() async {
await getData();
prefs.then((SharedPreferences prefs) {
role = prefs.getString('role');
});
}
getData() async {

View File

@ -0,0 +1,284 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './filter_dialog_view_model.dart';
class FilterDialogView extends StatelessWidget {
final DialogRequest? request;
final Function(DialogResponse)? completer;
const FilterDialogView({
Key? key,
this.request,
this.completer,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<FilterDialogViewModel>.reactive(
viewModelBuilder: () => FilterDialogViewModel(),
onViewModelReady: (FilterDialogViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
FilterDialogViewModel model,
Widget? child,
) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"FILTER LAPORAN",
style: boldTextStyle.copyWith(
fontSize: 16,
),
),
const SizedBox(height: 10),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Jenis Dana Sosial",
style: regularTextStyle.copyWith(color: mainColor),
textAlign: TextAlign.left,
),
),
Container(
width: double.infinity,
height: 60,
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: mainColor,
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: model.jenisDonasi,
onChanged: (String? newValue) {
// model.setSelectedjenisDonasi(newValue!);
model.log.i(newValue);
model.jenisDonasi = newValue!;
model.notifyListeners();
},
items: model.jenisDonasiList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 10),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Filter Bulan",
style: regularTextStyle.copyWith(color: mainColor),
textAlign: TextAlign.left,
),
),
Container(
width: double.infinity,
height: 60,
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: mainColor,
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: model.bulan,
onChanged: (String? newValue) {
// model.setSelectedbulan(newValue!);
model.log.i(newValue);
model.bulan = newValue!;
model.notifyListeners();
},
items: model.bulanList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 10),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Filter Tahun",
style: regularTextStyle.copyWith(color: mainColor),
textAlign: TextAlign.left,
),
),
Container(
width: double.infinity,
height: 60,
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: mainColor,
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: model.tahun,
onChanged: (String? newValue) {
// model.setSelectedtahun(newValue!);
model.log.i(newValue);
model.tahun = newValue!;
model.notifyListeners();
},
items: model.tahunList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 10),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Filter Status",
style: regularTextStyle.copyWith(color: mainColor),
textAlign: TextAlign.left,
),
),
Container(
width: double.infinity,
height: 60,
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: mainColor,
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: model.status,
onChanged: (String? newValue) {
// model.setSelectedstatus(newValue!);
model.log.i(newValue);
model.status = newValue!;
model.notifyListeners();
},
items: model.statusList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: TextButton(
onPressed: () {
// model.filter();
// model.filter();
completer!(
DialogResponse(
confirmed: true,
data: {
'jenisDonasi': model.jenisDonasi,
'bulan': model.bulan,
'tahun': model.tahun,
'status': model.status,
},
),
);
},
style: TextButton.styleFrom(
backgroundColor: mainColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
),
child: Text(
"Filter",
style: boldTextStyle.copyWith(
fontSize: 16,
color: Colors.white,
),
),
),
),
const SizedBox(width: 10),
Expanded(
child: TextButton(
onPressed: () {
completer!(DialogResponse(confirmed: false));
},
style: TextButton.styleFrom(
backgroundColor: mainGrey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
),
child: Text(
"Close",
style: boldTextStyle.copyWith(
fontSize: 16,
color: Colors.white,
),
),
),
),
],
)
],
),
),
);
},
);
}
}

View File

@ -0,0 +1,41 @@
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
class FilterDialogViewModel extends CustomBaseViewModel {
final log = getLogger('FilterDialogViewModel');
String jenisDonasi = 'Semua';
List<String> jenisDonasiList = ['Semua', 'Uang', 'Barang'];
String bulan = 'Semua';
List<String> bulanList = [
'Semua',
'Januari',
'Februari',
'Maret',
'April',
'Mei',
'Juni',
'Agustus',
'September',
'Oktober',
'November',
'Desember'
];
String tahun = 'Semua';
List<String> tahunList = [
'Semua',
'2023',
'2022',
];
String status = 'Semua';
List<String> statusList = [
'Semua',
'Belum Dikonfirmasi',
'Sudah Dikonfirmasi',
];
Future<void> init() async {}
}

View File

@ -4,11 +4,13 @@ import 'package:stacked/stacked.dart';
import './sejarah_view_model.dart';
class SejarahView extends StatelessWidget {
const SejarahView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<SejarahViewModel>.nonReactive(
viewModelBuilder: () => SejarahViewModel(),
onModelReady: (SejarahViewModel model) async {
onViewModelReady: (SejarahViewModel model) async {
await model.init();
},
builder: (
@ -29,9 +31,9 @@ class SejarahView extends StatelessWidget {
height: 150,
),
),
SizedBox(height: 20),
const SizedBox(height: 20),
Text(
model.isi1 + '\n\n' + model.isi2,
'${model.isi1}\n\n${model.isi2}',
style: const TextStyle(fontSize: 18),
textAlign: TextAlign.justify,
),

View File

@ -4,11 +4,13 @@ import 'package:stacked/stacked.dart';
import './struktur_organisasi_view_model.dart';
class StrukturOrganisasiView extends StatelessWidget {
const StrukturOrganisasiView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<StrukturOrganisasiViewModel>.nonReactive(
viewModelBuilder: () => StrukturOrganisasiViewModel(),
onModelReady: (StrukturOrganisasiViewModel model) async {
onViewModelReady: (StrukturOrganisasiViewModel model) async {
await model.init();
},
builder: (
@ -43,7 +45,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
model.Ketua,
model.ketua,
style: const TextStyle(
fontSize: 20,
),
@ -62,7 +64,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
model.Sekretaris,
model.sekretaris,
style: const TextStyle(
fontSize: 20,
),
@ -81,7 +83,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
model.Bendahara,
model.bendahara,
style: const TextStyle(
fontSize: 20,
),
@ -100,7 +102,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
'${model.SeksiPengasuh1}\n${model.SeksiPengasuh2}\n${model.SeksiPengasuh3}\n${model.SeksiPengasuh4}',
'${model.seksiPengasuh1}\n${model.seksiPengasuh2}\n${model.seksiPengasuh3}\n${model.seksiPengasuh4}',
style: const TextStyle(
fontSize: 20,
),
@ -119,7 +121,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
'${model.SeksiIbadah1}\n${model.SeksiIbadah2}\n${model.SeksiIbadah3}\n${model.SeksiIbadah4}',
'${model.seksiIbadah1}\n${model.seksiIbadah2}\n${model.seksiIbadah3}\n${model.seksiIbadah4}',
style: const TextStyle(
fontSize: 20,
),
@ -138,7 +140,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
'${model.SeksiPendidikan1}\n${model.SeksiPendidikan2}',
'${model.seksiPendidikan1}\n${model.seksiPendidikan2}',
style: const TextStyle(
fontSize: 20,
),
@ -157,7 +159,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
model.SeksiKesehatan,
model.seksiKesehatan,
style: const TextStyle(
fontSize: 20,
),
@ -176,7 +178,7 @@ class StrukturOrganisasiView extends StatelessWidget {
height: 2,
),
Text(
model.SeksiKebersihan,
model.seksiKebersihan,
style: const TextStyle(
fontSize: 20,
),
@ -192,7 +194,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
model.SeksiKeterampilan1,
model.seksiKeterampilan1,
style: const TextStyle(
fontSize: 20,
),
@ -208,7 +210,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
model.SeksiSaranaPrasarana1,
model.seksiSaranaPrasarana1,
style: const TextStyle(
fontSize: 20,
),
@ -224,7 +226,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
'${model.SeksiKonsumsi1}\n${model.SeksiKonsumsi2}',
'${model.seksiKonsumsi1}\n${model.seksiKonsumsi2}',
style: const TextStyle(
fontSize: 20,
),
@ -240,7 +242,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
'${model.SeksiKeamanan1}\n${model.SeksiKeamanan2}',
'${model.seksiKeamanan1}\n${model.seksiKeamanan2}',
style: const TextStyle(
fontSize: 20,
),
@ -256,7 +258,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
'${model.SeksiGedung1}\n${model.SeksiGedung2}\n${model.SeksiGedung3}\n${model.SeksiGedung4}',
'${model.seksiGedung1}\n${model.seksiGedung2}\n${model.seksiGedung3}\n${model.seksiGedung4}',
style: const TextStyle(
fontSize: 20,
),
@ -272,7 +274,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
'${model.SeksiWisma1}\n${model.SeksiWisma2}\n${model.SeksiWisma3}\n${model.SeksiWisma4}\n${model.SeksiWisma5}',
'${model.seksiWisma1}\n${model.seksiWisma2}\n${model.seksiWisma3}\n${model.seksiWisma4}\n${model.seksiWisma5}',
style: const TextStyle(
fontSize: 20,
),
@ -288,7 +290,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
'${model.KelompokPutri1}\n${model.KelompokPutri2}\n${model.KelompokPutri3}',
'${model.kelompokPutri1}\n${model.kelompokPutri2}\n${model.kelompokPutri3}',
style: const TextStyle(
fontSize: 20,
),
@ -304,7 +306,7 @@ class StrukturOrganisasiView extends StatelessWidget {
),
),
Text(
'${model.KelompokPutra1}\n${model.KelompokPutra2}\n${model.KelompokPutra3}',
'${model.kelompokPutra1}\n${model.kelompokPutra2}\n${model.kelompokPutra3}',
style: const TextStyle(
fontSize: 20,
),

View File

@ -1,54 +1,54 @@
import 'package:panti_asuhan/app/core/custom_base_view_model.dart';
class StrukturOrganisasiViewModel extends CustomBaseViewModel {
String Ketua = "Dr. Andi Fitriani D, S.Ag, M.Pd";
String Sekretaris = "Fitriana Buyanus, S.Si ., M.Kes";
String Bendahara = "Hj. Djaliah, A.Ma";
String ketua = "Dr. Andi Fitriani D, S.Ag, M.Pd";
String sekretaris = "Fitriana Buyanus, S.Si ., M.Kes";
String bendahara = "Hj. Djaliah, A.Ma";
String SeksiPengasuh1 = "Dra Hj, CIA";
String SeksiPengasuh2 = "Dahang, S.Ag";
String SeksiPengasuh3 = "Sumadin, S.Pd.I";
String SeksiPengasuh4 = "Darwan";
String seksiPengasuh1 = "Dra Hj, CIA";
String seksiPengasuh2 = "Dahang, S.Ag";
String seksiPengasuh3 = "Sumadin, S.Pd.I";
String seksiPengasuh4 = "Darwan";
String SeksiIbadah1 = "Drs. Najib La'ady";
String SeksiIbadah2 = "Sumadin, S.Pd.I";
String SeksiIbadah3 = "Ahmad";
String SeksiIbadah4 = "Darwan";
String seksiIbadah1 = "Drs. Najib La'ady";
String seksiIbadah2 = "Sumadin, S.Pd.I";
String seksiIbadah3 = "Ahmad";
String seksiIbadah4 = "Darwan";
String SeksiPendidikan1 = "Dra. Hj. CIA";
String SeksiPendidikan2 = "Hj. Djaliah, A.Ma";
String seksiPendidikan1 = "Dra. Hj. CIA";
String seksiPendidikan2 = "Hj. Djaliah, A.Ma";
String SeksiKesehatan = "Haerul, SKM";
String SeksiKebersihan = "Bd. Lina Sutomo";
String seksiKesehatan = "Haerul, SKM";
String seksiKebersihan = "Bd. Lina Sutomo";
String SeksiKeterampilan1 = "Yuslihudriani, S.Pd";
String seksiKeterampilan1 = "Yuslihudriani, S.Pd";
String SeksiSaranaPrasarana1 = "Muh.Adham, ST";
String seksiSaranaPrasarana1 = "Muh.Adham, ST";
String SeksiKonsumsi1 = "Fatmawati";
String SeksiKonsumsi2 = "Rasnaya";
String seksiKonsumsi1 = "Fatmawati";
String seksiKonsumsi2 = "Rasnaya";
String SeksiKeamanan1 = "Firdaus";
String SeksiKeamanan2 = "Ahmad";
String seksiKeamanan1 = "Firdaus";
String seksiKeamanan2 = "Ahmad";
String SeksiGedung1 = "Dra. Bangsuari";
String SeksiGedung2 = "Hidayani";
String SeksiGedung3 = "Dahang. S,Ag";
String SeksiGedung4 = "Saharia";
String seksiGedung1 = "Dra. Bangsuari";
String seksiGedung2 = "Hidayani";
String seksiGedung3 = "Dahang. S,Ag";
String seksiGedung4 = "Saharia";
String SeksiWisma1 = "Drs. Muh, Yasmin";
String SeksiWisma2 = "Hj. Hadilah";
String SeksiWisma3 = "Muh.Adham, ST";
String SeksiWisma4 = "Ahmad";
String SeksiWisma5 = "Dahang, S.Ag";
String seksiWisma1 = "Drs. Muh, Yasmin";
String seksiWisma2 = "Hj. Hadilah";
String seksiWisma3 = "Muh.Adham, ST";
String seksiWisma4 = "Ahmad";
String seksiWisma5 = "Dahang, S.Ag";
String KelompokPutri1 = "St. Khadijah";
String KelompokPutri2 = "St. Aisyah";
String KelompokPutri3 = "St. Fatimah";
String kelompokPutri1 = "St. Khadijah";
String kelompokPutri2 = "St. Aisyah";
String kelompokPutri3 = "St. Fatimah";
String KelompokPutra1 = "Ahmad Dahlan";
String KelompokPutra2 = "Ar. Fahruddin";
String KelompokPutra3 = "Amin Rais";
String kelompokPutra1 = "Ahmad Dahlan";
String kelompokPutra2 = "Ar. Fahruddin";
String kelompokPutra3 = "Amin Rais";
Future<void> init() async {}
}

View File

@ -4,11 +4,13 @@ import 'package:stacked/stacked.dart';
import './visi_misi_view_model.dart';
class VisiMisiView extends StatelessWidget {
const VisiMisiView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<VisiMisiViewModel>.nonReactive(
viewModelBuilder: () => VisiMisiViewModel(),
onModelReady: (VisiMisiViewModel model) async {
onViewModelReady: (VisiMisiViewModel model) async {
await model.init();
},
builder: (
@ -29,36 +31,28 @@ class VisiMisiView extends StatelessWidget {
height: 150,
),
),
Center(
const Center(
child: Text(
'Visi',
style: const TextStyle(fontSize: 20),
style: TextStyle(fontSize: 20),
),
),
SizedBox(height: 10),
const SizedBox(height: 10),
Text(
model.visi,
style: const TextStyle(fontSize: 18),
textAlign: TextAlign.justify,
),
SizedBox(height: 30),
Center(
const SizedBox(height: 30),
const Center(
child: Text(
'Misi',
style: const TextStyle(fontSize: 20),
style: TextStyle(fontSize: 20),
),
),
SizedBox(height: 10),
const SizedBox(height: 10),
Text(
model.misi1 +
'\n\n' +
model.misi2 +
'\n\n' +
model.misi3 +
'\n\n' +
model.misi4 +
'\n\n' +
model.misi5,
'${model.misi1}\n\n${model.misi2}\n\n${model.misi3}\n\n${model.misi4}\n\n${model.misi5}',
style: const TextStyle(fontSize: 18),
textAlign: TextAlign.justify,
),

View File

@ -0,0 +1,213 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../app/themes/app_colors.dart';
import '../../../app/themes/app_text.dart';
import '../../widgets/my_textformfield.dart';
import './detail_dana_sosial_view_model.dart';
class DetailDanaSosialView extends StatelessWidget {
final int id;
const DetailDanaSosialView({Key? key, required this.id}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<DetailDanaSosialViewModel>.reactive(
viewModelBuilder: () => DetailDanaSosialViewModel(),
onViewModelReady: (DetailDanaSosialViewModel model) async {
await model.init(id);
},
builder: (
BuildContext context,
DetailDanaSosialViewModel model,
Widget? child,
) {
return Scaffold(
appBar: AppBar(
title: const Text('Detail Dana Sosial',
style: TextStyle(color: Colors.white)),
backgroundColor: mainColor,
iconTheme: const IconThemeData(color: Colors.white),
),
body: Padding(
padding: const EdgeInsets.all(15),
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),
),
),
MyTextFormField(
controller: model.namaController,
maxLines: 1,
readOnly: true,
),
const SizedBox(
height: 15,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Tanggal",
style: regularTextStyle.copyWith(color: mainColor),
),
),
MyTextFormField(
controller: model.tanggalController,
maxLines: 1,
readOnly: true,
),
const SizedBox(
height: 15,
),
Align(
alignment: Alignment.centerLeft,
child: Text(
"Jenis",
style: regularTextStyle.copyWith(color: mainColor),
),
),
MyTextFormField(
controller: model.jenisController,
maxLines: 1,
readOnly: true,
),
Visibility(
visible: model.jenisBool,
child: const SizedBox(
height: 15,
),
),
Visibility(
visible: model.jenisBool,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Jumlah",
style: regularTextStyle.copyWith(color: mainColor),
),
),
),
Visibility(
visible: model.jenisBool,
child: MyTextFormField(
controller: model.jumlahController,
maxLines: 1,
readOnly: true,
),
),
Visibility(
visible: !model.jenisBool,
child: const SizedBox(
height: 15,
),
),
Visibility(
visible: !model.jenisBool,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
"Keterangan",
style: regularTextStyle.copyWith(color: mainColor),
),
),
),
Visibility(
visible: !model.jenisBool,
child: MyTextFormField(
controller: model.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: model.danaSosialModel == null
? Container(
decoration: BoxDecoration(
border: Border.all(color: mainColor),
),
)
: (model.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
],
),
),
),
],
),
),
);
},
);
}
}
class TtdWidget extends ViewModelWidget<DetailDanaSosialViewModel> {
const TtdWidget({
super.key,
});
@override
Widget build(BuildContext context, DetailDanaSosialViewModel viewModel) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: mainColor),
),
child: viewModel.role == 'pimpinan'
? InkWell(
onTap: () {
viewModel.handleTtd();
},
child: Center(
child: Text(
"Tanda Tangan",
style: regularTextStyle.copyWith(
color: mainColor,
fontStyle: FontStyle.italic,
),
),
),
)
: null,
);
}
}

View File

@ -0,0 +1,105 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../app/app.locator.dart';
import '../../../app/app.logger.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 DetailDanaSosialViewModel extends CustomBaseViewModel {
final log = getLogger('DetailDanaSosialViewModel');
final _httpService = locator<MyHttpServices>();
final easyLoading = locator<MyEasyLoading>();
int? idDanaSosial;
DanaSosialModel? danaSosialModel;
bool jenisBool = true;
String? role;
TextEditingController namaController = TextEditingController();
TextEditingController tanggalController = TextEditingController();
TextEditingController jumlahController = TextEditingController();
TextEditingController jenisController = TextEditingController();
TextEditingController keteranganController = TextEditingController();
Future<void> init(int id) async {
log.i('init and id: $id');
getData(id);
idDanaSosial = id;
prefs.then((SharedPreferences prefs) {
role = prefs.getString('role');
});
}
getData(int id) async {
setBusy(true);
easyLoading.showLoading();
try {
var response = await _httpService.get('dana_sosial_detail?id=$id');
log.i(response.data);
danaSosialModel = DanaSosialModel.fromJson(response.data['data']);
namaController.text = danaSosialModel!.nama!;
tanggalController.text = danaSosialModel!.tanggal!;
jumlahController.text =
"Rp. ${OtherFunction().commaFormat(danaSosialModel!.jumlah != null ? int.parse(danaSosialModel!.jumlah!) : 0)}";
jenisController.text = danaSosialModel!.jenisDonasi!;
keteranganController.text = danaSosialModel!.keterangan!;
if (danaSosialModel!.jenisDonasi == 'Uang') {
jenisBool = true;
} else {
jenisBool = false;
}
log.i('status: ${danaSosialModel!.status}');
setBusy(false);
notifyListeners();
} catch (e) {
log.e(e);
setBusy(false);
} finally {
easyLoading.dismissLoading();
}
}
void handleTtd() {
dialogService
.showConfirmationDialog(
title: 'Konfirmasi',
description: 'Apakah anda yakin ingin mengkonfirmasi tanda tangan ini?',
cancelTitle: 'Tidak',
confirmationTitle: 'Ya',
)
.then((value) async {
if (value!.confirmed) {
setBusy(true);
easyLoading.showLoading();
try {
FormData formData = FormData.fromMap({
'id': idDanaSosial,
});
var response =
await _httpService.postWithFormData('dana_sosial_ttd', formData);
log.i(response.data);
getData(idDanaSosial!);
setBusy(false);
notifyListeners();
} catch (e) {
log.e(e);
setBusy(false);
dialogService.showDialog(
title: 'Error',
description: e.toString(),
);
} finally {
easyLoading.dismissLoading();
}
}
});
}
}

View File

@ -1,9 +1,11 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/ui/widgets/my_button.dart';
import 'package:panti_asuhan/ui/widgets/my_textformfield.dart';
import 'package:stacked/stacked.dart';
import 'package:validatorless/validatorless.dart';
import '../../../app/app.router.dart';
import '../../../app/themes/app_text.dart';
import '../../widgets/my_button.dart';
import '../../widgets/my_textformfield.dart';
import './login_screen_view_model.dart';
class LoginScreenView extends StatelessWidget {
@ -25,59 +27,77 @@ class LoginScreenView extends StatelessWidget {
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.2,
),
// show the logo.png
const Center(
child: Image(
image: AssetImage("assets/logo.png"),
width: 150,
height: 150,
child: Form(
key: model.formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.2,
),
),
const SizedBox(height: 10),
Text(
"SILAHKAN LOGIN",
style: boldTextStyle.copyWith(
fontSize: 18,
// show the logo.png
const Center(
child: Image(
image: AssetImage("assets/logo.png"),
width: 150,
height: 150,
),
),
),
const SizedBox(
height: 10,
),
const MyTextFormField(
hintText: "Username",
prefixIcon: Icon(Icons.person),
// controller: model.usernameController,
),
const SizedBox(
height: 10,
),
const MyTextFormField(
hintText: "Password",
prefixIcon: Icon(Icons.lock),
// controller: model.passwordController,
obscureText: true,
),
const SizedBox(
height: 10,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: MyButton(
text: "LOGIN",
const SizedBox(height: 10),
Text(
"SILAHKAN LOGIN",
style: boldTextStyle.copyWith(
fontSize: 18,
),
),
const SizedBox(
height: 10,
),
MyTextFormField(
hintText: "Username",
prefixIcon: const Icon(Icons.person),
controller: model.usernameController,
validator:
Validatorless.required("Username tidak boleh kosong"),
),
const SizedBox(
height: 10,
),
MyTextFormField(
hintText: "Password",
prefixIcon: const Icon(Icons.lock),
controller: model.passwordController,
obscureText: true,
validator:
Validatorless.required("Password tidak boleh kosong"),
),
const SizedBox(
height: 10,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: MyButton(
text: "LOGIN",
onPressed: () {
if (model.formKey.currentState!.validate()) {
model.login();
}
},
),
),
TextButton(
onPressed: () {
model.goToAdmin();
model.navigationService
.navigateTo(Routes.userIndexTrackingView);
},
),
),
],
child: const Text(
"Kembali ke beranda",
),
)
],
),
),
),
),

View File

@ -1,13 +1,45 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../app/app.logger.dart';
import '../../../app/app.router.dart';
import '../../../app/core/custom_base_view_model.dart';
class LoginScreenViewModel extends CustomBaseViewModel {
final log = getLogger('LoginScreenViewModel');
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Future<void> init() async {}
goToAdmin() {
log.d('goToAdmin');
navigationService.navigateTo(Routes.adminIndexTrackingView);
final formKey = GlobalKey<FormState>();
TextEditingController usernameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
login() {
if (usernameController.text == 'admin' &&
passwordController.text == 'admin') {
_prefs.then((SharedPreferences prefs) {
prefs.setBool('isLogin', true);
prefs.setString('role', 'admin');
});
log.d('goToAdmin');
navigationService.navigateTo(Routes.adminIndexTrackingView);
} else if (usernameController.text == 'pimpinan' &&
passwordController.text == 'pimpinan') {
_prefs.then((SharedPreferences prefs) {
prefs.setBool('isLogin', true);
prefs.setString('role', 'pimpinan');
});
log.d('goToPimpinan');
navigationService.navigateTo(Routes.pimpinanIndexTrackingView);
} else {
dialogService.showDialog(
title: 'Gagal',
description: 'Username atau password salah',
);
_prefs.then((SharedPreferences prefs) {
prefs.setBool('isLogin', false);
prefs.remove('role');
});
}
}
}

View File

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:stylish_bottom_bar/model/bar_items.dart';
import 'package:stylish_bottom_bar/stylish_bottom_bar.dart';
import '../../../../app/app.router.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './pimpinan_index_tracking_view_model.dart';
class PimpinanIndexTrackingView extends StatelessWidget {
const PimpinanIndexTrackingView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PimpinanIndexTrackingViewModel>.reactive(
viewModelBuilder: () => PimpinanIndexTrackingViewModel(),
onViewModelReady: (PimpinanIndexTrackingViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
PimpinanIndexTrackingViewModel model,
Widget? child,
) {
return Scaffold(
appBar: AppBar(
title: Text(
model.header,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
),
backgroundColor: mainColor,
elevation: 0,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
// model.navigationService.navigateTo(Routes.loginScreenView);
model.logout();
},
icon: const Icon(
Icons.logout,
color: Colors.white,
),
),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: ExtendedNavigator(
navigatorKey: StackedService.nestedNavigationKey(4),
router: PimpinanIndexTrackingViewRouter(),
initialRoute: PimpinanIndexTrackingViewRoutes.danaSosialAdminView,
),
),
bottomNavigationBar: StylishBottomBar(
items: [
for (var item in model.bottomNavBarList)
BottomBarItem(
icon: Icon(item['icon'],
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? sixthGrey
: backgroundColor),
title: Text(
item['name'],
style: regularTextStyle.copyWith(
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? sixthGrey
: Colors.grey,
),
),
backgroundColor:
model.currentIndex == model.bottomNavBarList.indexOf(item)
? Colors.white
: Colors.grey,
),
],
currentIndex: model.currentIndex,
hasNotch: true,
backgroundColor: mainColor,
onTap: (value) {
model.handleNavigation(value);
},
option: BubbleBarOptions(
barStyle: BubbleBarStyle.horizotnal,
bubbleFillStyle: BubbleFillStyle.fill,
opacity: 0.3),
),
);
},
);
}
}

View File

@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../../app/app.locator.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/app.router.dart';
class PimpinanIndexTrackingViewModel extends IndexTrackingViewModel {
final log = getLogger('PimpinanIndexTrackingViewModel');
final _navigationService = locator<NavigationService>();
final _dialogService = locator<DialogService>();
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
String header = 'Dana Sosial';
final _bottomNavBarList = [
{
'name': 'Siswa',
'icon': Icons.people_alt_outlined,
'header': 'List Siswa'
},
{'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial'},
{
'name': 'Profil',
'icon': Icons.person_4_outlined,
'header': 'Profil Panti Asuhan'
},
];
List<Map<String, dynamic>> get bottomNavBarList => _bottomNavBarList;
final List<String> _views = [
PimpinanIndexTrackingViewRoutes.dataSiswaView,
PimpinanIndexTrackingViewRoutes.danaSosialAdminView,
PimpinanIndexTrackingViewRoutes.profilView,
];
Future<void> init() async {
_prefs.then((SharedPreferences prefs) {
if (prefs.getString('role') == 'pimpinan') {
setIndex(1);
// // await 2 seconds to make sure the view is loaded
// Future.delayed(const Duration(milliseconds: 500));
} else {
prefs.setBool('isLogin', false);
prefs.remove('role');
_navigationService.clearStackAndShow(Routes.loginScreenView);
}
});
}
void handleNavigation(int index) {
log.d("handleNavigation: $index");
log.d("currentIndex: $currentIndex");
if (currentIndex == index) return;
setIndex(index);
header = _bottomNavBarList[index]['header'] as String;
_navigationService.navigateTo(
_views[index],
id: 4,
);
}
logout() {
_dialogService
.showConfirmationDialog(
title: 'Logout',
description: 'Apakah anda yakin ingin logout?',
cancelTitle: 'Ya',
confirmationTitle: 'Tidak',
// barrierDismissible: true,
)
.then((value) {
if (!value!.confirmed) {
_prefs.then((SharedPreferences prefs) {
prefs.setBool('isLogin', false);
prefs.remove('role');
_navigationService.clearStackAndShow(Routes.loginScreenView);
});
} else {
_navigationService.back();
}
});
}
}

View File

@ -1,3 +1,5 @@
import 'package:shared_preferences/shared_preferences.dart';
import '../../../app/app.logger.dart';
import '../../../app/app.router.dart';
import '../../../app/core/custom_base_view_model.dart';
@ -7,8 +9,29 @@ class SplashScreenViewModel extends CustomBaseViewModel {
Future<void> init() async {
// wait 2 seconds then navigate to login
await Future.delayed(const Duration(seconds: 2));
await navigationService.navigateTo(
Routes.loginScreenView,
);
prefs.then((SharedPreferences prefs) {
if (prefs.getBool('isLogin') != true) {
return navigationService.navigateTo(
Routes.userIndexTrackingView,
);
}
if (prefs.getString('role') == 'admin') {
return navigationService.navigateTo(
Routes.adminIndexTrackingView,
);
}
if (prefs.getString('role') == 'pimpinan') {
return navigationService.navigateTo(
Routes.pimpinanIndexTrackingView,
);
}
});
// await navigationService.navigateTo(
// // Routes.loginScreenView,
// Routes.userIndexTrackingView,
// );
}
}

View File

@ -58,18 +58,68 @@ class TambahDanaSosialView extends StatelessWidget {
),
const SizedBox(height: 20),
Text(
"Jumlah (Rp. )",
"Jenis Donasi",
style: regularTextStyle.copyWith(color: mainColor),
),
MyTextFormField(
hintText: "Jumlah (Rp. )",
keyboardType: TextInputType.number,
controller: model.jumlahController,
validator: Validatorless.multiple(
[
Validatorless.required('Jumlah tidak boleh kosong'),
Validatorless.number('Jumlah harus angka'),
],
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<String>(
value: model.jenisDonasi,
onChanged: (String? newValue) {
// model.setSelectedjenisDonasi(newValue!);
model.log.i(newValue);
model.jenisDonasi = newValue!;
model.notifyListeners();
},
items: model.jenisDonasiList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
Visibility(
visible: model.jenisDonasi == 'Uang',
child: const SizedBox(height: 20),
),
Visibility(
visible: model.jenisDonasi == 'Uang',
child: Text(
"Jumlah (Rp. )",
style: regularTextStyle.copyWith(color: mainColor),
),
),
Visibility(
visible: model.jenisDonasi == 'Uang',
child: MyTextFormField(
hintText: "Jumlah (Rp. ) Donasi",
keyboardType: TextInputType.number,
controller: model.jumlahController,
validator: model.jenisDonasi == 'Uang'
? Validatorless.multiple(
[
Validatorless.required(
'Jumlah tidak boleh kosong'),
Validatorless.number('Jumlah harus angka'),
],
)
: null,
),
),
const SizedBox(height: 20),
@ -78,7 +128,7 @@ class TambahDanaSosialView extends StatelessWidget {
style: regularTextStyle.copyWith(color: mainColor),
),
MyTextFormField(
hintText: 'Tanggal',
hintText: ' Pilih Tanggal',
readOnly: true,
controller: model.tanggalController,
validator: Validatorless.required(
@ -88,6 +138,30 @@ class TambahDanaSosialView extends StatelessWidget {
},
),
const SizedBox(height: 20),
Visibility(
visible: model.jenisDonasi == 'Barang',
child: Text(
"Keterangan",
style: regularTextStyle.copyWith(color: mainColor),
),
),
Visibility(
visible: model.jenisDonasi == 'Barang',
child: MyTextFormField(
hintText: 'Masukkan Keterangan',
maxLines: 3,
controller: model.keteranganController,
validator: model.jenisDonasi == 'Barang'
? Validatorless.multiple(
[
Validatorless.required(
'Keterangan tidak boleh kosong'),
],
)
: null,
),
),
const SizedBox(height: 20),
MyButton(
text: "Simpan Data",
onPressed: () {

View File

@ -13,14 +13,15 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel {
final _httpService = locator<MyHttpServices>();
final easyLoading = locator<MyEasyLoading>();
String jenisDana = 'Pemasukan';
List<String> jenisDanaList = ['Pemasukan', 'Pengeluaran'];
String jenisDonasi = 'Uang';
List<String> jenisDonasiList = ['Uang', 'Barang'];
final formKey = GlobalKey<FormState>();
TextEditingController namaController = TextEditingController();
TextEditingController jumlahController = TextEditingController();
TextEditingController tanggalController = TextEditingController();
TextEditingController keteranganController = TextEditingController();
Future<void> init() async {}
@ -47,6 +48,8 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel {
'nama': namaController.text,
'jumlah': jumlahController.text,
'tanggal': tanggalController.text,
'ket': keteranganController.text,
'jenis': jenisDonasi,
});
var response =
await _httpService.postWithFormData('dana_sosial', formData);

View File

@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/app.router.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:stylish_bottom_bar/model/bar_items.dart';
import 'package:stylish_bottom_bar/stylish_bottom_bar.dart';
import '../../../app/themes/app_colors.dart';
import '../../../app/themes/app_text.dart';
import './user_index_tracking_view_model.dart';
class UserIndexTrackingView extends StatelessWidget {
const UserIndexTrackingView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<UserIndexTrackingViewModel>.reactive(
viewModelBuilder: () => UserIndexTrackingViewModel(),
onViewModelReady: (UserIndexTrackingViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
UserIndexTrackingViewModel model,
Widget? child,
) {
return Scaffold(
appBar: AppBar(
title: Text(
model.header,
style: const TextStyle(
color: Colors.white,
fontSize: 20,
),
),
backgroundColor: mainColor,
elevation: 0,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
model.login();
},
icon: const Icon(Icons.login, color: Colors.white),
),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
child: ExtendedNavigator(
navigatorKey: StackedService.nestedNavigationKey(5),
router: UserIndexTrackingViewRouter(),
initialRoute: UserIndexTrackingViewRoutes.danaSosialAdminView,
),
),
bottomNavigationBar: StylishBottomBar(
items: [
for (var item in model.bottomNavBarList)
BottomBarItem(
icon: Icon(item['icon'],
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? sixthGrey
: backgroundColor),
title: Text(
item['name'],
style: regularTextStyle.copyWith(
color: model.currentIndex ==
model.bottomNavBarList.indexOf(item)
? sixthGrey
: Colors.grey,
),
),
backgroundColor:
model.currentIndex == model.bottomNavBarList.indexOf(item)
? Colors.white
: Colors.grey,
),
],
currentIndex: model.currentIndex,
hasNotch: true,
backgroundColor: mainColor,
onTap: (value) {
model.handleNavigation(value);
},
option: BubbleBarOptions(
barStyle: BubbleBarStyle.horizotnal,
bubbleFillStyle: BubbleFillStyle.fill,
opacity: 0.3),
),
);
},
);
}
}

View File

@ -0,0 +1,71 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/app.router.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../app/app.locator.dart';
import '../../../app/app.logger.dart';
class UserIndexTrackingViewModel extends IndexTrackingViewModel {
final log = getLogger('PimpinanIndexTrackingViewModel');
final _navigationService = locator<NavigationService>();
// final _dialogService = locator<DialogService>();
String header = 'Dana Sosial';
final _bottomNavBarList = [
{
'name': 'Siswa',
'icon': Icons.people_alt_outlined,
'header': 'List Siswa'
},
{'name': 'Dana', 'icon': Icons.money, 'header': 'Dana Sosial'},
{
'name': 'Profil',
'icon': Icons.person_4_outlined,
'header': 'Profil Panti Asuhan'
},
{'name': 'V & M', 'icon': Icons.list_alt_rounded, 'header': 'Visi & Misi'},
{'name': 'Sejarah', 'icon': Icons.list_outlined, 'header': 'Sejarah'},
{
'name': 'S O',
'icon': Icons.people_alt_outlined,
'header': 'Struktur Organisasi'
},
];
List<Map<String, dynamic>> get bottomNavBarList => _bottomNavBarList;
final List<String> _views = [
UserIndexTrackingViewRoutes.dataSiswaView,
UserIndexTrackingViewRoutes.danaSosialAdminView,
UserIndexTrackingViewRoutes.profilView,
UserIndexTrackingViewRoutes.visiMisiView,
UserIndexTrackingViewRoutes.sejarahView,
UserIndexTrackingViewRoutes.strukturOrganisasiView
];
Future<void> init() async {
setIndex(1);
}
void handleNavigation(int index) {
log.d("handleNavigation: $index");
log.d("currentIndex: $currentIndex");
if (currentIndex == index) return;
setIndex(index);
header = _bottomNavBarList[index]['header'] as String;
_navigationService.navigateTo(
_views[index],
id: 5,
);
}
void login() {
_navigationService.navigateTo(
Routes.loginScreenView,
);
}
}