20 KiB
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)
--color-primary-dark: #181818
--color-primary-blue: #0A2463
--color-primary-light: #3E92CC
--color-primary-white: #FFFAFF
--color-primary-accent: #D8315B
Problèmes identifiés
- Stack disproportionnée — Angular + Zone.js pour un portfolio statique = bundle lourd (warning 500 kB dans
angular.json), overkill pour du contenu vitrine. - 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.
- Contenu 100 % hardcodé dans les templates — chaque modif de texte, techno, projet ou date d'expérience impose de recompiler + redéployer.
- Animations minimalistes — juste des particules en
requestAnimationFrame, pas d'effets wow (scroll reveal, parallax, 3D, text morphing, cursors custom…). - Icônes PNG — flou sur écrans HiDPI, poids réseau élevé, pas de teinte dynamique possible.
- FontAwesome référencé mais jamais chargé → les 4 icônes des centres d'intérêt sont invisibles.
- Tests inexistants malgré la config Karma — bruit dans
package.json. - 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
SeoServiceet 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
ContentServicefait unfetch('/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 :
{
"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-gradientanimé).
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
SeoServicevers un composant<SEO>Astro.
Phase 2 — Contenu & structure (1–2 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 (2–3 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 (1–2 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
/distexistant). - 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
/jeuxou/bacspour expériences DJ.
6. Estimation totale
| Phase | Charge |
|---|---|
| 0 — Décisions | 30 min |
| 1 — Bootstrap | 1 jour |
| 2 — Contenu & structure | 1–2 jours |
| 3 — Animations | 2–3 jours |
| 4 — Admin (optionnel) | 1–2 jours |
| 5 — Polish & deploy | 1 jour |
| Total sans admin | 5–7 jours |
| Total avec admin | 6–9 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(templateminimal, TS strict)- Installer intégrations :
@astrojs/react,@astrojs/tailwind,@astrojs/node(adapter SSR) - Configurer
astro.config.mjsmodehybrid+ 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.tspublic/content/*.json: contenu extrait des templates Angular actuels + MAJContentService(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 verspublic/img//api/export+/api/import— backup/restore JSON
Étape 7 — SEO + PWA + déploiement ⬜
- Composant
<SEO />(title, description, OG, canonical, Twitter) sitemap.xmlautomanifest.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.mddu 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.ymldéclenché sur pushmain - Contenu projets mis à jour : Techos, Amarea Tattoo, Lidge, Bot Discord KSauce, LPLV (archivé), MonVoisinGeek (archivé)
Prochaines étapes côté utilisateur
cd ~/WebstormProjects/portfolio && npm run dev→ vérifier sur http://localhost:3100npm run hash:password -- monMotDePasse→ copierADMIN_PASSWORD_HASH+ADMIN_JWT_SECRETdans un.envlocal- Tester
/admin/loginpuis/admin - Initialiser git et pousser sur
mainvers Gitea - Configurer les secrets Gitea (
FTP_HOST,FTP_USER,FTP_PASSWORD,FTP_TARGET_DIR) - Configurer Plesk Node.js : startup file
dist/server/entry.mjs, variables d'env admin, Node 22 - Pousser sur
main→ CI déploie → redémarrer l'app Node dans Plesk