karbe/src/app/layout.tsx
Claude Integration 3bc52b2b60
All checks were successful
CI / test (pull_request) Successful in 2m9s
feat: global SiteHeader avec user menu (login/inscription, Mes réservations, Espace hôte, Admin)
2026-06-01 04:29:52 +00:00

113 lines
3.8 KiB
TypeScript

import type { Metadata } from "next";
import { Geist, Geist_Mono, Cormorant_Garamond, PT_Serif } from "next/font/google";
import "./globals.css";
import { PluginProvider } from "@/lib/plugins/client";
import { getEnabledPluginKeys, syncPluginsFromRegistry } from "@/lib/plugins/server";
import { SeasonBanner } from "@/components/SeasonBanner";
import { SiteHeaderGuard } from "@/components/SiteHeaderGuard";
import { LocaleProvider } from "@/lib/i18n/client";
import { dict, getLocale } from "@/lib/i18n/server";
// Le layout interroge la DB Plugin à chaque request → rendu dynamique forcé.
// Sans ça, le layout (et donc data-theme + enabledKeys passés au client) est
// statiquement rendu au build et ne reflète plus l'état actuel des toggles.
export const dynamic = "force-dynamic";
export const revalidate = 0;
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
// Cormorant Garamond : typographie display pour le theme Guyane (gated par
// le plugin `theme-guyane`). Sert pour `font-serif`.
const cormorant = Cormorant_Garamond({
variable: "--font-serif",
subsets: ["latin"],
weight: ["400", "500", "600"],
display: "swap",
});
// PT Serif : typographie display pour le theme Aquarelle (carnet naturaliste).
// Plus dense, plus encrée, parfaite pour les planches d'illustration.
const ptSerif = PT_Serif({
variable: "--font-serif-aquarelle",
subsets: ["latin"],
weight: ["400", "700"],
display: "swap",
});
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000";
export const metadata: Metadata = {
metadataBase: new URL(siteUrl),
title: {
default: "Karbé — carbets fluviaux de Guyane",
template: "%s | Karbé",
},
description:
"Karbé, la marketplace de location de carbets fluviaux de Guyane.",
openGraph: {
type: "website",
siteName: "Karbé",
locale: "fr_FR",
title: "Karbé — carbets fluviaux de Guyane",
description:
"La marketplace pour louer des carbets fluviaux le long des fleuves de Guyane.",
},
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
// Plugins Karbé : sync registry → DB puis charge la liste activée pour le client.
// En cas d'erreur DB (build statique sans DB par ex.), on retombe en mode "aucun
// plugin activé" pour ne pas casser le rendu.
let enabledKeys: string[] = [];
try {
await syncPluginsFromRegistry();
enabledKeys = await getEnabledPluginKeys();
} catch {
enabledKeys = [];
}
// Aquarelle > Guyane si les deux activés (mutual exclusion garantie par
// le hook plugin, mais on est défensif au cas où).
const themeAquarelle = enabledKeys.includes("theme-aquarelle");
const themeGuyane = !themeAquarelle && enabledKeys.includes("theme-guyane");
const dataTheme = themeAquarelle ? "aquarelle" : themeGuyane ? "guyane" : undefined;
// En thème aquarelle, on substitue la variable --font-serif par PT Serif
// (au lieu de Cormorant) pour coller à l'esthétique carnet.
const serifVariable = themeAquarelle ? ptSerif.variable : cormorant.variable;
const locale = await getLocale();
const messages = await dict(locale);
return (
<html
lang={locale}
className={`${geistSans.variable} ${geistMono.variable} ${serifVariable} h-full antialiased`}
>
<body
data-theme={dataTheme}
className="min-h-full flex flex-col font-sans"
>
<PluginProvider enabledKeys={enabledKeys}>
<LocaleProvider locale={locale} messages={messages}>
<SeasonBanner />
<SiteHeaderGuard />
{children}
</LocaleProvider>
</PluginProvider>
</body>
</html>
);
}