feat(parcours): intégration des sections parcours, compétences et référents

- Intégration de la timeline en 7 étapes conforme à la maquette Figma
- Ajout du composant modèle de développement des compétences (paliers 01 à 03)
- Ajout de la section d'accompagnement des référents avec visuel d'équipe
- Ajustements responsive mobiles et desktop
This commit is contained in:
MohamedLoum1001
2026-10-05 11:23:05 +02:00
parent bb1393e9ef
commit c94227c534
16 changed files with 352 additions and 58 deletions

View File

@ -1,7 +1,7 @@
import React from 'react';
// Imports des 7 images (vérifie bien tes extensions .png ou .png)
import decouvertImg from '../../img/decouvert.png';
// Imports exacts des images exportées de Figma
import decouverteImg from '../../img/decouverte.png';
import preProfilImg from '../../img/pre-profil.png';
import entretienImg from '../../img/entretien.png';
import constructionImg from '../../img/construction.png';
@ -15,7 +15,7 @@ const STEPS = [
title: 'Étape 1 — Découverte',
intro:
'Vous découvrez les projets, les équipes, les trajectoires et les opportunités proposées par gaea21.',
image: decouvertImg,
image: decouverteImg,
},
{
step: 2,
@ -39,11 +39,13 @@ const STEPS = [
step: 3,
title: 'Étape 3 — Entretien',
intro:
'Un entretien permet d’approfondir votre démarche et d’identifier les opportunités les plus adaptées :',
'Un entretien permet d’approfondir votre profil et d’identifier les opportunités les plus pertinentes.',
subIntro: 'Nous cherchons à comprendre :',
bullets: [
'vos compétences à mobiliser ;',
'les projets correspondant à votre profil ;',
'ce que vous souhaitez développer.',
'où vous en êtes ;',
'où vous souhaitez aller ;',
'ce que vous souhaitez développer ;',
'ce qui pourrait accélérer votre évolution.',
],
image: entretienImg,
},
@ -51,52 +53,49 @@ const STEPS = [
step: 4,
title: 'Étape 4 — Construction de la trajectoire',
intro:
'À partir des informations recueillies, nous définissons :',
'À partir des informations recueillies, nous identifions :',
bullets: [
'vos objectifs d’apprentissage ;',
'la trajectoire la plus adaptée ;',
'les projets pertinents ;',
'les compétences à développer ;',
'votre rôle dans les projets gaea21 ;',
'la durée et le rythme de votre parcours.',
'les ressources à mobiliser ;',
'les accompagnements nécessaires.',
],
conclusion:
'Cette étape permet de construire une feuille de route sur mesure.',
'Chaque personne suit un parcours unique.',
image: constructionImg,
},
{
step: 5,
title: 'Étape 5 — Intégration dans les projets',
intro:
'Vous intégrez un ou plusieurs projets réels :',
bullets: [
'accompagné(e) par des tuteurs et experts ;',
'au sein d’une équipe pluridisciplinaire ;',
'avec des livrables concrets à réaliser.',
paragraphs: [
'Vous rejoignez une ou plusieurs équipes projet.',
'Vous participez progressivement à des réunions et des livrables.',
'Vous développez des compétences en contribuant à des projets concrets.',
],
image: integrationImg,
},
{
step: 6,
title: 'Étape 6 — Développement des compétences',
intro:
'Vous montez en compétences à travers la pratique :',
bullets: [
'ateliers, méthodologies et outils gaea21 ;',
'développement de compétences transversales et techniques ;',
'suivi personnalisé et feedback régulier.',
paragraphs: [
'Les projets deviennent des espaces d’apprentissage continu.',
'L’expérience devient un outil de progression.',
'Les responsabilités évoluent progressivement selon votre développement.',
],
image: developpementImg,
},
{
step: 7,
title: 'Étape 7 — Évolution et opportunités',
title: 'Étape 7 — Évolution',
intro:
'À la fin de votre parcours :',
'L’objectif n’est pas simplement de participer à un projet.',
subIntro: 'L’objectif est de développer :',
bullets: [
'bilan des compétences acquises ;',
'attestation de parcours gaea21 ;',
'recommandation professionnelle ;',
'opportunités de mandats internes ou externes ;',
'accès au réseau Alumni gaea21.',
'une expérience démontrable ;',
'des compétences transférables ;',
'un réseau actif et engagé ;',
'des perspectives professionnelles claires.',
],
image: evolutionImg,
},
@ -104,75 +103,172 @@ const STEPS = [
export default function ParcoursIntegration() {
return (
<section className="w-full bg-[#fbfbf9] text-[#1e293b] py-14 lg:py-20 px-6 md:px-12 font-sans">
<section className="w-full bg-[#fbfbf9] text-[#1e293b] py-10 md:py-20 px-4 sm:px-6 md:px-12 font-sans">
<div className="max-w-[1240px] mx-auto">
{/* 1. Le trait vert horizontal au-dessus du titre (identique à Figma) */}
<div className="w-12 h-1 bg-[#475734] rounded-full mb-6" />
{/* Trait de repère vert horizontal */}
<div className="w-12 h-1 bg-[#475734] rounded-full mb-4 md:mb-6" />
{/* 2. Titre de section */}
<h2 className="text-base sm:text-lg lg:text-xl font-extrabold uppercase tracking-tight text-[#111827] mb-14 text-left">
{/* Titre de section */}
<h2 className="text-lg sm:text-xl md:text-2xl font-extrabold uppercase tracking-tight text-[#111827] mb-8 md:mb-16 text-left">
COMMENT FONCTIONNE LE{' '}
<span className="text-[#8c8f3e]">PARCOURS D'INTÉGRATION</span> ?
</h2>
{/* 3. Timeline */}
<div className="max-w-[940px] mx-auto lg:ml-0 flex flex-col">
{/* ========================================================================= */}
{/* 1. VERSION MOBILE (< md) : Vue empilée et lisible */}
{/* ========================================================================= */}
<div className="flex md:hidden flex-col gap-10">
{STEPS.map((item, index) => {
const isLast = index === STEPS.length - 1;
return (
<div key={item.step} className="flex items-start">
<div key={item.step} className="flex flex-col">
{/* Image mobile */}
<div className="w-full max-w-[340px] mx-auto mb-4">
<img
src={item.image}
alt={item.title}
className="w-full h-auto object-contain block"
/>
</div>
{/* Colonne GAUCHE : Illustration */}
<div className="w-[42%] flex justify-end pr-6 sm:pr-10 shrink-0">
<div className="w-40 h-28 sm:w-52 sm:h-36 flex items-center justify-end">
{/* Bloc pastille + ligne à gauche & texte à droite */}
<div className="flex items-start">
<div className="relative flex flex-col items-center shrink-0 mr-4 self-stretch">
<div className="w-9 h-9 rounded-full bg-[#8c8f3e] text-white text-sm font-bold flex items-center justify-center shadow-xs z-10 shrink-0">
{item.step}
</div>
{!isLast && (
<div className="w-[2px] bg-[#8c8f3e] flex-1 my-1" />
)}
</div>
<div className="flex-1 pb-6 text-left">
<h3 className="text-sm font-extrabold text-[#111827] mb-1.5 pt-1.5">
{item.title}
</h3>
{item.intro && (
<p className="text-xs text-[#4b5563] leading-relaxed mb-2">
{item.intro}
</p>
)}
{item.subIntro && (
<p className="text-xs text-[#4b5563] font-medium leading-relaxed mb-1">
{item.subIntro}
</p>
)}
{item.bullets && item.bullets.length > 0 && (
<ul className="space-y-1 text-xs text-[#4b5563] leading-tight mb-2">
{item.bullets.map((bullet, idx) => (
<li key={idx} className="flex items-start gap-1.5">
<span className="text-[#111827] text-xs leading-none mt-0.5">•</span>
<span>{bullet}</span>
</li>
))}
</ul>
)}
{item.paragraphs && item.paragraphs.length > 0 && (
<div className="space-y-1 text-xs text-[#4b5563] leading-relaxed">
{item.paragraphs.map((p, idx) => (
<p key={idx}>{p}</p>
))}
</div>
)}
{item.conclusion && (
<p className="text-xs text-[#4b5563] italic leading-relaxed mt-1">
{item.conclusion}
</p>
)}
</div>
</div>
</div>
);
})}
</div>
{/* ========================================================================= */}
{/* 2. VERSION DESKTOP (md et plus) : Ton affichage exact qui fonctionne */}
{/* ========================================================================= */}
<div className="hidden md:flex max-w-[1100px] mx-auto lg:ml-0 flex-col">
{STEPS.map((item, index) => {
const isLast = index === STEPS.length - 1;
return (
<div key={item.step} className="flex items-center">
{/* 1. Colonne GAUCHE */}
<div className="w-[48%] flex justify-end shrink-0">
<div className="w-full max-w-[420px] -ml-1 -mr-1 z-0">
<img
src={item.image}
alt={item.title}
className="max-h-full max-w-full object-contain"
className="w-full h-auto object-contain block select-none"
/>
</div>
</div>
{/* Colonne CENTRALE : Cercle numéroté + Ligne verticale */}
<div className="relative flex flex-col items-center shrink-0 self-stretch">
{/* Rond vert olive avec chiffre blanc (Figma) */}
<div className="w-8 h-8 rounded-full bg-[#8c8f3e] text-white text-xs sm:text-sm font-bold flex items-center justify-center shadow-xs z-10">
{/* 2. Colonne CENTRALE */}
<div className="relative flex flex-col items-center shrink-0 self-stretch justify-center z-10">
<div
className={`w-[2px] bg-[#8c8f3e] flex-1 ${index === 0 ? 'opacity-0' : ''
}`}
/>
<div className="w-10 h-10 sm:w-11 sm:h-11 rounded-full bg-[#8c8f3e] text-white text-base sm:text-lg font-bold flex items-center justify-center shadow-xs select-none shrink-0 my-1">
{item.step}
</div>
{/* Ligne verticale verte reliant chaque pastille */}
{!isLast && (
<div className="w-[2px] bg-[#8c8f3e] flex-1 my-1" />
)}
<div
className={`w-[2px] bg-[#8c8f3e] flex-1 ${isLast ? 'opacity-0' : ''
}`}
/>
</div>
{/* Colonne DROITE : Textes fidèles à Figma */}
<div className="flex-1 pl-6 sm:pl-10 pb-12 sm:pb-16 text-left">
<h3 className="text-xs sm:text-sm font-bold text-[#111827] leading-none mb-2">
{/* 3. Colonne DROITE */}
<div className="flex-1 pl-6 sm:pl-8 py-6 sm:py-8 text-left">
<h3 className="text-base sm:text-lg font-extrabold text-[#111827] leading-none mb-2">
{item.title}
</h3>
{item.intro && (
<p className="text-[11px] sm:text-xs text-[#52525b] leading-relaxed mb-2 max-w-md">
<p className="text-xs sm:text-[13px] text-[#4b5563] leading-relaxed mb-2 max-w-md">
{item.intro}
</p>
)}
{item.subIntro && (
<p className="text-xs sm:text-[13px] text-[#4b5563] font-medium leading-relaxed mb-1 max-w-md">
{item.subIntro}
</p>
)}
{item.bullets && item.bullets.length > 0 && (
<ul className="space-y-1 text-[11px] text-[#71717a] leading-tight max-w-md">
<ul className="space-y-0.5 text-xs sm:text-[13px] text-[#4b5563] leading-tight max-w-md mb-2">
{item.bullets.map((bullet, idx) => (
<li key={idx} className="flex items-start gap-1.5">
<span className="text-[#8c8f3e] text-xs leading-none mt-0.5">•</span>
<span className="text-[#111827] text-xs leading-none mt-1">•</span>
<span>{bullet}</span>
</li>
))}
</ul>
)}
{item.paragraphs && item.paragraphs.length > 0 && (
<div className="space-y-1 text-xs sm:text-[13px] text-[#4b5563] leading-relaxed max-w-md">
{item.paragraphs.map((p, idx) => (
<p key={idx}>{p}</p>
))}
</div>
)}
{item.conclusion && (
<p className="text-[11px] text-[#52525b] leading-relaxed mt-2 max-w-md">
<p className="text-xs sm:text-[13px] text-[#4b5563] italic leading-relaxed max-w-md mt-1">
{item.conclusion}
</p>
)}