nxtgauge-admin-solid/src/components/AdminSidebar.tsx

146 lines
7.1 KiB
TypeScript
Raw Normal View History

import { A, useLocation } from '@solidjs/router';
import { createSignal } from 'solid-js';
type LinkItem = {
href: string;
label: string;
icon: string;
aliasPrefix?: string;
};
const links: LinkItem[] = [
{ href: '/admin', label: 'Dashboard', icon: 'dashboard.svg' },
{ href: '/admin/department', label: 'Department Management', icon: 'department.svg' },
{ href: '/admin/designation', label: 'Designation Management', icon: 'designation.svg' },
{ href: '/admin/employees', label: 'Employee Management', icon: 'users.svg' },
{ href: '/admin/roles', label: 'Internal Role Management', icon: 'role.svg' },
{ href: '/admin/runtime-roles', label: 'External Role Management', icon: 'role.svg' },
{ href: '/admin/onboarding-schemas', label: 'External Onboarding Management', icon: 'reviews.svg' },
{ href: '/admin/internal-dashboard-management', label: 'Internal Dashboard Management', icon: 'dashboard.svg' },
{ href: '/admin/external-dashboard-management', label: 'External Dashboard Management', icon: 'dashboard.svg', aliasPrefix: '/admin/role-ui-configs' },
{ href: '/admin/approval', label: 'Approval Management', icon: 'approval.svg' },
{ href: '/admin/users', label: 'Users Management', icon: 'users.svg' },
{ href: '/admin/company', label: 'Company Management', icon: 'company.svg' },
{ href: '/admin/candidate', label: 'Candidate Management', icon: 'candidate.svg' },
{ href: '/admin/customer', label: 'Customer Management', icon: 'users.svg' },
{ href: '/admin/photographer', label: 'Photographer Management', icon: 'photographer.svg' },
{ href: '/admin/makeup-artist', label: 'Makeup Artist Management', icon: 'makeup-artist.svg' },
{ href: '/admin/tutors', label: 'Tutors Management', icon: 'tutor.svg' },
{ href: '/admin/developers', label: 'Developers Management', icon: 'developers.svg' },
{ href: '/admin/video-editors', label: 'Video Editor Management', icon: 'developers.svg' },
{ href: '/admin/fitness-trainers', label: 'Fitness Trainer Management', icon: 'tutor.svg' },
{ href: '/admin/catering-services', label: 'Catering Services Management', icon: 'company.svg' },
{ href: '/admin/graphic-designers', label: 'Graphics Designer Management', icon: 'developers.svg' },
{ href: '/admin/social-media-managers', label: 'Social Media Manager Management', icon: 'developers.svg' },
{ href: '/admin/jobs', label: 'Jobs Management', icon: 'jobs.svg' },
{ href: '/admin/leads', label: 'Leads Management', icon: 'leads.svg' },
{ href: '/admin/pricing', label: 'Pricing Management', icon: 'pricing.svg' },
{ href: '/admin/credit', label: 'Credit Management', icon: 'credits.svg' },
{ href: '/admin/coupon', label: 'Coupon Management', icon: 'coupon.svg' },
{ href: '/admin/discount', label: 'Discount Management', icon: 'discount.svg' },
{ href: '/admin/tax', label: 'Tax Management', icon: 'tax.svg' },
{ href: '/admin/order', label: 'Order Management', icon: 'order.svg' },
{ href: '/admin/invoice', label: 'Invoice Management', icon: 'invoice.svg' },
{ href: '/admin/review', label: 'Review Management', icon: 'reviews.svg' },
{ href: '/admin/support', label: 'Support Management', icon: 'support.svg' },
{ href: '/admin/kb', label: 'Knowledge Base Management', icon: 'reviews.svg' },
{ href: '/admin/notifications', label: 'Notifications', icon: 'reviews.svg' },
{ href: '/admin/report', label: 'Report Management', icon: 'report.svg' },
{ href: '/admin/ledger', label: 'Ledger Management', icon: 'ledger.svg' },
];
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';
if (aliasPrefix && location.pathname.startsWith(aliasPrefix)) return true;
return location.pathname === href || location.pathname.startsWith(`${href}/`);
};
return (
<aside
class={`flex h-full flex-col border-r border-slate-200 bg-[#fcfcfd] px-3 pb-3 pt-5 transition-all duration-300 ${
collapsed() ? 'w-20' : 'w-64'
}`}
>
{/* Collapse toggle */}
<div class="mb-4 flex justify-end px-2">
<button
type="button"
onClick={() => setCollapsed((v) => !v)}
aria-label={collapsed() ? 'Expand sidebar' : 'Collapse sidebar'}
class="rounded-lg p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-700"
>
<svg
class={`h-4 w-4 transition-transform ${collapsed() ? 'rotate-180' : ''}`}
fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7" />
</svg>
</button>
</div>
{/* Nav items */}
<nav class="scrollbar min-h-0 flex-1 space-y-1.5 overflow-y-auto pr-1">
{links.map((item) => {
const active = isActive(item.href, item.aliasPrefix);
return (
<A
href={item.href}
activeClass=""
inactiveClass=""
title={collapsed() ? item.label : undefined}
class={`group relative flex items-center gap-3 rounded-xl border px-3 py-3 text-[15px] leading-5 transition-all ${
collapsed() ? 'justify-center px-2' : ''
} ${
active
? 'border-orange-200 bg-gradient-to-r from-orange-50 to-orange-100/70 text-slate-900 shadow-[inset_3px_0_0_0_#FD6216]'
: 'border-transparent text-slate-500 hover:border-slate-200 hover:bg-white hover:text-slate-800'
}`}
>
{/* Active left rail */}
<span
class={`absolute bottom-2 left-0 top-2 w-[3px] rounded-r-full bg-orange-500 transition-opacity ${
active ? 'opacity-100' : 'opacity-0'
}`}
/>
{/* Icon */}
<img
src={`/sidebar-icons/${item.icon}`}
alt=""
class="h-[18px] w-[18px] shrink-0 transition-all"
style={active
? 'filter: invert(42%) sepia(78%) saturate(1200%) hue-rotate(360deg) brightness(95%) contrast(95%); opacity:1'
: 'opacity:0.45'
}
/>
{/* Label */}
{!collapsed() && (
<span class={`truncate font-medium ${active ? 'text-slate-900' : 'text-slate-600 group-hover:text-slate-800'}`}>
{item.label}
</span>
)}
{/* Active badge (expanded) */}
{!collapsed() && active && (
<span class="ml-auto rounded-full border border-orange-200 bg-orange-100 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-orange-700">
Active
</span>
)}
{/* Active dot (collapsed) */}
{collapsed() && active && (
<span class="absolute -right-0.5 top-1/2 h-2 w-2 -translate-y-1/2 rounded-full bg-orange-500" />
)}
</A>
);
})}
</nav>
</aside>
);
}