From 465f7153a42ceaa3298c090f34c00c6c552f1428 Mon Sep 17 00:00:00 2001 From: Thatsaphorn Atchariyaphap Date: Sat, 27 Sep 2025 14:21:48 +0200 Subject: [PATCH] Cleanup --- finlog_app/app/assets/i18n/de.i18n.json | 4 +- finlog_app/app/assets/i18n/en.i18n.json | 4 +- .../app/lib/core/i18n/translations.g.dart | 4 +- .../app/lib/core/i18n/translations_de.g.dart | 8 +- .../app/lib/core/i18n/translations_en.g.dart | 16 +- finlog_app/app/lib/modules/app_shell.dart | 282 ++++++++++-------- ...gs_view.dart => design_settings_view.dart} | 6 +- .../modules/app/features_settings_view.dart | 12 +- ...l.dart => design_settings_view_model.dart} | 3 - .../lib/modules/settings/settings_view.dart | 121 ++++---- 10 files changed, 258 insertions(+), 202 deletions(-) rename finlog_app/app/lib/modules/settings/modules/app/{app_settings_view.dart => design_settings_view.dart} (97%) rename finlog_app/app/lib/modules/settings/modules/app/model/{app_settings_view_model.dart => design_settings_view_model.dart} (95%) diff --git a/finlog_app/app/assets/i18n/de.i18n.json b/finlog_app/app/assets/i18n/de.i18n.json index e0ed9cf..cea4fd0 100644 --- a/finlog_app/app/assets/i18n/de.i18n.json +++ b/finlog_app/app/assets/i18n/de.i18n.json @@ -13,9 +13,11 @@ "title": "Budgets" }, "app": { + "navigationCar": "Auto", "navigationSettings": "Einstellungen", "navigationDashboard": "Dashboard", "navigationBudgets": "Budgets", + "navigationHousehold": "Haushalt", "navigationInventory": "Inventar", "navigationReports": "Berichte", "tooltipMenu": "Menü", @@ -27,7 +29,6 @@ }, "settings": { "title": "Einstellungen", - "featureSettings": "Funktionseinstellungen", "sections": { "account": "Konto & Daten", "app": "App", @@ -35,6 +36,7 @@ }, "items": { "appSettings": "App-Einstellungen", + "designSettings": "Design-Einstellungen", "personalData": "Persönliche Daten", "accountManagement": "Kontoverwaltung", "helpCenter": "Hilfe", diff --git a/finlog_app/app/assets/i18n/en.i18n.json b/finlog_app/app/assets/i18n/en.i18n.json index 6386f66..bb99310 100644 --- a/finlog_app/app/assets/i18n/en.i18n.json +++ b/finlog_app/app/assets/i18n/en.i18n.json @@ -13,8 +13,10 @@ "title": "Budgets" }, "app": { + "navigationCar": "Car", "navigationSettings": "Settings", "navigationDashboard": "Dashboard", + "navigationHousehold": "Household", "navigationBudgets": "Budgets", "navigationInventory": "Inventory", "navigationReports": "Reports", @@ -27,7 +29,6 @@ }, "settings": { "title": "Settings", - "featureSettings": "Feature Settings", "sections": { "account": "Account & Data", "app": "App", @@ -35,6 +36,7 @@ }, "items": { "appSettings": "App settings", + "designSettings": "Design settings", "personalData": "Personal data", "accountManagement": "Account management", "helpCenter": "Help", diff --git a/finlog_app/app/lib/core/i18n/translations.g.dart b/finlog_app/app/lib/core/i18n/translations.g.dart index 266a8c0..7514cac 100644 --- a/finlog_app/app/lib/core/i18n/translations.g.dart +++ b/finlog_app/app/lib/core/i18n/translations.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 2 -/// Strings: 122 (61 per locale) +/// Strings: 126 (63 per locale) /// -/// Built on 2025-09-27 at 11:35 UTC +/// Built on 2025-09-27 at 12:19 UTC // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/finlog_app/app/lib/core/i18n/translations_de.g.dart b/finlog_app/app/lib/core/i18n/translations_de.g.dart index 210bd88..4aa049c 100644 --- a/finlog_app/app/lib/core/i18n/translations_de.g.dart +++ b/finlog_app/app/lib/core/i18n/translations_de.g.dart @@ -85,9 +85,11 @@ class _TranslationsAppDe implements TranslationsAppEn { final TranslationsDe _root; // ignore: unused_field // Translations + @override String get navigationCar => 'Auto'; @override String get navigationSettings => 'Einstellungen'; @override String get navigationDashboard => 'Dashboard'; @override String get navigationBudgets => 'Budgets'; + @override String get navigationHousehold => 'Haushalt'; @override String get navigationInventory => 'Inventar'; @override String get navigationReports => 'Berichte'; @override String get tooltipMenu => 'Menü'; @@ -106,7 +108,6 @@ class _TranslationsSettingsDe implements TranslationsSettingsEn { // Translations @override String get title => 'Einstellungen'; - @override String get featureSettings => 'Funktionseinstellungen'; @override late final _TranslationsSettingsSectionsDe sections = _TranslationsSettingsSectionsDe._(_root); @override late final _TranslationsSettingsItemsDe items = _TranslationsSettingsItemsDe._(_root); @override late final _TranslationsSettingsMessagesDe messages = _TranslationsSettingsMessagesDe._(_root); @@ -150,6 +151,7 @@ class _TranslationsSettingsItemsDe implements TranslationsSettingsItemsEn { // Translations @override String get appSettings => 'App-Einstellungen'; + @override String get designSettings => 'Design-Einstellungen'; @override String get personalData => 'Persönliche Daten'; @override String get accountManagement => 'Kontoverwaltung'; @override String get helpCenter => 'Hilfe'; @@ -291,9 +293,11 @@ extension on TranslationsDe { case 'login.success': return 'Login erfolgreich'; case 'dashboard.welcome': return 'Dashboard – Willkommen bei Finlog'; case 'budget.title': return 'Budgets'; + case 'app.navigationCar': return 'Auto'; case 'app.navigationSettings': return 'Einstellungen'; case 'app.navigationDashboard': return 'Dashboard'; case 'app.navigationBudgets': return 'Budgets'; + case 'app.navigationHousehold': return 'Haushalt'; case 'app.navigationInventory': return 'Inventar'; case 'app.navigationReports': return 'Berichte'; case 'app.tooltipMenu': return 'Menü'; @@ -303,11 +307,11 @@ extension on TranslationsDe { case 'app.tooltipExpandRail': return 'Leiste erweitern'; case 'app.drawerSettings': return 'Einstellungen'; case 'settings.title': return 'Einstellungen'; - case 'settings.featureSettings': return 'Funktionseinstellungen'; case 'settings.sections.account': return 'Konto & Daten'; case 'settings.sections.app': return 'App'; case 'settings.sections.help': return 'Hilfe & Rechtliches'; case 'settings.items.appSettings': return 'App-Einstellungen'; + case 'settings.items.designSettings': return 'Design-Einstellungen'; case 'settings.items.personalData': return 'Persönliche Daten'; case 'settings.items.accountManagement': return 'Kontoverwaltung'; case 'settings.items.helpCenter': return 'Hilfe'; diff --git a/finlog_app/app/lib/core/i18n/translations_en.g.dart b/finlog_app/app/lib/core/i18n/translations_en.g.dart index 6fbca5d..373e32e 100644 --- a/finlog_app/app/lib/core/i18n/translations_en.g.dart +++ b/finlog_app/app/lib/core/i18n/translations_en.g.dart @@ -104,12 +104,18 @@ class TranslationsAppEn { // Translations + /// en: 'Car' + String get navigationCar => 'Car'; + /// en: 'Settings' String get navigationSettings => 'Settings'; /// en: 'Dashboard' String get navigationDashboard => 'Dashboard'; + /// en: 'Household' + String get navigationHousehold => 'Household'; + /// en: 'Budgets' String get navigationBudgets => 'Budgets'; @@ -149,9 +155,6 @@ class TranslationsSettingsEn { /// en: 'Settings' String get title => 'Settings'; - /// en: 'Feature Settings' - String get featureSettings => 'Feature Settings'; - late final TranslationsSettingsSectionsEn sections = TranslationsSettingsSectionsEn._(_root); late final TranslationsSettingsItemsEn items = TranslationsSettingsItemsEn._(_root); late final TranslationsSettingsMessagesEn messages = TranslationsSettingsMessagesEn._(_root); @@ -204,6 +207,9 @@ class TranslationsSettingsItemsEn { /// en: 'App settings' String get appSettings => 'App settings'; + /// en: 'Design settings' + String get designSettings => 'Design settings'; + /// en: 'Personal data' String get personalData => 'Personal data'; @@ -418,8 +424,10 @@ extension on Translations { case 'login.success': return 'Logged in successfully'; case 'dashboard.welcome': return 'Dashboard – Welcome to Finlog'; case 'budget.title': return 'Budgets'; + case 'app.navigationCar': return 'Car'; case 'app.navigationSettings': return 'Settings'; case 'app.navigationDashboard': return 'Dashboard'; + case 'app.navigationHousehold': return 'Household'; case 'app.navigationBudgets': return 'Budgets'; case 'app.navigationInventory': return 'Inventory'; case 'app.navigationReports': return 'Reports'; @@ -430,11 +438,11 @@ extension on Translations { case 'app.tooltipExpandRail': return 'Expand Rail'; case 'app.drawerSettings': return 'Settings'; case 'settings.title': return 'Settings'; - case 'settings.featureSettings': return 'Feature Settings'; case 'settings.sections.account': return 'Account & Data'; case 'settings.sections.app': return 'App'; case 'settings.sections.help': return 'Help & Legal'; case 'settings.items.appSettings': return 'App settings'; + case 'settings.items.designSettings': return 'Design settings'; case 'settings.items.personalData': return 'Personal data'; case 'settings.items.accountManagement': return 'Account management'; case 'settings.items.helpCenter': return 'Help'; diff --git a/finlog_app/app/lib/modules/app_shell.dart b/finlog_app/app/lib/modules/app_shell.dart index dc3764c..d858845 100644 --- a/finlog_app/app/lib/modules/app_shell.dart +++ b/finlog_app/app/lib/modules/app_shell.dart @@ -1,6 +1,9 @@ +import 'package:app/core/app/router.dart'; +import 'package:app/core/features/feature_controller.dart'; import 'package:app/core/i18n/translations.g.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:provider/provider.dart'; class AppShell extends StatefulWidget { final Widget child; @@ -12,7 +15,7 @@ class AppShell extends StatefulWidget { } class _AppShellState extends State { - static const double _breakpoint = 800; // Tablet/Desktop threshold + static const double _breakpoint = 800; final FocusNode _contentFocus = FocusNode(debugLabel: 'contentFocus'); @override @@ -23,7 +26,7 @@ class _AppShellState extends State { // --- NAV ITEMS ------------------------------------------------------------- - // Desktop/Tablet drawer items (you can keep them rich/longer here) + // Desktop/Tablet drawer items List<({IconData icon, IconData? selectedIcon, String label, String route})> _getDesktopItems(BuildContext context) { final t = Translations.of(context); @@ -32,46 +35,61 @@ class _AppShellState extends State { icon: Icons.dashboard_outlined, selectedIcon: Icons.dashboard, label: t.app.navigationDashboard, - route: '/', + route: AppRoute.home.path, ), ( icon: Icons.account_balance_wallet_outlined, selectedIcon: Icons.account_balance_wallet, - label: t.app.navigationBudgets, - route: '/budget', + label: t.app.navigationBudgets, // Haushaltsbereich inkl. Budget + route: AppRoute.budget.path, ), ( icon: Icons.inventory_2_outlined, selectedIcon: Icons.inventory_2, label: t.app.navigationInventory, - route: '/inventory', + route: AppRoute.inventory.path, ), ( icon: Icons.bar_chart_outlined, selectedIcon: Icons.bar_chart, label: t.app.navigationReports, - route: '/reports', + route: AppRoute.reports.path, ), ( icon: Icons.settings_outlined, selectedIcon: Icons.settings, label: t.app.navigationSettings, - route: '/settings', + route: AppRoute.settings.path, ), ]; } - // Mobile bottom bar items (exactly the four you asked for) + // Mobile bottom bar items (4 Tabs) List<({IconData icon, String label, String route})> _getMobileTabs( BuildContext context, ) { final t = Translations.of(context); return [ - (icon: Icons.dashboard, label: t.app.navigationDashboard, route: '/home'), - // “Haushalt (inkl. Budget)” → map to /budget for now - (icon: Icons.home, label: 'Haushalt', route: '/budget'), - (icon: Icons.inventory_2, label: 'Inventar', route: '/inventory'), - (icon: Icons.directions_car, label: 'Auto', route: '/car'), + ( + icon: Icons.dashboard, + label: t.app.navigationDashboard, + route: AppRoute.home.path, + ), + ( + icon: Icons.home, + label: (t.app.navigationHousehold), + route: AppRoute.budget.path, + ), + ( + icon: Icons.inventory_2, + label: t.app.navigationInventory, + route: AppRoute.inventory.path, + ), + ( + icon: Icons.directions_car, + label: (t.app.navigationCar), + route: AppRoute.car.path, + ), ]; } @@ -82,13 +100,18 @@ class _AppShellState extends State { return 0; } - void _goForIndex( - BuildContext ctx, - int i, - List items, - String Function(T) routeOf, - ) { - ctx.go(routeOf(items[i])); + // Route→Feature-Guard + bool _routeEnabled(String route, FeatureController fc) { + if (route.startsWith(AppRoute.home.path)) return true; + if (route.startsWith(AppRoute.settings.path)) return true; + + if (route.startsWith(AppRoute.budget.path)) return fc.hasHousehold; + if (route.startsWith(AppRoute.inventory.path)) return fc.hasInventory; + if (route.startsWith(AppRoute.car.path)) return fc.hasCar; + if (route.startsWith(AppRoute.reports.path)) return fc.hasReports; + + // Default: sichtbar + return true; } @override @@ -107,16 +130,8 @@ class _AppShellState extends State { final appBar = AppBar( title: const _LogoHeader(), - // On desktop we use a persistent drawer, so no burger button. - leading: isDesktop - ? null - : Builder( - builder: (ctx) => IconButton( - icon: const Icon(Icons.menu), - onPressed: () => Scaffold.of(ctx).openDrawer(), - tooltip: t.app.tooltipMenu, - ), - ), + // Kein Burger-Button, da mobil ohne Drawer (BottomNav) und Desktop mit persistentem Drawer + leading: null, actions: [ IconButton( tooltip: t.app.tooltipNotifications, @@ -125,7 +140,7 @@ class _AppShellState extends State { ), IconButton( tooltip: t.app.tooltipUserSettings, - onPressed: () => context.push('/settings'), + onPressed: () => context.push(AppRoute.settings.path), icon: const Icon(Icons.account_circle_outlined), ), ], @@ -133,21 +148,67 @@ class _AppShellState extends State { if (!isDesktop) { // ------------------- MOBILE: Bottom Navigation ------------------- - final tabs = _getMobileTabs(context); - final selected = _indexForPath(currentPath, tabs, (it) => it.route); + final fc = context.read(); + + // Wenn aktuelle Route deaktiviert ist, sanft nach Home umleiten + WidgetsBinding.instance.addPostFrameCallback((_) { + final p = GoRouterState.of(context).matchedLocation; + if (!_routeEnabled(p, fc)) { + if (mounted) context.go(AppRoute.home.path); + } + }); return Scaffold( appBar: appBar, - // Keep drawer for mobile? You asked for bottom bar instead — remove drawer. body: SafeArea(child: widget.child), - bottomNavigationBar: NavigationBar( - selectedIndex: selected, - onDestinationSelected: (i) => - _goForIndex(context, i, tabs, (it) => it.route), - destinations: [ - for (final it in tabs) - NavigationDestination(icon: Icon(it.icon), label: it.label), - ], + bottomNavigationBar: AnimatedBuilder( + animation: fc, + builder: (context, _) { + final baseTabs = _getMobileTabs(context); + + // Erlaubte Tabs filtern + var tabs = <({IconData icon, String label, String route})>[ + for (final it in baseTabs) + if (_routeEnabled(it.route, fc)) it, + ]; + + // Fallback: min. 2 Ziele sicherstellen + if (tabs.length < 2) { + // Home ist immer erlaubt; „Einstellungen“ als zweites Ziel ergänzen + tabs = [ + // Stelle sicher, dass Home als erstes drin ist + ( + icon: Icons.dashboard, + label: Translations.of(context).app.navigationDashboard, + route: AppRoute.home.path, + ), + ( + icon: Icons.settings, + label: Translations.of(context).app.navigationSettings, + route: AppRoute.settings.path, + ), + ]; + } + + // aktuellen Index robust bestimmen + final currentPath = GoRouterState.of(context).matchedLocation; + int selected = 0; + for (var i = 0; i < tabs.length; i++) { + if (currentPath.startsWith(tabs[i].route)) { + selected = i; + break; + } + } + + return NavigationBar( + selectedIndex: selected, + onDestinationSelected: (i) => context.go(tabs[i].route), + destinations: [ + for (final it in tabs) + NavigationDestination(icon: Icon(it.icon), label: it.label), + ], + ); + }, ), ); } @@ -194,87 +255,74 @@ class _DesktopDrawer extends StatelessWidget { @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; + final fc = context.read(); - return Material( - elevation: 0, - child: SafeArea( - child: ListTileTheme( - selectedColor: scheme.onSecondaryContainer, - selectedTileColor: scheme.secondaryContainer, - child: ListView( - padding: const EdgeInsets.symmetric(vertical: 8), - children: [ - const _LogoHeader(), - const Divider(), - for (var i = 0; i < items.length; i++) - ListTile( - selected: i == selectedIndex, - leading: Icon( - i == selectedIndex - ? (items[i].selectedIcon ?? items[i].icon) - : items[i].icon, - ), - title: Text(items[i].label), - onTap: () => context.go(items[i].route), - ), - ], - ), - ), - ), - ); - } -} + bool routeEnabled(String route) { + if (route.startsWith(AppRoute.home.path)) return true; + if (route.startsWith(AppRoute.settings.path)) return true; -class _AppDrawer extends StatelessWidget { - final List< - ({IconData icon, IconData? selectedIcon, String label, String route}) - > - items; - final int selectedIndex; + if (route.startsWith(AppRoute.budget.path)) return fc.hasHousehold; + if (route.startsWith(AppRoute.inventory.path)) return fc.hasInventory; + if (route.startsWith(AppRoute.car.path)) return fc.hasCar; + if (route.startsWith(AppRoute.reports.path)) return fc.hasReports; - const _AppDrawer({required this.items, required this.selectedIndex}); + return true; + } - @override - Widget build(BuildContext context) { - final scheme = Theme.of(context).colorScheme; + return AnimatedBuilder( + animation: fc, + builder: (context, _) { + final visibleItems = [ + for (final it in items) + if (routeEnabled(it.route)) it, + ]; - return Drawer( - child: SafeArea( - child: ListTileTheme( - selectedColor: scheme.onSecondaryContainer, - selectedTileColor: scheme.secondaryContainer, - child: ListView( - padding: const EdgeInsets.symmetric(vertical: 8), - children: [ - const _LogoHeader(), - const Divider(), - for (var i = 0; i < items.length; i++) - ListTile( - selected: i == selectedIndex, - leading: Icon( - i == selectedIndex - ? (items[i].selectedIcon ?? items[i].icon) - : items[i].icon, - ), - title: Text(items[i].label), - onTap: () { - Navigator.of(context).maybePop(); - context.go(items[i].route); - }, - ), - const Divider(), - ListTile( - leading: const Icon(Icons.settings_outlined), - title: Text(Translations.of(context).app.drawerSettings), - onTap: () { - Navigator.of(context).maybePop(); - context.go('/settings'); - }, + final currentPath = GoRouterState.of(context).matchedLocation; + int safeSelected = 0; + for (var i = 0; i < visibleItems.length; i++) { + if (currentPath.startsWith(visibleItems[i].route)) { + safeSelected = i; + break; + } + } + + return Material( + elevation: 0, + child: SafeArea( + child: ListTileTheme( + selectedColor: scheme.onSecondaryContainer, + selectedTileColor: scheme.secondaryContainer, + child: ListView( + padding: const EdgeInsets.symmetric(vertical: 8), + children: [ + const _LogoHeader(), + const Divider(), + for (var i = 0; i < visibleItems.length; i++) + ListTile( + selected: i == safeSelected, + leading: Icon( + i == safeSelected + ? (visibleItems[i].selectedIcon ?? + visibleItems[i].icon) + : visibleItems[i].icon, + ), + title: Text(visibleItems[i].label), + onTap: () => context.go(visibleItems[i].route), + ), + // Optional: Settings als fixer Eintrag, + // falls du ihn unabhängig von items immer unten haben willst: + // const Divider(), + // ListTile( + // leading: const Icon(Icons.settings_outlined), + // title: Text(t.app.navigationSettings), + // onTap: () => context.go(AppRoute.settings.path), + // ), + ], ), - ], + ), ), - ), - ), + ); + }, ); } } diff --git a/finlog_app/app/lib/modules/settings/modules/app/app_settings_view.dart b/finlog_app/app/lib/modules/settings/modules/app/design_settings_view.dart similarity index 97% rename from finlog_app/app/lib/modules/settings/modules/app/app_settings_view.dart rename to finlog_app/app/lib/modules/settings/modules/app/design_settings_view.dart index 35c3f47..d9ebf27 100644 --- a/finlog_app/app/lib/modules/settings/modules/app/app_settings_view.dart +++ b/finlog_app/app/lib/modules/settings/modules/app/design_settings_view.dart @@ -2,12 +2,12 @@ import 'package:app/core/i18n/translations.g.dart'; import 'package:app/core/ui/controller/locale_controller.dart'; import 'package:app/core/ui/controller/scale_controller.dart'; import 'package:app/core/ui/controller/theme.dart'; -import 'package:app/modules/settings/modules/app/model/app_settings_view_model.dart'; +import 'package:app/modules/settings/modules/app/model/design_settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -class AppSettingsView extends StatelessWidget { - const AppSettingsView({super.key}); +class DesignSettingsView extends StatelessWidget { + const DesignSettingsView({super.key}); @override Widget build(BuildContext context) { diff --git a/finlog_app/app/lib/modules/settings/modules/app/features_settings_view.dart b/finlog_app/app/lib/modules/settings/modules/app/features_settings_view.dart index ad9918b..bd47d3c 100644 --- a/finlog_app/app/lib/modules/settings/modules/app/features_settings_view.dart +++ b/finlog_app/app/lib/modules/settings/modules/app/features_settings_view.dart @@ -3,26 +3,20 @@ import 'package:app/modules/settings/modules/app/model/feature_settings_view_mod import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:app/core/i18n/translations.g.dart'; - /// A dedicated section under "Einstellungen" to enable/disable features. /// You can link this screen from your existing Settings list. /// If you keep a single Settings page, render _FeatureSettingsSection in-place. -class FeatureSettingsView extends StatelessWidget { - const FeatureSettingsView({super.key}); +class AppSettingsView extends StatelessWidget { + const AppSettingsView({super.key}); @override Widget build(BuildContext context) { - final t = Translations.of(context); final featureController = context.read(); final model = FeatureSettingsViewModel(featureController); return ChangeNotifierProvider( create: (BuildContext context) => model, - child: Scaffold( - appBar: AppBar(title: Text(t.settings.featureSettings)), - body: const _FeatureSettingsSection(), - ), + child: Scaffold(body: const _FeatureSettingsSection()), ); } } diff --git a/finlog_app/app/lib/modules/settings/modules/app/model/app_settings_view_model.dart b/finlog_app/app/lib/modules/settings/modules/app/model/design_settings_view_model.dart similarity index 95% rename from finlog_app/app/lib/modules/settings/modules/app/model/app_settings_view_model.dart rename to finlog_app/app/lib/modules/settings/modules/app/model/design_settings_view_model.dart index 4b3594a..9278a3b 100644 --- a/finlog_app/app/lib/modules/settings/modules/app/model/app_settings_view_model.dart +++ b/finlog_app/app/lib/modules/settings/modules/app/model/design_settings_view_model.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; class AppSettingsViewModel extends ChangeNotifier { bool _isLoading = false; - bool _isSaving = false; final ThemeController _theme; final ScaleController _scale; @@ -53,6 +52,4 @@ class AppSettingsViewModel extends ChangeNotifier { TextScalePref get textScale => _scale.scale; bool get isLoading => _isLoading; - - bool get isSaving => _isSaving; } diff --git a/finlog_app/app/lib/modules/settings/settings_view.dart b/finlog_app/app/lib/modules/settings/settings_view.dart index a473f3a..e393075 100644 --- a/finlog_app/app/lib/modules/settings/settings_view.dart +++ b/finlog_app/app/lib/modules/settings/settings_view.dart @@ -1,6 +1,6 @@ import 'package:app/core/i18n/translations.g.dart'; import 'package:app/core/ui/panel.dart'; -import 'package:app/modules/settings/modules/app/app_settings_view.dart'; +import 'package:app/modules/settings/modules/app/design_settings_view.dart'; import 'package:app/modules/settings/modules/app/features_settings_view.dart'; import 'package:app/modules/settings/modules/help/feedback_view.dart'; import 'package:app/modules/settings/modules/help/help_view.dart'; @@ -14,10 +14,7 @@ class SettingsView extends StatelessWidget { @override Widget build(BuildContext context) { - final t = Translations.of(context); - return Scaffold( - // appBar: AppBar(title: Text(t.settings.title)), body: PanelNavigator(rootBuilder: (ctx) => _CategoryList()), ); } @@ -55,65 +52,69 @@ class _CategoryList extends StatelessWidget { ); } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _SectionHeader(t.settings.sections.app), - tile( - Icons.tune, - t.settings.items.appSettings, - () => const AppSettingsView(), - ), - const SizedBox(height: 12), - tile( - Icons.tune, - t.settings.featureSettings, - () => const FeatureSettingsView(), - ), - const SizedBox(height: 12), + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _SectionHeader(t.settings.sections.app), + tile( + Icons.tune, + t.settings.items.appSettings, + () => const AppSettingsView(), + ), + const SizedBox(height: 12), + tile( + Icons.phone_iphone, + t.settings.items.designSettings, + () => const DesignSettingsView(), + ), + const SizedBox(height: 12), - _SectionHeader(t.settings.sections.account), - tile( - Icons.badge_outlined, - t.settings.items.personalData, - () => const PersonalPanel(), - ), - tile( - Icons.manage_accounts_outlined, - t.settings.items.accountManagement, - () => const AccountPanel(), - ), - const SizedBox(height: 12), + _SectionHeader(t.settings.sections.account), + tile( + Icons.badge_outlined, + t.settings.items.personalData, + () => const PersonalPanel(), + ), + tile( + Icons.manage_accounts_outlined, + t.settings.items.accountManagement, + () => const AccountPanel(), + ), + const SizedBox(height: 12), - _SectionHeader(t.settings.sections.help), - tile( - Icons.help_outline, - t.settings.items.helpCenter, - () => const HelpPanel(), - ), - tile( - Icons.feedback_outlined, - t.settings.items.feedback, - () => const FeedbackPanel(), - ), - tile( - Icons.gavel_outlined, - t.settings.items.legalPrivacy, // "Rechtliches & Datenschutz" - () => const LegalPanel(), - ), - const SizedBox(height: 24), + _SectionHeader(t.settings.sections.help), + tile( + Icons.help_outline, + t.settings.items.helpCenter, + () => const HelpPanel(), + ), + tile( + Icons.feedback_outlined, + t.settings.items.feedback, + () => const FeedbackPanel(), + ), + tile( + Icons.gavel_outlined, + t.settings.items.legalPrivacy, // "Rechtliches & Datenschutz" + () => const LegalPanel(), + ), + const SizedBox(height: 24), - const Divider(), - ListTile( - leading: const Icon(Icons.logout), - title: Text(t.settings.items.logout), - onTap: () { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(t.settings.messages.logoutNotImplemented)), - ); - }, - ), - ], + const Divider(), + ListTile( + leading: const Icon(Icons.logout), + title: Text(t.settings.items.logout), + onTap: () { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(t.settings.messages.logoutNotImplemented), + ), + ); + }, + ), + ], + ), ); } }