import { useEffect, useState } from "react"; import { AdminButton, AdminBadge } from "@/components/admin/design-system"; import { type WholesaleProduct, deleteWholesaleProduct, saveWholesaleProduct, } from "@/actions/wholesale"; import type { MsgFn } from "./types"; interface ProductsTabProps { products: WholesaleProduct[]; brandId: string; onMsg: MsgFn; onRefresh: () => void; } // Wholesale product catalog management. Create/edit/delete products and their price tiers. export default function ProductsTab({ products, brandId, onMsg, onRefresh }: ProductsTabProps) { const [showForm, setShowForm] = useState(false); const [editing, setEditing] = useState(null); const [form, setForm] = useState({ name: "", description: "", unitType: "each", availability: "available", qtyAvailable: 0, priceTiers: "", hpSku: "", hpItemId: "", handlingInstructions: "", storageWarning: "", productLabel: "", }); const [saving, setSaving] = useState(false); const [openProductActions, setOpenProductActions] = useState(null); const [deletingProduct, setDeletingProduct] = useState(null); // Close product actions dropdown when clicking outside useEffect(() => { function handleClick(e: MouseEvent) { if (!(e.target as Element).closest(".product-actions-cell")) { setOpenProductActions(null); } } document.addEventListener("click", handleClick); return () => document.removeEventListener("click", handleClick); }, []); function toggleProductActions(productId: string, e: React.MouseEvent) { e.stopPropagation(); setOpenProductActions(prev => prev === productId ? null : productId); } async function handleDeleteProduct(productId: string) { if (!confirm("Delete this product? Products attached to order items cannot be deleted. Set availability to unavailable instead.")) return; setDeletingProduct(productId); const result = await deleteWholesaleProduct(productId); setDeletingProduct(null); if (result.success) { onMsg("success", "Product deleted."); onRefresh(); } else { onMsg("error", result.error ?? "Failed to delete product."); } } async function handleSave() { setSaving(true); let tiers: Array<{ min_qty: number; max_qty: number; price: number }> = []; try { tiers = JSON.parse(form.priceTiers || "[]"); } catch {} const result = await saveWholesaleProduct({ brandId, id: editing?.id, name: form.name, description: form.description || undefined, unitType: form.unitType, availability: form.availability, qtyAvailable: form.qtyAvailable, priceTiers: tiers, hpSku: form.hpSku || undefined, hpItemId: form.hpItemId || undefined, handlingInstructions: form.handlingInstructions || undefined, storageWarning: form.storageWarning || undefined, productLabel: form.productLabel || undefined, }); setSaving(false); if (result.success) { onMsg("success", editing ? "Product updated." : "Product created."); setShowForm(false); onRefresh(); } else { onMsg("error", result.error ?? "Failed to save."); } } function openNew() { setEditing(null); setForm({ name: "", description: "", unitType: "each", availability: "available", qtyAvailable: 0, priceTiers: "", hpSku: "", hpItemId: "", handlingInstructions: "", storageWarning: "", productLabel: "" }); setShowForm(true); } function openEdit(p: WholesaleProduct) { setEditing(p); setForm({ name: p.name, description: p.description ?? "", unitType: p.unit_type, availability: p.availability, qtyAvailable: Number(p.qty_available), priceTiers: JSON.stringify(p.price_tiers), hpSku: p.hp_sku ?? "", hpItemId: p.hp_item_id ?? "", handlingInstructions: p.handling_instructions ?? "", storageWarning: p.storage_warning ?? "", productLabel: p.product_label ?? "", }); setShowForm(true); } return (

Wholesale Products ({products.length})

+ Add Product
{showForm && (

{editing ? "Edit Product" : "New Product"}

setForm(f => ({ ...f, name: e.target.value }))} className="w-full rounded-xl border border-[var(--admin-border)] px-3 py-2 text-sm outline-none focus:border-[var(--admin-accent)]" />