The copy-paste component model has a reputation: great for landing pages, useless past the login screen. Heroes and pricing tables paste cleanly because they are static. A dashboard is different. It has a collapsible sidebar that must survive mobile, charts that need wiring, tables with sorting and selection state, a command palette listening for ⌘K. The usual advice is to buy a template, inherit six thousand lines of someone else's architecture, and spend a week deleting.
We think that advice is outdated. Today we are shipping thirteen dashboard blocks: complete, app-grade screens that install with one command, render real interactions out of the box, and hand you every visible number as a typed prop. Not screenshots of dashboards. Working ones.
What actually installs
Each block is a single React component backed by a small set of shared app components. When you install a block, the shadcn CLI resolves the whole tree:
npx shadcn add "https://ui.beste.co/r/dashboard1?email=YOUR_EMAIL&license_key=YOUR_KEY"That one command lands three layers in your codebase:
- The screen at
components/beste/block/dashboard1.tsx. Plain TSX you own and edit. - The app components it composes at
components/beste/component/: things likesidebar-nav,data-table,user-menu,notifications-menu, and six chart components built on Recharts. - The shadcn/ui primitives those need (
button,badge,sheet,command,dialog, and so on), installed only if you do not already have them.
There is no runtime dependency on us. No theme object, no provider, no license check in your bundle. If you are on Base UI instead of Radix, swap /r/ for /r-base/ in the URL and you get the Base UI build of the same tree.
Because every block composes the same shared components, installing five dashboards does not give you five sidebars. It gives you one sidebar-nav, one data-table, one chart kit, and five screens arranged on top of them.
The frame: an admin shell in one component
Most dashboard work starts with the boring part: the layout. Sidebar, topbar, account menu, notifications, search. dashboard1 is that entire frame plus a first screen.
Look past the KPIs and notice what already works. The sidebar collapses to an icon rail on desktop and becomes a sheet drawer on mobile. The search button (or ⌘K anywhere on the page) opens a real command palette built on the shadcn Command primitive, fed by a commandGroups prop. The orders table sorts, paginates, selects rows, and exposes row actions. The notification bell and avatar menu are their own reusable components.
That is the pattern for the whole set: the chrome you would normally spend the first sprint on is the baseline, not the deliverable.
The tour
Thirteen screens cover most of what product teams actually build. Every one links to a live, full-screen preview on its block page.
| Block | Screen | Built around |
|---|---|---|
| dashboard1 | Admin shell | Sidebar, ⌘K palette, KPI row, orders table |
| dashboard2 | Customers table | One serious data table: search, sort, selection, row actions |
| dashboard3 | Commerce analytics | Area, bar, and radial charts over a product table |
| dashboard4 | Project workspace | Stats, weekly chart, team list, a live focus timer |
| dashboard5 | Booking workspace | Calendar, day agenda, room availability timeline |
| dashboard6 | Talent sourcing | Filterable talent grid with wishlist and invite states |
| dashboard7 | Traffic analytics | Realtime strip, four chart types, top-pages table |
| dashboard8 | Finance overview | Balance hero, budget gauge, cashflow and spending charts |
| dashboard9 | Sales pipeline | Four-stage kanban, forecast chart, rep leaderboard |
| dashboard10 | Support inbox | Three-pane helpdesk with a working composer and search |
| dashboard11 | Fitness overview | Activity rings, range-switching charts, workout log |
| dashboard12 | Service monitoring | Health grid, latency charts, 30-day uptime strip |
| dashboard13 | Account settings | Five-panel settings: profile, security, billing, team |
A few of them deserve a closer look.
Analytics that swap datasets, not chart libraries
dashboard3 is a commerce console: four KPIs with deltas, a net-profit area chart, a repeat-purchase gauge, a busiest-weekday bar chart, and a best-sellers table.
The charts are not bespoke Recharts code buried in the block. They are the shared chart components (area-chart, bar-chart, radial-chart) driven by profitData and dayData props. You change the analytics by changing arrays.
Screens with a point of view
dashboard8 shows the set is not twelve variations of the same grid. It is a personal-finance screen with a dark balance hero, account tiles, a budget gauge, and a transaction table where income renders green and spending does not.
dashboard9 is a working sales pipeline: a four-stage kanban with owner avatars and hot-deal flags, revenue against forecast, and a quota leaderboard where the progress bars derive from the rep data you pass.
Interaction is the product
dashboard10 is the block we expect people to underestimate from a screenshot. It is a three-pane support inbox where the parts you would assume are fake are not: the status chips filter tickets, the search input live-filters by subject and customer, selecting a ticket swaps the conversation, and the composer actually appends your reply to the thread (⌘Enter sends).
dashboard13 closes the loop on the screens every app needs eventually and nobody enjoys building: settings. Five panels (profile, security, notifications, billing, team) behind a vertical section nav, with working switches, session lists, per-member role selects, and an invoice table.
Every number on the screen is a prop
Here is the design rule we held the whole set to: if you can read it, you can pass it.
Each block renders its full demo out of the box, so <Dashboard8 /> with zero props looks exactly like the preview above. Every prop is optional and falls back to the demo value, which means you migrate to real data one field at a time instead of filling a giant config before anything renders:
import { Dashboard8 } from "@/components/beste/block/dashboard8";
export default function FinancePage() {
return (
<Dashboard8
brandName="Ledgerline"
totalBalance="$58,940.10"
balanceDelta="12.3%"
budgetValue={74}
budgetCaption="$6,180 of $8,400"
txns={transactions}
cashflowData={cashflow}
/>
);
}This sounds obvious until you audit dashboard templates for it. The usual failure mode is the "designed" corner: the chart takes a data prop, but the $482.6K headline above it is a string literal, so the moment you wire real data the hero contradicts the chart. We went through all thirteen screens and pulled every one of those into the props: hero figures, gauge values and their captions, uptime percentages, reminder cards, timer labels, the billing plan on the settings screen. If a number is visible, it is in the interface, typed, with the demo as its default.
Two more things fall out of the demo-as-default pattern:
- Exported demo objects. Each block exports its dataset (
dashboard8Demo,dashboard3Demo, and so on). They double as documentation: the exact shape your data needs, in a file you can open. - Readable interfaces.
Dashboard9Propstells you a pipeline isstages,revenueData,reps,quotaValue,quotaCaption. No docs site required; the props are the spec.
Migrate one field at a time
Start from the demo export, spread it, and override as your API comes online:
<Dashboard9 {...dashboard9Demo} stages={liveStages} />. The screen stays
complete at every step, so there is never a day when the dashboard looks
broken in review.
The app components underneath
The thirteen screens are also a delivery mechanism for something quieter: a set of app-grade components that install alongside them and are yours to reuse on any screen you build from scratch.
data-table is a generic, typed table: search, sorting, selection, pagination, row actions, toolbar slot, empty state. Columns are declared, not templated:
const columns: DataTableColumn<Invoice>[] = [
{ id: "customer", header: "Customer", value: (row) => row.customer, sortable: true },
{
id: "amount",
header: "Amount",
align: "right",
value: (row) => row.amount,
cell: (row) => <span className="font-medium">${row.amount}</span>,
sortable: true,
},
];
<DataTable
columns={columns}
data={invoices}
searchable
selectable
rowActions={[{ id: "view", label: "View" }]}
onRowAction={(actionId, row) => console.log(actionId, row.id)}
pageSize={8}
/>The chart kit is six components (area-chart, bar-chart, line-chart, pie-chart, radar-chart, radial-chart) sharing one convention: a data array, an xKey, and a config object that names each series and assigns its color. Colors resolve through CSS variables, so charts follow your theme in light and dark without a JS theme bridge:
<AreaChart
data={revenue}
xKey="month"
config={{
revenue: { label: "Revenue", color: "var(--chart-1)" },
orders: { label: "Orders", color: "var(--chart-2)" },
}}
stacked
showLegend
/>sidebar-nav takes groups of typed items (id, label, icon, badge, optional href), works controlled or uncontrolled for both the active item and the collapsed state, and handles the icon-rail collapse styling for you. user-menu and notifications-menu are the account dropdown and notification bell every app rebuilds. And the specialty screens contribute their own reusables: calendar-month, schedule-timeline, and talent-card.
The details you would have had to build twice
A dashboard template is easy to demo and hard to live with. These are the living-with-it details the set already handles:
- Server rendering is safe. No
Date.now()orMath.random()in render paths, timers seed deterministically and start in effects, calendar state uses fixed dates. The screens hydrate without mismatch warnings. - Mobile is not an afterthought. Shells collapse to icon rails and sheet drawers; grids reflow; the booking workspace splits its panes.
- Keyboards work. ⌘K opens palettes globally, ⌘Enter sends replies in the inbox, icon-only buttons carry
aria-labels, switches and menus are the accessible shadcn primitives underneath. - Theming is token-based. Everything reads from your CSS variables (
background,card,chart-1throughchart-5), so the blocks adopt your brand and your dark mode the moment they land. - The code is yours. No wrapper package to fork when you hit the inevitable custom requirement. It is TSX in your repo, structured the way you would have written it on a good day.
Start with the frame, swap in screens
The set is designed to be combined. A practical route for a new product:
- Install
dashboard1and make it your app frame: your nav groups, your command palette entries, your user menu. - Drop screens behind routes as features ship:
dashboard2for the customers page,dashboard3ordashboard7for analytics,dashboard13for settings. - When you outgrow a screen, you are not starting over. You are rearranging the same
data-table, chart kit, and nav primitives the blocks themselves are made of.
Since every block declares its dependencies, the CLI keeps this cheap: shared components install once, and each new screen is an incremental add.