Admin dashboard
BlockProAn administration console: the shell every admin page shares — navigation, breadcrumb, account menu — and the overview that is its front page, with what needs attention first.
Overview
What needs attention, and how the business is doing.
Monthly revenue
Monthly revenue: $48,200, up +9.3% vs last month
Active accounts
Active accounts: 1,284, up +4.3% vs last month
Churn
Churn: 2.1%, up +23.5% vs last month
Open tickets
Open tickets: 12, down -36.8% vs last week
Accounts to watch
Newest, trialling, or behind on payment.
| Account | Plan | Seats | Status | Monthly | Created | Open |
|---|---|---|---|---|---|---|
| Northwind Traders | Team | 12 | Past due | $240 | ||
| Initech | Team | 8 | Past due | $160 | ||
| Globex | Enterprise | 60 | Trial | $0 | ||
| Umbrella Health | Team | 25 | Trial | $0 | ||
| Stark Logistics | Business | 140 | Active | $2,800 | ||
| Hooli | Team | 4 | Suspended | $0 |
A still, rendered at build time from the same story the tests run. The block itself is interactive; the copy that runs is the one the CLI installs.
Installation
The block is written to your blocks directory, and everything it is built from is installed alongside it. This one needs a licence: sign in once with the CLI and the install is the same command.
pnpm dlx @dowel-ui/cli add admin-dashboardBuilt from
A block is not a black box. Every piece is a component you already have documentation for, and can change independently.
Props
AdminDashboardBlock
| Prop | Type | Default |
|---|---|---|
navigation (required) | AdminNavGroup[] | — |
workspaceName (required)The product or workspace, at the top of the navigation. | string | — |
accounts | AdminAccount[] | [] |
accountsDescription | string | "Newest, trialling, or behind on payment." |
accountsTitle | string | "Accounts to watch" |
activeHrefThe | string | — |
breadcrumbs | AdminBreadcrumb[] | [] |
description | string | "What needs attention, and how the business is doing." |
headerActions | ReactNode | — |
notices | AdminNotice[] | [] |
onNavigateCalled instead of following the link, for a client-side router. | (href: string) => void | — |
onOpenAccount | (account: AdminAccount) => void | — |
onOpenProfile | () => void | — |
onSignOut | () => void | — |
stats | AdminStat[] | [] |
title | string | "Overview" |
user | AdminUser | — |
childrenReplaces the overview. The shell around it stays. | ReactNode | — |
className | string | — |
Accessibility
What needs attention comes first and is the only loud part of the page; it is not a live region, because the list is there on load and re-announcing it on every refresh would make the console unusable. The navigation is a landmark called Admin, the breadcrumb another, so neither is one more thing called 'navigation'. The current page carries aria-current, a count beside a nav item says what it counts, the account menu is named after its owner, and each Open button is named after its account. Every status is a word, with colour agreeing rather than replacing.
Source
One file, written by dowel add admin-dashboard with imports rewritten to your own path alias, and yours to edit from then on.
This is a Pro block.
The preview is the real block, rendered from its own story — a still of it, not a copy of it. The source is installed by the CLI once this machine is signed in with a licence key — dowel login checks the key against the registry before storing it — and lands in your project as a file you own, exactly like a free block.
Registry name: admin-dashboard