finnow/flutter_app/lib/pages/login_page.dart

112 lines
3.3 KiB
Dart

import 'package:finnow_app/auth/model.dart';
import 'package:finnow_app/components/form_label.dart';
import 'package:finnow_app/components/title_text.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../api/auth.dart';
import '../main.dart';
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 300.0),
padding: const EdgeInsets.all(10),
child: const LoginForm(),
),
));
}
}
class LoginForm extends StatefulWidget {
const LoginForm({super.key});
@override
State<LoginForm> createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final formKey = GlobalKey<FormState>();
final usernameTextController = TextEditingController();
final passwordTextController = TextEditingController();
var loginFailed = false;
@override
Widget build(BuildContext context) {
return Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const TitleText('Login to Finnow'),
const SizedBox(height: 20),
const FormLabel('Username'),
TextFormField(
controller: usernameTextController,
decoration: const InputDecoration(
hintText: 'Enter username', border: OutlineInputBorder()),
validator: usernameValidator,
),
const SizedBox(height: 10),
const FormLabel('Password'),
TextFormField(
controller: passwordTextController,
obscureText: true,
decoration: const InputDecoration(
hintText: 'Enter password', border: OutlineInputBorder()),
validator: passwordValidator,
),
const SizedBox(height: 10),
if (!loginFailed)
TextButton(onPressed: onLoginPressed, child: const Text('Login')),
if (loginFailed) ...[
const SizedBox(height: 10),
TextButton(
onPressed: () {}, child: const Text('Forgot password?'))
],
TextButton(
onPressed: onCreateAccountPressed,
child: const Text('Create an Account'))
],
));
}
@override
void dispose() {
usernameTextController.dispose();
passwordTextController.dispose();
super.dispose();
}
void onLoginPressed() async {
if (formKey.currentState!.validate()) {
final credentials = LoginCredentials(
usernameTextController.text, passwordTextController.text);
try {
String token = await postLogin(credentials);
getIt<AuthenticationModel>().state = Authenticated(token, credentials.username);
} catch (e) {
print(e);
onLoginAttemptFailed();
}
} else {
onLoginAttemptFailed();
}
}
void onLoginAttemptFailed() async {
setState(() => loginFailed = true);
Future.delayed(
const Duration(seconds: 3), () => setState(() => loginFailed = false));
}
void onCreateAccountPressed() async {
getIt<GoRouter>().go('/register');
}
}