diff --git a/src/app/(app)/quotes/approvals/page.test.tsx b/src/app/(app)/quotes/approvals/page.test.tsx index 768b413..6858a9c 100644 --- a/src/app/(app)/quotes/approvals/page.test.tsx +++ b/src/app/(app)/quotes/approvals/page.test.tsx @@ -213,9 +213,8 @@ describe("ApprovalsPage — Approve & send from list", () => { }); const { toast } = await import("sonner"); await waitFor(() => { - expect(toast).toHaveBeenCalledWith( - expect.stringContaining("already actioned"), - expect.anything() + expect(toast.info).toHaveBeenCalledWith( + expect.stringContaining("already actioned") ); }); }); diff --git a/src/app/(app)/quotes/approvals/page.tsx b/src/app/(app)/quotes/approvals/page.tsx index f2866bd..d0d578b 100644 --- a/src/app/(app)/quotes/approvals/page.tsx +++ b/src/app/(app)/quotes/approvals/page.tsx @@ -8,14 +8,13 @@ import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { toast } from "sonner"; import getPocketBase from "@/lib/pocketbase"; -import { formatDate, formatCurrency } from "@/lib/pb-helpers"; +import { formatDate } from "@/lib/pb-helpers"; import { quoteStatusClassName, formatQuoteStatus } from "@/lib/quote-status"; import { ArrowLeft, CheckCircle, XCircle, Loader2, FileText, ListChecks } from "lucide-react"; import { getClientIdentity } from "@/lib/dev-identity"; import { cn } from "@/lib/utils"; import type { Quote, QuoteItem, QuoteAttachment } from "@/lib/types"; import { SendQuoteModal } from "@/components/quotes/send-quote-modal"; -import { isPlaceholderCustomer } from "@/lib/placeholder-customers"; /** * /quotes/approvals — queue of quotes awaiting the rep's eyes. @@ -208,7 +207,7 @@ export default function ApprovalsPage() { // 3) Anything else (placeholder customer, validation, 5xx) — // generic error toast. if (body.code === "invalid_status") { - toast("This quote was already actioned — refreshing.", { type: "info" }); + toast.info("This quote was already actioned — refreshing."); router.refresh(); setSendModalQuoteId(null); return; @@ -221,6 +220,12 @@ export default function ApprovalsPage() { router.refresh(); return; } + if (res.status === 404) { + toast.info("This quote no longer exists. Refreshing."); + setSendModalQuoteId(null); + router.refresh(); + return; + } toast.error(body.error ?? `Approve failed (HTTP ${res.status})`); return; } @@ -543,17 +548,9 @@ export default function ApprovalsPage() { )} - {/* Placeholder-customer UX (disable submit) is delegated to the - server's 422 response. The detail page passes a customerIsPlaceholder - prop to SendQuoteModal; the list page deliberately doesn't bother — - placeholder customers shouldn't reach the approval queue in normal - flow, and the existing 422 handler shows the failure cleanly. */} {(() => { const openQuote = quotes.find((q) => q.id === sendModalQuoteId); if (!openQuote) return null; - const customerIsPlaceholder = isPlaceholderCustomer( - openQuote.expand?.customer?.customer ?? "" - ); return (