feat: update API endpoint for product listing and simplify manual product creation UI
Test Suite / test (24.15.0) (push) Has been cancelled

This commit is contained in:
Nils-Johan Gynther
2026-05-06 10:43:55 +02:00
parent ea44c4fe7a
commit 7a8f441390
2 changed files with 6 additions and 85 deletions
@@ -58,7 +58,7 @@ class _CreateInventoryScreenState
try { try {
final token = await ref.read(authStateProvider.future); final token = await ref.read(authStateProvider.future);
final api = ref.read(apiClientProvider); final api = ref.read(apiClientProvider);
final data = await api.getJson(ProductApiPaths.list, token: token); final data = await api.getJson(ProductApiPaths.mine, token: token);
final list = data is List<dynamic> final list = data is List<dynamic>
? data ? data
: (data is Map<String, dynamic> && data['items'] is List<dynamic>) : (data is Map<String, dynamic> && data['items'] is List<dynamic>)
@@ -3,11 +3,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../../core/api/api_error_mapper.dart'; import '../../../core/api/api_error_mapper.dart';
import '../../../core/api/api_paths.dart';
import '../../../core/api/api_providers.dart';
import '../../../core/l10n/l10n.dart'; import '../../../core/l10n/l10n.dart';
import '../../../core/ui/async_state_views.dart'; import '../../../core/ui/async_state_views.dart';
import '../../auth/data/auth_providers.dart';
import '../data/inventory_providers.dart'; import '../data/inventory_providers.dart';
import 'swipeable_inventory_tile.dart'; import 'swipeable_inventory_tile.dart';
@@ -22,65 +19,6 @@ class InventoryScreen extends ConsumerWidget {
(value: 'bestBeforeDesc', label: context.l10n.inventorySortBestBeforeDesc), (value: 'bestBeforeDesc', label: context.l10n.inventorySortBestBeforeDesc),
]; ];
Future<void> _createManualProduct(BuildContext context, WidgetRef ref) async {
final nameCtrl = TextEditingController();
final created = await showDialog<String>(
context: context,
builder: (dialogContext) => AlertDialog(
title: const Text('Ny produkt'),
content: TextField(
controller: nameCtrl,
autofocus: true,
decoration: const InputDecoration(
labelText: 'Produktnamn',
border: OutlineInputBorder(),
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(dialogContext),
child: Text(context.l10n.cancelAction),
),
FilledButton(
onPressed: () {
final value = nameCtrl.text.trim();
if (value.isEmpty) return;
Navigator.pop(dialogContext, value);
},
child: const Text('Skapa'),
),
],
),
);
nameCtrl.dispose();
if (created == null || created.trim().isEmpty || !context.mounted) return;
try {
final token = ref.read(authStateProvider).maybeWhen(
data: (t) => t,
orElse: () => null,
) ??
await ref.read(authStateProvider.future);
final api = ref.read(apiClientProvider);
await api.postJson(
ProductApiPaths.createPrivate,
body: {'name': created.trim()},
token: token,
);
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Produkt skapad. Lägg nu till den i inventariet.')),
);
context.push('/inventory/create');
} catch (e) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
);
}
}
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final location = ref.watch(inventoryLocationFilterProvider); final location = ref.watch(inventoryLocationFilterProvider);
@@ -158,22 +96,11 @@ class InventoryScreen extends ConsumerWidget {
Positioned( Positioned(
right: 16, right: 16,
bottom: 16, bottom: 16,
child: Column( child: FloatingActionButton.extended(
mainAxisSize: MainAxisSize.min,
children: [
FloatingActionButton.extended(
onPressed: () => context.push('/inventory/create'), onPressed: () => context.push('/inventory/create'),
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
label: Text(context.l10n.addAction), label: Text(context.l10n.addAction),
), ),
const SizedBox(height: 8),
FloatingActionButton.extended(
onPressed: () => _createManualProduct(context, ref),
icon: const Icon(Icons.add_box_outlined),
label: const Text('Ny produkt'),
),
],
),
), ),
], ],
); );
@@ -202,12 +129,6 @@ class InventoryScreen extends ConsumerWidget {
label: Text(context.l10n.addAction), label: Text(context.l10n.addAction),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
FloatingActionButton.extended(
onPressed: () => _createManualProduct(context, ref),
icon: const Icon(Icons.add_box_outlined),
label: const Text('Ny produkt'),
),
const SizedBox(height: 8),
FloatingActionButton.extended( FloatingActionButton.extended(
onPressed: () => context.go('/recipes'), onPressed: () => context.go('/recipes'),
icon: const Icon(Icons.restaurant_menu), icon: const Icon(Icons.restaurant_menu),