import 'package:email_validator/email_validator.dart'; import 'package:flutter/material.dart'; import 'package:prosapp_web_app/providers/auth_provider.dart'; import 'package:prosapp_web_app/providers/login_form_provider.dart'; import 'package:prosapp_web_app/router/router.dart'; import 'package:provider/provider.dart'; class LoginView extends StatelessWidget { const LoginView({super.key}); @override Widget build(BuildContext context) { final authProvider = Provider.of(context); final isDark = Theme.of(context).brightness == Brightness.dark; final cardColor = isDark ? const Color(0xFF1E293B) : Colors.white; final titleColor = isDark ? Colors.white : const Color(0xFF0F172A); final subtitleColor = isDark ? const Color(0xFF94A3B8) : const Color(0xFF64748B); final inputFill = isDark ? const Color(0xFF0F172A) : const Color(0xFFF8FAFF); final inputBorder = isDark ? const Color(0xFF334155) : const Color(0xFFCDD5F0); final inputTextColor = isDark ? Colors.white : const Color(0xFF0F172A); InputDecoration inputDecoration(String label, String hint, IconData icon) { return InputDecoration( labelText: label, labelStyle: TextStyle(color: subtitleColor), hintText: hint, hintStyle: TextStyle(color: subtitleColor), prefixIcon: Icon(icon, color: const Color(0xFF42A4EF)), filled: true, fillColor: inputFill, border: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide(color: inputBorder)), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Color(0xFF42A4EF), width: 2)), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Colors.red)), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Colors.red, width: 2)), ); } return ChangeNotifierProvider( create: (_) => LoginFormProvider(), child: Builder(builder: (context) { final loginFormProvider = Provider.of(context, listen: false); return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 32), child: Container( decoration: BoxDecoration( color: cardColor, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(isDark ? 0.3 : 0.08), blurRadius: 24, offset: const Offset(0, 4), ), ], ), padding: const EdgeInsets.all(28), child: Form( autovalidateMode: AutovalidateMode.onUserInteraction, key: loginFormProvider.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Iniciar sesión', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: titleColor), ), const SizedBox(height: 4), Text( 'Ingresa con tu cuenta de email', style: TextStyle(color: subtitleColor, fontSize: 13), ), const SizedBox(height: 28), TextFormField( keyboardType: TextInputType.emailAddress, onFieldSubmitted: (_) => _submit(loginFormProvider, authProvider), validator: (v) => EmailValidator.validate(v ?? '') ? null : 'Email no válido', onChanged: (v) => loginFormProvider.email = v, style: TextStyle(color: inputTextColor), decoration: inputDecoration('Email', 'correo@ejemplo.com', Icons.email_outlined), ), const SizedBox(height: 16), TextFormField( obscureText: true, onFieldSubmitted: (_) => _submit(loginFormProvider, authProvider), validator: (v) { if (v == null || v.isEmpty) return 'Ingresa tu contraseña'; if (v.length < 6) return 'Mínimo 6 caracteres'; return null; }, onChanged: (v) => loginFormProvider.password = v, style: TextStyle(color: inputTextColor), decoration: inputDecoration('Contraseña', '••••••••', Icons.lock_outline), ), const SizedBox(height: 24), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () => _submit(loginFormProvider, authProvider), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF42A4EF), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), elevation: 0, ), child: const Text('Ingresar', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600)), ), ), const SizedBox(height: 24), Row(children: [ const Expanded(child: Divider()), Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: Text('o', style: TextStyle(color: subtitleColor)), ), const Expanded(child: Divider()), ]), const SizedBox(height: 16), SizedBox( width: double.infinity, child: OutlinedButton.icon( onPressed: () => Navigator.pushReplacementNamed( context, Flurorouter.phoneLoginRoute), icon: const Icon(Icons.phone_android, color: Color(0xFF42A4EF)), label: const Text('Ingresar con celular', style: TextStyle( color: Color(0xFF42A4EF), fontWeight: FontWeight.w600)), style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), side: const BorderSide(color: Color(0xFF42A4EF)), ), ), ), const SizedBox(height: 12), Center( child: TextButton( onPressed: () => Navigator.pushReplacementNamed( context, Flurorouter.registerRoute), child: RichText( text: TextSpan( style: TextStyle(color: subtitleColor, fontSize: 13), children: const [ TextSpan(text: '¿No tienes cuenta? '), TextSpan( text: 'Regístrate', style: TextStyle( color: Color(0xFF42A4EF), fontWeight: FontWeight.w600), ), ], ), ), ), ), ], ), ), ), ), ), ); }), ); } void _submit(LoginFormProvider form, AuthProvider auth) async { if (form.validateForm()) { await auth.login(form.email, form.password); } } }