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

20 KiB
Raw Blame History

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

  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 :

{
  "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