Use Cases

How to Build an Admin Dashboard: Claude Code 활용 가이드

build an admin dashboard: Claude Code 활용. 실용적인 코드 예시와 단계별 가이드를 포함합니다.

관리ダッシュボードをClaude Code로 구축하기

관리ダッシュボードは、KPI표시、사용자관리、데이터分析など多くの画面を含む複雑な애플리케이션です。Claude Code를 활용하면 사이드바내비게이션、데이터테이블、チャートを備えた本格的なダッシュボードを빠르게作れます。

ダッシュボード레이아웃

> React + Tailwind CSSで관리ダッシュボードを作って。
> 사이드바내비게이션、헤더、メイン콘텐츠の3カラム레이아웃で。
> KPIカード、売上チャート、最近の注文테이블を표시して。
// 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カード컴포넌트

// 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">前月比</span>
      </div>
    </div>
  );
}

売上チャートの통합

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

const salesData = [
  { month: '1月', revenue: 4200000, orders: 320 },
  { month: '2月', revenue: 3800000, orders: 290 },
  { month: '3月', revenue: 5100000, orders: 410 },
  { month: '4月', revenue: 4700000, orders: 380 },
  { month: '5月', revenue: 5600000, orders: 450 },
  { month: '6月', revenue: 6200000, 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">売上推移</h3>
      <ResponsiveContainer width="100%" height={300}>
        <AreaChart data={salesData}>
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="month" />
          <YAxis tickFormatter={(v) => `$${(v / 10000).toFixed(0)}万`} />
          <Tooltip
            formatter={(value: number) => `$${value.toLocaleString()}`}
          />
          <Area
            type="monotone"
            dataKey="revenue"
            stroke="#3B82F6"
            fill="#3B82F6"
            fillOpacity={0.1}
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  );
}

데이터테이블

// 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: '完了',
  pending: '処理中',
  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">最近の注文</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">注文ID</th>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">顧客名</th>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">金額</th>
            <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">ステータス</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>
  );
}

関連リソース

데이터の可視化에 대해서는데이터可視化の구현、ロールベースのアクセス制御はRBAC구현가이드를 참고하세요.

Recharts의 공식 문서(recharts.org)もチャートの커스터마이징に便利です。

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