Feat: add slicing change Nomor ID screen

This commit is contained in:
orangdeso 2025-05-25 23:43:14 +07:00
parent 74a09d4d3a
commit b0eb48cbfe
6 changed files with 218 additions and 43 deletions

View File

@ -11,6 +11,7 @@ class InputPassword extends StatefulWidget {
final TextEditingController? controller;
final String? Function(String?)? validator;
final bool obscureText;
final Color? backgroundColor;
const InputPassword({
Key? key,
@ -19,6 +20,7 @@ class InputPassword extends StatefulWidget {
this.controller,
this.validator,
this.obscureText = true,
this.backgroundColor = GrayColors.gray50,
}) : super(key: key);
@override
@ -38,7 +40,7 @@ class _InputPasswordState extends State<InputPassword> {
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: GrayColors.gray50,
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(10.r),
),
child: TextFormField(

View File

@ -0,0 +1,40 @@
import 'package:e_porter/_core/constants/colors.dart';
import 'package:e_porter/_core/constants/typography.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class RadioButtonGender extends StatelessWidget {
final String value;
final String label;
final ValueNotifier<String> selectedGender;
RadioButtonGender({
Key? key,
required this.value,
required this.label,
required this.selectedGender,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<String>(
valueListenable: selectedGender,
builder: (context, selected, child) {
return Row(
children: [
Radio<String>(
value: value,
groupValue: selected,
activeColor: PrimaryColors.primary800,
onChanged: (val) {
selectedGender.value = val!;
},
),
SizedBox(width: 10.w),
TypographyStyles.body(label, color: GrayColors.gray800, fontWeight: FontWeight.w500)
],
);
},
);
}
}

View File

@ -8,6 +8,7 @@ import 'package:e_porter/_core/constants/typography.dart';
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
import 'package:e_porter/_core/validators/validators.dart';
import 'package:e_porter/presentation/controllers/profil_controller.dart';
import 'package:e_porter/presentation/screens/profile/component/radio_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -121,9 +122,9 @@ class _AddPassengerScreenState extends State<AddPassengerScreen> {
TypographyStyles.body('Jenis Kelamin', color: GrayColors.gray600, fontWeight: FontWeight.w400),
Row(
children: [
_buildRadioButton(context, label: 'Laki-laki', value: 'Laki-laki'),
RadioButtonGender(value: 'Laki-laki', label: 'Laki-laki', selectedGender: selectedGender),
SizedBox(width: 40.h),
_buildRadioButton(context, label: 'Perempuan', value: 'Perempuan')
RadioButtonGender(value: 'Perempuan', label: 'Perempuan', selectedGender: selectedGender),
],
)
],
@ -148,32 +149,6 @@ class _AddPassengerScreenState extends State<AddPassengerScreen> {
);
}
Widget _buildRadioButton(
BuildContext context, {
required String label,
required String value,
}) {
return ValueListenableBuilder<String>(
valueListenable: selectedGender,
builder: (context, selected, child) {
return Row(
children: [
Radio<String>(
value: value,
groupValue: selected,
activeColor: PrimaryColors.primary800,
onChanged: (val) {
selectedGender.value = val!;
},
),
SizedBox(width: 10.w),
TypographyStyles.body(label, color: GrayColors.gray800, fontWeight: FontWeight.w500)
],
);
},
);
}
Future<void> _onSavePassenger() async {
final name = _nameController.text.trim();
final noId = _noIdController.text.trim();

View File

@ -0,0 +1,139 @@
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
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/text_input/text_field_component.dart';
import 'package:e_porter/_core/constants/colors.dart';
import 'package:e_porter/_core/constants/typography.dart';
import 'package:e_porter/_core/validators/validators.dart';
import 'package:e_porter/presentation/screens/auth/component/Input_password.dart';
import 'package:e_porter/presentation/screens/profile/component/header_information.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class ChangeNoId extends StatefulWidget {
const ChangeNoId({super.key});
@override
State<ChangeNoId> createState() => _ChangeNoIdState();
}
class _ChangeNoIdState extends State<ChangeNoId> {
final _formKey = GlobalKey<FormState>();
final _oldPassword = TextEditingController();
final _noIdController = TextEditingController();
String selectedTypeId = 'KTP';
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: DefaultAppbarComponent(
title: 'Ganti Nomor ID',
textColor: Colors.white,
backgroundColors: PrimaryColors.primary800,
onTab: () {
Get.back();
},
),
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HeaderInformation(
title:
'Apakah anda yakin ingin mengganti Nomor ID akun anda?. Silahkan masukkan password lama anda sebagai verifikasi dan Type Nomor ID baru anda',
),
SizedBox(height: 32.h),
CustomText.textPadding8('Password Lama'),
SizedBox(height: 16.h),
InputPassword(
controller: _oldPassword,
hintText: '••••••••••',
svgIconPath: 'assets/icons/ic_padlock.svg',
backgroundColor: Colors.white,
validator: Validators.validatorPassword,
),
SizedBox(height: 20.h),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TypographyStyles.body('Tipe ID', color: GrayColors.gray600, fontWeight: FontWeight.w400),
SizedBox(height: 16.h),
DropdownComponent(
hintText: "Pilih jenis dokument",
items: ['KTP', 'Pasport'],
value: selectedTypeId,
onChanged: (value) {
setState(() {
selectedTypeId = value!;
});
},
),
],
),
SizedBox(width: 16.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TypographyStyles.body('No ID', color: GrayColors.gray600, fontWeight: FontWeight.w400),
SizedBox(height: 16.h),
TextFieldComponent(
controller: _noIdController,
hintText: 'Masukkan ID',
validators: Validators.validatorNoID,
textInputType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(16),
],
)
],
),
)
],
),
],
),
),
),
),
),
// bottomNavigationBar: Obx(
// () {
// return CustomeShadowCotainner(
// child: _authController.isChangingPhone.value
// ? Center(
// child: CircularProgressIndicator(color: PrimaryColors.primary800),
// )
// : ButtonFill(
// text: 'Simpan',
// textColor: Colors.white,
// onTap: () async {
// if (!_formKey.currentState!.validate()) return;
// final result = await _authController.changePhone(
// oldPassword: _oldPassword.text.trim(),
// newPhone: _phoneNumber.text.trim(),
// );
// if (result) {
// _oldPassword.clear();
// _phoneNumber.clear();
// }
// },
// ),
// );
// },
// ),
);
}
}

