mirror of
https://github.com/Ladebeze66/devsite.git
synced 2026-05-11 16:56:26 +02:00
4.4 KiB
4.4 KiB
Frontend Next.js
Dernière mise à jour : 2026-05-10
Stack
- Next.js 15.x, React 18, TypeScript (fichiers
.tsx/.ts) avec fichiers.jsx/.jsencore 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— exemple de slug public / vault :transcription-audio-fgc-transcription(Transcription audio FGC).realisation-ia:name,description,picture,slug,resum(richtext, alias accepté côté front :Resumpour lesprojectuniquement),link,order, relationcompetences(plusieurs)- Vignette → toujours navigation vers la fiche détail interne ; le champ
linksert de bouton Voir plus en bas de fiche (comme sur les fichesproject).
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_URLou défauthttps://api.fernandgrascalvet.com.
- Côté navigateur : si hostname est local / LAN →
fetchData(app/utils/fetchData.ts) : collection +slug, populatepicture,cache: "no-store".- Accueil (
app/page.tsx) :homepages, retry 3×, timeout 10 s.
Configuration Next
next.config.ts:rewritesde/api/:path*vers${API_URL}/api/:path*oùAPI_URLvient deNEXT_PUBLIC_API_URLou défaut production.next/image:images.remotePatternsvers les chemins/uploads/**de l’API Strapi (HTTPS prod +localhost/127.0.0.1:1337en dev) ;formatsAVIF/WebP ;compress: false(compatibilité reverse proxy IIS — voir09-performances-images.md§4.1).- Médias Strapi : utilitaire
pickStrapiImage(app/utils/strapiImage.ts) pour préférer les variantesmedium/largeselon le contexte (liste, hero, galerie). - Plan Server Components (données Strapi), non implémenté :
10-plan-server-components.md.
Composants notables
- Carrousels :
Carousel.tsx,CarouselCompetences.tsx(swiper / react-responsive-carousel). - Sections :
ContentSection.tsx,ContentSectionCompetences*.tsx. ContactForm.tsx→POST /api/contact→ Brevo API (voirdocs-site-interne/contact-flow.md).GrasBotFab+ChatBot.js→askAI.js→/api/proxy→ FastAPI/askavecsession_id+user_id(UUID anonymes viaapp/utils/grasbotIds.js, voirdocs-site-interne/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/strapiImage.ts
app/utils/fetchData.ts
app/api/contact/route.ts
next.config.ts