import { useState, useEffect } from 'react'; import { Plus, Search, ShoppingCart, Package, Filter, AlertCircle, ExternalLink, X, Loader2 } from 'lucide-react'; import { suppliesApi, SupplyItem, SupplyCategory } from '../lib/suppliesApi'; import { PageHeader, EmptyState, CardSkeleton } from '../components/ui/LinearPrimitives'; import { useToast } from '../context/ToastContext'; export default function SuppliesPage() { const { addToast } = useToast(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [view, setView] = useState<'all' | 'shopping'>('all'); const [search, setSearch] = useState(''); const [categoryFilter, setCategoryFilter] = useState('ALL'); const [isAddModalOpen, setIsAddModalOpen] = useState(false); const [newItem, setNewItem] = useState({ name: '', category: 'OTHER' as SupplyCategory, quantity: 0, minThreshold: 1, unit: 'each', location: '', vendor: '', productUrl: '', notes: '' }); useEffect(() => { loadItems(); }, []); const loadItems = async () => { setLoading(true); try { const data = await suppliesApi.getAll(); setItems(data); } catch (error) { console.error('Failed to load supplies', error); } finally { setLoading(false); } }; const handleQuantityAdjust = async (id: string, adjustment: number) => { setItems(current => current.map(item => { if (item.id === id) { return { ...item, quantity: Math.max(0, item.quantity + adjustment) }; } return item; })); try { await suppliesApi.adjustQuantity(id, adjustment); } catch (error) { loadItems(); } }; const handleCreate = async (e: React.FormEvent) => { e.preventDefault(); try { await suppliesApi.create(newItem); setIsAddModalOpen(false); setNewItem({ name: '', category: 'OTHER', quantity: 0, minThreshold: 1, unit: 'each', location: '', vendor: '', productUrl: '', notes: '' }); addToast('Item created', 'success'); loadItems(); } catch (error) { addToast('Failed to create item', 'error'); } }; const handleMarkOrdered = async (id: string) => { try { const updated = await suppliesApi.markOrdered(id); setItems(current => current.map(item => item.id === id ? updated : item)); addToast('Marked as ordered', 'success'); } catch (error) { addToast('Failed to update', 'error'); } }; const shoppingListCount = items.filter(i => i.quantity <= i.minThreshold).length; const filteredItems = items.filter(item => { const matchesSearch = item.name.toLowerCase().includes(search.toLowerCase()) || (item.location && item.location.toLowerCase().includes(search.toLowerCase())) || (item.vendor && item.vendor.toLowerCase().includes(search.toLowerCase())); const matchesCategory = categoryFilter === 'ALL' || item.category === categoryFilter; const matchesView = view === 'all' || (view === 'shopping' && item.quantity <= item.minThreshold); return matchesSearch && matchesCategory && matchesView; }); const categories: SupplyCategory[] = ['FILTER', 'CLEANING', 'PPE', 'OFFICE', 'BATHROOM', 'KITCHEN', 'MAINTENANCE', 'OTHER']; return (
setIsAddModalOpen(true)} className="btn btn-primary" > Add Item } /> {/* View Toggle */}
{/* Filters */}
setSearch(e.target.value)} className="input w-full pl-9" />
{categories.map(cat => ( ))}
{/* Items */} {loading ? (
{Array.from({ length: 6 }).map((_, i) => )}
) : filteredItems.length === 0 ? ( { setSearch(''); setCategoryFilter('ALL'); }} className="text-accent hover:underline text-sm" > Clear filters ) : ( ) } /> ) : (
{filteredItems.map(item => (

{item.name} {item.quantity <= item.minThreshold && ( )}

{item.category.toLowerCase()} {item.location && 📍 {item.location}}
{item.quantity}
{item.unit}
{item.quantity <= item.minThreshold && (
{item.productUrl && ( Buy )}
)}
))}
)} {/* Mobile FAB */} {/* Add Modal */} {isAddModalOpen && (

Add New Item

setNewItem({ ...newItem, name: e.target.value })} placeholder="e.g. 5 Gallon Pots" />
setNewItem({ ...newItem, unit: e.target.value })} placeholder="box, each..." />
setNewItem({ ...newItem, quantity: parseInt(e.target.value) || 0 })} />
setNewItem({ ...newItem, minThreshold: parseInt(e.target.value) || 0 })} />
setNewItem({ ...newItem, vendor: e.target.value })} placeholder="e.g. Amazon" />
setNewItem({ ...newItem, productUrl: e.target.value })} placeholder="https://..." />
setNewItem({ ...newItem, location: e.target.value })} placeholder="e.g. Storage Room A" />
)}
); }