"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Loader2, Package, X, Check } from "lucide-react"; // Assign the container this site hires. // // `code` is what the invoice prints for it (e.g. "MPLANT05"); `assetId` is the plant // item it books to. With both set, a container line arriving on an invoice for this // site is allocated automatically on import instead of landing unbooked. export function SiteContainerEditor({ siteId, siteName, code, assetId, assets, }: { siteId: string; siteName: string; code: string; assetId: string; assets: { id: string; label: string }[]; }) { const router = useRouter(); const [open, setOpen] = useState(false); const [c, setC] = useState(code); const [a, setA] = useState(assetId); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [saved, setSaved] = useState(false); async function save(clear = false) { setBusy(true); setError(null); try { const res = await fetch(`/api/sites/${siteId}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(clear ? { container_code: "", container_asset: "" } : { container_code: c, container_asset: a }), }); const data = await res.json().catch(() => ({ ok: false, error: "Unexpected response" })); if (!data.ok) { setError(data.error || "Could not save"); } else { setOpen(false); setSaved(true); setTimeout(() => setSaved(false), 2500); router.refresh(); } } catch { setError("Could not reach the server"); } finally { setBusy(false); } } if (!open) { return ( ); } return (
setC(e.target.value)} placeholder="MPLANT05" className="min-h-[44px] w-full px-3 rounded-lg border border-gray-200 dark:border-white/10 bg-white dark:bg-white/5 text-sm font-mono focus:outline-none focus:border-[#30638E]" />
{error &&

{error}

}
{assetId && ( )}

Container lines on an invoice for {siteName} matching this code will be booked to it automatically.

); }