block
Dashboard components
The shared admin library: shell, data table, KPI tiles, sales chart, status badges, filter bar, timeline.
npx shadcn@latest add @hextor/store-dash-uiSource
import type { Address } from "@/registry/hextor/lib/store";
import { cn } from "@/registry/hextor/lib/utils";
/** Renders a shipping or billing `Address`, or a muted placeholder when absent. */
export function AddressCard({
title,
address,
emptyLabel = "No address on file",
className,
}: {
title: string;
address?: Address;
emptyLabel?: string;
className?: string;
}) {
return (
<div className={cn("space-y-1.5", className)}>
<p className="text-xs font-medium text-muted-foreground">{title}</p>
{address ? (
<address className="text-sm leading-relaxed not-italic">
<p>{address.name}</p>
<p>{address.line1}</p>
{address.line2 ? <p>{address.line2}</p> : null}
<p>
{address.city}
{address.province ? `, ${address.province}` : ""} {address.postalCode}
</p>
<p>{address.country}</p>
{address.phone ? <p className="text-muted-foreground">{address.phone}</p> : null}
</address>
) : (
<p className="text-sm text-muted-foreground">{emptyLabel}</p>
)}
</div>
);
}
Docs
DashboardShell takes its nav and activeHref as props, never a router hook — a block that calls usePathname() only works inside the router it was authored against.
Order state reuses @hextor/verdict-badge rather than inventing a second status palette, so a paid badge here is the same green as a passing verdict everywhere else.
The sales chart is inline SVG reading CSS custom properties. A charting library would be a dependency in every consumer's bundle for one sparkline.
Dependencies
lucide-reactbuttonbadgecardseparatorinputlabelselectcheckboxtabledropdown-menusheetswitchtextareascroll-area@hextor/store-model@hextor/verdict-badge