Add base skeleton

This commit is contained in:
2025-07-01 20:40:00 +02:00
parent ab8974c0a8
commit 29fec99b8f
19 changed files with 722 additions and 24 deletions

View File

@ -0,0 +1,85 @@
import 'package:flextras/flextras.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gutter/flutter_gutter.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:moneymgr_mobile/routes/login/login_model.dart';
import 'package:moneymgr_mobile/widgets/app_button.dart';
import '../../../services/auth_state.dart';
import '../../../utils/extensions.dart';
class LoginScreen extends HookConsumerWidget {
const LoginScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isPasswordVisible = useState(false);
final usernameController = useTextEditingController();
final passwordController = useTextEditingController();
void onSettingsPressed() => context.push('/settings');
Future<void> onLoginPressed() async {
try {
await ref.read(currentAuthStateProvider.notifier).login(LoginModel(
username: usernameController.text,
password: passwordController.text,
));
} on Exception catch (e) {
if (!context.mounted) return;
context.showTextSnackBar(e.toString());
}
}
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
actions: [
IconButton(
onPressed: onSettingsPressed,
icon: const Icon(Icons.settings),
),
],
),
body: SeparatedColumn(
padding: EdgeInsets.all(context.gutter),
separatorBuilder: () => const Gutter(),
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
controller: usernameController,
decoration: const InputDecoration(labelText: 'Username'),
textInputAction: TextInputAction.next,
),
TextField(
controller: passwordController,
decoration: InputDecoration(
labelText: 'Password',
suffixIcon: IconButton(
icon: Icon(
isPasswordVisible.value
? Icons.visibility_off
: Icons.visibility,
),
onPressed: () =>
isPasswordVisible.value = !isPasswordVisible.value,
),
),
obscureText: !isPasswordVisible.value,
keyboardType: TextInputType.visiblePassword,
textInputAction: TextInputAction.done,
),
const SizedBox.shrink(),
AppButton(
onPressed: onLoginPressed,
label: 'Login',
),
],
),
);
}
}