"use client"; import { Loader2, Package, Pencil, Plus, Trash2 } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { createBcItem, deleteBcItem, updateBcItem } from "@/actions/catalog-bc"; import { useConfirmDialog } from "@/components/admin/confirm-dialog"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { useLatestRequest } from "@/features/catalog/client/use-latest-request"; import { useServerAction } from "@/hooks/use-server-action"; interface BcItem { id: number; pageId: number; itemIds: string; catalogName: string; orderNumber: number; extradata: string; } interface BcItemsEditorProps { pageId: number; canEdit: boolean; } export function BcItemsEditor({ pageId, canEdit }: BcItemsEditorProps) { const { confirm, dialog: confirmDialog } = useConfirmDialog(); const requests = useLatestRequest(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); const [editingItem, setEditingItem] = useState(null); const [addingItem, setAddingItem] = useState(false); const load = useCallback(async () => { const request = requests.start(); setError(false); setLoading(true); try { const res = await fetch( `/api/admin/catalog/items?pageId=${pageId}&catalog=bc`, { signal: request.signal }, ); if (!res.ok) throw new Error(); const data = await res.json(); if (!request.isCurrent()) return; setItems(Array.isArray(data.items) ? data.items : []); } catch { if (!request.isCurrent()) return; setError(true); } finally { if (request.isCurrent()) setLoading(false); } }, [pageId, requests]); useEffect(() => { if (pageId > 0) void load(); return () => requests.cancel(); }, [pageId, load, requests]); return (
{confirmDialog}
BC Items ({items.length})
{canEdit && ( )}
{loading ? (
) : error ? (
) : items.length === 0 ? (

No items in this page.

) : (
ID Name Item IDs Order Extra Data {canEdit && ( Actions )} {items.map((item) => ( {item.id} {item.catalogName} {item.itemIds} {item.orderNumber} {item.extradata || "\u2014"} {canEdit && (
)}
))}
)} {editingItem && ( setEditingItem(null)} onSubmit={async (data) => { const result = await updateBcItem({ id: editingItem.id, ...data }); if (result.ok) { setItems((prev) => prev.map((i) => i.id === editingItem.id ? { ...i, ...data } : i, ), ); } return result; }} /> )} {addingItem && ( setAddingItem(false)} onSubmit={async (data) => { const result = await createBcItem({ pageId, ...data }); if (result.ok) await load(); return result; }} /> )}
); } function BcItemDialog({ item, mode, onClose, onSubmit, }: { item: BcItem; mode: "add" | "edit"; onClose: () => void; onSubmit: (data: { itemIds: string; catalogName: string; orderNumber: number; extradata: string; }) => Promise<{ ok: boolean; error?: string }>; }) { const { run, isPending } = useServerAction(); const [form, setForm] = useState({ itemIds: item.itemIds, catalogName: item.catalogName, orderNumber: item.orderNumber, extradata: item.extradata, }); return ( !open && onClose()}> {mode === "add" ? "Add BC Item" : `Edit Item #${item.id}`}
setForm((f) => ({ ...f, catalogName: e.target.value })) } />
setForm((f) => ({ ...f, itemIds: e.target.value })) } />
setForm((f) => ({ ...f, orderNumber: parseInt(e.target.value, 10) || 0, })) } />
setForm((f) => ({ ...f, extradata: e.target.value })) } placeholder="Optional" />
); }