Project

General

Profile

Actions

Feature #1313

open
RA

Feature #1312: [EPIC] Tutoriel guidé GetYourJob — visite interactive "Take a tour" post-setup profil

Tutoriel — Framework core (TourProvider, spotlight, persistance, reprise)

Feature #1313: Tutoriel — Framework core (TourProvider, spotlight, persistance, reprise)

Added by Redmine Admin 28 days ago. Updated 12 days ago.

Status:
Preprod
Priority:
Normal
Assignee:
-
Start date:
07/07/2026
Due date:
% Done:

0%

Estimated time:
spec_ref:
build_status:
build_number:
ci_run_url:
scan_status:
scan_report_url:
deploy_status:
preprod_url:
deployed_at:
branch:
pr_url:
security_key:
severity:
paused:

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).

RA Updated by Redmine Admin 28 days ago Actions #1

  • Status changed from Submitted to QA

Implémenté, mergé dans dev via PR https://github.com/omdev-tech/GetYourJob/pull/420 (commit 151828d5). Framework livré : TourProvider/TourOverlay/useTour/tourStorage + 11 tests unitaires verts. Smoke test complet OK (voir #1312).

RA Updated by Redmine Admin 28 days ago Actions #2

Évolution suite au retour utilisateur sur preprod : la persistance passe de localStorage-only à *une table en base par utilisateur et par page* (@tutorial_progress@, unique userId+tourId) — "déjà vu" suit désormais le compte sur tous les navigateurs/appareils, indépendamment par page.

* Migration @20260707210028_add_tutorial_progress@ + route @/api/tutorial-progress@ (GET hydratation, PUT upsert avec états terminaux sticky).
* @TourProvider@ hydrate depuis le serveur AVANT de démarrer un tour (pas de flash d'un tour déjà vu ailleurs) ; le local devient un cache/fallback hors-ligne ; l'existant localStorage est poussé en base une fois.
* Écritures en @keepalive@ pour survivre aux étapes click-target qui naviguent.
* 24 tests verts ; smoke complet : nouveau navigateur simulé → reprise à l'étape exacte depuis la base ; skip en base → aucun replay ailleurs.

PR : https://github.com/omdev-tech/GetYourJob/pull/422 (merge auto sur CI verte, puis promotion preprod).

RA Updated by Redmine Admin 12 days ago Actions #3

  • Status changed from QA to Preprod

Déployé sur preprod via PR #440 (inclut PR #420 tutoriel). Validable sur https://preprod.getyourjob.pro → statut Preprod.

Actions

Also available in: PDF Atom