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)
309 lines
9.9 KiB
TypeScript
309 lines
9.9 KiB
TypeScript
/* ============================================================
|
|
Contenu du portfolio — SOURCE DE VÉRITÉ unique.
|
|
Pour modifier le site (textes, projets, expériences…),
|
|
c'est ici que ça se passe. Tout est typé.
|
|
============================================================ */
|
|
|
|
export type ProjectStatus = "live" | "archived" | "oss";
|
|
|
|
export interface Project {
|
|
id: string;
|
|
title: string;
|
|
subtitle: string;
|
|
desc: string;
|
|
stack: string[];
|
|
status: ProjectStatus;
|
|
link?: string;
|
|
img?: string;
|
|
}
|
|
|
|
export interface Experience {
|
|
company: string;
|
|
logo: string;
|
|
role: string;
|
|
period: string;
|
|
duration: string;
|
|
desc: string;
|
|
missions: string[];
|
|
stack: string[];
|
|
current?: boolean;
|
|
}
|
|
|
|
export interface Formation {
|
|
title: string;
|
|
school: string;
|
|
period: string;
|
|
desc?: string;
|
|
}
|
|
|
|
export interface StackGroup {
|
|
label: string;
|
|
items: string[]; // noms de technos, résolus en icônes par <TechIcon/>
|
|
}
|
|
|
|
export interface Interest {
|
|
name: string;
|
|
note: string;
|
|
icon: "gamepad" | "film" | "music" | "code";
|
|
}
|
|
|
|
export const profile = {
|
|
name: "Johan Leroy",
|
|
role: "Développeur fullstack",
|
|
lede:
|
|
"Je conçois et développe des applications web performantes, propres et scalables — du front jusqu'à la mise en production. Basé à Nantes, profil « builder » : open-source, auto-hébergement, projets perso.",
|
|
bio:
|
|
"Développeur fullstack passionné par les technologies modernes. J'aime construire des produits complets — penser l'archi, soigner l'expérience, déployer et maintenir. J'expérimente en continu via mes projets perso, mes services auto-hébergés et l'open-source.",
|
|
};
|
|
|
|
export const social = {
|
|
email: "contact@johanleroy.fr",
|
|
github: "https://github.com/JohanLeroy",
|
|
gitea: "https://git.lidge.fr/johanleroy",
|
|
linkedin: "https://www.linkedin.com/in/johan-leroy-472409180/",
|
|
site: "https://johanleroy.fr",
|
|
};
|
|
|
|
/* URL du bouton « café » — à remplacer par le service retenu
|
|
(Buy Me a Coffee, Ko-fi, Liberapay, PayPal.me, Stripe…). */
|
|
export const coffeeUrl = "https://buymeacoffee.com/johanleroy";
|
|
|
|
export const stats = [
|
|
{ n: "~3 ans", l: "d'expérience pro" },
|
|
{ n: "6+", l: "projets livrés" },
|
|
{ n: "8+", l: "services auto-hébergés" },
|
|
{ n: "OSS", l: "contributeur open-source" },
|
|
];
|
|
|
|
export const projectsFeatured: Project[] = [
|
|
{
|
|
id: "techos",
|
|
title: "Techos",
|
|
subtitle: "Plateforme hébergement & domaines",
|
|
desc:
|
|
"Plateforme client + admin de gestion d'hébergement web et de domaines pour une association, bâtie sur WHMCS. Design system « Liquid Glass » clair/sombre.",
|
|
stack: ["Next.js 16", "React 19", "NestJS 11", "Tailwind 4", "shadcn/ui", "Redis", "WHMCS API"],
|
|
status: "live",
|
|
link: "https://techos-asso.fr",
|
|
img: "/images/projets/techos.png",
|
|
},
|
|
{
|
|
id: "amarea",
|
|
title: "Amarea Tattoo",
|
|
subtitle: "Site du studio de tatouage Amarea",
|
|
desc:
|
|
"Site vitrine + gestion pour un studio de tatouage. Architecture découplée SPA + API REST avec gestion de médias.",
|
|
stack: ["Vue 3", "Vite", "NestJS 11", "TypeORM", "MariaDB", "Tailwind 4"],
|
|
status: "live",
|
|
},
|
|
{
|
|
id: "lidge",
|
|
title: "Lidge",
|
|
subtitle: "Portail d'abonnements aux services auto-hébergés",
|
|
desc:
|
|
"Plateforme perso pour gérer les abonnements à mes services auto-hébergés (Jellyfin, Cloud, Vault, Mail, Git…) avec SSO, tickets et workflow d'accès.",
|
|
stack: ["Nuxt 3", "NestJS 11", "TypeORM", "MariaDB", "JWT", "Nodemailer"],
|
|
status: "live",
|
|
},
|
|
];
|
|
|
|
export const projectsOther: Project[] = [
|
|
{
|
|
id: "arboretum",
|
|
title: "Arboretum",
|
|
subtitle: "Pilotage de worktrees git + agents IA",
|
|
desc:
|
|
"Outil open-source : dashboard web pour piloter des worktrees git et des sessions d'agents IA. Lancé en npx, propulsé par un daemon Node.",
|
|
stack: ["Node.js", "Vue 3", "TypeScript", "npx"],
|
|
status: "oss",
|
|
link: "https://github.com/JohanLeroy",
|
|
},
|
|
{
|
|
id: "ksauce",
|
|
title: "Bot Discord KSauce",
|
|
subtitle: "Bot communautaire Discord",
|
|
desc:
|
|
"Bot Discord pour la communauté KSauce : commandes, modération et fonctionnalités sur-mesure.",
|
|
stack: ["Node.js", "TypeScript", "Discord.js"],
|
|
status: "live",
|
|
},
|
|
{
|
|
id: "lplv",
|
|
title: "Liberty Pour La Vie",
|
|
subtitle: "Site associatif",
|
|
desc: "Site web complet pour l'association Liberty Pour La Vie. Projet désormais fermé.",
|
|
stack: ["Java", "Spring Boot", "Thymeleaf", "Bootstrap", "MariaDB"],
|
|
status: "archived",
|
|
img: "/images/projets/lplv.png",
|
|
},
|
|
{
|
|
id: "mvg",
|
|
title: "Mon Voisin Geek",
|
|
subtitle: "Site vitrine",
|
|
desc: "Site vitrine simple pour Mon Voisin Geek. Projet désormais fermé.",
|
|
stack: ["Angular", "Tailwind CSS", "Express.js", "MariaDB"],
|
|
status: "archived",
|
|
img: "/images/projets/monvoisingeek.png",
|
|
},
|
|
];
|
|
|
|
export const experiences: Experience[] = [
|
|
{
|
|
company: "Almeria",
|
|
logo: "/images/entreprises/almeria.png",
|
|
role: "Développeur",
|
|
period: "Depuis 2023",
|
|
duration: "3 ans",
|
|
desc: "Conception et développement d'applications web et de logiciels d'intégration ERP.",
|
|
missions: [
|
|
"Analyse, conception & développement d'applications web",
|
|
"Création de logiciels d'intégration ERP",
|
|
"Maintenance & évolution des solutions",
|
|
],
|
|
stack: ["Angular", "Express.js", "NestJS", "SQL Server", "MariaDB"],
|
|
current: true,
|
|
},
|
|
{
|
|
company: "CEREMA",
|
|
logo: "/images/entreprises/cerema.png",
|
|
role: "Technicien évaluation — mesure trafic & mobilité",
|
|
period: "2021 — 2023",
|
|
duration: "2 ans",
|
|
desc: "Installation de capteurs et analyse de données de mobilité.",
|
|
missions: [
|
|
"Pose de capteurs provisoires (mobilité)",
|
|
"Optimisation des données et outils numériques",
|
|
"Analyse du trafic & de la mobilité",
|
|
],
|
|
stack: ["Analyse de données", "PHP", "MariaDB"],
|
|
},
|
|
{
|
|
company: "Réseau SNCF",
|
|
logo: "/images/entreprises/sncf.png",
|
|
role: "Agent télécom",
|
|
period: "2019 — 2021",
|
|
duration: "2 ans",
|
|
desc:
|
|
"Maintenance des équipements de sonorisation, d'affichage et de téléphonie sur le réseau ferroviaire.",
|
|
missions: [
|
|
"Maintenance préventive & corrective",
|
|
"Affichage dynamique en gare",
|
|
"Téléphonie sur les voies",
|
|
],
|
|
stack: ["Télécoms", "Maintenance", "Audio", "Affichage"],
|
|
},
|
|
{
|
|
company: "Novoferm",
|
|
logo: "/images/entreprises/novoferm.png",
|
|
role: "Stage développeur",
|
|
period: "2019",
|
|
duration: "7 semaines",
|
|
desc:
|
|
"Application web de récupération de fichiers SharePoint ; réparation et configuration de postes, imprimantes et téléphones.",
|
|
missions: [],
|
|
stack: [],
|
|
},
|
|
{
|
|
company: "Pivot Point",
|
|
logo: "/images/entreprises/pivotpoint.png",
|
|
role: "Stage développeur",
|
|
period: "2018",
|
|
duration: "1 semaine",
|
|
desc: "Développement d'un site internet en PHP.",
|
|
missions: [],
|
|
stack: ["PHP"],
|
|
},
|
|
{
|
|
company: "Actemium",
|
|
logo: "/images/entreprises/actemium.png",
|
|
role: "Stage développeur",
|
|
period: "2018",
|
|
duration: "1 semaine",
|
|
desc: "Développement d'applications Windows d'automatisation.",
|
|
missions: [],
|
|
stack: [],
|
|
},
|
|
];
|
|
|
|
export const formation: Formation[] = [
|
|
{
|
|
title: "Concepteur Développeur d'Applications",
|
|
school: "Campus ENI — Nantes",
|
|
period: "Depuis 2023",
|
|
desc: "Conception & dév d'applications web/mobiles, architecture logicielle, gestion de projet.",
|
|
},
|
|
{
|
|
title: "BTS Systèmes Numériques",
|
|
school: "Saint Félix La Salle — Nantes",
|
|
period: "2021 — 2023",
|
|
desc: "Systèmes électroniques & informatiques, informatique industrielle & réseaux.",
|
|
},
|
|
{
|
|
title: "BAC PRO Systèmes Numériques",
|
|
school: "Saint Félix La Salle — Nantes",
|
|
period: "2018 — 2021",
|
|
desc: "Systèmes électroniques & réseaux, installation & maintenance.",
|
|
},
|
|
{
|
|
title: "Diplôme National du Brevet",
|
|
school: "Saint Père en Retz",
|
|
period: "avant 2018",
|
|
},
|
|
];
|
|
|
|
export const stackMain: StackGroup[] = [
|
|
{ label: "Langages", items: ["TypeScript", "JavaScript", "Java", "Python", "PHP"] },
|
|
{ label: "Frameworks", items: ["NestJS", "Nuxt", "Next.js", "Vue.js", "Angular", "Tailwind CSS", "Astro"] },
|
|
{ label: "Bases de données", items: ["MariaDB", "MySQL", "PostgreSQL", "Redis"] },
|
|
{ label: "Outils & DevOps", items: ["Docker", "Git", "AWS", "Terraform", "NGINX", "Plesk"] },
|
|
{ label: "IDE & Éditeurs", items: ["WebStorm", "PhpStorm", "PyCharm", "Claude Code"] },
|
|
{ label: "Systèmes", items: ["Debian", "Ubuntu", "macOS"] },
|
|
];
|
|
|
|
export const stackSecondary: StackGroup[] = [
|
|
{ label: "Langages", items: ["C#", "C++", "Dart", "Kotlin"] },
|
|
{ label: "Frameworks & libs", items: ["Spring", "Symfony", "Express.js", "FastAPI", "Flutter", "GraphQL", "Vuetify", "Bootstrap"] },
|
|
{ label: "Bases de données", items: ["MongoDB", "SQLite"] },
|
|
{ label: "Services & outils", items: ["Firebase", "Swagger", "Postman", "Stripe"] },
|
|
];
|
|
|
|
export const softTech = [
|
|
"Dév. Frontend",
|
|
"Dév. Backend",
|
|
"Analyse & traitement de données",
|
|
"Mise en production",
|
|
"Analyse de BDD",
|
|
"Modélisation UML",
|
|
"Maquettage",
|
|
"Sécurité",
|
|
];
|
|
|
|
export const softHuman = [
|
|
"Gestion de projet",
|
|
"Travail en équipe",
|
|
"Communication",
|
|
"Autonomie",
|
|
"Organisation",
|
|
"Adaptation",
|
|
"Veille techno",
|
|
];
|
|
|
|
export const interests: Interest[] = [
|
|
{ name: "Jeux vidéo", note: "// détente", icon: "gamepad" },
|
|
{ name: "Films & Séries", note: "// veille culture", icon: "film" },
|
|
{ name: "Musique électronique / DJing", note: "// loisir", icon: "music" },
|
|
{ name: "Projets personnels", note: "// always building", icon: "code" },
|
|
];
|
|
|
|
/* Texte tapé dans le mockup terminal du hero (état final = contenu no-JS). */
|
|
export const terminalText = `$ whoami
|
|
johan-leroy
|
|
$ cat about.json
|
|
{
|
|
"name": "Johan Leroy",
|
|
"role": "Développeur fullstack",
|
|
"stack": ["TypeScript", "NestJS", "Nuxt", "Next.js"],
|
|
"location": "Nantes, France",
|
|
"status": "ouvert aux opportunités"
|
|
}`;
|