VisorVisor
Blocks

Admin Dashboard

Drop-in admin overview composition — PageHeader, responsive stat grid, optional secondary region, and ActivityFeed with empty-state fallback.

Preview

Overview

Dashboard

A live snapshot of your workspace — metrics, activity, and anything else worth a glance.

Total revenue

$48,120

+12.4%vs last monthup vs last month

Active users

2,847

+3.1%vs last monthup vs last month

Conversion rate

4.82%

-0.4%vs last monthdown vs last month

Churn

1.2%

0.0%vs last monthflat vs last month

Recent activity

View all
  1. New subscriptionJane Cooper

    Acme Corp upgraded to the Team plan.

    2 minutes ago
  2. User invitedWade Warren

    dev@initech.example was invited to the workspace.

    18 minutes ago
  3. Payment receivedSystem

    $1,240.00 from Stark Industries.

    1 hour ago
  4. Report exportedEsther Howard

    Q1 revenue report exported as CSV.

    3 hours ago

Installation

npx visor add --block admin-dashboard

This copies files into your project:

  • blocks/admin-dashboard/admin-dashboard.tsx — the block component
  • blocks/admin-dashboard/admin-dashboard.module.css — the styles

The registry pulls in page-header, stat-card, activity-feed, and empty-state as dependencies.

Usage

'use client';

import { AdminDashboard } from '@/blocks/admin-dashboard/admin-dashboard';
import { Button } from '@/components/ui/button/button';

export default function DashboardPage() {
  return (
    <AdminDashboard
      eyebrow="Overview"
      title="Dashboard"
      description="A live snapshot of your workspace."
      actions={<Button>New report</Button>}
      stats={[
        {
          id: 'revenue',
          label: 'Total revenue',
          value: '$48,120',
          delta: { value: '+12.4%', direction: 'up', label: 'vs last month' },
          variant: 'highlight',
        },
        {
          id: 'active-users',
          label: 'Active users',
          value: '2,847',
          delta: { value: '+3.1%', direction: 'up' },
        },
      ]}
      activities={[
        {
          id: '1',
          title: 'New subscription',
          description: 'Acme Corp upgraded to the Team plan.',
          actor: 'Jane Cooper',
          timestamp: '2 minutes ago',
        },
      ]}
      activityViewAllHref="/admin/activity"
    />
  );
}

Drop this inside an AdminShell to get the full chrome — sidebar, topbar, and dashboard content in one composition.

Layout

The block is a vertical stack with consistent spacing:

  1. PageHeader — title, optional eyebrow, optional description, optional actions slot.
  2. Stat grid — responsive grid of StatCards. Driven by container queries: 1 column narrow, 2 columns at 36rem, 3 columns at 56rem, 4 columns at 72rem.
  3. Secondary region (optional) — a free-form slot for charts, announcements, or other widgets.
  4. Activity section — a <section aria-labelledby> with a title, optional "View all" link, and an ActivityFeed. Falls back to a subtle EmptyState when activities is empty.

Because the block uses container queries on its own root, it adapts to whatever column width the surrounding AdminShell hands it — no global breakpoints involved.

Empty State

If activities.length === 0, the block renders a default <EmptyState> with a "No recent activity" message. Pass your own activityEmptyState ReactNode to override it entirely.

Accessibility

  • The activity section is a semantic <section> with aria-labelledby pointing at the generated heading.
  • The activity heading is a level-2 <h2> — assumes the PageHeader title is the page's <h1>.
  • The "View all" link has a tokenized focus ring.

Props

PropTypeDefaultDescription
titleReactNodeRequired. Page title rendered in the PageHeader.
eyebrowReactNodeOptional small uppercase label above the title.
descriptionReactNodeOptional supporting copy below the title.
actionsReactNodeOptional actions slot on the right side of the header.
statsAdminDashboardStat[][]Stat cards rendered in the responsive grid.
activityTitleReactNode"Recent activity"Heading rendered above the activity feed.
activitiesAdminDashboardActivity[][]Activity events rendered in the feed.
activityViewAllHrefstringIf provided, renders a "View all" link in the activity section header.
activityEmptyStateReactNodeDefault EmptyStateReplaces the default EmptyState when activities is empty.
activityVariant"default" | "compact" | "timeline""default"Variant forwarded to the underlying ActivityFeed.
secondaryRegionReactNodeOptional region rendered below the stat grid and above the activity feed.
titleAs"h1" | "h2" | "h3""h1"Heading level used for the PageHeader title.
classNamestringAdditional CSS class on the root element.

AdminDashboardStat

PropTypeDefaultDescription
idstringRequired. Unique key for React list reconciliation.
labelReactNodeRequired. Stat label text.
valueReactNodeRequired. Stat value.
deltaStatCardDeltaOptional change indicator (value + direction).
trendReactNodeOptional trend visualization (sparkline, icon).
variant"default" | "highlight""default"Visual variant.
size"sm" | "md""md"Card size.

AdminDashboardActivity

PropTypeDefaultDescription
idstringRequired. Unique key for React list reconciliation.
leadingReactNodeOptional leading element (avatar, icon).
titleReactNodeRequired. Activity title.
descriptionReactNodeOptional detail text.
actorReactNodeOptional actor name/element.
timestampReactNodeRequired. When the activity occurred.
trailingReactNodeOptional trailing element (action button, badge).

About Blocks

Blocks are complete UI patterns made up of multiple Visor components. Unlike individual components, blocks represent larger, composed sections of UI — such as admin shells, login forms, or dashboard panels.

Blocks are copy-and-own, just like components. Install them into your project and customize freely.