Add testimonials page with personality-styled cards (Story 2.6)

- Add testimonials table migration with personality enum
- Create Testimonial model with HasTranslations trait
- Add TestimonialSeeder with 4 test testimonials
- Create TestimonialController and TestimonialResource
- Add useFetchTestimonials composable
- Create TestimonialCard component with personality-based styling
- Add temoignages.vue page with loading/error states
- Add testimonials translations in FR/EN

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 10:59:54 +01:00
parent 2b043674ca
commit 1cba01595b
15 changed files with 585 additions and 65 deletions

View File

@@ -1,6 +1,6 @@
# Story 2.6: Page Témoignages et migrations BDD
Status: ready-for-dev
Status: review
## Story
@@ -22,73 +22,73 @@ so that j'ai une validation sociale de ses compétences.
## Tasks / Subtasks
- [ ] **Task 1: Créer la migration table testimonials** (AC: #1)
- [ ] Créer migration `create_testimonials_table`
- [ ] Colonnes : id, name, role, company, avatar, text_key, personality (ENUM: sage, sarcastique, enthousiaste, professionnel), project_id (FK nullable), display_order, is_active (boolean), timestamps
- [ ] Foreign key project_id → projects.id (nullable, ON DELETE SET NULL)
- [ ] Index sur display_order pour le tri
- [ ] Index sur is_active pour le filtrage
- [x] **Task 1: Créer la migration table testimonials** (AC: #1)
- [x] Créer migration `create_testimonials_table`
- [x] Colonnes : id, name, role, company, avatar, text_key, personality (ENUM: sage, sarcastique, enthousiaste, professionnel), project_id (FK nullable), display_order, is_active (boolean), timestamps
- [x] Foreign key project_id → projects.id (nullable, ON DELETE SET NULL)
- [x] Index sur display_order pour le tri
- [x] Index sur is_active pour le filtrage
- [ ] **Task 2: Créer le Model Testimonial** (AC: #1)
- [ ] Créer `app/Models/Testimonial.php`
- [ ] Définir les fillable : name, role, company, avatar, text_key, personality, project_id, display_order, is_active
- [ ] Casts : is_active → boolean
- [ ] Relation `project()` : belongsTo(Project::class)
- [ ] Scope `scopeActive($query)` pour filtrer les actifs
- [ ] Scope `scopeOrdered($query)` pour le tri
- [x] **Task 2: Créer le Model Testimonial** (AC: #1)
- [x] Créer `app/Models/Testimonial.php`
- [x] Définir les fillable : name, role, company, avatar, text_key, personality, project_id, display_order, is_active
- [x] Casts : is_active → boolean
- [x] Relation `project()` : belongsTo(Project::class)
- [x] Scope `scopeActive($query)` pour filtrer les actifs
- [x] Scope `scopeOrdered($query)` pour le tri
- [ ] **Task 3: Créer le Seeder des témoignages** (AC: #2)
- [ ] Créer `database/seeders/TestimonialSeeder.php`
- [ ] Ajouter 4-5 témoignages de test avec différentes personnalités
- [ ] Ajouter les traductions FR et EN dans TranslationSeeder
- [ ] Lier certains témoignages à des projets existants
- [ ] Mettre à jour `DatabaseSeeder.php`
- [x] **Task 3: Créer le Seeder des témoignages** (AC: #2)
- [x] Créer `database/seeders/TestimonialSeeder.php`
- [x] Ajouter 4-5 témoignages de test avec différentes personnalités
- [x] Ajouter les traductions FR et EN dans TranslationSeeder
- [x] Lier certains témoignages à des projets existants
- [x] Mettre à jour `DatabaseSeeder.php`
- [ ] **Task 4: Créer l'endpoint API testimonials** (AC: #3, #4, #6, #7)
- [ ] Créer `app/Http/Controllers/Api/TestimonialController.php`
- [ ] Méthode `index()` pour lister les témoignages actifs
- [ ] Créer `app/Http/Resources/TestimonialResource.php`
- [ ] Inclure le projet lié (si existe) avec titre traduit
- [ ] Trier par display_order
- [ ] Ajouter la route `GET /api/testimonials`
- [x] **Task 4: Créer l'endpoint API testimonials** (AC: #3, #4, #6, #7)
- [x] Créer `app/Http/Controllers/Api/TestimonialController.php`
- [x] Méthode `index()` pour lister les témoignages actifs
- [x] Créer `app/Http/Resources/TestimonialResource.php`
- [x] Inclure le projet lié (si existe) avec titre traduit
- [x] Trier par display_order
- [x] Ajouter la route `GET /api/testimonials`
- [ ] **Task 5: Créer le composable useFetchTestimonials** (AC: #3)
- [ ] Créer `frontend/app/composables/useFetchTestimonials.ts`
- [ ] Typer la réponse avec interface Testimonial[]
- [x] **Task 5: Créer le composable useFetchTestimonials** (AC: #3)
- [x] Créer `frontend/app/composables/useFetchTestimonials.ts`
- [x] Typer la réponse avec interface Testimonial[]
- [ ] **Task 6: Créer la page temoignages.vue** (AC: #3, #4, #5, #8)
- [ ] Créer `frontend/app/pages/temoignages.vue`
- [ ] Charger les données avec le composable
- [ ] Afficher chaque témoignage comme une card
- [ ] Appliquer un style visuel selon la personnalité
- [ ] Préparer l'emplacement pour DialoguePNJ
- [x] **Task 6: Créer la page temoignages.vue** (AC: #3, #4, #5, #8)
- [x] Créer `frontend/app/pages/temoignages.vue`
- [x] Charger les données avec le composable
- [x] Afficher chaque témoignage comme une card
- [x] Appliquer un style visuel selon la personnalité
- [x] Préparer l'emplacement pour DialoguePNJ
- [ ] **Task 7: Créer le composant TestimonialCard** (AC: #4, #5, #6)
- [ ] Créer `frontend/app/components/feature/TestimonialCard.vue`
- [ ] Props : testimonial (avec name, role, company, avatar, text, personality, project)
- [ ] Afficher l'avatar, le nom, le rôle, l'entreprise
- [ ] Afficher le texte du témoignage
- [ ] Style de bulle selon la personnalité
- [ ] Lien vers le projet si présent
- [x] **Task 7: Créer le composant TestimonialCard** (AC: #4, #5, #6)
- [x] Créer `frontend/app/components/feature/TestimonialCard.vue`
- [x] Props : testimonial (avec name, role, company, avatar, text, personality, project)
- [x] Afficher l'avatar, le nom, le rôle, l'entreprise
- [x] Afficher le texte du témoignage
- [x] Style de bulle selon la personnalité
- [x] Lien vers le projet si présent
- [ ] **Task 8: Styles visuels par personnalité** (AC: #5)
- [ ] Définir 4 styles de bulles/cards selon personality :
- sage : style calme, bordure subtile
- sarcastique : style décalé, accent différent
- enthousiaste : style vif, couleurs plus marquées
- professionnel : style sobre, formel
- [ ] Classes CSS ou Tailwind variants
- [x] **Task 8: Styles visuels par personnalité** (AC: #5)
- [x] Définir 4 styles de bulles/cards selon personality :
- sage : style calme, bordure subtile (emerald)
- sarcastique : style décalé, accent différent (purple)
- enthousiaste : style vif, couleurs plus marquées (amber)
- professionnel : style sobre, formel (sky)
- [x] Classes CSS ou Tailwind variants
- [ ] **Task 9: Meta tags SEO** (AC: #9)
- [ ] Titre : "Témoignages | Skycel"
- [ ] Description dynamique
- [x] **Task 9: Meta tags SEO** (AC: #9)
- [x] Titre : "Témoignages | Skycel"
- [x] Description dynamique
- [ ] **Task 10: Tests et validation**
- [ ] Exécuter les migrations
- [ ] Vérifier le seeding des données
- [ ] Tester l'API en FR et EN
- [ ] Valider l'affichage de la page
- [ ] Vérifier les liens vers projets
- [x] **Task 10: Tests et validation**
- [x] Exécuter les migrations
- [x] Vérifier le seeding des données
- [x] Tester l'API en FR et EN
- [x] Valider l'affichage de la page
- [x] Vérifier les liens vers projets
## Dev Notes
@@ -655,6 +655,7 @@ frontend/app/
| Date | Change | Author |
|------|--------|--------|
| 2026-02-04 | Story créée avec contexte complet | SM Agent |
| 2026-02-06 | Implémentation complète: migration, model, seeder, API, frontend | Claude Opus 4.5 |
### File List