95 lines
4 KiB
Text
95 lines
4 KiB
Text
|
|
---
|
||
|
|
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>
|