nxtgauge-admin-solid/src/routes/admin/index.tsx

170 lines
9.3 KiB
TypeScript
Raw Normal View History

import { For } from 'solid-js';
import AdminShell from '~/components/AdminShell';
const kpis = [
{ title: 'Total Users', value: '12,458', delta: '+12.5%', note: '+1,245 from last month', tone: 'up' as const, icon: 'US' },
{ title: 'Active Companies', value: '1,234', delta: '+8.2%', note: '+94 from last month', tone: 'up' as const, icon: 'CP' },
{ title: 'Open Leads', value: '847', delta: '-3.1%', note: '-27 from last month', tone: 'down' as const, icon: 'LD' },
{ title: 'Credits Purchased', value: '$45,890', delta: '+18.7%', note: '+$7,234 from last month', tone: 'up' as const, icon: 'CR' },
];
const trendSeries = [62, 70, 81, 75, 88, 102];
const revSeries = [42000, 48000, 55000, 51000, 62000, 69000];
const maxAmount = 80000;
const leadRows = [
{ title: 'Corporate Event Photographer', customer: 'Bright Media', category: 'Photography', budget: '$3,500', status: 'New', priority: 'High' },
{ title: 'Wedding Makeup Artist', customer: 'Aster Weddings', category: 'Makeup Artist', budget: '$1,800', status: 'In Review', priority: 'Medium' },
{ title: 'SAT Batch Tutor', customer: 'EduPath', category: 'Tutors', budget: '$2,300', status: 'Assigned', priority: 'Low' },
{ title: 'Personal Fitness Trainer', customer: 'Core Fitness', category: 'Fitness', budget: '$2,900', status: 'Escalated', priority: 'High' },
{ title: 'Corporate Video Editor', customer: 'Pixel Forge', category: 'Video Editor', budget: '$4,200', status: 'New', priority: 'Critical' },
];
export default function AdminDashboard() {
return (
<AdminShell>
<div class="space-y-6">
<section class="rounded-3xl border border-[#e3e5ec] bg-[#f7f7f8] px-6 py-5">
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
<div>
<h1 class="text-[40px] font-semibold leading-[1.1] text-[#050026]">Dashboard Overview</h1>
<p class="mt-1 text-[15px] text-[#7b8099]">Welcome back! Here&apos;s what&apos;s happening with your platform today.</p>
</div>
<button class="inline-flex h-11 items-center rounded-2xl bg-[#050026] px-5 text-sm font-semibold text-white">
Export Report
</button>
</div>
</section>
<section class="grid gap-4 xl:grid-cols-4">
<For each={kpis}>
{(item) => (
<article class="rounded-3xl border border-[#d9dde6] bg-[#f7f7f8] p-5 shadow-[0_0_0_1px_rgba(0,0,0,0.01)]">
<div class="flex items-center justify-between">
<div class="inline-flex h-10 w-10 items-center justify-center rounded-xl bg-[#fff1ea] text-xs font-bold text-[#fd6116]">{item.icon}</div>
<span
class={`inline-flex items-center rounded-xl px-2.5 py-1 text-xs font-semibold ${
item.tone === 'up' ? 'bg-[#ffe8dc] text-[#fd6116]' : 'bg-[#eceff6] text-[#383e5c]'
}`}
>
{item.delta}
</span>
</div>
<p class="mt-5 text-[15px] text-[#747a93]">{item.title}</p>
<p class="mt-1 text-[44px] font-semibold leading-none text-[#050026]">{item.value}</p>
<p class="mt-1 text-[14px] text-[#8a90a8]">{item.note}</p>
</article>
)}
</For>
</section>
<section class="grid gap-4 xl:grid-cols-2">
<article class="rounded-3xl border border-[#d9dde6] bg-[#f7f7f8] p-5">
<h2 class="text-[34px] font-semibold leading-[1.1] text-[#050026]">Leads Trend</h2>
<p class="mt-1 text-[14px] text-[#8087a0]">Monthly leads performance overview</p>
<div class="mt-5 rounded-2xl border border-[#e2e6ee] bg-[#f5f5f6] p-4">
<div class="relative h-52">
<div class="absolute inset-0">
<For each={[0, 1, 2, 3]}>{() => <div class="h-1/4 border-b border-dashed border-[#d9dde6]" />}</For>
</div>
<svg viewBox="0 0 100 40" class="relative h-full w-full overflow-visible" preserveAspectRatio="none" aria-hidden="true">
<defs>
<linearGradient id="trendFill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#fd6116" stop-opacity="0.28" />
<stop offset="100%" stop-color="#fd6116" stop-opacity="0.02" />
</linearGradient>
</defs>
<polyline
fill="none"
stroke="#050026"
stroke-width="1.1"
points={trendSeries.map((v, i) => `${i * 20},${40 - v / 3}`).join(' ')}
/>
<polygon
fill="url(#trendFill)"
points={`0,40 ${trendSeries.map((v, i) => `${i * 20},${40 - v / 3}`).join(' ')} 100,40`}
/>
</svg>
</div>
<div class="mt-1 grid grid-cols-6 text-center text-xs font-semibold text-[#3f4562]">
<For each={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']}>{(month) => <span>{month}</span>}</For>
</div>
</div>
</article>
<article class="rounded-3xl border border-[#d9dde6] bg-[#f7f7f8] p-5">
<h2 class="text-[34px] font-semibold leading-[1.1] text-[#050026]">Revenue Overview</h2>
<p class="mt-1 text-[14px] text-[#8087a0]">Monthly revenue vs expenses comparison</p>
<div class="mt-5 rounded-2xl border border-[#e2e6ee] bg-[#f5f5f6] p-4">
<div class="relative h-52">
<div class="absolute inset-0">
<For each={[0, 1, 2, 3]}>{() => <div class="h-1/4 border-b border-dashed border-[#d9dde6]" />}</For>
</div>
<div class="relative flex h-full items-end gap-4 px-2">
<For each={revSeries}>
{(value) => (
<div class="flex h-full flex-1 items-end justify-center">
<div class="w-2.5 rounded-t bg-[#050026]" style={{ height: `${(value / maxAmount) * 100}%` }} />
</div>
)}
</For>
</div>
</div>
<div class="mt-1 grid grid-cols-6 text-center text-xs font-semibold text-[#3f4562]">
<For each={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']}>{(month) => <span>{month}</span>}</For>
</div>
</div>
</article>
</section>
<section class="rounded-3xl border border-[#d9dde6] bg-[#f7f7f8] p-1">
<div class="flex flex-col gap-3 px-5 py-4 md:flex-row md:items-center md:justify-between">
<div>
<h2 class="text-[32px] font-semibold leading-[1.1] text-[#050026]">Recent Leads</h2>
<p class="mt-1 text-[14px] text-[#8087a0]">Latest customer inquiries and opportunities</p>
</div>
<button class="inline-flex h-10 items-center rounded-2xl border border-[#d9dde6] bg-white px-4 text-sm font-semibold text-[#050026]">
View All Leads
</button>
</div>
<div class="overflow-x-auto px-1 pb-1">
<table class="w-full min-w-[860px] border-collapse overflow-hidden rounded-2xl">
<thead>
<tr class="bg-[#eef1f7] text-left">
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Lead Title</th>
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Customer</th>
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Category</th>
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Budget</th>
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Status</th>
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Priority</th>
<th class="px-5 py-3 text-[12px] font-semibold uppercase tracking-wide text-[#616985]">Action</th>
</tr>
</thead>
<tbody>
<For each={leadRows}>
{(row) => (
<tr class="border-t border-[#e1e6f0] bg-white">
<td class="px-5 py-3 text-sm font-medium text-[#050026]">{row.title}</td>
<td class="px-5 py-3 text-sm text-[#3c4260]">{row.customer}</td>
<td class="px-5 py-3 text-sm text-[#3c4260]">{row.category}</td>
<td class="px-5 py-3 text-sm font-semibold text-[#050026]">{row.budget}</td>
<td class="px-5 py-3 text-sm text-[#3c4260]">{row.status}</td>
<td class="px-5 py-3 text-sm text-[#3c4260]">{row.priority}</td>
<td class="px-5 py-3 text-sm">
<button class="rounded-lg border border-[#d9dde6] bg-white px-3 py-1.5 font-medium text-[#050026] hover:bg-[#f8f9fc]">
Open
</button>
</td>
</tr>
)}
</For>
</tbody>
</table>
</div>
</section>
</div>
</AdminShell>
);
}