Blox/
Stats Dashboard
An analytics dashboard with stat cards, bar charts, progress bars, and data tables. Perfect for admin panels and reporting interfaces.
Stat CardsChartsData Table
Installation
Terminal
TSXReactTailwind
npx @uiblox/cli add stats-dashboardPreview
Revenue
$45.2k+20.1%
Users
2,350+15.3%
Conv. Rate
3.2%-2.1%
Revenue
Recent Activity
John Doe
Purchased Pro
Jane Smith
Updated Profile
Bob Johnson
Support Ticket
Source Code
stats-dashboard.tsx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115export function StatsDashboard() { const stats = [ { label: "Total Revenue", value: "$45,231", change: "+20.1%", trend: "up", icon: "dollar" }, { label: "Active Users", value: "2,350", change: "+15.3%", trend: "up", icon: "users" }, { label: "Conversion Rate", value: "3.2%", change: "-2.1%", trend: "down", icon: "chart" }, { label: "Avg. Session", value: "4m 32s", change: "+8.4%", trend: "up", icon: "clock" }, ]; return ( <div className="space-y-6"> {/* Stats Grid */} <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"> {stats.map((stat) => ( <div key={stat.label} className="p-6 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800"> <div className="flex items-center justify-between mb-4"> <span className="text-sm font-medium text-slate-500">{stat.label}</span> <StatIcon name={stat.icon} /> </div> <div className="flex items-end justify-between"> <span className="text-2xl font-bold text-slate-900 dark:text-white">{stat.value}</span> <span className={`text-sm font-medium ${stat.trend === "up" ? "text-emerald-600" : "text-red-600"}`}> {stat.change} </span> </div> </div> ))} </div> {/* Chart Area */} <div className="grid grid-cols-1 lg:grid-cols-3 gap-4"> <div className="lg:col-span-2 p-6 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800"> <h3 className="text-lg font-semibold text-slate-900 dark:text-white mb-4">Revenue Overview</h3> <div className="h-64 flex items-end gap-2"> {[40, 65, 45, 80, 55, 70, 85, 60, 75, 90, 65, 80].map((h, i) => ( <div key={i} className="flex-1 bg-purple-500/20 rounded-t" style={{ height: `${h}%` }}> <div className="w-full bg-purple-500 rounded-t" style={{ height: "60%" }} /> </div> ))} </div> <div className="flex justify-between mt-2 text-xs text-slate-500"> <span>Jan</span><span>Feb</span><span>Mar</span><span>Apr</span><span>May</span><span>Jun</span> <span>Jul</span><span>Aug</span><span>Sep</span><span>Oct</span><span>Nov</span><span>Dec</span> </div> </div> <div className="p-6 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800"> <h3 className="text-lg font-semibold text-slate-900 dark:text-white mb-4">Top Sources</h3> <div className="space-y-4"> {[ { name: "Google", value: 42, color: "bg-purple-500" }, { name: "Direct", value: 28, color: "bg-cyan-500" }, { name: "Twitter", value: 18, color: "bg-emerald-500" }, { name: "GitHub", value: 12, color: "bg-amber-500" }, ].map((source) => ( <div key={source.name}> <div className="flex justify-between text-sm mb-1"> <span className="text-slate-700 dark:text-slate-300">{source.name}</span> <span className="text-slate-500">{source.value}%</span> </div> <div className="h-2 bg-slate-100 dark:bg-slate-800 rounded-full overflow-hidden"> <div className={`h-full ${source.color} rounded-full`} style={{ width: `${source.value}%` }} /> </div> </div> ))} </div> </div> </div> {/* Recent Activity */} <div className="p-6 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800"> <h3 className="text-lg font-semibold text-slate-900 dark:text-white mb-4">Recent Activity</h3> <div className="overflow-x-auto"> <table className="w-full"> <thead> <tr className="border-b border-slate-200 dark:border-slate-800"> <th className="text-left py-3 px-4 text-sm font-medium text-slate-500">User</th> <th className="text-left py-3 px-4 text-sm font-medium text-slate-500">Action</th> <th className="text-left py-3 px-4 text-sm font-medium text-slate-500">Date</th> <th className="text-left py-3 px-4 text-sm font-medium text-slate-500">Status</th> </tr> </thead> <tbody> {[ { user: "John Doe", action: "Purchased Pro Plan", date: "2 min ago", status: "Completed" }, { user: "Jane Smith", action: "Updated Profile", date: "15 min ago", status: "Completed" }, { user: "Bob Johnson", action: "Submitted Support Ticket", date: "1 hour ago", status: "Pending" }, ].map((row, i) => ( <tr key={i} className="border-b border-slate-100 dark:border-slate-800"> <td className="py-3 px-4 text-sm text-slate-900 dark:text-white">{row.user}</td> <td className="py-3 px-4 text-sm text-slate-600 dark:text-slate-400">{row.action}</td> <td className="py-3 px-4 text-sm text-slate-500">{row.date}</td> <td className="py-3 px-4"> <span className={`px-2 py-1 text-xs font-medium rounded-full ${ row.status === "Completed" ? "bg-emerald-100 text-emerald-700" : "bg-amber-100 text-amber-700" }`}>{row.status}</span> </td> </tr> ))} </tbody> </table> </div> </div> </div> ); } function StatIcon({ name }: { name: string }) { const icons: Record<string, JSX.Element> = { dollar: <svg className="w-5 h-5 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>, users: <svg className="w-5 h-5 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" /></svg>, chart: <svg className="w-5 h-5 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" /></svg>, clock: <svg className="w-5 h-5 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>, }; return icons[name] || null; }