Section Parcours : mini-timeline visuelle, expériences featured, lien vers parcours complet

This commit is contained in:
Jalil Arfaoui 2026-03-10 23:40:44 +01:00
parent 6d10824a92
commit 58594c37bc
7 changed files with 35 additions and 17 deletions

View file

@ -7,6 +7,7 @@ startDate: "2022-01"
endDate: "2023-01" endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"] technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance" type: "freelance"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -7,6 +7,7 @@ startDate: "2022-01"
endDate: "2023-01" endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"] technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance" type: "freelance"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -7,6 +7,7 @@ startDate: "2022-01"
endDate: "2023-01" endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"] technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance" type: "freelance"
featured: true
lang: "fr" lang: "fr"
--- ---

View file

@ -6,6 +6,7 @@ location: "ألبي"
startDate: "2019-09" startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"] technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching" type: "teaching"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -6,6 +6,7 @@ location: "Albi"
startDate: "2019-09" startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"] technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching" type: "teaching"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -6,6 +6,7 @@ location: "Albi"
startDate: "2019-09" startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"] technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching" type: "teaching"
featured: true
lang: "fr" lang: "fr"
--- ---

View file

@ -15,7 +15,7 @@ const experiences = (await getCollection("experiences"))
.filter((e) => e.data.lang === locale && !e.data.draft) .filter((e) => e.data.lang === locale && !e.data.draft)
.sort((a, b) => (b.data.startDate > a.data.startDate ? 1 : -1)); .sort((a, b) => (b.data.startDate > a.data.startDate ? 1 : -1));
const recentExperiences = experiences.slice(0, 4); const recentExperiences = experiences.filter((e) => e.data.featured).slice(0, 4);
const projects = (await getCollection("projects")) const projects = (await getCollection("projects"))
.filter((p) => p.data.lang === locale && !p.data.draft && p.data.category === "dev" && p.data.featured) .filter((p) => p.data.lang === locale && !p.data.draft && p.data.category === "dev" && p.data.featured)
@ -65,30 +65,42 @@ function formatMonth(dateStr: string) {
<h2 class="text-2xl font-bold text-white ">Parcours</h2> <h2 class="text-2xl font-bold text-white ">Parcours</h2>
<a href="/code/parcours" class="text-sm text-purple-200 hover:text-white transition-colors">Voir tout &rarr;</a> <a href="/code/parcours" class="text-sm text-purple-200 hover:text-white transition-colors">Voir tout &rarr;</a>
</div> </div>
<div class="divide-y divide-white/[0.08]"> <div class="relative ml-3">
<div class="absolute left-0 top-1.5 bottom-1.5 w-px bg-purple-300/20"></div>
{recentExperiences.map((exp) => { {recentExperiences.map((exp) => {
const isOngoing = !exp.data.endDate; const isOngoing = !exp.data.endDate;
const start = formatMonth(exp.data.startDate); const start = formatMonth(exp.data.startDate);
const end = exp.data.endDate ? formatMonth(exp.data.endDate) : 'Présent'; const end = exp.data.endDate ? formatMonth(exp.data.endDate) : 'Présent';
return ( return (
<div class="py-4 first:pt-0 last:pb-0"> <div class="relative pl-7 pb-6 last:pb-0">
<div class="flex items-start justify-between gap-4"> <div class:list={[
<div class="min-w-0"> "absolute left-0 top-1.5 w-2.5 h-2.5 rounded-full -translate-x-1/2 border-2",
<p class="font-semibold text-white text-sm">{exp.data.role}</p> isOngoing
<p class="text-sm text-white/45 mt-0.5"> ? "bg-purple-400 border-purple-400/50 shadow-[0_0_8px_rgba(168,85,247,0.4)]"
{exp.data.companyUrl ? ( : "bg-transparent border-purple-300/30"
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="text-purple-200 hover:text-white transition-colors">{exp.data.company}</a> ]} />
) : exp.data.company} {isOngoing && (
{exp.data.location && ` · ${exp.data.location}`} <div class="absolute left-0 top-1.5 w-2.5 h-2.5 rounded-full -translate-x-1/2 bg-purple-400/50 animate-ping" />
</p> )}
</div> <span class:list={[isOngoing ? "text-purple-200" : "text-white/55"]}>
<span class:list={["text-sm whitespace-nowrap flex-shrink-0", isOngoing ? "text-purple-200" : "text-white/35"]}> {start} — {end}
{start} — {end} </span>
</span> <p class="font-semibold text-white text-lg mt-0.5">{exp.data.role}</p>
</div> <p class="text-white/55 mt-0.5">
{exp.data.companyUrl ? (
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="text-purple-200 hover:text-white transition-colors">{exp.data.company}</a>
) : exp.data.company}
{exp.data.location && ` · ${exp.data.location}`}
</p>
</div> </div>
); );
})} })}
<div class="relative pl-7 pt-2 flex items-center gap-3">
<span class="text-purple-300/40 tracking-[0.3em]">...</span>
<a href="/code/parcours" class="text-purple-200 hover:text-white transition-colors">
Voir le parcours complet &rarr;
</a>
</div>
</div> </div>
</div> </div>