v1.5 - history and timeline as well as many datastructure updates added, polished, fixes

This commit is contained in:
Zaldimmar 2026-09-25 02:38:51 -05:00
parent 1f0aa3078f
commit 1d84400aef
63 changed files with 7927 additions and 208 deletions

View file

@ -0,0 +1,34 @@
/* ═══════════════════════════════════════════════════════════════
ROLE GUARD — src/pages/admin/RequireRole.tsx
Sits inside RequireAuth, never instead of it: by the time this
renders, the session question has already been answered. All
this decides is whether the answer was good enough.
Same caveat as RequireAuth — this hides the interface, not the
data. /api/admin/panel/* is superadmin-only on the server, and
that's the part that matters. Without it, a bookmarked URL and
a disabled select would be the only thing between a viewer and
the account list.
Bounces to Home rather than showing a "denied" page. Someone
who lands here has almost always followed a stale link, and a
working page beats an explanation of one.
═══════════════════════════════════════════════════════════════ */
import { Navigate, Outlet } from "react-router-dom";
import { useAuth } from "../../lib/auth.tsx";
import { atLeast } from "../../lib/roles.ts";
import { ADMIN_HOME } from "./adminNav.js";
export default function RequireRole({ role = "superadmin" }) {
const { user, loading } = useAuth();
// RequireAuth is already showing its own placeholder above this.
if (loading) return null;
if (!user) return <Navigate to="/admin/login" replace />;
if (!atLeast(user, role)) return <Navigate to={ADMIN_HOME} replace />;
return <Outlet />;
}