Skip to content
dashboard-design logo

Dashboard Design

dashboard-design

Design effective dashboards with clear layouts, KPI displays, data grids, and real-time updates. Covers dashboard patterns, information hierarchy, responsive grids, widget design, and admin panel layouts. Use for building analytics dashboards, admin interfaces, and monitoring displays.

SKILL.md

Full skill instructions

Dashboard Design

Create effective, information-rich dashboards that surface key data clearly.

Instructions

  1. Prioritize information - Most important metrics at top-left
  2. Use consistent card layouts - Same styling for similar data types
  3. Design for scanning - Users glance, not read; make data obvious
  4. Show context - Compare to previous periods, show trends
  5. Enable action - Dashboards should lead to decisions

Dashboard Layout Patterns

Standard Admin Dashboard

function AdminDashboard() {
  return (
    <div className="min-h-screen bg-gray-100 dark:bg-gray-900">
      {/​* Top Navigation */​}
      <header className="sticky top-0 z-50 bg-white dark:bg-gray-800 border-b shadow-sm">
        <div className="flex items-center justify-between h-16 px-6">
          <Logo />
          <div className="flex items-center gap-4">
            <SearchInput />
            <NotificationBell />
            <UserMenu />
          </​div>
        </​div>
      </​header>

      <div className="flex">
        {/​* Sidebar Navigation */​}
        <aside className="hidden lg:block w-64 bg-white dark:bg-gray-800 border-r min-h-[calc(100vh-4rem)] sticky top-16">
          <nav className="p-4 space-y-2">
            <SidebarLink icon={HomeIcon} label="Overview" active />
            <SidebarLink icon={ChartIcon} label="Analytics" />
            <SidebarLink icon={UsersIcon} label="Customers" />
            <SidebarLink icon={SettingsIcon} label="Settings" />
          </​nav>
        </​aside>

        {/​* Main Content */​}
        <main className="flex-1 p-6">
          {/​* Page Header */​}
          <div className="mb-6">
            <h1 className="text-2xl font-bold text-gray-900 dark:text-white">
              Dashboard Overview
            </​h1>
            <p className="text-gray-500">Welcome back, here's what's happening</​p>
          </​div>

          {/​* KPI Cards Row */​}
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
            <KPICard
              title="Total Revenue"
              value="$45,231"
              change="+12.5%"
              trend="up"
            />
            <KPICard
              title="Active Users"
              value="2,345"
              change="+5.2%"
              trend="up"
            />
            <KPICard
              title="Conversion Rate"
              value="3.2%"
              change="-0.4%"
              trend="down"
            />
            <KPICard
              title="Avg. Order Value"
              value="$127"
              change="+8.1%"
              trend="up"
            />
          </​div>

          {/​* Charts Row */​}
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
            <ChartCard title="Revenue Over Time">
              <LineChart data={revenueData} />
            </​ChartCard>
            <ChartCard title="Sales by Category">
              <BarChart data={categoryData} />
            </​ChartCard>
          </​div>

          {/​* Data Table */​}
          <Card>
            <CardHeader>
              <CardTitle>Recent Orders</​CardTitle>
              <Button variant="outline" size="sm">View All</​Button>
            </​CardHeader>
            <DataTable
              columns={orderColumns}
              data={recentOrders}
              pagination
            />
          </​Card>
        </​main>
      </​div>
    </​div>
  );
}

KPI Card Component

interface KPICardProps {
  title: string;
  value: string | number;
  change?: string;
  trend?: 'up' | 'down' | 'neutral';
  icon?: React.ComponentType;
  subtitle?: string;
}

function KPICard({ title, value, change, trend, icon: Icon, subtitle }: KPICardProps) {
  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-sm border border-gray-200 dark:border-gray-700">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-medium text-gray-500 dark:text-gray-400">
            {title}
          </​p>
          <p className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">
            {value}
          </​p>
          {change && (
            <div className="mt-2 flex items-center gap-1">
              {trend === 'up' && (
                <ArrowUpIcon className="w-4 h-4 text-green-500" />
              )}
              {trend === 'down' && (
                <ArrowDownIcon className="w-4 h-4 text-red-500" />
              )}
              <span className={`text-sm font-medium ${
                trend === 'up' ? 'text-green-600' :
                trend === 'down' ? 'text-red-600' :
                'text-gray-500'
              }`}>
                {change}
              </​span>
              <span className="text-sm text-gray-400">vs last month</​span>
            </​div>
          )}
        </​div>
        {Icon && (
          <div className="p-3 bg-blue-50 dark:bg-blue-900/​20 rounded-lg">
            <Icon className="w-6 h-6 text-blue-600 dark:text-blue-400" />
          </​div>
        )}
      </​div>
    </​div>
  );
}

Chart Card Component

interface ChartCardProps {
  title: string;
  subtitle?: string;
  action?: React.ReactNode;
  children: React.ReactNode;
}

function ChartCard({ title, subtitle, action, children }: ChartCardProps) {
  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
      <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700">
        <div>
          <h3 className="font-semibold text-gray-900 dark:text-white">{title}</​h3>
          {subtitle && (
            <p className="text-sm text-gray-500">{subtitle}</​p>
          )}
        </​div>
        {action}
      </​div>
      <div className="p-6">
        {children}
      </​div>
    </​div>
  );
}

Dashboard Grid Patterns

Responsive Dashboard Grid

