step 25 : upload ktp, qrcode string, edit data,
check token expired 10 menit dari expired_date
This commit is contained in:
715
lib/screen/no-login-scan/no_login_edit_scan_screen.dart
Normal file
715
lib/screen/no-login-scan/no_login_edit_scan_screen.dart
Normal file
@@ -0,0 +1,715 @@
|
||||
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/model/no-login/no_login_sex_model.dart';
|
||||
import 'package:scanktpflutter/provider/no-login-scan/no_login_scan_provider.dart';
|
||||
import 'package:scanktpflutter/screen/no-login-scan/no_login_edit_scan_provider.dart';
|
||||
import 'package:scanktpflutter/screen/scan/edit_scan_provider.dart';
|
||||
import '../../model/sex_model.dart';
|
||||
import '../../provider/no-login/no_login_current_user_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';
|
||||
import '../home/list_riwayat_scan_provider.dart';
|
||||
import '../no-login-home/no_login_riwayat_scan_provider.dart';
|
||||
import '../no-login/no_login_refresh_token_provider.dart';
|
||||
import 'no_login_sex_provider.dart';
|
||||
|
||||
class NoLoginEditScanScreen extends HookConsumerWidget {
|
||||
const NoLoginEditScanScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [
|
||||
SystemUiOverlay.bottom,
|
||||
]);
|
||||
|
||||
final currentUser = ref.watch(noLoginCurrentUserProvider);
|
||||
// final username = currentUser?.model.username ?? "-";
|
||||
final host = currentUser?.host ?? "";
|
||||
final isLoading = useState<bool>(false);
|
||||
final client_id = currentUser?.client_id ?? "";
|
||||
final token = currentUser?.token ?? "";
|
||||
final expire_date = currentUser?.expire_date ?? "";
|
||||
final readProsesAksi = ref.watch(noLoginprosesAksi);
|
||||
final baseUrl = "https://$host/";
|
||||
|
||||
final selectedPersonId = ref.watch(selectedPersonIdx);
|
||||
|
||||
final listDataEdit = ref.watch(selectedEdit);
|
||||
|
||||
final listSex = useState<List<NoLoginSexModel>>(
|
||||
List.empty(growable: true),
|
||||
);
|
||||
|
||||
useEffect(() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||
if (client_id == "0" || token == "") {
|
||||
// not logged in and doesn't have token
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(noLoginRoute, (route) => false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (token != "") {
|
||||
if (await isTokenExpired() == true) {
|
||||
print("Token expired, refreshing...");
|
||||
ref.read(noLoginRefreshTokenProvider.notifier).refreshToken(
|
||||
client_id: client_id,
|
||||
host: host,
|
||||
expire_date: expire_date,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
return () {};
|
||||
}, [currentUser]);
|
||||
|
||||
// sex
|
||||
ref.listen(noLoginSexProvider, (prev, next) {
|
||||
if (next is NoLoginSexStateLoading) {
|
||||
isLoading.value = true;
|
||||
} else if (next is NoLoginSexStateError) {
|
||||
isLoading.value = false;
|
||||
// errorMessage.value = next.message;
|
||||
snackbarWidget(
|
||||
context,
|
||||
next.message,
|
||||
snackbarType.error,
|
||||
Duration(seconds: 3),
|
||||
);
|
||||
} else if (next is NoLoginSexStateDone) {
|
||||
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(eQrCode.notifier).state =
|
||||
TextEditingController(text: listDataEdit.personQrCode);
|
||||
|
||||
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(noLoginSexProvider.notifier).sex(
|
||||
host: host,
|
||||
client_id: client_id,
|
||||
token: token,
|
||||
);
|
||||
}
|
||||
});
|
||||
return () {};
|
||||
}, [selectedPersonId]);
|
||||
|
||||
// date picker
|
||||
Future<void> _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());
|
||||
}
|
||||
}
|
||||
|
||||
// refreshToken Provider
|
||||
ref.listen(noLoginRefreshTokenProvider, (prev, next) async {
|
||||
if (next is NoLoginRefreshTokenStateLoading) {
|
||||
isLoading.value = true;
|
||||
} else if (next is NoLoginRefreshTokenStateError) {
|
||||
isLoading.value = false;
|
||||
// errorMessage.value = next.message;
|
||||
snackbarWidget(
|
||||
context,
|
||||
next.message,
|
||||
snackbarType.error,
|
||||
Duration(seconds: 3),
|
||||
);
|
||||
} else if (next is NoLoginRefreshTokenStateDone) {
|
||||
isLoading.value = false;
|
||||
|
||||
// check proses aksi yg berlangsung
|
||||
if (readProsesAksi == Constant.getRiwayat) {
|
||||
ref.read(noLoginRiwayatScanProvider.notifier).noLoginRiwayatScan(
|
||||
host: host,
|
||||
client_id: client_id,
|
||||
token: token,
|
||||
expire_date: expire_date,
|
||||
);
|
||||
} else if (readProsesAksi == Constant.postEditScan) {
|
||||
ref.read(noLoginEditScanProvider.notifier).editScan(
|
||||
token: token,
|
||||
host: host,
|
||||
client_id: client_id,
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// void getRiwayat
|
||||
void getRiwayat() async {
|
||||
if (await isTokenExpired() == true) {
|
||||
ref.read(noLoginprosesAksi.notifier).state = Constant.getRiwayat;
|
||||
print("Token expired, refreshing...");
|
||||
ref.read(noLoginRefreshTokenProvider.notifier).refreshToken(
|
||||
client_id: client_id,
|
||||
host: host,
|
||||
expire_date: expire_date,
|
||||
);
|
||||
} else {
|
||||
ref.read(noLoginRiwayatScanProvider.notifier).noLoginRiwayatScan(
|
||||
host: host,
|
||||
client_id: client_id,
|
||||
token: token,
|
||||
expire_date: expire_date,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// listRiwayProvider
|
||||
ref.listen(noLoginRiwayatScanProvider, (prev, next) async {
|
||||
if (next is NoLoginRiwayatScanStateLoading) {
|
||||
isLoading.value = true;
|
||||
} else if (next is NoLoginRiwayatScanStateError) {
|
||||
isLoading.value = false;
|
||||
// errorMessage.value = next.message;
|
||||
snackbarWidget(
|
||||
context,
|
||||
next.message,
|
||||
snackbarType.error,
|
||||
Duration(seconds: 3),
|
||||
);
|
||||
} else if (next is NoLoginRiwayatScanStateDone) {
|
||||
// isLoading.value = false;
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
noLoginHomeRoute,
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// proses edit
|
||||
ref.listen(noLoginEditScanProvider, (prev, next) {
|
||||
if (next is NoLoginEditScanStateLoading) {
|
||||
isLoading.value = true;
|
||||
} else if (next is NoLoginEditScanStateError) {
|
||||
isLoading.value = false;
|
||||
// errorMessage.value = next.message;
|
||||
snackbarWidget(
|
||||
context,
|
||||
next.message,
|
||||
snackbarType.error,
|
||||
Duration(seconds: 3),
|
||||
);
|
||||
} else if (next is NoLoginEditScanStateDone) {
|
||||
isLoading.value = false;
|
||||
getRiwayat();
|
||||
}
|
||||
});
|
||||
|
||||
void postEdit() async {
|
||||
if (await isTokenExpired() == true) {
|
||||
ref.read(noLoginprosesAksi.notifier).state = Constant.postEditScan;
|
||||
print("Token expired, refreshing...");
|
||||
ref.read(noLoginRefreshTokenProvider.notifier).refreshToken(
|
||||
client_id: client_id,
|
||||
host: host,
|
||||
expire_date: expire_date,
|
||||
);
|
||||
} else {
|
||||
ref.read(noLoginEditScanProvider.notifier).editScan(
|
||||
token: token,
|
||||
host: host,
|
||||
client_id: client_id,
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 qrcode
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: Constant.getActualYPhone(context: context, y: 12),
|
||||
right: Constant.getActualYPhone(context: context, y: 12),
|
||||
),
|
||||
child: Text(
|
||||
'QR Code',
|
||||
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,
|
||||
maxLines: 2,
|
||||
controller: ref.read(eQrCode),
|
||||
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 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<NoLoginSexModel>(
|
||||
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((NoLoginSexModel g) {
|
||||
return DropdownMenuItem<NoLoginSexModel>(
|
||||
value: g,
|
||||
child: Text(
|
||||
g.m_sexname,
|
||||
style: Constant.title_400(context: context).copyWith(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (NoLoginSexModel? 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: () {
|
||||
postEdit();
|
||||
},
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user