From ce1c175c628726b957604c8968cc1f702eb6efb4 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Tue, 1 Jul 2025 22:45:20 +0200 Subject: [PATCH] Adapt base login page --- .../lib/routes/login/base_auth_page.dart | 36 ++++++ .../lib/routes/login/login_screen.dart | 119 +++++++----------- .../lib/services/router/routes_list.dart | 4 + 3 files changed, 87 insertions(+), 72 deletions(-) create mode 100644 moneymgr_mobile/lib/routes/login/base_auth_page.dart diff --git a/moneymgr_mobile/lib/routes/login/base_auth_page.dart b/moneymgr_mobile/lib/routes/login/base_auth_page.dart new file mode 100644 index 0000000..4c61f97 --- /dev/null +++ b/moneymgr_mobile/lib/routes/login/base_auth_page.dart @@ -0,0 +1,36 @@ +import 'package:flextras/flextras.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gutter/flutter_gutter.dart'; +import 'package:go_router/go_router.dart'; + +import '../../services/router/routes_list.dart'; + +class BaseAuthPage extends StatelessWidget { + final List children; + + const BaseAuthPage({super.key, required this.children}); + + @override + Widget build(BuildContext context) { + void onSettingsPressed() => context.push(settingsPage); + + return Scaffold( + appBar: AppBar( + title: const Text('MoneyMgr'), + 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: children, + ), + ); + } +} diff --git a/moneymgr_mobile/lib/routes/login/login_screen.dart b/moneymgr_mobile/lib/routes/login/login_screen.dart index a34d116..def0284 100644 --- a/moneymgr_mobile/lib/routes/login/login_screen.dart +++ b/moneymgr_mobile/lib/routes/login/login_screen.dart @@ -1,86 +1,61 @@ -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/routes/login/base_auth_page.dart'; import 'package:moneymgr_mobile/services/router/routes_list.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(settingsPage); - - Future 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('MoneyMgr'), - 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', - ), - ], - ), + return BaseAuthPage( + children: [ + Gutter(scaleFactor: 3), + Text( + "This application requires a token from MoneyMgr to be used.\n\nPlease create a token on your Money Manager instance and make sure to click on \"For mobile app\" button. You can then enter here generated credentials.", + textAlign: TextAlign.justify, + ), + Expanded(child: Container()), + _LoginChoice( + route: manualAuthPage, + icon: Icons.edit_document, + label: "Enter manually authentication information", + ), + _LoginChoice( + route: manualAuthPage, + icon: Icons.qr_code_2, + label: "Scan authentication Qr Code", + ), + Gutter(scaleFactor: 3), + ], + ); + } +} + +class _LoginChoice extends StatelessWidget { + const _LoginChoice({ + super.key, + required this.route, + required this.label, + required this.icon, + }); + + final String route; + final String label; + final IconData icon; + + @override + Widget build(BuildContext context) { + return FilledButton( + onPressed: () => context.push(route), + style: ButtonStyle( + padding: WidgetStatePropertyAll( + EdgeInsetsGeometry.symmetric(vertical: 20.0, horizontal: 30.0), + ), + ), + child: Row(children: [Icon(icon, size: 25.0), Gutter(), Text(label)]), ); } } diff --git a/moneymgr_mobile/lib/services/router/routes_list.dart b/moneymgr_mobile/lib/services/router/routes_list.dart index 33aa071..dc0b12e 100644 --- a/moneymgr_mobile/lib/services/router/routes_list.dart +++ b/moneymgr_mobile/lib/services/router/routes_list.dart @@ -1,7 +1,11 @@ +/// Base home page const homePage = "/"; /// Authentication path const authPage = "/login"; +/// Manual authentication +const manualAuthPage = "/login/manual"; + /// Settings path const settingsPage = "/settings"; \ No newline at end of file