import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../application/auth_notifier.dart'; import 'widgets/winded_brand_header.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { static const _purple = Color(0xFF8B30C8); static const _purpleLight = Color(0xFFBF77F6); final _formKey = GlobalKey(); final _emailCtrl = TextEditingController(); final _passwordCtrl = TextEditingController(); bool _obscurePassword = true; @override void dispose() { _emailCtrl.dispose(); _passwordCtrl.dispose(); super.dispose(); } Future _submit() async { final form = _formKey.currentState; if (form == null || !form.validate()) return; FocusScope.of(context).unfocus(); await ref.read(authNotifierProvider.notifier).signIn( email: _emailCtrl.text, password: _passwordCtrl.text, ); if (!mounted) return; final state = ref.read(authNotifierProvider); if (state.hasError) { final message = authErrorMessage(state.error!); ScaffoldMessenger.of(context) ..hideCurrentSnackBar() ..showSnackBar(SnackBar(content: Text(message))); } // Successful sign-in triggers router redirect via auth stream — no // manual navigation needed here. } @override Widget build(BuildContext context) { final theme = Theme.of(context); final colors = theme.colorScheme; final authState = ref.watch(authNotifierProvider); final isLoading = authState.isLoading; return Scaffold( backgroundColor: colors.surface, body: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 440), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const WindedBrandHeader(), const SizedBox(height: 8), Text( 'SIGN IN TO YOUR PITCH', textAlign: TextAlign.center, style: theme.textTheme.labelMedium?.copyWith( color: colors.onSurfaceVariant, letterSpacing: 2.0, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 32), Container( decoration: BoxDecoration( color: const Color(0xFF1A1A1A), borderRadius: BorderRadius.circular(4), border: Border.all(color: const Color(0xFF3A3A3A)), ), child: Column( children: [ Container( height: 3, decoration: const BoxDecoration( color: _purple, borderRadius: BorderRadius.vertical(top: Radius.circular(4)), ), ), Padding( padding: const EdgeInsets.all(20), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextFormField( controller: _emailCtrl, enabled: !isLoading, keyboardType: TextInputType.emailAddress, autofillHints: const [AutofillHints.email], textInputAction: TextInputAction.next, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w600, letterSpacing: 0.5, ), decoration: const InputDecoration( labelText: 'EMAIL', prefixIcon: Icon(Icons.email_outlined), ), validator: _validateEmail, ), const SizedBox(height: 16), TextFormField( controller: _passwordCtrl, enabled: !isLoading, obscureText: _obscurePassword, autofillHints: const [AutofillHints.password], textInputAction: TextInputAction.done, onFieldSubmitted: (_) => _submit(), style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w600, letterSpacing: 0.5, ), decoration: InputDecoration( labelText: 'PASSWORD', prefixIcon: const Icon(Icons.lock_outline), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility_outlined : Icons.visibility_off_outlined, ), onPressed: isLoading ? null : () => setState(() { _obscurePassword = !_obscurePassword; }), ), ), validator: (v) { if (v == null || v.isEmpty) { return 'Enter your password'; } return null; }, ), const SizedBox(height: 24), FilledButton( onPressed: isLoading ? null : _submit, style: FilledButton.styleFrom( minimumSize: const Size.fromHeight(52), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(4)), ), ), child: isLoading ? SizedBox( width: 22, height: 22, child: CircularProgressIndicator( strokeWidth: 2.5, color: colors.onPrimary, ), ) : const Text( 'SIGN IN', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w900, letterSpacing: 2.0, ), ), ), ], ), ), ), ], ), ), const SizedBox(height: 24), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'NEW HERE? ', style: theme.textTheme.labelMedium?.copyWith( color: colors.onSurfaceVariant, letterSpacing: 1.5, ), ), TextButton( onPressed: isLoading ? null : () => context.go('/register'), style: TextButton.styleFrom( foregroundColor: _purpleLight, textStyle: const TextStyle( fontWeight: FontWeight.w800, letterSpacing: 1.5, ), ), child: const Text('CREATE AN ACCOUNT'), ), ], ), ], ), ), ), ), ), ); } String? _validateEmail(String? value) { final trimmed = value?.trim() ?? ''; if (trimmed.isEmpty) return 'Enter your email'; final emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$'); if (!emailRegex.hasMatch(trimmed)) return 'Enter a valid email address'; return null; } }