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

84 lines
2.7 KiB
TypeScript
Raw Normal View History

import { A, useLocation, useNavigate } from '@solidjs/router';
import { createSignal, onMount, type JSX } from 'solid-js';
import AdminSidebar from './AdminSidebar';
import { clearAdminSession, hasAdminSession } from '~/lib/admin-session';
export default function AdminShell(props: { children: JSX.Element }) {
const location = useLocation();
const navigate = useNavigate();
const [checkedSession, setCheckedSession] = createSignal(false);
const tabs = [
{ href: '/admin/runtime-roles', label: 'View Roles' },
{ href: '/admin/runtime-roles/new', label: 'Create Role' },
{ href: '/admin/role-ui-configs', label: 'Inspector' },
{ href: '/admin/onboarding-schemas', label: 'Onboarding' },
];
const isTabActive = (href: string) => {
if (href === '/admin/runtime-roles') {
return location.pathname === href || (location.pathname.startsWith('/admin/runtime-roles/') && location.pathname !== '/admin/runtime-roles/new');
}
return location.pathname === href || location.pathname.startsWith(`${href}/`);
};
onMount(() => {
if (!hasAdminSession()) {
const from = encodeURIComponent(location.pathname + location.search);
navigate(`/login?from=${from}`, { replace: true });
return;
}
setCheckedSession(true);
});
const onLogout = () => {
clearAdminSession();
navigate('/login', { replace: true });
};
return (
<div class="admin-root">
<header class="admin-header">
<div class="admin-header-inner">
<div class="admin-brand">
<img src="/nxtgauge-logo.png" alt="NXTGAUGE" />
<div>
<p class="admin-brand-kicker">Administration</p>
<h1>NXTGAUGE Admin Panel</h1>
</div>
</div>
<div class="admin-header-actions">
<p class="admin-role-chip">Super Admin</p>
<button class="btn" type="button" onClick={onLogout}>Logout</button>
</div>
</div>
</header>
{checkedSession() ? (
<div class="shell">
<AdminSidebar />
<main class="main">
<div class="admin-tab-wrap">
<nav class="admin-tabs">
{tabs.map((tab) => (
<A href={tab.href} class={`admin-tab ${isTabActive(tab.href) ? 'active' : ''}`}>
{tab.label}
</A>
))}
</nav>
</div>
<div class="main-inner">{props.children}</div>
</main>
</div>
) : (
<div class="shell">
<main class="main">
<div class="card">
<p class="notice">Checking session...</p>
</div>
</main>
</div>
)}
</div>
);
}