feat(parcours): intégration des sections de la page Parcours conforme à Figma
- Prise en charge du thème sombre du Header sur la route /parcours - Ajout de la section Hero et présentation des chiffres clés - Grille des profils 'Qui peut rejoindre' avec méthode map() et icônes - Intégration de la timeline verticale des étapes d'intégration - Ajout du bandeau 'Learning by Doing' - Restructuration des composants par dossier
This commit is contained in:
180
assets/components/home/Impact.jsx
Normal file
180
assets/components/home/Impact.jsx
Normal file
@ -0,0 +1,180 @@
|
||||
// 1. IMPORTATIONS DES MODULES ET ASSETS
|
||||
import React, { useState } from 'react';
|
||||
|
||||
// Webpack Encore gère l'empreinte de hachage (hash) et le chemin public de l'image de fond
|
||||
import impactBg from '../../img/impact.png';
|
||||
|
||||
/**
|
||||
* 2. STRUCTURE DE DONNÉES STATIQUE : DIAPOSITIVES DU CARROUSEL
|
||||
* Externaliser les données hors du composant évite de recréer ce tableau
|
||||
* en mémoire à chaque nouveau cycle de rendu (re-render) du composant.
|
||||
*
|
||||
* Le tableau est structuré sous forme de tableau de diapositives (slides).
|
||||
* SLIDES[0] contient le groupe actif affiché à l'écran.
|
||||
*/
|
||||
const SLIDES = [
|
||||
[
|
||||
{
|
||||
value: '3000 +',
|
||||
label: 'personnes accompagnées',
|
||||
size: 'w-16 h-16 sm:w-20 sm:h-20', // Taille standard des pastilles latérales
|
||||
},
|
||||
{
|
||||
value: '94% - 97%',
|
||||
label: 'de réussites en insertion',
|
||||
size: 'w-24 h-24 sm:w-28 sm:h-28', // Pastille centrale plus imposante pour créer une hiérarchie visuelle
|
||||
},
|
||||
{
|
||||
value: '20 ANS',
|
||||
label: 'de recherches appliquées',
|
||||
size: 'w-16 h-16 sm:w-20 sm:h-20', // Taille standard
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* 3. COMPOSANT PRINCIPAL : Impact
|
||||
* Présente la section "NOTRE IMPACT" avec :
|
||||
* - Un arrière-plan immersif en pleine largeur
|
||||
* - 3 indicateurs chiffrés majeurs avec pastilles colorées
|
||||
* - Des contrôles de carrousel (flèches gauche/droite et indicateurs à points)
|
||||
*/
|
||||
export default function Impact() {
|
||||
/**
|
||||
* ÉTAT LOCAL (State) : Indice du point actif de pagination
|
||||
* Initialisé à 2 pour correspondre au point central parmi les 5 points du design Figma.
|
||||
*/
|
||||
const [currentSlide, setCurrentSlide] = useState(2);
|
||||
|
||||
return (
|
||||
/*
|
||||
Balise sémantique <section> :
|
||||
- relative : point d'ancrage pour positionner l'overlay sombre absolu
|
||||
- w-full : occupe toute la largeur de l'écran (full bleed)
|
||||
- py-24 sm:py-32 : padding vertical généreux pour donner de l'espace à la section
|
||||
- px-6 sm:px-12 : padding horizontal adaptatif
|
||||
- bg-cover bg-center : l'image remplit tout l'arrière-plan sans déformation et reste centrée
|
||||
- overflow-hidden : empêche tout débordement lié aux animations de zoom
|
||||
*/
|
||||
<section
|
||||
className="relative w-full py-24 sm:py-32 px-6 sm:px-12 bg-cover bg-center overflow-hidden"
|
||||
style={{ backgroundImage: `url("${impactBg}")` }}
|
||||
>
|
||||
{/*
|
||||
CALQUE D'OVERLAY SOMBRE :
|
||||
- absolute inset-0 : couvre 100% de la surface de la section
|
||||
- bg-black/40 : voile noir à 40% d'opacité pour garantir la lisibilité des textes blancs
|
||||
- pointer-events-none : empêche ce filtre de capturer les clics
|
||||
*/}
|
||||
<div className="absolute inset-0 bg-black/40 pointer-events-none" />
|
||||
|
||||
{/*
|
||||
CONTENEUR DE CONTENU :
|
||||
- relative z-10 : positionne le contenu au-dessus du voile sombre
|
||||
- max-w-[1400px] mx-auto : largeur maximale cadrée et centrée
|
||||
- text-center text-white : typographie blanche centrée par défaut
|
||||
*/}
|
||||
<div className="relative z-10 max-w-[1400px] mx-auto text-center text-white">
|
||||
|
||||
{/* ====================================================================
|
||||
A. EN-TÊTE : SURTITRE & TITRE PRINCIPAL
|
||||
==================================================================== */}
|
||||
{/* Surtitre en majuscules avec espacement étendu (tracking-wide) */}
|
||||
<span className="text-xs sm:text-sm font-bold tracking-[0.25em] uppercase text-white/90 block mb-2">
|
||||
NOTRE IMPACT
|
||||
</span>
|
||||
|
||||
{/* Titre descriptif sobre avec marge basse importante avant les chiffres */}
|
||||
<h2 className="text-lg sm:text-xl font-normal text-white/95 mb-16 sm:mb-20">
|
||||
Des résultats concrets et durables
|
||||
</h2>
|
||||
|
||||
{/* ====================================================================
|
||||
B. ZONE CENTRALE : FLÈCHE GAUCHE + 3 MÉTRIQUES + FLÈCHE DROITE
|
||||
- flex items-center justify-between : alignement horizontal sur une seule ligne
|
||||
==================================================================== */}
|
||||
<div className="flex items-center justify-between gap-4 sm:gap-8">
|
||||
|
||||
{/* Bouton de navigation gauche (Précédent) */}
|
||||
<button
|
||||
type="button"
|
||||
className="w-10 h-10 sm:w-12 sm:h-12 rounded-full border border-white/60 flex items-center justify-center text-white hover:bg-white/20 transition-colors shrink-0"
|
||||
aria-label="Précédent"
|
||||
>
|
||||
{/* Icône flèche retour */}
|
||||
<svg className="w-5 h-5 sm:w-6 sm:h-6" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/*
|
||||
Grille des 3 métriques chiffrées :
|
||||
- 1 colonne sur mobile (grid-cols-1)
|
||||
- 3 colonnes à partir des écrans moyens (md:grid-cols-3)
|
||||
- items-end : aligne les éléments par le bas pour absorber la différence de taille du cercle central
|
||||
- flex-1 max-w-4xl mx-auto : occupe l'espace central disponible de façon équilibrée
|
||||
*/}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-10 md:gap-8 flex-1 items-end max-w-4xl mx-auto">
|
||||
{SLIDES[0].map((item, index) => (
|
||||
<div key={index} className="flex flex-col items-center">
|
||||
{/*
|
||||
Pastille ronde vert olive (#9da74d) :
|
||||
- Taille dynamique issue de la donnée (item.size)
|
||||
- shadow-[...] : ombre portée sombre accentuant la profondeur
|
||||
- hover:scale-105 : micro-interaction au survol
|
||||
*/}
|
||||
<div
|
||||
className={`${item.size} rounded-full bg-[#9da74d] mb-6 shadow-[0_4px_16px_rgba(0,0,0,0.35)] transition-transform duration-300 hover:scale-105`}
|
||||
/>
|
||||
|
||||
{/* Valeur numérique mise en avant (ex: 3000 +, 94% - 97%) */}
|
||||
<span className="text-3xl sm:text-4xl md:text-5xl font-normal tracking-tight text-white mb-2">
|
||||
{item.value}
|
||||
</span>
|
||||
|
||||
{/* Libellé descriptif sous le chiffre */}
|
||||
<span className="text-xs sm:text-sm font-light text-white/85 max-w-[200px]">
|
||||
{item.label}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Bouton de navigation droit (Suivant) */}
|
||||
<button
|
||||
type="button"
|
||||
className="w-10 h-10 sm:w-12 sm:h-12 rounded-full border border-white/60 flex items-center justify-center text-white hover:bg-white/20 transition-colors shrink-0"
|
||||
aria-label="Suivant"
|
||||
>
|
||||
{/* Icône flèche suivant */}
|
||||
<svg className="w-5 h-5 sm:w-6 sm:h-6" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* ====================================================================
|
||||
C. INDICATEURS DE PAGINATION (CAROUSEL DOTS)
|
||||
- 5 points horizontaux centrés en bas de section
|
||||
==================================================================== */}
|
||||
<div className="flex justify-center items-center gap-2 mt-16 sm:mt-20">
|
||||
{[0, 1, 2, 3, 4].map((dot) => (
|
||||
<span
|
||||
key={dot}
|
||||
/*
|
||||
Style dynamique du point :
|
||||
- Si c'est le point actif (dot === currentSlide) : couleur vert olive (#a3ad53) et taille augmentée (scale-125)
|
||||
- Sinon : blanc translucide (bg-white/50)
|
||||
*/
|
||||
className={`w-2.5 h-2.5 rounded-full transition-all duration-200 ${dot === currentSlide
|
||||
? 'bg-[#a3ad53] scale-125'
|
||||
: 'bg-white/50'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user