"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { cancelPo, supersedePo } from "@/app/(portal)/po/[id]/actions"; // ── Cancel PO button + confirmation modal ────────────────────────────────────── // The manager must type the word "cancel" and provide a reason before the action // is enabled — a deliberate friction step for an irreversible, terminal action. export function CancelPoButton({ poId, poNumber }: { poId: string; poNumber: string }) { const router = useRouter(); const [open, setOpen] = useState(false); const [reason, setReason] = useState(""); const [confirmText, setConfirmText] = useState(""); const [pending, setPending] = useState(false); const [error, setError] = useState(""); const confirmed = confirmText.trim().toLowerCase() === "cancel"; const canSubmit = confirmed && reason.trim().length > 0 && !pending; function close() { if (pending) return; setOpen(false); setReason(""); setConfirmText(""); setError(""); } async function handleCancel() { if (!canSubmit) return; setPending(true); setError(""); const result = await cancelPo({ poId, reason: reason.trim() }); if ("error" in result) { setError(result.error); setPending(false); } else { setPending(false); setOpen(false); router.refresh(); } } return ( <> {open && (
This marks the purchase order as cancelled and removes its value from all spend trackers and graphs. This cannot be undone.