Add settings screen
This commit is contained in:
		| @@ -5,6 +5,7 @@ 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/services/router/routes_list.dart'; | ||||
| import 'package:moneymgr_mobile/widgets/app_button.dart'; | ||||
| 
 | ||||
| import '../../../services/auth_state.dart'; | ||||
| @@ -20,7 +21,7 @@ class LoginScreen extends HookConsumerWidget { | ||||
|     final usernameController = useTextEditingController(); | ||||
|     final passwordController = useTextEditingController(); | ||||
| 
 | ||||
|     void onSettingsPressed() => context.push('/settings'); | ||||
|     void onSettingsPressed() => context.push(settingsPage); | ||||
| 
 | ||||
|     Future<void> onLoginPressed() async { | ||||
|       try { | ||||
| @@ -36,7 +37,7 @@ class LoginScreen extends HookConsumerWidget { | ||||
| 
 | ||||
|     return Scaffold( | ||||
|       appBar: AppBar( | ||||
|         title: const Text('Login'), | ||||
|         title: const Text('MoneyMgr'), | ||||
|         actions: [ | ||||
|           IconButton( | ||||
|             onPressed: onSettingsPressed, | ||||
							
								
								
									
										74
									
								
								moneymgr_mobile/lib/routes/settings/settings_screen.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								moneymgr_mobile/lib/routes/settings/settings_screen.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||||
| import 'package:moneymgr_mobile/providers/settings.dart'; | ||||
| import 'package:moneymgr_mobile/utils/extensions.dart'; | ||||
|  | ||||
| class SettingsScreen extends ConsumerWidget { | ||||
|   const SettingsScreen({super.key}); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context, WidgetRef ref) { | ||||
|     final themeMode = ref.watch(currentThemeModeProvider); | ||||
|  | ||||
|     void onTapThemeMode() => | ||||
|         showDialog(context: context, builder: (_) => const _ThemeModeDialog()); | ||||
|  | ||||
|     void onTapLicenses() => context.showAppLicensePage(); | ||||
|  | ||||
|     return Scaffold( | ||||
|       appBar: AppBar(title: const Text('Settings')), | ||||
|       body: ListView( | ||||
|         children: [ | ||||
|           ListTile( | ||||
|             leading: const Icon(Icons.brightness_6), | ||||
|             title: const Text('Theme mode'), | ||||
|             trailing: Text(themeMode.label), | ||||
|             onTap: onTapThemeMode, | ||||
|           ), | ||||
|           const Divider(), | ||||
|           ListTile( | ||||
|             leading: const Icon(Icons.info_outline), | ||||
|             title: const Text('Licenses'), | ||||
|             onTap: onTapLicenses, | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// Select theme dialog | ||||
| class _ThemeModeDialog extends ConsumerWidget { | ||||
|   const _ThemeModeDialog(); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context, WidgetRef ref) { | ||||
|     void onTapOption(ThemeMode themeMode) { | ||||
|       ref.read(currentThemeModeProvider.notifier).set(themeMode); | ||||
|       Navigator.of(context).pop(); | ||||
|     } | ||||
|  | ||||
|     return SimpleDialog( | ||||
|       clipBehavior: Clip.antiAlias, | ||||
|       children: [ | ||||
|         for (final themeMode in ThemeMode.values) | ||||
|           _ThemeModeDialogOption( | ||||
|             value: themeMode, | ||||
|             onTap: () => onTapOption(themeMode), | ||||
|           ), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| class _ThemeModeDialogOption extends StatelessWidget { | ||||
|   const _ThemeModeDialogOption({required this.value, required this.onTap}); | ||||
|  | ||||
|   final ThemeMode value; | ||||
|   final GestureTapCallback? onTap; | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return ListTile(onTap: onTap, title: Text(value.label)); | ||||
|   } | ||||
| } | ||||
| @@ -56,12 +56,12 @@ class CurrentAuthState extends _$CurrentAuthState { | ||||
|  | ||||
| /// The possible authentication states of the app. | ||||
| enum AuthState { | ||||
|   unknown(redirectPath: homePath, allowedPaths: [homePath]), | ||||
|   unknown(redirectPath: homePage, allowedPaths: [homePage]), | ||||
|   unauthenticated( | ||||
|     redirectPath: authPath, | ||||
|     allowedPaths: [authPath, settingsPath], | ||||
|     redirectPath: authPage, | ||||
|     allowedPaths: [authPage, settingsPage], | ||||
|   ), | ||||
|   authenticated(redirectPath: homePath, allowedPaths: null); | ||||
|   authenticated(redirectPath: homePage, allowedPaths: null); | ||||
|  | ||||
|   const AuthState({required this.redirectPath, required this.allowedPaths}); | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:go_router/go_router.dart'; | ||||
| import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||||
| import 'package:moneymgr_mobile/routes/login/login_screens.dart'; | ||||
| import 'package:moneymgr_mobile/routes/login/login_screen.dart'; | ||||
| import 'package:moneymgr_mobile/routes/settings/settings_screen.dart'; | ||||
| import 'package:moneymgr_mobile/services/auth_state.dart'; | ||||
| import 'package:moneymgr_mobile/services/router/routes_list.dart'; | ||||
| import 'package:moneymgr_mobile/widgets/scaffold_with_navigation.dart'; | ||||
| @@ -58,11 +59,11 @@ GoRouter router(Ref ref) { | ||||
|     debugLogDiagnostics: true, | ||||
|     initialLocation: navigationItems.first.path, | ||||
|     routes: [ | ||||
|       GoRoute(path: homePath, builder: (_, __) => const Scaffold()), | ||||
|       GoRoute(path: authPath, builder: (_, __) => const LoginScreen()), | ||||
|       GoRoute(path: homePage, builder: (_, __) => const Scaffold()), | ||||
|       GoRoute(path: authPage, builder: (_, __) => const LoginScreen()), | ||||
|       GoRoute( | ||||
|         path: settingsPath, | ||||
|         builder: (_, __) => const Text("settings screen"), | ||||
|         path: settingsPage, | ||||
|         builder: (_, __) => const SettingsScreen(), | ||||
|       ), | ||||
|  | ||||
|       // Configuration for the bottom navigation bar routes. The routes themselves | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| const homePath = "/"; | ||||
| const homePage = "/"; | ||||
|  | ||||
| /// Authentication path | ||||
| const authPath = "/login"; | ||||
| const authPage = "/login"; | ||||
|  | ||||
| /// Settings path | ||||
| const settingsPath = "/settings"; | ||||
| const settingsPage = "/settings"; | ||||
| @@ -25,7 +25,8 @@ extension BuildContextX on BuildContext { | ||||
|   void showAppLicensePage() => showLicensePage( | ||||
|     context: this, | ||||
|     useRootNavigator: true, | ||||
|     applicationName: 'DummyMart', | ||||
|     applicationName: 'MoneyMgr', | ||||
|     applicationLegalese: '(c) Pierre HUBERT 2025 - ${DateTime.now().year}' | ||||
|   ); | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user