WFDASH-WEBAPP/src/lib/quote-status.ts
SJCoetz 7a68cafe35 chore: add logos, opencode config and build assets
This commit includes the temporary Next.js build cache files, public brand
logos, and project configuration added in this change.
2026-07-27 08:21:20 +02:00

88 lines
4.2 KiB
TypeScript

/**
* Theme-driven status palettes. Every entry uses semantic tokens
* (--info / --warn / --success / --destructive) so the colour
* palette follows the active theme — switching from crisp→nvidia→neon
* changes which exact hue "approved" renders as, but the *meaning*
* (success = green, warning = amber, etc.) stays consistent.
*
* Keeping the semantic names intentional: they're named after what
* the status MEANS to the operator, not after a Tailwind palette
* name. That way the suite works across every theme in the picker.
*/
const quoteStatusClasses: Record<string, string> = {
// In-flight / awaiting further action — info (cool blue)
new: "border-info/30 bg-info/10 text-info",
claimed: "border-info/30 bg-info/10 text-info",
processed: "border-info/30 bg-info/10 text-info",
emailed: "border-info/30 bg-info/10 text-info",
sending: "border-info/40 bg-info/15 text-info",
template: "border-info/30 bg-info/10 text-info",
// Soft warning — needs operator attention soon
approval_pending: "border-warn/40 bg-warn/15 text-warn-foreground",
// Partial-approval variants — added 2026-07-24. Same warning palette
// as approval_pending (operator + rep both treat these as "needs
// eyes") but a different border weight so the rep can tell at a
// glance that the submission is incomplete.
partial_approval_pending: "border-warn/30 bg-warn/10 text-warn-foreground",
follow_up: "border-warn/40 bg-warn/15 text-warn-foreground",
// Terminal-positive
approved: "border-success/30 bg-success/10 text-success",
complete: "border-success/30 bg-success/10 text-success",
// Partial-approved (terminal for this batch, but a continuation quote
// exists with the remaining items). Slightly muted success colour so
// the operator can tell the original isn't "fully done" — the
// continuation is the live quote.
partial_approved: "border-success/30 bg-success/5 text-success/80",
// Terminal-negative
rejected: "border-destructive/30 bg-destructive/10 text-destructive",
email_failed: "border-destructive/30 bg-destructive/10 text-destructive",
mail_failed: "border-destructive/40 bg-destructive/15 text-destructive",
unmatched_bounce: "border-destructive/30 bg-destructive/10 text-destructive",
problem: "border-destructive/30 bg-destructive/10 text-destructive",
// Neutral terminal
cancelled: "border-muted bg-muted text-muted-foreground",
};
export function quoteStatusClassName(status: string) {
return quoteStatusClasses[status] || "border-muted bg-muted text-muted-foreground";
}
/**
* Human-friendly status label. Most statuses just replace underscores
* with spaces ("approval_pending" → "approval pending"), but a handful
* of legacy PB status strings render better with bespoke labels so the
* operator reads them as workflow states rather than raw enum values:
*
* emailed → "Awaiting reply"
* (the email was sent to the customer; we're waiting for them to come back.
* The legacy enum `emailed` doesn't read like a state on its own.)
* sending → "Sending…"
* (transient — outbound send in flight, n8n is processing.)
* follow_up → "Follow up"
* (just title-case it for nicer rendering.)
*/
const STATUS_LABELS: Record<string, string> = {
emailed: "Awaiting reply",
sending: "Sending…",
follow_up: "Follow up",
approval_pending: "Pending approval",
// Partial-approval labels — distinguish "full quote awaiting eyes"
// from "5 of 15 awaiting eyes". The "partial" prefix keeps the
// signal clear in lists, filters, and badge tooltips.
partial_approval_pending: "Partial — pending approval",
partial_approved: "Partial — sent",
unmatched_bounce: "Unmatched bounce",
email_failed: "Email failed",
mail_failed: "Mail failed",
// "delivery_note" is the status the office gives a quote that
// prices a delivery note. The operator claims it, fills in
// prices, and sends it without going through the regular
// approval queue — the items are already with the customer, so
// approval is implicit. See the v2.1 sendQuoteEmail change for
// the matching skip-approval logic.
delivery_note: "Delivery note",
};
export function formatQuoteStatus(status: string) {
return STATUS_LABELS[status] || status.replace(/_/g, " ");
}