{"$schema":"https://ui.shadcn.com/schema/registry-item.json","type":"registry:block","registryDependencies":["badge","button","card","chart","empty","table","@efferd/app-shell-2","@efferd/formater"],"name":"dashboard-2","description":"Dense KPI grid with net revenue, channel sales lines, invoices table, billing health, and activity feed.","categories":["dashboard"],"files":[{"path":"registry/blocks/dashboard/2/billing-health.tsx","type":"registry:component","content":"import { Button } from \"@/components/ui/button\";\nimport {\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n} from \"@/components/ui/card\";\nimport {\n\tEmpty,\n\tEmptyContent,\n\tEmptyDescription,\n\tEmptyHeader,\n\tEmptyMedia,\n\tEmptyTitle,\n} from \"@/components/ui/empty\";\nimport { DashboardCard } from \"@/components/dashboard-card\";\n\nexport function BillingHealth() {\n\treturn (\n\t\t<DashboardCard className=\"gap-0\">\n\t\t\t<CardHeader className=\"border-b\">\n\t\t\t\t<CardTitle className=\"text-balance text-base\">Billing health</CardTitle>\n\t\t\t\t<CardDescription className=\"text-pretty\">\n\t\t\t\t\tNothing urgent needs your attention.\n\t\t\t\t</CardDescription>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"flex h-full items-center px-0\">\n\t\t\t\t<Empty>\n\t\t\t\t\t<EmptyHeader>\n\t\t\t\t\t\t<EmptyMedia variant=\"icon\">\n\t\t\t\t\t\t\t<IconPlaceholder\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\thugeicons=\"CheckmarkCircle02Icon\"\n\t\t\t\t\t\t\t\tlucide=\"CircleCheckIcon\"\n\t\t\t\t\t\t\t\tphosphor=\"CheckCircleIcon\"\n\t\t\t\t\t\t\t\tremixicon=\"RiCheckboxCircleLine\"\n\t\t\t\t\t\t\t\ttabler=\"IconCircleCheck\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</EmptyMedia>\n\t\t\t\t\t\t<EmptyTitle>You're caught up.</EmptyTitle>\n\t\t\t\t\t\t<EmptyDescription className=\"text-xs\">\n\t\t\t\t\t\t\tBalances and payouts look fine. nothing overdue in this snapshot.\n\t\t\t\t\t\t</EmptyDescription>\n\t\t\t\t\t</EmptyHeader>\n\t\t\t\t\t<EmptyContent>\n\t\t\t\t\t\t<Button asChild variant=\"ghost\">\n\t\t\t\t\t\t\t<a href=\"/#\">\n\t\t\t\t\t\t\t\tReview open invoices\n\t\t\t\t\t\t\t\t<IconPlaceholder\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\thugeicons=\"ArrowRightIcon\"\n\t\t\t\t\t\t\t\t\tlucide=\"ArrowRightIcon\"\n\t\t\t\t\t\t\t\t\tphosphor=\"ArrowRightIcon\"\n\t\t\t\t\t\t\t\t\tremixicon=\"RiArrowRightLine\"\n\t\t\t\t\t\t\t\t\ttabler=\"IconArrowRight\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</EmptyContent>\n\t\t\t\t</Empty>\n\t\t\t</CardContent>\n\t\t</DashboardCard>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/channel-sales-chart.tsx","type":"registry:component","content":"\"use client\";\n\nimport { useId } from \"react\";\nimport { CartesianGrid, Line, LineChart, XAxis } from \"recharts\";\nimport { formatDate } from \"@/lib/formater\";\nimport {\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n} from \"@/components/ui/card\";\nimport {\n\ttype ChartConfig,\n\tChartContainer,\n\tChartTooltip,\n\tChartTooltipContent,\n} from \"@/components/ui/chart\";\nimport { Delta, DeltaIcon, DeltaValue } from \"@/components/delta\";\nimport { DashboardCard } from \"@/components/dashboard-card\";\n\nconst VISIBLE_DAYS = 7;\n\n/** One row per day: ISO `date`, `retail` / `online` = sales counts (units sold). */\ntype ChannelSalesChartRow = {\n\tdate: string;\n\tretail: number;\n\tonline: number;\n};\n\n/**\n * Demo Data.\n */\nconst chartData: ChannelSalesChartRow[] = [\n\t{ date: \"2026-03-15\", retail: 198, online: 96 },\n\t{ date: \"2026-03-16\", retail: 176, online: 82 },\n\t{ date: \"2026-03-17\", retail: 184, online: 88 },\n\t{ date: \"2026-03-18\", retail: 170, online: 80 },\n\t{ date: \"2026-03-19\", retail: 188, online: 90 },\n\t{ date: \"2026-03-20\", retail: 180, online: 85 },\n\t{ date: \"2026-03-21\", retail: 192, online: 92 },\n\t{ date: \"2026-03-22\", retail: 172, online: 78 },\n\t{ date: \"2026-03-23\", retail: 166, online: 74 },\n\t{ date: \"2026-03-24\", retail: 174, online: 79 },\n\t{ date: \"2026-03-25\", retail: 158, online: 72 },\n\t{ date: \"2026-03-26\", retail: 168, online: 76 },\n\t{ date: \"2026-03-27\", retail: 152, online: 70 },\n\t{ date: \"2026-03-28\", retail: 160, online: 74 },\n\t{ date: \"2026-03-29\", retail: 146, online: 68 },\n\t{ date: \"2026-03-30\", retail: 154, online: 71 },\n\t{ date: \"2026-03-31\", retail: 142, online: 65 },\n\t{ date: \"2026-04-01\", retail: 140, online: 63 },\n\t{ date: \"2026-04-02\", retail: 132, online: 59 },\n\t{ date: \"2026-04-03\", retail: 124, online: 56 },\n\t{ date: \"2026-04-04\", retail: 128, online: 58 },\n\t{ date: \"2026-04-05\", retail: 116, online: 52 },\n\t{ date: \"2026-04-06\", retail: 84, online: 40 },\n\t{ date: \"2026-04-07\", retail: 82, online: 38 },\n\t{ date: \"2026-04-08\", retail: 96, online: 46 },\n\t{ date: \"2026-04-09\", retail: 92, online: 69 },\n\t{ date: \"2026-04-10\", retail: 96, online: 62 },\n\t{ date: \"2026-04-11\", retail: 112, online: 75 },\n\t{ date: \"2026-04-12\", retail: 101, online: 77 },\n\t{ date: \"2026-04-13\", retail: 112, online: 78 },\n];\n\n/** Most recent daily rows shown in the chart. */\nconst chartRows = chartData.slice(-VISIBLE_DAYS);\n\nfunction rowTotal(row: ChannelSalesChartRow) {\n\treturn row.retail + row.online;\n}\n\nfunction growthPctForWindow(rows: readonly ChannelSalesChartRow[]) {\n\tconst first = rows[0];\n\tif (!first) {\n\t\treturn 0;\n\t}\n\tconst last = rows.at(-1);\n\tif (!last) {\n\t\treturn 0;\n\t}\n\tconst a = rowTotal(first);\n\tconst b = rowTotal(last);\n\tif (!a) {\n\t\treturn 0;\n\t}\n\treturn ((b - a) / a) * 100;\n}\n\nconst growthPctNum = growthPctForWindow(chartRows);\n\nconst chartConfig = {\n\tretail: {\n\t\tlabel: \"Retail\",\n\t\tcolor: \"var(--chart-2)\",\n\t},\n\tonline: {\n\t\tlabel: \"Online\",\n\t\tcolor: \"var(--chart-1)\",\n\t},\n} satisfies ChartConfig;\n\nexport function ChannelSalesChart() {\n\tconst chartUid = useId().replace(/:/g, \"\");\n\tconst idLineGlow = `channel-sales-line-glow-${chartUid}`;\n\n\treturn (\n\t\t<DashboardCard className=\"gap-0 md:col-span-2\">\n\t\t\t<CardHeader>\n\t\t\t\t<div className=\"min-w-0 space-y-2\">\n\t\t\t\t\t<div className=\"flex flex-wrap items-center gap-2\">\n\t\t\t\t\t\t<CardTitle>Channel sales</CardTitle>\n\t\t\t\t\t\t<Delta value={growthPctNum} variant=\"badge\">\n\t\t\t\t\t\t\t<DeltaIcon variant=\"trend\" />\n\t\t\t\t\t\t\t<DeltaValue />\n\t\t\t\t\t\t</Delta>\n\t\t\t\t\t</div>\n\t\t\t\t\t<CardDescription>\n\t\t\t\t\t\tDaily sales count by channel, last {VISIBLE_DAYS} days.\n\t\t\t\t\t</CardDescription>\n\t\t\t\t</div>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t<ChartContainer\n\t\t\t\t\tclassName=\"aspect-auto h-60 w-full p-0 md:h-80\"\n\t\t\t\t\tconfig={chartConfig}\n\t\t\t\t>\n\t\t\t\t\t<LineChart\n\t\t\t\t\t\taccessibilityLayer\n\t\t\t\t\t\tdata={chartRows}\n\t\t\t\t\t\tmargin={{\n\t\t\t\t\t\t\tleft: 12,\n\t\t\t\t\t\t\tright: 12,\n\t\t\t\t\t\t\ttop: 8,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<CartesianGrid className=\"stroke-border\" vertical={false} />\n\t\t\t\t\t\t<XAxis\n\t\t\t\t\t\t\taxisLine={false}\n\t\t\t\t\t\t\tdataKey=\"date\"\n\t\t\t\t\t\t\tinterval={0}\n\t\t\t\t\t\t\ttickFormatter={(value) => formatDate(String(value), \"day-month\")}\n\t\t\t\t\t\t\ttickLine={false}\n\t\t\t\t\t\t\ttickMargin={8}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<ChartTooltip\n\t\t\t\t\t\t\tcontent={<ChartTooltipContent hideLabel />}\n\t\t\t\t\t\t\tcursor={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<defs>\n\t\t\t\t\t\t\t<filter\n\t\t\t\t\t\t\t\theight=\"140%\"\n\t\t\t\t\t\t\t\tid={idLineGlow}\n\t\t\t\t\t\t\t\twidth=\"140%\"\n\t\t\t\t\t\t\t\tx=\"-20%\"\n\t\t\t\t\t\t\t\ty=\"-20%\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<feGaussianBlur result=\"blur\" stdDeviation=\"10\" />\n\t\t\t\t\t\t\t\t<feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"over\" />\n\t\t\t\t\t\t\t</filter>\n\t\t\t\t\t\t</defs>\n\t\t\t\t\t\t<Line\n\t\t\t\t\t\t\tdataKey=\"online\"\n\t\t\t\t\t\t\tdot={false}\n\t\t\t\t\t\t\tfilter={`url(#${idLineGlow})`}\n\t\t\t\t\t\t\tstroke=\"var(--color-online)\"\n\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Line\n\t\t\t\t\t\t\tdataKey=\"retail\"\n\t\t\t\t\t\t\tdot={false}\n\t\t\t\t\t\t\tfilter={`url(#${idLineGlow})`}\n\t\t\t\t\t\t\tstroke=\"var(--color-retail)\"\n\t\t\t\t\t\t\tstrokeWidth={2}\n\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</LineChart>\n\t\t\t\t</ChartContainer>\n\t\t\t</CardContent>\n\t\t</DashboardCard>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/dashboard-activity.tsx","type":"registry:component","content":"import {\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n} from \"@/components/ui/card\";\nimport { DashboardCard } from \"@/components/dashboard-card\";\n\nconst items = [\n\t{\n\t\ttitle: \"Invoice #1045 marked paid\",\n\t\ttime: \"About 2 hours ago\",\n\t\ticon: (\n\t\t\t<IconPlaceholder\n\t\t\t\thugeicons=\"CreditCardIcon\"\n\t\t\t\tlucide=\"CreditCardIcon\"\n\t\t\t\tphosphor=\"CreditCardIcon\"\n\t\t\t\tremixicon=\"RiBankCardLine\"\n\t\t\t\ttabler=\"IconCreditCard\"\n\t\t\t/>\n\t\t),\n\t},\n\t{\n\t\ttitle: \"Jordan joined the team\",\n\t\ttime: \"This morning\",\n\t\ticon: (\n\t\t\t<IconPlaceholder\n\t\t\t\thugeicons=\"UserAdd01Icon\"\n\t\t\t\tlucide=\"UserPlusIcon\"\n\t\t\t\tphosphor=\"UserPlusIcon\"\n\t\t\t\tremixicon=\"RiUserAddLine\"\n\t\t\t\ttabler=\"IconUserPlus\"\n\t\t\t/>\n\t\t),\n\t},\n\t{\n\t\ttitle: \"Weekly summary exported\",\n\t\ttime: \"Yesterday\",\n\t\ticon: (\n\t\t\t<IconPlaceholder\n\t\t\t\thugeicons=\"File01Icon\"\n\t\t\t\tlucide=\"FileTextIcon\"\n\t\t\t\tphosphor=\"FileTextIcon\"\n\t\t\t\tremixicon=\"RiFileTextLine\"\n\t\t\t\ttabler=\"IconFileText\"\n\t\t\t/>\n\t\t),\n\t},\n\t{\n\t\ttitle: \"Dashboard v2 shipped to prod\",\n\t\ttime: \"2 days ago\",\n\t\ticon: (\n\t\t\t<IconPlaceholder\n\t\t\t\thugeicons=\"Rocket01Icon\"\n\t\t\t\tlucide=\"RocketIcon\"\n\t\t\t\tphosphor=\"RocketIcon\"\n\t\t\t\tremixicon=\"RiRocketLine\"\n\t\t\t\ttabler=\"IconRocket\"\n\t\t\t/>\n\t\t),\n\t},\n] as const;\n\nexport function DashboardActivity() {\n\treturn (\n\t\t<DashboardCard className=\"gap-0\">\n\t\t\t<CardHeader className=\"border-b\">\n\t\t\t\t<CardTitle>Activity</CardTitle>\n\t\t\t\t<CardDescription>Latest updates in your workspace.</CardDescription>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"px-0\">\n\t\t\t\t<ul className=\"flex flex-col divide-y divide-border\">\n\t\t\t\t\t{items.map((item) => (\n\t\t\t\t\t\t<li className=\"flex h-16 items-center gap-3 px-6\" key={item.title}>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tclassName=\"flex size-10 shrink-0 items-center justify-center [&_svg]:size-4\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{item.icon}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t\t\t\t\t<p className=\"line-clamp-1 text-pretty text-foreground text-sm leading-snug\">\n\t\t\t\t\t\t\t\t\t{item.title}\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-xs\">{item.time}</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t</CardContent>\n\t\t</DashboardCard>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/dashboard-card.tsx","type":"registry:component","content":"import { cn } from \"@/lib/utils\";\nimport type * as React from \"react\";\nimport { Card } from \"@/components/ui/card\";\n\nexport function DashboardCard({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof Card>) {\n\treturn (\n\t\t<Card\n\t\t\tclassName={cn(\"rounded-none bg-background shadow-none ring-0\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/dashboard-invoices.tsx","type":"registry:component","content":"\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n} from \"@/components/ui/card\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCaption,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRow,\n} from \"@/components/ui/table\";\nimport { DashboardCard } from \"@/components/dashboard-card\";\n\nconst invoices = [\n\t{\n\t\tid: \"1045\",\n\t\tcustomer: \"Northwind Labs\",\n\t\tamount: \"$2,400.00\",\n\t\tstatus: \"Paid\",\n\t},\n\t{\n\t\tid: \"1044\",\n\t\tcustomer: \"Blue River Co.\",\n\t\tamount: \"$890.00\",\n\t\tstatus: \"Pending\",\n\t},\n\t{\n\t\tid: \"1043\",\n\t\tcustomer: \"Oak Street Studio\",\n\t\tamount: \"$5,120.00\",\n\t\tstatus: \"Paid\",\n\t},\n\t{\n\t\tid: \"1042\",\n\t\tcustomer: \"Harbor Freight LLC\",\n\t\tamount: \"$310.50\",\n\t\tstatus: \"Overdue\",\n\t},\n] as const;\n\nexport function DashboardInvoices() {\n\treturn (\n\t\t<DashboardCard className=\"relative gap-0 md:col-span-2\">\n\t\t\t<CardHeader className=\"border-b\">\n\t\t\t\t<CardTitle className=\"text-base\">Recent invoices</CardTitle>\n\t\t\t\t<CardDescription>Open amounts and payment status.</CardDescription>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"mask-b-from-50% mask-b-to-100% px-0\">\n\t\t\t\t<Table>\n\t\t\t\t\t<TableCaption className=\"sr-only\">\n\t\t\t\t\t\tRecent invoices with customer, amount, and status.\n\t\t\t\t\t</TableCaption>\n\t\t\t\t\t<TableHeader>\n\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t<TableHead className=\"ps-6\">Customer</TableHead>\n\t\t\t\t\t\t\t<TableHead>Invoice</TableHead>\n\t\t\t\t\t\t\t<TableHead className=\"pe-6 text-right tabular-nums\">\n\t\t\t\t\t\t\t\tAmount\n\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t</TableHeader>\n\t\t\t\t\t<TableBody>\n\t\t\t\t\t\t{invoices.map((inv) => (\n\t\t\t\t\t\t\t<TableRow className=\"h-12\" key={inv.id}>\n\t\t\t\t\t\t\t\t<TableCell className=\"max-w-40 truncate ps-6 font-medium\">\n\t\t\t\t\t\t\t\t\t{inv.customer}\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t<TableCell className=\"text-muted-foreground tabular-nums\">\n\t\t\t\t\t\t\t\t\t#{inv.id}\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t<TableCell className=\"pe-6 text-right tabular-nums\">\n\t\t\t\t\t\t\t\t\t{inv.amount}\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</TableBody>\n\t\t\t\t</Table>\n\t\t\t</CardContent>\n\t\t\t<div className=\"mask-t-from-30% absolute inset-x-0 bottom-0 flex h-1/5 items-center justify-center bg-background\">\n\t\t\t\t<Button asChild className=\"relative\" variant=\"ghost\">\n\t\t\t\t\t<a href=\"/#\">\n\t\t\t\t\t\tView All\n\t\t\t\t\t\t<IconPlaceholder\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\thugeicons=\"ArrowRightIcon\"\n\t\t\t\t\t\t\tlucide=\"ArrowRightIcon\"\n\t\t\t\t\t\t\tphosphor=\"ArrowRightIcon\"\n\t\t\t\t\t\t\tremixicon=\"RiArrowRightLine\"\n\t\t\t\t\t\t\ttabler=\"IconArrowRight\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</a>\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</DashboardCard>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/dashboard.tsx","type":"registry:component","content":"import { BillingHealth } from \"@/components/billing-health\";\nimport { ChannelSalesChart } from \"@/components/channel-sales-chart\";\nimport { DashboardActivity } from \"@/components/dashboard-activity\";\nimport { DashboardInvoices } from \"@/components/dashboard-invoices\";\nimport { NetRevenueChart } from \"@/components/net-revenue-chart\";\nimport { DashboardStats } from \"@/components/stats\";\n\nexport function Dashboard() {\n\treturn (\n\t\t<div className=\"grid grid-cols-1 gap-px bg-border p-px md:grid-cols-2 lg:grid-cols-4\">\n\t\t\t<DashboardStats />\n\t\t\t<NetRevenueChart />\n\t\t\t<ChannelSalesChart />\n\t\t\t<DashboardInvoices />\n\t\t\t<BillingHealth />\n\t\t\t<DashboardActivity />\n\t\t</div>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/net-revenue-chart.tsx","type":"registry:component","content":"\"use client\";\n\nimport type * as React from \"react\";\nimport { Bar, BarChart, XAxis } from \"recharts\";\nimport {\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n} from \"@/components/ui/card\";\nimport {\n\ttype ChartConfig,\n\tChartContainer,\n\tChartTooltip,\n\tChartTooltipContent,\n} from \"@/components/ui/chart\";\nimport { Delta, DeltaIcon, DeltaValue } from \"@/components/delta\";\nimport { DashboardCard } from \"@/components/dashboard-card\";\n\n/** Demo: last 7 days. */\nconst salesDaily7 = [\n\t{ day: \"Mon\", sales: 3200 },\n\t{ day: \"Tue\", sales: 3001 },\n\t{ day: \"Wed\", sales: 3780 },\n\t{ day: \"Thu\", sales: 4100 },\n\t{ day: \"Fri\", sales: 4520 },\n\t{ day: \"Sat\", sales: 4004 },\n\t{ day: \"Sun\", sales: 5340 },\n] as const;\n\nconst chartRows = salesDaily7.map((row) => ({ ...row }));\n\nconst firstDay = salesDaily7[0].sales;\nconst lastDay = salesDaily7.at(-1)?.sales ?? firstDay;\nconst growthPct = (((lastDay - firstDay) / firstDay) * 100).toFixed(1);\n\nconst chartConfig = {\n\tsales: {\n\t\tlabel: \"Sales\",\n\t\tcolor: \"var(--chart-2)\",\n\t},\n} satisfies ChartConfig;\n\nfunction CustomGradientBar(\n\tprops: React.SVGProps<SVGRectElement> & {\n\t\tindex?: number;\n\t\tdataKey?: string | number;\n\t}\n) {\n\tconst {\n\t\tfill,\n\t\tx = 0,\n\t\ty = 0,\n\t\twidth = 0,\n\t\theight = 0,\n\t\tdataKey = \"sales\",\n\t\tindex = 0,\n\t} = props;\n\tconst gid = `gradient-bar-${String(dataKey)}-${index}`;\n\n\treturn (\n\t\t<>\n\t\t\t<rect\n\t\t\t\tfill={`url(#${gid})`}\n\t\t\t\theight={height}\n\t\t\t\tstroke=\"none\"\n\t\t\t\twidth={width}\n\t\t\t\tx={x}\n\t\t\t\ty={y}\n\t\t\t/>\n\t\t\t<rect fill={fill} height={2} stroke=\"none\" width={width} x={x} y={y} />\n\t\t\t<defs>\n\t\t\t\t<linearGradient id={gid} x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n\t\t\t\t\t<stop offset=\"0%\" stopColor={fill} stopOpacity={0.5} />\n\t\t\t\t\t<stop offset=\"100%\" stopColor={fill} stopOpacity={0} />\n\t\t\t\t</linearGradient>\n\t\t\t</defs>\n\t\t</>\n\t);\n}\n\nexport function NetRevenueChart() {\n\treturn (\n\t\t<DashboardCard className=\"gap-0 md:col-span-2\">\n\t\t\t<CardHeader className=\"gap-2\">\n\t\t\t\t<div className=\"flex flex-wrap items-center gap-2\">\n\t\t\t\t\t<CardTitle>Net revenue</CardTitle>\n\t\t\t\t\t<Delta value={Number(growthPct)} variant=\"badge\">\n\t\t\t\t\t\t<DeltaIcon variant=\"trend\" />\n\t\t\t\t\t\t<DeltaValue />\n\t\t\t\t\t</Delta>\n\t\t\t\t</div>\n\t\t\t\t<CardDescription>Daily net sales, last 7 days.</CardDescription>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t<ChartContainer\n\t\t\t\t\tclassName=\"aspect-auto h-60 w-full md:h-80\"\n\t\t\t\t\tconfig={chartConfig}\n\t\t\t\t>\n\t\t\t\t\t<BarChart accessibilityLayer data={chartRows}>\n\t\t\t\t\t\t<XAxis\n\t\t\t\t\t\t\taxisLine={false}\n\t\t\t\t\t\t\tdataKey=\"day\"\n\t\t\t\t\t\t\tinterval={0}\n\t\t\t\t\t\t\ttickFormatter={(value) => String(value)}\n\t\t\t\t\t\t\ttickLine={false}\n\t\t\t\t\t\t\ttickMargin={10}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<ChartTooltip\n\t\t\t\t\t\t\tcontent={<ChartTooltipContent hideLabel />}\n\t\t\t\t\t\t\tcursor={false}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Bar\n\t\t\t\t\t\t\tdataKey=\"sales\"\n\t\t\t\t\t\t\tfill=\"var(--color-sales)\"\n\t\t\t\t\t\t\tshape={<CustomGradientBar />}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</BarChart>\n\t\t\t\t</ChartContainer>\n\t\t\t</CardContent>\n\t\t</DashboardCard>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/2/stats.tsx","type":"registry:component","content":"import {\n\tCardContent,\n\tCardFooter,\n\tCardHeader,\n\tCardTitle,\n} from \"@/components/ui/card\";\nimport { Delta, DeltaIcon, DeltaValue } from \"@/components/delta\";\nimport { DashboardCard } from \"@/components/dashboard-card\";\n\ntype Stat = {\n\tlabel: string;\n\tvalue: string;\n\tdelta: number;\n};\n\nconst stats: Stat[] = [\n\t{\n\t\tlabel: \"Active users\",\n\t\tvalue: \"847\",\n\t\tdelta: 3.1,\n\t},\n\t{\n\t\tlabel: \"Revenue\",\n\t\tvalue: \"$18,290\",\n\t\tdelta: 12.4,\n\t},\n\t{\n\t\tlabel: \"Conversion Rate\",\n\t\tvalue: \"3.28%\",\n\t\tdelta: -0.4,\n\t},\n\t{\n\t\tlabel: \"New signups\",\n\t\tvalue: \"142\",\n\t\tdelta: 8.7,\n\t},\n] as const;\n\nexport function DashboardStats() {\n\treturn (\n\t\t<>\n\t\t\t{stats.map((s) => (\n\t\t\t\t<DashboardCard className=\"\" key={s.label}>\n\t\t\t\t\t<CardHeader className=\"flex flex-row items-center justify-between\">\n\t\t\t\t\t\t<CardTitle className=\"font-normal text-xs tracking-wide\">\n\t\t\t\t\t\t\t{s.label}\n\t\t\t\t\t\t</CardTitle>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent className=\"flex flex-row items-center gap-2\">\n\t\t\t\t\t\t<p className=\"font-semibold text-2xl tabular-nums\">{s.value}</p>\n\t\t\t\t\t</CardContent>\n\t\t\t\t\t<CardFooter className=\"gap-1 rounded-none bg-background text-xs\">\n\t\t\t\t\t\t<Delta value={s.delta}>\n\t\t\t\t\t\t\t<DeltaIcon />\n\t\t\t\t\t\t\t<DeltaValue />\n\t\t\t\t\t\t</Delta>\n\t\t\t\t\t\t<span className=\"text-muted-foreground\">vs last week</span>{\" \"}\n\t\t\t\t\t</CardFooter>\n\t\t\t\t</DashboardCard>\n\t\t\t))}\n\t\t</>\n\t);\n}\n"},{"path":"registry/blocks/dashboard/delta.tsx","type":"registry:component","content":"\"use client\";\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\nimport { Badge } from \"@/components/ui/badge\";\n\ntype DeltaIconVariant = \"default\" | \"trend\" | \"arrow\";\ntype DeltaVariant = \"default\" | \"badge\";\n\ntype DeltaContextValue = {\n\tvalue: number;\n};\n\nconst DeltaContext = React.createContext<DeltaContextValue | null>(null);\n\nfunction useDeltaValue() {\n\tconst context = React.useContext(DeltaContext);\n\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"DeltaIcon and DeltaValue must be used inside a `Delta` component.\"\n\t\t);\n\t}\n\n\treturn context.value;\n}\n\nfunction Delta({\n\tclassName,\n\tvalue,\n\tvariant = \"default\",\n\t...props\n}: React.ComponentProps<\"div\"> & {\n\tvalue: number;\n\tvariant?: DeltaVariant;\n}) {\n\treturn (\n\t\t<DeltaContext.Provider value={{ value }}>\n\t\t\t{variant === \"badge\" ? (\n\t\t\t\t<Badge\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"gap-1 border-none tabular-nums [&_svg]:size-4 [&_svg]:shrink-0\",\n\t\t\t\t\t\tvalue > 0\n\t\t\t\t\t\t\t? \"bg-emerald-500/10 text-emerald-500\"\n\t\t\t\t\t\t\t: \"bg-red-500/10 text-red-500\",\n\t\t\t\t\t\tclassName\n\t\t\t\t\t)}\n\t\t\t\t\tdata-slot=\"delta\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t{...(props as React.ComponentProps<typeof Badge>)}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"inline-flex items-center gap-1 text-muted-foreground tabular-nums\",\n\t\t\t\t\t\t\"[&_svg]:size-3 [&_svg]:shrink-0\",\n\t\t\t\t\t\tvalue > 0 ? \"text-emerald-600 dark:text-emerald-400\" : \"\",\n\t\t\t\t\t\tvalue < 0 ? \"text-rose-600 dark:text-rose-400\" : \"\",\n\t\t\t\t\t\tclassName\n\t\t\t\t\t)}\n\t\t\t\t\tdata-slot=\"delta\"\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</DeltaContext.Provider>\n\t);\n}\n\nfunction FilledShell({\n\tvalue,\n\tchildren,\n}: {\n\tvalue: number;\n\tchildren: React.ReactNode;\n}) {\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex size-3 shrink-0 items-center justify-center rounded-full\",\n\t\t\t\t\"[&_svg]:size-2! [&_svg]:shrink-0 [&_svg]:stroke-3! [&_svg]:text-background\",\n\t\t\t\tvalue > 0 && \"bg-emerald-500\",\n\t\t\t\tvalue < 0 && \"bg-red-500\",\n\t\t\t\t(!value || value === 0) && \"bg-muted-foreground\"\n\t\t\t)}\n\t\t\tdata-slot=\"delta-icon\"\n\t\t>\n\t\t\t{children}\n\t\t</span>\n\t);\n}\n\nfunction DeltaIcon({\n\tvariant = \"default\",\n\tfilled = false,\n\tclassName,\n\t...props\n}: Omit<React.ComponentProps<\"svg\">, \"fill\"> & {\n\tvariant?: DeltaIconVariant;\n\tfilled?: boolean;\n}) {\n\tconst resolvedValue = useDeltaValue();\n\n\tconst mergedClassName = cn(className);\n\n\tconst shell = (node: React.ReactElement) =>\n\t\tfilled ? <FilledShell value={resolvedValue}>{node}</FilledShell> : node;\n\n\tconst slotProps = filled ? {} : { \"data-slot\": \"delta-icon\" as const };\n\n\tif (!resolvedValue || resolvedValue === 0) {\n\t\treturn shell(\n\t\t\t<IconPlaceholder\n\t\t\t\t{...slotProps}\n\t\t\t\tclassName={mergedClassName}\n\t\t\t\thugeicons=\"MinusSignIcon\"\n\t\t\t\tlucide=\"MinusIcon\"\n\t\t\t\tphosphor=\"MinusIcon\"\n\t\t\t\tremixicon=\"RiSubtractLine\"\n\t\t\t\ttabler=\"IconMinus\"\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t}\n\n\tif (resolvedValue > 0) {\n\t\tif (variant === \"trend\") {\n\t\t\treturn shell(\n\t\t\t\t<IconPlaceholder\n\t\t\t\t\t{...slotProps}\n\t\t\t\t\tclassName={mergedClassName}\n\t\t\t\t\thugeicons=\"TradeUpIcon\"\n\t\t\t\t\tlucide=\"TrendingUpIcon\"\n\t\t\t\t\tphosphor=\"TrendUpIcon\"\n\t\t\t\t\tremixicon=\"RiArrowRightUpLine\"\n\t\t\t\t\ttabler=\"IconTrendingUp\"\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\n\t\tif (variant === \"arrow\") {\n\t\t\treturn shell(\n\t\t\t\t<IconPlaceholder\n\t\t\t\t\t{...slotProps}\n\t\t\t\t\tclassName={mergedClassName}\n\t\t\t\t\thugeicons=\"ArrowUp02Icon\"\n\t\t\t\t\tlucide=\"ArrowUpIcon\"\n\t\t\t\t\tphosphor=\"ArrowUpIcon\"\n\t\t\t\t\tremixicon=\"RiArrowUpLine\"\n\t\t\t\t\ttabler=\"IconArrowUp\"\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t);\n\t\t}\n\n\t\treturn shell(\n\t\t\t<IconPlaceholder\n\t\t\t\t{...slotProps}\n\t\t\t\tclassName={mergedClassName}\n\t\t\t\thugeicons=\"ArrowUp01Icon\"\n\t\t\t\tlucide=\"ChevronUpIcon\"\n\t\t\t\tphosphor=\"CaretUpIcon\"\n\t\t\t\tremixicon=\"RiArrowUpSLine\"\n\t\t\t\ttabler=\"IconChevronUp\"\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t}\n\n\tif (variant === \"trend\") {\n\t\treturn shell(\n\t\t\t<IconPlaceholder\n\t\t\t\t{...slotProps}\n\t\t\t\tclassName={mergedClassName}\n\t\t\t\thugeicons=\"TradeDownIcon\"\n\t\t\t\tlucide=\"TrendingDownIcon\"\n\t\t\t\tphosphor=\"TrendDownIcon\"\n\t\t\t\tremixicon=\"RiArrowRightDownLine\"\n\t\t\t\ttabler=\"IconTrendingDown\"\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t}\n\n\tif (variant === \"arrow\") {\n\t\treturn shell(\n\t\t\t<IconPlaceholder\n\t\t\t\t{...slotProps}\n\t\t\t\tclassName={mergedClassName}\n\t\t\t\thugeicons=\"ArrowDown02Icon\"\n\t\t\t\tlucide=\"ArrowDownIcon\"\n\t\t\t\tphosphor=\"ArrowDownIcon\"\n\t\t\t\tremixicon=\"RiArrowDownLine\"\n\t\t\t\ttabler=\"IconArrowDown\"\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn shell(\n\t\t<IconPlaceholder\n\t\t\t{...slotProps}\n\t\t\tclassName={mergedClassName}\n\t\t\thugeicons=\"ArrowDown01Icon\"\n\t\t\tlucide=\"ChevronDownIcon\"\n\t\t\tphosphor=\"CaretDownIcon\"\n\t\t\tremixicon=\"RiArrowDownSLine\"\n\t\t\ttabler=\"IconChevronDown\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DeltaValue({\n\tclassName,\n\tprecision = 1,\n\tsuffix = \"%\",\n\tabsolute = true,\n\t...props\n}: React.ComponentProps<\"span\"> & {\n\tprecision?: number;\n\tsuffix?: string;\n\tabsolute?: boolean;\n}) {\n\tconst resolvedValue = useDeltaValue();\n\n\tconst formattedValue = (\n\t\tabsolute ? Math.abs(resolvedValue) : resolvedValue\n\t).toFixed(precision);\n\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\"tabular-nums\", className)}\n\t\t\tdata-slot=\"delta-value\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{formattedValue}\n\t\t\t{suffix}\n\t\t</span>\n\t);\n}\nexport { Delta, DeltaIcon, DeltaValue };\n"}]}