feat: Add inventory management feature with CRUD operations

- 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.
This commit is contained in:
Nils-Johan Gynther
2026-04-22 08:12:37 +02:00
parent af1a3cd6eb
commit 967121113e
12 changed files with 1301 additions and 0 deletions
+64
View File
@@ -11,6 +11,12 @@ import '../../features/recipes/presentation/create_recipe_screen.dart';
import '../../features/recipes/presentation/recipe_detail_screen.dart';
import '../../features/recipes/presentation/recipe_edit_screen.dart';
import '../../features/recipes/presentation/recipes_screen.dart';
import '../../features/inventory/presentation/inventory_screen.dart';
import '../../features/inventory/presentation/inventory_detail_screen.dart';
import '../../features/inventory/presentation/create_inventory_screen.dart';
import '../../features/inventory/presentation/inventory_edit_screen.dart';
import '../../features/inventory/presentation/consume_inventory_screen.dart';
import '../../features/inventory/presentation/consumption_history_screen.dart';
final appRouterProvider = Provider<GoRouter>((ref) {
final authState = ref.watch(authStateProvider);
@@ -84,6 +90,60 @@ final appRouterProvider = Provider<GoRouter>((ref) {
return RecipeEditScreen(recipeId: id);
},
),
// Inventory detail routes — outside ShellRoute for full-screen.
// /inventory/create must be listed before /inventory/:id.
GoRoute(
path: '/inventory/create',
builder: (context, state) => const CreateInventoryScreen(),
),
GoRoute(
path: '/inventory/:id',
redirect: (context, state) {
final raw = state.pathParameters['id'] ?? '';
if (int.tryParse(raw) == null) return '/inventory';
return null;
},
builder: (context, state) {
final id = int.parse(state.pathParameters['id']!);
return InventoryDetailScreen(itemId: id);
},
),
GoRoute(
path: '/inventory/:id/edit',
redirect: (context, state) {
final raw = state.pathParameters['id'] ?? '';
if (int.tryParse(raw) == null) return '/inventory';
return null;
},
builder: (context, state) {
final id = int.parse(state.pathParameters['id']!);
return InventoryEditScreen(itemId: id);
},
),
GoRoute(
path: '/inventory/:id/consume',
redirect: (context, state) {
final raw = state.pathParameters['id'] ?? '';
if (int.tryParse(raw) == null) return '/inventory';
return null;
},
builder: (context, state) {
final id = int.parse(state.pathParameters['id']!);
return ConsumeInventoryScreen(itemId: id);
},
),
GoRoute(
path: '/inventory/:id/history',
redirect: (context, state) {
final raw = state.pathParameters['id'] ?? '';
if (int.tryParse(raw) == null) return '/inventory';
return null;
},
builder: (context, state) {
final id = int.parse(state.pathParameters['id']!);
return ConsumptionHistoryScreen(itemId: id);
},
),
// Shell routes — shared AppShell with navigation bar.
ShellRoute(
builder: (context, state, child) {
@@ -94,6 +154,10 @@ final appRouterProvider = Provider<GoRouter>((ref) {
path: '/recipes',
builder: (context, state) => const RecipesScreen(),
),
GoRoute(
path: '/inventory',
builder: (context, state) => const InventoryScreen(),
),
GoRoute(
path: '/profile',
builder: (context, state) => const ProfileScreen(),
+6
View File
@@ -21,6 +21,12 @@ class AppShell extends ConsumerWidget {
icon: Icons.restaurant_menu,
label: 'Recept',
),
_AppDestination(
path: '/inventory',
title: 'Inventarie',
icon: Icons.inventory_2_outlined,
label: 'Inventarie',
),
_AppDestination(
path: '/profile',
title: 'Profil',