import dynamic from "next/dynamic"; import { NextIntlClientProvider } from "next-intl"; import { getLocale, getMessages } from "next-intl/server"; import type { ReactNode } from "react"; import { CloudsField } from "@/components/clouds-field"; import MotionPageWrapper from "@/components/motion-page-wrapper"; import { Navigation } from "@/components/navigation"; import { SiteFooter } from "@/components/site-footer"; import { SiteHeader } from "@/components/site-header"; import { TopHeader } from "@/components/top-header"; import { auth } from "@/lib/auth"; import { publicClientMessages } from "@/lib/i18n-client-messages"; const RadioPlayerGate = dynamic( () => import("@/components/public/radio-player-gate"), { loading: () => (
), }, ); /** * Public site chrome. Route group `(site)` keeps this off `/admin` and `/client`, * so housekeeping is never constrained by the public max-w-7xl grid. * * The message provider lives here rather than only in the root layout: nested * NextIntlClientProviders replace the parent set instead of merging, so this is * where the public catalogue is installed — without the ~177 KB of staff-tool * namespaces that no page in this group can reach. */ export default async function SiteLayout({ children, }: { children: ReactNode; }) { const [session, locale, messages] = await Promise.all([ auth(), getLocale(), getMessages(), ]); const clientMessages = publicClientMessages(messages); return ( {/* Site chrome is public: hiding it all for anonymous visitors used to strand them — from /news, /leaderboard or /shop there was no way to reach any other page at all. */}
{children}
); }