feat: add pantry management features including repository, providers, and UI integration

This commit is contained in:
Nils-Johan Gynther
2026-04-22 10:45:37 +02:00
parent f11364b73e
commit dd05fed279
9 changed files with 615 additions and 7 deletions
@@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/api/api_error_mapper.dart';
import '../../../core/ui/async_state_views.dart';
import '../../auth/data/auth_providers.dart';
import '../data/inventory_providers.dart';
import '../domain/inventory_item.dart';
@@ -79,13 +81,35 @@ class _InventoryTile extends StatelessWidget {
return ListTile(
title: Text(item.productName),
subtitle: Text(subtitle),
trailing: item.opened
? const Chip(
label: Text('Öppnad'),
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
)
: null,
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (item.opened)
const Padding(
padding: EdgeInsets.only(right: 4),
child: Chip(
label: Text('Oppnad'),
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
),
),
Tooltip(
message: 'Konsumera',
child: IconButton(
icon: const Icon(Icons.remove_circle_outline),
onPressed: () => context.push('/inventory/${item.id}/consume'),
),
),
Tooltip(
message: 'Redigera',
child: IconButton(
icon: const Icon(Icons.edit_outlined),
onPressed: () => context.push('/inventory/${item.id}/edit'),
),
),
_DeleteInventoryButton(item: item),
],
),
onTap: () => context.push('/inventory/${item.id}'),
);
}
@@ -99,3 +123,53 @@ class _InventoryTile extends StatelessWidget {
}
}
}
class _DeleteInventoryButton extends ConsumerWidget {
final InventoryItem item;
const _DeleteInventoryButton({required this.item});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Tooltip(
message: 'Ta bort',
child: IconButton(
icon: const Icon(Icons.delete_outline, color: Colors.red),
onPressed: () async {
final confirmed = await showDialog<bool>(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Ta bort inventariepost?'),
content: Text('Vill du ta bort "${item.productName}"?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx, false),
child: const Text('Avbryt'),
),
FilledButton(
onPressed: () => Navigator.pop(ctx, true),
child: const Text('Ta bort'),
),
],
),
);
if (confirmed != true) return;
try {
final token = await ref.read(authStateProvider.future);
await ref
.read(inventoryRepositoryProvider)
.deleteInventoryItem(item.id, token: token);
ref.invalidate(inventoryProvider);
} catch (error) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(mapErrorToUserMessage(error))),
);
}
},
),
);
}
}