2026-04-23 19:19:31 +02:00

66 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Frontend Next.js
**Dernière mise à jour :** 2026-04-24
## Stack
- **Next.js** 15.x, **React** 18, **TypeScript** (fichiers `.tsx`/`.ts`) avec fichiers **`.jsx`/`.js`** encore présents.
- **Tailwind CSS** + `@tailwindcss/typography`.
- Rendu riche Strapi : `@strapi/blocks-react-renderer`, **react-markdown** + rehype/remark.
## Routes (App Router)
| Chemin | Fichier | Notes |
|--------|---------|--------|
| `/` | `app/page.tsx` | Accueil : `GET /api/homepages?populate=*` |
| `/portfolio` | `app/portfolio/page.jsx` | Liste projets |
| `/portfolio/[slug]` | `app/portfolio/[slug]/page.tsx` | Détail projet : `ContentSection` + `fetchData('projects', slug)` |
| `/competences` | `app/competences/page.jsx` | Liste compétences — tri par champ Strapi `order` (v4 : `attributes.order`, v5 : `order` à la racine) |
| `/competences/[slug]` | `app/competences/[slug]/page.tsx` | **Rendu conditionnel** : si au moins une entrée `realisation-ia` est liée à la compétence (filtre API sur le slug), **grille de vignettes** (même rythme visuel que le portfolio) ; sinon fiche richtext historique via `ContentSectionCompetencesContainer` |
| `/competences/[slug]/[realisation]` | `app/competences/[slug]/[realisation]/page.tsx` | Fiche d'une **réalisation** (collection Strapi `realisation-ia`) : réutilise `ContentSection` comme les projets (carousel, Markdown `resum` ou `Resum`, CTA `link` externe) |
| `/contact` | `app/contact/page.js` | Formulaire → `/api/contact` (Brevo, voir `contact-flow.md`) |
| `/api/contact` | `app/api/contact/route.ts` | Endpoint serveur : envoie un email via Brevo, honeypot + rate-limit |
| `/api/proxy` | `app/api/proxy/route.js` | Proxy GET vers API LLM distante |
**Strapi — content-types concernés :**
- `competence` : `name`, `content` (richtext), `picture`, `slug`, `order`
- `realisation-ia` : `name`, `description`, `picture`, `slug`, `resum` (richtext, alias accepté côté front : `Resum` pour les `project` uniquement), `link`, `order`, relation `competences` (plusieurs)
- Vignette → toujours navigation vers la **fiche détail** interne ; le champ `link` sert de bouton *Voir plus* en bas de fiche (comme sur les fiches `project`).
## Layout
- `app/layout.tsx`**Client Component** (`"use client"`). Header fixe, menu burger mobile, fond décoratif, **Footer**, compteur de visites **localStorage** (`visitCount`).
## Données Strapi
- **`getApiUrl()`** (`app/utils/getApiUrl.ts`) :
- Côté **navigateur** : si hostname est local / LAN → `http://localhost:1337`, sinon → `https://api.fernandgrascalvet.com`.
- Côté **serveur** : `process.env.NEXT_PUBLIC_API_URL` ou défaut `https://api.fernandgrascalvet.com`.
- **`fetchData`** (`app/utils/fetchData.ts`) : collection + `slug`, populate `picture`, `cache: "no-store"`.
- **Accueil** (`app/page.tsx`) : `homepages`, retry 3×, timeout 10 s.
## Configuration Next
- `next.config.ts` : `rewrites` de `/api/:path*` vers `${API_URL}/api/:path*``API_URL` vient de `NEXT_PUBLIC_API_URL` ou défaut production.
- `images.domains` : `localhost`, `api.fernandgrascalvet.com`.
## Composants notables
- Carrousels : `Carousel.tsx`, `CarouselCompetences.tsx` (swiper / react-responsive-carousel).
- Sections : `ContentSection.tsx`, `ContentSectionCompetences*.tsx`.
- `ContactForm.tsx``POST /api/contact` → Brevo API (voir `contact-flow.md`).
- `GrasBotFab` + `ChatBot.js``askAI.js``/api/proxy` → FastAPI `/ask` avec `session_id` + `user_id` (UUID anonymes via `app/utils/grasbotIds.js`, voir `langfuse-observability.md`).
- `ModalGlossaire.tsx` — glossaire (données Strapi selon usage dans les pages).
## Fichiers clés (liste courte)
```
app/layout.tsx
app/page.tsx
app/utils/getApiUrl.ts
app/utils/fetchData.ts
app/api/contact/route.ts
next.config.ts
```