2026-03-16 23:20:54 +01:00
|
|
|
import { A, useLocation } from '@solidjs/router';
|
2026-03-24 02:36:40 +01:00
|
|
|
import { For, Show } from 'solid-js';
|
|
|
|
|
import {
|
|
|
|
|
Bell,
|
|
|
|
|
Briefcase,
|
|
|
|
|
ClipboardList,
|
|
|
|
|
FileText,
|
|
|
|
|
FolderCog,
|
|
|
|
|
HandHelping,
|
|
|
|
|
LayoutGrid,
|
|
|
|
|
Percent,
|
|
|
|
|
Receipt,
|
|
|
|
|
Sparkles,
|
|
|
|
|
UserCircle2,
|
|
|
|
|
Users,
|
|
|
|
|
WalletCards,
|
|
|
|
|
} from 'lucide-solid';
|
|
|
|
|
|
|
|
|
|
type Item = {
|
feat(admin): Phase 0 — Tailwind v4 foundation, shell rewrite, modern dashboard
- Install Tailwind CSS v4 via @tailwindcss/vite; configure vite.config.ts
- Rewrite app.css: Tailwind base, Exo 2 font, brand tokens (orange #fd6216, navy #050026), scrollbar utility; fix @import order
- Rewrite AdminShell.tsx: fixed header, fixed inset body grid (sidebar + main), session check, sub-tab system, logout, admin avatar/name/role
- Rewrite AdminSidebar.tsx: collapsible w-64/w-20, orange active rail + badge/dot, CSS filter for SVG icon tinting, min-h-0 flex fix
- Replace 84 route stub CSS classes (page-title, card, btn, table-wrap, etc.) with Tailwind equivalents via safe class-attr-only regex script
- Rewrite admin dashboard: Lucide icons in colored chip backgrounds, 4-col KPI grid, Control Plane 6-module grid, hover lift animations
- Disable SSR (ssr: false) to fix Vinxi dev manifest error; clear stale .vinxi cache
- Add lucide-solid icon library
- Add scripts/cleanup-css.mjs for class migration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:00:21 +01:00
|
|
|
href: string;
|
|
|
|
|
label: string;
|
2026-03-24 02:36:40 +01:00
|
|
|
iconPath?: string;
|
|
|
|
|
icon?: any;
|
feat(admin): Phase 0 — Tailwind v4 foundation, shell rewrite, modern dashboard
- Install Tailwind CSS v4 via @tailwindcss/vite; configure vite.config.ts
- Rewrite app.css: Tailwind base, Exo 2 font, brand tokens (orange #fd6216, navy #050026), scrollbar utility; fix @import order
- Rewrite AdminShell.tsx: fixed header, fixed inset body grid (sidebar + main), session check, sub-tab system, logout, admin avatar/name/role
- Rewrite AdminSidebar.tsx: collapsible w-64/w-20, orange active rail + badge/dot, CSS filter for SVG icon tinting, min-h-0 flex fix
- Replace 84 route stub CSS classes (page-title, card, btn, table-wrap, etc.) with Tailwind equivalents via safe class-attr-only regex script
- Rewrite admin dashboard: Lucide icons in colored chip backgrounds, 4-col KPI grid, Control Plane 6-module grid, hover lift animations
- Disable SSR (ssr: false) to fix Vinxi dev manifest error; clear stale .vinxi cache
- Add lucide-solid icon library
- Add scripts/cleanup-css.mjs for class migration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:00:21 +01:00
|
|
|
aliasPrefix?: string;
|
2026-03-24 02:36:40 +01:00
|
|
|
separatorBefore?: boolean;
|
feat(admin): Phase 0 — Tailwind v4 foundation, shell rewrite, modern dashboard
- Install Tailwind CSS v4 via @tailwindcss/vite; configure vite.config.ts
- Rewrite app.css: Tailwind base, Exo 2 font, brand tokens (orange #fd6216, navy #050026), scrollbar utility; fix @import order
- Rewrite AdminShell.tsx: fixed header, fixed inset body grid (sidebar + main), session check, sub-tab system, logout, admin avatar/name/role
- Rewrite AdminSidebar.tsx: collapsible w-64/w-20, orange active rail + badge/dot, CSS filter for SVG icon tinting, min-h-0 flex fix
- Replace 84 route stub CSS classes (page-title, card, btn, table-wrap, etc.) with Tailwind equivalents via safe class-attr-only regex script
- Rewrite admin dashboard: Lucide icons in colored chip backgrounds, 4-col KPI grid, Control Plane 6-module grid, hover lift animations
- Disable SSR (ssr: false) to fix Vinxi dev manifest error; clear stale .vinxi cache
- Add lucide-solid icon library
- Add scripts/cleanup-css.mjs for class migration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:00:21 +01:00
|
|
|
};
|
2026-03-19 03:36:46 +01:00
|
|
|
|
2026-03-24 02:36:40 +01:00
|
|
|
const items: Item[] = [
|
|
|
|
|
{ href: '/admin', label: 'Dashboard', iconPath: '/sidebar-icons/dashboard.svg', icon: LayoutGrid },
|
|
|
|
|
{ href: '/admin/roles', label: 'Internal Role Management', iconPath: '/sidebar-icons/role.svg', icon: FolderCog },
|
|
|
|
|
{ href: '/admin/runtime-roles', label: 'External Role Management', iconPath: '/sidebar-icons/users.svg', icon: Users },
|
|
|
|
|
{ href: '/admin/onboarding-management', label: 'External Onboarding', iconPath: '/sidebar-icons/users.svg', icon: Users, aliasPrefix: '/admin/onboarding-schemas' },
|
|
|
|
|
{ href: '/admin/internal-dashboard-management', label: 'Internal Dashboards', iconPath: '/sidebar-icons/dashboard.svg', icon: LayoutGrid },
|
|
|
|
|
{ href: '/admin/external-dashboard-management', label: 'External Dashboards', iconPath: '/sidebar-icons/dashboard.svg', icon: LayoutGrid, aliasPrefix: '/admin/role-ui-configs' },
|
|
|
|
|
{ href: '/admin/approval', label: 'Approval Management', iconPath: '/sidebar-icons/approval.svg', icon: ClipboardList },
|
|
|
|
|
{ href: '/admin/department', label: 'Department Management', iconPath: '/sidebar-icons/department.svg', icon: Briefcase, separatorBefore: true },
|
|
|
|
|
{ href: '/admin/designation', label: 'Designation Management', iconPath: '/sidebar-icons/designation.svg', icon: Briefcase },
|
|
|
|
|
{ href: '/admin/employees', label: 'Employee Management', iconPath: '/sidebar-icons/users.svg', icon: UserCircle2 },
|
|
|
|
|
{ href: '/admin/users', label: 'Users Management', iconPath: '/sidebar-icons/users.svg', icon: Users },
|
|
|
|
|
{ href: '/admin/company', label: 'Company Management', iconPath: '/sidebar-icons/company.svg', icon: Briefcase },
|
|
|
|
|
{ href: '/admin/candidate', label: 'Candidate Management', iconPath: '/sidebar-icons/candidate.svg', icon: UserCircle2 },
|
|
|
|
|
{ href: '/admin/customer', label: 'Customer Management', iconPath: '/sidebar-icons/support.svg', icon: UserCircle2 },
|
|
|
|
|
{ href: '/admin/photographer', label: 'Photographer Management', iconPath: '/sidebar-icons/photographer.svg', icon: Sparkles, separatorBefore: true },
|
|
|
|
|
{ href: '/admin/makeup-artist', label: 'Makeup Artist Management', iconPath: '/sidebar-icons/makeup-artist.svg', icon: Sparkles },
|
|
|
|
|
{ href: '/admin/tutors', label: 'Tutors Management', iconPath: '/sidebar-icons/tutor.svg', icon: Sparkles },
|
|
|
|
|
{ href: '/admin/developers', label: 'Developers Management', iconPath: '/sidebar-icons/developers.svg', icon: Sparkles },
|
|
|
|
|
{ href: '/admin/jobs', label: 'Jobs Management', iconPath: '/sidebar-icons/jobs.svg', icon: Briefcase },
|
|
|
|
|
{ href: '/admin/leads', label: 'Leads Management', iconPath: '/sidebar-icons/leads.svg', icon: HandHelping },
|
|
|
|
|
{ href: '/admin/pricing', label: 'Pricing Management', iconPath: '/sidebar-icons/pricing.svg', icon: WalletCards },
|
|
|
|
|
{ href: '/admin/credit', label: 'Credit Management', iconPath: '/sidebar-icons/credits.svg', icon: WalletCards },
|
|
|
|
|
{ href: '/admin/coupon', label: 'Coupon Management', iconPath: '/sidebar-icons/coupon.svg', icon: Percent },
|
|
|
|
|
{ href: '/admin/discount', label: 'Discount Management', iconPath: '/sidebar-icons/discount.svg', icon: Percent },
|
|
|
|
|
{ href: '/admin/tax', label: 'Tax Management', iconPath: '/sidebar-icons/tax.svg', icon: Receipt },
|
|
|
|
|
{ href: '/admin/order', label: 'Order Management', iconPath: '/sidebar-icons/order.svg', icon: FileText },
|
|
|
|
|
{ href: '/admin/invoice', label: 'Invoice Management', iconPath: '/sidebar-icons/invoice.svg', icon: FileText },
|
|
|
|
|
{ href: '/admin/review', label: 'Review Management', iconPath: '/sidebar-icons/reviews.svg', icon: FileText },
|
|
|
|
|
{ href: '/admin/support', label: 'Support Management', iconPath: '/sidebar-icons/support.svg', icon: UserCircle2 },
|
|
|
|
|
{ href: '/admin/report', label: 'Report Management', iconPath: '/sidebar-icons/report.svg', icon: Bell },
|
|
|
|
|
{ href: '/admin/ledger', label: 'Ledger Management', iconPath: '/sidebar-icons/ledger.svg', icon: Receipt },
|
|
|
|
|
{ href: '/admin/kb', label: 'Knowledge Base', icon: FileText },
|
|
|
|
|
{ href: '/admin/notifications', label: 'Notifications', icon: Bell },
|
2026-03-16 23:20:54 +01:00
|
|
|
];
|
|
|
|
|
|
2026-03-24 02:36:40 +01:00
|
|
|
function renderIcon(item: Item, isActive: boolean) {
|
|
|
|
|
if (item.iconPath) {
|
|
|
|
|
return <img src={item.iconPath} alt="" class={`h-[18px] w-[18px] object-contain ${isActive ? 'opacity-95' : 'opacity-70'}`} />;
|
|
|
|
|
}
|
|
|
|
|
const Icon = item.icon || FileText;
|
|
|
|
|
return <Icon size={18} class={isActive ? 'text-[#0f172a]' : 'text-slate-500'} />;
|
|
|
|
|
}
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
2026-03-24 02:36:40 +01:00
|
|
|
export default function AdminSidebar(props: { onNavigate?: () => void; onLogout?: () => void }) {
|
|
|
|
|
const location = useLocation();
|
2026-03-16 23:20:54 +01:00
|
|
|
|
2026-03-24 02:36:40 +01:00
|
|
|
const active = (item: Item) => {
|
|
|
|
|
if (item.href === '/admin') return location.pathname === '/admin';
|
|
|
|
|
if (item.aliasPrefix && location.pathname.startsWith(item.aliasPrefix)) return true;
|
|
|
|
|
return location.pathname === item.href || location.pathname.startsWith(`${item.href}/`);
|
feat(ui): apply stitch design system — left-accent KPI cards, Intelligence Hub, glassmorphism header
- 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 <noreply@anthropic.com>
2026-03-23 23:34:33 +01:00
|
|
|
};
|
|
|
|
|
|
2026-03-16 23:20:54 +01:00
|
|
|
return (
|
2026-03-24 02:36:40 +01:00
|
|
|
<aside class="flex h-full w-[310px] flex-col border-r border-[#d7d8df] bg-[#f6f6f8]">
|
|
|
|
|
<nav class="scrollbar flex-1 overflow-y-auto px-6 py-5">
|
|
|
|
|
<For each={items}>
|
|
|
|
|
{(item) => {
|
|
|
|
|
const isActive = active(item);
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Show when={item.separatorBefore}>
|
|
|
|
|
<div class="my-4 border-t border-[#dfdfe5]" />
|
|
|
|
|
</Show>
|
|
|
|
|
<A
|
|
|
|
|
href={item.href}
|
|
|
|
|
onClick={() => props.onNavigate?.()}
|
|
|
|
|
class={`group relative mb-1.5 flex min-h-[48px] items-center gap-3 rounded-xl px-4 text-[17px] font-medium leading-tight transition ${
|
|
|
|
|
isActive ? 'bg-[#ffece3] text-[#fd6216]' : 'text-[#2f3647] hover:bg-white hover:text-[#111827]'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
<span class={`absolute bottom-0 left-0 top-0 w-[4px] rounded-r-md bg-[#fd6216] transition-opacity ${isActive ? 'opacity-100' : 'opacity-0'}`} />
|
|
|
|
|
{renderIcon(item, isActive)}
|
|
|
|
|
<span class="truncate">{item.label}</span>
|
|
|
|
|
</A>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
</For>
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<div class="border-t border-[#dfdfe5] px-6 py-5">
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={() => props.onLogout?.()}
|
|
|
|
|
class="flex h-[50px] w-full items-center gap-3 rounded-xl px-4 text-left text-[17px] font-semibold text-[#c51d1d] transition hover:bg-[#fff1f1]"
|
|
|
|
|
>
|
|
|
|
|
<svg class="h-[18px] w-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H9m8 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h8a3 3 0 013 3v1" />
|
|
|
|
|
</svg>
|
|
|
|
|
<span>Sign Out</span>
|
|
|
|
|
</button>
|
feat(ui): apply stitch design system — left-accent KPI cards, Intelligence Hub, glassmorphism header
- 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 <noreply@anthropic.com>
2026-03-23 23:34:33 +01:00
|
|
|
</div>
|
2026-03-16 23:20:54 +01:00
|
|
|
</aside>
|
|
|
|
|
);
|
|
|
|
|
}
|