import 'package:flutter/material.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import '../supabase_config.dart'; /// Connexion d'un client existant (email + mot de passe). class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State { final _formKey = GlobalKey(); final _emailCtrl = TextEditingController(); final _mdpCtrl = TextEditingController(); bool _enCours = false; bool _voirMdp = false; String? _erreur; @override void dispose() { _emailCtrl.dispose(); _mdpCtrl.dispose(); super.dispose(); } Future _connexion() async { if (!_formKey.currentState!.validate()) return; setState(() { _enCours = true; _erreur = null; }); try { await supabase.auth.signInWithPassword( email: _emailCtrl.text.trim(), password: _mdpCtrl.text, ); // L'AuthGate prend le relais automatiquement (pop de cet écran). if (mounted) Navigator.of(context).pop(); } on AuthException catch (e) { if (mounted) setState(() => _erreur = e.message); } catch (e) { if (mounted) setState(() => _erreur = 'Erreur : $e'); } finally { if (mounted) setState(() => _enCours = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Connexion')), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 8), TextFormField( controller: _emailCtrl, keyboardType: TextInputType.emailAddress, autofillHints: const [AutofillHints.email], decoration: const InputDecoration( labelText: 'Email', prefixIcon: Icon(Icons.mail_outline), ), validator: (v) => (v == null || !v.contains('@')) ? 'Email invalide' : null, ), const SizedBox(height: 14), TextFormField( controller: _mdpCtrl, obscureText: !_voirMdp, decoration: InputDecoration( labelText: 'Mot de passe', prefixIcon: const Icon(Icons.lock_outline), suffixIcon: IconButton( icon: Icon( _voirMdp ? Icons.visibility_off : Icons.visibility), onPressed: () => setState(() => _voirMdp = !_voirMdp), ), ), validator: (v) => (v == null || v.isEmpty) ? 'Mot de passe requis' : null, onFieldSubmitted: (_) => _connexion(), ), if (_erreur != null) ...[ const SizedBox(height: 16), Text(_erreur!, textAlign: TextAlign.center, style: TextStyle(color: Colors.red.shade600)), ], const SizedBox(height: 24), FilledButton( onPressed: _enCours ? null : _connexion, child: _enCours ? const SizedBox( height: 22, width: 22, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white)) : const Text('Se connecter'), ), ], ), ), ), ), ); } }