import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../providers/auth_provider.dart'; /// Login page for user authentication 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; @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } Future _handleLogin() async { if (!_formKey.currentState!.validate()) return; final success = await ref.read(authProvider.notifier).login( email: _emailController.text.trim(), password: _passwordController.text, ); if (!mounted) return; if (success) { // Navigate to home or show success ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Login successful!')), ); // TODO: Navigate to home page } else { final errorMessage = ref.read(authProvider).errorMessage; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(errorMessage ?? 'Login failed'), backgroundColor: Colors.red, ), ); } } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); return Scaffold( appBar: AppBar( title: const Text('Login'), ), body: SafeArea( child: Padding( padding: const EdgeInsets.all(24.0), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Logo or app name Icon( Icons.shopping_cart, size: 80, color: Theme.of(context).primaryColor, ), const SizedBox(height: 16), Text( 'Retail POS', textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineMedium, ), const SizedBox(height: 48), // Email field TextFormField( controller: _emailController, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Email', prefixIcon: Icon(Icons.email), border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your email'; } if (!value.contains('@')) { return 'Please 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), border: const OutlineInputBorder(), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility : Icons.visibility_off, ), onPressed: () { setState(() { _obscurePassword = !_obscurePassword; }); }, ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your password'; } if (value.length < 8) { return 'Password must be at least 8 characters'; } return null; }, ), const SizedBox(height: 24), // Login button FilledButton( onPressed: authState.isLoading ? null : _handleLogin, child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: authState.isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, ), ) : const Text('Login'), ), ), const SizedBox(height: 16), // Register link TextButton( onPressed: () { // TODO: Navigate to register page // Navigator.push(context, MaterialPageRoute(builder: (_) => const RegisterPage())); }, child: const Text('Don\'t have an account? Register'), ), ], ), ), ), ), ); } }