Annonces & maintenance
Bandeau global multi-langue et mode maintenance avec bypass admin.
Deux features admin pour parler à tous les visiteurs sans toucher au code.
Bannière d'annonce
Affichée en haut de chaque page (rendue dans app/layout.tsx via
<AnnouncementBanner>). Configurable depuis /admin/announcements ou
/admin/settings (onglet Annonces).
Champs (SiteConfig)
announcementText: LocalizedText | null // { fr: "...", en: "..." }
announcementVariant: "info" | "warning" | "promo"
announcementDismissible: booleanVariants stylés : info (sky), warning (amber), promo (primary).
Multi-langue
announcementText est un LocalizedText. Le composant pioche via
pickLocalized(announcementText, locale) avec fallback locale → fr → en → première dispo. Si aucune valeur non-vide, la bannière est masquée.
Dismissal localStorage
Quand dismissible = true, le composant calcule un hash
${variant}:${text} et stocke __announcement-dismissed:${hash} dans
localStorage à la fermeture. Un nouveau message ré-apparaît même si
l'utilisateur avait fermé l'ancien — le hash change.
Pour forcer la ré-apparition d'un même message, change le variant ou ajoute un caractère.
Mode maintenance
Quand siteConfig.maintenanceMode = true, tout le monde sauf les
admins est redirigé vers /maintenance.
Comment ça marche
proxy.ts vérifie getCachedSiteConfig() à chaque requête. Si
maintenance ON et session.user.role !== "ADMIN" → redirect("/maintenance").
Le matcher du proxy exclut explicitement /maintenance pour éviter la
boucle. Les admins gardent l'accès partout, ce qui leur permet de
désactiver le mode depuis l'admin sans devoir éditer la DB à la main.
Page /maintenance
app/maintenance/page.tsx (hors [locale], accessible à tous). Affiche
maintenanceMessage (LocalizedText) avec fallback sur le défaut :
fr: "Le site est en maintenance. Reviens dans quelques minutes."
en: "The site is under maintenance. Please come back in a few minutes."Bouton désactivation rapide
Sur la page /maintenance elle-même, si l'admin est connecté, un bouton
"Désactiver la maintenance" appelle PATCH /api/admin/site-config avec
{ maintenanceMode: false } puis recharge.
Cache
getCachedSiteConfig() utilise unstable_cache avec tag "site-config".
Toute mutation via PATCH /api/admin/site-config appelle
revalidateTag("site-config") pour purger immédiatement.
Allez plus loin
- i18n —
LocalizedTextetpickLocalized - Dashboard admin — onglet Settings
- Architecture —
proxy.ts