karbe/src/components/SeasonBanner.tsx
Claude Integration cf9da94bb5 feat(plugin): i18n FR + EN (Phase 4.2)
Infrastructure i18n légère, sans deps externe :

- lib/i18n/types.ts : LOCALES, DEFAULT_LOCALE, cookie name
- lib/i18n/server.ts : getLocale (cookie > Accept-Language > FR),
  t(key) async server-side, dict(locale)
- lib/i18n/client.tsx : LocaleProvider + useLocale + useT
- messages/fr.json + messages/en.json : ~50 clés pour landing + header + footer
- LocaleSwitcher component (cookie + router.refresh)

Plugin gated :
- Quand i18n-fr-en désactivé, getLocale() force FR. Le switcher ne s'affiche
  pas dans le hero. Pas d'impact sur le rendu existant.
- Quand activé, switcher visible coin haut-droit du hero. Les composants
  landing/header/footer rendent en FR ou EN selon le cookie utilisateur.

Composants i18n-isés :
- HeroSection (eyebrow, titre, CTA)
- ExperiencesSection (route/fleuve vs expédition, tous les bullets)
- HowItWorksSection (3 étapes)
- CESection (KPIs + body + CTA)
- TestimonialsSection (eyebrow + titre, citations restent en VO)
- Footer (taglines, colonnes)
- SeasonBanner (3 saisons + messages)
- AccessTypeBadge (labels + tooltips)

Pour les ContentPage, le champ lang existait déjà. Une suite (PR ultérieure)
ajoutera le filtre lang dans getContentPage + seed pages EN.
2026-05-31 11:38:39 +00:00

43 lines
1.6 KiB
TypeScript

import { isPluginEnabled } from "@/lib/plugins/server";
import { currentSeason, SEASON_META } from "@/lib/seasonality";
import { t } from "@/lib/i18n/server";
const TONES = {
ok: "bg-[var(--color-karbe-canopy-700)] text-[var(--color-karbe-bone)]",
warn: "bg-[var(--color-karbe-laterite-500)] text-[var(--color-karbe-bone)]",
info: "bg-[var(--color-karbe-maroni-700)] text-[var(--color-karbe-bone)]",
} as const;
const SEASON_KEYS = {
DRY: { label: "season.dry", message: "season.dry.message" },
LOW_WATER: { label: "season.lowWater", message: "season.lowWater.message" },
WET: { label: "season.wet", message: "season.wet.message" },
} as const;
/**
* Bandeau saison — affiché en haut de la home et de /carbets si le plugin
* `seasonality` est activé. Server component pur, pas de fetch DB.
* Texte i18n via t() server-side.
*/
export async function SeasonBanner() {
if (!(await isPluginEnabled("seasonality"))) return null;
const season = currentSeason();
const meta = SEASON_META[season];
const keys = SEASON_KEYS[season];
const label = await t(keys.label);
const message = await t(keys.message);
return (
<aside className={`${TONES[meta.tone]} text-xs sm:text-sm`}>
<div className="mx-auto flex max-w-6xl items-center justify-between gap-3 px-6 py-2 sm:px-8 lg:px-12">
<span className="flex items-center gap-2">
<span aria-hidden>{meta.emoji}</span>
<span className="font-semibold uppercase tracking-wider">{label}</span>
<span className="hidden text-[var(--color-karbe-bone)]/85 sm:inline">
· {message}
</span>
</span>
</div>
</aside>
);
}