feat: Add functionality to move inventory items to pantry and enhance pantry management
Test Suite / test (24.15.0) (push) Has been cancelled

- Implemented moveInventoryItemToPantry method in InventoryRepository to facilitate moving items from inventory to pantry.
- Enhanced InventoryScreen with a new header section providing context about the inventory.
- Added a button in SwipeableInventoryTile to move items to pantry with appropriate error handling.
- Introduced movePantryItemToInventory method in PantryRepository to support moving items back to inventory.
- Refactored PantryScreen to rename _addToInventory to _moveToInventory for clarity and updated UI to reflect changes.
- Added AdminPantryItem model to represent pantry items in the admin panel.
- Created AdminPantryPanel for managing pantry items, including moving items to inventory and listing users.
- Developed AdminPrivateProductsPanel for managing private products, allowing promotion to global products.
This commit is contained in:
Nils-Johan Gynther
2026-05-11 09:06:30 +02:00
parent edf9c74e75
commit 84ccabe2fe
27 changed files with 1851 additions and 376 deletions
@@ -6,6 +6,7 @@ import '../../../core/api/guarded_api_call.dart';
import '../../auth/data/auth_providers.dart';
import '../domain/admin_ai_categorize_result.dart';
import '../domain/admin_category_node.dart';
import '../domain/admin_pantry_item.dart';
import '../domain/admin_inventory_item.dart';
import '../domain/admin_product.dart';
import '../domain/ai_model_info.dart';
@@ -177,6 +178,9 @@ class AdminRepository {
Future<List<AdminProduct>> listGlobalProducts() =>
_getList(ProductApiPaths.list, AdminProduct.fromJson, requiresAuth: false);
Future<List<PendingProduct>> listPrivateProducts() =>
_getList(ProductApiPaths.privateList, PendingProduct.fromJson);
Future<List<AdminProduct>> listDeletedProducts() =>
_getList(ProductApiPaths.deleted, AdminProduct.fromJson);
@@ -186,6 +190,13 @@ class AdminRepository {
Future<void> setProductStatus(int productId, String status) =>
_patchVoid(ProductApiPaths.setStatus(productId), {'status': status});
Future<AdminProduct> promotePrivateProduct(int productId) =>
_post<AdminProduct>(
ProductApiPaths.promotePrivate(productId),
body: null,
parse: (d) => AdminProduct.fromJson(Map<String, dynamic>.from(d as Map)),
);
Future<void> setProductCategory(int productId, {required int? categoryId}) =>
_patchVoid(ProductApiPaths.update(productId), {'categoryId': categoryId});
@@ -388,6 +399,29 @@ class AdminRepository {
Future<void> removeAdminInventory(int inventoryId) =>
_deleteVoid(AdminInventoryApiPaths.remove(inventoryId));
Future<void> moveAdminInventoryToPantry(int inventoryId) =>
_postVoid(AdminInventoryApiPaths.moveToPantry(inventoryId));
// ── Admin pantry ──────────────────────────────────────────────────────────
Future<List<AdminPantryItem>> listAdminPantry({int? userId}) {
final params = <String, String>{};
if (userId != null) params['userId'] = '$userId';
final path = params.isEmpty
? PantryApiPaths.adminList
: '${PantryApiPaths.adminList}?${params.entries.map((e) => '${Uri.encodeQueryComponent(e.key)}=${Uri.encodeQueryComponent(e.value)}').join('&')}';
return _getList(path, AdminPantryItem.fromJson);
}
Future<void> removeAdminPantryItem(int pantryItemId) =>
_deleteVoid(PantryApiPaths.adminRemove(pantryItemId));
Future<void> moveAdminPantryToInventory(
int pantryItemId,
Map<String, dynamic> body,
) =>
_postVoid(PantryApiPaths.moveToInventoryAdmin(pantryItemId), body);
Future<void> mergeAdminInventory({
required int sourceInventoryId,
required int targetInventoryId,