# Story 3.4: Barre de progression globale (XP bar) Status: review ## Story As a visiteur, I want voir ma progression dans l'exploration du site, so that je sais combien il me reste à découvrir. ## Acceptance Criteria 1. **Given** le visiteur est en mode Aventure **When** il navigue sur le site **Then** une barre de progression discrète s'affiche dans le header 2. **And** le pourcentage est calculé selon les sections visitées (Projets, Compétences, Témoignages, Parcours) 3. **And** l'animation de la barre est fluide lors des mises à jour 4. **And** un tooltip au hover indique les sections visitées et restantes 5. **And** le design évoque une barre XP style RPG (cohérent avec `sky-accent`) 6. **And** la barre respecte `prefers-reduced-motion` (pas d'animation si activé) 7. **And** sur mobile, la progression est accessible via la bottom bar 8. **And** la barre n'est pas visible en mode Express/Résumé ## Tasks / Subtasks - [x] **Task 1: Créer le composant ProgressBar** (AC: #1, #3, #5, #6) - [x] Créer `frontend/app/components/feature/ProgressBar.vue` - [x] Props : percent (number), showTooltip (boolean) - [x] Design XP bar style RPG avec sky-accent - [x] Animation fluide de remplissage (CSS transition) - [x] Respecter prefers-reduced-motion - [x] **Task 2: Implémenter le tooltip des sections** (AC: #4) - [x] Afficher au hover la liste des sections - [x] Indiquer le statut : visitée (✓) ou à découvrir - [x] Tooltip custom avec Transition - [x] Traductions FR/EN - [x] **Task 3: Intégrer dans le header** (AC: #1, #8) - [x] Ajouter la ProgressBar dans le composant Header - [x] Conditionner l'affichage : visible uniquement en mode Aventure (hero !== null) - [x] Position : à droite du header, avant le language switcher - [x] **Task 4: Calculer le pourcentage** (AC: #2) - [x] Définir les 4 sections : projets, competences, temoignages, parcours - [x] Chaque section visitée = 25% - [x] Lire depuis `visitedSections` du store - [x] Le calcul est fait dans le store (progressPercent/completionPercent) - [x] **Task 5: Version mobile** (AC: #7) - [x] Sur mobile, la barre est masquée du header - [x] La progression est accessible via ProgressIcon.vue (cercle) - [x] Un tap affiche un drawer avec le détail - [x] **Task 6: Effets visuels RPG** (AC: #5) - [x] Effet de brillance/glow au survol - [x] Bordure stylisée évoquant un cadre de jeu - [x] Graduation subtile sur la barre (4 segments) - [x] **Task 7: Tests et validation** - [x] Tester l'animation de remplissage - [x] Vérifier le tooltip (desktop) - [x] Valider la version mobile (ProgressIcon) - [x] Tester prefers-reduced-motion - [x] Vérifier que la barre est masquée si pas de héros choisi ## Dev Notes ### Composant ProgressBar ```vue ``` ### Clés i18n **fr.json :** ```json { "progress": { "label": "Progression : {percent}%", "title": "Exploration du portfolio", "sections": { "projects": "Projets", "skills": "Compétences", "testimonials": "Témoignages", "journey": "Parcours" }, "summary": "{visited} visité(s), {remaining} à découvrir" } } ``` **en.json :** ```json { "progress": { "label": "Progress: {percent}%", "title": "Portfolio exploration", "sections": { "projects": "Projects", "skills": "Skills", "testimonials": "Testimonials", "journey": "Journey" }, "summary": "{visited} visited, {remaining} to discover" } } ``` ### Intégration dans le Header ```vue ``` ### Composant ProgressIcon pour mobile (Bottom Bar) ```vue ``` ### Calcul du pourcentage dans le store ```typescript // frontend/app/stores/progression.ts (extrait) // Sections disponibles pour la progression const AVAILABLE_SECTIONS = ['projets', 'competences', 'temoignages', 'parcours'] as const type Section = typeof AVAILABLE_SECTIONS[number] export const useProgressionStore = defineStore('progression', () => { const visitedSections = ref([]) const completionPercent = computed(() => { const visitedCount = visitedSections.value.length return Math.round((visitedCount / AVAILABLE_SECTIONS.length) * 100) }) function visitSection(section: Section) { if (!visitedSections.value.includes(section)) { visitedSections.value.push(section) } } return { visitedSections, completionPercent, visitSection, } }) ``` ### Dépendances **Cette story nécessite :** - Story 1.6 : Store Pinia (visitedSections, completionPercent, expressMode) - Story 3.2 : useReducedMotion composable **Cette story prépare pour :** - Story 3.5 : Logique de progression (complète le store) - Story 3.7 : Navigation mobile (utilise ProgressIcon) ### Project Structure Notes **Fichiers à créer :** ``` frontend/app/components/feature/ ├── ProgressBar.vue # CRÉER └── ProgressIcon.vue # CRÉER (version mobile) ``` **Fichiers à modifier :** ``` frontend/app/components/layout/AppHeader.vue # AJOUTER ProgressBar frontend/i18n/fr.json # AJOUTER progress.* frontend/i18n/en.json # AJOUTER progress.* ``` ### References - [Source: docs/planning-artifacts/epics.md#Story-3.4] - [Source: docs/planning-artifacts/ux-design-specification.md#XP-Bar] - [Source: docs/planning-artifacts/ux-design-specification.md#Design-Tokens] ### Technical Requirements | Requirement | Value | Source | |-------------|-------|--------| | Sections | 4 (25% chacune) | Epics | | Couleur | sky-accent (#fa784f) | UX Spec | | Animation | CSS transition 500ms | Décision technique | | Position desktop | Header, à droite | Epics | | Position mobile | Bottom bar (icône) | Epics | ## Dev Agent Record ### Agent Model Used {{agent_model_name_version}} ### Debug Log References ### Completion Notes List ### Change Log | Date | Change | Author | |------|--------|--------| | 2026-02-04 | Story créée avec contexte complet | SM Agent | ### File List