import { A, useLocation, useNavigate, useSearchParams } from '@solidjs/router'; import { createMemo, createSignal, onMount, type JSX } from 'solid-js'; import AdminSidebar from './AdminSidebar'; import { isExternalIdentity } from '~/lib/admin-auth'; import { clearAdminSession, hasAdminSession, setAdminSession } from '~/lib/admin-session'; import { sidebarCollapsed } from '~/lib/sidebar-state'; type Tab = { href: string; label: string; exact?: boolean }; const TAB_SETS: Array<{ prefixes: string[]; tabs: Tab[] }> = [ { prefixes: ['/admin/roles'], tabs: [ { href: '/admin/roles', label: 'Internal Roles', exact: true }, { href: '/admin/roles/create', label: 'Create Role' }, { href: '/admin/roles/templates', label: 'Role Templates' }, ], }, { prefixes: ['/admin/runtime-roles'], tabs: [ { href: '/admin/runtime-roles', label: 'External Roles', exact: true }, { href: '/admin/runtime-roles/new', label: 'Create External Role' }, ], }, { prefixes: ['/admin/onboarding-schemas'], tabs: [ { href: '/admin/onboarding-schemas', label: 'Onboarding Flows', exact: true }, { href: '/admin/onboarding-schemas/new', label: 'Create Flow' }, ], }, { prefixes: ['/admin/internal-dashboard-management'], tabs: [ { href: '/admin/internal-dashboard-management', label: 'Internal Dashboards' }, ], }, { prefixes: ['/admin/external-dashboard-management'], tabs: [ { href: '/admin/external-dashboard-management', label: 'External Dashboards' }, ], }, { prefixes: ['/admin/role-ui-configs'], tabs: [ { href: '/admin/role-ui-configs', label: 'Config Inspector', exact: true }, { href: '/admin/role-ui-configs/new', label: 'Create Config' }, ], }, ]; const PAGE_TITLES: Array<{ prefix: string; title: string }> = [ { prefix: '/admin/workspace', title: 'Dashboard Workspace' }, { prefix: '/admin/settings', title: 'Settings' }, { prefix: '/admin/role-modules', title: 'Role Modules' }, { prefix: '/admin/modules', title: 'Module Management' }, { prefix: '/admin/responses', title: 'Lead Responses' }, { prefix: '/admin/applications', title: 'Applications' }, { prefix: '/admin/financial', title: 'Financial Management' }, { prefix: '/admin/help', title: 'Support Management' }, { prefix: '/admin/verification-status', title: 'Verification Status' }, { prefix: '/admin/verification', title: 'Verification Review' }, { prefix: '/admin/approval', title: 'Approval Management' }, { prefix: '/admin/users', title: 'Users Management' }, { prefix: '/admin/company', title: 'Company Management' }, { prefix: '/admin/customer', title: 'Customer Management' }, { prefix: '/admin/candidate', title: 'Candidate Management' }, { prefix: '/admin/photographer', title: 'Photographer Management' }, { prefix: '/admin/makeup-artist', title: 'Makeup Artist Management' }, { prefix: '/admin/tutors', title: 'Tutors Management' }, { prefix: '/admin/developers', title: 'Developers Management' }, { prefix: '/admin/graphic-designers', title: 'Graphics Designer Management' }, { prefix: '/admin/jobs', title: 'Jobs Management' }, { prefix: '/admin/leads', title: 'Leads Management' }, { prefix: '/admin/pricing', title: 'Pricing Management' }, { prefix: '/admin/invoice', title: 'Invoice Management' }, { prefix: '/admin/credit', title: 'Credit Management' }, { prefix: '/admin/ledger', title: 'Ledger Management' }, { prefix: '/admin/report', title: 'Report Management' }, { prefix: '/admin/employees', title: 'Employee Management' }, { prefix: '/admin/roles', title: 'Internal Role Management' }, { prefix: '/admin/external-role-management', title: 'External Role Management' }, { prefix: '/admin/internal-role-management', title: 'Internal Role Management' }, { prefix: '/admin/runtime-roles', title: 'External Role Management' }, { prefix: '/admin/onboarding-management', title: 'External Onboarding Management' }, { prefix: '/admin/onboarding-schemas', title: 'External Onboarding Management' }, { prefix: '/admin/kb', title: 'KB Management' }, { prefix: '/admin', title: 'Dashboard' }, ]; export default function AdminShell(props: { children: JSX.Element }) { const location = useLocation(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); const [checkedSession, setCheckedSession] = createSignal(false); const tabs = createMemo(() => { const path = location.pathname; for (const set of TAB_SETS) { if (set.prefixes.some((p) => path === p || path.startsWith(`${p}/`))) { return set.tabs; } } return []; }); const isTabActive = (tab: Tab) => { if (tab.exact) return location.pathname === tab.href; return location.pathname === tab.href || location.pathname.startsWith(`${tab.href}/`); }; const pageTitle = createMemo(() => { const path = location.pathname; for (const item of PAGE_TITLES) { if (path === item.prefix || path.startsWith(`${item.prefix}/`)) return item.title; } return 'Dashboard'; }); onMount(() => { // ?_preview=1 or sessionStorage flag — bypass auth for UI testing without a live backend. // Sets the session cookie AND a sessionStorage flag so all subsequent pages in this tab // also skip the API check without needing ?_preview=1 in every URL. const isPreview = searchParams._preview === '1' || (typeof sessionStorage !== 'undefined' && sessionStorage.getItem('nxtgauge_admin_preview') === '1'); if (isPreview) { if (typeof sessionStorage !== 'undefined') sessionStorage.setItem('nxtgauge_admin_preview', '1'); setAdminSession(); setCheckedSession(true); return; } const verify = async () => { if (!hasAdminSession()) { const from = encodeURIComponent(location.pathname + location.search); navigate(`/login?from=${from}`, { replace: true }); return; } try { const response = await fetch('/api/gateway/users/auth/me', { method: 'GET', headers: { Accept: 'application/json', 'x-portal-target': 'admin', }, credentials: 'include', }); const payload = await response.json().catch(() => ({})); if (!response.ok || isExternalIdentity(payload)) { throw new Error('Unauthorized'); } setCheckedSession(true); } catch { clearAdminSession(); const from = encodeURIComponent(location.pathname + location.search); navigate(`/login?from=${from}`, { replace: true }); } }; void verify(); }); const onLogout = async () => { await fetch('/api/gateway/users/auth/logout', { method: 'POST', headers: { Accept: 'application/json', 'x-portal-target': 'admin', }, credentials: 'include', }).catch(() => {}); clearAdminSession(); navigate('/login', { replace: true }); }; return (
NXTGAUGE

{pageTitle()}

Super Admin

{checkedSession() ? (
{tabs().length > 0 ? (
) : null}
{props.children}
) : (

Checking session...

)}
); }