From 828efede421c393059dcb20b465cefd12582b89c Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Wed, 1 Apr 2026 17:30:21 -0700 Subject: [PATCH] fix: align frontend InventoryItem type with actual API response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit InventoryItemResponse returns flat fields (product_name, barcode, category) not a nested product object. Frontend interface and templates were using item.product.name / item.product.brand which threw TypeError on render, blanking the inventory tab. - InventoryItem: remove product:Product, add product_name/barcode/category - InventoryStats: fix total_products→available_items, expired→expired_items, items_by_location→locations - item IDs are int not string — update deleteItem/updateItem/consumeItem sigs - EditItemModal, RecipesView, InventoryList: fix all item.product.xxx refs --- frontend/src/components/EditItemModal.vue | 4 ++-- frontend/src/components/InventoryList.vue | 20 ++++++++++---------- frontend/src/components/RecipesView.vue | 2 +- frontend/src/services/api.ts | 21 +++++++++++---------- frontend/src/stores/inventory.ts | 4 ++-- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/frontend/src/components/EditItemModal.vue b/frontend/src/components/EditItemModal.vue index a426f92..3ad5333 100644 --- a/frontend/src/components/EditItemModal.vue +++ b/frontend/src/components/EditItemModal.vue @@ -10,8 +10,8 @@
- {{ item.product.name }} - ({{ item.product.brand }}) + {{ item.product_name || 'Unknown Product' }} + {{ item.category }}
diff --git a/frontend/src/components/InventoryList.vue b/frontend/src/components/InventoryList.vue index 5da5e0b..7b8476f 100644 --- a/frontend/src/components/InventoryList.vue +++ b/frontend/src/components/InventoryList.vue @@ -9,8 +9,8 @@
Total Items
-
{{ stats.total_products }}
-
Unique Products
+
{{ stats.available_items }}
+
Available
{{ store.expiringItems.length }}
@@ -263,8 +263,8 @@ :class="getItemClass(item)" >
-

{{ item.product.name }}

- {{ item.product.brand }} +

{{ item.product_name || 'Unknown Product' }}

+ {{ item.category }}
@@ -485,11 +485,11 @@ async function handleSave() { async function confirmDelete(item: InventoryItem) { showConfirm( - `Are you sure you want to delete ${item.product.name}?`, + `Are you sure you want to delete ${item.product_name || 'item'}?`, async () => { try { await store.deleteItem(item.id) - showToast(`${item.product.name} deleted successfully`, 'success') + showToast(`${item.product_name || 'item'} deleted successfully`, 'success') } catch (err) { showToast('Failed to delete item', 'error') } @@ -504,12 +504,12 @@ async function confirmDelete(item: InventoryItem) { async function markAsConsumed(item: InventoryItem) { showConfirm( - `Mark ${item.product.name} as consumed?`, + `Mark ${item.product_name || 'item'} as consumed?`, async () => { try { await inventoryAPI.consumeItem(item.id) await refreshItems() - showToast(`${item.product.name} marked as consumed`, 'success') + showToast(`${item.product_name || 'item'} marked as consumed`, 'success') } catch (err) { showToast('Failed to mark item as consumed', 'error') } @@ -542,7 +542,7 @@ async function handleScannerGunInput() { const item = result.results[0] scannerResults.value.push({ type: 'success', - message: `✓ Added: ${item.product.name}${item.product.brand ? ' (' + item.product.brand + ')' : ''} to ${scannerLocation.value}`, + message: `✓ Added: ${item.product_name || 'item'}${''} to ${scannerLocation.value}`, }) await refreshItems() } else { @@ -588,7 +588,7 @@ async function handleBarcodeImageSelect(e: Event) { const item = result.results[0] barcodeResults.value.push({ type: 'success', - message: `✓ Found: ${item.product.name}${item.product.brand ? ' (' + item.product.brand + ')' : ''}`, + message: `✓ Found: ${item.product_name || 'item'}${''}`, }) await refreshItems() } else { diff --git a/frontend/src/components/RecipesView.vue b/frontend/src/components/RecipesView.vue index 1b0a7ca..0430084 100644 --- a/frontend/src/components/RecipesView.vue +++ b/frontend/src/components/RecipesView.vue @@ -291,7 +291,7 @@ const pantryItems = computed(() => { if (!b.expiration_date) return -1 return new Date(a.expiration_date).getTime() - new Date(b.expiration_date).getTime() }) - return sorted.map((item) => item.product.name) + return sorted.map((item) => item.product_name).filter(Boolean) as string[] }) // Grocery links relevant to a specific recipe's missing ingredients diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 80ebe27..7713d06 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -80,9 +80,11 @@ export interface Tag { } export interface InventoryItem { - id: string - product_id: string - product: Product + id: number + product_id: number + product_name: string | null + barcode: string | null + category: string | null quantity: number unit: string location: string @@ -109,11 +111,10 @@ export interface InventoryItemUpdate { export interface InventoryStats { total_items: number - total_products: number + available_items: number expiring_soon: number - expired: number - items_by_location: Record - items_by_status: Record + expired_items: number + locations: Record } export interface Receipt { @@ -185,7 +186,7 @@ export const inventoryAPI = { /** * Update an inventory item */ - async updateItem(itemId: string, update: InventoryItemUpdate): Promise { + async updateItem(itemId: number, update: InventoryItemUpdate): Promise { const response = await api.patch(`/inventory/items/${itemId}`, update) return response.data }, @@ -193,7 +194,7 @@ export const inventoryAPI = { /** * Delete an inventory item */ - async deleteItem(itemId: string): Promise { + async deleteItem(itemId: number): Promise { await api.delete(`/inventory/items/${itemId}`) }, @@ -234,7 +235,7 @@ export const inventoryAPI = { /** * Mark item as consumed */ - async consumeItem(itemId: string): Promise { + async consumeItem(itemId: number): Promise { await api.post(`/inventory/items/${itemId}/consume`) }, diff --git a/frontend/src/stores/inventory.ts b/frontend/src/stores/inventory.ts index fe119f5..874c63e 100644 --- a/frontend/src/stores/inventory.ts +++ b/frontend/src/stores/inventory.ts @@ -76,7 +76,7 @@ export const useInventoryStore = defineStore('inventory', () => { } } - async function updateItem(itemId: string, update: InventoryItemUpdate) { + async function updateItem(itemId: number, update: InventoryItemUpdate) { loading.value = true error.value = null @@ -99,7 +99,7 @@ export const useInventoryStore = defineStore('inventory', () => { } } - async function deleteItem(itemId: string) { + async function deleteItem(itemId: number) { loading.value = true error.value = null