967121113e
- Implemented inventory screen to display items with details. - Added create, edit, and consume inventory screens for managing items. - Introduced consumption history screen to track item usage. - Created inventory repository and providers for API interactions. - Enhanced routing to include inventory-related paths. - Added necessary models for inventory items and consumption history. - Integrated error handling and loading states for better user experience.
128 lines
3.4 KiB
Dart
128 lines
3.4 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: '/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,
|
|
});
|
|
}
|