JSX
Copy
// Leaderboards and mini tables: a recent-orders table with status badges, a sales leaderboard with
// quota bars, and a top-products list. The tables are real <table>s that scroll inside a focusable,
// labelled region on narrow screens.
// Usage: <Leaderboards orders={[…]} reps={[…]} products={[…]} /> — all props have demo data.
import { useId } from 'react';
const STATUS = {
paid: { label: 'Paid', cls: 'text-[#166534] bg-[#dcfce7]', icon: <path d="M20 6 9 17l-5-5" /> },
pending: { label: 'Pending', cls: 'text-[#92400e] bg-[#fef3c7]', icon: <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></> },
shipped: { label: 'Shipped', cls: 'text-[#1e40af] bg-[#dbeafe]', icon: <><path d="M1 3h15v13H1zM16 8h4l3 3v5h-7z" /><circle cx="5.5" cy="18.5" r="2.5" /><circle cx="18.5" cy="18.5" r="2.5" /></> },
refunded: { label: 'Refunded', cls: 'text-[#334155] bg-[#e2e8f0]', icon: <><path d="M3 7v6h6" /><path d="M21 17a9 9 0 0 0-15-6.7L3 13" /></> },
failed: { label: 'Failed', cls: 'text-[#991b1b] bg-[#fee2e2]', icon: <><circle cx="12" cy="12" r="9" /><path d="M15 9l-6 6M9 9l6 6" /></> },
};
const defaultOrders = [
{ id: '#10491', customer: 'Hana Kim', date: '2026-10-16', total: 248, status: 'paid' },
{ id: '#10490', customer: 'Diego Alvarez', date: '2026-10-16', total: 1120.5, status: 'pending' },
{ id: '#10489', customer: 'Freya Lund', date: '2026-10-15', total: 76.4, status: 'shipped' },
{ id: '#10488', customer: 'Omar Haddad', date: '2026-10-15', total: 312.99, status: 'refunded' },
{ id: '#10487', customer: 'Chloe Martin', date: '2026-10-15', total: 59, status: 'failed' },
];
const defaultReps = [
{ name: 'Sofia Reyes', initials: 'SR', color: 'bg-[#1f5fae]', segment: 'Enterprise', deals: 18, revenue: 412600, quota: 128 },
{ name: 'Marcus Lee', initials: 'ML', color: 'bg-[#0f766e]', segment: 'Mid-market', deals: 26, revenue: 298400, quota: 112 },
{ name: 'Aisha Bello', initials: 'AB', color: 'bg-[#9333ea]', segment: 'Enterprise', deals: 11, revenue: 276900, quota: 104 },
{ name: 'Tomás Ruiz', initials: 'TR', color: 'bg-[#c2410c]', segment: 'SMB', deals: 41, revenue: 188250, quota: 94 },
{ name: 'Emma Novak', initials: 'EN', color: 'bg-[#475569]', segment: 'Mid-market', deals: 19, revenue: 171300, quota: 86 },
];
const defaultProducts = [
{ name: 'Linen throw blanket', category: 'Home', sold: 1284, revenue: 82176 },
{ name: 'Ceramic pour-over set', category: 'Kitchen', sold: 962, revenue: 45214 },
{ name: 'Merino beanie', category: 'Apparel', sold: 875, revenue: 26250 },
{ name: 'Oak serving board', category: 'Kitchen', sold: 640, revenue: 24960 },
{ name: 'Beeswax candle trio', category: 'Home', sold: 588, revenue: 17052 },
];
const MEDALS = ['bg-[#fde68a] text-[#713f12]', 'bg-[#e2e8f0] text-[#1e293b]', 'bg-[#fed7aa] text-[#7c2d12]'];
const money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
const money0 = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
const num = new Intl.NumberFormat('en-US');
const shortDate = (iso) => new Date(`${iso}T12:00:00`).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
const panel = 'min-w-0 overflow-hidden rounded-2xl border border-[#e2e8f0] bg-white text-[#0f172a] shadow-[0_1px_2px_rgba(15,23,42,.04),0_8px_24px_rgba(15,23,42,.05)]';
const link = 'rounded font-semibold text-[#1f5fae] no-underline hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1f5fae]';
const cell = 'border-t border-[#e2e8f0] px-[18px] py-[11px] align-middle';
const headCell = `${cell} bg-[#f8fafc] text-[.72rem] font-semibold tracking-[.06em] text-[#4b5768] uppercase`;
const label = 'mb-4 block text-[.72rem] tracking-[.12em] text-[#4b5768] uppercase';
// A table that scrolls sideways inside a keyboard-focusable region named by the card title.
function ScrollTable({ labelledBy, caption, columns, children }) {
return (
<div className="overflow-x-auto focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1f5fae]" role="region" aria-labelledby={labelledBy} tabIndex={0}>
<table className="w-full border-collapse text-left text-[.86rem] whitespace-nowrap">
<caption className="sr-only">{caption}</caption>
<thead>
<tr>
{columns.map((c) => (
<th key={c.label} scope="col" className={`${headCell} ${c.right ? 'text-right' : ''}`}>{c.label}</th>
))}
</tr>
</thead>
<tbody>{children}</tbody>
</table>
</div>
);
}
function StatusBadge({ status }) {
const s = STATUS[status];
return (
<span className={`inline-flex items-center gap-[5px] rounded-full py-0.5 pr-[9px] pl-[7px] text-[.76rem] font-bold ${s.cls}`}>
<svg className="size-[13px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{s.icon}</svg>
{s.label}
</span>
);
}
function RecentOrders({ orders }) {
const titleId = useId();
return (
<section className={panel} aria-labelledby={titleId}>
<div className="flex items-center justify-between gap-3 px-[18px] py-4">
<div><h3 className="text-base font-bold" id={titleId}>Recent orders</h3><p className="text-[.78rem] text-[#4b5768]">Fernhill Goods · 5 of 184 this week</p></div>
<a href="#" className={`whitespace-nowrap ${link}`}>View all orders</a>
</div>
<ScrollTable labelledBy={titleId} caption="Recent orders, newest first" columns={[{ label: 'Order' }, { label: 'Customer' }, { label: 'Date' }, { label: 'Total', right: true }, { label: 'Status' }]}>
{orders.map((o) => (
<tr key={o.id} className="hover:bg-[#f8fafc]">
<th scope="row" className={`${cell} font-semibold`}><a href="#" className={link}>{o.id}</a></th>
<td className={cell}>{o.customer}</td>
<td className={cell}><time dateTime={o.date}>{shortDate(o.date)}</time></td>
<td className={`${cell} text-right tabular-nums`}>{money.format(o.total)}</td>
<td className={cell}><StatusBadge status={o.status} /></td>
</tr>
))}
</ScrollTable>
</section>
);
}
function SalesLeaderboard({ reps }) {
const titleId = useId();
return (
<section className={panel} aria-labelledby={titleId}>
<div className="px-[18px] py-4"><h3 className="text-base font-bold" id={titleId}>Top sales reps</h3><p className="text-[.78rem] text-[#4b5768]">Q3 2026 · closed-won revenue</p></div>
<ScrollTable labelledBy={titleId} caption="Top sales reps by revenue, Q3 2026" columns={[{ label: 'Rank' }, { label: 'Rep' }, { label: 'Deals', right: true }, { label: 'Revenue', right: true }, { label: 'Quota', right: true }]}>
{reps.map((r, i) => (
<tr key={r.name} className="hover:bg-[#f8fafc]">
<td className={cell}><span className={`inline-grid size-7 place-items-center rounded-full text-[.82rem] font-bold tabular-nums ${MEDALS[i] ?? 'text-[#4b5768]'}`}>{i + 1}</span></td>
<th scope="row" className={`${cell} font-semibold`}>
<span className="flex items-center gap-2.5">
<span className={`grid size-[34px] flex-none place-items-center rounded-full ${r.color} text-[.74rem] font-bold text-white`} aria-hidden="true">{r.initials}</span>
<span><b className="block font-semibold">{r.name}</b><small className="block text-[.76rem] font-normal text-[#4b5768]">{r.segment}</small></span>
</span>
</th>
<td className={`${cell} text-right tabular-nums`}>{r.deals}</td>
<td className={`${cell} text-right tabular-nums`}>{money0.format(r.revenue)}</td>
<td className={cell}>
<span className="flex items-center justify-end gap-2.5">
<span className="relative block h-1.5 w-[90px] overflow-hidden rounded-full bg-[#e2e8f0]" aria-hidden="true">
<i className={`absolute inset-y-0 left-0 rounded-full ${r.quota >= 100 ? 'bg-[#15803d]' : 'bg-[#2a78d6]'}`} style={{ width: `${Math.min(100, r.quota)}%` }} />
</span>
<span className="min-w-[4ch] text-right font-semibold tabular-nums">{r.quota}%</span>
</span>
</td>
</tr>
))}
</ScrollTable>
</section>
);
}
function TopProducts({ products }) {
const titleId = useId();
const total = products.reduce((a, p) => a + p.revenue, 0);
return (
<section className={panel} aria-labelledby={titleId}>
<div className="flex items-center justify-between gap-3 px-[18px] py-4">
<div><h3 className="text-base font-bold" id={titleId}>Best-selling products</h3><p className="text-[.78rem] text-[#4b5768]">October 1–15 · by revenue</p></div>
<a href="#" className={`whitespace-nowrap ${link}`}>Report</a>
</div>
<ol className="px-[18px] pb-2">
{products.map((p, i) => {
const share = Math.round((p.revenue / total) * 100);
return (
<li key={p.name} className="flex gap-3.5 border-t border-[#e2e8f0] py-3">
<span className="grid size-7 flex-none place-items-center rounded-lg bg-[#f1f5f9] text-[.82rem] font-bold text-[#4b5768]" aria-hidden="true">{i + 1}</span>
<div className="flex min-w-0 flex-1 flex-col gap-[3px]">
<div className="flex justify-between gap-3 text-[.9rem]"><b className="font-semibold">{p.name}</b><span className="font-bold tabular-nums">{money0.format(p.revenue)}</span></div>
<div className="flex justify-between gap-3 text-[.76rem] text-[#4b5768]"><span>{p.category} · {num.format(p.sold)} sold</span><span className="tabular-nums">{share}% of top {products.length}</span></div>
<span className="relative mt-1 block h-1.5 w-full overflow-hidden rounded-full bg-[#e2e8f0]" aria-hidden="true">
<i className="absolute inset-y-0 left-0 rounded-full bg-[#2a78d6]" style={{ width: `${share}%` }} />
</span>
</div>
</li>
);
})}
</ol>
</section>
);
}
export default function Leaderboards({ orders = defaultOrders, reps = defaultReps, products = defaultProducts }) {
return (
<div className="grid grid-cols-1 items-start gap-x-[22px] gap-y-[46px] lg:grid-cols-[minmax(0,7fr)_minmax(0,5fr)]">
<div className="col-span-full"><span className={label}>Recent orders table</span><RecentOrders orders={orders} /></div>
<div><span className={label}>Sales leaderboard</span><SalesLeaderboard reps={reps} /></div>
<div><span className={label}>Top items list</span><TopProducts products={products} /></div>
</div>
);
}