import 'package:flutter/material.dart'; import '../constants/app_colors.dart'; import '../services/supabase_service.dart'; import '../screens/logado_inicial_screen.dart'; class AnimatedButton extends StatefulWidget { final String text; final VoidCallback onPressed; final Color backgroundColor; final Color textColor; final bool isLoading; const AnimatedButton({ super.key, required this.text, required this.onPressed, required this.backgroundColor, required this.textColor, this.isLoading = false, }); @override State createState() => _AnimatedButtonState(); } class _AnimatedButtonState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _scaleAnimation; late Animation _bounceAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 150), vsync: this, ); _scaleAnimation = Tween( begin: 1.0, end: 0.92, ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut)); _bounceAnimation = Tween(begin: 0.0, end: -3.0).animate( CurvedAnimation( parent: _controller, curve: const Interval(0.3, 0.8, curve: Curves.elasticOut), ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } void _handleTap() { _controller.forward().then((_) { _controller.reverse().then((_) { widget.onPressed(); }); }); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return Transform.translate( offset: Offset(0, _bounceAnimation.value), child: Transform.scale( scale: _scaleAnimation.value, child: SizedBox( width: double.infinity, height: 60, child: ElevatedButton( onPressed: widget.isLoading ? null : _handleTap, style: ElevatedButton.styleFrom( backgroundColor: widget.backgroundColor, foregroundColor: widget.textColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), elevation: 5, ), child: widget.isLoading ? const CircularProgressIndicator(color: Colors.white) : Text( widget.text, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w600, ), ), ), ), ), ); }, ); } } class EntrarSheet extends StatefulWidget { const EntrarSheet({super.key}); @override State createState() => _EntrarSheetState(); } class _EntrarSheetState extends State { final _formKey = GlobalKey(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); bool _isLoading = false; Future _handleLogin() async { if (_formKey.currentState!.validate()) { setState(() => _isLoading = true); try { await SupabaseService.signIn( email: _emailController.text.trim(), password: _passwordController.text, ); if (mounted) { // Close the bottom sheet first Navigator.of(context).pop(); // Show success message above the sheet ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Login realizado com sucesso!'), backgroundColor: Colors.green, ), ); // Then navigate to LogadoInicialScreen Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (context) => const LogadoInicialScreen(), ), ); } } catch (e) { if (mounted) { // Close the bottom sheet first Navigator.of(context).pop(); // Show error message above the sheet ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString()), backgroundColor: Colors.red), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } } Future _handlePasswordReset() async { final email = _emailController.text.trim(); if (email.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Por favor, insira seu email'), backgroundColor: Colors.orange, ), ); return; } try { await SupabaseService.resetPassword(email); if (mounted) { // Close the bottom sheet first Navigator.of(context).pop(); // Show success message above the sheet ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Email de redefinição enviado!'), backgroundColor: Colors.green, ), ); } } catch (e) { if (mounted) { // Close the bottom sheet first Navigator.of(context).pop(); // Show error message above the sheet ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(e.toString()), backgroundColor: Colors.red), ); } } } @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return DraggableScrollableSheet( initialChildSize: 0.6, // Start at 60% for login form minChildSize: 0.4, // 40% minimum maxChildSize: 0.9, // 90% maximum snap: true, // Enable snap points snapSizes: [0.6, 0.9], // Snap to 60% or 90% builder: (context, scrollController) { return Container( decoration: BoxDecoration( color: AppColors.backgroundGrey, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, -5), ), ], ), child: SingleChildScrollView( controller: scrollController, child: SafeArea( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Drag handle Center( child: Container( width: 60, height: 6, margin: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: Colors.grey[400], borderRadius: BorderRadius.circular(3), ), ), ), const SizedBox(height: 24), // Title const Text( 'Entrar', style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 32), // Email field const Text( 'Email', style: TextStyle(fontSize: 16, color: Colors.white70), ), const SizedBox(height: 8), Form( key: _formKey, child: TextFormField( controller: _emailController, decoration: InputDecoration( filled: true, fillColor: Colors.white.withOpacity(0.1), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), hintText: 'seu@email.com', hintStyle: const TextStyle(color: Colors.white38), ), style: const TextStyle(color: Colors.white), validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, insira seu email'; } if (!value.contains('@')) { return 'Email inválido'; } return null; }, ), ), const SizedBox(height: 20), // Password field const Text( 'Senha', style: TextStyle(fontSize: 16, color: Colors.white70), ), const SizedBox(height: 8), TextFormField( controller: _passwordController, obscureText: true, decoration: InputDecoration( filled: true, fillColor: Colors.white.withOpacity(0.1), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), hintText: '••••••••', hintStyle: const TextStyle(color: Colors.white38), ), style: const TextStyle(color: Colors.white), validator: (value) { if (value == null || value.isEmpty) { return 'Por favor, insira sua senha'; } if (value.length < 6) { return 'Senha deve ter pelo menos 6 caracteres'; } return null; }, ), const SizedBox(height: 32), // Login button AnimatedButton( text: 'Entrar', onPressed: _handleLogin, backgroundColor: AppColors.buttonColor, textColor: AppColors.white, isLoading: _isLoading, ), const SizedBox(height: 20), // Forgot password Center( child: TextButton( onPressed: _handlePasswordReset, child: const Text( 'Esqueceu a senha?', style: TextStyle(color: Colors.white70, fontSize: 16), ), ), ), const SizedBox(height: 40), ], ), ), ), ), ); }, ); } }