Files
2026-04-10 17:50:10 +02:00

96 lines
4.6 KiB
Markdown

# Structure
**Analysis Date:** 2026-04-10
## Directory Layout
```
portfolio/
├── app/ # Nuxt 4 app directory (srcDir)
│ ├── app.vue # Root component (UApp wrapper)
│ ├── error.vue # Error/404 page
│ ├── assets/css/main.css # Global CSS (Tailwind imports)
│ ├── components/
│ │ ├── layout/
│ │ │ ├── AppHeader.vue # Sticky header with nav, locale/theme toggles
│ │ │ └── AppFooter.vue # Footer with social links, copyright
│ │ ├── sections/
│ │ │ ├── HeroSection.vue # Landing hero with CTA
│ │ │ ├── FeaturedProjectsSection.vue
│ │ │ ├── ServicesSection.vue
│ │ │ ├── TestimonialsSection.vue
│ │ │ ├── FAQSection.vue
│ │ │ └── CTASection.vue
│ │ ├── ContactForm.vue # Form with Zod validation + honeypot
│ │ ├── ProjectCard.vue # Project display card
│ │ ├── ProjectGallery.vue # Image gallery modal
│ │ └── TechBadge.vue # Technology badge with icon
│ ├── composables/
│ │ └── useProjects.ts # Project data access + i18n + filtering
│ ├── data/ # Static typed data
│ │ ├── projects.ts # 7 projects (Omit translatable fields)
│ │ ├── testimonials.ts # Client testimonials
│ │ ├── techstack.ts # Technology categories
│ │ ├── faq.ts # FAQ entries (i18n keys)
│ │ └── site.ts # Site config (SEO, contact, social)
│ ├── layouts/
│ │ └── default.vue # Main layout (header + slot + footer)
│ └── pages/ # File-based routing
│ ├── index.vue # Homepage
│ ├── about.vue # About page
│ ├── contact.vue # Contact form page
│ ├── projects.vue # Project listing with filters
│ ├── fiverr.vue # Fiverr services page
│ └── project/[id].vue # Dynamic project detail
├── i18n/locales/ # Translation files
│ ├── fr.json # French (default locale)
│ └── en.json # English
├── server/api/
│ └── contact.post.ts # Contact form POST handler (nodemailer)
├── shared/types/
│ └── index.ts # All TypeScript interfaces
├── public/images/ # Static images (WebP)
├── nuxt.config.ts # Nuxt configuration
├── app.config.ts # Nuxt UI theme tokens
├── Dockerfile # Multi-stage SSR build (node:22-alpine)
├── docker-compose.yml # Docker compose with Traefik
├── package.json # Dependencies (pnpm)
└── pnpm-lock.yaml # pnpm lockfile
```
## Page Inventory
| Route | File | Description |
|-------|------|-------------|
| `/` | `index.vue` | Homepage with 6 sections (hero, projects, services, testimonials, FAQ, CTA) |
| `/about` | `about.vue` | About page with tech stack badges |
| `/projects` | `projects.vue` | Project listing with search + category filters |
| `/project/:id` | `project/[id].vue` | Dynamic project detail with gallery |
| `/contact` | `contact.vue` | Contact form page |
| `/fiverr` | `fiverr.vue` | Fiverr services page |
| `/en/*` | (same files) | English prefix routes via i18n |
## Component Hierarchy
- **Layout components** (`layout/`): AppHeader, AppFooter — used in `default.vue` layout
- **Section components** (`sections/`): 6 homepage sections — composed in `index.vue`
- **Shared components** (root): ContactForm, ProjectCard, ProjectGallery, TechBadge — reused across pages
All components auto-imported with `pathPrefix: false` — use `AppHeader` not `LayoutAppHeader`.
## Where to Add Things
| To add... | Location |
|-----------|----------|
| New page | `app/pages/newpage.vue` (auto-routed) |
| New component | `app/components/` (auto-imported) |
| New section | `app/components/sections/` |
| New API route | `server/api/name.method.ts` |
| New data file | `app/data/name.ts` |
| New type | `shared/types/index.ts` |
| New i18n keys | `i18n/locales/fr.json` + `en.json` |
---
*Structure analysis: 2026-04-10*