visitapp-web/todo-features.md
2026-05-07 15:28:48 +02:00

139 lines
7.8 KiB
Markdown

# TODO — Parité visitapp-web vs mymuseum-visitapp
> Suivi des features Flutter (`mymuseum-visitapp`) à porter sur la version web (`visitapp-web`).
> Légende : ❌ Non implémenté · ⚠️ Partiel · ✅ Fait · 🚫 Hors scope web (natif uniquement)
Référence Flutter : `c:\Users\ThomasFransolet\Documents\Documents\Perso\GITEA\mymuseum-visitapp\lib\`
---
## Sections
| Section | Flutter | Web | Statut |
|---|---|---|---|
| Article | `Sections/Article/article_page.dart` | `ArticleSection.tsx` | ✅ |
| Agenda | `Sections/Agenda/agenda_page.dart` | `AgendaSection.tsx` | ⚠️ Partiel — popup à enrichir |
| Menu | `Sections/Menu/menu_page.dart` | `MenuSection.tsx` | ✅ |
| Slider | `Sections/Slider/` | `SliderSection.tsx` | ✅ |
| Video | `Sections/Video/` | `VideoSection.tsx` | ✅ |
| Map (+ parcours) | `Sections/Map/` | `MapSection.tsx` | ✅ |
| PDF | `Sections/PDF/` | `PdfSection.tsx` | ✅ |
| Weather | `Sections/Weather/` | `WeatherSection.tsx` | ✅ |
| Quiz | `Sections/Quiz/` | `QuizSection.tsx` | ✅ |
| Web | `Sections/Web/` | `WebSection.tsx` | ✅ |
| Game (Puzzle / Sliding / Escape) | `Sections/Game/` | `GameSection.tsx` + `EscapeProgression.tsx` | ✅ |
| GuidedPath (intégré Map / Game Escape) | `Sections/GuidedPath/` | `MapSection.tsx` + `EscapeProgression.tsx` | ✅ |
| **Event** | `Sections/Event/event_page.dart`, `event_map_full_page.dart` | `EventSection.tsx` + `event/EventMap.tsx` | ✅ |
---
## ✅ Section Event — fait
Page dédiée pour les sections de type Event ([EventSection.tsx](visitapp-web/src/components/sections/EventSection.tsx) + [event/EventMap.tsx](visitapp-web/src/components/sections/event/EventMap.tsx)).
**Implémenté** :
- Layout vertical scrollable (pas de TabBar — aligné avec le Flutter)
- Hero : image + gradient + titre + badge dates `startDate…endDate` + back button
- Section **Programme** : timeline verticale des `ProgrammeBlock` (triés par `startTime`), bloc actif (heure courante dans `startTime…endTime`) mis en évidence (badge "EN COURS", bordure primaire, dot avec halo), tap → bottom sheet détail + liste des annotations spatiales du bloc
- Section **Carte** : mini-carte Leaflet (220px) avec annotations globales en couleur primaire + annotations du bloc actif en orange superposées. Bouton "Plein écran" overlay
- Section **Parcours** : chips horizontaux (parcours guidés liés à l'event), tap → navigation vers la section Map associée (`baseSectionMapId`) qui héberge la progression existante
- Section **À propos** : description HTML
- Bottom sheet block detail : titre + horaire + description + liste annotations (badge orange + label)
- Pré-fetch server-side des `guidedPaths` via le même endpoint polymorphe `/api/SectionMap/{eventId}/GuidedPath`
**Types ajoutés** : `EventDTO`, `ProgrammeBlock`, `MapAnnotationDTO` dans [types.ts](visitapp-web/src/lib/api/types.ts)
**Reste à faire** (nice-to-have) :
- [ ] Mise en avant home : si `applicationInstanceDTO.sectionEventId != null`, afficher un bloc "à la une" en haut de la grille de configurations. Nécessite d'étendre `ApplicationInstanceDTO` (champ `sectionEventDTO?`) et de lui dédier un widget sur `[slug]/page.tsx`.
---
## ✅ Agenda — popup événement enrichi
**Bug fix bonus** : le type web `EventAgendaDTO` était désynchronisé du backend (`title`/`startDate` au lieu de `label`/`dateFrom`). Type aligné dans [types.ts](visitapp-web/src/lib/api/types.ts).
**Implémenté dans [AgendaSection.tsx](visitapp-web/src/components/sections/AgendaSection.tsx) + [agenda/EventMiniMap.tsx](visitapp-web/src/components/sections/agenda/EventMiniMap.tsx)** :
- Mini-carte Leaflet centrée sur `address.geometry.coordinates`
- Vidéo embarquée : iframe YouTube (`idVideoYoutube` ou `videoLink` YouTube), lecteur HTML5 natif (`videoLink` direct ou `videoResource.url`)
- Liens cliquables : email (`mailto:`), téléphone (`tel:`), site web (target="_blank")
- Adresse postale formatée → lien Google Maps
---
## ✅ Statistiques — tracking visiteur
**Endpoint backend** : `POST /api/Stats/event` (anonyme, accepte `appType: "Web"`).
**Implémenté** :
- [src/lib/stats.ts](visitapp-web/src/lib/stats.ts) : `trackEvent()` + sessionId persistant (`sessionStorage`)
- [src/hooks/useSectionTracking.ts](visitapp-web/src/hooks/useSectionTracking.ts) : hook auto qui émet `SectionView` au mount + `SectionLeave` au unmount avec durée
- [src/components/TrackedSection.tsx](visitapp-web/src/components/TrackedSection.tsx) : wrapper appliqué au dispatcher → toutes les sections trackées sans toucher leur code
- `instanceId` propagé via `VisitorContext` (depuis le layout `[slug]`)
- Events spécifiques branchés : `MapPoiTap`, `QuizComplete`, `GameComplete`, `AgendaEventTap`, `QrScan`
**Tous les events Flutter sont branchés** : `SectionView`, `SectionLeave`, `MapPoiTap`, `QuizComplete`, `GameComplete`, `AgendaEventTap`, `QrScan`, `ArticleRead` (déclenché au scroll ≥80%), `MenuItemTap`.
---
---
## ✅ Event "à la une" sur la home
**Implémenté** :
- `ApplicationInstanceDTO.sectionEventDTO` ajouté aux types
- [src/components/FeaturedEvent.tsx](visitapp-web/src/components/FeaturedEvent.tsx) : carte hero (220px) avec image, badge "À LA UNE", badge dates, titre HTML
- Branché dans [src/app/[slug]/page.tsx](visitapp-web/src/app/[slug]/page.tsx) : si `instance.sectionEventDTO` est rempli côté backend, le bloc s'affiche au-dessus de la grille de configurations
---
## ✅ Scanner QR code
**Implémenté** :
- Lib : `qr-scanner` (MIT, ~13kb gzip, cross-browser via `getUserMedia`)
- [src/components/QRScannerButton.tsx](visitapp-web/src/components/QRScannerButton.tsx) :
- Bouton flottant en bas-droite sur la home `/[slug]`
- Modal fullscreen avec aperçu caméra + animation de scan
- Parser regex qui extrait un path `/{slug}/{configId}/sections/{sectionId}` depuis le payload (URL absolue ou relative)
- Sur match → `router.push()` vers le path
- Émet l'event `QrScan` (avec payload + path parsé)
- Gère les erreurs de permission caméra avec message visuel
- Nécessite HTTPS en production (sauf localhost)
Le bouton scanner est exposé sur la home (`/[slug]`) et dans la page configuration (`/[slug]/[configId]`).
---
## 🚫 Hors scope (décision produit ou natif uniquement)
Ces features ne sont **pas portées sur le web** :
- **Assistant IA / Chat** — décision produit : feature premium réservée à l'app mobile native, pas portée côté web
- **Mode offline / cache local** — décision produit : pas dans le scope web pour le moment, l'app web suppose une connexion
- **Push notifications Firebase FCM** — réservées à l'app native (mobile installée)
- **Beacons BLE** — Web Bluetooth pas supporté sur iOS Safari, et l'usage réel suppose un device mobile dédié
- **Lecteur audio avancé** (just_audio Flutter) — l'audio HTML5 natif suffit, pas besoin d'aller plus loin
- **Téléchargement caméra natif pour QR** — remplaçable par `getUserMedia` si on en a besoin (voir section QR ci-dessus)
---
## Suivi
| Feature | Priorité | Statut |
|---|---|---|
| **Event Section** | Haute (gap fonctionnel) | ✅ Fait |
| **Agenda popup enrichi** | Moyenne | ✅ Fait |
| **Stats tracking** | Moyenne (besoin métier) | ✅ Fait (tous les events) |
| **Event "à la une" sur la home** | Basse (UX) | ✅ Fait |
| **QR Scanner** | Basse | ✅ Fait |
---
## Référence — fichiers Flutter clés à consulter
- Home + scanner : `lib/Screens/Home/home.dart`, `lib/Components/ScannerDialog.dart`
- Event : `lib/Screens/Sections/Event/event_page.dart`, `event_map_full_page.dart`
- Agenda popup : `lib/Screens/Sections/Agenda/event_popup.dart`
- Services : `lib/Services/statisticsService.dart`, `assistantService.dart`
- Cache local : `lib/Helpers/DatabaseHelper.dart`, `lib/Services/downloadConfiguration.dart`
- Composants chat : `lib/Components/AssistantChatSheet.dart`