/// Login Page library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/theme/colors.dart'; import '../../providers/auth_provider.dart'; class LoginPage extends ConsumerStatefulWidget { const LoginPage({super.key}); @override ConsumerState createState() => _LoginPageState(); } class _LoginPageState extends ConsumerState { final _formKey = GlobalKey(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); bool _obscurePassword = true; bool _isLoginMode = true; @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } Future _submit() async { if (!_formKey.currentState!.validate()) return; final authNotifier = ref.read(authProvider.notifier); if (_isLoginMode) { await authNotifier.login( _emailController.text.trim(), _passwordController.text, ); } else { await authNotifier.register( email: _emailController.text.trim(), username: _emailController.text.split('@')[0], password: _passwordController.text, ); } if (mounted && authNotifier.hasError) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(authNotifier.error ?? 'An error occurred'), backgroundColor: AppColors.error, ), ); } } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); // If already logged in, redirect to home if (authState.isAuthenticated) { WidgetsBinding.instance.addPostFrameCallback((_) { Navigator.of(context).pushReplacementNamed('/'); }); } return Scaffold( body: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ AppColors.primary, AppColors.surface, ], ), ), child: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), child: Card( elevation: 20, shadowColor: AppColors.cyan.withOpacity(0.3), child: Padding( padding: const EdgeInsets.all(32), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ // Logo/Title const Text( 'AudiOhm', style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, foreground: AppColors.primaryGradient, ), ), const SizedBox(height: 8), Text( _isLoginMode ? 'Welcome back' : 'Create account', style: const TextStyle( fontSize: 14, color: AppColors.muted, ), ), const SizedBox(height: 32), // Email field TextFormField( controller: _emailController, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Email', prefixIcon: Icon(Icons.email_outlined), ), validator: (value) { if (value == null || value.isEmpty) { return 'Email is required'; } if (!value.contains('@')) { return 'Enter a valid email'; } return null; }, ), const SizedBox(height: 16), // Password field TextFormField( controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( labelText: 'Password', prefixIcon: const Icon(Icons.lock_outlined), suffixIcon: IconButton( icon: Icon(_obscurePassword ? Icons.visibility_outlined : Icons.visibility_off_outlined), onPressed: () { setState(() { _obscurePassword = !_obscurePassword; }); }, ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Password is required'; } if (value.length < 8) { return 'Password must be at least 8 characters'; } return null; }, ), const SizedBox(height: 24), // Login button SizedBox( width: double.infinity, height: 50, child: FilledButton( onPressed: authState.isLoading ? null : _submit, child: authState.isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, color: AppColors.primary, ), ) : Text(_isLoginMode ? 'Login' : 'Register'), ), ), const SizedBox(height: 16), // Toggle mode TextButton( onPressed: () { setState(() { _isLoginMode = !_isLoginMode; }); }, child: Text( _isLoginMode ? "Don't have an account? Register" : 'Already have an account? Login', ), ), ], ), ), ), ), ), ), ), ), ), ); } }