# Admin Dashboard Page

> A React admin dashboard page: greeting and period, four KPIs, revenue against the previous period, recent orders, alerts and team activity.

- Type: React block (Blocks)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.2.1
- Install: `npx wingo-ui@latest add admin-dashboard-page`
- Docs: https://wingo-ui.com/components/admin-dashboard-page

## Interaction

Pick the period in the date range field (presets such as Last 7 days or Last month beside two months on desktop, a bottom sheet on phones): every panel fades to the new numbers, the KPI values count to theirs and the chart grows again. Each KPI tile is a link with a spoken name ("Revenue, $248,300, up 12.4%"); the (i) buttons explain revenue and conversion. Switch the revenue chart between Daily and Weekly (weekly needs 14 days or more), hover, tap or arrow through its points to read both periods, and click a legend entry to hide a series. The Needs attention rows are links with a count. In Recent orders, search by number or client, toggle the New, Shipping and Unpaid chips, sort by a header, select rows for the bulk bar (Confirm, Export, Cancel), open a row's menu (View, Confirm order, Print label, Cancel; Shift+F10 on a focused row) or click a row, or press Enter on it, to open the order sheet: its status, the delivery tracker with the carrier and tracking number, the products, the client and the payment, with Confirm order, Print label and Cancel in the footer. Confirming shows a spinner in the row's badge while it saves; cancelling asks first, then offers Undo in a toast for 5 seconds. The sheet slides in from the right (a tall bottom sheet on phones, drag the handle down to close), Escape closes it and focus returns to the row. On phones the orders are cards with Load more, the header keeps the period field, a + button and a menu with Export, and the KPIs sit two by two. Sections rise in once on mount; reduced motion keeps everything still.

## Installation

```bash
npx wingo-ui@latest add admin-dashboard-page
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/admin-dashboard-page` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `components/blocks/admin-dashboard-page.tsx`
- `components/blocks/admin-dashboard-page-data.ts`

npm dependencies: `npm i motion lucide-react`

Wingo UI dependencies (installed automatically):

