Use Cases

How to Build an Admin Dashboard with Claude Code

Learn how to build an admin dashboard using Claude Code. Includes practical code examples and step-by-step guidance.

Building an Admin Dashboard With Claude Code

Admin dashboards are complex applications that contain many screens: KPI displays, user management, analytics, and more. With Claude Code, you can quickly build a full-featured dashboard with sidebar navigation, data tables, and charts.

Dashboard Layout

> Build an admin dashboard in React + Tailwind CSS.
> Use a three-column layout with sidebar navigation, header, and main content.
> Display KPI cards, a sales chart, and a recent orders table.
// src/components/DashboardLayout.tsx
import { ReactNode, useState } from 'react';
import { Sidebar } from './Sidebar';
import { Header } from './Header';

export function DashboardLayout({ children }: { children: ReactNode }) {
  const [isSidebarOpen, setSidebarOpen] = useState(true);

  return (
    <div className="flex h-screen bg-gray-50 dark:bg-gray-900">
      <Sidebar isOpen={isSidebarOpen} onToggle={() => setSidebarOpen(!isSidebarOpen)} />
      <div className="flex-1 flex flex-col overflow-hidden">
        <Header onMenuClick={() => setSidebarOpen(!isSidebarOpen)} />
        <main className="flex-1 overflow-y-auto p-6">
          {children}
        </main>
      </div>
    </div>
  );
}

KPI Card Component

// src/components/KpiCard.tsx
interface KpiCardProps {
  title: string;
  value: string;
  change: number;
  icon: ReactNode;
}

export function KpiCard({ title, value, change, icon }: KpiCardProps) {
  const isPositive = change >= 0;

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-sm">
      <div className="flex items-center justify-between mb-4">
        <span className="text-gray-500 dark:text-gray-400 text-sm">{title}</span>
        <div className="p-2 bg-blue-50 dark:bg-blue-900/30 rounded-lg">{icon}</div>
      </div>
      <div className="text-2xl font-bold dark:text-white mb-1">{value}</div>
      <div className={`text-sm flex items-center gap-1 ${isPositive ? 'text-green-500' : 'text-red-500'}`}>
        <span>{isPositive ? '↑' : '↓'}</span>
        <span>{Math.abs(change)}%</span>
        <span className="text-gray-400 ml-1">vs last month</span>
      </div>
    </div>
  );
}

Integrating the Sales Chart

// src/components/SalesChart.tsx
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';

const salesData = [
  { month: 'Jan', revenue: 42000, orders: 320 },
  { month: 'Feb', revenue: 38000, orders: 290 },
  { month: 'Mar', revenue: 51000, orders: 410 },
  { month: 'Apr', revenue: 47000, orders: 380 },
  { month: 'May', revenue: 56000, orders: 450 },
  { month: 'Jun', revenue: 62000, orders: 510 },
];

export function SalesChart() {
  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-sm">
      <h3 className="text-lg font-semibold dark:text-white mb-4">Sales Trend</h3>
      <ResponsiveContainer width="100%" height={300}>
        <AreaChart data={salesData}>
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="month" />
          <YAxis tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`} />
          <Tooltip
            formatter={(value: number) => `$${value.toLocaleString()}`}
          />
          <Area
            type="monotone"
            dataKey="revenue"
            stroke="#3B82F6"
            fill="#3B82F6"
            fillOpacity={0.1}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  );
}

Data Table

// src/components/RecentOrders.tsx
interface Order {
  id: string;
  customer: string;
  amount: number;
  status: 'completed' | 'pending' | 'cancelled';
  date: string;
}

const statusStyles = {
  completed: 'bg-green-100 text-green-800',
  pending: 'bg-yellow-100 text-yellow-800',
  cancelled: 'bg-red-100 text-red-800',
};

const statusLabels = {
  completed: 'Completed',
  pending: 'Pending',
  cancelled: 'Cancelled',
};

export function RecentOrders({ orders }: { orders: Order[] }) {
  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm overflow-hidden">
      <div className="p-6 border-b dark:border-gray-700">
        <h3 className="text-lg font-semibold dark:text-white">Recent Orders</h3>
      </div>
      <table className="w-full">
        <thead className="bg-gray-50 dark:bg-gray-700">
          <tr>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Order ID</th>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Customer</th>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Amount</th>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Status</th>
          </tr>
        </thead>
        <tbody className="divide-y dark:divide-gray-700">
          {orders.map((order) => (
            <tr key={order.id} className="hover:bg-gray-50 dark:hover:bg-gray-700/50">
              <td className="px-6 py-4 text-sm dark:text-gray-300">{order.id}</td>
              <td className="px-6 py-4 text-sm dark:text-gray-300">{order.customer}</td>
              <td className="px-6 py-4 text-sm dark:text-gray-300">${order.amount.toLocaleString()}</td>
              <td className="px-6 py-4">
                <span className={`text-xs px-2 py-1 rounded-full ${statusStyles[order.status]}`}>
                  {statusLabels[order.status]}
                </span>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

For data visualization, see data visualization implementation, and for role-based access control, see the RBAC implementation guide.

The Recharts official documentation is also useful for chart customization.

#Claude Code #dashboard #React #data visualization #Recharts

Level up your Claude Code workflow

50 battle-tested prompt templates you can copy-paste into Claude Code right now.

Free

Free PDF: Claude Code Cheatsheet in 5 Minutes

Key commands, shortcuts, and prompt examples on a single printable page.

Download PDF
M

About the Author

Masa

Engineer obsessed with Claude Code. Runs claudecode-lab.com, a 10-language tech media with 2,000+ pages.