e_receipt_mobile/lib/presentation/login/login_page.dart

125 lines
4.3 KiB
Dart
Raw Normal View History

2026-02-13 19:46:02 +00:00
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<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends ConsumerState<LoginPage> {
final _formKey = GlobalKey<FormState>();
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 &&
previous?.successMessage != next.successMessage) {
Navigator.of(context).pushReplacement(
MaterialPageRoute<void>(
builder: (_) => const HomeScreen(),
),
);
}
});
return Scaffold(
backgroundColor: Colors.blue,
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),
const SizedBox(height: 12),
//Password
roundedInput(controller: _passwordController, hint: "Password", icon: Icons.lock, isPassword: true),
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'),
),
],
),
),
),
),
),
),
),
);
}
}