"use client"; import { useState } from "react"; import { cn } from "@/lib/utils"; import { Check, Package, Loader2 } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; type Item = { id: string; rawName: string; quantity: string | null; unit: string | null; aisle: string | null; checked: boolean; }; export function ShoppingListView({ listId, initialItems, }: { listId: string; initialItems: Item[]; }) { const [items, setItems] = useState(initialItems); const [movingToPantry, setMovingToPantry] = useState(false); const checkedItems = items.filter((i) => i.checked); async function moveToPantry() { if (checkedItems.length === 0) return; setMovingToPantry(true); try { const res = await fetch("/api/v1/pantry/bulk", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items: checkedItems.map((i) => ({ rawName: i.rawName, quantity: i.quantity ?? undefined, unit: i.unit ?? undefined, })), }), }); if (!res.ok) { toast.error("Failed to move items to pantry"); return; } toast.success(`${checkedItems.length} item${checkedItems.length !== 1 ? "s" : ""} added to pantry`); } finally { setMovingToPantry(false); } } async function toggleItem(item: Item) { const next = !item.checked; setItems((prev) => prev.map((i) => i.id === item.id ? { ...i, checked: next } : i)); await fetch(`/api/v1/shopping-lists/${listId}/items/${item.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ checked: next }), }); } const grouped = items.reduce>((acc, item) => { const key = item.aisle ?? "Other"; (acc[key] ??= []).push(item); return acc; }, {}); const checkedCount = items.filter((i) => i.checked).length; if (items.length === 0) { return

This list is empty.

; } return (

{checkedCount}/{items.length} checked

{checkedCount > 0 && ( )}
{Object.entries(grouped).sort(([a], [b]) => a.localeCompare(b)).map(([aisle, aisleItems]) => (
{Object.keys(grouped).length > 1 && (

{aisle}

)}
{aisleItems.map((item) => ( ))}
))}
); }