Add project detail page with prev/next navigation (Story 2.3)

- Enhance ProjectController show() with prev/next navigation data
- Create useFetchProject composable with ProjectNavigation type
- Implement [slug].vue with full project details:
  - Hero image, title with featured badge, formatted date
  - Description, external links (site/GitHub)
  - Skills grid with level progression (before → after)
  - Prev/next navigation with project titles
  - 404 state with spider narrator
- Add dynamic SEO meta tags with og:image from project
- Responsive design: stacked mobile, grid desktop

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 02:20:27 +01:00
parent 0399f0dc1c
commit 2269ecdb62
7 changed files with 356 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
# Story 2.3: Page Projet - Détail
Status: ready-for-dev
Status: review
## Story
@@ -22,59 +22,59 @@ so that je comprends le travail réalisé et les technologies utilisées.
## Tasks / Subtasks
- [ ] **Task 1: Créer l'endpoint API pour le détail du projet** (AC: #1, #2, #3, #4, #8)
- [ ] Ajouter la méthode `show($slug)` dans `ProjectController`
- [ ] Charger le projet avec ses compétences (eager loading)
- [ ] Retourner 404 si le slug n'existe pas
- [ ] Inclure les données de traduction selon `Accept-Language`
- [x] **Task 1: Créer l'endpoint API pour le détail du projet** (AC: #1, #2, #3, #4, #8)
- [x] Ajouter la méthode `show($slug)` dans `ProjectController`
- [x] Charger le projet avec ses compétences (eager loading)
- [x] Retourner 404 si le slug n'existe pas
- [x] Inclure les données de traduction selon `Accept-Language`
- [ ] **Task 2: Créer l'endpoint API pour la navigation prev/next** (AC: #5)
- [ ] Ajouter une méthode `navigation($slug)` ou inclure dans `show()`
- [ ] Retourner le projet précédent et suivant (basé sur l'ordre de tri)
- [ ] Si premier projet : prev = null, si dernier : next = null
- [x] **Task 2: Créer l'endpoint API pour la navigation prev/next** (AC: #5)
- [x] Ajouter une méthode `navigation($slug)` ou inclure dans `show()`
- [x] Retourner le projet précédent et suivant (basé sur l'ordre de tri)
- [x] Si premier projet : prev = null, si dernier : next = null
- [ ] **Task 3: Créer le composable useFetchProject** (AC: #1)
- [ ] Créer `frontend/app/composables/useFetchProject.ts`
- [ ] Accepter le slug en paramètre
- [ ] Gérer les états loading, error, data
- [ ] Gérer l'erreur 404
- [x] **Task 3: Créer le composable useFetchProject** (AC: #1)
- [x] Créer `frontend/app/composables/useFetchProject.ts`
- [x] Accepter le slug en paramètre
- [x] Gérer les états loading, error, data
- [x] Gérer l'erreur 404
- [ ] **Task 4: Créer la page [slug].vue** (AC: #1, #2, #3, #4, #6, #9)
- [ ] Créer `frontend/app/pages/projets/[slug].vue`
- [ ] Afficher l'image principale en grand format
- [ ] Afficher le titre et la description complète
- [ ] Afficher la date de réalisation formatée
- [ ] Afficher la liste des compétences avec progression (avant → après)
- [ ] Afficher les liens externes (site live, GitHub) si présents
- [ ] Ajouter un bouton "Retour à la galerie"
- [x] **Task 4: Créer la page [slug].vue** (AC: #1, #2, #3, #4, #6, #9)
- [x] Créer `frontend/app/pages/projets/[slug].vue`
- [x] Afficher l'image principale en grand format
- [x] Afficher le titre et la description complète
- [x] Afficher la date de réalisation formatée
- [x] Afficher la liste des compétences avec progression (avant → après)
- [x] Afficher les liens externes (site live, GitHub) si présents
- [x] Ajouter un bouton "Retour à la galerie"
- [ ] **Task 5: Implémenter la navigation prev/next** (AC: #5)
- [ ] Ajouter les boutons "Projet précédent" et "Projet suivant"
- [ ] Utiliser NuxtLink pour la navigation
- [ ] Afficher le titre du projet dans le bouton
- [ ] Désactiver/masquer si pas de prev ou next
- [x] **Task 5: Implémenter la navigation prev/next** (AC: #5)
- [x] Ajouter les boutons "Projet précédent" et "Projet suivant"
- [x] Utiliser NuxtLink pour la navigation
- [x] Afficher le titre du projet dans le bouton
- [x] Désactiver/masquer si pas de prev ou next
- [ ] **Task 6: Meta tags SEO dynamiques** (AC: #7)
- [ ] Utiliser `useHead()` avec le titre du projet
- [ ] Utiliser `useSeoMeta()` pour description, og:title, og:description, og:image
- [ ] L'image OG doit être l'image du projet
- [x] **Task 6: Meta tags SEO dynamiques** (AC: #7)
- [x] Utiliser `useHead()` avec le titre du projet
- [x] Utiliser `useSeoMeta()` pour description, og:title, og:description, og:image
- [x] L'image OG doit être l'image du projet
- [ ] **Task 7: Gestion de l'erreur 404** (AC: #8)
- [ ] Détecter si le projet n'existe pas
- [ ] Afficher un message approprié avec le narrateur
- [ ] Proposer de retourner à la galerie
- [x] **Task 7: Gestion de l'erreur 404** (AC: #8)
- [x] Détecter si le projet n'existe pas
- [x] Afficher un message approprié avec le narrateur
- [x] Proposer de retourner à la galerie
- [ ] **Task 8: Design responsive** (AC: #9)
- [ ] Mobile : layout vertical, image pleine largeur
- [ ] Desktop : layout 2 colonnes (image + contenu) ou grande image + contenu dessous
- [ ] Liste des compétences responsive (flex wrap)
- [x] **Task 8: Design responsive** (AC: #9)
- [x] Mobile : layout vertical, image pleine largeur
- [x] Desktop : layout 2 colonnes (image + contenu) ou grande image + contenu dessous
- [x] Liste des compétences responsive (flex wrap)
- [ ] **Task 9: Tests et validation**
- [ ] Tester avec différents slugs de projets
- [ ] Tester la navigation prev/next
- [ ] Tester le 404 avec un slug inexistant
- [ ] Valider les meta tags SEO
- [ ] Tester le responsive
- [x] **Task 9: Tests et validation**
- [x] Tester avec différents slugs de projets
- [x] Tester la navigation prev/next
- [x] Tester le 404 avec un slug inexistant
- [x] Valider les meta tags SEO
- [x] Tester le responsive
## Dev Notes
@@ -437,16 +437,40 @@ frontend/nuxt.config.ts # AJOUTER datetimeFormats
### Agent Model Used
{{agent_model_name_version}}
Claude Opus 4.5 (claude-opus-4-5-20251101)
### Debug Log References
- Aucun problème. Méthode show() existait déjà mais sans navigation prev/next.
### Completion Notes List
- ProjectController show() amélioré avec navigation prev/next et erreur 404 structurée
- Composable useFetchProject créé avec typage ProjectNavigation
- Page [slug].vue complète avec :
- Image principale pleine largeur
- Titre, date formatée selon locale, badge featured
- Description complète
- Liens externes (site et GitHub)
- Grille responsive des compétences utilisées avec niveaux avant/après
- Navigation prev/next avec titres traduits
- État loading (skeleton), état 404 avec narrateur spider
- SEO dynamique via useSeo avec og:image du projet
- Formatage date via Intl.DateTimeFormat selon locale
- Traductions FR/EN ajoutées (10 nouvelles clés projects.*)
- Store progression visitSection('projets') sur mount
### Change Log
| Date | Change | Author |
|------|--------|--------|
| 2026-02-04 | Story créée avec contexte complet | SM Agent |
| 2026-02-06 | Tasks 1-9 implémentées et validées | Dev Agent (Claude Opus 4.5) |
### File List
- `api/app/Http/Controllers/Api/ProjectController.php` — MODIFIÉ (show avec navigation)
- `frontend/app/composables/useFetchProject.ts` — CRÉÉ
- `frontend/app/pages/projets/[slug].vue` — RÉÉCRIT
- `frontend/i18n/fr.json` — MODIFIÉ (ajout projects.*)
- `frontend/i18n/en.json` — MODIFIÉ (ajout projects.*)