diff --git a/flutter/lib/core/ui/app_shell.dart b/flutter/lib/core/ui/app_shell.dart index 6a27c95b..d762855d 100644 --- a/flutter/lib/core/ui/app_shell.dart +++ b/flutter/lib/core/ui/app_shell.dart @@ -5,7 +5,14 @@ import 'package:go_router/go_router.dart'; import '../../features/auth/data/auth_providers.dart'; import '../../features/recipes/data/recipes_grid_provider.dart'; -const _adminDestination = _AppDestination( +const _profileHeaderDestination = _AppDestination( + path: '/profile', + title: 'Profil', + icon: Icons.person, + label: 'Profil', +); + +const _adminHeaderDestination = _AppDestination( path: '/admin', title: 'Admin', icon: Icons.admin_panel_settings_outlined, @@ -53,24 +60,32 @@ class AppShell extends ConsumerWidget { icon: Icons.upload_file_outlined, label: 'Importera', ), - _AppDestination( - path: '/profile', - title: 'Profil', - icon: Icons.person, - label: 'Profil', - ), ]; - List<_AppDestination> _destinations(bool isAdmin) => [ - ..._baseDestinations, - if (isAdmin) _adminDestination, - ]; + List<_AppDestination> _destinations(bool isAdmin) => _baseDestinations; - int _selectedIndex(List<_AppDestination> destinations) { + int? _selectedIndex(List<_AppDestination> destinations) { final index = destinations.indexWhere( (destination) => location.startsWith(destination.path), ); - return index < 0 ? 0 : index; + return index < 0 ? null : index; + } + + _AppDestination _selectedHeaderDestination( + List<_AppDestination> destinations, + bool isAdmin, + ) { + if (location.startsWith('/profile')) { + return _profileHeaderDestination; + } + if (location.startsWith('/admin') && isAdmin) { + return _adminHeaderDestination; + } + final selectedIndex = _selectedIndex(destinations); + if (selectedIndex != null) { + return destinations[selectedIndex]; + } + return destinations.first; } @override @@ -78,7 +93,7 @@ class AppShell extends ConsumerWidget { final isAdmin = ref.watch(isAdminProvider); final dests = _destinations(isAdmin); final selectedIndex = _selectedIndex(dests); - final selectedDestination = dests[selectedIndex]; + final selectedDestination = _selectedHeaderDestination(dests, isAdmin); final isWide = MediaQuery.of(context).size.width >= 900; void navigateTo(int index) { @@ -90,6 +105,7 @@ class AppShell extends ConsumerWidget { final isRecipesRoute = location.startsWith('/recipes') && !location.startsWith('/recipes/'); + final isImportRoute = location == '/import'; Future logout() async { await ref.read(authStateProvider.notifier).logout(); @@ -98,9 +114,23 @@ class AppShell extends ConsumerWidget { } } - return Scaffold( + Widget shell = Scaffold( appBar: AppBar( title: Text(selectedDestination.title), + bottom: isImportRoute + ? const TabBar( + tabs: [ + Tab( + icon: Icon(Icons.restaurant_menu_outlined), + text: 'Recept', + ), + Tab( + icon: Icon(Icons.receipt_long_outlined), + text: 'Kvitto', + ), + ], + ) + : null, actions: [ if (isRecipesRoute) Consumer( @@ -177,7 +207,7 @@ class AppShell extends ConsumerWidget { ? Row( children: [ NavigationRail( - selectedIndex: selectedIndex, + selectedIndex: selectedIndex ?? 0, onDestinationSelected: navigateTo, labelType: NavigationRailLabelType.all, destinations: dests @@ -197,7 +227,7 @@ class AppShell extends ConsumerWidget { bottomNavigationBar: isWide ? null : NavigationBar( - selectedIndex: selectedIndex, + selectedIndex: selectedIndex ?? 0, onDestinationSelected: navigateTo, destinations: dests .map( @@ -209,6 +239,12 @@ class AppShell extends ConsumerWidget { .toList(), ), ); + + if (isImportRoute) { + shell = DefaultTabController(length: 2, child: shell); + } + + return shell; } } diff --git a/flutter/lib/features/admin/presentation/admin_screen.dart b/flutter/lib/features/admin/presentation/admin_screen.dart index 481e6051..bc42794e 100644 --- a/flutter/lib/features/admin/presentation/admin_screen.dart +++ b/flutter/lib/features/admin/presentation/admin_screen.dart @@ -12,12 +12,7 @@ class AdminScreen extends ConsumerStatefulWidget { class _AdminScreenState extends ConsumerState { @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Admin – Användare'), - ), - body: const AdminUsersPanel(), - ); + return const AdminUsersPanel(); } } diff --git a/flutter/lib/features/import/presentation/import_screen.dart b/flutter/lib/features/import/presentation/import_screen.dart index e4d4f7ff..f74274f5 100644 --- a/flutter/lib/features/import/presentation/import_screen.dart +++ b/flutter/lib/features/import/presentation/import_screen.dart @@ -14,42 +14,14 @@ class ImportScreen extends StatefulWidget { State createState() => _ImportScreenState(); } -class _ImportScreenState extends State - with SingleTickerProviderStateMixin { - late final TabController _tabController; - - @override - void initState() { - super.initState(); - _tabController = TabController(length: 2, vsync: this); - } - - @override - void dispose() { - _tabController.dispose(); - super.dispose(); - } - +class _ImportScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const Text('Importera'), - bottom: TabBar( - controller: _tabController, - tabs: const [ - Tab(icon: Icon(Icons.restaurant_menu_outlined), text: 'Recept'), - Tab(icon: Icon(Icons.receipt_long_outlined), text: 'Kvitto'), - ], - ), - ), - body: TabBarView( - controller: _tabController, - children: const [ - RecipeImportTab(), - ReceiptImportTab(), - ], - ), + return const TabBarView( + children: [ + RecipeImportTab(), + ReceiptImportTab(), + ], ); } }