import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:scanktpflutter/screen/scan/edit_scan_provider.dart'; import '../../model/sex_model.dart'; import '../../screen/scan/sex_provider.dart'; import '../../provider/scan_provider.dart'; import '../../widget/customsnackbarwidget.dart'; import '../../app/app_extension.dart'; import '../../app/constant.dart'; import '../../app/route.dart'; import '../../provider/current_user_provider.dart'; class EditScanScreen extends HookConsumerWidget { const EditScanScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [ SystemUiOverlay.bottom, ]); final currentUser = ref.watch(currentUserProvider); final host = currentUser?.host ?? ""; final userId = currentUser?.model.userId ?? ""; final baseUrl = "https://$host/"; final selectedPersonId = ref.watch(selectedPersonIdx); final isLoading = useState(false); final listDataEdit = ref.watch(selectedEdit); final listSex = useState>( List.empty(growable: true), ); useEffect(() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { final userID = currentUser?.model.userId ?? "0"; if (userID == "0") { // not logged in Navigator.of(context) .pushNamedAndRemoveUntil(loginRoute, (route) => false); return; } }); return () {}; }, [currentUser]); // sex ref.listen(sexProvider, (prev, next) { if (next is SexStateLoading) { isLoading.value = true; } else if (next is SexStateError) { isLoading.value = false; // errorMessage.value = next.message; snackbarWidget( context, next.message, snackbarType.error, Duration(seconds: 3), ); } else if (next is SexStateDone) { isLoading.value = false; listSex.value = next.model; // ref.read(eSexCtr.notifier).state = // TextEditingController(text: next.model[0].m_sexname); final sexSel = ref.read(selectedEdit.notifier).state; if (next.model.isNotEmpty) { final matchedItems = next.model .where((item) => item.M_SexID == sexSel.personSex) .toList(); if (matchedItems.length == 1) { ref.read(eSexCtr.notifier).state = TextEditingController( text: matchedItems[0].m_sexname, ); } else { // Jika lebih dari satu atau tidak ada yang cocok print('Error: Multiple or no matching items found.'); // Bisa juga mengatur default value jika tidak ditemukan ref.read(eSexCtr.notifier).state = TextEditingController(text: ''); // atau nilai default lain } } } }); // isLoading useEffect(() { WidgetsBinding.instance.addPostFrameCallback((timestamp) async { if (isLoading.value == true) { snackbarWidget( context, "Sedang Memuat Data", snackbarType.warning, Duration(days: 1), ); } }); return () {}; }, [isLoading]); // check person id useEffect(() { WidgetsBinding.instance.addPostFrameCallback((timestamp) async { final personIDx = selectedPersonId; if (personIDx == "0") { snackbarWidget( context, 'Gagal mendapatkan data', snackbarType.error, Duration(seconds: 3), ); Navigator.of(context) .pushNamedAndRemoveUntil(homeRoute, (route) => false); return; } else { // listDataEdit // set ke inputan ref.read(eNikCtr.notifier).state = TextEditingController(text: listDataEdit.personNIK); ref.read(eNamaCtr.notifier).state = TextEditingController(text: listDataEdit.personName); ref.read(eDobCtr.notifier).state = TextEditingController( text: formatDateJiffy(listDataEdit.personDob)); ref.read(eDobDt.notifier).state = DateTime.parse(listDataEdit.personDob); final parsedDate = DateTime.parse(listDataEdit.personDob); // print("Parsed Date: $parsedDate"); ref.read(eDobDt.notifier).state = parsedDate; // sex ref.read(sexProvider.notifier).sex( host: host, ); } }); return () {}; }, [selectedPersonId]); // date picker Future _selectDate(BuildContext context, WidgetRef ref) async { DateTime? newSelectedDate = await showDatePicker( initialEntryMode: DatePickerEntryMode.calendarOnly, context: context, initialDate: (listDataEdit.personDob != "0000-00-00") ? DateTime.parse(listDataEdit.personDob) : DateTime.now(), firstDate: DateTime(1900), lastDate: DateTime(2100), ); if (newSelectedDate != null) { ref.read(eDobDt.notifier).state = newSelectedDate; ref.read(eDobCtr.notifier).state.text = formatDateJiffy(newSelectedDate.toLocal().toString()); } } // proses edit ref.listen(editScanProvider, (prev, next) { if (next is EditScanStateLoading) { isLoading.value = true; } else if (next is EditScanStateError) { isLoading.value = false; // errorMessage.value = next.message; snackbarWidget( context, next.message, snackbarType.error, Duration(seconds: 3), ); } else if (next is EditScanStateDone) { isLoading.value = false; snackbarWidget( context, next.pesan, snackbarType.success, Duration(seconds: 3), ); Navigator.of(context).pushNamedAndRemoveUntil( homeRoute, (route) => false, ); return; } }); return GestureDetector( onTap: () { FocusManager.instance.primaryFocus!.unfocus(); }, child: Scaffold( resizeToAvoidBottomInset: true, backgroundColor: Constant.bgGrey, body: ListView( // crossAxisAlignment: CrossAxisAlignment.start, children: [ // atas Image.asset( 'images/vektoratas.png', width: double.infinity, fit: BoxFit.cover, ), SizedBox( height: Constant.getActualYPhone( context: context, y: 34, ), ), // image ktp Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: Image.network( baseUrl + listDataEdit.personUrl, fit: BoxFit.fitWidth, ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 32, ), ), // inputan nik Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: Text( 'NIK', style: Constant.title_400(context: context).copyWith( color: Constant.inputanGrey, ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: TextField( controller: ref.read(eNikCtr), keyboardType: TextInputType.number, decoration: InputDecoration( // hintText: "NIK", enabledBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.grey, width: 1, ), ), focusedBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.blue, width: 2, ), ), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), // inputan nama Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: Text( 'Nama', style: Constant.title_400(context: context).copyWith( color: Constant.inputanGrey, ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: TextField( controller: ref.read(eNamaCtr), decoration: InputDecoration( // hintText: "NIK", enabledBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.grey, width: 1, ), ), focusedBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.blue, width: 2, ), ), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), // inputan dob Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: Text( 'DOB', style: Constant.title_400(context: context).copyWith( color: Constant.inputanGrey, ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: TextField( readOnly: true, controller: ref.read(eDobCtr), onTap: () { _selectDate(context, ref); }, decoration: InputDecoration( // hintText: "NIK", suffixIcon: IconButton( icon: Icon(Icons.calendar_today, color: Constant.textCardGrey), onPressed: () { _selectDate(context, ref); }, ), enabledBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.grey, width: 1, ), ), focusedBorder: const OutlineInputBorder( borderSide: BorderSide( color: Colors.blue, width: 2, ), ), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), // inputan jenis kelamin Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: Text( 'Jenis Kelamin', style: Constant.title_400(context: context).copyWith( color: Constant.inputanGrey, ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 16, ), ), Padding( padding: EdgeInsets.only( left: Constant.getActualYPhone(context: context, y: 12), right: Constant.getActualYPhone(context: context, y: 12), ), child: DropdownButtonHideUnderline( child: DropdownButton2( isExpanded: true, value: (listSex.value.isNotEmpty) ? listSex.value.firstWhere( (sex) => sex.M_SexID == ref.read(eSexSelected.notifier).state.M_SexID, orElse: () => listSex.value[0], ) : null, items: listSex.value.map((SexModel g) { return DropdownMenuItem( value: g, child: Text( g.m_sexname, style: Constant.title_400(context: context).copyWith( color: Colors.black, fontWeight: FontWeight.normal, ), ), ); }).toList(), onChanged: (SexModel? value) { if (value != null) { ref.read(eSexSelected.notifier).state = value; ref.read(eSexCtr.notifier).state = TextEditingController( text: value.m_sexname, ); FocusScope.of(context).unfocus(); } }, buttonStyleData: ButtonStyleData( decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey), ), padding: EdgeInsets.symmetric(horizontal: 12), width: double.infinity, ), dropdownStyleData: DropdownStyleData( maxHeight: 100, width: MediaQuery.of(context).size.width - 20, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: Colors.white, ), offset: Offset(0, 2), ), menuItemStyleData: MenuItemStyleData( padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), ), onMenuStateChange: (isOpen) { if (!isOpen) { ref.read(eSexCtr).clear(); } }, ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 44, ), ), // button save Padding( padding: EdgeInsets.only( left: Constant.getActualXPhone( context: context, x: 16, ), right: Constant.getActualXPhone( context: context, x: 16, ), ), child: SizedBox( width: double.infinity, height: Constant.getActualYPhone( context: context, y: 48, ), child: ElevatedButton( onPressed: () { var param = { "userId": userId, "Person_ID": selectedPersonId, "Person_NIK": ref.read(eNikCtr).text, "Person_Name": ref.read(eNamaCtr).text, "Person_Dob": ref.read(eDobCtr).text, "Person_Sex": ref.read(eSexSelected).M_SexID, }; print(param); ref.read(editScanProvider.notifier).editScan( host: host, userId: userId, Person_ID: selectedPersonId, Person_NIK: ref.read(eNikCtr).text, Person_Name: ref.read(eNamaCtr).text, Person_Dob: ref.read(eDobCtr).text, Person_Sex: ref.read(eSexSelected).M_SexID, ); }, style: ElevatedButton.styleFrom( backgroundColor: Constant.bgButton, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 8, shadowColor: Constant.bgButton.withOpacity(0.24), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'SAVE', style: Constant.titleButton500(context: context).copyWith( color: Constant.textWhite, ), ), ], ), ), ), ), SizedBox( height: Constant.getActualYPhone( context: context, y: 70, ), ), ], ), ), ); } }