import 'package:flutter/material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:go_router/go_router.dart'; import 'package:qpay/models/responsive_policy.dart'; import 'package:qpay/screens/onboarding/phone/phone_controller.dart'; import 'package:skeletonizer/skeletonizer.dart'; class PhoneScreen extends StatefulWidget { const PhoneScreen({super.key}); @override State createState() => _PhoneScreenState(); } class _PhoneScreenState extends State { late PhoneController phoneController; final _formKey = GlobalKey(); final TextEditingController _phoneController = TextEditingController(); String selectedCountryCode = '+263'; // Default to ZW // Common country codes with flags and names final List> countryCodes = [ {'code': '+263', 'name': 'ZW', 'flag': '🇿🇼'}, {'code': '+27', 'name': 'ZA', 'flag': '🇿🇦'}, {'code': '+1', 'name': 'US', 'flag': '🇺🇸'}, {'code': '+44', 'name': 'UK', 'flag': '🇬🇧'}, {'code': '+61', 'name': 'AU', 'flag': '🇦🇺'}, {'code': '+91', 'name': 'IN', 'flag': '🇮🇳'}, {'code': '+86', 'name': 'CN', 'flag': '🇨🇳'}, {'code': '+81', 'name': 'JP', 'flag': '🇯🇵'}, {'code': '+49', 'name': 'DE', 'flag': '🇩🇪'}, {'code': '+33', 'name': 'FR', 'flag': '🇫🇷'}, {'code': '+39', 'name': 'IT', 'flag': '🇮🇹'}, {'code': '+34', 'name': 'ES', 'flag': '🇪🇸'}, {'code': '+7', 'name': 'RU', 'flag': '🇷🇺'}, {'code': '+55', 'name': 'BR', 'flag': '🇧🇷'}, {'code': '+52', 'name': 'MX', 'flag': '🇲🇽'}, {'code': '+971', 'name': 'AE', 'flag': '🇦🇪'}, {'code': '+966', 'name': 'SA', 'flag': '🇸🇦'}, {'code': '+234', 'name': 'NG', 'flag': '🇳🇬'}, {'code': '+254', 'name': 'KE', 'flag': '🇰🇪'}, {'code': '+233', 'name': 'GH', 'flag': '🇬🇭'}, {'code': '+256', 'name': 'UG', 'flag': '🇺🇬'}, ]; @override void initState() { super.initState(); phoneController = PhoneController(context); } Future updatePhoneNumber(String phoneNumber) async { String existingPhone = phoneNumber; if (existingPhone.isNotEmpty) { // Try to extract country code from existing phone number for (var country in countryCodes) { if (existingPhone.startsWith(country['code']!)) { setState(() { selectedCountryCode = country['code']!; }); _phoneController.text = existingPhone.substring( country['code']!.length, ); break; } } // If no country code found, use default and set the full number if (_phoneController.text.isEmpty) { _phoneController.text = existingPhone; } } } @override Widget build(BuildContext context) { return ListenableBuilder( listenable: phoneController, builder: (context, child) { return Scaffold( body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(25.0), child: Form( key: _formKey, child: Center( child: LayoutBuilder( builder: (context, constraints) { final maxWidth = constraints.maxWidth > ResponsivePolicy.md ? ResponsivePolicy.md.toDouble() : constraints.maxWidth; return SizedBox( width: maxWidth, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(height: 75), Text( 'Verify Your Device', style: TextStyle( fontSize: 30, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary, ), textAlign: TextAlign.center, ), SizedBox(height: 10), Text( 'We will send you a verification code to this number', style: TextStyle(fontSize: 18), textAlign: TextAlign.center, ), Image.asset('assets/phone.png', width: 300), SizedBox(height: 20), _buildPhoneField(), SizedBox(height: 30), Padding( padding: const EdgeInsets.symmetric( horizontal: 25, ), child: Skeletonizer( enabled: phoneController.model.isLoading, child: Row( children: [ Expanded( child: ElevatedButton( onPressed: () async { if (_formKey.currentState! .validate()) { String fullPhoneNumber = _phoneController.text; phoneController.updatePhone( fullPhoneNumber, ); await phoneController.register(); if (phoneController.model.status != 'failed') { context.go('/onboarding/verify'); } } }, child: Text( 'Send Code', style: TextStyle(fontSize: 16), ), ), ), SizedBox(width: 16), Expanded( child: OutlinedButton( onPressed: () { context.go('/onboarding/login'); }, child: Text( 'Go to Login', style: TextStyle(fontSize: 16), ), ), ), ], ), ), ), SizedBox(height: 10), TextButton( onPressed: () { context.go('/'); }, child: Text( 'Continue as guest?', style: TextStyle(fontSize: 14), ), ), ], ), ); }, ), ), ), ), ), ); }, ); } Widget _buildPhoneField() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ // Country code dropdown Container( width: 100, height: 55, decoration: BoxDecoration( border: Border.all( color: Theme.of(context).colorScheme.primary.withOpacity(0.2), ), borderRadius: BorderRadius.circular(12), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: selectedCountryCode, isExpanded: true, icon: const Icon(Icons.arrow_drop_down), padding: const EdgeInsets.symmetric(horizontal: 8), items: countryCodes.map((country) { return DropdownMenuItem( value: country['code'], child: Row( mainAxisSize: MainAxisSize.min, children: [ Text(country['flag']!), const SizedBox(width: 4), Text( country['code']!, style: const TextStyle(fontSize: 16), ), ], ), ); }).toList(), onChanged: (String? newValue) { if (newValue != null) { setState(() { selectedCountryCode = newValue; }); } }, ), ), ), const SizedBox(width: 8), // Phone number field Expanded( child: TextFormField( controller: _phoneController, keyboardType: TextInputType.numberWithOptions(decimal: true), decoration: InputDecoration( hintText: 'Enter phone number', focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: Theme.of(context).colorScheme.secondary, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: Theme.of( context, ).colorScheme.primary.withOpacity(0.2), ), ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter a phone number'; } // Remove any non-digit characters for validation String digitsOnly = value.replaceAll(RegExp(r'[^\d]'), ''); if (digitsOnly.length < 7) { return 'Phone number must be at least 7 digits'; } if (digitsOnly.length > 15) { return 'Phone number is too long'; } return null; }, ), ), ], ), ], ); } }