Registry : ajoute 2 plugins : - theme-aquarelle (carnet naturaliste XIXᵉ, mutual exclusion avec theme-guyane) - image-gallery-aquarelle-seed (14 aquarelles → MinIO + Media carbets démo) Hooks : - theme-guyane et theme-aquarelle se désactivent mutuellement au toggle ON via disableOtherTheme() CSS (globals.css) : - body[data-theme=aquarelle] : background papier teinté #faf5e9 + texture grain papier inline SVG + radial gradients ocres/canopy délavés - Surcharges automatiques des borders zinc/gray vers sépia délavé Layout : - PT_Serif (au lieu de Cormorant) en theme aquarelle, plus dense et encrée - data-theme = aquarelle prioritaire sur guyane si les deux sont enabled (défensif — le hook garantit normalement la mutual exclusion) Hero : - 2 versions dans le composant : guyane (existant, SVG CarbetRiver) et aquarelle (image MinIO 01-hero-fleuve-maroni.jpg en fond, voile crème, texte sépia, CTAs carrés sans rounded, hairlines, ornement de planche) - Branchement via getActiveTheme() - aquarelleUrl() helper qui construit l'URL MinIO publique Partie 2/2 (PR ultérieure) : upload des 14 images dans MinIO + hook image-gallery-aquarelle-seed + variantes aquarelle des autres composants (CarbetCard, ExperiencesSection, HowItWorksSection, CESection, Footer).
111 lines
3.7 KiB
TypeScript
111 lines
3.7 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 { 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 />
|
|
{children}
|
|
</LocaleProvider>
|
|
</PluginProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|