layout.tsx70 lines · main
1import Link from 'next/link';
2import type { ReactNode } from 'react';
3import { notFound } from 'next/navigation';
4
5import { loadAuthV2Workspace } from '../lib/load-workspace';
6import { AuthProjectNav } from './auth-project-nav';
7
8export const dynamic = 'force-dynamic';
9
10/**
11 * Per-project Auth shell: title + tabs (users, sessions, keys, …).
12 */
13export default async function AuthProjectLayout({
14 children,
15 params,
16}: {
17 children: ReactNode;
18 params: Promise<{ projectId: string }>;
19}) {
20 const { projectId } = await params;
21 const projects = await loadAuthV2Workspace();
22 const project = projects.find(
23 (p) => p.id === projectId || p.id.toLowerCase() === projectId.toLowerCase(),
24 );
25 if (!project) {
26 notFound();
27 }
28
29 // Trust workspace flag; layout badge only (page may re-check enable).
30 const authOn = project.authEnabled === true;
31
32 return (
33 <div className="flex flex-col gap-6">
34 <header>
35 <p className="font-mono text-[10px] uppercase tracking-widest text-[var(--color-text-muted)]">
36 <Link href="/dashboard/auth" className="hover:underline">
37 Auth
38 </Link>
39 {' · '}
40 project
41 </p>
42 <h1 className="mt-1 font-mono text-xl tracking-tight text-[var(--color-text)]">
43 {project.name}
44 </h1>
45 <p className="mt-1 font-mono text-sm text-[var(--color-text-muted)]">
46 {project.slug}
47 {authOn ? (
48 <span style={{ color: 'var(--auth-accent, #FFFD74)' }}>
49 {' · '}
50 Auth on
51 </span>
52 ) : (
53 <span>
54 {' · '}
55 Auth off
56 </span>
57 )}
58 {project.tenantId ? (
59 <span className="text-[var(--color-text-subtle)]">
60 {' · '}
61 {project.tenantId}
62 </span>
63 ) : null}
64 </p>
65 </header>
66 <AuthProjectNav projectId={project.id} />
67 {children}
68 </div>
69 );
70}