Feat: fix change data complete screen
This commit is contained in:
parent
59817eb99d
commit
ae09c5a89a
|
@ -163,6 +163,29 @@ class ProfilRepositoryImpl implements ProfilRepository {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updateUserData(UserData userData) async {
|
||||||
|
try {
|
||||||
|
if (userData.uid.isEmpty) {
|
||||||
|
throw Exception("User ID tidak boleh kosong");
|
||||||
|
}
|
||||||
|
|
||||||
|
await _firestore.collection('users').doc(userData.uid).update({
|
||||||
|
'name': userData.name,
|
||||||
|
'birth_date': userData.birthDate,
|
||||||
|
'gender': userData.gender,
|
||||||
|
'work': userData.work,
|
||||||
|
'city': userData.city,
|
||||||
|
'address': userData.address
|
||||||
|
});
|
||||||
|
|
||||||
|
log("Data pengguna berhasil diperbarui untuk ID: ${userData.uid}");
|
||||||
|
} catch (e) {
|
||||||
|
log("Error saat memperbarui data pengguna: $e");
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @override
|
// @override
|
||||||
// Future<void> changeEmail({
|
// Future<void> changeEmail({
|
||||||
// required String oldPassword,
|
// required String oldPassword,
|
||||||
|
|
|
@ -18,6 +18,7 @@ class ProfilBinding extends Bindings {
|
||||||
Get.lazyPut(() => ChangeNoIdUseCase(Get.find()));
|
Get.lazyPut(() => ChangeNoIdUseCase(Get.find()));
|
||||||
Get.lazyPut(() => DeletePassengerUseCase(Get.find()));
|
Get.lazyPut(() => DeletePassengerUseCase(Get.find()));
|
||||||
Get.lazyPut(() => UpdatePassengerUseCase(Get.find()));
|
Get.lazyPut(() => UpdatePassengerUseCase(Get.find()));
|
||||||
|
Get.lazyPut(() => UpdateUserDataUseCase(Get.find()));
|
||||||
// Get.lazyPut(() => ChangeEmailUseCase(Get.find()));
|
// Get.lazyPut(() => ChangeEmailUseCase(Get.find()));
|
||||||
|
|
||||||
Get.lazyPut(
|
Get.lazyPut(
|
||||||
|
@ -30,6 +31,7 @@ class ProfilBinding extends Bindings {
|
||||||
changeNoIdUseCase: Get.find(),
|
changeNoIdUseCase: Get.find(),
|
||||||
deletePassengerUseCase: Get.find(),
|
deletePassengerUseCase: Get.find(),
|
||||||
updatePassengerUseCase: Get.find(),
|
updatePassengerUseCase: Get.find(),
|
||||||
|
updateUserDataUseCase: Get.find(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ abstract class ProfilRepository {
|
||||||
required String oldPassword,
|
required String oldPassword,
|
||||||
required String newPassword,
|
required String newPassword,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> changePhone({
|
Future<void> changePhone({
|
||||||
required String oldPassword,
|
required String oldPassword,
|
||||||
required String newPhone,
|
required String newPhone,
|
||||||
|
@ -37,6 +37,8 @@ abstract class ProfilRepository {
|
||||||
required String noId,
|
required String noId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Future<void> updateUserData(UserData userData);
|
||||||
|
|
||||||
// Future<void> changeEmail({
|
// Future<void> changeEmail({
|
||||||
// required String oldPassword,
|
// required String oldPassword,
|
||||||
// required String newEmail,
|
// required String newEmail,
|
||||||
|
|
|
@ -127,3 +127,12 @@ class UpdatePassengerUseCase {
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
class UpdateUserDataUseCase {
|
||||||
|
final ProfilRepository profilRepository;
|
||||||
|
UpdateUserDataUseCase(this.profilRepository);
|
||||||
|
|
||||||
|
Future<void> call(UserData userData) {
|
||||||
|
return profilRepository.updateUserData(userData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ class ProfilController extends GetxController {
|
||||||
final ChangeNoIdUseCase changeNoIdUseCase;
|
final ChangeNoIdUseCase changeNoIdUseCase;
|
||||||
final DeletePassengerUseCase deletePassengerUseCase;
|
final DeletePassengerUseCase deletePassengerUseCase;
|
||||||
final UpdatePassengerUseCase updatePassengerUseCase;
|
final UpdatePassengerUseCase updatePassengerUseCase;
|
||||||
|
final UpdateUserDataUseCase updateUserDataUseCase;
|
||||||
// final ChangeEmailUseCase changeEmailUseCase;
|
// final ChangeEmailUseCase changeEmailUseCase;
|
||||||
|
|
||||||
var passengerList = <PassengerModel>[].obs;
|
var passengerList = <PassengerModel>[].obs;
|
||||||
|
@ -25,6 +26,7 @@ class ProfilController extends GetxController {
|
||||||
var isChangingNoId = false.obs;
|
var isChangingNoId = false.obs;
|
||||||
var isDeletingPassenger = false.obs;
|
var isDeletingPassenger = false.obs;
|
||||||
var isUpdatingPassenger = false.obs;
|
var isUpdatingPassenger = false.obs;
|
||||||
|
var isUpdatingUserData = false.obs;
|
||||||
// var isChangingEmail = false.obs;
|
// var isChangingEmail = false.obs;
|
||||||
|
|
||||||
ProfilController({
|
ProfilController({
|
||||||
|
@ -36,6 +38,7 @@ class ProfilController extends GetxController {
|
||||||
required this.changeNoIdUseCase,
|
required this.changeNoIdUseCase,
|
||||||
required this.deletePassengerUseCase,
|
required this.deletePassengerUseCase,
|
||||||
required this.updatePassengerUseCase,
|
required this.updatePassengerUseCase,
|
||||||
|
required this.updateUserDataUseCase,
|
||||||
// required this.changeEmailUseCase,
|
// required this.changeEmailUseCase,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -244,6 +247,47 @@ class ProfilController extends GetxController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> updateUserData({
|
||||||
|
required String name,
|
||||||
|
String? birthDate,
|
||||||
|
String? gender,
|
||||||
|
String? work,
|
||||||
|
String? city,
|
||||||
|
String? address,
|
||||||
|
}) async {
|
||||||
|
isUpdatingUserData.value = true;
|
||||||
|
try {
|
||||||
|
final currentUser = userData.value;
|
||||||
|
if (currentUser == null) {
|
||||||
|
throw Exception("Data pengguna tidak tersedia");
|
||||||
|
}
|
||||||
|
|
||||||
|
final updatedUserData = UserData(
|
||||||
|
uid: currentUser.uid,
|
||||||
|
email: currentUser.email,
|
||||||
|
name: name,
|
||||||
|
birthDate: birthDate,
|
||||||
|
gender: gender,
|
||||||
|
work: work,
|
||||||
|
city: city,
|
||||||
|
address: address,
|
||||||
|
phone: currentUser.phone,
|
||||||
|
role: currentUser.role,
|
||||||
|
noId: currentUser.noId,
|
||||||
|
tipeId: currentUser.tipeId,
|
||||||
|
);
|
||||||
|
await updateUserDataUseCase(updatedUserData);
|
||||||
|
await _loadProfile();
|
||||||
|
SnackbarHelper.showSuccess("Berhasil", "Anda telah berhasil memperbarui data diri");
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
SnackbarHelper.showError("Gagal", "Terjadi kesalahan: $e");
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
isUpdatingUserData.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Future<bool> changeEmail({
|
// Future<bool> changeEmail({
|
||||||
// required String oldPassword,
|
// required String oldPassword,
|
||||||
// required String newEmail,
|
// required String newEmail,
|
||||||
|
@ -279,40 +323,4 @@ class ProfilController extends GetxController {
|
||||||
// isChangingEmail.value = false;
|
// isChangingEmail.value = false;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Future<bool> changeEmail({
|
|
||||||
// required String oldPassword,
|
|
||||||
// required String newEmail,
|
|
||||||
// }) async {
|
|
||||||
// isChangingEmail.value = true;
|
|
||||||
// try {
|
|
||||||
// await changeEmailUseCase(oldPassword: oldPassword, newEmail: newEmail);
|
|
||||||
// SnackbarHelper.showSuccess("Link Terkirim", "Silakan cek email $newEmail untuk verifikasi.");
|
|
||||||
// return true;
|
|
||||||
// } on FirebaseAuthException catch (e) {
|
|
||||||
// switch (e.code) {
|
|
||||||
// case 'wrong-password':
|
|
||||||
// case 'invalid-credential':
|
|
||||||
// SnackbarHelper.showError("Gagal", "Password lama salah.");
|
|
||||||
// break;
|
|
||||||
// case 'email-already-in-use':
|
|
||||||
// SnackbarHelper.showError("Gagal", "Email baru sudah digunakan.");
|
|
||||||
// break;
|
|
||||||
// case 'unauthorized-domain':
|
|
||||||
// SnackbarHelper.showError(
|
|
||||||
// "Gagal",
|
|
||||||
// "Domain verifikasi belum diizinkan. "
|
|
||||||
// "Tambahkan \"eporter.page.link\" di Firebase Console → Authentication → Settings → Authorized domains.");
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// SnackbarHelper.showError("Gagal", e.message ?? e.code);
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// } catch (_) {
|
|
||||||
// SnackbarHelper.showError("Gagal", "Terjadi kesalahan.");
|
|
||||||
// return false;
|
|
||||||
// } finally {
|
|
||||||
// isChangingEmail.value = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,15 +59,15 @@ class _InputFormState extends State<InputForm> {
|
||||||
widget.inputFormatters ?? <TextInputFormatter>[FilteringTextInputFormatter.singleLineFormatter],
|
widget.inputFormatters ?? <TextInputFormatter>[FilteringTextInputFormatter.singleLineFormatter],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'DMSans',
|
fontFamily: 'DMSans',
|
||||||
fontSize: 14.sp,
|
fontSize: 16.sp,
|
||||||
fontWeight: (!widget.enabled && hasValidValue) ? FontWeight.w500 : FontWeight.w400,
|
fontWeight: (widget.enabled && hasValidValue) ? FontWeight.w500 : FontWeight.w500,
|
||||||
color: hasValidValue ? GrayColors.gray800 : GrayColors.gray500,
|
color: hasValidValue ? GrayColors.gray800 : GrayColors.gray800,
|
||||||
),
|
),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: widget.hintText,
|
hintText: widget.hintText,
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
fontFamily: 'DMSans',
|
fontFamily: 'DMSans',
|
||||||
fontSize: 14.sp,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: GrayColors.gray500,
|
color: GrayColors.gray500,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
|
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
|
||||||
import 'package:e_porter/_core/component/button/button_fill.dart';
|
import 'package:e_porter/_core/component/button/button_fill.dart';
|
||||||
import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart';
|
import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart';
|
||||||
|
@ -7,10 +6,14 @@ import 'package:e_porter/_core/component/text/custom_text.dart';
|
||||||
import 'package:e_porter/_core/component/text_field/dropdown/dropdown_component.dart';
|
import 'package:e_porter/_core/component/text_field/dropdown/dropdown_component.dart';
|
||||||
import 'package:e_porter/_core/constants/colors.dart';
|
import 'package:e_porter/_core/constants/colors.dart';
|
||||||
import 'package:e_porter/_core/utils/formatter/uppercase_helper.dart';
|
import 'package:e_porter/_core/utils/formatter/uppercase_helper.dart';
|
||||||
|
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
||||||
import 'package:e_porter/_core/validators/validators.dart';
|
import 'package:e_porter/_core/validators/validators.dart';
|
||||||
|
import 'package:e_porter/domain/models/user_entity.dart';
|
||||||
|
import 'package:e_porter/presentation/controllers/profil_controller.dart';
|
||||||
import 'package:e_porter/presentation/screens/auth/component/Input_form.dart';
|
import 'package:e_porter/presentation/screens/auth/component/Input_form.dart';
|
||||||
import 'package:e_porter/presentation/screens/profile/component/header_information.dart';
|
import 'package:e_porter/presentation/screens/profile/component/header_information.dart';
|
||||||
import 'package:e_porter/presentation/screens/profile/component/radio_button.dart';
|
import 'package:e_porter/presentation/screens/profile/component/radio_button.dart';
|
||||||
|
import 'package:e_porter/presentation/screens/routes/app_rountes.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
@ -27,10 +30,13 @@ class ChangeDataComplete extends StatefulWidget {
|
||||||
class _ChangeDataCompleteState extends State<ChangeDataComplete> {
|
class _ChangeDataCompleteState extends State<ChangeDataComplete> {
|
||||||
DateTime selectedDate = DateTime.now();
|
DateTime selectedDate = DateTime.now();
|
||||||
String selectedDateText = 'dd/mm/yyyy';
|
String selectedDateText = 'dd/mm/yyyy';
|
||||||
String? selectedTypeId;
|
String? selectedWork;
|
||||||
|
|
||||||
|
final _profileController = Get.find<ProfilController>();
|
||||||
final _nameController = TextEditingController();
|
final _nameController = TextEditingController();
|
||||||
final _dateController = TextEditingController();
|
final _dateController = TextEditingController();
|
||||||
|
final _cityController = TextEditingController();
|
||||||
|
final _addressController = TextEditingController();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final ValueNotifier<String> selectedGender = ValueNotifier<String>('Laki-laki');
|
final ValueNotifier<String> selectedGender = ValueNotifier<String>('Laki-laki');
|
||||||
|
|
||||||
|
@ -38,15 +44,84 @@ class _ChangeDataCompleteState extends State<ChangeDataComplete> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_dateController.text = 'dd/mm/yyyy';
|
_dateController.text = 'dd/mm/yyyy';
|
||||||
|
_initializeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_nameController.dispose();
|
_nameController.dispose();
|
||||||
_dateController.dispose();
|
_dateController.dispose();
|
||||||
|
_cityController.dispose();
|
||||||
|
_addressController.dispose();
|
||||||
|
selectedGender.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _initializeData() {
|
||||||
|
final userData = _profileController.userData.value;
|
||||||
|
if (userData != null) {
|
||||||
|
_nameController.text = userData.name ?? '';
|
||||||
|
|
||||||
|
if (userData.birthDate != null && userData.birthDate!.isNotEmpty) {
|
||||||
|
try {
|
||||||
|
selectedDate = DateFormat('dd MMMM yyyy', 'en_US').parse(userData.birthDate!);
|
||||||
|
_dateController.text = userData.birthDate!;
|
||||||
|
} catch (e) {
|
||||||
|
_dateController.text = 'dd/mm/yyyy';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_dateController.text = 'dd/mm/yyyy';
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedGender.value = userData.gender ?? 'Laki-laki';
|
||||||
|
selectedWork = userData.work;
|
||||||
|
_cityController.text = userData.city ?? '';
|
||||||
|
_addressController.text = userData.address ?? '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _handleSaveData() async {
|
||||||
|
if (!_formKey.currentState!.validate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final userData = _profileController.userData.value;
|
||||||
|
String formattedBirthDate = DateFormat('dd MMMM yyyy', 'en_US').format(selectedDate);
|
||||||
|
|
||||||
|
bool hasChanges = _hasDataChanged(userData, formattedBirthDate);
|
||||||
|
|
||||||
|
if (!hasChanges) {
|
||||||
|
SnackbarHelper.showInfo('Info', 'Tidak ada perubahan data yang perlu disimpan');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final success = await _profileController.updateUserData(
|
||||||
|
name: _nameController.text.trim(),
|
||||||
|
birthDate: _dateController.text,
|
||||||
|
gender: selectedGender.value,
|
||||||
|
work: selectedWork!,
|
||||||
|
city: _cityController.text.trim(),
|
||||||
|
address: _addressController.text.trim(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
Get.toNamed(Routes.INFORMATIONS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _hasDataChanged(UserData? userData, String formattedBirthDate) {
|
||||||
|
if (userData == null) return true;
|
||||||
|
|
||||||
|
bool nameChanged = (_nameController.text.trim()) != (userData.name ?? '');
|
||||||
|
bool birthDateChanged = formattedBirthDate != (userData.birthDate ?? '');
|
||||||
|
bool genderChanged = selectedGender.value != (userData.gender ?? 'Laki-laki');
|
||||||
|
bool workChanged = selectedWork != userData.work;
|
||||||
|
bool cityChanged = (_cityController.text.trim()) != (userData.city ?? '');
|
||||||
|
bool addressChanged = (_addressController.text.trim()) != (userData.address ?? '');
|
||||||
|
|
||||||
|
return nameChanged || birthDateChanged || genderChanged || workChanged || cityChanged || addressChanged;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -68,126 +143,140 @@ class _ChangeDataCompleteState extends State<ChangeDataComplete> {
|
||||||
title: 'Pastikan anda memasukkan informasi mengenai data diri anda dengan benar!',
|
title: 'Pastikan anda memasukkan informasi mengenai data diri anda dengan benar!',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CustomeShadowCotainner(
|
Expanded(
|
||||||
height: MediaQuery.of(context).size.height * 0.67,
|
child: CustomeShadowCotainner(
|
||||||
borderRadius: BorderRadius.circular(0),
|
height: MediaQuery.of(context).size.height * 0.67,
|
||||||
child: SingleChildScrollView(
|
borderRadius: BorderRadius.circular(0),
|
||||||
padding: EdgeInsets.only(bottom: 10.h),
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
padding: EdgeInsets.only(bottom: 10.h),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Form(
|
||||||
children: [
|
key: _formKey,
|
||||||
CustomText.textPadding8('Nama Lengkap'),
|
child: Column(
|
||||||
SizedBox(height: 16.h),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
InputForm(
|
|
||||||
controller: _nameController,
|
|
||||||
hintText: 'SUPARJO',
|
|
||||||
svgIconPath: 'assets/icons/ic_account.svg',
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
validator: Validators.validatorName,
|
|
||||||
inputFormatters: [
|
|
||||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z\s]')),
|
|
||||||
UpperCaseTextFormatter(),
|
|
||||||
],
|
|
||||||
textInputType: TextInputType.text,
|
|
||||||
),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
CustomText.textPadding8('Tanggal Lahir'),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
InputForm(
|
|
||||||
controller: _dateController,
|
|
||||||
hintText: 'dd/mm/yyyy',
|
|
||||||
svgIconPath: 'assets/icons/ic_account.svg',
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
enabled: false,
|
|
||||||
validator: Validators.validatorName,
|
|
||||||
textInputType: TextInputType.text,
|
|
||||||
onTap: () async {
|
|
||||||
final DateTime? picked = await showDatePicker(
|
|
||||||
context: context,
|
|
||||||
initialDate: selectedDate,
|
|
||||||
firstDate: DateTime(1950),
|
|
||||||
lastDate: DateTime.now(),
|
|
||||||
builder: (context, child) {
|
|
||||||
return Theme(
|
|
||||||
data: ThemeData.light().copyWith(
|
|
||||||
colorScheme: ColorScheme.light(
|
|
||||||
primary: PrimaryColors.primary800,
|
|
||||||
onPrimary: Colors.white,
|
|
||||||
surface: Colors.white,
|
|
||||||
),
|
|
||||||
dialogBackgroundColor: Colors.white,
|
|
||||||
),
|
|
||||||
child: child!,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (picked != null && picked != selectedDate) {
|
|
||||||
setState(() {
|
|
||||||
selectedDate = picked;
|
|
||||||
_dateController.text = DateFormat('dd MMMM yyyy', 'en_US').format(selectedDate);
|
|
||||||
log(selectedDate.toString());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
CustomText.textPadding8('Jenis Kelamin'),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
Row(
|
|
||||||
children: [
|
children: [
|
||||||
RadioButtonGender(value: 'Laki-laki', label: 'Laki-laki', selectedGender: selectedGender),
|
CustomText.textPadding8('Nama Lengkap'),
|
||||||
SizedBox(width: 40.h),
|
SizedBox(height: 16.h),
|
||||||
RadioButtonGender(value: 'Perempuan', label: 'Perempuan', selectedGender: selectedGender),
|
InputForm(
|
||||||
|
controller: _nameController,
|
||||||
|
hintText: 'SUPARJO',
|
||||||
|
svgIconPath: 'assets/icons/ic_account.svg',
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
validator: Validators.validatorName,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z\s]')),
|
||||||
|
UpperCaseTextFormatter(),
|
||||||
|
],
|
||||||
|
textInputType: TextInputType.text,
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.h),
|
||||||
|
CustomText.textPadding8('Tanggal Lahir'),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
InputForm(
|
||||||
|
controller: _dateController,
|
||||||
|
hintText: 'dd/mm/yyyy',
|
||||||
|
svgIconPath: 'assets/icons/ic_account.svg',
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
enabled: false,
|
||||||
|
validator: Validators.validatorName,
|
||||||
|
textInputType: TextInputType.text,
|
||||||
|
onTap: () async {
|
||||||
|
final DateTime? picked = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: selectedDate,
|
||||||
|
firstDate: DateTime(1950),
|
||||||
|
lastDate: DateTime.now(),
|
||||||
|
builder: (context, child) {
|
||||||
|
return Theme(
|
||||||
|
data: ThemeData.light().copyWith(
|
||||||
|
colorScheme: ColorScheme.light(
|
||||||
|
primary: PrimaryColors.primary800,
|
||||||
|
onPrimary: Colors.white,
|
||||||
|
surface: Colors.white,
|
||||||
|
),
|
||||||
|
dialogBackgroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
child: child!,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (picked != null && picked != selectedDate) {
|
||||||
|
setState(() {
|
||||||
|
selectedDate = picked;
|
||||||
|
_dateController.text = DateFormat('dd MMMM yyyy', 'en_US').format(selectedDate);
|
||||||
|
log(selectedDate.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.h),
|
||||||
|
CustomText.textPadding8('Jenis Kelamin'),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
RadioButtonGender(value: 'Laki-laki', label: 'Laki-laki', selectedGender: selectedGender),
|
||||||
|
SizedBox(width: 40.h),
|
||||||
|
RadioButtonGender(value: 'Perempuan', label: 'Perempuan', selectedGender: selectedGender),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.h),
|
||||||
|
CustomText.textPadding8('Pekerjaan'),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
DropdownComponent(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
hintText: "Pilih pekerjaan",
|
||||||
|
items: ['PELAJAR/MAHASISWA', 'KARYAWAN SWASTA', 'WIRASWASTA', 'PNS', 'TNI/POLRI'],
|
||||||
|
value: selectedWork,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
selectedWork = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.h),
|
||||||
|
CustomText.textPadding8('Kota / Kabupaten'),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
InputForm(
|
||||||
|
controller: _cityController,
|
||||||
|
hintText: 'Kota / Kabupaten',
|
||||||
|
svgIconPath: 'assets/icons/ic_account.svg',
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
validator: Validators.validatorName,
|
||||||
|
textInputType: TextInputType.text,
|
||||||
|
),
|
||||||
|
SizedBox(height: 20.h),
|
||||||
|
CustomText.textPadding8('Alamat'),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
InputForm(
|
||||||
|
controller: _addressController,
|
||||||
|
hintText: 'Jl. Contoh Alamat No. 123',
|
||||||
|
svgIconPath: 'assets/icons/ic_account.svg',
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
validator: Validators.validatorName,
|
||||||
|
textInputType: TextInputType.text,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 20.h),
|
),
|
||||||
CustomText.textPadding8('Pekerjaan'),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
DropdownComponent(
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
hintText: "Pilih pekerjaan",
|
|
||||||
items: ['PELAJAR/MAHASISWA', 'KARYAWAN SWASTA', 'WIRASWASTA', 'PNS', 'TNI/POLRI'],
|
|
||||||
value: selectedTypeId,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
selectedTypeId = value!;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
CustomText.textPadding8('Kota / Kabupaten'),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
InputForm(
|
|
||||||
hintText: 'Kota / Kabupaten',
|
|
||||||
svgIconPath: 'assets/icons/ic_account.svg',
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
validator: Validators.validatorName,
|
|
||||||
textInputType: TextInputType.text,
|
|
||||||
),
|
|
||||||
SizedBox(height: 20.h),
|
|
||||||
CustomText.textPadding8('Alamat'),
|
|
||||||
SizedBox(height: 16.h),
|
|
||||||
InputForm(
|
|
||||||
hintText: 'Jl. Contoh Alamat No. 123',
|
|
||||||
svgIconPath: 'assets/icons/ic_account.svg',
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
validator: Validators.validatorName,
|
|
||||||
textInputType: TextInputType.text,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
bottomNavigationBar: CustomeShadowCotainner(
|
bottomNavigationBar: Obx(
|
||||||
borderRadius: BorderRadius.circular(0),
|
() => CustomeShadowCotainner(
|
||||||
child: ButtonFill(
|
borderRadius: BorderRadius.circular(0),
|
||||||
text: 'Simpan',
|
child: ButtonFill(
|
||||||
textColor: Colors.white,
|
text: _profileController.isUpdatingUserData.value ? 'Menyimpan...' : 'Simpan',
|
||||||
onTap: () {},
|
textColor: Colors.white,
|
||||||
|
isLoading: _profileController.isUpdatingUserData.value,
|
||||||
|
onTap: _profileController.isUpdatingUserData.value
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
await _handleSaveData();
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -113,7 +113,7 @@ class _InformationUsersScreenState extends State<InformationUsersScreen> {
|
||||||
label: 'Nama Lengkap',
|
label: 'Nama Lengkap',
|
||||||
value: userData.name ?? '-',
|
value: userData.name ?? '-',
|
||||||
isDivider: false,
|
isDivider: false,
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
Get.toNamed(Routes.CHANGEDATACOMPLETE);
|
Get.toNamed(Routes.CHANGEDATACOMPLETE);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue