---
phase: 03-pages-ship
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- package.json
- package-lock.json
- app/data/site.ts
- shared/types/index.ts
- app/components/sections/HeroSection.vue
- app/components/sections/ServicesSection.vue
- app/components/sections/FeaturedProjectsSection.vue
- app/components/sections/TestimonialsSection.vue
- app/components/sections/FAQSection.vue
- app/components/sections/CTASection.vue
- app/components/ProjectCard.vue
- app/components/TechBadge.vue
- app/components/ProjectGallery.vue
- app/components/ContactForm.vue
- server/api/contact.post.ts
- nuxt.config.ts
- app/app.vue
autonomous: true
requirements:
- COMP-01
- COMP-02
- COMP-03
- COMP-04
must_haves:
truths:
- "Gallery modal opens with UModal + UCarousel and thumbnails, keyboard nav works"
- "Contact form validates with Zod, sends via nodemailer SMTP, shows UToast"
- "FAQ accordion renders i18n content with UAccordion"
- "Testimonials section renders all testimonials with UCard"
- "Project cards link to detail pages with translated content"
- "Site config data (contact, social, fiverr) is available as typed data"
artifacts:
- path: "app/components/ProjectGallery.vue"
provides: "UModal + UCarousel gallery with thumbnails and keyboard nav"
- path: "app/components/ContactForm.vue"
provides: "UForm + Zod validated contact form"
- path: "server/api/contact.post.ts"
provides: "Nodemailer SMTP server route"
- path: "app/components/sections/FAQSection.vue"
provides: "UAccordion FAQ section"
- path: "app/components/sections/TestimonialsSection.vue"
provides: "Testimonials with UCard"
key_links:
- from: "app/components/ContactForm.vue"
to: "server/api/contact.post.ts"
via: "$fetch('/api/contact', { method: 'POST' })"
pattern: "\\$fetch.*api/contact"
- from: "app/components/ProjectGallery.vue"
to: "UModal + UCarousel"
via: "v-model:open + useTemplateRef"
pattern: "UModal|UCarousel"
---
Installer les dependances manquantes (nodemailer, zod), migrer la config site, et creer tous les composants partages reutilisables : sections landing (Hero, Services, FeaturedProjects, Testimonials, FAQ, CTA), ProjectCard, TechBadge, ProjectGallery (UModal+UCarousel), ContactForm (UForm+Zod+nodemailer), et la route serveur contact.
Purpose: Ces composants sont consommes par toutes les pages en Wave 2-3. Les construire d'abord evite la duplication et permet le parallelisme.
Output: Composants dans app/components/, route serveur dans server/api/, dependances installees.
@C:\Users\minit\.claude\get-shit-done\workflows\execute-plan.md
@C:\Users\minit\.claude\get-shit-done\templates\summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/03-pages-ship/03-CONTEXT.md
@.planning/phases/03-pages-ship/03-RESEARCH.md
@app/data/projects.ts
@app/data/testimonials.ts
@app/data/faq.ts
@app/data/techstack.ts
@app/composables/useProjects.ts
@shared/types/index.ts
@src/config/site.ts
@src/components/sections/HeroSection.vue
@src/components/sections/ServicesSection.vue
@src/components/TestimonialsSection.vue
@src/components/ServiceFAQ.vue
@src/components/ProjectCard.vue
@src/components/TechBadge.vue
@src/components/GalleryModal.vue
@src/components/FiverrHero.vue
@src/components/FiverrServiceCard.vue
@app/app.vue
@nuxt.config.ts
From shared/types/index.ts:
```typescript
export interface Project { id: string; title: string; description: string; longDescription?: string; image: string; technologies: string[]; category: string; date: string; featured?: boolean; buttons?: ProjectButton[]; gallery?: string[]; demoUrl?: string; githubUrl?: string; features?: string[] }
export interface Technology { name: string; level: 'Beginner' | 'Intermediate' | 'Advanced'; image: string }
export interface TechStack { programming: Technology[]; front: Technology[]; database: Technology[]; devtools: Technology[]; operating_systems: Technology[]; socials: Technology[] }
export interface Testimonial { name: string; role: string; company: string; avatar: string; rating: number; content: string; date: string; platform: string; featured?: boolean; project_type: string; results?: string[] }
export interface TestimonialsStats { totalReviews: number; averageRating: number; projectsCompleted: number }
export interface FAQ { questionKey: string; answerKey: string; featuresKey?: string }
```
From app/composables/useProjects.ts:
```typescript
export function useProjects(): { projects: ComputedRef; featuredProjects: ComputedRef; filterByCategory(cat: string): ComputedRef; search(query: Ref | string): ComputedRef; findById(id: string): ComputedRef }
```
From src/config/site.ts (to migrate):
```typescript
export interface SiteConfig { name: string; title: string; description: string; author: string; contact: ContactInfo; social: SocialLink[]; fiverr: FiverrConfig; url: string; seo: {...}; performance: {...} }
export interface FiverrService { id: string; url: string; image: string; price: string }
export interface FiverrConfig { profileUrl: string; services: FiverrService[] }
export interface ContactInfo { email: string; phone: string; location: string }
export interface SocialLink { name: string; url: string; icon: string; username?: string }
```
Task 1: Installer deps, migrer site config, ajouter UApp, configurer runtimeConfig SMTP
package.json, package-lock.json, app/data/site.ts, shared/types/index.ts, nuxt.config.ts, app/app.vue
1. Installer les dependances :
```bash
npm install nodemailer zod
npm install --save-dev @types/nodemailer
```
2. Creer `app/data/site.ts` en migrant le contenu de `src/config/site.ts`. Copier la structure exacte (siteConfig avec contact, social, fiverr, seo, performance). Ajuster les chemins images fiverr : remplacer `@/assets/images/fiverr/` par `/images/fiverr/` (images dans public/). Exporter `siteConfig` et les interfaces `SiteConfig`, `ContactInfo`, `SocialLink`, `FiverrService`, `FiverrConfig`.
3. Ajouter les interfaces manquantes dans `shared/types/index.ts` : `SiteConfig`, `ContactInfo`, `SocialLink`, `FiverrService`, `FiverrConfig` (ou les exporter depuis `app/data/site.ts` directement — au choix du plus simple).
4. Mettre a jour `nuxt.config.ts` pour ajouter le runtimeConfig SMTP prive (per D-11, D-13) :
```typescript
runtimeConfig: {
smtpHost: '', // NUXT_SMTP_HOST
smtpUser: '', // NUXT_SMTP_USER
smtpPass: '', // NUXT_SMTP_PASS
smtpTo: '', // NUXT_SMTP_TO
public: {
gtag: { id: '' },
},
},
```
IMPORTANT : les credentials SMTP dans la section privee, JAMAIS dans public (per RESEARCH.md Pitfall 4).
5. Mettre a jour `app/app.vue` pour wrapper avec `` — requis pour que `useToast()` fonctionne (per D-10, RESEARCH.md Pitfall 1) :
```vue
```
Conserver le `