- Modèle Prisma Plugin (key, name, description, category, version, enabled, config JSONB, migrationsApplied, timestamps) + migration SQL - PluginRegistry (src/lib/plugins/registry.ts) avec 12 plugins déclarés : visuels (theme-guyane, landing-hero, landing-sections, image-gallery-seed, demo-carbets-seed), métier (access-type, seasonality, pirogue-providers, min-stay), contenus (content-pages, legal-pages), i18n (i18n-fr-en) - Server helpers (server.ts) : sync, isEnabled, getEnabledKeys, toggle avec hooks onEnable/onDisable, updateConfig, cache 5s - Client bridge (client.tsx) : PluginProvider + useIsPluginEnabled - Composant <IfPluginEnabled plugin=... fallback=...> - Guard requirePluginOr404 pour pages et routes - Page admin /admin/plugins avec table toggle par catégorie + édition config - Route PATCH /api/admin/plugins/[key] + GET - Layout async qui sync registry + passe enabledKeys au PluginProvider Tous plugins en enabled=false par défaut, activation pilotée depuis l'admin.
31 lines
803 B
TypeScript
31 lines
803 B
TypeScript
"use client";
|
|
|
|
import type { ReactNode } from "react";
|
|
import { useIsPluginEnabled } from "@/lib/plugins/client";
|
|
|
|
/**
|
|
* Composant client : affiche `children` uniquement si le plugin est activé.
|
|
* Le `<PluginProvider>` doit être présent en amont (layout) avec la liste
|
|
* des plugins activés calculée côté serveur.
|
|
*
|
|
* Usage :
|
|
* <IfPluginEnabled plugin="landing-hero">
|
|
* <HeroSection />
|
|
* </IfPluginEnabled>
|
|
*
|
|
* <IfPluginEnabled plugin="seasonality" fallback={<DefaultBanner />}>
|
|
* <SeasonBanner />
|
|
* </IfPluginEnabled>
|
|
*/
|
|
export function IfPluginEnabled({
|
|
plugin,
|
|
fallback = null,
|
|
children,
|
|
}: {
|
|
plugin: string;
|
|
fallback?: ReactNode;
|
|
children: ReactNode;
|
|
}) {
|
|
const enabled = useIsPluginEnabled(plugin);
|
|
return <>{enabled ? children : fallback}</>;
|
|
}
|