import 'package:flutter/material.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import '../main.dart' show supabase; Future showLoginSheet(BuildContext context) { return showModalBottomSheet( context: context, isScrollControlled: true, showDragHandle: true, backgroundColor: const Color(0xFFFFE6F1), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(24)), ), builder: (ctx) => const LoginBottomSheet(), ); } class LoginBottomSheet extends StatefulWidget { const LoginBottomSheet({super.key}); @override State createState() => _LoginBottomSheetState(); } class _LoginBottomSheetState extends State { final _formKey = GlobalKey(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); bool _loading = false; @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final bottomInset = MediaQuery.viewInsetsOf(context).bottom; return SafeArea( child: Padding( padding: EdgeInsets.fromLTRB(18, 6, 18, 18 + bottomInset), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( 'Entrar', textAlign: TextAlign.center, style: TextStyle( fontSize: 18, fontWeight: FontWeight.w900, color: Color(0xFFFF55A7), ), ), const SizedBox(height: 12), Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.82), borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.black.withValues(alpha: 0.08)), ), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ TextFormField( controller: _emailController, keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, decoration: const InputDecoration(labelText: 'Email'), validator: (v) { final value = (v ?? '').trim(); if (value.isEmpty) return 'Informe seu email'; if (!value.contains('@')) return 'Email inválido'; return null; }, ), TextFormField( controller: _passwordController, obscureText: true, textInputAction: TextInputAction.done, decoration: const InputDecoration(labelText: 'Senha'), validator: (v) { final value = (v ?? ''); if (value.isEmpty) return 'Informe sua senha'; if (value.length < 6) return 'Mínimo de 6 caracteres'; return null; }, ), ], ), ), ), const SizedBox(height: 14), Row( children: [ Expanded( child: SizedBox( height: 44, child: TextButton( onPressed: _loading ? null : () => Navigator.of(context).pop(), child: const Text('Cancelar'), ), ), ), const SizedBox(width: 10), Expanded( child: SizedBox( height: 44, child: FilledButton( style: FilledButton.styleFrom( backgroundColor: const Color(0xFF2F9E94), foregroundColor: Colors.white, shape: const StadiumBorder(), textStyle: const TextStyle(fontWeight: FontWeight.w900), ), onPressed: _loading ? null : _submit, child: _loading ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : const Text('Entrar'), ), ), ), ], ), ], ), ), ); } Future _submit() async { if (!(_formKey.currentState?.validate() ?? false)) return; setState(() => _loading = true); try { final email = _emailController.text.trim(); final password = _passwordController.text; await supabase.auth.signInWithPassword(email: email, password: password); if (!mounted) return; Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Login efetuado')), ); } on AuthException catch (e) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(_friendlyAuthError(e))), ); } catch (e) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Erro: $e')), ); } finally { if (mounted) setState(() => _loading = false); } } String _friendlyAuthError(AuthException e) { switch (e.code) { case 'invalid_credentials': return 'Email ou senha incorretos.'; case 'user_not_found': return 'Usuário não encontrado.'; default: return e.message; } } }