diff --git a/lib/presentation/components/field/field.dart b/lib/presentation/components/field/field.dart index 6a1c77b..a985bf1 100644 --- a/lib/presentation/components/field/field.dart +++ b/lib/presentation/components/field/field.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import '../../../common/extension/extension.dart'; import '../../../common/theme/theme.dart'; diff --git a/lib/presentation/components/field/text_form_field.dart b/lib/presentation/components/field/text_form_field.dart index ce5cab3..bdfd86b 100644 --- a/lib/presentation/components/field/text_form_field.dart +++ b/lib/presentation/components/field/text_form_field.dart @@ -4,6 +4,7 @@ class AppTextFormField extends StatelessWidget { const AppTextFormField({ super.key, this.hintText, + this.helperText, required this.title, this.controller, this.focusNode, @@ -14,9 +15,11 @@ class AppTextFormField extends StatelessWidget { this.validator, this.readOnly = false, this.onTap, + this.inputFormatters, }); final String? hintText; + final String? helperText; final String title; final TextEditingController? controller; final FocusNode? focusNode; @@ -27,6 +30,7 @@ class AppTextFormField extends StatelessWidget { final String? Function(String?)? validator; final bool readOnly; final Function()? onTap; + final List? inputFormatters; @override Widget build(BuildContext context) { @@ -39,6 +43,7 @@ class AppTextFormField extends StatelessWidget { controller: controller, focusNode: focusNode, keyboardType: keyboardType, + inputFormatters: inputFormatters, onChanged: onChanged, cursorColor: AppColor.primary, style: AppStyle.md.copyWith( @@ -50,6 +55,8 @@ class AppTextFormField extends StatelessWidget { readOnly: readOnly, decoration: InputDecoration( hintText: hintText, + helperText: helperText, + helperStyle: AppStyle.sm.copyWith(color: AppColor.textSecondary), prefixIcon: prefixIcon, suffixIcon: suffixIcon, prefixIconConstraints: const BoxConstraints( diff --git a/lib/presentation/pages/auth/login/widgets/phone_field.dart b/lib/presentation/pages/auth/login/widgets/phone_field.dart index 7caa40b..4baceda 100644 --- a/lib/presentation/pages/auth/login/widgets/phone_field.dart +++ b/lib/presentation/pages/auth/login/widgets/phone_field.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../../application/auth/check_phone_form/check_phone_form_bloc.dart'; @@ -36,6 +37,9 @@ class _LoginPhoneFieldState extends State { void _clearText() { _controller.clear(); + context.read().add( + const CheckPhoneFormEvent.phoneNumberChanged(''), + ); setState(() {}); } @@ -44,13 +48,19 @@ class _LoginPhoneFieldState extends State { return AppTextFormField( title: 'Masukkan no telepon', hintText: '8712671212', + helperText: 'Harus diawali angka 8', controller: _controller, focusNode: _focusNode, keyboardType: TextInputType.phone, + inputFormatters: [_PhoneAfterCountryCodeFormatter()], validator: (value) { - if (context.read().state.phoneNumber.isEmpty) { + final phoneNumber = context.read().state.phoneNumber; + if (phoneNumber.isEmpty) { return 'Masukkan no telepon'; } + if (!phoneNumber.startsWith('8')) { + return 'No telepon harus diawali angka 8'; + } return null; }, @@ -80,3 +90,27 @@ class _LoginPhoneFieldState extends State { ); } } + +/// Prefix +62 sudah tampil di field, jadi input harus langsung diawali 8. +/// Ketikan `0`/`6` di awal ditolak; tempelan `08…`, `62…`, atau `+62…` +/// dirapikan jadi `8…`. +class _PhoneAfterCountryCodeFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + var digits = newValue.text.replaceAll(RegExp(r'\D'), ''); + if (digits.startsWith('62')) digits = digits.substring(2); + digits = digits.replaceFirst(RegExp(r'^0+'), ''); + + if (digits.isEmpty) return const TextEditingValue(); + if (!digits.startsWith('8')) return oldValue; + if (digits == newValue.text) return newValue; + + return TextEditingValue( + text: digits, + selection: TextSelection.collapsed(offset: digits.length), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 01052ad..e4b39a3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: "A new Flutter project." publish_to: "none" -version: 1.0.0+1 +version: 1.0.0+2 environment: sdk: ^3.8.1