modify struktur organisasi page so can be edited, add delete siswa, add 'pengeluaran' in dana sosial, added edit siswa dialog

This commit is contained in:
kicap 2023-08-21 03:46:54 +08:00
parent 4f7a8b870c
commit b1dc1851a4
15 changed files with 1173 additions and 519 deletions

View File

@ -1,11 +1,4 @@
import 'package:panti_asuhan/ui/views/admin_index_tracking/dana_sosial_admin/dana_sosial_admin_view.dart';
import 'package:panti_asuhan/ui/views/admin_index_tracking/data_siswa/data_siswa_view.dart';
import 'package:panti_asuhan/ui/views/admin_index_tracking/edit_siswa/edit_siswa_view.dart';
import 'package:panti_asuhan/ui/views/admin_index_tracking/profil/profil_view.dart';
import 'package:panti_asuhan/ui/views/admin_index_tracking/struktur_organisasi/edit_strukrur_organisasi_dialog/edit_strukrur_organisasi_dialog_view.dart';
import 'package:panti_asuhan/ui/views/detail_dana_sosial/detail_dana_sosial_view.dart';
import 'package:panti_asuhan/ui/views/pimpinan_index_tracking/pimpinan_index_tracking/pimpinan_index_tracking_view.dart';
import 'package:panti_asuhan/ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart';
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';
@ -13,12 +6,20 @@ import '../services/http_services.dart';
import '../services/my_easyloading.dart';
import '../ui/views/admin_index_tracking/add_siswa_dialog/add_siswa_dialog/add_siswa_dialog_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_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';
import '../ui/views/admin_index_tracking/sejarah/sejarah_view.dart';
import '../ui/views/admin_index_tracking/struktur_organisasi/edit_strukrur_organisasi_dialog/edit_strukrur_organisasi_dialog_view.dart';
import '../ui/views/admin_index_tracking/struktur_organisasi/struktur_organisasi_view.dart';
import '../ui/views/admin_index_tracking/visi_misi/visi_misi_view.dart';
import '../ui/views/detail_dana_sosial/detail_dana_sosial_view.dart';
import '../ui/views/login_screen/login_screen_view.dart';
import '../ui/views/pimpinan_index_tracking/pimpinan_index_tracking/pimpinan_index_tracking_view.dart';
import '../ui/views/splash_screen/splash_screen_view.dart';
import '../ui/views/tambah_dana_sosial/tambah_dana_sosial_view.dart';
import '../ui/views/user_index_tracking/user_index_tracking_view.dart';
@StackedApp(
@ -66,6 +67,7 @@ import '../ui/views/user_index_tracking/user_index_tracking_view.dart';
StackedDialog(classType: AddSiswaDialogView),
StackedDialog(classType: FilterDialogView),
StackedDialog(classType: EditStrukrurOrganisasiDialogView),
StackedDialog(classType: EditDialogSiswaView)
],
dependencies: [
LazySingleton(classType: NavigationService),

View File

@ -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/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';
@ -15,6 +16,7 @@ enum DialogType {
addSiswaDialogView,
filterDialogView,
editStrukrurOrganisasiDialogView,
editDialogSiswaView,
}
void setupDialogUi() {
@ -28,6 +30,8 @@ void setupDialogUi() {
DialogType.editStrukrurOrganisasiDialogView:
(context, request, completer) => EditStrukrurOrganisasiDialogView(
request: request, completer: completer),
DialogType.editDialogSiswaView: (context, request, completer) =>
EditDialogSiswaView(request: request, completer: completer),
};
dialogService.registerCustomDialogBuilders(builders);

View File

@ -1,5 +1,6 @@
class DanaSosialModel {
String? idDanaSosial;
String? bentuk;
String? nama;
String? jumlah;
String? tanggal;
@ -12,6 +13,7 @@ class DanaSosialModel {
DanaSosialModel(
{this.idDanaSosial,
this.bentuk,
this.nama,
this.jumlah,
this.tanggal,
@ -23,6 +25,7 @@ class DanaSosialModel {
DanaSosialModel.fromJson(Map<String, dynamic> json) {
idDanaSosial = json['id_dana_sosial'];
bentuk = json['bentuk'];
nama = json['nama'];
jumlah = json['jumlah'];
tanggal = json['tanggal'];
@ -37,6 +40,7 @@ class DanaSosialModel {
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id_dana_sosial'] = idDanaSosial;
data['bentuk'] = bentuk;
data['nama'] = nama;
data['jumlah'] = jumlah;
data['tanggal'] = tanggal;

View File

@ -20,7 +20,9 @@ class MyHttpServices {
Future<Response> get(String path) async {
try {
return await _dio.get(path);
} on DioError {
} on DioError catch (e) {
log.e(e.message);
log.e(e.response);
rethrow;
}
}
@ -28,8 +30,31 @@ class MyHttpServices {
Future<Response> postWithFormData(String path, FormData formData) async {
try {
return await _dio.post(path, data: formData);
} on DioError {
} on DioError catch (e) {
log.e(e.message);
log.e(e.response);
rethrow;
}
}
// // delete
// Future<Response> delete(String path, FormData data) async {
// try {
// // log.i('path: $path');
// return await _dio.delete(
// path,
// data: data,
// // encoding: Encoding.getByName('utf-8'),
// options: Options(
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
// },
// ),
// );
// } on DioError catch (e) {
// log.e(e.message);
// log.e(e.response);
// rethrow;
// }
// }
}

View File

@ -167,15 +167,52 @@ class TheData extends ViewModelWidget<DanaSosialAdminViewModel> {
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),
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 ?? '',

View File

@ -0,0 +1,313 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/themes/app_colors.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 './edit_dialog_siswa_view_model.dart';
class EditDialogSiswaView extends StatelessWidget {
final DialogRequest request;
final Function(DialogResponse) completer;
const EditDialogSiswaView({
Key? key,
required this.request,
required this.completer,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<EditDialogSiswaViewModel>.reactive(
viewModelBuilder: () => EditDialogSiswaViewModel(),
onViewModelReady: (EditDialogSiswaViewModel model) async {
await model.init(request.data);
},
builder: (
BuildContext context,
EditDialogSiswaViewModel model,
Widget? child,
) {
return Dialog(
child: Container(
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
child: SingleChildScrollView(
child: Form(
key: model.formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
const Center(
child: Text(
'Edit Data Siswa',
style: boldTextStyle,
),
),
const SizedBox(height: 10),
Text(
' Nama',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
hintText: 'Masukkan Nama',
controller: model.namaController,
validator:
Validatorless.required('Nama tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Tanggal Lahir',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.tanggalLahirController,
readOnly: true,
validator: Validatorless.required(
'Tanggal lahir tidak boleh kosong'),
onTap: () {
model.changeDate(context);
},
),
const SizedBox(height: 10),
Text(
' Tempat Lahir',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
hintText: 'Masukkan Tempat Lahir',
controller: model.tempatLahirController,
validator: Validatorless.required(
'Tempat lahir tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Jenis Kelamin',
style: regularTextStyle.copyWith(
fontSize: 12,
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<String>(
value: model.jenisKelamin,
onChanged: (String? newValue) {
// model.setSelectedJenisKelamin(newValue!);
model.log.i(newValue);
model.jenisKelamin = newValue!;
model.notifyListeners();
},
items: model.jenisKelaminList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 10),
Text(
' No. Telepon',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
hintText: 'Masukkan No. Telepon',
controller: model.noTelponController,
validator: Validatorless.multiple(
[
Validatorless.required(
'No. telepon tidak boleh kosong'),
Validatorless.number(
'No. telepon harus berupa angka'),
],
),
),
const SizedBox(height: 10),
Text(
' Agama',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.agamaController,
validator:
Validatorless.required('Agama tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Kewarganegaraan',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.kewarganegaraanController,
validator: Validatorless.required(
'Kewarganegaraan tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Alamat',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.alamatController,
maxLines: 2,
validator:
Validatorless.required('Alamat tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Pendidikan SD',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.pendidikanSDController,
validator: Validatorless.required(
'Pendidikan SD tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Pendidikan SMP',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.pendidikanSMPController,
validator: Validatorless.required(
'Pendidikan SMP tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Pendidikan SMA',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.pendidikanSMAController,
validator: Validatorless.required(
'Pendidikan SMA tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Kemampuan',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.kemampuanController,
maxLines: 4,
validator: Validatorless.required(
'Kemampuan tidak boleh kosong'),
),
const SizedBox(height: 10),
Text(
' Hobi',
style: regularTextStyle.copyWith(
fontSize: 12,
color: mainColor,
),
),
MyTextFormField(
controller: model.hobiController,
maxLines: 4,
validator:
Validatorless.required('Hobi tidak boleh kosong'),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {},
child: const Text(
'Batal',
style: TextStyle(
color: dangerColor,
),
),
),
TextButton(
onPressed: () async {
if (model.formKey.currentState!.validate()) {
// bool res = await model.postData();
// model.log.i("res: $res");
// if (res) {
// completer(
// DialogResponse(
// confirmed: true,
// ),
// );
// }
}
},
child: const Text(
'Update',
style: TextStyle(
color: blueColor,
),
),
),
],
),
],
),
),
),
),
);
},
);
}
}

View File

@ -0,0 +1,69 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_holo_date_picker/flutter_holo_date_picker.dart';
import '../../../../../app/app.logger.dart';
import '../../../../../app/core/custom_base_view_model.dart';
import '../../../../../model/siswa_model.dart';
class EditDialogSiswaViewModel extends CustomBaseViewModel {
final log = getLogger('EditDialogSiswaViewModel');
SiswaModel? siswaModel;
String jenisKelamin = 'Laki-laki';
List<String> jenisKelaminList = ['Laki-laki', 'Perempuan'];
TextEditingController namaController = TextEditingController();
TextEditingController tanggalLahirController = TextEditingController();
TextEditingController tempatLahirController = TextEditingController();
TextEditingController alamatController = TextEditingController();
TextEditingController noTelponController = TextEditingController();
TextEditingController agamaController = TextEditingController();
TextEditingController kewarganegaraanController = TextEditingController();
TextEditingController pendidikanSDController = TextEditingController();
TextEditingController pendidikanSMPController = TextEditingController();
TextEditingController pendidikanSMAController = TextEditingController();
TextEditingController kemampuanController = TextEditingController();
TextEditingController hobiController = TextEditingController();
final formKey = GlobalKey<FormState>();
Future<void> init(data) async {
log.i('data: $data');
setBusy(true);
siswaModel = data;
notifyListeners();
setBusy(false);
namaController.text = siswaModel!.nama!;
tanggalLahirController.text = siswaModel!.tanggalLahir!;
tempatLahirController.text = siswaModel!.tempatLahir!;
alamatController.text = siswaModel!.alamat!;
noTelponController.text = siswaModel!.noTelpon!;
agamaController.text = siswaModel!.agama!;
kewarganegaraanController.text = siswaModel!.kewarganegaraan!;
pendidikanSDController.text = siswaModel!.pendidikanSd!;
pendidikanSMPController.text = siswaModel!.pendidikanSmp!;
pendidikanSMAController.text = siswaModel!.pendidikanSma!;
kemampuanController.text = siswaModel!.kemampuan!;
hobiController.text = siswaModel!.hobi!;
jenisKelamin = siswaModel!.jenisKelamin!;
notifyListeners();
}
void changeDate(BuildContext context) async {
// get today's date
var datePicked = await DatePicker.showSimpleDatePicker(
context,
initialDate: DateTime(2010),
firstDate: DateTime(2000),
lastDate: DateTime(2015),
dateFormat: "dd-MMMM-yyyy",
locale: DateTimePickerLocale.id,
looping: true,
);
if (datePicked != null) {
String date = datePicked.toString().split(' ')[0];
tanggalLahirController.text = date;
}
}
}

View File

@ -43,15 +43,15 @@ class EditSiswaView extends StatelessWidget {
body: Padding(
padding: const EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: Column(
child: Stack(
children: [
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Stack(
children: [
CircleAvatar(
child: CircleAvatar(
radius: 50,
backgroundColor: fontParagraphColor,
backgroundImage: model.siswaModel != null
@ -67,8 +67,6 @@ class EditSiswaView extends StatelessWidget {
)
: null,
),
],
),
),
const SizedBox(height: 10),
MyTextFormField(
@ -117,7 +115,8 @@ class EditSiswaView extends StatelessWidget {
[
Validatorless.required(
'No. telepon tidak boleh kosong'),
Validatorless.number('No. telepon harus berupa angka'),
Validatorless.number(
'No. telepon harus berupa angka'),
],
),
),
@ -178,8 +177,8 @@ class EditSiswaView extends StatelessWidget {
controller: model.kemampuanController,
enabled: false,
maxLines: 4,
validator:
Validatorless.required('Kemampuan tidak boleh kosong'),
validator: Validatorless.required(
'Kemampuan tidak boleh kosong'),
),
const SizedBox(height: 10),
MyTextFormField(
@ -227,6 +226,78 @@ class EditSiswaView extends StatelessWidget {
// ),
],
),
Positioned(
top: 0,
right: 45,
// create a edit rounded button
child: Container(
alignment: Alignment.center,
height: 30,
width: 30,
decoration: BoxDecoration(
color: blueColor,
borderRadius: BorderRadius.circular(20),
),
child: IconButton(
onPressed: () {
// model.changeEdit();
model.editData();
},
icon: const Icon(
Icons.edit,
color: Colors.white,
size: 13,
),
),
),
),
Positioned(
top: 0,
right: 0,
// create a close rounded button
child: Container(
alignment: Alignment.center,
height: 30,
width: 30,
decoration: BoxDecoration(
color: dangerColor,
borderRadius: BorderRadius.circular(20),
),
child: IconButton(
onPressed: () {
// model.changeEdit();
model.dialogService
.showDialog(
title: 'Hapus Data',
description:
'Apakah anda yakin ingin menghapus data ini?',
buttonTitle: 'Hapus',
cancelTitle: 'Batal',
buttonTitleColor: dangerColor,
cancelTitleColor: mainColor,
)
.then((value) {
if (value!.confirmed) {
model.deleteData();
// close dialog
Navigator.pop(context);
// model.navigationService.clearTillFirstAndShow(
// Routes.splashScreenView);
}
});
// model.deleteData();
},
icon: const Icon(
Icons.delete_forever,
color: Colors.white,
size: 15,
),
),
),
),
],
),
),
),
);

View File

@ -1,5 +1,7 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.locator.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
@ -64,4 +66,46 @@ class EditSiswaViewModel extends CustomBaseViewModel {
easyLoading.dismissLoading();
}
}
void deleteData() async {
setBusy(true);
easyLoading.showLoading();
try {
var response = await _httpService.postWithFormData(
'siswa_delete',
FormData.fromMap(
{
'id': siswaModel!.idSiswa,
},
),
);
log.i(response.data);
snackbarService.showSnackbar(
message: 'Data berhasil dihapus',
title: 'Berhasil',
duration: const Duration(seconds: 2),
);
// navigationService.back();
} catch (e) {
snackbarService.showSnackbar(
message: 'Data gagal dihapus',
title: 'Gagal',
duration: const Duration(seconds: 2),
);
log.e(e);
} finally {
setBusy(false);
easyLoading.dismissLoading();
}
}
editData() async {
var res = dialogService.showCustomDialog(
variant: DialogType.editDialogSiswaView,
data: siswaModel,
);
res;
}
}

View File

@ -55,10 +55,9 @@ class EditStrukrurOrganisasiDialogView extends StatelessWidget {
),
),
// top right rounded add button
// request?.data['tambahan'] == false
// ? const SizedBox()
// :
Positioned(
request?.data['tambahan'] == false
? const SizedBox()
: Positioned(
top: 0,
right: 0,
child: GestureDetector(
@ -90,7 +89,7 @@ class EditStrukrurOrganisasiDialogView extends StatelessWidget {
text: 'Simpan',
onPressed: () {
// model.check();
model.uploadJabatan();
model.uploadJabatan(completer!);
},
),
),
@ -108,6 +107,7 @@ class TheWidget extends ViewModelWidget<EditStrukrurOrganisasiDialogViewModel> {
final TextEditingController controller;
final int index;
@override
// ignore: overridden_fields
final Key key;
const TheWidget({
@ -151,7 +151,7 @@ class TheWidget extends ViewModelWidget<EditStrukrurOrganisasiDialogViewModel> {
],
),
// top right rounded add button
index == 0
index == 1
? const SizedBox()
: Positioned(
top: 0,

View File

@ -4,6 +4,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:http_parser/http_parser.dart';
import 'package:image_picker/image_picker.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../../../app/app.locator.dart';
import '../../../../../app/app.logger.dart';
@ -89,7 +90,35 @@ class EditStrukrurOrganisasiDialogViewModel extends CustomBaseViewModel {
}
}
uploadJabatan() async {
uploadJabatan(Function(DialogResponse p1) completer) async {
// check if the controller is empty
for (var i = 1; i <= controllers.length; i++) {
String key = controllers.keys.elementAt(i - 1);
if (controllers[key]!.text.isEmpty) {
snackbarService.showSnackbar(
message: 'Nama tidak boleh kosong',
title: 'Error',
duration: const Duration(seconds: 2),
);
return;
}
}
// check if the image is empty
for (var i = 1; i <= controllers.length; i++) {
// String key = controllers.keys.elementAt(i - 1);
if (!imagePaths.containsKey('image$i')) {
snackbarService.showSnackbar(
message: 'Gambar tidak boleh kosong',
title: 'Error',
duration: const Duration(seconds: 2),
);
return;
}
}
setBusy(true);
easyloading.customLoading('Edit Detail Jabatan $name');
Map<String, dynamic> array = {
'jabatan': name,
'jumlah': controllers.length.toString(),
@ -108,21 +137,26 @@ class EditStrukrurOrganisasiDialogViewModel extends CustomBaseViewModel {
contentType: MediaType.parse('image/jpeg'),
);
}
FormData formData = FormData.fromMap(array);
// log.i(array);
try {
// // // log.i(formData.fields);
var response =
await _httpService.postWithFormData('edit_jabatan', formData);
log.i(response.data);
setBusy(true);
easyloading.customLoading('Edit Detail Jabatan $name');
await Future.delayed(const Duration(seconds: 1));
// log.i(response.data);
completer(
DialogResponse(confirmed: true),
);
} catch (e) {
log.e(e);
completer(
DialogResponse(confirmed: false),
);
} finally {
easyloading.dismissLoading();
setBusy(false);
}
}
void removeWidget(int index, Key containerKey) {
log.i('remove widget $index');

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:stacked/stacked.dart';
import './struktur_organisasi_view_model.dart';
@ -34,237 +35,130 @@ class StrukturOrganisasiView extends StatelessWidget {
const SizedBox(
height: 20,
),
const KetuaWidget(),
const SizedBox(
height: 20,
),
const SekretarisWidget(),
const SizedBox(
height: 20,
),
const BendaharaWidget(),
const SizedBox(
height: 20,
),
const Text(
"Seksi Pengasuh",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 2,
),
Text(
'${model.seksiPengasuh1}\n${model.seksiPengasuh2}\n${model.seksiPengasuh3}\n${model.seksiPengasuh4}',
style: const TextStyle(
fontSize: 20,
),
FirstWidget(
title: "Ketua",
data: model.dataKetua,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Ibadah",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 2,
),
Text(
'${model.seksiIbadah1}\n${model.seksiIbadah2}\n${model.seksiIbadah3}\n${model.seksiIbadah4}',
style: const TextStyle(
fontSize: 20,
),
FirstWidget(
title: 'Sekretaris',
data: model.dataSekretaris,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Pendidikan",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 2,
),
Text(
'${model.seksiPendidikan1}\n${model.seksiPendidikan2}',
style: const TextStyle(
fontSize: 20,
),
FirstWidget(
title: 'Bendahara',
data: model.dataBendahara,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Kesehatan",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 2,
),
Text(
model.seksiKesehatan,
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Pengasuh',
data: model.dataPengasuh,
length: model.dataPengasuhLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Kebersihan",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 2,
),
Text(
model.seksiKebersihan,
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Ibadah',
data: model.dataIbadah,
length: model.dataIbadahLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Keterampilan",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
model.seksiKeterampilan1,
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Pendidikan',
data: model.dataPendidikan,
length: model.dataPendidikanLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Sarana Prasarana",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
model.seksiSaranaPrasarana1,
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Kesehatan',
data: model.dataKesehatan,
length: model.dataKesehatanLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Konsumsi",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
'${model.seksiKonsumsi1}\n${model.seksiKonsumsi2}',
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Kebersihan',
data: model.dataKebersihan,
length: model.dataKebersihanLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Keamanan",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
'${model.seksiKeamanan1}\n${model.seksiKeamanan2}',
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Keterampilan',
data: model.dataKeterampilan,
length: model.dataKeterampilanLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Gedung",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
'${model.seksiGedung1}\n${model.seksiGedung2}\n${model.seksiGedung3}\n${model.seksiGedung4}',
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Sarana dan Prasarana',
data: model.dataSaranaDanPrasarana,
length: model.dataSaranaDanPrasaranaLength,
),
const SizedBox(
height: 20,
),
const Text(
"Seksi Wisma",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
'${model.seksiWisma1}\n${model.seksiWisma2}\n${model.seksiWisma3}\n${model.seksiWisma4}\n${model.seksiWisma5}',
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Konsumsi',
data: model.dataKonsumsi,
length: model.dataKonsumsiLength,
),
const SizedBox(
height: 20,
),
const Text(
"Kelompok Putri",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
Text(
'${model.kelompokPutri1}\n${model.kelompokPutri2}\n${model.kelompokPutri3}',
style: const TextStyle(
fontSize: 20,
),
SecondWidget(
title: 'Seksi Keamanan',
data: model.dataKeamanan,
length: model.dataKeamananLength,
),
const SizedBox(
height: 20,
),
const Text(
"Kelompok Putra",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
SecondWidget(
title: 'Seksi Gedung',
data: model.dataGedung,
length: model.dataGedungLength,
),
const SizedBox(
height: 20,
),
Text(
'${model.kelompokPutra1}\n${model.kelompokPutra2}\n${model.kelompokPutra3}',
style: const TextStyle(
fontSize: 20,
SecondWidget(
title: 'Seksi Wisma',
data: model.dataWisma,
length: model.dataWismaLength,
),
const SizedBox(
height: 20,
),
SecondWidget(
title: 'Kelompok Putra',
data: model.dataKelompokPutra,
length: model.dataKelompokPutraLength,
),
const SizedBox(
height: 20,
),
SecondWidget(
title: 'Kelompok Putri',
data: model.dataKelompokPutri,
length: model.dataKelompokPutriLength,
),
const SizedBox(
height: 20,
),
],
),
@ -276,9 +170,16 @@ class StrukturOrganisasiView extends StatelessWidget {
}
}
class BendaharaWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
const BendaharaWidget({
class SecondWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
final String title;
final Map<String, dynamic> data;
final int length;
const SecondWidget({
super.key,
required this.title,
required this.data,
required this.length,
});
@override
@ -292,56 +193,10 @@ class BendaharaWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Bendahara",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
IconButton(
onPressed: () {
// model.editSekretaris();
},
icon: const Icon(Icons.edit),
)
],
),
const SizedBox(
height: 2,
),
Text(
viewModel.bendahara,
title,
style: const TextStyle(
fontSize: 20,
),
),
],
),
);
}
}
class SekretarisWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
const SekretarisWidget({
super.key,
});
@override
Widget build(BuildContext context, StrukturOrganisasiViewModel viewModel) {
return Card(
elevation: 4,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Sekretaris",
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
@ -350,30 +205,65 @@ class SekretarisWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
),
IconButton(
onPressed: () {
// model.editSekretaris();
viewModel.editData(title, true);
},
icon: const Icon(Icons.edit),
)
],
),
for (var i = 0; i < length; i++)
Column(
children: [
Center(
child: data.isEmpty
? null
: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image.network(
'${dotenv.env['url']}${data['img_url$i']}',
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
),
const SizedBox(
height: 2,
),
Text(
viewModel.sekretaris,
data['nama$i'] ?? '...',
style: const TextStyle(
fontSize: 20,
),
),
const SizedBox(
height: 5,
),
// create a line
const Divider(
color: Colors.black,
height: 20,
thickness: 1,
indent: 20,
endIndent: 20,
),
const SizedBox(height: 5),
],
),
],
),
);
}
}
class KetuaWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
const KetuaWidget({
class FirstWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
final String title;
final Map<String, dynamic> data;
const FirstWidget({
super.key,
required this.title,
required this.data,
});
@override
@ -387,9 +277,9 @@ class KetuaWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
"Ketua",
style: TextStyle(
Text(
title,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
@ -399,17 +289,30 @@ class KetuaWidget extends ViewModelWidget<StrukturOrganisasiViewModel> {
),
IconButton(
onPressed: () {
viewModel.editData('ketua', false);
viewModel.editData(title, false);
},
icon: const Icon(Icons.edit),
)
],
),
Center(
child: data.isEmpty
? null
: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image.network(
'${dotenv.env['url']}${data['img_url']}',
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
),
const SizedBox(
height: 2,
),
Text(
viewModel.ketua,
data['nama'] ?? '...',
style: const TextStyle(
fontSize: 20,
),

View File

@ -1,61 +1,155 @@
import 'package:panti_asuhan/app/core/custom_base_view_model.dart';
import '../../../../app/app.dialogs.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 StrukturOrganisasiViewModel extends CustomBaseViewModel {
final log = getLogger('StrukturOrganisasiViewModel');
final _httpService = locator<MyHttpServices>();
final easyLoading = locator<MyEasyLoading>();
String ketua = "Dr. Andi Fitriani D, S.Ag, M.Pd";
String sekretaris = "Fitriana Buyanus, S.Si ., M.Kes";
String bendahara = "Hj. Djaliah, A.Ma";
Map<String, dynamic> dataKetua = {};
Map<String, dynamic> dataSekretaris = {};
Map<String, dynamic> dataBendahara = {};
String seksiPengasuh1 = "Dra Hj, CIA";
String seksiPengasuh2 = "Dahang, S.Ag";
String seksiPengasuh3 = "Sumadin, S.Pd.I";
String seksiPengasuh4 = "Darwan";
Map<String, dynamic> dataPengasuh = {};
int dataPengasuhLength = 0;
String seksiIbadah1 = "Drs. Najib La'ady";
String seksiIbadah2 = "Sumadin, S.Pd.I";
String seksiIbadah3 = "Ahmad";
String seksiIbadah4 = "Darwan";
Map<String, dynamic> dataIbadah = {};
int dataIbadahLength = 0;
String seksiPendidikan1 = "Dra. Hj. CIA";
String seksiPendidikan2 = "Hj. Djaliah, A.Ma";
Map<String, dynamic> dataPendidikan = {};
int dataPendidikanLength = 0;
String seksiKesehatan = "Haerul, SKM";
String seksiKebersihan = "Bd. Lina Sutomo";
Map<String, dynamic> dataKebersihan = {};
int dataKebersihanLength = 0;
String seksiKeterampilan1 = "Yuslihudriani, S.Pd";
Map<String, dynamic> dataKesehatan = {};
int dataKesehatanLength = 0;
String seksiSaranaPrasarana1 = "Muh.Adham, ST";
Map<String, dynamic> dataKeterampilan = {};
int dataKeterampilanLength = 0;
String seksiKonsumsi1 = "Fatmawati";
String seksiKonsumsi2 = "Rasnaya";
Map<String, dynamic> dataSaranaDanPrasarana = {};
int dataSaranaDanPrasaranaLength = 0;
String seksiKeamanan1 = "Firdaus";
String seksiKeamanan2 = "Ahmad";
Map<String, dynamic> dataKonsumsi = {};
int dataKonsumsiLength = 0;
String seksiGedung1 = "Dra. Bangsuari";
String seksiGedung2 = "Hidayani";
String seksiGedung3 = "Dahang. S,Ag";
String seksiGedung4 = "Saharia";
Map<String, dynamic> dataKeamanan = {};
int dataKeamananLength = 0;
String seksiWisma1 = "Drs. Muh, Yasmin";
String seksiWisma2 = "Hj. Hadilah";
String seksiWisma3 = "Muh.Adham, ST";
String seksiWisma4 = "Ahmad";
String seksiWisma5 = "Dahang, S.Ag";
Map<String, dynamic> dataGedung = {};
int dataGedungLength = 0;
String kelompokPutri1 = "St. Khadijah";
String kelompokPutri2 = "St. Aisyah";
String kelompokPutri3 = "St. Fatimah";
Map<String, dynamic> dataWisma = {};
int dataWismaLength = 0;
String kelompokPutra1 = "Ahmad Dahlan";
String kelompokPutra2 = "Ar. Fahruddin";
String kelompokPutra3 = "Amin Rais";
Map<String, dynamic> dataKelompokPutra = {};
int dataKelompokPutraLength = 0;
Future<void> init() async {}
Map<String, dynamic> dataKelompokPutri = {};
int dataKelompokPutriLength = 0;
Future<void> init() async {
getData('Ketua', false, null);
getData('Sekretaris', false, null);
getData('Bendahara', false, null);
getData('Seksi Pengasuh', true, dataPengasuhLength);
getData('Seksi Ibadah', true, dataIbadahLength);
getData('Seksi Pendidikan', true, dataPendidikanLength);
getData('Seksi Kebersihan', true, dataKebersihanLength);
getData('Seksi Kesehatan', true, dataKesehatanLength);
getData('Seksi Keterampilan', true, dataKeterampilanLength);
getData('Sarana dan Prasarana', true, dataSaranaDanPrasaranaLength);
getData('Seksi Konsumsi', true, dataKonsumsiLength);
getData('Seksi Keamanan', true, dataKeamananLength);
getData('Seksi Gedung', true, dataGedungLength);
getData('Seksi Wisma', true, dataWismaLength);
getData('Kelompok Putra', true, dataKelompokPutraLength);
getData('Kelompok Putri', true, dataKelompokPutriLength);
}
getData(String jabatan, bool stat, int? length) async {
easyLoading.customLoading('Loading Data');
setBusy(true);
try {
var response = await _httpService.get('jabatan?jabatan=$jabatan');
// log.i(response.data);
if (response.data['data'].length == 0) return;
Map<String, dynamic> data = {};
if (!stat) {
var datanya = response.data['data'][0];
data['nama'] = datanya['nama'];
data['img_url'] = datanya['img_url'];
// log.i(data);
// return;
} else {
var datanya = response.data['data'];
length = datanya.length;
for (var i = 0; i < datanya.length; i++) {
data['nama$i'] = datanya[i]['nama'];
data['img_url$i'] = datanya[i]['img_url'];
}
}
if (jabatan == 'Ketua') {
dataKetua = data;
} else if (jabatan == 'Sekretaris') {
dataSekretaris = data;
} else if (jabatan == 'Bendahara') {
dataBendahara = data;
} else if (jabatan == 'Seksi Pengasuh') {
dataPengasuh = data;
dataPengasuhLength = length!;
} else if (jabatan == 'Seksi Ibadah') {
dataIbadah = data;
dataIbadahLength = length!;
} else if (jabatan == 'Seksi Pendidikan') {
dataPendidikan = data;
dataPendidikanLength = length!;
} else if (jabatan == 'Seksi Kebersihan') {
dataKebersihan = data;
dataKebersihanLength = length!;
} else if (jabatan == 'Seksi Kesehatan') {
dataKesehatan = data;
dataKesehatanLength = length!;
} else if (jabatan == 'Seksi Keterampilan') {
dataKeterampilan = data;
dataKeterampilanLength = length!;
} else if (jabatan == 'Sarana dan Prasarana') {
dataSaranaDanPrasarana = data;
dataSaranaDanPrasaranaLength = length!;
} else if (jabatan == 'Seksi Konsumsi') {
dataKonsumsi = data;
dataKonsumsiLength = length!;
} else if (jabatan == 'Seksi Keamanan') {
dataKeamanan = data;
dataKeamananLength = length!;
} else if (jabatan == 'Seksi Gedung') {
dataGedung = data;
dataGedungLength = length!;
} else if (jabatan == 'Seksi Wisma') {
dataWisma = data;
dataWismaLength = length!;
} else if (jabatan == 'Kelompok Putra') {
dataKelompokPutra = data;
dataKelompokPutraLength = length!;
} else if (jabatan == 'Kelompok Putri') {
dataKelompokPutri = data;
dataKelompokPutriLength = length!;
}
} catch (e) {
log.e(e);
} finally {
notifyListeners();
setBusy(false);
easyLoading.dismissLoading();
}
}
void editData(String jabatan, bool bool) {
var res = dialogService.showCustomDialog(
@ -66,6 +160,9 @@ class StrukturOrganisasiViewModel extends CustomBaseViewModel {
},
);
res;
res.whenComplete(() async => {
// await Future.delayed(Duration(seconds: 1)),
init(),
});
}
}

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:panti_asuhan/app/themes/app_colors.dart';
import 'package:panti_asuhan/app/themes/app_text.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/themes/app_colors.dart';
import '../../../app/themes/app_text.dart';
import '../../widgets/my_button.dart';
import '../../widgets/my_textformfield.dart';
import './tambah_dana_sosial_view_model.dart';
class TambahDanaSosialView extends StatelessWidget {
@ -46,19 +46,66 @@ class TambahDanaSosialView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Bentuk Donasi",
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<String>(
value: model.bentukDonasi,
onChanged: (String? newValue) {
// model.setSelectedbentukDonasi(newValue!);
model.log.i(newValue);
model.bentukDonasi = newValue!;
model.notifyListeners();
},
items: model.bentukDonasiList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 20),
Visibility(
visible: model.bentukDonasi == 'Pemasukan',
child: Text(
"Nama Donator",
style: regularTextStyle.copyWith(color: mainColor),
),
MyTextFormField(
),
Visibility(
visible: model.bentukDonasi == 'Pemasukan',
child: MyTextFormField(
hintText: "Nama Donatur",
controller: model.namaController,
maxLines: 1,
validator: Validatorless.required(
'Nama Donatur tidak boleh kosong'),
// validator: Validatorless.required(
// 'Nama Donatur tidak boleh kosong'),
),
),
Visibility(
visible: model.bentukDonasi == 'Pemasukan',
child: const SizedBox(height: 20),
),
const SizedBox(height: 20),
Text(
"Jenis Donasi",
"Jenis Donasi / Pengeluaran",
style: regularTextStyle.copyWith(color: mainColor),
),
Container(

View File

@ -13,6 +13,9 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel {
final _httpService = locator<MyHttpServices>();
final easyLoading = locator<MyEasyLoading>();
String bentukDonasi = 'Pemasukan';
List<String> bentukDonasiList = ['Pemasukan', 'Pengeluaran'];
String jenisDonasi = 'Uang';
List<String> jenisDonasiList = ['Uang', 'Barang'];
@ -45,6 +48,7 @@ class TambahDanaSosialViewModel extends CustomBaseViewModel {
easyLoading.customLoading('Menambahkan data...');
try {
var formData = FormData.fromMap({
'bentuk': bentukDonasi,
'nama': namaController.text,
'jumlah': jumlahController.text,
'tanggal': tanggalController.text,