View File

@ -88,7 +88,14 @@ class _InformationUsersScreenState extends State<InformationUsersScreen> {
),
SizedBox(height: 24.h),
itemDoubleWithButton(
label1: 'Tipe ID', value1: userData.tipeId ?? '-', label2: 'No ID', value2: userData.noId ?? '-'),
label1: 'Tipe ID',
value1: userData.tipeId ?? '-',
label2: 'No ID',
value2: userData.noId ?? '-',
onTap: () {
Get.toNamed(Routes.CHANGENOID);
},
),
],
),
),
@ -194,6 +201,7 @@ class _InformationUsersScreenState extends State<InformationUsersScreen> {
required String label2,
required String value1,
required String value2,
required VoidCallback onTap,
}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -206,20 +214,25 @@ class _InformationUsersScreenState extends State<InformationUsersScreen> {
infoDoubleItem(label: label2, value: value2)
],
),
Container(
padding: EdgeInsets.symmetric(vertical: 6.h, horizontal: 10.w),
decoration: BoxDecoration(
color: PrimaryColors.primary100,
borderRadius: BorderRadius.circular(10.r),
),
child: Row(
children: [
Icon(Icons.edit, color: PrimaryColors.primary800, size: 14.sp),
Padding(
padding: EdgeInsets.only(left: 8.w),
child: TypographyStyles.small('Ubah', color: PrimaryColors.primary800),
ZoomTapAnimation(
child: InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.symmetric(vertical: 6.h, horizontal: 10.w),
decoration: BoxDecoration(
color: PrimaryColors.primary100,
borderRadius: BorderRadius.circular(10.r),
),
],
child: Row(
children: [
Icon(Icons.edit, color: PrimaryColors.primary800, size: 14.sp),
Padding(
padding: EdgeInsets.only(left: 8.w),
child: TypographyStyles.small('Ubah', color: PrimaryColors.primary800),
),
],
),
),
),
)
],

View File

@ -35,6 +35,7 @@ import 'package:e_porter/presentation/screens/home/pages/ticket_booking_step4_sc
import 'package:e_porter/presentation/screens/home/pages/upload_file_screen.dart';
import 'package:e_porter/presentation/screens/navigation/main_navigation.dart';
import 'package:e_porter/presentation/screens/onboarding/onboarding_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/change/change_no_id.dart';
import 'package:e_porter/presentation/screens/profile/pages/change_email_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/change_number_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/change_password_screen.dart';
@ -215,6 +216,10 @@ class AppRoutes {
name: Routes.CHANGENUMBER,
page: () => ChangeNumberScreen(),
),
GetPage(
name: Routes.CHANGENOID,
page: () => ChangeNoId(),
),
GetPage(
name: Routes.CHANGEEMAIL,
page: () => ChangeEmailScreen(),
@ -271,6 +276,7 @@ class Routes {
static const INFORMATIONS = '/informations';
static const CHANGEPASSWORD = '/change_password';
static const CHANGENUMBER = '/change_number';
static const CHANGENOID = '/change_no_id';
static const CHANGEEMAIL = '/change_email';
static const PASSENGERLIST = '/passenger_list';
}