import 'package:flutter/material.dart'; import '../theme/app_theme.dart'; import '../widgets/widgets.dart' as w; import 'main_shell.dart'; class RegisterScreen extends StatefulWidget { const RegisterScreen({super.key}); @override State createState() => _RegisterScreenState(); } class _RegisterScreenState extends State { final _pageController = PageController(); int _currentPage = 0; bool _loading = false; // Paso 1 final _nombreCtrl = TextEditingController(); final _apellidoCtrl = TextEditingController(); final _emailCtrl = TextEditingController(); final _telefonoCtrl = TextEditingController(); final _passCtrl = TextEditingController(); bool _obscurePass = true; // Paso 2 final _calleCtrl = TextEditingController(); final _coloniaCtrl = TextEditingController(); final _cpCtrl = TextEditingController(); int _radioAlerta = 200; @override void dispose() { _pageController.dispose(); _nombreCtrl.dispose(); _apellidoCtrl.dispose(); _emailCtrl.dispose(); _telefonoCtrl.dispose(); _passCtrl.dispose(); _calleCtrl.dispose(); _coloniaCtrl.dispose(); _cpCtrl.dispose(); super.dispose(); } void _nextPage() { _pageController.nextPage( duration: const Duration(milliseconds: 350), curve: Curves.easeInOut, ); setState(() => _currentPage = 1); } Future _register() async { setState(() => _loading = true); await Future.delayed(const Duration(seconds: 1)); if (!mounted) return; setState(() => _loading = false); Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => const MainShell()), (_) => false, ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppTheme.background, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, iconTheme: const IconThemeData(color: AppTheme.textPrimary), title: Text( _currentPage == 0 ? 'Crear cuenta' : 'Mi dirección', style: const TextStyle(color: AppTheme.textPrimary, fontSize: 16), ), bottom: PreferredSize( preferredSize: const Size.fromHeight(4), child: _StepIndicator(current: _currentPage, total: 2), ), ), body: PageView( controller: _pageController, physics: const NeverScrollableScrollPhysics(), children: [ _Step1( nombreCtrl: _nombreCtrl, apellidoCtrl: _apellidoCtrl, emailCtrl: _emailCtrl, telefonoCtrl: _telefonoCtrl, passCtrl: _passCtrl, obscurePass: _obscurePass, onTogglePass: () => setState(() => _obscurePass = !_obscurePass), onNext: _nextPage, ), _Step2( calleCtrl: _calleCtrl, coloniaCtrl: _coloniaCtrl, cpCtrl: _cpCtrl, radioAlerta: _radioAlerta, onRadioChanged: (v) => setState(() => _radioAlerta = v), onRegister: _register, loading: _loading, ), ], ), ); } } // ── Indicador de pasos ──────────────────────────────────────────────────────── class _StepIndicator extends StatelessWidget { final int current; final int total; const _StepIndicator({required this.current, required this.total}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 6), child: Row( children: List.generate(total, (i) { final active = i <= current; return Expanded( child: Container( margin: EdgeInsets.only(right: i < total - 1 ? 6 : 0), height: 4, decoration: BoxDecoration( color: active ? AppTheme.primary : AppTheme.border, borderRadius: BorderRadius.circular(4), ), ), ); }), ), ); } } // ── Paso 1: Datos personales ────────────────────────────────────────────────── class _Step1 extends StatelessWidget { final TextEditingController nombreCtrl, apellidoCtrl, emailCtrl, telefonoCtrl, passCtrl; final bool obscurePass; final VoidCallback onTogglePass; final VoidCallback onNext; const _Step1({ required this.nombreCtrl, required this.apellidoCtrl, required this.emailCtrl, required this.telefonoCtrl, required this.passCtrl, required this.obscurePass, required this.onTogglePass, required this.onNext, }); @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), // ── Sección personal ────────────────────────────────────────── _FormCard( icon: Icons.person_outline, title: 'Información personal', child: Column( children: [ Row( children: [ Expanded( child: w.FormField( label: 'Nombre', hint: 'Carlos', controller: nombreCtrl, ), ), const SizedBox(width: 12), Expanded( child: w.FormField( label: 'Apellido', hint: 'Martínez', controller: apellidoCtrl, ), ), ], ), const SizedBox(height: 14), w.FormField( label: 'Correo electrónico', hint: 'tu@correo.com', controller: emailCtrl, keyboardType: TextInputType.emailAddress, ), const SizedBox(height: 14), w.FormField( label: 'Teléfono', hint: '+52 461 123 4567', controller: telefonoCtrl, keyboardType: TextInputType.phone, ), const SizedBox(height: 14), w.FormField( label: 'Contraseña', hint: '••••••••', controller: passCtrl, obscureText: obscurePass, suffix: IconButton( icon: Icon( obscurePass ? Icons.visibility_outlined : Icons.visibility_off_outlined, size: 18, color: AppTheme.textSecondary, ), onPressed: onTogglePass, ), ), ], ), ), const SizedBox(height: 28), SizedBox( width: double.infinity, height: 52, child: ElevatedButton( onPressed: onNext, child: Row( mainAxisSize: MainAxisSize.min, children: const [ Text('Siguiente'), SizedBox(width: 8), Icon(Icons.arrow_forward, size: 18), ], ), ), ), const SizedBox(height: 20), Center( child: Row( mainAxisSize: MainAxisSize.min, children: [ const Text('¿Ya tienes cuenta? ', style: TextStyle( fontSize: 13, color: AppTheme.textSecondary)), GestureDetector( onTap: () => Navigator.pop(context), child: const Text('Inicia sesión', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: AppTheme.primary)), ), ], ), ), ], ), ); } } // ── Paso 2: Dirección ───────────────────────────────────────────────────────── class _Step2 extends StatelessWidget { final TextEditingController calleCtrl, coloniaCtrl, cpCtrl; final int radioAlerta; final ValueChanged onRadioChanged; final VoidCallback onRegister; final bool loading; const _Step2({ required this.calleCtrl, required this.coloniaCtrl, required this.cpCtrl, required this.radioAlerta, required this.onRadioChanged, required this.onRegister, required this.loading, }); @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), _FormCard( icon: Icons.home_outlined, title: 'Dirección de tu casa', child: Column( children: [ w.FormField( label: 'Calle y número', hint: 'Av. Insurgentes 245', controller: calleCtrl, ), const SizedBox(height: 14), Row( children: [ Expanded( flex: 3, child: w.FormField( label: 'Colonia', hint: 'Centro', controller: coloniaCtrl, ), ), const SizedBox(width: 12), Expanded( flex: 2, child: w.FormField( label: 'C.P.', hint: '38000', controller: cpCtrl, keyboardType: TextInputType.number, ), ), ], ), const SizedBox(height: 14), // Usar ubicación actual GestureDetector( onTap: () {}, child: Container( padding: const EdgeInsets.symmetric( vertical: 11, horizontal: 14), decoration: BoxDecoration( color: AppTheme.primaryLight, borderRadius: BorderRadius.circular(AppTheme.radiusSm), border: Border.all( color: AppTheme.primaryMid, width: 0.5), ), child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.my_location, color: AppTheme.primary, size: 18), SizedBox(width: 8), Text('Usar mi ubicación actual', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w500, color: AppTheme.primaryDark)), ], ), ), ), ], ), ), const SizedBox(height: 16), _FormCard( icon: Icons.notifications_outlined, title: 'Distancia de alerta', child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Te avisamos cuando el camión esté a esta distancia de tu casa.', style: TextStyle( fontSize: 13, color: AppTheme.textSecondary, height: 1.4), ), const SizedBox(height: 14), ...([200, 400, 600]).map((dist) => _RadioOption( value: dist, groupValue: radioAlerta, label: '$dist metros', sublabel: dist == 200 ? 'Alerta muy temprana (~2-3 min)' : dist == 400 ? 'Alerta temprana (~4-5 min)' : 'Alerta anticipada (~6-8 min)', onChanged: onRadioChanged, )), ], ), ), const SizedBox(height: 28), SizedBox( width: double.infinity, height: 52, child: ElevatedButton( onPressed: loading ? null : onRegister, child: loading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white), ) : const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.check, size: 18), SizedBox(width: 8), Text('Registrarme'), ], ), ), ), const SizedBox(height: 16), Center( child: Text( 'Al registrarte aceptas los Términos de Servicio\ny la Política de Privacidad.', textAlign: TextAlign.center, style: const TextStyle( fontSize: 11, color: AppTheme.textSecondary, height: 1.5), ), ), ], ), ); } } // ── Tarjeta de formulario ───────────────────────────────────────────────────── class _FormCard extends StatelessWidget { final IconData icon; final String title; final Widget child; const _FormCard( {required this.icon, required this.title, required this.child}); @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppTheme.surface, borderRadius: BorderRadius.circular(AppTheme.radiusLg), border: Border.all(color: AppTheme.border, width: 0.5), boxShadow: AppTheme.softShadow, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, color: AppTheme.primary, size: 18), const SizedBox(width: 8), Text(title, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppTheme.textPrimary)), ], ), const SizedBox(height: 16), child, ], ), ); } } // ── Opción radio ────────────────────────────────────────────────────────────── class _RadioOption extends StatelessWidget { final int value; final int groupValue; final String label; final String sublabel; final ValueChanged onChanged; const _RadioOption({ required this.value, required this.groupValue, required this.label, required this.sublabel, required this.onChanged, }); @override Widget build(BuildContext context) { final selected = value == groupValue; return GestureDetector( onTap: () => onChanged(value), child: Container( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 11), decoration: BoxDecoration( color: selected ? AppTheme.primaryLight : AppTheme.background, borderRadius: BorderRadius.circular(AppTheme.radiusSm), border: Border.all( color: selected ? AppTheme.primary : AppTheme.border, width: selected ? 1.5 : 0.5, ), ), child: Row( children: [ Container( width: 18, height: 18, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: selected ? AppTheme.primary : AppTheme.border, width: 2, ), ), child: selected ? Center( child: Container( width: 8, height: 8, decoration: const BoxDecoration( shape: BoxShape.circle, color: AppTheme.primary, ), ), ) : null, ), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: selected ? AppTheme.primaryDark : AppTheme.textPrimary)), Text(sublabel, style: TextStyle( fontSize: 11, color: selected ? AppTheme.primary : AppTheme.textSecondary)), ], ), ], ), ), ); } }