diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index 6f7f23d..08dceda 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -1,5 +1,8 @@ import type { ReactNode } from "react"; import ConditionalNavigation from "../components/navigation/ConditionalNavigation"; +import { MessagesProvider } from "../contexts/MessagesContext"; +import { AuthModalProvider } from "../contexts/AuthModalContext"; +import messages from "../../messages/en/index"; // Reads the session for admin chrome (matches the HttpOnly cookie on first // HTML response). Scoped here so `(marketing)` can render statically. @@ -9,9 +12,11 @@ export const dynamic = "force-dynamic"; // public marketing footer. Auth/access is enforced upstream. export default function AdminLayout({ children }: { children: ReactNode }) { return ( - <> - -
{children}
- + + + +
{children}
+
+
); } diff --git a/app/(app)/layout.tsx b/app/(app)/layout.tsx index 2218eaf..11e8278 100644 --- a/app/(app)/layout.tsx +++ b/app/(app)/layout.tsx @@ -1,5 +1,8 @@ import type { ReactNode } from "react"; import ConditionalNavigation from "../components/navigation/ConditionalNavigation"; +import { MessagesProvider } from "../contexts/MessagesContext"; +import { AuthModalProvider } from "../contexts/AuthModalContext"; +import messages from "../../messages/en/index"; // Reads `cr_session` via Server Components on every navigation so the header // matches the HttpOnly cookie on the first HTML response (no "Log in" flash @@ -12,9 +15,11 @@ export const dynamic = "force-dynamic"; // CreateFlow) is composed in nested layouts. export default function AppLayout({ children }: { children: ReactNode }) { return ( - <> - -
{children}
- + + + +
{children}
+
+
); } diff --git a/app/(dev)/layout.tsx b/app/(dev)/layout.tsx index e67fa09..699928e 100644 --- a/app/(dev)/layout.tsx +++ b/app/(dev)/layout.tsx @@ -1,10 +1,19 @@ import type { ReactNode } from "react"; import { notFound } from "next/navigation"; +import { MessagesProvider } from "../contexts/MessagesContext"; +import { AuthModalProvider } from "../contexts/AuthModalContext"; +import messages from "../../messages/en/index"; // Development-only previews (e.g. `/components-preview`) — no public chrome. export default function DevLayout({ children }: { children: ReactNode }) { if (process.env.NODE_ENV === "production") { notFound(); } - return
{children}
; + return ( + + +
{children}
+
+
+ ); } diff --git a/app/(marketing)/layout.tsx b/app/(marketing)/layout.tsx index 188695d..6155b79 100644 --- a/app/(marketing)/layout.tsx +++ b/app/(marketing)/layout.tsx @@ -1,6 +1,9 @@ import dynamic from "next/dynamic"; import type { ReactNode } from "react"; import MarketingNavigation from "../components/navigation/MarketingNavigation"; +import { MessagesProvider } from "../contexts/MessagesContext"; +import { AuthModalProvider } from "../contexts/AuthModalContext"; +import marketingMessages from "../../messages/en/marketing"; // Site footer is part of the public marketing chrome only — not rendered for // signed-in product surfaces, admin dashboards, or dev previews. See @@ -14,10 +17,12 @@ const Footer = dynamic(() => import("../components/navigation/Footer"), { export default function MarketingLayout({ children }: { children: ReactNode }) { return ( - <> - -
{children}
-