Feat: done slicing informatation data users

This commit is contained in:
orangdeso 2025-05-26 17:38:14 +07:00
parent a44530f51d
commit f6fdc1f77d
9 changed files with 283 additions and 53 deletions

View File

@ -8,6 +8,7 @@ class DropdownComponent extends StatefulWidget {
final String? value;
final Function(String?) onChanged;
final String hintText;
final double? width;
const DropdownComponent({
Key? key,
@ -15,6 +16,7 @@ class DropdownComponent extends StatefulWidget {
this.value,
required this.onChanged,
required this.hintText,
this.width,
}) : super(key: key);
@override
@ -28,13 +30,18 @@ class _DropdownComponentState extends State<DropdownComponent> {
@override
void initState() {
super.initState();
selectedValue = widget.value;
// selectedValue = widget.value;
if (widget.value != null && widget.items.contains(widget.value)) {
selectedValue = widget.value;
} else {
selectedValue = null;
}
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.height * 0.14,
width: widget.width ?? MediaQuery.of(context).size.height * 0.14,
child: DropdownButtonHideUnderline(
child: DropdownButton2<String>(
isExpanded: true,
@ -57,9 +64,9 @@ class _DropdownComponentState extends State<DropdownComponent> {
widget.hintText,
style: TextStyle(
fontFamily: 'DMsans',
fontSize: 16.sp,
color: GrayColors.gray600,
fontWeight: FontWeight.w500,
fontSize: 14.sp,
color: GrayColors.gray500,
fontWeight: FontWeight.w400,
),
),
onMenuStateChange: (isOpen) {
@ -77,9 +84,7 @@ class _DropdownComponentState extends State<DropdownComponent> {
padding: EdgeInsets.only(left: 10.w, right: 16.w, top: 4.h, bottom: 4.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.r),
border: Border.all(
width: 1.w,
color: _isMenuOpen ? PrimaryColors.primary800 : GrayColors.gray200),
border: Border.all(width: 1.w, color: _isMenuOpen ? PrimaryColors.primary800 : GrayColors.gray200),
color: Colors.white,
),
),

View File

@ -13,6 +13,10 @@ class InputForm extends StatefulWidget {
final String? Function(String?)? validator;
final TextInputType textInputType;
final List<TextInputFormatter>? inputFormatters;
final Widget? suffixIcon;
final bool enabled;
final VoidCallback? onTap;
final Color? backgroundColor;
const InputForm({
Key? key,
@ -22,6 +26,10 @@ class InputForm extends StatefulWidget {
this.validator,
this.textInputType = TextInputType.text,
this.inputFormatters,
this.suffixIcon,
this.enabled = true,
this.onTap,
this.backgroundColor = GrayColors.gray50,
}) : super(key: key);
@override
@ -31,51 +39,68 @@ class InputForm extends StatefulWidget {
class _InputFormState extends State<InputForm> {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: GrayColors.gray50,
borderRadius: BorderRadius.circular(10.r),
),
child: TextFormField(
controller: widget.controller,
validator: widget.validator,
keyboardType: widget.textInputType,
inputFormatters:
widget.inputFormatters ?? <TextInputFormatter>[FilteringTextInputFormatter.singleLineFormatter],
decoration: InputDecoration(
hintText: widget.hintText,
hintStyle: TextStyle(
bool hasValidValue = widget.controller?.text.isNotEmpty == true &&
widget.controller?.text != 'dd/mm/yyyy' &&
widget.controller?.text != widget.hintText;
return GestureDetector(
onTap: widget.onTap,
child: Container(
decoration: BoxDecoration(
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(10.r),
),
child: TextFormField(
controller: widget.controller,
validator: widget.validator,
enabled: widget.enabled,
keyboardType: widget.textInputType,
inputFormatters:
widget.inputFormatters ?? <TextInputFormatter>[FilteringTextInputFormatter.singleLineFormatter],
style: TextStyle(
fontFamily: 'DMSans',
fontSize: 14.sp,
fontWeight: FontWeight.w400,
color: GrayColors.gray600,
fontWeight: (!widget.enabled && hasValidValue) ? FontWeight.w500 : FontWeight.w400,
color: hasValidValue ? GrayColors.gray800 : GrayColors.gray500,
),
prefixIcon: Padding(
padding: EdgeInsets.symmetric(vertical: 14.h, horizontal: 14.w),
child: SvgPicture.asset(
widget.svgIconPath,
decoration: InputDecoration(
hintText: widget.hintText,
hintStyle: TextStyle(
fontFamily: 'DMSans',
fontSize: 14.sp,
fontWeight: FontWeight.w400,
color: GrayColors.gray500,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.r),
borderSide: BorderSide(
width: 1.w,
color: GrayColors.gray200,
prefixIcon: Padding(
padding: EdgeInsets.symmetric(vertical: 14.h, horizontal: 14.w),
child: SvgPicture.asset(
widget.svgIconPath,
color: GrayColors.gray500,
),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.r),
borderSide: BorderSide(
width: 2.w,
color: PrimaryColors.primary800,
suffixIcon: widget.suffixIcon != null
? Padding(padding: EdgeInsets.symmetric(vertical: 14.h, horizontal: 14.w), child: widget.suffixIcon)
: null,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.r),
borderSide: BorderSide(
width: 1.w,
color: GrayColors.gray200,
),
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.r),
borderSide: BorderSide(
width: 1.w,
color: GrayColors.gray200,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.r),
borderSide: BorderSide(
width: 2.w,
color: PrimaryColors.primary800,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.r),
borderSide: BorderSide(
width: 1.w,
color: GrayColors.gray200,
),
),
),
),

View File

@ -19,8 +19,6 @@ import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:zoom_tap_animation/zoom_tap_animation.dart';
import '../../../../_core/service/logger_service.dart';
class BookingTickets extends StatefulWidget {
const BookingTickets({super.key});
@ -121,7 +119,6 @@ class _BookingTicketsState extends State<BookingTickets> {
setState(() {
selectedDate = picked;
selectedDateText = DateFormat('EEE, d MMM yyyy', 'en_US').format(selectedDate);
logger.d(selectedDate);
});
}
},

View File

@ -0,0 +1,195 @@
import 'dart:developer';
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/card/custome_shadow_cotainner.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/constants/colors.dart';
import 'package:e_porter/_core/utils/formatter/uppercase_helper.dart';
import 'package:e_porter/_core/validators/validators.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/radio_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
class ChangeDataComplete extends StatefulWidget {
const ChangeDataComplete({super.key});
@override
State<ChangeDataComplete> createState() => _ChangeDataCompleteState();
}
class _ChangeDataCompleteState extends State<ChangeDataComplete> {
DateTime selectedDate = DateTime.now();
String selectedDateText = 'dd/mm/yyyy';
String? selectedTypeId;
final _nameController = TextEditingController();
final _dateController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final ValueNotifier<String> selectedGender = ValueNotifier<String>('Laki-laki');
@override
void initState() {
super.initState();
_dateController.text = 'dd/mm/yyyy';
}
@override
void dispose() {
_nameController.dispose();
_dateController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: GrayColors.gray50,
appBar: DefaultAppbarComponent(
title: 'Informasi Data Anda',
textColor: Colors.white,
backgroundColors: PrimaryColors.primary800,
onTab: () {
Get.back();
},
),
body: SafeArea(
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
child: HeaderInformation(
title: 'Pastikan anda memasukkan informasi mengenai data diri anda dengan benar!',
),
),
CustomeShadowCotainner(
height: MediaQuery.of(context).size.height * 0.67,
borderRadius: BorderRadius.circular(0),
child: SingleChildScrollView(
padding: EdgeInsets.only(bottom: 10.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CustomText.textPadding8('Nama Lengkap'),
SizedBox(height: 16.h),
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: 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(
borderRadius: BorderRadius.circular(0),
child: ButtonFill(
text: 'Simpan',
textColor: Colors.white,
onTap: () {},
),
),
);
}
}

View File

@ -113,7 +113,9 @@ class _InformationUsersScreenState extends State<InformationUsersScreen> {
label: 'Nama Lengkap',
value: userData.name ?? '-',
isDivider: false,
onTap: () {},
onTap: () {
Get.toNamed(Routes.CHANGEDATACOMPLETE);
},
),
SizedBox(height: 24.h),
Row(

View File

@ -35,10 +35,11 @@ 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_data_complete.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';
import 'package:e_porter/presentation/screens/profile/pages/change/change_email_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/change/change_number_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/change/change_password_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/information_users_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/passenger_list_screen.dart';
import 'package:e_porter/presentation/screens/profile/pages/profile_screen.dart';
@ -220,6 +221,10 @@ class AppRoutes {
name: Routes.CHANGENOID,
page: () => ChangeNoId(),
),
GetPage(
name: Routes.CHANGEDATACOMPLETE,
page: () => ChangeDataComplete(),
),
GetPage(
name: Routes.CHANGEEMAIL,
page: () => ChangeEmailScreen(),
@ -277,6 +282,7 @@ class Routes {
static const CHANGEPASSWORD = '/change_password';
static const CHANGENUMBER = '/change_number';
static const CHANGENOID = '/change_no_id';
static const CHANGEDATACOMPLETE = '/change_data_complete';
static const CHANGEEMAIL = '/change_email';
static const PASSENGERLIST = '/passenger_list';
}