import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../services/auth_service.dart'; import '../services/sync_service.dart'; import 'home_screen.dart'; const _loginInk = Color(0xFF17251E); const _loginGreen = Color(0xFF456C52); class PhoneLoginScreen extends StatefulWidget { const PhoneLoginScreen({super.key}); @override State createState() => _PhoneLoginScreenState(); } class _PhoneLoginScreenState extends State { final _phone = TextEditingController(); final _code = TextEditingController(); final _name = TextEditingController(); bool _registration = false; bool _codeSent = false; bool _busy = false; @override void dispose() { _phone.dispose(); _code.dispose(); _name.dispose(); super.dispose(); } Future _requestCode() async { final phone = _phone.text.trim(); if (!RegExp(r'^\+[1-9][0-9]{7,14}$').hasMatch(phone)) { _showMessage('اكتب رقمك بصيغة دولية، مثل ‎+9627XXXXXXXX.'); return; } setState(() => _busy = true); try { await Get.find().requestOtp( phoneE164: phone, isRegistration: _registration, ); if (mounted) setState(() => _codeSent = true); _showMessage('أرسلنا رمز التحقق إذا كانت الخدمة مفعّلة.'); } catch (error) { _showMessage(error.toString()); } finally { if (mounted) setState(() => _busy = false); } } Future _verifyCode() async { if (!RegExp(r'^\d{6}$').hasMatch(_code.text.trim())) { _showMessage('أدخل رمز التحقق المكوّن من ٦ أرقام.'); return; } if (_registration && _name.text.trim().isEmpty) { _showMessage('اكتب الاسم الذي تود ظهوره في حسابك.'); return; } setState(() => _busy = true); try { await Get.find().verifyOtp( phoneE164: _phone.text.trim(), code: _code.text.trim(), isRegistration: _registration, displayName: _name.text.trim().isEmpty ? null : _name.text.trim(), ); if (mounted) { Get.offAll(() => const HomeScreen()); Get.find().syncPendingWorkouts(retryNow: true); } } catch (error) { _showMessage(error.toString()); } finally { if (mounted) setState(() => _busy = false); } } void _showMessage(String message) { if (!mounted) return; ScaffoldMessenger.of(context) ..hideCurrentSnackBar() ..showSnackBar(SnackBar(content: Text(message))); } @override Widget build(BuildContext context) { final auth = Get.find(); return Scaffold( backgroundColor: const Color(0xFFF5F7F2), body: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(24, 32, 24, 28), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Align( alignment: AlignmentDirectional.centerStart, child: Container( width: 44, height: 44, decoration: BoxDecoration( color: _loginGreen, borderRadius: BorderRadius.circular(15), ), alignment: Alignment.center, child: const Text('S', style: TextStyle( color: Colors.white, fontFamily: 'Georgia', fontSize: 27, fontStyle: FontStyle.italic)), ), ), const SizedBox(height: 40), const Text('أهلًا بك في SportPath', style: TextStyle( color: _loginGreen, fontSize: 13, fontWeight: FontWeight.w600)), const SizedBox(height: 9), Text( _codeSent ? 'تحقق من رقمك.' : 'رحلتك تبدأ من هنا.', style: const TextStyle( color: _loginInk, fontSize: 30, height: 1.25, fontWeight: FontWeight.w600, letterSpacing: -.7), ), const SizedBox(height: 11), Text( _codeSent ? 'أدخل الرمز المكوّن من ٦ أرقام الذي وصلك برسالة.' : 'استخدم رقم هاتفك لحفظ تقدمك ومزامنة نشاطك بأمان.', style: const TextStyle( color: Color(0xFF778078), fontSize: 14, height: 1.8), ), const SizedBox(height: 24), if (!_codeSent) ...[ SegmentedButton( segments: const [ ButtonSegment( value: false, label: Text('تسجيل الدخول')), ButtonSegment(value: true, label: Text('حساب جديد')), ], selected: {_registration}, onSelectionChanged: _busy ? null : (value) => setState(() => _registration = value.first), ), const SizedBox(height: 18), if (_registration) ...[ _InputField( controller: _name, label: 'الاسم', hint: 'كيف نناديك؟', keyboardType: TextInputType.name), const SizedBox(height: 12), ], _InputField( controller: _phone, label: 'رقم الهاتف', hint: '+9627XXXXXXXX', keyboardType: TextInputType.phone, direction: TextDirection.ltr), ] else ...[ _InputField( controller: _phone, label: 'رقم الهاتف', hint: '+9627XXXXXXXX', keyboardType: TextInputType.phone, direction: TextDirection.ltr, enabled: false), const SizedBox(height: 12), _InputField( controller: _code, label: 'رمز التحقق', hint: '000000', keyboardType: TextInputType.number, direction: TextDirection.ltr, maxLength: 6), const SizedBox(height: 9), TextButton( onPressed: _busy ? null : () => setState(() { _codeSent = false; _code.clear(); }), child: const Text('تغيير الرقم أو طلب رمز جديد')), ], const SizedBox(height: 13), FilledButton( onPressed: _busy ? null : (_codeSent ? _verifyCode : _requestCode), style: FilledButton.styleFrom( backgroundColor: _loginGreen, foregroundColor: Colors.white, minimumSize: const Size.fromHeight(52), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15))), child: _busy ? const SizedBox( width: 21, height: 21, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white)) : Text(_codeSent ? 'تأكيد الرمز' : 'إرسال رمز التحقق', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600)), ), const SizedBox(height: 16), if (!auth.isApiConfigured) const Text( 'نسخة التطوير تحتاج عنوان API آمنًا عبر API_BASE_URL قبل تسجيل الدخول.', textAlign: TextAlign.center, style: TextStyle( color: Color(0xFF8A6254), fontSize: 11, height: 1.7)), const SizedBox(height: 22), const Text( 'نستخدم رقمك للتحقق من الحساب فقط. لا نقرأ بيانات البصمة أو الوجه؛ المصادقة الحيوية تبقى داخل نظام جهازك.', textAlign: TextAlign.center, style: TextStyle( color: Color(0xFF899189), fontSize: 10, height: 1.8)), ], ), ), ), ), ), ); } } class _InputField extends StatelessWidget { const _InputField( {required this.controller, required this.label, required this.hint, required this.keyboardType, this.direction, this.enabled = true, this.maxLength}); final TextEditingController controller; final String label; final String hint; final TextInputType keyboardType; final TextDirection? direction; final bool enabled; final int? maxLength; @override Widget build(BuildContext context) => TextField( controller: controller, enabled: enabled, keyboardType: keyboardType, textDirection: direction, maxLength: maxLength, style: const TextStyle(color: _loginInk, fontSize: 15), decoration: InputDecoration( labelText: label, hintText: hint, counterText: '', filled: true, fillColor: Colors.white, border: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: const BorderSide(color: Color(0xFFE6EBE3))), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(15), borderSide: const BorderSide(color: _loginGreen, width: 1.4)), ), ); }