@AGENTS.md # visitapp-web App visiteur web MyInfoMate — `app.myinfomate.be/[slug]` Next.js (App Router), TypeScript, Tailwind CSS. ## Contexte produit Partie de l'écosystème MyInfoMate (voir `GITEA/CLAUDE.md` pour la vue d'ensemble). Cette app est l'équivalent web de `mymuseum-visitapp` (Flutter). Elle doit reproduire fidèlement le visuel de `home_3.0.dart` et `configuration_page.dart`. Le backend est `manager-service` (C# / ASP.NET Core) — même API que les apps Flutter. > **Règle de développement** : pour tout bug ou feature à implémenter, toujours commencer > par lire l'équivalent Flutter dans `mymuseum-visitapp`. C'est la référence de comportement : > logique de navigation, appels API, endpoints utilisés — tout doit correspondre. ## Architecture ### Routing ``` src/app/ [slug]/ layout.tsx → fetch instance, inject thème CSS (couleurs instance) page.tsx → home (grille de configurations) [configId]/ layout.tsx → fetch ConfigurationDTO, override couleurs si définies page.tsx → liste des sections sections/[sectionId]/ page.tsx → dispatcher par type de section ``` ### Theming Couleurs injectées en CSS variables sur `` depuis le backend : - Home → `ApplicationInstanceDTO.primaryColor / secondaryColor` - Dans une configuration → `ConfigurationDTO.primaryColor ?? instance.primaryColor` Variables CSS disponibles partout : - `--color-primary`, `--color-secondary` - `--color-primary-light` (dérivée, 12% opacité) - `--color-on-primary` (blanc ou noir, calculé par contraste WCAG) - `--color-background`, `--color-surface`, `--color-text`, `--color-text-muted`, `--color-border` ### Multi-langue - Langue stockée dans `VisitorContext` (React context) + `localStorage` - Tous les champs texte sont `TranslationDTO[]` → `{ language: string, value: string }[]` - Helper `t(translations, lang)` pour résoudre la valeur dans la langue active ### Client API Généré depuis le Swagger de `manager-service`. Fichiers dans `src/lib/api/`. ### Rendu du contenu textuel Tous les champs de contenu texte long (article, description, etc.) sont produits par un éditeur **Quill** dans `manager-app`. Ils contiennent du **HTML** (balises `
`, ``,
``, etc.) — toujours les rendre avec `dangerouslySetInnerHTML`, jamais comme texte brut.
C'est le même comportement que `flutter_widget_from_html` dans `mymuseum-visitapp`.
## Commandes
```bash
npm run dev # dev local
npm run build # build production
npm run start # servir le build
```
## Sections supportées
Article, Agenda, Menu, Slider, Video, Map, PDF, Quiz, Game, Weather, Web, GuidedPath
### Layout par type de section
Deux patterns, calqués sur `mymuseum-visitapp` :
**AppBar standard** (`min-h-screen` + scroll) — contenu textuel/liste :
- Article, Agenda, Menu, Slider, Weather, Quiz, Game
**Full-screen** (`position: fixed; inset: 0` + dark AppBar) — contenu immersif :
- Video, Web, PDF, Map
Pour les titres : toujours `tPlain()` dans les AppBar et attributs `alt`.
Pour les contenus longs : toujours `dangerouslySetInnerHTML` (Quill → HTML).
## Hors scope
- Beacons BLE (WebBluetooth non supporté iOS Safari)
- Mode offline
- Push notifications