fix(ui): sidebar spacing/scrolling, navy accent bars, reduced border radius
- Sidebar: proper min-h-0 + overflow-y-auto scrolling, px-3 spacing, text-[13px] items with truncate, tighter py-2 rows, user card with navy avatar chip, w-60 width - KPI cards: navy #0a1d37 left accent bar instead of orange, navy icon chips, rounded-xl (was rounded-2xl), reduced shadow intensity - All cards/panels: rounded-xl (down from rounded-2xl/3xl) - Activity chart: navy bars instead of orange, rounded-t-md (less rounded) - Intelligence Hub actions: rounded-lg (was rounded-2xl) - Control Plane cards: rounded-xl with hover:border-[#0a1d37]/10 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
df560a91ea
commit
1f59fbbc4c
2 changed files with 145 additions and 152 deletions
|
|
@ -11,30 +11,30 @@ type LinkItem = {
|
||||||
const links: LinkItem[] = [
|
const links: LinkItem[] = [
|
||||||
{ href: '/admin', label: 'Dashboard', icon: 'dashboard.svg', group: '__top__' },
|
{ href: '/admin', label: 'Dashboard', icon: 'dashboard.svg', group: '__top__' },
|
||||||
|
|
||||||
{ href: '/admin/roles', label: 'Internal Role Management', icon: 'role.svg', group: 'Management' },
|
{ href: '/admin/roles', label: 'Internal Role Management', icon: 'role.svg', group: 'Management' },
|
||||||
{ href: '/admin/runtime-roles', label: 'External Role Management', icon: 'role.svg', group: 'Management' },
|
{ href: '/admin/runtime-roles', label: 'External Role Management', icon: 'role.svg', group: 'Management' },
|
||||||
{ href: '/admin/onboarding-schemas', label: 'External Onboarding', icon: 'reviews.svg', group: 'Management' },
|
{ href: '/admin/onboarding-schemas', label: 'External Onboarding', icon: 'reviews.svg', group: 'Management' },
|
||||||
{ href: '/admin/internal-dashboard-management',label: 'Internal Dashboard Mgmt.', icon: 'dashboard.svg', group: 'Management' },
|
{ href: '/admin/internal-dashboard-management', label: 'Internal Dashboard Mgmt.', icon: 'dashboard.svg', group: 'Management' },
|
||||||
{ href: '/admin/external-dashboard-management',label: 'External Dashboard Mgmt.', icon: 'dashboard.svg', aliasPrefix: '/admin/role-ui-configs', group: 'Management' },
|
{ href: '/admin/external-dashboard-management', label: 'External Dashboard Mgmt.', icon: 'dashboard.svg', aliasPrefix: '/admin/role-ui-configs', group: 'Management' },
|
||||||
{ href: '/admin/approval', label: 'Approval Management', icon: 'approval.svg', group: 'Management' },
|
{ href: '/admin/approval', label: 'Approval Management', icon: 'approval.svg', group: 'Management' },
|
||||||
{ href: '/admin/department', label: 'Department Management', icon: 'department.svg', group: 'Management' },
|
{ href: '/admin/department', label: 'Department Management', icon: 'department.svg', group: 'Management' },
|
||||||
{ href: '/admin/designation', label: 'Designation Management', icon: 'designation.svg',group: 'Management' },
|
{ href: '/admin/designation', label: 'Designation Management', icon: 'designation.svg', group: 'Management' },
|
||||||
{ href: '/admin/employees', label: 'Employee Management', icon: 'users.svg', group: 'Management' },
|
{ href: '/admin/employees', label: 'Employee Management', icon: 'users.svg', group: 'Management' },
|
||||||
{ href: '/admin/users', label: 'Users Management', icon: 'users.svg', group: 'Management' },
|
{ href: '/admin/users', label: 'Users Management', icon: 'users.svg', group: 'Management' },
|
||||||
{ href: '/admin/company', label: 'Company Management', icon: 'company.svg', group: 'Management' },
|
{ href: '/admin/company', label: 'Company Management', icon: 'company.svg', group: 'Management' },
|
||||||
{ href: '/admin/candidate', label: 'Candidate Management', icon: 'candidate.svg', group: 'Management' },
|
{ href: '/admin/candidate', label: 'Candidate Management', icon: 'candidate.svg', group: 'Management' },
|
||||||
{ href: '/admin/customer', label: 'Customer Management', icon: 'users.svg', group: 'Management' },
|
{ href: '/admin/customer', label: 'Customer Management', icon: 'users.svg', group: 'Management' },
|
||||||
{ href: '/admin/photographer', label: 'Photographer Management', icon: 'photographer.svg',group: 'Management' },
|
{ href: '/admin/photographer', label: 'Photographer Management', icon: 'photographer.svg', group: 'Management' },
|
||||||
{ href: '/admin/makeup-artist', label: 'Makeup Artist Management', icon: 'makeup-artist.svg',group: 'Management'},
|
{ href: '/admin/makeup-artist', label: 'Makeup Artist Management', icon: 'makeup-artist.svg',group: 'Management' },
|
||||||
{ href: '/admin/tutors', label: 'Tutors Management', icon: 'tutor.svg', group: 'Management' },
|
{ href: '/admin/tutors', label: 'Tutors Management', icon: 'tutor.svg', group: 'Management' },
|
||||||
{ href: '/admin/developers', label: 'Developers Management', icon: 'developers.svg', group: 'Management' },
|
{ href: '/admin/developers', label: 'Developers Management', icon: 'developers.svg', group: 'Management' },
|
||||||
{ href: '/admin/video-editors', label: 'Video Editor Management', icon: 'developers.svg', group: 'Management' },
|
{ href: '/admin/video-editors', label: 'Video Editor Management', icon: 'developers.svg', group: 'Management' },
|
||||||
{ href: '/admin/fitness-trainers', label: 'Fitness Trainer Management', icon: 'tutor.svg', group: 'Management' },
|
{ href: '/admin/fitness-trainers', label: 'Fitness Trainer Management', icon: 'tutor.svg', group: 'Management' },
|
||||||
{ href: '/admin/catering-services', label: 'Catering Services Mgmt.', icon: 'company.svg', group: 'Management' },
|
{ href: '/admin/catering-services', label: 'Catering Services', icon: 'company.svg', group: 'Management' },
|
||||||
{ href: '/admin/graphic-designers', label: 'Graphics Designer Mgmt.', icon: 'developers.svg', group: 'Management' },
|
{ href: '/admin/graphic-designers', label: 'Graphics Designer Mgmt.', icon: 'developers.svg', group: 'Management' },
|
||||||
{ href: '/admin/social-media-managers', label: 'Social Media Mgr. Mgmt.', icon: 'developers.svg', group: 'Management' },
|
{ href: '/admin/social-media-managers', label: 'Social Media Mgr.', icon: 'developers.svg', group: 'Management' },
|
||||||
{ href: '/admin/jobs', label: 'Jobs Management', icon: 'jobs.svg', group: 'Management' },
|
{ href: '/admin/jobs', label: 'Jobs Management', icon: 'jobs.svg', group: 'Management' },
|
||||||
{ href: '/admin/leads', label: 'Leads Management', icon: 'leads.svg', group: 'Management' },
|
{ href: '/admin/leads', label: 'Leads Management', icon: 'leads.svg', group: 'Management' },
|
||||||
|
|
||||||
{ href: '/admin/pricing', label: 'Pricing Management', icon: 'pricing.svg', group: 'Finance' },
|
{ href: '/admin/pricing', label: 'Pricing Management', icon: 'pricing.svg', group: 'Finance' },
|
||||||
{ href: '/admin/credit', label: 'Credit Management', icon: 'credits.svg', group: 'Finance' },
|
{ href: '/admin/credit', label: 'Credit Management', icon: 'credits.svg', group: 'Finance' },
|
||||||
|
|
@ -45,11 +45,11 @@ const links: LinkItem[] = [
|
||||||
{ href: '/admin/invoice', label: 'Invoice Management', icon: 'invoice.svg', group: 'Finance' },
|
{ href: '/admin/invoice', label: 'Invoice Management', icon: 'invoice.svg', group: 'Finance' },
|
||||||
{ href: '/admin/ledger', label: 'Ledger Management', icon: 'ledger.svg', group: 'Finance' },
|
{ href: '/admin/ledger', label: 'Ledger Management', icon: 'ledger.svg', group: 'Finance' },
|
||||||
|
|
||||||
{ href: '/admin/review', label: 'Review Management', icon: 'reviews.svg', group: 'Platform' },
|
{ href: '/admin/review', label: 'Review Management', icon: 'reviews.svg', group: 'Platform' },
|
||||||
{ href: '/admin/support', label: 'Support Management', icon: 'support.svg', group: 'Platform' },
|
{ href: '/admin/support', label: 'Support Management', icon: 'support.svg', group: 'Platform' },
|
||||||
{ href: '/admin/kb', label: 'Knowledge Base Mgmt.', icon: 'reviews.svg', group: 'Platform' },
|
{ href: '/admin/kb', label: 'Knowledge Base', icon: 'reviews.svg', group: 'Platform' },
|
||||||
{ href: '/admin/notifications', label: 'Notifications', icon: 'reviews.svg', group: 'Platform' },
|
{ href: '/admin/notifications', label: 'Notifications', icon: 'reviews.svg', group: 'Platform' },
|
||||||
{ href: '/admin/report', label: 'Report Management', icon: 'report.svg', group: 'Platform' },
|
{ href: '/admin/report', label: 'Report Management', icon: 'report.svg', group: 'Platform' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function AdminSidebar() {
|
export default function AdminSidebar() {
|
||||||
|
|
@ -61,11 +61,6 @@ export default function AdminSidebar() {
|
||||||
return location.pathname === href || location.pathname.startsWith(`${href}/`);
|
return location.pathname === href || location.pathname.startsWith(`${href}/`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const topLinks = links.filter(l => l.group === '__top__');
|
|
||||||
const mgmtLinks = links.filter(l => l.group === 'Management');
|
|
||||||
const finLinks = links.filter(l => l.group === 'Finance');
|
|
||||||
const platLinks = links.filter(l => l.group === 'Platform');
|
|
||||||
|
|
||||||
const NavItem = (item: LinkItem) => {
|
const NavItem = (item: LinkItem) => {
|
||||||
const active = isActive(item.href, item.aliasPrefix);
|
const active = isActive(item.href, item.aliasPrefix);
|
||||||
return (
|
return (
|
||||||
|
|
@ -74,57 +69,74 @@ export default function AdminSidebar() {
|
||||||
activeClass=""
|
activeClass=""
|
||||||
inactiveClass=""
|
inactiveClass=""
|
||||||
title={item.label}
|
title={item.label}
|
||||||
class={`relative flex items-center gap-3 rounded-xl py-2.5 pl-4 pr-3 text-sm font-semibold tracking-wide transition-all duration-150 ${
|
class={`relative flex min-w-0 items-center gap-2.5 rounded-lg px-3 py-2 text-[13px] font-semibold transition-colors duration-150 ${
|
||||||
active
|
active
|
||||||
? 'bg-slate-50 text-[#0a1d37] before:absolute before:left-0 before:top-1/2 before:h-6 before:-translate-y-1/2 before:w-1 before:rounded-r-full before:bg-[#fd6216] before:content-[\'\']'
|
? 'bg-slate-100 text-[#0a1d37] before:absolute before:left-0 before:top-1/2 before:h-5 before:-translate-y-1/2 before:w-[3px] before:rounded-r-full before:bg-[#fd6216] before:content-[\'\']'
|
||||||
: 'text-[#0a1d37]/60 hover:bg-slate-50 hover:text-[#0a1d37]'
|
: 'text-[#0a1d37]/55 hover:bg-slate-50 hover:text-[#0a1d37]'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={`/sidebar-icons/${item.icon}`}
|
src={`/sidebar-icons/${item.icon}`}
|
||||||
alt=""
|
alt=""
|
||||||
class="h-[18px] w-[18px] shrink-0"
|
class="h-4 w-4 shrink-0"
|
||||||
style={active ? 'opacity:0.9' : 'opacity:0.4'}
|
style={active ? 'opacity:0.85' : 'opacity:0.35'}
|
||||||
/>
|
/>
|
||||||
<span class="truncate">{item.label}</span>
|
<span class="truncate">{item.label}</span>
|
||||||
</A>
|
</A>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const GroupLabel = (label: string) => (
|
const topLinks = links.filter(l => l.group === '__top__');
|
||||||
<div class="px-4 pb-2 pt-4">
|
const mgmtLinks = links.filter(l => l.group === 'Management');
|
||||||
<p class="text-[10px] font-bold uppercase tracking-widest text-slate-400">{label}</p>
|
const finLinks = links.filter(l => l.group === 'Finance');
|
||||||
</div>
|
const platLinks = links.filter(l => l.group === 'Platform');
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside class="flex h-full w-64 flex-col border-r border-slate-100 bg-white py-5">
|
<aside class="flex h-full w-60 flex-col border-r border-slate-100 bg-white">
|
||||||
{/* Top (Dashboard) */}
|
|
||||||
<nav class="px-3">
|
{/* Top: Dashboard link */}
|
||||||
|
<div class="px-3 pt-4 pb-2">
|
||||||
{topLinks.map(NavItem)}
|
{topLinks.map(NavItem)}
|
||||||
</nav>
|
|
||||||
|
|
||||||
{/* Scrollable nav groups */}
|
|
||||||
<div class="scrollbar mt-1 min-h-0 flex-1 overflow-y-auto px-3">
|
|
||||||
{GroupLabel('Management')}
|
|
||||||
{mgmtLinks.map(NavItem)}
|
|
||||||
|
|
||||||
{GroupLabel('Finance')}
|
|
||||||
{finLinks.map(NavItem)}
|
|
||||||
|
|
||||||
{GroupLabel('Platform')}
|
|
||||||
{platLinks.map(NavItem)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* User card at bottom */}
|
{/* Scrollable groups */}
|
||||||
<div class="mt-2 border-t border-slate-100 px-4 pt-4">
|
<div class="scrollbar flex-1 overflow-y-auto px-3 pb-3" style="min-height:0">
|
||||||
<div class="flex items-center gap-3 rounded-xl bg-slate-50 p-3">
|
|
||||||
<div class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[#fd6216] text-sm font-black text-white">
|
{/* Management */}
|
||||||
|
<p class="mt-3 mb-1.5 px-2 text-[10px] font-bold uppercase tracking-widest text-slate-400">
|
||||||
|
Management
|
||||||
|
</p>
|
||||||
|
<div class="space-y-0.5">
|
||||||
|
{mgmtLinks.map(NavItem)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Finance */}
|
||||||
|
<p class="mt-4 mb-1.5 px-2 text-[10px] font-bold uppercase tracking-widest text-slate-400">
|
||||||
|
Finance
|
||||||
|
</p>
|
||||||
|
<div class="space-y-0.5">
|
||||||
|
{finLinks.map(NavItem)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Platform */}
|
||||||
|
<p class="mt-4 mb-1.5 px-2 text-[10px] font-bold uppercase tracking-widest text-slate-400">
|
||||||
|
Platform
|
||||||
|
</p>
|
||||||
|
<div class="space-y-0.5">
|
||||||
|
{platLinks.map(NavItem)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* User card */}
|
||||||
|
<div class="border-t border-slate-100 px-3 py-3">
|
||||||
|
<div class="flex items-center gap-2.5 rounded-lg bg-slate-50 px-3 py-2.5">
|
||||||
|
<div class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[#0a1d37] text-xs font-black text-white">
|
||||||
A
|
A
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1 overflow-hidden">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="truncate text-xs font-bold text-[#0a1d37]">Admin User</p>
|
<p class="truncate text-[12px] font-bold text-[#0a1d37]">Admin User</p>
|
||||||
<p class="truncate text-[10px] text-slate-500">master_admin@nxtgauge.io</p>
|
<p class="truncate text-[10px] text-slate-400">master_admin@nxtgauge.io</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,123 +11,105 @@ type KpiCard = {
|
||||||
label: string;
|
label: string;
|
||||||
value: string;
|
value: string;
|
||||||
badge?: string;
|
badge?: string;
|
||||||
badgeColor?: string;
|
badgeColor: string;
|
||||||
href: string;
|
href: string;
|
||||||
icon: Component<any>;
|
icon: Component<any>;
|
||||||
accentColor: string; // full tailwind class for the left bar bg
|
|
||||||
chipBg: string;
|
|
||||||
chipFg: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const KPI: KpiCard[] = [
|
const KPI: KpiCard[] = [
|
||||||
{
|
{ label: 'Total Users', value: '—', badge: '+0%', badgeColor: 'text-emerald-600 bg-emerald-50', href: '/admin/users', icon: Users },
|
||||||
label: 'Total Users', value: '—', badge: '+0%', badgeColor: 'text-emerald-600 bg-emerald-50',
|
{ label: 'Total Revenue', value: '—', badge: 'Weekly', badgeColor: 'text-[#0a1d37] bg-slate-100', href: '/admin/invoice', icon: Receipt },
|
||||||
href: '/admin/users', icon: Users,
|
{ label: 'Active Roles', value: '—', badge: 'Live', badgeColor: 'text-amber-600 bg-amber-50', href: '/admin/runtime-roles', icon: Briefcase},
|
||||||
accentColor: 'bg-[#fd6216]', chipBg: 'bg-[#fd6216]/5', chipFg: 'text-[#fd6216]',
|
{ label: 'Pending Approvals', value: '—', badge: 'Action Required', badgeColor: 'text-white bg-red-500', href: '/admin/approval', icon: Clock },
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Total Revenue', value: '—', badge: 'Weekly', badgeColor: 'text-[#0a1d37] bg-slate-100',
|
|
||||||
href: '/admin/invoice', icon: Receipt,
|
|
||||||
accentColor: 'bg-[#0a1d37]', chipBg: 'bg-[#0a1d37]/5', chipFg: 'text-[#0a1d37]',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Active Roles', value: '—', badge: 'Live', badgeColor: 'text-amber-600 bg-amber-50',
|
|
||||||
href: '/admin/runtime-roles', icon: Briefcase,
|
|
||||||
accentColor: 'bg-[#fd6216]', chipBg: 'bg-amber-50', chipFg: 'text-amber-600',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Pending Approvals', value: '—', badge: 'Action Required', badgeColor: 'text-white bg-red-500',
|
|
||||||
href: '/admin/approval', icon: Clock,
|
|
||||||
accentColor: 'bg-[#fd6216]', chipBg: 'bg-red-50', chipFg: 'text-red-600',
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Activity chart data (placeholder heights)
|
|
||||||
const ACTIVITY = [
|
const ACTIVITY = [
|
||||||
{ day: 'MON', h: 40 }, { day: 'TUE', h: 65 }, { day: 'WED', h: 95 },
|
{ day: 'MON', h: 40 }, { day: 'TUE', h: 65 }, { day: 'WED', h: 95 },
|
||||||
{ day: 'THU', h: 70 }, { day: 'FRI', h: 55 }, { day: 'SAT', h: 30 }, { day: 'SUN', h: 45 },
|
{ day: 'THU', h: 70 }, { day: 'FRI', h: 55 }, { day: 'SAT', h: 30 }, { day: 'SUN', h: 45 },
|
||||||
];
|
];
|
||||||
|
|
||||||
const QUICK_ACTIONS = [
|
const QUICK_ACTIONS = [
|
||||||
{ label: 'Create New Role', href: '/admin/roles/create', icon: Shield },
|
{ label: 'Create New Role', href: '/admin/roles/create', icon: Shield },
|
||||||
{ label: 'Configure Dashboard', href: '/admin/external-dashboard-management', icon: LayoutDashboard },
|
{ label: 'Configure Dashboard', href: '/admin/external-dashboard-management', icon: LayoutDashboard },
|
||||||
{ label: 'Add Employee', href: '/admin/employees', icon: Users },
|
{ label: 'Add Employee', href: '/admin/employees', icon: Users },
|
||||||
];
|
];
|
||||||
|
|
||||||
const PIPELINE = [
|
const PIPELINE = [
|
||||||
{ name: 'Candidate Roles', type: 'External Role', status: 'Active', statusBg: 'bg-emerald-50 text-emerald-600', progress: 85, color: 'bg-[#fd6216]' },
|
{ name: 'Candidate Roles', type: 'External Role', status: 'Active', statusColor: 'text-emerald-600 bg-emerald-50', progress: 85, barColor: 'bg-[#fd6216]' },
|
||||||
{ name: 'Onboarding Flows', type: 'Schema Builder', status: 'Pending', statusBg: 'bg-amber-50 text-amber-600', progress: 42, color: 'bg-amber-400' },
|
{ name: 'Onboarding Flows', type: 'Schema Builder', status: 'Pending', statusColor: 'text-amber-600 bg-amber-50', progress: 42, barColor: 'bg-amber-400' },
|
||||||
{ name: 'Dashboard Config', type: 'UI Config', status: 'Draft', statusBg: 'bg-slate-100 text-slate-500', progress: 12, color: 'bg-slate-400' },
|
{ name: 'Dashboard Config', type: 'UI Config', status: 'Draft', statusColor: 'text-slate-500 bg-slate-100', progress: 12, barColor: 'bg-slate-300' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONTROL: Array<{ label: string; href: string; desc: string; icon: Component<any>; iconBg: string; iconFg: string }> = [
|
const CONTROL: Array<{ label: string; href: string; desc: string; icon: Component<any>; iconBg: string; iconFg: string }> = [
|
||||||
{ label: 'Internal Roles', href: '/admin/roles', desc: 'Permissions & access levels for internal staff.', icon: Shield, iconBg: 'bg-blue-50', iconFg: 'text-blue-600' },
|
{ label: 'Internal Roles', href: '/admin/roles', desc: 'Permissions & access levels for internal staff.', icon: Shield, iconBg: 'bg-blue-50', iconFg: 'text-blue-600' },
|
||||||
{ label: 'External Roles', href: '/admin/runtime-roles', desc: 'Modules, credits & capabilities per external role.', icon: UserCog, iconBg: 'bg-violet-50', iconFg: 'text-violet-600' },
|
{ label: 'External Roles', href: '/admin/runtime-roles', desc: 'Modules, credits & capabilities per external role.', icon: UserCog, iconBg: 'bg-violet-50', iconFg: 'text-violet-600' },
|
||||||
{ label: 'Onboarding Flows', href: '/admin/onboarding-schemas', desc: 'Schema-driven onboarding forms per external role.', icon: FormInput, iconBg: 'bg-amber-50', iconFg: 'text-amber-600' },
|
{ label: 'Onboarding Flows', href: '/admin/onboarding-schemas', desc: 'Schema-driven onboarding forms per external role.', icon: FormInput, iconBg: 'bg-amber-50', iconFg: 'text-amber-600' },
|
||||||
{ label: 'External Dashboards', href: '/admin/external-dashboard-management', desc: 'Sidebar, widgets & runtimeConfig per role.', icon: LayoutDashboard, iconBg: 'bg-teal-50', iconFg: 'text-teal-600' },
|
{ label: 'External Dashboards', href: '/admin/external-dashboard-management', desc: 'Sidebar, widgets & runtimeConfig per role.', icon: LayoutDashboard, iconBg: 'bg-teal-50', iconFg: 'text-teal-600' },
|
||||||
{ label: 'Internal Dashboards', href: '/admin/internal-dashboard-management', desc: 'Home widgets & KPI panels for internal staff.', icon: LayoutDashboard, iconBg: 'bg-orange-50', iconFg: 'text-orange-600' },
|
{ label: 'Internal Dashboards', href: '/admin/internal-dashboard-management', desc: 'Home widgets & KPI panels for internal staff.', icon: LayoutDashboard, iconBg: 'bg-orange-50', iconFg: 'text-orange-600' },
|
||||||
{ label: 'Approval Queue', href: '/admin/approval', desc: 'Review, approve or reject pending action requests.', icon: BadgeCheck, iconBg: 'bg-rose-50', iconFg: 'text-rose-600' },
|
{ label: 'Approval Queue', href: '/admin/approval', desc: 'Review, approve or reject pending action requests.', icon: BadgeCheck, iconBg: 'bg-rose-50', iconFg: 'text-rose-600' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function AdminDashboard() {
|
export default function AdminDashboard() {
|
||||||
return (
|
return (
|
||||||
<AdminShell>
|
<AdminShell>
|
||||||
<div class="space-y-8">
|
<div class="space-y-6">
|
||||||
|
|
||||||
{/* ── KPI Cards ── */}
|
{/* ── KPI Cards ── */}
|
||||||
<div class="grid grid-cols-2 gap-6 lg:grid-cols-4">
|
<div class="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
||||||
{KPI.map((kpi) => {
|
{KPI.map((kpi) => {
|
||||||
const Icon = kpi.icon;
|
const Icon = kpi.icon;
|
||||||
return (
|
return (
|
||||||
<A
|
<A
|
||||||
href={kpi.href}
|
href={kpi.href}
|
||||||
class="relative overflow-hidden rounded-2xl bg-white p-6 shadow-[0_8px_32px_rgba(10,29,55,0.04)] transition-all duration-200 hover:-translate-y-0.5 hover:shadow-[0_12px_40px_rgba(10,29,55,0.08)]"
|
class="relative overflow-hidden rounded-xl bg-white p-5 shadow-[0_4px_20px_rgba(10,29,55,0.06)] transition-all duration-200 hover:-translate-y-px hover:shadow-[0_8px_28px_rgba(10,29,55,0.10)]"
|
||||||
>
|
>
|
||||||
{/* Left accent bar */}
|
{/* Left navy accent bar */}
|
||||||
<div class={`absolute left-0 top-0 h-full w-1.5 ${kpi.accentColor}`} />
|
<div class="absolute left-0 top-0 h-full w-1.5 rounded-l-xl bg-[#0a1d37]" />
|
||||||
|
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between pl-1">
|
||||||
<div class={`flex h-12 w-12 items-center justify-center rounded-xl ${kpi.chipBg}`}>
|
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-[#0a1d37]/6">
|
||||||
<Icon class={`h-6 w-6 ${kpi.chipFg}`} />
|
<Icon class="h-5 w-5 text-[#0a1d37]" />
|
||||||
</div>
|
</div>
|
||||||
{kpi.badge && (
|
{kpi.badge && (
|
||||||
<span class={`rounded-full px-2 py-1 text-[11px] font-bold ${kpi.badgeColor}`}>
|
<span class={`rounded-md px-2 py-0.5 text-[10px] font-bold ${kpi.badgeColor}`}>
|
||||||
{kpi.badge}
|
{kpi.badge}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="mt-4 text-[10px] font-bold uppercase tracking-widest text-slate-400">
|
<div class="mt-4 pl-1">
|
||||||
{kpi.label}
|
<h3 class="text-[10px] font-bold uppercase tracking-widest text-slate-400">
|
||||||
</h3>
|
{kpi.label}
|
||||||
<p class="mt-1 text-3xl font-black tracking-tight text-[#0a1d37]">
|
</h3>
|
||||||
{kpi.value}
|
<p class="mt-1 text-3xl font-black tracking-tight text-[#0a1d37]">
|
||||||
</p>
|
{kpi.value}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</A>
|
</A>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ── Activity Chart + Intelligence Hub ── */}
|
{/* ── Activity + Intelligence Hub ── */}
|
||||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
<div class="grid grid-cols-1 gap-4 lg:grid-cols-3">
|
||||||
|
|
||||||
{/* Activity Chart */}
|
{/* Activity Chart */}
|
||||||
<div class="lg:col-span-2 rounded-3xl bg-white p-8 shadow-[0_8px_32px_rgba(10,29,55,0.04)]">
|
<div class="lg:col-span-2 rounded-xl bg-white p-6 shadow-[0_4px_20px_rgba(10,29,55,0.06)]">
|
||||||
<div class="mb-8 flex items-end justify-between">
|
<div class="mb-6 flex items-end justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-xl font-black tracking-tight text-[#0a1d37]">System Activity</h2>
|
<h2 class="text-lg font-black tracking-tight text-[#0a1d37]">System Activity</h2>
|
||||||
<p class="mt-0.5 text-sm text-slate-500">Platform traffic & Tracecoin velocity</p>
|
<p class="mt-0.5 text-sm text-slate-400">Platform traffic & Tracecoin velocity</p>
|
||||||
</div>
|
</div>
|
||||||
<select class="rounded-lg border-0 bg-slate-50 py-2 pl-3 pr-8 text-xs font-bold text-[#0a1d37] focus:ring-0">
|
<select class="rounded-lg border border-slate-200 bg-white py-1.5 pl-3 pr-8 text-xs font-semibold text-[#0a1d37] focus:outline-none focus:ring-2 focus:ring-[#0a1d37]/10">
|
||||||
<option>Last 7 Days</option>
|
<option>Last 7 Days</option>
|
||||||
<option>Last 30 Days</option>
|
<option>Last 30 Days</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex h-52 items-end justify-between gap-3">
|
<div class="flex h-44 items-end justify-between gap-2">
|
||||||
{ACTIVITY.map((d) => (
|
{ACTIVITY.map((d) => (
|
||||||
<div class="group flex flex-1 flex-col items-center gap-2">
|
<div class="group flex flex-1 flex-col items-center gap-1.5">
|
||||||
<div
|
<div
|
||||||
class={`w-full rounded-t-xl transition-all duration-200 ${d.day === 'WED' ? 'bg-[#fd6216] shadow-lg shadow-[#fd6216]/20' : 'bg-slate-100 group-hover:bg-[#0a1d37]'}`}
|
class={`w-full rounded-t-md transition-all duration-200 ${d.day === 'WED' ? 'bg-[#0a1d37] shadow-lg shadow-[#0a1d37]/20' : 'bg-slate-100 group-hover:bg-slate-300'}`}
|
||||||
style={`height: ${d.h}%`}
|
style={`height: ${d.h}%`}
|
||||||
/>
|
/>
|
||||||
<span class={`text-[10px] font-bold ${d.day === 'WED' ? 'text-[#0a1d37]' : 'text-slate-400'}`}>
|
<span class={`text-[10px] font-bold ${d.day === 'WED' ? 'text-[#0a1d37]' : 'text-slate-400'}`}>
|
||||||
|
|
@ -138,21 +120,21 @@ export default function AdminDashboard() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Intelligence Hub + System Health */}
|
{/* Intelligence Hub + Pipeline */}
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
{/* Intelligence Hub */}
|
{/* Intelligence Hub */}
|
||||||
<div class="relative overflow-hidden rounded-3xl bg-[#0a1d37] p-6 text-white">
|
<div class="relative overflow-hidden rounded-xl bg-[#0a1d37] p-5 text-white">
|
||||||
<div class="absolute -right-4 -top-4 h-24 w-24 rounded-full bg-white/5 blur-2xl" />
|
<div class="absolute -right-4 -top-4 h-20 w-20 rounded-full bg-white/5 blur-2xl" />
|
||||||
<h2 class="mb-4 text-lg font-black">Intelligence Hub</h2>
|
<h2 class="mb-3 text-base font-black">Intelligence Hub</h2>
|
||||||
<div class="space-y-2.5">
|
<div class="space-y-2">
|
||||||
{QUICK_ACTIONS.map((a) => {
|
{QUICK_ACTIONS.map((a) => {
|
||||||
const Icon = a.icon;
|
const Icon = a.icon;
|
||||||
return (
|
return (
|
||||||
<A
|
<A
|
||||||
href={a.href}
|
href={a.href}
|
||||||
class="group flex w-full items-center justify-between rounded-2xl bg-white/10 p-3.5 transition-all hover:bg-white/15"
|
class="group flex w-full items-center justify-between rounded-lg bg-white/10 px-3.5 py-3 transition-all hover:bg-white/15"
|
||||||
>
|
>
|
||||||
<span class="text-sm font-semibold">{a.label}</span>
|
<span class="text-[13px] font-semibold">{a.label}</span>
|
||||||
<Icon class="h-4 w-4 text-[#fd6216] transition-transform group-hover:translate-x-0.5" />
|
<Icon class="h-4 w-4 text-[#fd6216] transition-transform group-hover:translate-x-0.5" />
|
||||||
</A>
|
</A>
|
||||||
);
|
);
|
||||||
|
|
@ -161,26 +143,25 @@ export default function AdminDashboard() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Pipeline Status */}
|
{/* Pipeline Status */}
|
||||||
<div class="rounded-3xl bg-white p-6 shadow-[0_8px_32px_rgba(10,29,55,0.04)]">
|
<div class="rounded-xl bg-white p-5 shadow-[0_4px_20px_rgba(10,29,55,0.06)]">
|
||||||
<h2 class="mb-4 text-[11px] font-black uppercase tracking-widest text-[#0a1d37]">
|
<h2 class="mb-4 text-[10px] font-bold uppercase tracking-widest text-[#0a1d37]">
|
||||||
Pipeline Status
|
Pipeline Status
|
||||||
</h2>
|
</h2>
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
{PIPELINE.map((p) => (
|
{PIPELINE.map((p) => (
|
||||||
<div class="space-y-1.5">
|
<div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="mb-1.5 flex items-center justify-between gap-2">
|
||||||
<div>
|
<div class="min-w-0">
|
||||||
<p class="text-sm font-bold text-[#0a1d37]">{p.name}</p>
|
<p class="truncate text-[13px] font-bold text-[#0a1d37]">{p.name}</p>
|
||||||
<p class="text-[10px] text-slate-400">{p.type}</p>
|
<p class="text-[10px] text-slate-400">{p.type}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class={`rounded-full px-2 py-0.5 text-[10px] font-black uppercase ${p.statusBg}`}>
|
<span class={`shrink-0 rounded-md px-2 py-0.5 text-[10px] font-bold uppercase ${p.statusColor}`}>
|
||||||
{p.status}
|
{p.status}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-1.5 w-full overflow-hidden rounded-full bg-slate-100">
|
<div class="h-1.5 w-full overflow-hidden rounded-full bg-slate-100">
|
||||||
<div class={`h-full rounded-full ${p.color}`} style={`width: ${p.progress}%`} />
|
<div class={`h-full rounded-full ${p.barColor}`} style={`width: ${p.progress}%`} />
|
||||||
</div>
|
</div>
|
||||||
<p class="text-right text-[10px] font-bold text-slate-400">{p.progress}%</p>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -190,28 +171,28 @@ export default function AdminDashboard() {
|
||||||
|
|
||||||
{/* ── Control Plane ── */}
|
{/* ── Control Plane ── */}
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-5 flex items-center justify-between">
|
<div class="mb-4 flex items-center justify-between">
|
||||||
<h2 class="text-xl font-black tracking-tight text-[#0a1d37]">Control Plane</h2>
|
<h2 class="text-lg font-black tracking-tight text-[#0a1d37]">Control Plane</h2>
|
||||||
<span class="rounded-full border border-slate-200 bg-white px-3 py-1 text-[11px] font-bold uppercase tracking-widest text-slate-400 shadow-sm">
|
<span class="rounded-md border border-slate-200 bg-white px-2.5 py-1 text-[10px] font-bold uppercase tracking-widest text-slate-400">
|
||||||
{CONTROL.length} modules
|
{CONTROL.length} modules
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{CONTROL.map((item) => {
|
{CONTROL.map((item) => {
|
||||||
const Icon = item.icon;
|
const Icon = item.icon;
|
||||||
return (
|
return (
|
||||||
<A
|
<A
|
||||||
href={item.href}
|
href={item.href}
|
||||||
class="group flex items-start gap-4 rounded-2xl border border-slate-100 bg-white p-5 shadow-[0_8px_32px_rgba(10,29,55,0.04)] transition-all duration-200 hover:-translate-y-0.5 hover:border-[#fd6216]/20 hover:shadow-[0_12px_40px_rgba(10,29,55,0.08)]"
|
class="group flex items-start gap-3.5 rounded-xl border border-slate-100 bg-white p-4 shadow-[0_4px_20px_rgba(10,29,55,0.04)] transition-all duration-200 hover:-translate-y-px hover:border-[#0a1d37]/10 hover:shadow-[0_8px_28px_rgba(10,29,55,0.08)]"
|
||||||
>
|
>
|
||||||
<div class={`mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-xl ${item.iconBg}`}>
|
<div class={`mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg ${item.iconBg}`}>
|
||||||
<Icon class={`h-4 w-4 ${item.iconFg}`} />
|
<Icon class={`h-4 w-4 ${item.iconFg}`} />
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-bold text-[#0a1d37] transition-colors group-hover:text-[#fd6216]">{item.label}</p>
|
<p class="truncate text-[13px] font-bold text-[#0a1d37] transition-colors group-hover:text-[#fd6216]">{item.label}</p>
|
||||||
<p class="mt-0.5 text-[11px] leading-relaxed text-slate-400">{item.desc}</p>
|
<p class="mt-0.5 text-[11px] leading-relaxed text-slate-400">{item.desc}</p>
|
||||||
</div>
|
</div>
|
||||||
<ArrowRight class="mt-0.5 h-4 w-4 shrink-0 text-slate-200 transition-all group-hover:translate-x-0.5 group-hover:text-[#fd6216]" />
|
<ArrowRight class="mt-0.5 h-3.5 w-3.5 shrink-0 text-slate-200 transition-all group-hover:translate-x-0.5 group-hover:text-[#0a1d37]" />
|
||||||
</A>
|
</A>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue