# Portfolio — Johan Leroy Site vitrine personnel en **Astro 6 hybrid** (SSG public + SSR admin), déployé sur Plesk Node.js. 🎧 Dev le jour, DJ la nuit — stack cyberpunk dark, contenu éditable sans recompilation. --- ## Stack - **Astro 6** (`output: 'static'` + adapter Node standalone — hybrid via `prerender: false` sur `/admin/*` et `/api/*`) - **React 19** (îlots interactifs) - **Tailwind CSS 4** + custom design system cyberpunk - **Framer Motion** + **GSAP** + **Lenis** (animations) - **@react-three/fiber** (hero 3D disco ball) - **Zod** (validation schémas de contenu) - **jose** + **bcryptjs** (auth admin JWT cookie) --- ## Développement ```bash npm install npm run dev ``` → http://localhost:3100 ## Édition du contenu Tout le contenu éditable est dans `public/content/*.json` : | Fichier | Rôle | |---|---| | `profile.json` | Profil, photo, CTA hero, réseaux sociaux | | `skills.json` | Compétences techniques (primary + secondary) | | `experiences.json` | Parcours pro + compétences techniques & transverses | | `formations.json` | Diplômes et formations | | `projects.json` | Portfolio de projets | | `interests.json` | Centres d'intérêt | | `site.json` | Meta SEO + flags features | Tu peux éditer : - **Via `/admin`** (interface web protégée par mot de passe) — recommandé en prod - **Manuellement** en éditant les JSON et en rechargeant la page **Aucune recompilation n'est nécessaire** : les fichiers sont servis statiquement côté site public, et relus au runtime côté admin. --- ## Admin ### Configuration initiale 1. Générer un hash de mot de passe : ```bash npm run hash:password -- monMotDePasse ``` 2. Copier les deux lignes générées (`ADMIN_PASSWORD_HASH` et `ADMIN_JWT_SECRET`) dans un fichier `.env` (local) ou dans les variables d'environnement Plesk (prod). ### Accès → http://localhost:3100/admin (ou https://johanleroy.fr/admin en prod) Login via mot de passe, cookie httpOnly 7 jours. --- ## Déploiement Plesk Node.js ### Variables d'environnement à définir sur Plesk | Variable | Valeur | |---|---| | `ADMIN_PASSWORD_HASH` | hash bcrypt généré | | `ADMIN_JWT_SECRET` | secret JWT aléatoire | | `PORT` | `3100` (ou ce que Plesk impose) | | `HOST` | `0.0.0.0` | | `NODE_ENV` | `production` | ### Paramètres Plesk Node.js - **Node.js version** : 22 - **Application root** : racine du repo - **Application startup file** : `dist/server/entry.mjs` - **Application URL** : https://johanleroy.fr ### CI/CD Gitea (branch `main`) Le workflow `.gitea/workflows/deploy.yml` déclenche un build + upload FTP sur chaque push `main`. **Secrets Gitea à configurer :** - `FTP_HOST` - `FTP_USER` - `FTP_PASSWORD` - `FTP_TARGET_DIR` (ex : `/httpdocs/johanleroy`) Après chaque déploiement : redémarrer l'application Node.js depuis Plesk pour prendre en compte les nouveaux fichiers. --- ## Structure ``` src/ ├── components/ │ ├── Header.astro, Footer.astro, SEO.astro │ ├── ProjectCard.astro │ └── islands/ # composants React hydratés │ ├── Hero3D.tsx │ ├── RolesMorph.tsx │ ├── Reveal.tsx │ ├── SkillCard.tsx │ ├── SmoothScroll.tsx │ └── CustomCursor.tsx ├── content/schemas/ # schémas Zod (typages + validation) ├── lib/ │ ├── auth.ts # JWT cookie admin │ └── content.ts # lecture/écriture JSON ├── layouts/BaseLayout.astro ├── middleware.ts # protection routes /admin et /api ├── pages/ │ ├── index.astro │ ├── formations.astro │ ├── experience.astro │ ├── projets.astro │ ├── 404.astro │ ├── admin/ │ │ ├── login.astro │ │ ├── index.astro │ │ └── edit/[section].astro │ └── api/ │ ├── auth/login.ts, logout.ts │ ├── content/[section].ts │ └── upload.ts └── styles/global.css public/ ├── content/*.json # données éditables ├── img/ # images (icônes, entreprises, projets, photos) └── assets/cv.pdf ``` --- ## Direction artistique **Cyberpunk Dark** — noir profond + cyan/magenta néon. - Palette : `#0A0A0F / #00F0FF / #FF2A6D / #D1F7FF` - Typographies : Space Grotesk (display), Inter (body), JetBrains Mono (mono) - Effets : disco ball 3D, smooth scroll Lenis, curseur custom, glow néon, scanlines, glitch --- ## Licence © 2026 Johan Leroy.