diff --git a/frontend/app/inventory/page.tsx b/frontend/app/inventory/page.tsx index e055c5de..98333ac0 100644 --- a/frontend/app/inventory/page.tsx +++ b/frontend/app/inventory/page.tsx @@ -6,12 +6,11 @@ import { inventoryApi } from '@/lib/api'; import PageShell from '@/components/PageShell'; import Scanner from '@/components/Scanner'; import StatCard from '@/components/StatCard'; +import InventoryTable from '@/components/InventoryTable'; import { useInventoryFilter } from '@/hooks/useInventoryFilter'; import { toast } from 'react-hot-toast'; import { Package, - ChevronRight, - ChevronDown, BarChart3, Layers, Plus, @@ -303,85 +302,23 @@ export default function InventoryPage() { - {/* Categorized List (Accordion) */} -
- {filteredCategories.map(cat => ( -
-
setExpandedCategory(expandedCategory === cat ? null : cat)} - > -
-
- -
-
-

{cat}

-

- {inventory.filter(i => i.category === cat).length} Item types in stock -

-
-
-
- {expandedCategory === cat ? : } - -
-
- - {expandedCategory === cat && ( -
-
- {getFilteredItems(cat).map(item => ( -
setSelectedItem(item)} - className="bg-background/40 border border-slate-800/50 p-4 rounded-2xl flex items-center justify-between hover:border-primary/40 cursor-pointer transition-all active:scale-[0.98]" - > -
-
- -
-
-

{item.name}

-

{item.specs}

-
-
-
- - {item.quantity} - -

Stock

-
-
- ))} -
- )} -
- ))} - - {filteredCategories.length === 0 && ( -
- -

No results found

-
- )} -
+ {/* Inventory Table */} + { + const categoryObj = categoriesList.find(c => c.name === cat); + if (categoryObj) { + setEditingCategory(categoryObj); + setCatEditedName(categoryObj.name); + setCatEditedDesc(categoryObj.description || ''); + } + }} + categoriesList={categoriesList} + /> {/* Stock Adjustment / Edit Item Overlay */} diff --git a/frontend/components/InventoryTable.tsx b/frontend/components/InventoryTable.tsx new file mode 100644 index 00000000..e16ce9eb --- /dev/null +++ b/frontend/components/InventoryTable.tsx @@ -0,0 +1,133 @@ +'use client'; + +import { useState } from 'react'; +import { Item } from '@/lib/db'; +import { ChevronRight, ChevronDown, Layers, Package } from 'lucide-react'; +import { clsx, type ClassValue } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +interface InventoryTableProps { + items: Item[]; + categories: string[]; + expandedCategory: string | null; + onExpandCategory: (category: string | null) => void; + onItemClick: (item: Item) => void; + onEditCategory?: (category: string) => void; + categoriesList?: any[]; +} + +export default function InventoryTable({ + items, + categories, + expandedCategory, + onExpandCategory, + onItemClick, + onEditCategory, + categoriesList = [] +}: InventoryTableProps) { + if (categories.length === 0) { + return ( +
+ +

No results found

+
+ ); + } + + return ( +
+ {categories.map(cat => { + const categoryItems = items.filter(i => i.category === cat); + return ( +
+
onExpandCategory(expandedCategory === cat ? null : cat)} + > +
+
+ +
+
+

{cat}

+

+ {categoryItems.length} Item types in stock +

+
+
+
+ {expandedCategory === cat ? : } + {onEditCategory && ( + + )} +
+
+ + {expandedCategory === cat && ( +
+
+ {categoryItems.map(item => ( +
onItemClick(item)} + className="bg-background/40 border border-slate-800/50 p-4 rounded-2xl flex items-center justify-between hover:border-primary/40 cursor-pointer transition-all active:scale-[0.98]" + > +
+
+ +
+
+

{item.name}

+

{item.specs}

+
+
+
+ + {item.quantity} + +

Stock

+
+
+ ))} +
+ )} +
+ ); + })} +
+ ); +} + +// EditIcon component (lucide-react equivalent) +function EditIcon({ size = 24 }: { size?: number }) { + return ( + + + + ); +}