step 15 : selected ke edit
This commit is contained in:
@@ -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<dynamic> 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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
45
lib/model/edit_person_model.dart
Normal file
45
lib/model/edit_person_model.dart
Normal file
@@ -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<String, dynamic> 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<String, dynamic> toJson() {
|
||||
return {
|
||||
'Person_ID':personID,
|
||||
'Person_NIK': personNIK,
|
||||
'Person_Name': personName,
|
||||
'Person_Dob': personDob,
|
||||
'Person_Sex': personSex,
|
||||
'Person_Url': personUrl,
|
||||
'm_sexname':m_sexname,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,13 @@ class PersonKtp {
|
||||
// Convert JSON to Model
|
||||
factory PersonKtp.fromJson(Map<String, dynamic> 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'] ?? "",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
31
lib/model/sex_model.dart
Normal file
31
lib/model/sex_model.dart
Normal file
@@ -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<String, dynamic> json) {
|
||||
return SexModel(
|
||||
M_SexID: json['M_SexID'],
|
||||
M_SexCode: json['M_SexCode'],
|
||||
m_sexname: json['m_sexname'],
|
||||
M_SexNameLang: json['M_SexNameLang'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'M_SexID': M_SexID,
|
||||
'M_SexCode': M_SexCode,
|
||||
'm_sexname': m_sexname,
|
||||
'M_SexNameLang': M_SexNameLang,
|
||||
};
|
||||
}
|
||||
}
|
||||
48
lib/provider/scan_provider.dart
Normal file
48
lib/provider/scan_provider.dart
Normal file
@@ -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<String>((ref) => "0");
|
||||
final selectedEdit = StateProvider<EditPersonModel>(
|
||||
(ref) => EditPersonModel(
|
||||
personID: "",
|
||||
personNIK: "",
|
||||
personName: "",
|
||||
personDob: "",
|
||||
personSex: "",
|
||||
personUrl: "",
|
||||
m_sexname: "",
|
||||
),
|
||||
);
|
||||
|
||||
// inputan edit
|
||||
final eNikCtr = StateProvider<TextEditingController>(
|
||||
(ref) => TextEditingController(text: ""),
|
||||
);
|
||||
|
||||
final eNamaCtr = StateProvider<TextEditingController>(
|
||||
(ref) => TextEditingController(text: ""),
|
||||
);
|
||||
|
||||
final eDobCtr = StateProvider<TextEditingController>(
|
||||
(ref) => TextEditingController(text: ""),
|
||||
);
|
||||
|
||||
final eDobDt = StateProvider<DateTime>(
|
||||
(ref) => DateTime.now(),
|
||||
);
|
||||
|
||||
final eSexCtr = StateProvider<TextEditingController>(
|
||||
(ref) => TextEditingController(text: ""),
|
||||
);
|
||||
|
||||
final eSexSelected = StateProvider<SexModel>(
|
||||
(ref) => SexModel(
|
||||
M_SexID: "",
|
||||
M_SexCode: "",
|
||||
m_sexname: "",
|
||||
M_SexNameLang: "",
|
||||
),
|
||||
);
|
||||
@@ -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<List<SexModel>> 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<SexModel>.empty(growable: true);
|
||||
resp['data'].forEach((e) {
|
||||
final model = SexModel.fromJson(e);
|
||||
result.add(model);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
476
lib/screen/scan/edit_scan_screen.dart
Normal file
476
lib/screen/scan/edit_scan_screen.dart
Normal file
@@ -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<bool>(false);
|
||||
|
||||
final listDataEdit = ref.watch(selectedEdit);
|
||||
|
||||
final listSex = useState<List<SexModel>>(
|
||||
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<void> _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<SexModel>(
|
||||
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<DropdownMenuEntry<SexModel>>((SexModel sex) {
|
||||
return DropdownMenuEntry<SexModel>(
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
70
lib/screen/scan/sex_provider.dart
Normal file
70
lib/screen/scan/sex_provider.dart
Normal file
@@ -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<SexNotifier, SexState>(
|
||||
(ref) => SexNotifier(ref: ref));
|
||||
|
||||
// 2. notifier
|
||||
class SexNotifier extends StateNotifier<SexState> {
|
||||
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<Object?> 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<SexModel> model;
|
||||
SexStateDone({
|
||||
required this.model,
|
||||
}) : super(DateTime.now());
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user