64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
// RouteChrome
|
|
// -----------
|
|
// Conditionally renders the internal navigation chrome (top NavBar +
|
|
// footer) only on internal routes. Public onboarding routes under
|
|
// `/onboard/*` must not surface the Overview / Directors / Companies /
|
|
// Onboarding links — a client with that URL must not be one tap away
|
|
// from the internal registry.
|
|
//
|
|
// Public route detection: pathname starts with "/onboard". A Client
|
|
// Component is required because Next.js' root layout is a Server
|
|
// Component and `usePathname()` only works client-side. The
|
|
// detection is a single string-prefix check, so the cost is trivial.
|
|
//
|
|
// Initial render: server sends the public chrome (no nav). If the
|
|
// user is actually on an internal route, the client effect flips
|
|
// to internal chrome on hydration. This avoids any chance of the
|
|
// nav flashing into view on the public route.
|
|
|
|
import { usePathname } from "next/navigation";
|
|
import type { ReactNode } from "react";
|
|
import NavBar from "@/components/NavBar";
|
|
|
|
export default function RouteChrome({ children }: { children: ReactNode }) {
|
|
const pathname = usePathname() ?? "/";
|
|
// Public route detection: the client-facing onboarding wizard lives
|
|
// at `/onboard/<token>` (note: NOT `/onboarding` — that's the
|
|
// internal inbox at `/onboarding`). The prefix check must therefore
|
|
// require both "/onboard" and a path separator after it, otherwise
|
|
// "/onboarding" (the inbox) gets treated as public and loses the
|
|
// NavBar + footer.
|
|
const isPublic =
|
|
pathname === "/onboard" ||
|
|
pathname.startsWith("/onboard/") ||
|
|
pathname.startsWith("/register/");
|
|
|
|
if (isPublic) {
|
|
// Public client route. No nav, no footer, full-height canvas.
|
|
return (
|
|
<main id="main" className="min-h-screen">
|
|
{children}
|
|
</main>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<NavBar />
|
|
<main id="main" className="min-h-[60vh] pb-24 md:pb-0">
|
|
{children}
|
|
</main>
|
|
<footer className="bg-surface-warm border-t border-border mt-16">
|
|
<div className="container-x py-10 flex flex-col gap-2 text-sm text-muted">
|
|
<p className="font-semibold text-fg">Workflow Registry Browser</p>
|
|
<p>
|
|
Read-only client to a self-hosted PocketBase instance. The
|
|
superuser token never leaves the server.
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
</>
|
|
);
|
|
}
|