import 'package:e_receipt_mobile/presentation/components/rounded_input.dart'; import 'package:e_receipt_mobile/presentation/home/home_screen.dart'; import 'package:e_receipt_mobile/presentation/login/login_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class LoginPage extends ConsumerStatefulWidget { const LoginPage({super.key}); @override ConsumerState createState() => _LoginPageState(); } class _LoginPageState extends ConsumerState { final _formKey = GlobalKey(); final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); @override void dispose() { _usernameController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final state = ref.watch(loginViewModelProvider); ref.listen(loginViewModelProvider, (previous, next) { if (!mounted) { return; } if (next.errorMessage != null && previous?.errorMessage != next.errorMessage) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(next.errorMessage!), backgroundColor: Colors.red, ), ); } if (next.successMessage != null && next.user != null && previous?.successMessage != next.successMessage) { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => HomeScreen(user: next.user!), ), ); } }); return Scaffold( backgroundColor: Colors.white, body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(32), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: Card( elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), child: Padding( padding: const EdgeInsets.all(20), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( 'E-Receipt', textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 20), //Username roundedInput( controller: _usernameController, hint: "Username", icon: Icons.person, validator: (value) { if ((value ?? '').trim().isEmpty) { return 'Username is required'; } return null; }, ), const SizedBox(height: 12), //Password roundedInput( controller: _passwordController, hint: "Password", icon: Icons.lock, isPassword: true, validator: (value) { if ((value ?? '').isEmpty) { return 'Password is required'; } if (value!.length < 6) { return 'Password must be at least 6 characters'; } return null; }, ), const SizedBox(height: 20), FilledButton( onPressed: state.isLoading ? null : () { ref .read(loginViewModelProvider.notifier) .clearMessages(); if (_formKey.currentState?.validate() ?? false) { ref .read(loginViewModelProvider.notifier) .login( username: _usernameController.text, password: _passwordController.text, ); } }, child: state.isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, ), ) : const Text('Login'), ), ], ), ), ), ), ), ), ), ); } }