← back to Homesonspec
packages/shared-ui/src/badges.tsx
50 lines
import type { ReactElement } from "react";
/** Verification labels — the consumer-trust surface. Colors are fixed per label. */
const LABEL_STYLES: Record<string, { text: string; classes: string }> = {
VERIFIED_FROM_BUILDER: { text: "Verified directly from builder", classes: "bg-emerald-100 text-emerald-900 border-emerald-300" },
BUILDER_WEBSITE: { text: "Verified from builder website", classes: "bg-teal-100 text-teal-900 border-teal-300" },
BUILDER_SUBMITTED: { text: "Builder-submitted", classes: "bg-sky-100 text-sky-900 border-sky-300" },
NEEDS_REVERIFICATION: { text: "Needs reverification", classes: "bg-amber-100 text-amber-900 border-amber-300" },
NO_LONGER_AVAILABLE: { text: "No longer available", classes: "bg-neutral-200 text-neutral-700 border-neutral-300" },
DEMONSTRATION: { text: "Demonstration data", classes: "bg-violet-100 text-violet-900 border-violet-300" },
};
export function VerificationBadge({ label }: { label: string }): ReactElement {
const style = LABEL_STYLES[label] ?? { text: label, classes: "bg-neutral-100 text-neutral-700 border-neutral-300" };
return (
<span className={`inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium ${style.classes}`}>
{style.text}
</span>
);
}
/**
* Created date + time chip — mandatory on every admin card (standing rule).
* Renders in the viewer's local timezone; full ISO in title for precision.
*/
export function CreatedChip({ date }: { date: Date | string }): ReactElement {
const d = typeof date === "string" ? new Date(date) : date;
return (
<span
title={d.toISOString()}
className="inline-flex items-center gap-1 rounded bg-neutral-100 px-2 py-0.5 text-xs text-neutral-600"
>
🕓{" "}
{d.toLocaleString(undefined, {
year: "numeric",
month: "short",
day: "numeric",
hour: "numeric",
minute: "2-digit",
})}
</span>
);
}
export function fmtPrice(price: number | string | null | undefined): string {
if (price === null || price === undefined) return "Price not published";
const n = typeof price === "string" ? Number(price) : price;
return n.toLocaleString("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 });
}