From 6af18dbe582895fc39b99d6633ae2daea525eb89 Mon Sep 17 00:00:00 2001 From: sindhu Date: Tue, 18 Feb 2025 05:46:59 +0700 Subject: [PATCH] step 15 : selected ke edit --- lib/app/route.dart | 13 + lib/main.dart | 2 +- lib/model/edit_person_model.dart | 45 ++ lib/model/person_ktp_model.dart | 14 +- lib/model/sex_model.dart | 31 ++ lib/provider/scan_provider.dart | 48 ++ lib/repository/scan_repository.dart | 20 + lib/screen/home/card_riwayat_scan.dart | 23 +- lib/screen/home/home_screen.dart | 6 +- .../home/list_riwayat_scan_provider.dart | 2 +- lib/screen/login/login_screen.dart | 2 +- lib/screen/scan/edit_scan_screen.dart | 476 ++++++++++++++++++ lib/screen/scan/scan_screen.dart | 2 +- lib/screen/scan/sex_provider.dart | 70 +++ lib/screen/scan/upload_scan_provider.dart | 2 +- test/widget_test.dart | 2 +- 16 files changed, 739 insertions(+), 19 deletions(-) create mode 100644 lib/model/edit_person_model.dart create mode 100644 lib/model/sex_model.dart create mode 100644 lib/provider/scan_provider.dart create mode 100644 lib/screen/scan/edit_scan_screen.dart create mode 100644 lib/screen/scan/sex_provider.dart diff --git a/lib/app/route.dart b/lib/app/route.dart index 9209499..e737074 100644 --- a/lib/app/route.dart +++ b/lib/app/route.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import '../screen/home/home_screen.dart'; import '../screen/login/login_screen.dart'; +import '../screen/scan/edit_scan_screen.dart'; import '../screen/scan/scan_screen.dart'; import '../screen/splash/splash_screen.dart'; @@ -9,6 +10,7 @@ const splashRoute = "/splashRoute"; const loginRoute = "/loginRoute"; const homeRoute = "/homeRoute"; const scanRoute = "/scanRoute"; +const editScanRoute = "/editScanRoute"; class AppRoute { static Route generateRoute(RouteSettings settings) { @@ -56,6 +58,17 @@ class AppRoute { }); } + // edit screen + if (settings.name == editScanRoute) { + return MaterialPageRoute(builder: (context) { + return MediaQuery( + data: MediaQuery.of(context).copyWith( + textScaler: TextScaler.linear(1.0), padding: EdgeInsets.all(0)), + child: EditScanScreen(), + ); + }); + } + return MaterialPageRoute(builder: (context) { return MediaQuery( data: MediaQuery.of(context).copyWith( diff --git a/lib/main.dart b/lib/main.dart index e8d7a6d..982d41f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,7 +2,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:scanktpflutter/app/route.dart'; +import '../../app/route.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); diff --git a/lib/model/edit_person_model.dart b/lib/model/edit_person_model.dart new file mode 100644 index 0000000..dd33db2 --- /dev/null +++ b/lib/model/edit_person_model.dart @@ -0,0 +1,45 @@ +class EditPersonModel { + final String personID; + final String personNIK; + final String personName; + final String personDob; + final String personSex; + final String personUrl; + final String m_sexname; + + EditPersonModel({ + required this.personID, + required this.personNIK, + required this.personName, + required this.personDob, + required this.personSex, + required this.personUrl, + required this.m_sexname, + }); + + // Convert JSON to Model + factory EditPersonModel.fromJson(Map json) { + return EditPersonModel( + personID: json['Person_ID'] ?? "", + personNIK: json['Person_NIK'] ?? "", + personName: json['Person_Name'] ?? "", + personDob: json['Person_Dob'] ?? DateTime.now(), + personSex: json['Person_Sex'] ?? "", + personUrl: json['Person_Url'] ?? "", + m_sexname: json['m_sexname'] ?? "", + ); + } + + // Convert Model to JSON + Map toJson() { + return { + 'Person_ID':personID, + 'Person_NIK': personNIK, + 'Person_Name': personName, + 'Person_Dob': personDob, + 'Person_Sex': personSex, + 'Person_Url': personUrl, + 'm_sexname':m_sexname, + }; + } +} diff --git a/lib/model/person_ktp_model.dart b/lib/model/person_ktp_model.dart index fa49aff..6594fb1 100644 --- a/lib/model/person_ktp_model.dart +++ b/lib/model/person_ktp_model.dart @@ -20,13 +20,13 @@ class PersonKtp { // Convert JSON to Model factory PersonKtp.fromJson(Map json) { return PersonKtp( - personID: json['Person_ID'], - personNIK: json['Person_NIK'], - personName: json['Person_Name'], - personDob: json['Person_Dob'], - personSex: json['Person_Sex'], - personUrl: json['Person_Url'], - m_sexname: json['m_sexname'], + personID: json['Person_ID'] ?? "", + personNIK: json['Person_NIK'] ?? "", + personName: json['Person_Name'] ?? "", + personDob: json['Person_Dob'] ?? DateTime.now(), + personSex: json['Person_Sex'] ?? "", + personUrl: json['Person_Url'] ?? "", + m_sexname: json['m_sexname'] ?? "", ); } diff --git a/lib/model/sex_model.dart b/lib/model/sex_model.dart new file mode 100644 index 0000000..28d41b9 --- /dev/null +++ b/lib/model/sex_model.dart @@ -0,0 +1,31 @@ +class SexModel { + final String M_SexID; + final String M_SexCode; + final String m_sexname; + final String M_SexNameLang; + + SexModel({ + required this.M_SexID, + required this.M_SexCode, + required this.m_sexname, + required this.M_SexNameLang, + }); + + factory SexModel.fromJson(Map json) { + return SexModel( + M_SexID: json['M_SexID'], + M_SexCode: json['M_SexCode'], + m_sexname: json['m_sexname'], + M_SexNameLang: json['M_SexNameLang'], + ); + } + + Map toJson() { + return { + 'M_SexID': M_SexID, + 'M_SexCode': M_SexCode, + 'm_sexname': m_sexname, + 'M_SexNameLang': M_SexNameLang, + }; + } +} diff --git a/lib/provider/scan_provider.dart b/lib/provider/scan_provider.dart new file mode 100644 index 0000000..15bce8a --- /dev/null +++ b/lib/provider/scan_provider.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:scanktpflutter/model/sex_model.dart'; + +import '../model/edit_person_model.dart'; + +final selectedPersonIdx = StateProvider((ref) => "0"); +final selectedEdit = StateProvider( + (ref) => EditPersonModel( + personID: "", + personNIK: "", + personName: "", + personDob: "", + personSex: "", + personUrl: "", + m_sexname: "", + ), +); + +// inputan edit +final eNikCtr = StateProvider( + (ref) => TextEditingController(text: ""), +); + +final eNamaCtr = StateProvider( + (ref) => TextEditingController(text: ""), +); + +final eDobCtr = StateProvider( + (ref) => TextEditingController(text: ""), +); + +final eDobDt = StateProvider( + (ref) => DateTime.now(), +); + +final eSexCtr = StateProvider( + (ref) => TextEditingController(text: ""), +); + +final eSexSelected = StateProvider( + (ref) => SexModel( + M_SexID: "", + M_SexCode: "", + m_sexname: "", + M_SexNameLang: "", + ), +); diff --git a/lib/repository/scan_repository.dart b/lib/repository/scan_repository.dart index b55b969..53b0c6b 100644 --- a/lib/repository/scan_repository.dart +++ b/lib/repository/scan_repository.dart @@ -1,4 +1,7 @@ +import '../../model/sex_model.dart'; + import '../model/person_ktp_model.dart'; +import '../model/edit_person_model.dart'; import 'base_repository.dart'; class ScanRepository extends BaseRepository { @@ -42,4 +45,21 @@ class ScanRepository extends BaseRepository { return resp['message']; } + + // sex + Future> sexRepo({ + required String host, + }) async { + // final service = "${Constant.baseUrl}xauth/login"; + final service = "http://${host}/one-api/scan-ktp/Scanktp/getSex"; + final resp = await post(param: {}, service: service); + + final result = List.empty(growable: true); + resp['data'].forEach((e) { + final model = SexModel.fromJson(e); + result.add(model); + }); + + return result; + } } diff --git a/lib/screen/home/card_riwayat_scan.dart b/lib/screen/home/card_riwayat_scan.dart index dbdae0e..da32852 100644 --- a/lib/screen/home/card_riwayat_scan.dart +++ b/lib/screen/home/card_riwayat_scan.dart @@ -1,10 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:scanktpflutter/app/app_extension.dart'; +import '../../app/app_extension.dart'; +import '../../app/route.dart'; import '../../app/constant.dart'; +import '../../model/edit_person_model.dart'; import '../../model/person_ktp_model.dart'; +import '../../provider/scan_provider.dart'; class CardRiwayatScan extends HookConsumerWidget { final PersonKtp data; @@ -42,8 +45,22 @@ class CardRiwayatScan extends HookConsumerWidget { ), ), InkWell( - onTap: (){ - print('id : ${data.personID}'); + onTap: () { + // print('id : ${data.personID}'); + ref.read(selectedPersonIdx.notifier).state = + data.personID; + ref.read(selectedEdit.notifier).state = EditPersonModel( + personID: data.personID, + personNIK: data.personNIK, + personName: data.personName, + m_sexname: data.m_sexname, + personDob: data.personDob, + personSex: data.personSex, + personUrl: data.personUrl, + ); + Navigator.of(context).pushNamed( + editScanRoute, + ); }, child: Icon( Icons.edit, diff --git a/lib/screen/home/home_screen.dart b/lib/screen/home/home_screen.dart index 5766cb9..8a076ec 100644 --- a/lib/screen/home/home_screen.dart +++ b/lib/screen/home/home_screen.dart @@ -2,9 +2,9 @@ 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/model/person_ktp_model.dart'; -import 'package:scanktpflutter/screen/home/card_riwayat_scan.dart'; -import 'package:scanktpflutter/screen/home/list_riwayat_scan_provider.dart'; +import '../../model/person_ktp_model.dart'; +import '../../screen/home/card_riwayat_scan.dart'; +import '../../screen/home/list_riwayat_scan_provider.dart'; import '../../app/constant.dart'; import '../../app/route.dart'; diff --git a/lib/screen/home/list_riwayat_scan_provider.dart b/lib/screen/home/list_riwayat_scan_provider.dart index 00d6f03..147c566 100644 --- a/lib/screen/home/list_riwayat_scan_provider.dart +++ b/lib/screen/home/list_riwayat_scan_provider.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:scanktpflutter/repository/scan_repository.dart'; +import '../../repository/scan_repository.dart'; import '../../model/person_ktp_model.dart'; import '../../provider/dio_provider.dart'; diff --git a/lib/screen/login/login_screen.dart b/lib/screen/login/login_screen.dart index 5435d8a..eb22ab6 100644 --- a/lib/screen/login/login_screen.dart +++ b/lib/screen/login/login_screen.dart @@ -2,7 +2,7 @@ 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/app/route.dart'; +import '../../app/route.dart'; import '../../app/constant.dart'; import '../../provider/current_user_provider.dart'; diff --git a/lib/screen/scan/edit_scan_screen.dart b/lib/screen/scan/edit_scan_screen.dart new file mode 100644 index 0000000..d03bfad --- /dev/null +++ b/lib/screen/scan/edit_scan_screen.dart @@ -0,0 +1,476 @@ +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 '../../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); + } + }); + + // 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); + // sex + ref.read(sexProvider.notifier).sex( + host: host, + ); + } + }); + return () {}; + }, [selectedPersonId]); + + // date picker + Future _selectDate(BuildContext context, WidgetRef ref) async { + DateTime? newSelectedDate = await showDatePicker( + context: context, + initialDate: (listDataEdit.personDob == "0000-00-00") + ? DateTime.parse(listDataEdit.personDob) + : DateTime.now(), + firstDate: DateTime(2000), + lastDate: DateTime(2100), + ); + + if (newSelectedDate != null) { + ref.read(eDobDt.notifier).state = newSelectedDate; + ref.read(eDobCtr.notifier).state.text = + formatDateJiffy(newSelectedDate.toLocal().toString()); + } + } + + 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), + 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: DropdownMenu( + initialSelection: + (listSex.value.isNotEmpty) ? listSex.value[0] : null, + controller: ref.read(eSexCtr), + width: Constant.getActualXPhone( + context: context, x: double.infinity), + // hintText: "Jenis Kelamin", + requestFocusOnTap: true, + enableFilter: true, + // label: const Text('Jenis Kelamin'), + onSelected: (SexModel? sex) { + if (sex != null) { + ref.read(eSexSelected.notifier).state = sex; + FocusScope.of(context).unfocus(); + } + }, + dropdownMenuEntries: listSex.value + .map>((SexModel sex) { + return DropdownMenuEntry( + value: sex, + label: sex.m_sexname, + ); + }).toList(), + inputDecorationTheme: InputDecorationTheme( + 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: 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 = { + "Person_ID":selectedPersonId, + "Person_Name":ref.read(eNamaCtr).text, + "Person_Dob":ref.read(eDobCtr).text, + "Person_Sex":ref.read(eSexSelected).M_SexID, + }; + + print(param); + + // Navigator.of(context).pushNamedAndRemoveUntil( + // homeRoute, + // (route) => false, + // ); + }, + 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: 20, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screen/scan/scan_screen.dart b/lib/screen/scan/scan_screen.dart index f56d271..5c2022b 100644 --- a/lib/screen/scan/scan_screen.dart +++ b/lib/screen/scan/scan_screen.dart @@ -6,7 +6,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:image/image.dart' as img; -import 'package:scanktpflutter/app/route.dart'; +import '../../app/route.dart'; import '../../app/constant.dart'; import '../../provider/current_user_provider.dart'; diff --git a/lib/screen/scan/sex_provider.dart b/lib/screen/scan/sex_provider.dart new file mode 100644 index 0000000..1c9eb43 --- /dev/null +++ b/lib/screen/scan/sex_provider.dart @@ -0,0 +1,70 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../model/sex_model.dart'; +import '../../repository/scan_repository.dart'; + +import '../../provider/dio_provider.dart'; +import '../../repository/base_repository.dart'; + +// 3. state provider +final sexProvider = + StateNotifierProvider( + (ref) => SexNotifier(ref: ref)); + +// 2. notifier +class SexNotifier extends StateNotifier { + final Ref ref; + SexNotifier({required this.ref}) + : super(SexStateInit()); + void sex({ + required String host, + }) async { + try { + state = SexStateLoading(); + final resp = await ScanRepository( + dio: ref.read(dioProvider), + ).sexRepo( + host: host + ); + + // print(resp); + state = SexStateDone(model: resp); + } catch (e) { + if (e is BaseRepositoryException) { + state = SexStateError(message: e.message); + } else { + state = SexStateError(message: e.toString()); + } + } + } +} + +// 1. state +abstract class SexState extends Equatable { + final DateTime date; + const SexState(this.date); + @override + List get props => [date]; +} + +class SexStateInit extends SexState { + SexStateInit() : super(DateTime.now()); +} + +class SexStateLoading extends SexState { + SexStateLoading() : super(DateTime.now()); +} + +class SexStateError extends SexState { + final String message; + SexStateError({ + required this.message, + }) : super(DateTime.now()); +} + +class SexStateDone extends SexState { + final List model; + SexStateDone({ + required this.model, + }) : super(DateTime.now()); +} diff --git a/lib/screen/scan/upload_scan_provider.dart b/lib/screen/scan/upload_scan_provider.dart index 71b8a91..2c28a60 100644 --- a/lib/screen/scan/upload_scan_provider.dart +++ b/lib/screen/scan/upload_scan_provider.dart @@ -1,6 +1,6 @@ import 'package:equatable/equatable.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:scanktpflutter/repository/scan_repository.dart'; +import '../../repository/scan_repository.dart'; import '../../provider/dio_provider.dart'; import '../../repository/base_repository.dart'; diff --git a/test/widget_test.dart b/test/widget_test.dart index f849283..5a228aa 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:scanktpflutter/main.dart'; +import '../../main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async {