import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:go_router/go_router.dart'; import '../providers/auth_provider.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State { final _formKey = GlobalKey(); final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); bool _obscurePassword = true; @override void dispose() { _usernameController.dispose(); _passwordController.dispose(); super.dispose(); } Future _submit() async { if (!_formKey.currentState!.validate()) return; final auth = context.read(); final success = await auth.login( _usernameController.text.trim(), _passwordController.text, ); if (success && mounted) { context.go('/dashboard'); } } @override Widget build(BuildContext context) { final auth = context.watch(); final theme = Theme.of(context); return Scaffold( backgroundColor: const Color(0xFFF5F7FA), body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Logo / En-tête Container( width: 90, height: 90, decoration: BoxDecoration( color: theme.colorScheme.primary, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: theme.colorScheme.primary.withOpacity(0.3), blurRadius: 20, offset: const Offset(0, 8), ), ], ), child: const Icon(Icons.factory, size: 48, color: Colors.white), ), const SizedBox(height: 24), Text( 'RAYHAN ERP', style: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.primary, letterSpacing: 2, ), ), const SizedBox(height: 6), Text( 'Système de Gestion Intégré', style: theme.textTheme.bodyMedium?.copyWith( color: Colors.grey[600], ), ), const SizedBox(height: 40), // Carte de connexion Container( constraints: const BoxConstraints(maxWidth: 420), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.08), blurRadius: 24, offset: const Offset(0, 4), ), ], ), padding: const EdgeInsets.all(32), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'Connexion', style: theme.textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( 'Entrez vos identifiants pour accéder au système', style: theme.textTheme.bodySmall?.copyWith( color: Colors.grey[600], ), ), const SizedBox(height: 28), // Champ nom d'utilisateur TextFormField( controller: _usernameController, decoration: InputDecoration( labelText: 'Nom d\'utilisateur', prefixIcon: const Icon(Icons.person_outline), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), filled: true, fillColor: const Color(0xFFF8F9FA), ), textInputAction: TextInputAction.next, validator: (v) => (v == null || v.trim().isEmpty) ? 'Champ obligatoire' : null, ), const SizedBox(height: 16), // Champ mot de passe TextFormField( controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( labelText: 'Mot de passe', prefixIcon: const Icon(Icons.lock_outline), suffixIcon: IconButton( icon: Icon(_obscurePassword ? Icons.visibility_off_outlined : Icons.visibility_outlined), onPressed: () => setState(() => _obscurePassword = !_obscurePassword), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), filled: true, fillColor: const Color(0xFFF8F9FA), ), textInputAction: TextInputAction.done, onFieldSubmitted: (_) => _submit(), validator: (v) => (v == null || v.isEmpty) ? 'Champ obligatoire' : null, ), const SizedBox(height: 12), // Message d'erreur if (auth.errorMessage != null) Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.red[50], borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.red[200]!), ), child: Row( children: [ Icon(Icons.error_outline, color: Colors.red[700], size: 18), const SizedBox(width: 8), Expanded( child: Text( auth.errorMessage!, style: TextStyle(color: Colors.red[700], fontSize: 13), ), ), ], ), ), const SizedBox(height: 24), // Bouton connexion SizedBox( height: 50, child: ElevatedButton( onPressed: auth.isLoading ? null : _submit, style: ElevatedButton.styleFrom( backgroundColor: theme.colorScheme.primary, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), elevation: 2, ), child: auth.isLoading ? const SizedBox( width: 22, height: 22, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : const Text( 'Se connecter', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ), ], ), ), ), const SizedBox(height: 32), Text( '© 2026 SUARL Rayhan — Tataouine, Tunisie', style: TextStyle(color: Colors.grey[500], fontSize: 12), ), ], ), ), ), ); } }