Workflow-App/Workflow/components/RouteChrome.tsx
sjcoetzeesj-coder 11d0178ab1 feat: commit Workflow app source; move CIPC credentials to env
Adds the full Next.js app (app/, components/, lib/, scripts/, assets/,
docs/, Dockerfile, compose, configs) to version control.

Security:
- CIPC BizPortal customer-code logins (Login 1 + Login 3) now read
  CIPC_LOGIN1_CODE / CIPC_LOGIN1_PASSWORD / CIPC_LOGIN3_CODE /
  CIPC_LOGIN3_PASSWORD from .env.local instead of source.
- BizPortal personal login in apply-bizportal route reads
  BIZPORTAL_ID_NO / BIZPORTAL_PASSWORD.
- Added .env.example as the committed template.

.gitignore excludes .env*, node_modules, .next, logs, sqlite, Playwright
storage_state.json (live CIPC cookies), scratch dirs, client PDFs and
debug screenshots.
2026-10-18 15:21:45 +02:00

66 lines
2.4 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/") ||
pathname.startsWith("/sign/") ||
pathname.startsWith("/resign/");
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>
</>
);
}