refonte: portfolio statique Astro (design moderne développeur)
Some checks failed
Deploy production / build-deploy (push) Failing after 56s
Some checks failed
Deploy production / build-deploy (push) Failing after 56s
- Remplace l'ancien Astro hybrid + admin par un site one-page statique (sortie static) - Thème clair/sombre sans flash, contenu typé (src/data/content.ts), zéro admin - Icônes simple-icons (SVG monochrome), polices auto-hébergées (RGPD) - SEO complet : canonical, Open Graph, Twitter Card, JSON-LD Person, robots.txt, sitemap.xml, image OG 1200x630 - CI Gitea de déploiement FTPS vers Plesk (.gitea/workflows/prod.yml)
This commit is contained in:
170
README.md
170
README.md
@@ -1,161 +1,37 @@
|
||||
# Portfolio — Johan Leroy
|
||||
# Portfolio — johanleroy.fr
|
||||
|
||||
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)
|
||||
|
||||
---
|
||||
Site vitrine **one-page** de Johan Leroy, développeur fullstack.
|
||||
Stack : **Astro 6** (sortie 100 % statique), TypeScript, CSS (variables de thème), zéro îlot
|
||||
framework. Thème **clair/sombre** persistant, polices **auto-hébergées** (RGPD-friendly), icônes
|
||||
de technos via **simple-icons** (SVG inline monochromes).
|
||||
|
||||
## Développement
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
npm run dev # serveur de dev (http://localhost:4321)
|
||||
npm run check # astro check (typage)
|
||||
npm run build # build statique → dist/
|
||||
npm run preview # prévisualise le build
|
||||
```
|
||||
|
||||
→ http://localhost:3100
|
||||
## Modifier le contenu
|
||||
|
||||
## Édition du contenu
|
||||
Tout le contenu (profil, projets, expériences, formation, stack, centres d'intérêt) vit dans
|
||||
**un seul fichier typé** : [`src/data/content.ts`](src/data/content.ts).
|
||||
L'URL du bouton « café » s'y trouve aussi (`coffeeUrl`).
|
||||
|
||||
Tout le contenu éditable est dans `public/content/*.json` :
|
||||
## Assets
|
||||
|
||||
| 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 |
|
||||
- `public/images/` — logo, photos de profil, logos d'entreprises, visuels de projets.
|
||||
- `public/fonts/` — Inter + JetBrains Mono (`.woff2`, auto-hébergées).
|
||||
- `public/cv.pdf` — CV téléchargeable depuis le hero.
|
||||
|
||||
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
|
||||
## Déploiement
|
||||
|
||||
**Aucune recompilation n'est nécessaire** : les fichiers sont servis statiquement côté site public, et relus au runtime côté admin.
|
||||
**Automatique via Gitea Actions** (`.gitea/workflows/prod.yml`) : tout push sur `main` lance
|
||||
`astro check` + `npm run build`, puis envoie `dist/` en FTP vers Plesk.
|
||||
Secrets à définir dans Gitea (Settings → Actions → Secrets) :
|
||||
`FTP_HOST`, `FTP_USER`, `FTP_PASSWORD`, `FTP_TARGET_DIR` (chemin docroot, ex. `/httpdocs/johanleroy/public`).
|
||||
|
||||
---
|
||||
|
||||
## 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+ (24.x OK)
|
||||
- **Application root** : `/httpdocs/johanleroy`
|
||||
- **Document root Apache** : `/httpdocs/johanleroy/dist/client` (Apache sert les statiques buildés, le reste passe en proxy vers Node)
|
||||
- **Application startup file** : `dist/server/entry.mjs`
|
||||
- **Application URL** : https://johanleroy.fr (SSL Let's Encrypt obligatoire pour les cookies admin)
|
||||
|
||||
### Déploiement manuel
|
||||
|
||||
1. **Build local** : `npm run build` (vérifier que `dist/server/entry.mjs` est généré)
|
||||
2. **Upload FTP/SFTP** vers le répertoire de l'application Plesk (ex : `/httpdocs/johanleroy/`) :
|
||||
- `dist/` (écrase l'existant)
|
||||
- `public/` (écrase l'existant)
|
||||
- `package.json`
|
||||
- `package-lock.json`
|
||||
3. **Plesk → Node.js → NPM install** (à faire si `package.json` a changé)
|
||||
4. **Plesk → Node.js → Restart App** pour recharger le nouveau bundle
|
||||
|
||||
**Ne JAMAIS écraser** : `data/`, `.env`, `node_modules/` côté serveur.
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
Déploiement manuel possible : `npm run build` → uploader le contenu de `dist/` sur l'hébergement statique.
|
||||
|
||||
Reference in New Issue
Block a user