Dashboard
KPI grid plus chart strip plus transactions table. The canonical analytics surface for SaaS and storefront dashboards.
Overview
A complete dashboard surface: page header with an export action, a
four-column KPI grid, a revenue bar chart, and a recent-transactions
table. Composes Card, Badge, Table, BarChart, and Button.
This block is the starting point for any analytics route. Replace the mock data with your TanStack Query hooks and the layout, chart, and table will keep working without changes.
Preview
Dashboard
Snapshot of the last 30 days.
+12.4% from last month
+4.1% from last month
+18.3% from last month
-3.2% from last month
| month | Revenue |
|---|---|
| Jan | 4200 |
| Feb | 5100 |
| Mar | 4800 |
| Apr | 6200 |
| May | 7400 |
| Jun | 6900 |
| Jul | 8100 |
| Aug | 8900 |
| Invoice | Customer | Status | Amount |
|---|---|---|---|
| INV-001 | Olivia Martinolivia@example.com | Paid | $1,999 |
| INV-002 | Jackson Leejackson@example.com | Paid | $39 |
| INV-003 | Isabella Nguyenisabella@example.com | Pending | $299 |
| INV-004 | William Kimwill@example.com | Refunded | $99 |
| INV-005 | Sofia Davissofia@example.com | Paid | $1,499 |
Anatomy
Dashboard
├─ header page title + subtitle + Export Button
├─ KPI grid four StatCard (Card · CardHeader · CardTitle · trend delta)
├─ Card (Revenue) BarChart (rx-data) — monthly series
└─ Card (Transactions) Table — invoice · customer · status Badge · amountInstallation
npx gremorie@latest add rx-dashboardpnpm dlx gremorie@latest add rx-dashboardyarn dlx gremorie@latest add rx-dashboardbunx --bun gremorie@latest add rx-dashboardCode
'use client';
import {
Badge,
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@gremorie/rx-display';
import { BarChart, type ChartConfig, type ChartDatum } from '@gremorie/rx-data';
import { Button } from '@gremorie/rx-forms';
import {
ArrowDownRight,
ArrowUpRight,
CreditCard,
DollarSign,
Download,
ShoppingCart,
Users,
} from 'lucide-react';
const KPIs = [
{
label: 'Revenue',
value: '$48,920',
delta: '+12.4%',
trend: 'up',
icon: DollarSign,
},
{
label: 'Customers',
value: '2,318',
delta: '+4.1%',
trend: 'up',
icon: Users,
},
{
label: 'Orders',
value: '1,204',
delta: '+18.3%',
trend: 'up',
icon: ShoppingCart,
},
{
label: 'Refunds',
value: '$1,420',
delta: '-3.2%',
trend: 'down',
icon: CreditCard,
},
] as const;
const REVENUE_DATA: ChartDatum[] = [
{ month: 'Jan', revenue: 4200 },
{ month: 'Feb', revenue: 5100 },
{ month: 'Mar', revenue: 4800 },
{ month: 'Apr', revenue: 6200 },
{ month: 'May', revenue: 7400 },
{ month: 'Jun', revenue: 6900 },
{ month: 'Jul', revenue: 8100 },
{ month: 'Aug', revenue: 8900 },
];
const REVENUE_CONFIG: ChartConfig = {
revenue: { label: 'Revenue', color: 'var(--chart-1)' },
};
export function Dashboard() {
return (
<div className="flex w-full flex-col gap-6">
<div className="flex items-center justify-between">
<div className="flex flex-col gap-1">
<h2 className="text-xl font-semibold">Dashboard</h2>
<p className="text-sm text-muted-foreground">
Snapshot of the last 30 days.
</p>
</div>
<Button variant="outline" size="sm">
<Download aria-hidden="true" />
Export
</Button>
</div>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
{KPIs.map(({ label, value, delta, trend, icon: Icon }) => (
<Card key={label}>
<CardHeader>
<CardDescription className="flex items-center justify-between">
<span>{label}</span>
<Icon className="size-4 text-muted-foreground" aria-hidden />
</CardDescription>
<CardTitle className="text-2xl">{value}</CardTitle>
</CardHeader>
<CardContent>
<p
className={
trend === 'up'
? 'flex items-center gap-1 text-xs text-emerald-600 dark:text-emerald-400'
: 'flex items-center gap-1 text-xs text-destructive'
}
>
{trend === 'up' ? (
<ArrowUpRight className="size-3" aria-hidden />
) : (
<ArrowDownRight className="size-3" aria-hidden />
)}
{delta} from last month
</p>
</CardContent>
</Card>
))}
</div>
<Card>
<CardHeader>
<CardTitle>Revenue</CardTitle>
<CardDescription>Monthly recurring revenue</CardDescription>
</CardHeader>
<CardContent>
<BarChart data={REVENUE_DATA} config={REVENUE_CONFIG} xKey="month" />
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Recent transactions</CardTitle>
<CardDescription>
Latest activity from your storefront.
</CardDescription>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Invoice</TableHead>
<TableHead>Customer</TableHead>
<TableHead>Status</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>{/* rows */}</TableBody>
</Table>
</CardContent>
</Card>
</div>
);
}The Angular edition of this component is planned; the React edition is production-ready today.
Customization
- Swap mock data for TanStack Query / SWR hooks
- Replace
BarChartwithLineChartorAreaChartfrom@gremorie/rx-data - Add filters (date range, segment) to the header row
- Wire the "Export" button to a CSV download endpoint
Related
Sign-in
Authentication card with GitHub provider plus email and password. Drop into the auth route and wire to your backend.
Assistant
The flagship Gremorie chat surface — a streaming conversation with reasoning, an inline ChartArtifact and sources, a floating B2B PromptInput composer, and a new-chat start state. Fully composed.