skills/creating-dashboards/examples/executive-dashboard.tsx

200 lines
6.1 KiB
TypeScript

import React from 'react';
import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import { TrendingUp, TrendingDown, Users, DollarSign, ShoppingCart, Activity } from 'lucide-react';
/**
* Executive Dashboard Example
*
* High-level KPIs for leadership with:
* - Revenue, users, conversion, growth metrics
* - Trend indicators (up/down)
* - Comparison to previous period
* - Revenue trend chart (6 months)
* - Top products bar chart
*/
interface KPICardProps {
title: string;
value: string;
change: number;
changeLabel: string;
icon: React.ReactNode;
positive?: boolean;
}
function KPICard({ title, value, change, changeLabel, icon, positive = true }: KPICardProps) {
const isPositive = change >= 0;
const trendColor = (isPositive && positive) || (!isPositive && !positive) ? '#10b981' : '#ef4444';
return (
<div style={{
backgroundColor: '#fff',
border: '1px solid #e2e8f0',
borderRadius: '12px',
padding: '24px',
display: 'flex',
flexDirection: 'column',
gap: '8px',
}}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<span style={{ color: '#64748b', fontSize: '14px', fontWeight: 500 }}>{title}</span>
<div style={{ color: '#94a3b8' }}>{icon}</div>
</div>
<div style={{ fontSize: '32px', fontWeight: 700, color: '#0f172a' }}>
{value}
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '4px', fontSize: '14px' }}>
{isPositive ? (
<TrendingUp size={16} color={trendColor} />
) : (
<TrendingDown size={16} color={trendColor} />
)}
<span style={{ color: trendColor, fontWeight: 600 }}>
{Math.abs(change)}%
</span>
<span style={{ color: '#64748b' }}>{changeLabel}</span>
</div>
</div>
);
}
const revenueData = [
{ month: 'Jul', revenue: 42000 },
{ month: 'Aug', revenue: 45000 },
{ month: 'Sep', revenue: 51000 },
{ month: 'Oct', revenue: 49000 },
{ month: 'Nov', revenue: 58000 },
{ month: 'Dec', revenue: 63000 },
];
const productData = [
{ product: 'Pro Plan', sales: 125000 },
{ product: 'Enterprise', sales: 98000 },
{ product: 'Starter', sales: 67000 },
{ product: 'Add-ons', sales: 34000 },
];
export function ExecutiveDashboard() {
return (
<div style={{ padding: '24px', backgroundColor: '#f8fafc', minHeight: '100vh' }}>
<h1 style={{ fontSize: '30px', fontWeight: 700, marginBottom: '24px', color: '#0f172a' }}>
Executive Dashboard
</h1>
{/* KPI Cards */}
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
gap: '16px',
marginBottom: '24px',
}}>
<KPICard
title="Total Revenue"
value="$63,000"
change={8.6}
changeLabel="vs. last month"
icon={<DollarSign size={24} />}
positive={true}
/>
<KPICard
title="Active Users"
value="12,543"
change={12.4}
changeLabel="vs. last month"
icon={<Users size={24} />}
positive={true}
/>
<KPICard
title="Conversion Rate"
value="3.8%"
change={-2.1}
changeLabel="vs. last month"
icon={<ShoppingCart size={24} />}
positive={true}
/>
<KPICard
title="MRR Growth"
value="18.2%"
change={5.3}
changeLabel="vs. last quarter"
icon={<Activity size={24} />}
positive={true}
/>
</div>
{/* Charts Grid */}
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))',
gap: '16px',
}}>
{/* Revenue Trend */}
<div style={{
backgroundColor: '#fff',
border: '1px solid #e2e8f0',
borderRadius: '12px',
padding: '24px',
}}>
<h2 style={{ fontSize: '18px', fontWeight: 600, marginBottom: '16px', color: '#0f172a' }}>
Revenue Trend (6 Months)
</h2>
<ResponsiveContainer width="100%" height={300}>
<LineChart data={revenueData}>
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
<XAxis dataKey="month" stroke="#64748b" />
<YAxis stroke="#64748b" />
<Tooltip
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #e2e8f0',
borderRadius: '8px',
}}
/>
<Line
type="monotone"
dataKey="revenue"
stroke="#3b82f6"
strokeWidth={3}
dot={{ fill: '#3b82f6', r: 4 }}
activeDot={{ r: 6 }}
/>
</LineChart>
</ResponsiveContainer>
</div>
{/* Top Products */}
<div style={{
backgroundColor: '#fff',
border: '1px solid #e2e8f0',
borderRadius: '12px',
padding: '24px',
}}>
<h2 style={{ fontSize: '18px', fontWeight: 600, marginBottom: '16px', color: '#0f172a' }}>
Revenue by Product
</h2>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={productData} layout="vertical">
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
<XAxis type="number" stroke="#64748b" />
<YAxis dataKey="product" type="category" stroke="#64748b" width={100} />
<Tooltip
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #e2e8f0',
borderRadius: '8px',
}}
formatter={(value) => `$${value.toLocaleString()}`}
/>
<Bar dataKey="sales" fill="#3b82f6" radius={[0, 8, 8, 0]} />
</BarChart>
</ResponsiveContainer>
</div>
</div>
</div>
);
}
export default ExecutiveDashboard;