Section
Dashboard Overview — Vercel
Refined dark monochrome analytics dashboard overview with KPI stat cards and trend deltas, a pure-SVG area + line chart, a recent-activity feed, and a wired 7d/30d/90d range selector that swaps hardcoded datasets live. Hairline borders, generous spacing, and a single teal accent.
- Section
- Tailwind
- HTML
- MIT
Preview
Live section
9:41 100%
devsnips.dev/library/tailwind/sections/app-ui/dashboard-overview/vercel/ fluid · no fixed width 100%
Install
Add to your project
npx devsnips add Tailwind/Sections/App-UI/dashboard-overview/vercel Tailwind/Sections/App-UI/dashboard-overview/vercel <!--
Snippet Name: Dashboard Overview — Vercel
Description: Refined dark monochrome analytics dashboard with KPI stat cards, a pure-SVG area+line chart, an activity feed, and a wired 7d/30d/90d range selector that swaps hardcoded datasets. Hairline borders, a single teal accent.
Author: DevSnips Contributors
Usage Example: Drop into a dark product shell as an analytics overview. The range selector updates KPI values, deltas, and the chart in preview.html.
-->
<div class="relative w-full" data-dash="vc">
<!-- Panel -->
<div class="overflow-hidden rounded-[14px] border border-white/10 bg-[#0a0a0a] shadow-[0_0_0_1px_rgba(255,255,255,0.02),0_20px_60px_-20px_rgba(0,0,0,0.9)]">
<!-- top radial glow -->
<div class="pointer-events-none absolute inset-x-0 top-0 -z-0 h-40 [background:radial-gradient(60%_100%_at_50%_0%,rgba(80,227,194,0.10),transparent_70%)]" aria-hidden="true"></div>
<!-- Header / toolbar -->
<div class="relative flex flex-col gap-4 border-b border-white/[0.07] px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:px-6">
<div class="flex items-center gap-3">
<div class="flex h-9 w-9 items-center justify-center rounded-lg border border-white/10 bg-white text-black">
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M3 17l5-6 4 4 4-6 5 5" /></svg>
</div>
<div class="leading-tight">
<p class="font-g text-[15px] font-semibold text-white">Overview</p>
<p class="vc-mono mt-1 text-[11px] text-white/40">
<span class="vc-dot"></span>live · updated 2m ago
</p>
</div>
</div>
<div role="group" aria-label="Time range" class="flex w-fit items-center rounded-lg border border-white/10 bg-white/[0.03] p-0.5">
<button type="button" data-range="7" class="vc-range rounded-md px-3 py-1.5 font-mono text-[11px] transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-white/30">7d</button>
<button type="button" data-range="30" class="vc-range rounded-md px-3 py-1.5 font-mono text-[11px] transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-white/30">30d</button>
<button type="button" data-range="90" class="vc-range rounded-md px-3 py-1.5 font-mono text-[11px] transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-white/30">90d</button>
</div>
</div>
<!-- KPI cards -->
<div class="grid grid-cols-1 gap-px border-b border-white/[0.07] bg-white/[0.04] sm:grid-cols-2 lg:grid-cols-4">
<div class="bg-[#0a0a0a] p-5" data-kpi="revenue">
<div class="flex items-center justify-between">
<p class="vc-mono text-[11px] uppercase tracking-wider text-white/40">Revenue</p>
<svg class="h-4 w-4 text-white/30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 1v23M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" /></svg>
</div>
<p class="mt-3 font-g text-2xl font-semibold text-white" data-kpi-value>$48,210</p>
<p class="vc-mono mt-1.5 flex items-center gap-1 text-[11px]" data-kpi-delta>
<span class="text-[#50e3c2]">▲ +12.4%</span><span class="text-white/35">vs prev</span>
</p>
</div>
<div class="bg-[#0a0a0a] p-5" data-kpi="users">
<div class="flex items-center justify-between">
<p class="vc-mono text-[11px] uppercase tracking-wider text-white/40">Active Users</p>
<svg class="h-4 w-4 text-white/30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z" /></svg>
</div>
<p class="mt-3 font-g text-2xl font-semibold text-white" data-kpi-value>18,402</p>
<p class="vc-mono mt-1.5 flex items-center gap-1 text-[11px]" data-kpi-delta>
<span class="text-[#50e3c2]">▲ +8.1%</span><span class="text-white/35">vs prev</span>
</p>
</div>
<div class="bg-[#0a0a0a] p-5" data-kpi="mrr">
<div class="flex items-center justify-between">
<p class="vc-mono text-[11px] uppercase tracking-wider text-white/40">MRR</p>
<svg class="h-4 w-4 text-white/30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M3 3v18h18M7 14l3-3 3 3 5-6" /></svg>
</div>
<p class="mt-3 font-g text-2xl font-semibold text-white" data-kpi-value>$12,640</p>
<p class="vc-mono mt-1.5 flex items-center gap-1 text-[11px]" data-kpi-delta>
<span class="text-[#50e3c2]">▲ +5.7%</span><span class="text-white/35">vs prev</span>
</p>
</div>
<div class="bg-[#0a0a0a] p-5" data-kpi="churn">
<div class="flex items-center justify-between">
<p class="vc-mono text-[11px] uppercase tracking-wider text-white/40">Churn</p>
<svg class="h-4 w-4 text-white/30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M21 12a9 9 0 1 1-3-6.7L21 8" /></svg>
</div>
<p class="mt-3 font-g text-2xl font-semibold text-white" data-kpi-value>2.1%</p>
<p class="vc-mono mt-1.5 flex items-center gap-1 text-[11px]" data-kpi-delta>
<span class="text-[#50e3c2]">▼ -0.3pp</span><span class="text-white/35">good</span>
</p>
</div>
</div>
<!-- Chart + activity -->
<div class="grid grid-cols-1 lg:grid-cols-3">
<!-- Chart -->
<div class="border-b border-white/[0.07] p-5 sm:p-6 lg:col-span-2 lg:border-b-0 lg:border-r lg:border-white/[0.07]">
<div class="mb-5 flex flex-wrap items-end justify-between gap-3">
<div>
<p class="font-g text-[14px] font-medium text-white">Revenue Trend</p>
<p class="vc-mono mt-1 text-[11px] text-white/40">last <span data-range-label>30 days</span></p>
</div>
<div class="flex items-center gap-4">
<span class="flex items-center gap-1.5 vc-mono text-[11px] text-white/55">
<span class="inline-block h-2 w-2 rounded-full bg-[#50e3c2]"></span>Revenue
</span>
<span class="flex items-center gap-1.5 vc-mono text-[11px] text-white/55">
<span class="inline-block h-2 w-2 rounded-full bg-white/30"></span>Prev period
</span>
</div>
</div>
<div class="relative">
<svg data-chart viewBox="0 0 640 240" preserveAspectRatio="none" class="h-56 w-full sm:h-64" role="img" aria-label="Revenue trend chart"></svg>
<div class="mt-2 flex items-center justify-between vc-mono text-[10px] text-white/35" data-chart-axis></div>
</div>
</div>
<!-- Activity feed -->
<div class="p-5 sm:p-6">
<div class="mb-4 flex items-center justify-between">
<p class="font-g text-[14px] font-medium text-white">Recent Activity</p>
<button type="button" class="vc-mono text-[11px] text-white/40 transition-colors hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white/30">All</button>
</div>
<ul class="space-y-3" data-activity>
<li class="flex gap-3 rounded-lg border border-white/[0.07] bg-white/[0.02] p-3 transition-colors hover:bg-white/[0.05]">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-white/10 bg-[#50e3c2]/10 text-[#50e3c2]">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
</span>
<div class="min-w-0 flex-1">
<p class="font-g text-[13px] text-white/90">New customer upgrade</p>
<p class="vc-mono mt-0.5 text-[11px] text-white/35">acme-co · pro · 2m</p>
</div>
</li>
<li class="flex gap-3 rounded-lg border border-white/[0.07] bg-white/[0.02] p-3 transition-colors hover:bg-white/[0.05]">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-white/10 bg-white/5 text-white/70">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6" /></svg>
</span>
<div class="min-w-0 flex-1">
<p class="font-g text-[13px] text-white/90">Payout processed</p>
<p class="vc-mono mt-0.5 text-[11px] text-white/35">stripe · $4,820 · 38m</p>
</div>
</li>
<li class="flex gap-3 rounded-lg border border-white/[0.07] bg-white/[0.02] p-3 transition-colors hover:bg-white/[0.05]">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-white/10 bg-white/5 text-white/70">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>
</span>
<div class="min-w-0 flex-1">
<p class="font-g text-[13px] text-white/90">Churn alert resolved</p>
<p class="vc-mono mt-0.5 text-[11px] text-white/35">quark.io · 1h</p>
</div>
</li>
<li class="flex gap-3 rounded-lg border border-white/[0.07] bg-white/[0.02] p-3 transition-colors hover:bg-white/[0.05]">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-white/10 bg-white/5 text-white/70">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><circle cx="12" cy="12" r="3" /><path d="M12 2v3M12 19v3M2 12h3M19 12h3" /></svg>
</span>
<div class="min-w-0 flex-1">
<p class="font-g text-[13px] text-white/90">New trial signup</p>
<p class="vc-mono mt-0.5 text-[11px] text-white/35">loop-labs · 3h</p>
</div>
</li>
</ul>
</div>
</div>
</div>
<script>
(function () {
var root = document.currentScript.closest('[data-dash]');
if (!root) return;
var datasets = {
7: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
current: [42, 55, 48, 71, 66, 80, 95],
previous: [38, 47, 52, 60, 58, 70, 82],
kpis: {
revenue: { value: '$11,420', delta: '▲ +9.2%', color: '#50e3c2' },
users: { value: '4,820', delta: '▲ +6.4%', color: '#50e3c2' },
mrr: { value: '$12,640', delta: '▲ +5.7%', color: '#50e3c2' },
churn: { value: '2.1%', delta: '▼ -0.3pp', color: '#50e3c2', note: 'good' }
}
},
30: {
labels: ['W1', 'W2', 'W3', 'W4'],
current: [320, 410, 380, 510],
previous: [280, 360, 340, 460],
kpis: {
revenue: { value: '$48,210', delta: '▲ +12.4%', color: '#50e3c2' },
users: { value: '18,402', delta: '▲ +8.1%', color: '#50e3c2' },
mrr: { value: '$12,640', delta: '▲ +5.7%', color: '#50e3c2' },
churn: { value: '2.1%', delta: '▼ -0.3pp', color: '#50e3c2', note: 'good' }
}
},
90: {
labels: ['M1', 'M2', 'M3'],
current: [1480, 1720, 1610],
previous: [1260, 1520, 1450],
kpis: {
revenue: { value: '$142,080', delta: '▲ +18.6%', color: '#50e3c2' },
users: { value: '52,140', delta: '▲ +14.2%', color: '#50e3c2' },
mrr: { value: '$13,920', delta: '▲ +9.3%', color: '#50e3c2' },
churn: { value: '1.9%', delta: '▼ -0.4pp', color: '#50e3c2', note: 'good' }
}
}
};
var chart = root.querySelector('[data-chart]');
var axis = root.querySelector('[data-chart-axis]');
var rangeLabel = root.querySelector('[data-range-label]');
var buttons = root.querySelectorAll('.vc-range');
function smoothPath(pts) {
if (pts.length < 2) return '';
var d = 'M ' + pts[0].x.toFixed(1) + ' ' + pts[0].y.toFixed(1);
for (var i = 1; i < pts.length; i++) {
var p0 = pts[i - 1], p1 = pts[i];
var cx = (p0.x + p1.x) / 2;
d += ' C ' + cx.toFixed(1) + ' ' + p0.y.toFixed(1) + ' ' + cx.toFixed(1) + ' ' + p1.y.toFixed(1) + ' ' + p1.x.toFixed(1) + ' ' + p1.y.toFixed(1);
}
return d;
}
function render(range) {
var d = datasets[range];
if (!d) return;
['revenue', 'users', 'mrr', 'churn'].forEach(function (key) {
var card = root.querySelector('[data-kpi="' + key + '"]');
if (!card) return;
var k = d.kpis[key];
var valEl = card.querySelector('[data-kpi-value]');
var dEl = card.querySelector('[data-kpi-delta]');
if (valEl) valEl.textContent = k.value;
if (dEl) {
var note = k.note === 'good' ? 'good' : 'vs prev';
dEl.innerHTML = '<span style="color:' + k.color + '">' + k.delta + '</span><span class="text-white/35">' + note + '</span>';
}
});
if (rangeLabel) rangeLabel.textContent = range + ' days';
var W = 640, H = 240, padB = 22, padT = 14, padX = 18;
var n = d.current.length;
var max = Math.max.apply(null, d.current.concat(d.previous)) * 1.15;
var innerW = W - padX * 2;
var innerH = H - padT - padB;
var xAt = function (i) { return padX + (n === 1 ? innerW / 2 : (innerW * i) / (n - 1)); };
var yAt = function (v) { return padT + innerH - (v / max) * innerH; };
var curPts = d.current.map(function (v, i) { return { x: xAt(i), y: yAt(v) }; });
var prevPts = d.previous.map(function (v, i) { return { x: xAt(i), y: yAt(v) }; });
var curPath = smoothPath(curPts);
var prevPath = smoothPath(prevPts);
var areaPath = curPath + ' L ' + xAt(n - 1).toFixed(1) + ' ' + (H - padB) + ' L ' + xAt(0).toFixed(1) + ' ' + (H - padB) + ' Z';
var svg = '';
// gridlines
for (var g = 0; g <= 4; g++) {
var gy = padT + innerH * (g / 4);
svg += '<line x1="' + padX + '" y1="' + gy.toFixed(1) + '" x2="' + (W - padX) + '" y2="' + gy.toFixed(1) + '" stroke="rgba(255,255,255,0.06)" stroke-width="1"/>';
}
// defs gradient
svg += '<defs><linearGradient id="vcArea" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#50e3c2" stop-opacity="0.35"/><stop offset="100%" stop-color="#50e3c2" stop-opacity="0"/></linearGradient></defs>';
// previous line
svg += '<path d="' + prevPath + '" fill="none" stroke="rgba(255,255,255,0.25)" stroke-width="1.5" stroke-dasharray="3 3"/>';
// current area
svg += '<path d="' + areaPath + '" fill="url(#vcArea)"/>';
// current line
svg += '<path d="' + curPath + '" fill="none" stroke="#50e3c2" stroke-width="2" stroke-linecap="round"/>';
// points
curPts.forEach(function (p) {
svg += '<circle cx="' + p.x.toFixed(1) + '" cy="' + p.y.toFixed(1) + '" r="3" fill="#0a0a0a" stroke="#50e3c2" stroke-width="2"/>';
});
// baseline
svg += '<line x1="' + padX + '" y1="' + (H - padB) + '" x2="' + (W - padX) + '" y2="' + (H - padB) + '" stroke="rgba(255,255,255,0.1)" stroke-width="1"/>';
chart.innerHTML = svg;
if (axis) axis.innerHTML = d.labels.map(function (l) { return '<span>' + l + '</span>'; }).join('');
buttons.forEach(function (b) {
var active = b.dataset.range === String(range);
b.classList.toggle('bg-white', active);
b.classList.toggle('text-black', active);
b.classList.toggle('text-white/55', !active);
if (active) b.setAttribute('aria-pressed', 'true'); else b.removeAttribute('aria-pressed');
});
}
buttons.forEach(function (b) {
b.addEventListener('click', function () { render(parseInt(b.dataset.range, 10)); });
});
render(30);
})();
</script>
</div> 281 lines UTF-8 · LF · Spaces: 2
Continue browsing