Feature #1313
openFeature #1312: [EPIC] Tutoriel guidé GetYourJob — visite interactive "Take a tour" post-setup profil
Tutoriel — Framework core (TourProvider, spotlight, persistance, reprise)
0%
Description
Framework partagé par tous les tutoriels de pages. Aucune lib externe.
h2. Livrables
* @src/components/tour/TourProvider.tsx@ — contexte global monté dans @src/app/layout.tsx@ (dans @TranslationProvider@). API : @startTour(tourId)@, @nextStep@, @prevStep@, @skipTour@, @completeTour@, @activeTour@, @currentStep@.
* @src/components/tour/useTour.ts@ — hook par page : auto-démarre le tour si non complété/skippé, reprend à l'étape sauvegardée.
* @src/components/tour/TourOverlay.tsx@ — overlay plein écran (portal, zIndex 100001+ pour passer devant les modals existantes jusqu'à @zIndex:100000@) : fond assombri + flouté, découpe spotlight autour de la cible (rect arrondi, padding), bulle tooltip positionnée (flip haut/bas/gauche/droite + clamp viewport), scroll automatique de la cible dans le viewport, re-mesure sur resize/scroll/mutation.
* @src/components/tour/types.ts@ — @TourStep@ : @{ id, target: string /* [data-tour=…] */, titleKey, bodyKey, advanceOn: 'next' | 'click-target', route?, onEnter?, onExit? }@.
* @src/components/tour/tourStorage.ts@ — persistance localStorage @gyj_tour_state_v1@ : @{ [tourId]: { step, completedAt?, skippedAt? } }@ + helpers SSR-safe.
h2. Comportements
* *Skip indépendant par tour* : bouton "Passer le tutoriel" sur chaque bulle → @skippedAt@, ne réaffiche plus ce tour, n'affecte pas les autres.
* *Reprise* : chaque avancement d'étape persiste @step@ ; retour sur la page → reprise exacte.
* *advanceOn: 'click-target'* : l'étape avance quand l'utilisateur clique réellement l'élément cible (listener capture sur la cible) — utilisé pour ouvrir modals/lancer matching.
* *Handoff inter-pages* : si une étape fait naviguer ailleurs, le step suivant est persisté avant navigation ; le tour de la page reprend au retour.
* *Cible absente* : si @[data-tour=…]@ introuvable (feature gated, état vide), l'étape est sautée proprement.
* Étapes "info" sans cible possible (bulle centrée, ex. intro "Maintenant que votre profil est rempli…").
* Accessibilité : Échap = fermer (compte comme pause, pas skip), focus trap dans la bulle, @aria-live@.
h2. i18n
Namespace @tour.*@ dans @src/infrastructure/i18n/translations/fr.ts@ + @en.ts@, rendu via @useTranslation@. Boutons communs : Suivant / Précédent / Passer le tutoriel / Terminer.
h2. Tests
Unit tests (vitest) sur tourStorage (reprise, skip, complete, version) et sur la logique de séquencement des steps (cible absente → skip d'étape).