karbe/src/components/AccessTypeBadge.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

40 lines
1.3 KiB
TypeScript

"use client";
import { useIsPluginEnabled } from "@/lib/plugins/client";
import { useT } from "@/lib/i18n/client";
import type { AccessType } from "@/generated/prisma/enums";
/**
* Badge route+fleuve vs fleuve only. Gated par le plugin `access-type`.
* Si le plugin est désactivé, rien n'est rendu. Label i18n via useT().
*/
export function AccessTypeBadge({
accessType,
size = "sm",
}: {
accessType: AccessType;
size?: "sm" | "md";
}) {
const enabled = useIsPluginEnabled("access-type");
const t = useT();
if (!enabled) return null;
const isExpedition = accessType === "RIVER_ONLY";
const label = isExpedition ? t("access.riverOnly") : t("access.roadAndRiver");
const styles = isExpedition
? "bg-[var(--color-karbe-laterite-300)]/25 text-[var(--color-karbe-laterite-700)] ring-[var(--color-karbe-laterite-500)]/30"
: "bg-[var(--color-karbe-canopy-50)] text-[var(--color-karbe-canopy-700)] ring-[var(--color-karbe-canopy-500)]/30";
const sizing =
size === "md"
? "px-3 py-1.5 text-xs"
: "px-2 py-0.5 text-[11px]";
return (
<span
className={`inline-flex items-center gap-1 rounded-full font-medium ring-1 ${styles} ${sizing}`}
title={isExpedition ? t("access.riverOnly.title") : t("access.roadAndRiver.title")}
>
{label}
</span>
);
}