Files
recipe-app/flutter/lib/core/ui/app_shell.dart
T

134 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../features/auth/data/auth_providers.dart';
class AppShell extends ConsumerWidget {
final String location;
final Widget child;
const AppShell({
super.key,
required this.location,
required this.child,
});
static const _destinations = [
_AppDestination(
path: '/recipes',
title: 'Recept',
icon: Icons.restaurant_menu,
label: 'Recept',
),
_AppDestination(
path: '/inventory',
title: 'Inventarie',
icon: Icons.inventory_2_outlined,
label: 'Inventarie',
),
_AppDestination(
path: '/baslager',
title: 'Baslager',
icon: Icons.storefront_outlined,
label: 'Baslager',
),
_AppDestination(
path: '/profile',
title: 'Profil',
icon: Icons.person,
label: 'Profil',
),
];
int _selectedIndex() {
final index = _destinations.indexWhere(
(destination) => location.startsWith(destination.path),
);
return index < 0 ? 0 : index;
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedIndex = _selectedIndex();
final selectedDestination = _destinations[selectedIndex];
final isWide = MediaQuery.of(context).size.width >= 900;
Future<void> logout() async {
await ref.read(authStateProvider.notifier).logout();
if (context.mounted) {
context.go('/login');
}
}
void navigateTo(int index) {
final target = _destinations[index].path;
if (target != location && context.mounted) {
context.go(target);
}
}
return Scaffold(
appBar: AppBar(
title: Text(selectedDestination.title),
actions: [
IconButton(
tooltip: 'Logga ut',
icon: const Icon(Icons.logout),
onPressed: logout,
),
],
),
body: isWide
? Row(
children: [
NavigationRail(
selectedIndex: selectedIndex,
onDestinationSelected: navigateTo,
labelType: NavigationRailLabelType.all,
destinations: _destinations
.map(
(destination) => NavigationRailDestination(
icon: Icon(destination.icon),
label: Text(destination.label),
),
)
.toList(),
),
const VerticalDivider(width: 1),
Expanded(child: child),
],
)
: child,
bottomNavigationBar: isWide
? null
: NavigationBar(
selectedIndex: selectedIndex,
onDestinationSelected: navigateTo,
destinations: _destinations
.map(
(destination) => NavigationDestination(
icon: Icon(destination.icon),
label: destination.label,
),
)
.toList(),
),
);
}
}
class _AppDestination {
final String path;
final String title;
final IconData icon;
final String label;
const _AppDestination({
required this.path,
required this.title,
required this.icon,
required this.label,
});
}