feat: update API endpoint for product listing and simplify manual product creation UI
Test Suite / test (24.15.0) (push) Has been cancelled
Test Suite / test (24.15.0) (push) Has been cancelled
This commit is contained in:
@@ -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,21 +96,10 @@ class InventoryScreen extends ConsumerWidget {
|
|||||||
Positioned(
|
Positioned(
|
||||||
right: 16,
|
right: 16,
|
||||||
bottom: 16,
|
bottom: 16,
|
||||||
child: Column(
|
child: FloatingActionButton.extended(
|
||||||
mainAxisSize: MainAxisSize.min,
|
onPressed: () => context.push('/inventory/create'),
|
||||||
children: [
|
icon: const Icon(Icons.add),
|
||||||
FloatingActionButton.extended(
|
label: Text(context.l10n.addAction),
|
||||||
onPressed: () => context.push('/inventory/create'),
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
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),
|
||||||
|
|||||||
Reference in New Issue
Block a user