import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:real_estate_mobile/core/constants/app_colors.dart'; import 'package:real_estate_mobile/features/auth/presentation/providers/auth_provider.dart'; import 'package:real_estate_mobile/features/auth/presentation/widgets/auth_text_field.dart'; import 'package:real_estate_mobile/features/auth/presentation/widgets/or_divider.dart'; import 'package:real_estate_mobile/features/auth/presentation/widgets/role_toggle.dart'; import 'package:real_estate_mobile/features/auth/presentation/widgets/social_login_buttons.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { final _nameController = TextEditingController(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); String _selectedRole = 'USER'; bool _obscurePassword = true; @override void dispose() { _nameController.dispose(); _emailController.dispose(); _passwordController.dispose(); super.dispose(); } String? _validateLocally() { if (_emailController.text.trim().isEmpty) { return 'Please enter your email'; } if (_passwordController.text.isEmpty) { return 'Please enter a password'; } return null; } void _handleLogin() { final localError = _validateLocally(); if (localError != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(localError), behavior: SnackBarBehavior.floating, ), ); return; } ref.read(authProvider.notifier).login( email: _emailController.text.trim(), password: _passwordController.text, ); } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); final isLoading = authState.status == AuthStatus.loading; return Scaffold( body: Container( width: double.infinity, height: double.infinity, decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [AppColors.gradientStart, AppColors.gradientEnd], ), ), child: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 24), child: Column( children: [ const SizedBox(height: 40), // Logo Image.asset( 'assets/icons/logo.png', width: 143, height: 41, ), const SizedBox(height: 24), // Title const Text( 'Login', style: TextStyle( fontFamily: 'Fractul', fontSize: 25, fontWeight: FontWeight.w400, color: AppColors.primaryDark, ), ), const SizedBox(height: 24), // Role toggle (User / Admin) RoleToggle( selectedRole: _selectedRole, onChanged: (role) => setState(() => _selectedRole = role), ), const SizedBox(height: 20), // Subtitle const Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: Text( 'Login or create an account to enjoy FREE consultation on all property inquiries.', textAlign: TextAlign.center, style: TextStyle( fontFamily: 'SourceSerif4', fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.primaryDark, ), ), ), const SizedBox(height: 24), // Error banner if (authState.errorMessage != null && authState.fieldErrors.isEmpty) ...[ Container( width: double.infinity, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12), decoration: BoxDecoration( color: AppColors.errorBg, border: Border.all(color: AppColors.errorBorder), borderRadius: BorderRadius.circular(7), ), child: Text( authState.errorMessage!, style: const TextStyle( fontFamily: 'Fractul', fontSize: 14, fontWeight: FontWeight.w300, color: AppColors.error, ), ), ), const SizedBox(height: 16), ], // Name field AuthTextField( hintText: 'Name', controller: _nameController, keyboardType: TextInputType.name, ), const SizedBox(height: 16), // Email field AuthTextField( hintText: 'Email', controller: _emailController, keyboardType: TextInputType.emailAddress, errorText: authState.getFieldError('email'), ), const SizedBox(height: 16), // Password field AuthTextField( hintText: 'Password', controller: _passwordController, obscureText: _obscurePassword, textInputAction: TextInputAction.done, errorText: authState.getFieldError('password'), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility_off : Icons.visibility, color: AppColors.hintText, size: 22, ), onPressed: () => setState(() => _obscurePassword = !_obscurePassword), ), ), const SizedBox(height: 24), // Login button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: isLoading ? null : _handleLogin, child: isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, color: AppColors.primaryDark, ), ) : const Text('Login'), ), ), const SizedBox(height: 24), // Don't have an account? Sign up Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( "Don't have an account? ", style: TextStyle( fontFamily: 'SourceSerif4', fontSize: 14, fontWeight: FontWeight.w400, color: AppColors.primaryDark, ), ), GestureDetector( onTap: () => context.go('/signup'), child: const Text( 'Sign up', style: TextStyle( fontFamily: 'Fractul', fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.primaryDark, ), ), ), ], ), const SizedBox(height: 24), // Or divider const OrDivider(), const SizedBox(height: 24), // Social login buttons const SocialLoginButtons(), const SizedBox(height: 40), ], ), ), ), ), ); } }