jalil.arfaoui.net/src/pages/code/parcours.astro

95 lines
4 KiB
Text
Raw Normal View History

---
import { getCollection, render } from "astro:content";
import Layout from "../../layouts/main.astro";
const locale = "fr";
const experiences = (await getCollection("experiences"))
.filter((e) => e.data.lang === locale && !e.data.draft)
.sort((a, b) => (b.data.startDate > a.data.startDate ? 1 : -1));
const typeIcons: Record<string, string> = {
employment: '🏢', freelance: '💼', teaching: '🎓',
community: '🤝', entrepreneurship: '🚀',
};
function formatMonth(dateStr: string) {
const [year, month] = dateStr.split('-');
return new Date(parseInt(year), parseInt(month) - 1)
.toLocaleDateString('fr-FR', { year: 'numeric', month: 'short' });
}
---
<Layout
title="Parcours - Jalil Arfaoui"
facet="code"
description="Parcours professionnel de Jalil Arfaoui : plus de 20 ans d'expérience en développement logiciel, de développeur junior à lead developer et CTO."
>
<section class="relative z-20 max-w-3xl mx-auto my-12 px-7 lg:px-0">
<div class="mb-10">
<a href="/code" class="inline-flex items-center gap-1.5 text-sm text-white/50 hover:text-white/80 transition-colors mb-6 group">
<svg class="w-4 h-4 group-hover:-translate-x-0.5 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
</svg>
Code
</a>
<h1 class="text-3xl sm:text-4xl font-bold text-white">Parcours</h1>
<p class="mt-3 text-white/60 text-lg">Plus de 20 ans d'expérience en développement logiciel.</p>
</div>
<div class="mt-10">
{experiences.map(async (exp) => {
const { Content } = await render(exp);
const isOngoing = !exp.data.endDate;
const start = formatMonth(exp.data.startDate);
const end = exp.data.endDate ? formatMonth(exp.data.endDate) : 'Présent';
return (
<div class="relative pl-8 pb-10 border-l-2 border-white/[0.1] last:pb-0">
<div
class:list={[
"absolute -left-[9px] top-1 w-4 h-4 rounded-full border-2",
isOngoing
? "border-purple-300 bg-purple-400"
: "border-white/20 bg-white/10"
]}
>
{isOngoing && <div class="absolute inset-0.5 rounded-full bg-purple-300 animate-pulse" />}
</div>
<div class="facet-card rounded-2xl bg-white/[0.04] border border-white/[0.08] p-5 hover:bg-white/[0.08] transition-colors duration-200">
<div class="mb-2 flex items-center gap-2 flex-wrap">
<span class="text-xs text-white/40">
{typeIcons[exp.data.type] || '💼'} {start} — {end}
</span>
{exp.data.location && <span class="text-xs text-white/30">· {exp.data.location}</span>}
</div>
<h3 class="text-lg font-bold text-white">{exp.data.role}</h3>
<p class="text-sm font-medium text-purple-200 mb-3">
{exp.data.companyUrl ? (
<a href={exp.data.companyUrl} target="_blank" rel="noopener noreferrer" class="hover:text-white transition-colors">{exp.data.company}</a>
) : exp.data.company}
</p>
<div class="text-sm text-white/60 leading-relaxed mb-3 prose prose-sm prose-invert max-w-none [&_p]:text-white/60 [&_a]:text-purple-200 [&_a:hover]:text-white">
<Content />
</div>
{exp.data.technologies && exp.data.technologies.length > 0 && (
<div class="flex flex-wrap gap-1.5">
{exp.data.technologies.map((tech: string) => (
<span class="inline-block px-2 py-0.5 text-xs rounded-full bg-white/[0.06] text-white/50 border border-white/[0.06]">
{tech}
</span>
))}
</div>
)}
</div>
</div>
);
})}
</div>
</section>
</Layout>