feat(inventory): implement swipeable inventory tile and product picker field
This commit is contained in:
@@ -7,6 +7,7 @@ import '../../../core/ui/async_state_views.dart';
|
||||
import '../../auth/data/auth_providers.dart';
|
||||
import '../data/inventory_providers.dart';
|
||||
import '../domain/inventory_item.dart';
|
||||
import 'swipeable_inventory_tile.dart';
|
||||
|
||||
class InventoryScreen extends ConsumerWidget {
|
||||
const InventoryScreen({super.key});
|
||||
@@ -113,7 +114,7 @@ class InventoryScreen extends ConsumerWidget {
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) return filterSection;
|
||||
final item = items[index - 1];
|
||||
return _InventoryTile(item: item);
|
||||
return SwipeableInventoryTile(item: item);
|
||||
},
|
||||
),
|
||||
Positioned(
|
||||
@@ -132,111 +133,4 @@ class InventoryScreen extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _InventoryTile extends StatelessWidget {
|
||||
final InventoryItem item;
|
||||
|
||||
const _InventoryTile({required this.item});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final subtitle = [
|
||||
'${item.quantity} ${item.unit}',
|
||||
if (item.location != null && item.location!.isNotEmpty) item.location!,
|
||||
if (item.bestBeforeDate != null) 'Bäst före: ${_formatDate(item.bestBeforeDate!)}',
|
||||
].join(' · ');
|
||||
|
||||
return ListTile(
|
||||
title: Text(item.productName),
|
||||
subtitle: Text(subtitle),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (item.opened)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(right: 4),
|
||||
child: Chip(
|
||||
label: Text('Öppnad'),
|
||||
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}'),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDate(String iso) {
|
||||
try {
|
||||
final dt = DateTime.parse(iso);
|
||||
return '${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')}';
|
||||
} catch (_) {
|
||||
return iso;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, context))),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user