import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl_phone_field/countries.dart' hide countries; import 'package:intl_phone_field/phone_number.dart'; import '../config/country_list_beem.dart'; import '../config/language/language_enum.dart'; import '../providers/language_provider.dart'; // gives us languageSingleton import '../utils/colors.dart'; class PhoneInputField extends StatefulWidget { const PhoneInputField({ super.key, this.controller, this.hintStyle, this.onNumberChange, this.validator, }); final TextEditingController? controller; final TextStyle? hintStyle; final Function(PhoneNumber)? onNumberChange; final String? Function(PhoneNumber?)? validator; @override State createState() => _PhoneInputFieldState(); } class _PhoneInputFieldState extends State { Country selectedCountry = countries.firstWhere((country) => country.code == 'TN'); String? errorMessage; bool get _isArabic => languageSingleton.currentLangCode == Language.ar; @override void initState() { super.initState(); languageSingleton.addListener(_rebuild); } @override void dispose() { languageSingleton.removeListener(_rebuild); super.dispose(); } void _rebuild() => setState(() {}); void _onPhoneNumberChanged(String value) { final phoneNumber = PhoneNumber( countryISOCode: selectedCountry.code, countryCode: selectedCountry.dialCode, number: value, ); // Validate phone number final validationResult = widget.validator?.call(phoneNumber); setState(() { errorMessage = validationResult; }); widget.onNumberChange?.call(phoneNumber); } void _showCountryPicker() { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => _buildCountryPickerBottomSheet(), ); } Widget _buildCountryPickerBottomSheet() { return Container( height: MediaQuery.of(context).size.height * 0.7, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), ), child: Column( children: [ // Handle bar Container( margin: const EdgeInsets.only(top: 12), width: 40, height: 4, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(2), ), ), // Title Padding( padding: const EdgeInsets.all(20), child: Text( languageSingleton.translate('Select Country'), style: TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontSize: 18, fontWeight: FontWeight.w600, color: Colors.black, ), ), ), // Countries list Expanded( child: ListView.builder( itemCount: countries.length, itemBuilder: (context, index) { final country = countries[index]; return ListTile( leading: Container( width: 32, height: 24, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), border: Border.all(color: Colors.grey.shade300), ), child: ClipRRect( borderRadius: BorderRadius.circular(4), child: Text( country.flag, style: const TextStyle(fontSize: 18), ), ), ), title: Text( country.name, style: TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontSize: 16, fontWeight: FontWeight.w400, ), ), trailing: Text( country.dialCode, style: TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontSize: 16, fontWeight: FontWeight.w400, color: Colors.grey.shade600, ), ), onTap: () { setState(() { selectedCountry = country; }); Navigator.pop(context); _onPhoneNumberChanged(widget.controller?.text ?? ''); }, ); }, ), ), ], ), ); } @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Phone Number Label Padding( padding: const EdgeInsets.only(bottom: 8.0), child: Text( languageSingleton.translate('Phone Number'), style: TextStyle( color: AppNewColors.grayTxtColor, fontSize: 14, fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontWeight: FontWeight.w500, height: 1.33, ), ), ), // Custom Phone Input Field Container( decoration: BoxDecoration( color: AppNewColors.inputColor, borderRadius: BorderRadius.circular(12), border: Border.all( color: errorMessage != null ? Colors.red : Colors.grey.shade300, width: 1, ), ), child: Row( children: [ // Country Selector GestureDetector( onTap: _showCountryPicker, child: Container( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), decoration: BoxDecoration( color: AppNewColors.whiteBackGround, borderRadius: BorderRadius.circular(12), border: Border.all( color: errorMessage != null ? Colors.red : Colors.grey.shade300, width: 1, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ // Country Flag Center( child: Text( selectedCountry.flag, style: const TextStyle(fontSize: 14), ), ), const SizedBox(width: 8), // Country Code Text( "+${selectedCountry.dialCode}", style: TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontSize: 16, fontWeight: FontWeight.w600, color: AppNewColors.grayTxtColor, ), ), const SizedBox(width: 8), // Custom Dropdown Arrow SvgPicture.asset( 'assets/images/New/arrowTopDown.svg', width: 16, height: 16, colorFilter: ColorFilter.mode( Colors.grey.shade600, BlendMode.srcIn, ), ), ], ), ), ), const SizedBox(width: 8), // Divider // Container( // width: 1, // height: 24, // color: Colors.grey.shade300, // ), // Phone Number Input Expanded( child: TextField( controller: widget.controller, onChanged: _onPhoneNumberChanged, keyboardType: TextInputType.number, maxLength: 8, style: TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontSize: 16, fontWeight: FontWeight.w400, color: AppNewColors.black, ), textAlign: _isArabic ? TextAlign.right : TextAlign.left, decoration: InputDecoration( hintText: '123455678', hintStyle: widget.hintStyle ?? TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontWeight: FontWeight.w400, fontSize: 16, color: AppNewColors.inputTextColor, ), contentPadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 16, ), border: InputBorder.none, enabledBorder: InputBorder.none, focusedBorder: InputBorder.none, counterText: '', ), ), ), ], ), ), // Error Message if (errorMessage != null) Padding( padding: const EdgeInsets.only(top: 8, left: 16), child: Text( errorMessage!, style: TextStyle( fontFamily: _isArabic ? "Readex_Pro" : 'Inter', fontSize: 12, color: Colors.red, ), ), ), ], ); } }