98 lines
3.3 KiB
Markdown
98 lines
3.3 KiB
Markdown
@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 `<html>` 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 `<p>`, `<strong>`,
|
|
`<ul>`, 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
|