import type { HTMLAttributes } from "react"; import type { OrderStatus, ReviewDecision, StepStatus, WorkflowStepName, } from "@/lib/types/backend"; import { ORDER_STATUS_META, REVIEW_DECISION_META, STEP_STATUS_META, WORKFLOW_STEP_META, type StatusMeta, type StatusTone, } from "@/lib/types/status"; type StatusBadgeVariant = | "order" | "reviewDecision" | "stepStatus" | "workflowStep"; type StatusBadgeBaseProps = HTMLAttributes; type OrderStatusBadgeProps = StatusBadgeBaseProps & { status: OrderStatus; variant?: "order"; }; type ReviewDecisionBadgeProps = StatusBadgeBaseProps & { status: ReviewDecision; variant: "reviewDecision"; }; type StepStatusBadgeProps = StatusBadgeBaseProps & { status: StepStatus; variant: "stepStatus"; }; type WorkflowStepBadgeProps = StatusBadgeBaseProps & { status: WorkflowStepName | null; variant: "workflowStep"; }; export type StatusBadgeProps = | OrderStatusBadgeProps | ReviewDecisionBadgeProps | StepStatusBadgeProps | WorkflowStepBadgeProps; const TONE_STYLES: Record = { neutral: "border-[rgba(76,69,60,0.14)] bg-[rgba(110,98,84,0.08)] text-[var(--ink-muted)]", info: "border-[rgba(57,86,95,0.16)] bg-[rgba(57,86,95,0.1)] text-[#2e4d56]", warning: "border-[rgba(145,104,46,0.18)] bg-[rgba(202,164,97,0.14)] text-[#7a5323]", success: "border-[rgba(88,106,56,0.18)] bg-[rgba(110,127,82,0.14)] text-[#50633b]", danger: "border-[rgba(140,74,67,0.18)] bg-[rgba(140,74,67,0.12)] text-[#7f3f38]", }; function joinClasses(...values: Array) { return values.filter(Boolean).join(" "); } function getMetaFromRecord( record: Record, status: string, variant: StatusBadgeVariant, ): StatusMeta { const meta = record[status as T]; if (!meta) { throw new Error(`Invalid status "${status}" for variant "${variant}".`); } return meta; } function resolveStatusMeta(props: StatusBadgeProps): StatusMeta { switch (props.variant) { case "reviewDecision": return getMetaFromRecord(REVIEW_DECISION_META, props.status, props.variant); case "stepStatus": return getMetaFromRecord(STEP_STATUS_META, props.status, props.variant); case "workflowStep": if (props.status === null) { return { label: "未开始", tone: "neutral" }; } return getMetaFromRecord(WORKFLOW_STEP_META, props.status, props.variant); case "order": case undefined: return getMetaFromRecord(ORDER_STATUS_META, props.status, "order"); } } export function StatusBadge({ className, ...props }: StatusBadgeProps) { const meta = resolveStatusMeta(props); return ( {meta.label} ); }