Files
portfolio/docs/01-analyse-et-plan.md
Johan LEROY 9e9bc0f23d first commit
2026-04-21 14:14:03 +02:00

514 lines
20 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.
# Portfolio v2 — Analyse & plan d'action
**Projet source :** `/home/johan/WebstormProjects/Portfolio_angular`
**URL live :** https://johanleroy.fr
**Date :** 20 avril 2026
---
## 1. Analyse de l'existant
### Stack actuelle
| Élément | Valeur |
|---|---|
| Framework | Angular 19.2 |
| Styling | TailwindCSS 4 |
| State / Data | Aucun (tout en dur dans les templates) |
| Animations | Particules vanilla JS maison (`home.component.ts`) |
| Icônes | PNG dans `/public/img/icon/` (pas de SVG, pas HiDPI) |
| Icônes UI | Classes FontAwesome (`fa-gamepad`, `fa-film`) **sans lib chargée → cassées** |
| Dark mode | Toggle manuel via `localStorage` |
| SEO | Service custom `seo.service.ts` (title, description, OG, canonical) |
| Router | Lazy-load `PublicModule`, view transitions activées |
| Hébergement | Statique (`.htaccess` Apache dans `/public/`) |
| Tests | Karma/Jasmine (0 test écrit) |
### Structure
```
src/app/
├── _models/ particule.ts, seo.ts
├── _services/ seo.service.ts
└── public/
├── public-layout/ header + dark toggle + nav
├── public-routing.module.ts
├── public.module.ts
└── pages/
├── home/ (448 lignes HTML — accueil + skills + centres d'intérêt)
├── formations/ (169 lignes)
├── experience/ (417 lignes — 6 entreprises Actemium, SNCF, Cerema, Novoferm, PivotPoint, Almeria)
├── projets/ (104 lignes — 3 projets MonVoisinGeek, Techos, LPLV)
└── not-found/
```
### Palette actuelle (`src/styles.css`)
```css
--color-primary-dark: #181818
--color-primary-blue: #0A2463
--color-primary-light: #3E92CC
--color-primary-white: #FFFAFF
--color-primary-accent: #D8315B
```
### Problèmes identifiés
1. **Stack disproportionnée** — Angular + Zone.js pour un portfolio statique = bundle lourd (warning 500 kB dans `angular.json`), overkill pour du contenu vitrine.
2. **Décalage avec ta stack actuelle** — tu bosses maintenant sur Next.js/Nuxt/NestJS, Angular n'est plus dans aucun de tes projets en mémoire.
3. **Contenu 100 % hardcodé dans les templates** — chaque modif de texte, techno, projet ou date d'expérience impose de recompiler + redéployer.
4. **Animations minimalistes** — juste des particules en `requestAnimationFrame`, pas d'effets wow (scroll reveal, parallax, 3D, text morphing, cursors custom…).
5. **Icônes PNG** — flou sur écrans HiDPI, poids réseau élevé, pas de teinte dynamique possible.
6. **FontAwesome référencé mais jamais chargé** → les 4 icônes des centres d'intérêt sont invisibles.
7. **Tests inexistants** malgré la config Karma — bruit dans `package.json`.
8. **Pas de PWA** (manifest.json, service worker) alors que c'est trivial sur du statique.
### Ce qui marche bien et à conserver
- La structure de navigation (Accueil / Formations / Expérience / Projets).
- La palette existante (tu peux la reprendre ou l'enrichir).
- Le `SeoService` et ses meta tags dynamiques.
- Dark mode par défaut selon préférence système.
- Export statique déployé sur Plesk via Apache.
- Le CV PDF téléchargeable.
---
## 2. Choix techno recommandé
### Option A — **Astro 5 + React islands** ⭐ recommandé
**Pourquoi :**
- 0 JS par défaut → Lighthouse 100 presque gratuit.
- Islands pattern : tu charges React + Framer Motion uniquement sur les sections animées.
- Content Collections typées (Zod) → ton JSON devient un contrat validé au build.
- SSG pur, déploiement Plesk identique à l'actuel (export statique).
- Supporte nativement les endpoints SSR si tu veux un mini-admin.
**Stack complète :**
- Astro 5 (router fichiers, layouts)
- React 19 (îlots interactifs)
- TailwindCSS 4 (continuité palette)
- Framer Motion (micro-interactions déclaratives)
- GSAP + ScrollTrigger (timelines paillettes)
- Lenis (smooth scroll)
- @react-three/fiber + @react-three/drei (effets 3D type scène accueil)
- Lucide React (icônes UI) + Simple Icons via iconify (logos techno vectoriels)
- TypeScript strict
### Option B — **Next.js 15 + App Router**
Pertinent si tu veux un vrai mini-back-office plus tard (auth JWT, API routes, ISR). Plus lourd qu'Astro pour un simple portfolio.
### Option C — **Nuxt 4**
Si tu préfères rester côté Vue. Excellent mais tu connais déjà Vue 3 (Amarea, TrackSniff), donc pas de challenge.
### Recommandation
**Astro 5** — le meilleur rapport puissance/légèreté pour un portfolio. Tu ajoutes Next.js à ton CV avec Techos, Astro te donne un 3e framework frontend moderne à afficher, et tu gagnes une killer app de perf.
---
## 3. Système de contenu éditable sans rebuild
### Architecture proposée
```
public/
├── content/
│ ├── profile.json (nom, titre, accroche, photo, CV)
│ ├── skills.json (catégories + items avec niveau, logo iconify)
│ ├── experiences.json (tableau d'expériences pro)
│ ├── formations.json (tableau de formations)
│ ├── projects.json (tableau de projets + images + liens)
│ ├── interests.json (centres d'intérêt)
│ └── site.json (meta SEO, couleurs, switches features)
└── img/ (assets éditables)
```
### Principe
- Les fichiers JSON sont servis **en statique** par ton Plesk (pas dans le bundle).
- Côté client, un `ContentService` fait un `fetch('/content/profile.json')` au mount.
- Les composants React affichent les données via Suspense.
- **Modif en production = éditer le JSON sur le serveur → rechargement navigateur = MAJ immédiate. Zéro rebuild.**
### Schémas typés (Zod)
Les mêmes schémas servent :
- au build (validation SSG des données si tu veux injecter au build)
- au runtime (parsing des JSON fetchés)
- à l'admin (génération de formulaires)
Exemple `content/profile.json` :
```json
{
"name": "Johan Leroy",
"title": "Développeur Fullstack",
"tagline": "Dev le jour, DJ la nuit",
"hero": {
"photo": "/img/pp/pp3.png",
"cta": [
{ "label": "Télécharger mon CV", "href": "/assets/cv.pdf" },
{ "label": "Voir mes projets", "href": "/projets" }
]
},
"socials": {
"email": "leroyjohan3@gmail.com",
"github": "https://github.com/JohanLeroy",
"gitea": "https://git.lidge.fr/johanleroy",
"website": "https://johanleroy.fr"
}
}
```
### 3 niveaux d'édition (à choisir)
| Niveau | Outil | Usage |
|---|---|---|
| **1. Terminal / SFTP** | FTP Plesk + éditeur texte | MAJ rapide, zéro surcouche. Le plus simple. |
| **2. Mini-admin web** | `/admin` protégé par mot de passe (cookie httpOnly côté endpoint Astro SSR) | Formulaire qui édite `content/*.json` en live sur le serveur |
| **3. Gitea as CMS** | Un repo `johan-portfolio-content` dédié. L'admin web pousse via l'API Gitea. | Historisation automatique, rollback possible, build-free par cron `git pull` côté Plesk. |
**Reco pour toi :** niveau 2 ou 3. Le niveau 3 est le plus élégant car tu gardes un vrai git history sans polluer le repo code.
### Ce que l'admin web permettrait
- Édition inline du profil (nom, titre, bio)
- Ajout/édition/suppression de projets (drag-drop pour réordonner)
- Ajout d'une expérience pro
- Changement du thème de couleur (live preview)
- Toggle du mode "embauche disponible" (badge vert sur le site)
- Upload de nouvelles images (vers `/public/img/` via endpoint SSR)
- Export / import du JSON (backup)
---
## 4. UX "paillettes dans les yeux" — direction créative
### Accueil
- **Hero 3D** avec @react-three/fiber : scène minimaliste type "disco ball" qui tourne lentement, sensible au mouvement de souris (parallax). Nod subtil à ton univers DJ.
- **Texte morphing** (GSAP SplitText) — "Dev" se transforme en "DJ" puis en "Dev" en boucle lente.
- **Curseur custom** qui suit la souris avec un léger lag, change de forme sur les liens.
- **Gradient animé** en arrière-plan type aurore boréale (shader ou CSS `conic-gradient` animé).
### Scroll
- **Lenis smooth scroll** partout.
- **Scroll-triggered animations** : sections qui révèlent leur contenu en cascade (fade + translate-y + blur-out).
- **Pin + horizontal scroll** sur la section Projets (GSAP ScrollTrigger, type showcase Awwwards).
- **Progress bar** en haut de page.
### Section skills
- Cards avec effet **hover 3D tilt** (vanilla-tilt ou React équivalent).
- Icônes SVG des technos avec **glow au survol**.
- Compteur de maîtrise animé (ring progress) au scroll.
### Timeline expérience
- Layout type **métro parisien** (une ligne verticale animée, stations = expériences).
- Cards qui s'ouvrent en accordéon au scroll.
### Projets
- Carousel horizontal pinned avec images **zoom parallax**.
- Badge techno avec micro-logos simple-icons colorés.
- Hover : overlay gradient + CTA "voir projet".
### Detail bonus
- **Mode "party"** (easter egg) : un bouton discret qui active un strobe + particles + glitch texts → clin d'œil DJ.
- **Konami code** → affiche ton set DJ en fond sonore discret.
- **Switch 3 thèmes** : Day, Night, Neon (le mode neon = pleine paillettes).
---
## 5. Plan d'exécution
### Phase 0 — Prérequis (décision utilisateur)
- [ ] Valider le choix Astro vs Next.js vs Nuxt.
- [ ] Valider le niveau d'édition (SFTP / admin web / Gitea).
- [ ] Choisir nom de projet (`portfolio-v2`, `johanleroy-fr`, `portfolio-astro`, …).
- [ ] Palette : garder l'actuelle ou refaire ? (je peux proposer 3 palettes).
### Phase 1 — Bootstrap (1 jour)
- Scaffold Astro + TS strict + Tailwind 4 + React integration.
- Setup ESLint + Prettier + configs héritées de Techos (cohérence).
- Créer les 6 schémas Zod + JSON de contenu initial (repris du site actuel).
- Layout global + router fichier (`/`, `/formations`, `/experience`, `/projets`).
- Migrer `SeoService` vers un composant `<SEO>` Astro.
### Phase 2 — Contenu & structure (12 jours)
- Extraire tout le contenu des templates actuels vers les JSON.
- Migrer les PNG d'icônes → Iconify (Simple Icons + Lucide).
- Migrer les images projets/entreprises (optimisation avec `astro:assets`).
- Pages statiques sans animations pour valider la structure.
### Phase 3 — Animations & paillettes (23 jours)
- Intégration Lenis + configuration smooth scroll globale.
- Installation Framer Motion + GSAP + ScrollTrigger.
- Hero 3D @react-three/fiber.
- Scroll-triggered reveals sur chaque section.
- Curseur custom + cards 3D tilt + timeline métro.
- Carousel projets pinned horizontal.
- Thèmes Day / Night / Neon.
### Phase 4 — Admin d'édition (12 jours, optionnel selon niveau choisi)
- Endpoint Astro SSR `/api/content/:file` (GET/PUT).
- Protection par mot de passe + cookie httpOnly.
- Page `/admin` : formulaires dynamiques générés depuis les schémas Zod.
- Upload d'images.
- Export / import JSON.
- (Variante Gitea) : intégration Gitea API pour push auto.
### Phase 5 — Polish & deploy (1 jour)
- PWA (manifest + service worker).
- Audit Lighthouse (objectif 100/100/100/100).
- Sitemap auto + robots.txt.
- Meta tags Open Graph + Twitter Cards.
- Build production.
- Déploiement Plesk (remplacement `/dist` existant).
- Redirections 301 si URLs changent.
### Phase 6 — Extras plus tard
- Blog MDX (écriture d'articles techniques).
- Page contact avec vrai formulaire (via endpoint SSR ou Formspree).
- Section "Now" (what I'm up to, mis à jour mensuel).
- Stats GitHub/Gitea live (commits, streaks).
- Page `/jeux` ou `/bacs` pour expériences DJ.
---
## 6. Estimation totale
| Phase | Charge |
|---|---|
| 0 — Décisions | 30 min |
| 1 — Bootstrap | 1 jour |
| 2 — Contenu & structure | 12 jours |
| 3 — Animations | 23 jours |
| 4 — Admin (optionnel) | 12 jours |
| 5 — Polish & deploy | 1 jour |
| **Total sans admin** | **57 jours** |
| **Total avec admin** | **69 jours** |
---
## 7. Questions initiales — réponses validées ✅
| # | Question | Réponse |
|---|---|---|
| 1 | Framework | ✅ **Astro 5** |
| 2 | Système d'édition | ✅ **Admin web** (option 2) |
| 3 | Palette / identité | ✅ **Refonte DEV/DJ/Neon** |
| 4 | Hébergement | ✅ **Plesk** (stay put) — ISR à creuser selon contraintes |
| 5 | Niveau "paillettes" | ✅ **Wow mais pro** (pas d'effets dans tous les sens) |
| 6 | Contenu à rafraîchir | ✅ **Ajouter projets récents** (sauf Beehelp = pro/NDA) |
| 7 | Nom du repo | ✅ `portfolio` |
---
## 8. Setup technique dérivé des choix
| Élément | Valeur |
|---|---|
| Mode Astro | **Hybrid** — SSG pour pages publiques, SSR pour `/admin` et `/api` |
| Déploiement | **Plesk Node.js hosting** (même pattern que `techos_api`) |
| Persistance contenu | `/public/content/*.json` édités par endpoints SSR protégés |
| Auth admin | Mot de passe + cookie httpOnly (JWT ou session simple) |
| MAJ contenu en prod | Admin web → PUT JSON → **fetch runtime côté client, zéro rebuild** |
| ISR — note Plesk | Plesk = serveur Node permanent, on a l'équivalent d'ISR gratuit. Pas d'ISR Next.js-style mais re-fetch JSON runtime = effet identique |
---
## 9. Direction artistique — 3 palettes néon à trancher
### Option A — **Cyberpunk Dark** (blade-runner / tekno industrielle)
```
bg: #0A0A0F (noir profond)
accent 1: #00F0FF (cyan électrique)
accent 2: #FF2A6D (rose magenta)
accent 3: #D1F7FF (blanc bleuté)
texte: #E0E0FF
```
### Option B — **Rave / Miami** (90's, fun, coloré)
```
bg: #0D0221 (violet nuit)
accent 1: #FF00C8 (pink néon)
accent 2: #00FFC8 (mint laser)
accent 3: #FFD600 (jaune flash)
texte: #FFF8F0
```
### Option C — **Tech Minimal + 1 néon** ⭐ reco pro
```
bg: #0B0B0E (charbon)
surface: #16161D
accent: #39FF14 (vert néon strobe) — UN SEUL pop
texte: #EAEAEA
secondaire: #8A8F98
```
**Reco :** Option C pour recruteurs (le plus pro), Option A si on assume la vibe DJ.
---
## 10. Liste projets à afficher — proposition
| # | Projet | Statut | Action |
|---|---|---|---|
| 1 | **Techos** (asso hébergement) | Live `techos-asso.fr` | ✅ Inclure |
| 2 | **TrackSniff** | Privé (invitation) | ⚠️ À trancher |
| 3 | **Amarea Tattoo** | Client (studio tatouage) | ✅ Inclure |
| 4 | **Lidge** | Perso, auto-hébergé | ✅ Inclure |
| 5 | **Portfolio v2** (méta) | En cours | ✅ Classique circulaire |
| 6 | **MonVoisinGeek / LPLV** (anciens) | Live actuellement | ⚠️ Keep or drop ? |
| ❌ | **Beehelp** | Pro / NDA | ❌ Exclu (validé) |
---
## 11. Questions finales — réponses validées ✅
| # | Question | Réponse |
|---|---|---|
| 1 | **Palette** | ✅ **Option A — Cyberpunk Dark** (`#0A0A0F / #00F0FF / #FF2A6D / #D1F7FF / #E0E0FF`) |
| 2 | TrackSniff affiché ? | ❌ **Non** (privé, on n'affiche pas) |
| 3 | Portfolio v2 (self-reference) | ❌ **Non** |
| 4 | MonVoisinGeek / LPLV | ✅ **Garder** — mais marqués **"Projet fermé / archivé"**, infos présentes, liens morts |
| 5 | Projet supplémentaire | ✅ **Ajouter "Bot Discord KSauce"** |
| 6 | Nouvelle expérience/formation | — (à compléter au moment de migrer le contenu) |
### Liste finale des projets affichés
| # | Projet | État | Lien |
|---|---|---|---|
| 1 | **Techos** | Live | techos-asso.fr |
| 2 | **Amarea Tattoo** | Live | (à confirmer) |
| 3 | **Lidge** | Live perso | (à confirmer) |
| 4 | **Bot Discord KSauce** | (à préciser) | — |
| 5 | **MonVoisinGeek** | 🔒 Archivé | — |
| 6 | **LPLV** | 🔒 Archivé | — |
---
## 12. Plan d'implémentation détaillé — GO
**Répertoire cible :** `/home/johan/WebstormProjects/portfolio` (nouveau, à côté de l'ancien `Portfolio_angular`)
### Étape 1 — Bootstrap Astro hybrid ⬜
- [ ] `npm create astro@latest portfolio` (template `minimal`, TS strict)
- [ ] Installer intégrations : `@astrojs/react`, `@astrojs/tailwind`, `@astrojs/node` (adapter SSR)
- [ ] Configurer `astro.config.mjs` mode `hybrid` + adapter Node standalone (Plesk)
- [ ] Setup Prettier + ESLint (aligné sur Techos)
- [ ] `.gitignore`, `.editorconfig`, `README.md`
### Étape 2 — Design system Cyberpunk Dark ⬜
- [ ] `tailwind.config` + CSS custom properties (palette Option A)
- [ ] Typographies : **heading** = Space Grotesk / **body** = Inter / **mono accent** = JetBrains Mono
- [ ] Utilitaires `glow-cyan`, `glow-pink`, `neon-border`, `scanlines`, `noise-overlay`
- [ ] Cursor custom (composant React island)
- [ ] Dark only (pas de light mode — la vibe cyberpunk ne s'y prête pas)
### Étape 3 — Schémas Zod + contenu JSON ⬜
- [ ] `src/content/schemas/` : `profile.ts`, `skills.ts`, `experiences.ts`, `formations.ts`, `projects.ts`, `interests.ts`, `site.ts`
- [ ] `public/content/*.json` : contenu extrait des templates Angular actuels + MAJ
- [ ] `ContentService` (fetch runtime) côté client
- [ ] Validation Zod au parsing (garde-fou si JSON mal formé)
### Étape 4 — Pages publiques + layout ⬜
- [ ] Layout global : `Header` (nav + logo glitch), `Footer`, `CursorCustom`, `LenisProvider`
- [ ] `/` — Hero 3D disco-ball (R3F), scroll reveals, skills, centres d'intérêt
- [ ] `/formations` — Timeline métro verticale
- [ ] `/experience` — Timeline métro + cards accordéon (6 entreprises)
- [ ] `/projets` — Carousel pinned horizontal + badges techno Iconify
- [ ] `/404` — Page glitch 404
### Étape 5 — Animations paillettes ⬜
- [ ] Lenis smooth scroll global
- [ ] Framer Motion : reveals + micro-interactions
- [ ] GSAP + ScrollTrigger : timelines pinned
- [ ] Hero R3F : disco ball parallax souris
- [ ] SplitText : morphing "Dev / DJ / Dev"
- [ ] Cards skills : 3D tilt (hover)
- [ ] Gradient conic animé en bg
### Étape 6 — Admin SSR ⬜
- [ ] `/admin/login` — form password → cookie httpOnly
- [ ] Middleware `src/middleware.ts` : protection route `/admin/*`
- [ ] `/admin` — dashboard, liste des sections éditables
- [ ] `/admin/edit/[section]` — formulaires générés depuis Zod schemas
- [ ] `/api/content/[section]` — GET/PUT (lecture + écriture JSON serveur)
- [ ] `/api/upload` — upload images vers `public/img/`
- [ ] `/api/export` + `/api/import` — backup/restore JSON
### Étape 7 — SEO + PWA + déploiement ⬜
- [ ] Composant `<SEO />` (title, description, OG, canonical, Twitter)
- [ ] `sitemap.xml` auto
- [ ] `manifest.json` + service worker (PWA)
- [ ] Redirections 301 depuis anciennes URLs si nécessaire
- [ ] Build prod + test local
- [ ] Script déploiement Plesk Node (équivalent Techos API)
- [ ] Remplacement sur `johanleroy.fr`
### Étape 8 — Post-déploiement ⬜
- [ ] Audit Lighthouse (objectif 95+)
- [ ] Test admin web en prod
- [ ] Rédiger `docs/ADMIN.md` (comment éditer le contenu)
- [ ] Snapshot initial dans git du contenu actuel
- [ ] Mettre à jour `CLAUDE.md` du projet
---
**GO ✅** — scaffold démarré.
---
## 13. État d'implémentation (suivi)
| Étape | Status |
|---|---|
| 1 — Bootstrap Astro hybrid (React + Tailwind 4 + Node adapter) | ✅ |
| 2 — Design system Cyberpunk Dark (palette, glow, néon, fonts) | ✅ |
| 3 — Schémas Zod + JSON contenu extrait | ✅ |
| 4 — Layout + pages publiques (/, /formations, /experience, /projets, /404) | ✅ |
| 5 — Animations (Lenis, Framer Motion, R3F hero disco, morph, curseur) | ✅ |
| 6 — Admin SSR protégé + API CRUD JSON + upload | ✅ |
| 7 — SEO + build prod + workflow Gitea + README déploiement | ✅ |
### Livrables
- `/home/johan/WebstormProjects/portfolio/` (projet Astro 6 + React 19 + Tailwind 4)
- Build production OK → `dist/server/entry.mjs` (startup Plesk Node)
- Dev testé sur **http://localhost:3100**
- Workflow `.gitea/workflows/deploy.yml` déclenché sur push `main`
- Contenu projets mis à jour : Techos, Amarea Tattoo, Lidge, Bot Discord KSauce, LPLV (archivé), MonVoisinGeek (archivé)
### Prochaines étapes côté utilisateur
1. `cd ~/WebstormProjects/portfolio && npm run dev` → vérifier sur http://localhost:3100
2. `npm run hash:password -- monMotDePasse` → copier `ADMIN_PASSWORD_HASH` + `ADMIN_JWT_SECRET` dans un `.env` local
3. Tester `/admin/login` puis `/admin`
4. Initialiser git et pousser sur `main` vers Gitea
5. Configurer les secrets Gitea (`FTP_HOST`, `FTP_USER`, `FTP_PASSWORD`, `FTP_TARGET_DIR`)
6. Configurer Plesk Node.js : startup file `dist/server/entry.mjs`, variables d'env admin, Node 22
7. Pousser sur `main` → CI déploie → redémarrer l'app Node dans Plesk