- [Alert Dialog](https://wingo-ui.com/components/alert-dialog) ([Markdown](https://wingo-ui.com/components/alert-dialog.md))
- [Area chart](https://wingo-ui.com/components/area-chart) ([Markdown](https://wingo-ui.com/components/area-chart.md))
- [Avatar](https://wingo-ui.com/components/avatar) ([Markdown](https://wingo-ui.com/components/avatar.md))
- [Badge](https://wingo-ui.com/components/badge) ([Markdown](https://wingo-ui.com/components/badge.md))
- [Button](https://wingo-ui.com/components/button) ([Markdown](https://wingo-ui.com/components/button.md))
- [Data Table](https://wingo-ui.com/components/data-table) ([Markdown](https://wingo-ui.com/components/data-table.md))
- [Date Range Picker](https://wingo-ui.com/components/date-range-picker) ([Markdown](https://wingo-ui.com/components/date-range-picker.md))
- [Description List](https://wingo-ui.com/components/description-list) ([Markdown](https://wingo-ui.com/components/description-list.md))
- [Dropdown Menu](https://wingo-ui.com/components/dropdown-menu) ([Markdown](https://wingo-ui.com/components/dropdown-menu.md))
- [Empty State](https://wingo-ui.com/components/empty-state) ([Markdown](https://wingo-ui.com/components/empty-state.md))
- [Line chart](https://wingo-ui.com/components/line-chart) ([Markdown](https://wingo-ui.com/components/line-chart.md))
- [List](https://wingo-ui.com/components/list) ([Markdown](https://wingo-ui.com/components/list.md))
- [Order tracker](https://wingo-ui.com/components/order-tracker) ([Markdown](https://wingo-ui.com/components/order-tracker.md))
- [Page Header](https://wingo-ui.com/components/page-header) ([Markdown](https://wingo-ui.com/components/page-header.md))
- [Segmented Control](https://wingo-ui.com/components/segmented-control) ([Markdown](https://wingo-ui.com/components/segmented-control.md))
- [Sheet](https://wingo-ui.com/components/sheet) ([Markdown](https://wingo-ui.com/components/sheet.md))
- [Sparkline](https://wingo-ui.com/components/sparkline) ([Markdown](https://wingo-ui.com/components/sparkline.md))
- [Stat Card](https://wingo-ui.com/components/stat-card) ([Markdown](https://wingo-ui.com/components/stat-card.md))
- [Table](https://wingo-ui.com/components/table) ([Markdown](https://wingo-ui.com/components/table.md))
- [Timeline](https://wingo-ui.com/components/timeline) ([Markdown](https://wingo-ui.com/components/timeline.md))
- [Toast](https://wingo-ui.com/components/toast) ([Markdown](https://wingo-ui.com/components/toast.md))
- [useControllableState](https://wingo-ui.com/components/use-controllable-state) ([Markdown](https://wingo-ui.com/components/use-controllable-state.md))
- [useMediaQuery](https://wingo-ui.com/components/use-media-query) ([Markdown](https://wingo-ui.com/components/use-media-query.md))
- [Commerce](https://wingo-ui.com/components/commerce) ([Markdown](https://wingo-ui.com/components/commerce.md))
- [Date utils](https://wingo-ui.com/components/date-utils) ([Markdown](https://wingo-ui.com/components/date-utils.md))
- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [Navigation](https://wingo-ui.com/components/navigation) ([Markdown](https://wingo-ui.com/components/navigation.md))
- [Number format](https://wingo-ui.com/components/number-format) ([Markdown](https://wingo-ui.com/components/number-format.md))
- [Relative time](https://wingo-ui.com/components/relative-time) ([Markdown](https://wingo-ui.com/components/relative-time.md))
- [Tones](https://wingo-ui.com/components/tones) ([Markdown](https://wingo-ui.com/components/tones.md))
- [UIProvider](https://wingo-ui.com/components/ui-config) ([Markdown](https://wingo-ui.com/components/ui-config.md))

## Usage

```tsx
// app/(admin)/page.tsx (the shell lives in app/(admin)/layout.tsx: <AdminShell>{children}</AdminShell>)
"use client"

import { useRouter } from "next/navigation"
import { AdminDashboardPage } from "@/components/blocks/admin-dashboard-page"

export default function HomePage() {
  const router = useRouter()
  return (
    <AdminDashboardPage
      userName="Anna"
      onCreateOrder={() => router.push("/orders/new")}
      onOrderAction={async (action, order) => {
        await fetch(`/api/orders/${order.id}/${action}`, { method: "POST" })
      }}
    />
  )
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `userName?` | `string` | `"Anna"` | The name in the greeting ("Hi, Anna"). |
| `children?` | `ReactNode` |  | Extra sections after the built-in rows (more charts, a funnel, a table), in the page column; they rise in with the rest. |
| `period?` | `DateRange` |  | The reporting period, controlled; pair it with onPeriodChange. |
| `defaultPeriod?` | `DateRange` |  | The period while uncontrolled; defaults to August 26 to September 24, 2026. A change regenerates the sample through generateDashboardData when the data props are not given. |
| `onPeriodChange?` | `(period: DateRange) => void` |  | Called when a complete range is applied in the date field. |
| `presets?` | `DateRangePreset[]` |  | The quick ranges beside the calendar ({ key, label, value }). Defaults to Last 7 days, Last 30 days, This month, Last month, This quarter and This year, measured from now. |
| `kpis?` | `DashboardKpi[]` |  | The four tiles ({ id, label, value, format, delta, deltaFormat, sparkline, goal, href, info, icon, tone, caption }); defaults to the sample for the period (ADMIN_DASHBOARD_SAMPLE.kpis). A null value shows a dash. Every card in the row keeps one anatomy: when any card has a sparkline the others get a flat baseline in its place, and when any has a delta the others show caption (default labels.noComparison). A zero change reads No change. |
| `revenue?` | `{ date: string; current: number \| null; previous: number \| null }[]` |  | Daily revenue for the chart, ISO days; defaults to the sample for the period (ADMIN_DASHBOARD_SAMPLE.revenue). |
| `orders?` | `DashboardOrder[]` |  | The recent orders ({ id, number, client, date, status, payment, paid, total, items, courier, awb }); defaults to the 40 newest orders of the period (ADMIN_DASHBOARD_SAMPLE.orders). |
| `recent?` | `ReactNode` |  | Your own content for the recent panel (a table of payments or sign-ups); replaces the orders table. The panel keeps its title (labels.orders) and See all link (ordersHref). |
| `tasks?` | `DashboardTask[]` |  | The Needs attention rows ({ id, title, description, tone, href, count, icon }); defaults to ADMIN_DASHBOARD_SAMPLE.tasks. An empty list shows "All good". |
| `activity?` | `TimelineItemData[]` |  | The team feed with actors and times; defaults to ADMIN_DASHBOARD_SAMPLE.activity (8 items). |
| `topProducts?` | `{ id; title; quantity; revenue; trend? }[]` |  | The Products sold table, with a 14 day sparkline from trend; defaults to the five Summit CRM products of the sample. |
| `compare?` | `boolean` | `true` | The dashed previous-period series, the revenue change and the KPI deltas. |
| `chartType?` | `"area" \| "line"` | `"area"` | The revenue chart: AreaChart, or LineChart with a soft area. |
| `granularity?` | `"day" \| "week"` |  | The revenue grouping, controlled; pair it with onGranularityChange. |
| `defaultGranularity?` | `"day" \| "week"` | `"day"` | The revenue grouping while uncontrolled; week falls back to days for periods under 14 days. |
| `onGranularityChange?` | `(granularity: DashboardGranularity) => void` |  | Called when the Daily / Weekly switch changes. |
| `showAttention?` | `boolean` | `true` | The Needs attention panel beside the chart. |
| `attentionEmpty?` | `"compact" \| "panel" (AdminDashboardPageAttentionEmpty)` | `"compact"` | With no tasks (tasks=[]): a slim "All good" strip above the revenue row, with the chart taking the full width, or the full Needs attention panel with its empty state. With tasks the panel always shows. |
| `kpiIcons?` | `boolean` | `true` | Tinted icon tiles on the KPI cards: kpi.icon and kpi.tone, else an icon and a tone picked from the id (revenue orange, orders blue, clients green, conversion amber). |
| `chartTone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `""` | The revenue line's color. Unset, it follows tone (neutral: the chart's first series color); the previous period stays a muted dashed line. |
| `showActivity?` | `boolean` | `true` | The team activity feed. |
| `showTopProducts?` | `boolean` | `true` | The Products sold table. |
| `topProductsColumns?` | `("quantity" \| "revenue" \| "trend")[]` | `"[\"quantity\", \"revenue\", \"trend\"]"` | The value columns of the top table, in order. The first one is the phone card's value; ["quantity"] turns it into a plain ranking (installs, views). |
| `ordersPageSize?` | `number` | `8` | Orders per page on desktop, and per load on phones. |
| `onOrderAction?` | `(action: DashboardOrderAction, order: DashboardOrder) => (void \| Promise<unknown>)` |  | Runs a row, bulk or sheet action (confirm, cancel or print). The status changes at once and the row shows a spinner until the promise settles; a rejection rolls it back with an error toast. Without it the page waits 900 ms and toasts. |
| `onExport?` | `(period: DateRange) => (void \| Promise<unknown>)` |  | The Export action; a promise keeps the button loading. Without it a toast confirms the export. |
| `onCreateOrder?` | `() => (void \| Promise<unknown>)` |  | The New order action. Without it a toast stands in for the form. |
| `orderSheet?` | `boolean` | `true` | A row click opens the order sheet; false only calls onOrderClick. |
| `onOrderClick?` | `(order: DashboardOrder) => void` |  | Called when a row or its View action is chosen (before the sheet opens). |
| `defaultOpenOrder?` | `string` | `""` | An order id whose sheet is open on mount (o1042 is the one in delivery). |
| `ordersHref?` | `string` | `"/orders"` | Where the orders panel's See all goes. |
| `activityHref?` | `string` | `"/activity"` | Where the activity panel's See all goes. |
| `labels?` | `Partial<AdminDashboardPageLabels>` |  | Every visible string (English, DEFAULT_ADMIN_DASHBOARD_PAGE_LABELS; ADMIN_DASHBOARD_PAGE_LABELS_EN is the same set). Nested keys (statCard, chart, dateRange, ordersTable, table, list, timeline, orderTracker, sparkline) translate the composed items. |
| `locale?` | `string` | `"en-US"` | Intl locale for numbers, money and dates. |
| `currency?` | `string` | `"USD"` | ISO 4217 code for the KPIs, the chart, the orders and the products. |
| `now?` | `Date \| number` |  | The reference time for today, the presets and the relative times; default the live clock. |
| `tone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `"neutral"` | The primary actions, the KPI sparklines and goal bar, the chart's current series and the date selection. |
| `radius?` | `"sm" \| "md" \| "lg"` | `"md"` | Corner size of the KPI tiles and the panels (12 / 16 / 24px). |
| `loading?` | `boolean` | `false` | Skeletons in the real layout: the header, the tiles, the chart, the rows and the feed. |
| `animateIn?` | `boolean` | `true` | Sections rise in once when the page mounts on the client; off in thumbnails and under reduced motion. |
| `linkComponent?` | `(props: LinkComponentProps) => ReactNode` | `"<a>"` | The router link for the panel links and the attention rows; default the surrounding LinkProvider's (the admin shell's). |
| `className?` | `string` |  | Classes for the root. |
| `classNames?` | `Partial<Record<AdminDashboardPageSlot, string>>` |  | Classes for header, kpis, row, revenue, attention, orders, top, activity and orderSheet. |

## Parts

### DEFAULT_ADMIN_DASHBOARD_PAGE_LABELS (constant)

Every English string of the dashboard: greeting, period, KPI names, chart, orders, alerts and activity. Spread it and override what you translate.

### ADMIN_DASHBOARD_PAGE_LABELS_EN (constant)

An alias of DEFAULT_ADMIN_DASHBOARD_PAGE_LABELS, kept so older imports keep working.

### generateDashboardData (function)

Builds the whole dashboard (KPIs, revenue series, orders, alerts) for one period; the same period and seed always give the same numbers.

### sampleTasks (function)

Returns the sample alerts: overdue invoices, unconfirmed orders, low stock and a failed payment, each with a tone and a link.

### sampleActivity (function)

Returns the team's latest actions for the activity timeline, timed relative to a given now.

### ADMIN_DASHBOARD_SAMPLE (constant)

The demo dashboard for the default period, with its period and now. Replace it with data from your API.

### ADMIN_DASHBOARD_DEFAULT_PERIOD (constant)

The period the dashboard opens on when defaultPeriod is not set: the 30 days up to the sample's now (August 26 to September 24, 2026).

### ADMIN_DASHBOARD_NOW (constant)

The fixed "now" of the sample (September 24, 2026, 4:40 PM), so server and client render the same numbers.

### ADMIN_DASHBOARD_ORDER_IDS (constant)

The four sample order ids the demo offers for defaultOpenOrder.

## Examples

- **Order sheet open on #1042**: defaultOpenOrder="o1042": out for delivery with UPS, tracking 1Z 999 AA1 01 2345 678.
- **Loading**: loading: skeleton tiles, chart, rows and feed in the real layout.
- **An empty period**: January 1 to January 7, 2026, the office was closed: KPIs show a dash, the table offers another period.
- **Launch day**: No sales yet: zero KPIs read No change, the revenue panel is one row, All good is a slim strip and empty tables drop their headers.
- **Brand tone, weekly line chart**: tone="brand", chartType="line", defaultGranularity="week".
- **All clear, no comparison**: tasks={[]} shows All good; compare={false} hides the previous period and the deltas.
- **Your own sections**: recent replaces the orders table, children add sections, topProductsColumns={["quantity"]} and two presets.
- **British English, euros**: locale="en-GB", currency="EUR" with a controlled period regenerating the sample.

## See also

- [KPI Dashboard](https://wingo-ui.com/components/kpi-dashboard) ([Markdown](https://wingo-ui.com/components/kpi-dashboard.md))
- [Admin Shell](https://wingo-ui.com/components/admin-shell) ([Markdown](https://wingo-ui.com/components/admin-shell.md))
- [Data Table](https://wingo-ui.com/components/data-table) ([Markdown](https://wingo-ui.com/components/data-table.md))
- [Stat Card](https://wingo-ui.com/components/stat-card) ([Markdown](https://wingo-ui.com/components/stat-card.md))
- [Order tracker](https://wingo-ui.com/components/order-tracker) ([Markdown](https://wingo-ui.com/components/order-tracker.md))
- [Area chart](https://wingo-ui.com/components/area-chart) ([Markdown](https://wingo-ui.com/components/area-chart.md))

---

Canonical: https://wingo-ui.com/components/admin-dashboard-page
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
