From df560a91ea1631b99bf73146728766a2214e5948 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Mon, 23 Mar 2026 23:34:33 +0100 Subject: [PATCH] =?UTF-8?q?feat(ui):=20apply=20stitch=20design=20system=20?= =?UTF-8?q?=E2=80=94=20left-accent=20KPI=20cards,=20Intelligence=20Hub,=20?= =?UTF-8?q?glassmorphism=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app.css: Exo 2 font, #0a1d37 navy + #fd6216 orange tokens, #f9f9fd background - AdminShell: backdrop-blur-xl glassmorphism header, centered search bar, settings icon, name + bordered avatar, ambient shadow-[0_4px_24px_rgba(10,29,55,0.04)] - AdminSidebar: white bg, left orange 4px pill accent on active (before: pseudo), bg-slate-50 active state, MANAGEMENT/FINANCE/PLATFORM group labels, user card at bottom - Dashboard: KPI cards with absolute left-0 accent bar + ambient shadows, big font-black numbers, System Activity bar chart, Intelligence Hub dark navy panel with quick-action buttons, Pipeline Status cards with progress bars, Control Plane 3-col grid Co-Authored-By: Claude Sonnet 4.6 --- src/app.css | 150 ++++++----------- src/components/AdminShell.tsx | 100 ++++++------ src/components/AdminSidebar.tsx | 236 ++++++++++++--------------- src/routes/admin/index.tsx | 276 +++++++++++++++++++------------- 4 files changed, 362 insertions(+), 400 deletions(-) diff --git a/src/app.css b/src/app.css index 0951c3b..9a9605f 100644 --- a/src/app.css +++ b/src/app.css @@ -1,145 +1,85 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Exo+2:wght@400;500;600;700;800&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400&display=swap'); @import "tailwindcss"; @theme { - --color-brand-orange: #fd6216; - --color-brand-navy: #050026; - --color-orange-50: #fff4ee; - --color-orange-100: #ffe4d0; - --color-orange-200: #ffc9a0; - --color-orange-500: #fd6216; - --color-orange-600: #e5560f; + --color-primary: #fd6216; + --color-navy: #0a1d37; - /* Sidebar tokens */ - --color-sidebar-bg: #ffffff; - --color-sidebar-border: #f1f5f9; - --color-sidebar-text: #64748b; - --color-sidebar-active-text: #0f172a; + /* Brand surfaces */ + --color-bg: #f9f9fd; + --color-surface: #ffffff; + --color-surface-low: #f3f3f7; + --color-surface-container: #edeef1; - /* Surface tokens */ - --color-surface: #ffffff; - --color-surface-raised: #f8fafc; - --color-border-subtle: #f1f5f9; - --color-border: #e2e8f0; + /* Tailwind orange overrides */ + --color-orange-50: #fff4ee; + --color-orange-100: #ffe4d0; + --color-orange-200: #ffc9a0; + --color-orange-500: #fd6216; + --color-orange-600: #e5560f; - --font-family-sans: 'Inter', 'Exo 2', sans-serif; + --font-family-sans: 'Exo 2', sans-serif; } -* { - box-sizing: border-box; - margin: 0; - padding: 0; -} +* { box-sizing: border-box; margin: 0; padding: 0; } body { - font-family: 'Inter', 'Exo 2', sans-serif; - background: #f8fafc; - color: #0f172a; + font-family: 'Exo 2', sans-serif; + background: #f9f9fd; + color: #0a1d37; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* ===== Scrollbar ===== */ -.scrollbar { - scrollbar-width: thin; - scrollbar-color: #c7c7c7 transparent; -} -.scrollbar::-webkit-scrollbar { height: 8px; width: 8px; } +.scrollbar { scrollbar-width: thin; scrollbar-color: #c7c7c7 transparent; } +.scrollbar::-webkit-scrollbar { height: 6px; width: 6px; } .scrollbar::-webkit-scrollbar-track { background: transparent; } .scrollbar::-webkit-scrollbar-thumb { background-color: #c7c7c7; border-radius: 9999px; } .scrollbar::-webkit-scrollbar-thumb:hover { background-color: #9ca3af; } /* ===== Auth / Login page ===== */ .auth-page { - position: relative; - min-height: 100vh; - display: grid; - place-items: center; - padding: 20px; - overflow: hidden; + position: relative; min-height: 100vh; + display: grid; place-items: center; padding: 20px; overflow: hidden; } - .auth-bg { - position: absolute; - inset: 0; + position: absolute; inset: 0; background: radial-gradient(circle at 20% 20%, rgba(253, 98, 22, 0.24), transparent 42%), radial-gradient(circle at 80% 10%, rgba(99, 102, 241, 0.16), transparent 34%), linear-gradient(180deg, #100b2f 0%, #0c0828 52%, #07051d 100%); } - .auth-layout { - position: relative; - z-index: 1; - width: min(1120px, 100%); - display: grid; - grid-template-columns: 1.08fr 0.92fr; - gap: 24px; - align-items: stretch; + position: relative; z-index: 1; width: min(1120px, 100%); + display: grid; grid-template-columns: 1.08fr 0.92fr; gap: 24px; align-items: stretch; } - .auth-visual { - border-radius: 24px; - border: 1px solid rgba(255, 255, 255, 0.18); - background: rgba(255, 255, 255, 0.08); - padding: 28px; - box-shadow: 0 24px 72px -34px rgba(0, 0, 0, 0.72); + border-radius: 24px; border: 1px solid rgba(255,255,255,0.18); + background: rgba(255,255,255,0.08); padding: 28px; + box-shadow: 0 24px 72px -34px rgba(0,0,0,0.72); } - .auth-visual-kicker { - margin: 0; - display: inline-flex; - border-radius: 999px; - border: 1px solid rgba(255, 255, 255, 0.2); - background: rgba(255, 255, 255, 0.1); - color: #ffd7c2; - font-size: 11px; - font-weight: 700; - letter-spacing: 0.12em; - text-transform: uppercase; - padding: 6px 10px; + margin: 0; display: inline-flex; border-radius: 999px; + border: 1px solid rgba(255,255,255,0.2); background: rgba(255,255,255,0.1); + color: #ffd7c2; font-size: 11px; font-weight: 700; + letter-spacing: 0.12em; text-transform: uppercase; padding: 6px 10px; } - -.auth-visual h1 { - margin: 16px 0 0; - font-size: clamp(30px, 3.4vw, 42px); - line-height: 1.1; - color: #fff; -} - -.auth-visual p { - margin: 12px 0 0; - color: rgba(255, 255, 255, 0.82); -} - -.auth-visual img { - margin-top: 18px; - width: 100%; - height: 280px; - border-radius: 16px; - object-fit: cover; -} - +.auth-visual h1 { margin: 16px 0 0; font-size: clamp(30px,3.4vw,42px); line-height: 1.1; color: #fff; } +.auth-visual p { margin: 12px 0 0; color: rgba(255,255,255,0.82); } +.auth-visual img { margin-top: 18px; width: 100%; height: 280px; border-radius: 16px; object-fit: cover; } .auth-card { - position: relative; - z-index: 1; - border-radius: 24px; - border: 1px solid rgba(255, 255, 255, 0.22); - background: rgba(255, 255, 255, 0.96); - box-shadow: 0 24px 72px -34px rgba(0, 0, 0, 0.72); - padding: 30px; - color: #0f172a; + position: relative; z-index: 1; border-radius: 24px; + border: 1px solid rgba(255,255,255,0.22); background: rgba(255,255,255,0.96); + box-shadow: 0 24px 72px -34px rgba(0,0,0,0.72); padding: 30px; color: #0f172a; } - -.auth-form-card { display: flex; flex-direction: column; } -.auth-logo { height: 52px; width: auto; object-fit: contain; margin: 0 auto; } -.auth-title { margin: 18px 0 0; text-align: center; font-size: 32px; font-weight: 800; color: #0f172a; } -.auth-copy { margin: 12px 0 0; text-align: center; color: #475569; } -.auth-form-grid { margin-top: 24px; } - -.auth-switch { display: flex; justify-content: flex-end; margin-top: -2px; } +.auth-form-card { display: flex; flex-direction: column; } +.auth-logo { height: 52px; width: auto; object-fit: contain; margin: 0 auto; } +.auth-title { margin: 18px 0 0; text-align: center; font-size: 32px; font-weight: 800; color: #0f172a; } +.auth-copy { margin: 12px 0 0; text-align: center; color: #475569; } +.auth-form-grid { margin-top: 24px; } +.auth-switch { display: flex; justify-content: flex-end; margin-top: -2px; } .auth-switch.split { justify-content: space-between; } - .auth-link-btn { border: 0; padding: 0; background: transparent; color: #fd6216; font-size: 13px; font-weight: 600; cursor: pointer; diff --git a/src/components/AdminShell.tsx b/src/components/AdminShell.tsx index 0d52527..0b09af3 100644 --- a/src/components/AdminShell.tsx +++ b/src/components/AdminShell.tsx @@ -191,74 +191,78 @@ export default function AdminShell(props: { children: JSX.Element }) { const initials = () => adminName().charAt(0).toUpperCase() || 'A'; return ( -
+
{/* ── Fixed Header ── */} -
- {/* Left: logo + separator + page title */} -
-
- NXTGAUGE -
-
- {pageTitle()} +
+ {/* Left: logo */} +
+ NXTGAUGE
- {/* Right: notifications + avatar + logout */} -
+ {/* Center: search */} +
+ + + + +
+ + {/* Right: actions + avatar */} +
{/* Notification bell */} - -
+ {/* Settings */} + - {/* Avatar + name */} -
- +
- {/* Logout */} - + {/* Name + avatar */} +
+ {adminName()} +
+ {initials()} +
+ + {/* Logout */} +
{/* ── Body: sidebar + main (fixed, below header) ── */} {checkedSession() ? ( -
+
{/* Sidebar */} {/* Main content */} -
+
{/* Sub-tabs (shown for multi-tab sections) */} {tabs().length > 0 && (
@@ -281,8 +285,8 @@ export default function AdminShell(props: { children: JSX.Element }) {
) : ( /* Session check loading state */ -
-
+
+

Checking session…

diff --git a/src/components/AdminSidebar.tsx b/src/components/AdminSidebar.tsx index 8bae74d..b8e7c19 100644 --- a/src/components/AdminSidebar.tsx +++ b/src/components/AdminSidebar.tsx @@ -1,71 +1,59 @@ import { A, useLocation } from '@solidjs/router'; -import { createSignal } from 'solid-js'; type LinkItem = { href: string; label: string; icon: string; aliasPrefix?: string; - group?: string; + group: string; }; const links: LinkItem[] = [ - { href: '/admin', label: 'Dashboard', icon: 'dashboard.svg', group: 'Overview' }, + { href: '/admin', label: 'Dashboard', icon: 'dashboard.svg', group: '__top__' }, - { href: '/admin/department', label: 'Department', icon: 'department.svg', group: 'Organization' }, - { href: '/admin/designation', label: 'Designation', icon: 'designation.svg', group: 'Organization' }, - { href: '/admin/employees', label: 'Employees', icon: 'users.svg', group: 'Organization' }, + { 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/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/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/department', label: 'Department Management', icon: 'department.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/users', label: 'Users Management', icon: 'users.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/customer', label: 'Customer Management', icon: 'users.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/tutors', label: 'Tutors Management', icon: 'tutor.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/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/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/jobs', label: 'Jobs Management', icon: 'jobs.svg', group: 'Management' }, + { href: '/admin/leads', label: 'Leads Management', icon: 'leads.svg', group: 'Management' }, - { href: '/admin/roles', label: 'Internal Roles', icon: 'role.svg', group: 'Access & Roles' }, - { href: '/admin/runtime-roles', label: 'External Roles', icon: 'role.svg', group: 'Access & Roles' }, - { href: '/admin/onboarding-schemas', label: 'Onboarding Flows', icon: 'reviews.svg', group: 'Access & Roles' }, + { href: '/admin/pricing', label: 'Pricing Management', icon: 'pricing.svg', group: 'Finance' }, + { href: '/admin/credit', label: 'Credit Management', icon: 'credits.svg', group: 'Finance' }, + { href: '/admin/coupon', label: 'Coupon Management', icon: 'coupon.svg', group: 'Finance' }, + { href: '/admin/discount', label: 'Discount Management', icon: 'discount.svg', group: 'Finance' }, + { href: '/admin/tax', label: 'Tax Management', icon: 'tax.svg', group: 'Finance' }, + { href: '/admin/order', label: 'Order Management', icon: 'order.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/internal-dashboard-management', label: 'Internal Dashboards', icon: 'dashboard.svg', group: 'Dashboards' }, - { href: '/admin/external-dashboard-management', label: 'External Dashboards', icon: 'dashboard.svg', aliasPrefix: '/admin/role-ui-configs', group: 'Dashboards' }, - - { href: '/admin/users', label: 'Users', icon: 'users.svg', group: 'People' }, - { href: '/admin/company', label: 'Companies', icon: 'company.svg', group: 'People' }, - { href: '/admin/candidate', label: 'Candidates', icon: 'candidate.svg', group: 'People' }, - { href: '/admin/customer', label: 'Customers', icon: 'users.svg', group: 'People' }, - { href: '/admin/photographer', label: 'Photographers', icon: 'photographer.svg', group: 'People' }, - { href: '/admin/makeup-artist', label: 'Makeup Artists', icon: 'makeup-artist.svg', group: 'People' }, - { href: '/admin/tutors', label: 'Tutors', icon: 'tutor.svg', group: 'People' }, - { href: '/admin/developers', label: 'Developers', icon: 'developers.svg', group: 'People' }, - { href: '/admin/video-editors', label: 'Video Editors', icon: 'developers.svg', group: 'People' }, - { href: '/admin/fitness-trainers', label: 'Fitness Trainers', icon: 'tutor.svg', group: 'People' }, - { href: '/admin/catering-services', label: 'Catering Services', icon: 'company.svg', group: 'People' }, - { href: '/admin/graphic-designers', label: 'Graphic Designers', icon: 'developers.svg', group: 'People' }, - { href: '/admin/social-media-managers', label: 'Social Media Mgr.', icon: 'developers.svg', group: 'People' }, - - { href: '/admin/jobs', label: 'Jobs', icon: 'jobs.svg', group: 'Content' }, - { href: '/admin/leads', label: 'Leads', icon: 'leads.svg', group: 'Content' }, - { href: '/admin/review', label: 'Reviews', icon: 'reviews.svg', group: 'Content' }, - { href: '/admin/kb', label: 'Knowledge Base', icon: 'reviews.svg', group: 'Content' }, - { href: '/admin/notifications', label: 'Notifications', icon: 'reviews.svg', group: 'Content' }, - - { href: '/admin/pricing', label: 'Pricing', icon: 'pricing.svg', group: 'Finance' }, - { href: '/admin/credit', label: 'Credits', icon: 'credits.svg', group: 'Finance' }, - { href: '/admin/coupon', label: 'Coupons', icon: 'coupon.svg', group: 'Finance' }, - { href: '/admin/discount', label: 'Discounts', icon: 'discount.svg', group: 'Finance' }, - { href: '/admin/tax', label: 'Tax', icon: 'tax.svg', group: 'Finance' }, - { href: '/admin/order', label: 'Orders', icon: 'order.svg', group: 'Finance' }, - { href: '/admin/invoice', label: 'Invoices', icon: 'invoice.svg', group: 'Finance' }, - { href: '/admin/ledger', label: 'Ledger', icon: 'ledger.svg', group: 'Finance' }, - - { href: '/admin/approval', label: 'Approvals', icon: 'approval.svg', group: 'Operations' }, - { href: '/admin/support', label: 'Support', icon: 'support.svg', group: 'Operations' }, - { href: '/admin/report', label: 'Reports', icon: 'report.svg', group: 'Operations' }, + { href: '/admin/review', label: 'Review Management', icon: 'reviews.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/notifications', label: 'Notifications', icon: 'reviews.svg', group: 'Platform' }, + { href: '/admin/report', label: 'Report Management', icon: 'report.svg', group: 'Platform' }, ]; -// Build ordered group list preserving first appearance -const GROUP_ORDER: string[] = []; -for (const item of links) { - if (item.group && !GROUP_ORDER.includes(item.group)) GROUP_ORDER.push(item.group); -} - export default function AdminSidebar() { const location = useLocation(); - const [collapsed, setCollapsed] = createSignal(false); const isActive = (href: string, aliasPrefix?: string) => { if (href === '/admin') return location.pathname === '/admin'; @@ -73,91 +61,73 @@ export default function AdminSidebar() { 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 active = isActive(item.href, item.aliasPrefix); + return ( + + + {item.label} + + ); + }; + + const GroupLabel = (label: string) => ( +
+

{label}

+
+ ); + return ( -