"use client"; import { useState } from "react"; import Link from "next/link"; import { deleteProduct } from "@/actions/products"; import AdminBadge from "./design-system/AdminBadge"; type Product = { id: string; name: string; description: string; price: number; type: string; active: boolean; deleted_at?: string | null; brands: { name: string } | { name: string }[]; is_taxable?: boolean; }; type ProductTableBodyProps = { products: Product[]; search: string; statusFilter: "all" | "active" | "inactive"; onSearchChange: (v: string) => void; onStatusChange: (v: "all" | "active" | "inactive") => void; onDeleted: (productId: string) => void; }; export default function ProductTableBody({ products, search, statusFilter, onSearchChange, onStatusChange, onDeleted, }: ProductTableBodyProps) { const [openMenu, setOpenMenu] = useState(null); const [deletingId, setDeletingId] = useState(null); const [confirmDelete, setConfirmDelete] = useState(null); const [deleteError, setDeleteError] = useState(null); const filtered = products.filter((p) => { const matchesSearch = !search || p.name.toLowerCase().includes(search.toLowerCase()) || p.description.toLowerCase().includes(search.toLowerCase()); const matchesStatus = statusFilter === "all" || (statusFilter === "active" && p.active) || (statusFilter === "inactive" && !p.active); return matchesSearch && matchesStatus; }); async function handleDelete(productId: string) { setDeletingId(productId); setDeleteError(null); const result = await deleteProduct(productId, null); setDeletingId(null); setConfirmDelete(null); setOpenMenu(null); if (result.success) { onDeleted(productId); } else { setDeleteError(result.error ?? "Delete failed"); } } return ( <> {/* Filter bar — sits outside in the parent */}
onSearchChange(e.target.value)} className="flex-1 min-w-40 rounded-lg border border-[var(--admin-border)] bg-[var(--admin-card-bg)] px-3 py-2 text-sm text-[var(--admin-text-primary)] outline-none focus:border-[var(--admin-primary)]" />
{(["all", "active", "inactive"] as const).map((f) => ( ))}
{filtered.length}
{/* Delete error banner */} {deleteError && (
{deleteError}
)} {filtered.length === 0 ? ( ) : ( filtered.map((product) => ( {/* Actions */} )) )} ); }
{search || statusFilter !== "all" ? "No products match your search." : "No products found."}
{product.name}
{product.description || No description}
{Array.isArray(product.brands) ? product.brands[0]?.name : product.brands?.name} {product.type} ${Number(product.price).toFixed(2)} {product.active ? "Active" : "Inactive"} {product.is_taxable === false ? ( Non-taxable ) : ( Taxable )}
Edit {openMenu === product.id && ( <>
)} {confirmDelete === product.id && ( <> )}