// 12-column grid system
<div className="grid grid-cols-12 gap-6">
  {/​* Full width */​}
  <div className="col-span-12">
    <PageHeader />
  </​div>

  {/​* 4 equal KPI cards */​}
  <div className="col-span-12 sm:col-span-6 lg:col-span-3">
    <KPICard />
  </​div>
  <div className="col-span-12 sm:col-span-6 lg:col-span-3">
    <KPICard />
  </​div>
  <div className="col-span-12 sm:col-span-6 lg:col-span-3">
    <KPICard />
  </​div>
  <div className="col-span-12 sm:col-span-6 lg:col-span-3">
    <KPICard />
  </​div>

  {/​* 2/​3 + 1/​3 layout */​}
  <div className="col-span-12 lg:col-span-8">
    <MainChart />
  </​div>
  <div className="col-span-12 lg:col-span-4">
    <SidePanel />
  </​div>

  {/​* 50/​50 split */​}
  <div className="col-span-12 md:col-span-6">
    <ChartA />
  </​div>
  <div className="col-span-12 md:col-span-6">
    <ChartB />
  </​div>
</​div>

Real-Time Dashboard

function RealTimeDashboard() {
  const [metrics, setMetrics] = useState<Metrics | null>(null);

  useEffect(() => {
    // WebSocket for real-time updates
    const ws = new WebSocket('wss://api.example.com/​metrics');

    ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      setMetrics(data);
    };

    return () => ws.close();
  }, []);

  return (
    <div className="space-y-6">
      {/​* Live indicator */​}
      <div className="flex items-center gap-2">
        <span className="relative flex h-3 w-3">
          <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" />
          <span className="relative inline-flex rounded-full h-3 w-3 bg-green-500" />
        </​span>
        <span className="text-sm text-gray-500">Live</​span>
        <span className="text-sm text-gray-400">
          Updated {formatRelativeTime(metrics?.timestamp)}
        </​span>
      </​div>

      {/​* Real-time metrics */​}
      <div className="grid grid-cols-4 gap-4">
        <LiveMetric
          label="Active Users"
          value={metrics?.activeUsers}
          sparkline={metrics?.userHistory}
        />
        <LiveMetric
          label="Requests/​sec"
          value={metrics?.requestsPerSecond}
          unit="req/​s"
        />
        <LiveMetric
          label="Avg Response"
          value={metrics?.avgResponseTime}
          unit="ms"
        />
        <LiveMetric
          label="Error Rate"
          value={metrics?.errorRate}
          unit="%"
          alert={metrics?.errorRate > 1}
        />
      </​div>
    </​div>
  );
}

Data Table for Dashboards

interface DataTableProps<T> {
  columns: ColumnDef<T>[];
  data: T[];
  pagination?: boolean;
  searchable?: boolean;
  actions?: (row: T) => React.ReactNode;
}

function DataTable<T>({ columns, data, pagination, searchable }: DataTableProps<T>) {
  const [search, setSearch] = useState('');
  const [page, setPage] = useState(1);
  const pageSize = 10;

  const filteredData = useMemo(() => {
    if (!search) return data;
    return data.filter(row =>
      Object.values(row).some(val =>
        String(val).toLowerCase().includes(search.toLowerCase())
      )
    );
  }, [data, search]);

  const paginatedData = useMemo(() => {
    if (!pagination) return filteredData;
    const start = (page - 1) * pageSize;
    return filteredData.slice(start, start + pageSize);
  }, [filteredData, page, pagination]);

  return (
    <div>
      {searchable && (
        <div className="mb-4">
          <input
            type="search"
            placeholder="Search..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="px-4 py-2 border rounded-lg w-full max-w-sm"
          />
        </​div>
      )}

      <div className="overflow-x-auto">
        <table className="w-full">
          <thead className="bg-gray-50 dark:bg-gray-800">
            <tr>
              {columns.map(col => (
                <th key={col.key} className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                  {col.header}
                </​th>
              ))}
            </​tr>
          </​thead>
          <tbody className="divide-y divide-gray-200 dark:divide-gray-700">
            {paginatedData.map((row, i) => (
              <tr key={i} className="hover:bg-gray-50 dark:hover:bg-gray-800">
                {columns.map(col => (
                  <td key={col.key} className="px-6 py-4 whitespace-nowrap text-sm">
                    {col.render ? col.render(row) : row[col.key]}
                  </​td>
                ))}
              </​tr>
            ))}
          </​tbody>
        </​table>
      </​div>

      {pagination && (
        <Pagination
          page={page}
          totalPages={Math.ceil(filteredData.length / pageSize)}
          onPageChange={setPage}
        />
      )}
    </​div>
  );
}

Best Practices

  1. 5-second rule - Key metrics should be understood in 5 seconds
  2. Above the fold - Critical data visible without scrolling
  3. Consistent time ranges - All charts use same time period
  4. Progressive disclosure - Summary → details on demand
  5. Empty states - Show meaningful content when no data
  6. Loading states - Skeleton screens while loading

When to Use

  • Building admin panels and back-office tools
  • Creating analytics dashboards
  • Monitoring systems and real-time displays
  • Data-heavy business applications
  • Internal tools and management interfaces

Notes

  • Consider user role - executives vs analysts have different needs
  • Mobile dashboards need different layouts, not just responsive
  • Performance matters - virtualize long lists, lazy load charts
  • Allow customization - users can arrange their own dashboards

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View