jalil.arfaoui.net/src/pages/ar/برمجة/مسار.astro
Jalil Arfaoui a3732887f5 Restructuration section Code en sous-pages avec collections de contenu
Remplacement de la page unique /code par un hub avec 4 sous-pages :
parcours, projets, compétences, recommandations (FR/EN/AR).

Les données statiques (experiences.json, projects.json) sont remplacées
par des collections Astro (experiences, projects, recommendations) avec
support trilingue. Les recommandations sont les vrais textes LinkedIn.

Le design utilise du glassmorphism sur fond violet avec des composants
dédiés (NavigationCard, ProjectCard, RecommendationCard, SkillBadge...).
Le CSS facet est scopé proprement pour ne plus casser les composants.
2026-02-22 01:30:06 +01:00

94 lines
4.1 KiB
Text

---
import { getCollection, render } from "astro:content";
import Layout from "../../../layouts/main.astro";
const locale = "ar";
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('ar-SA', { year: 'numeric', month: 'short' });
}
---
<Layout
title="المسار المهني - جليل عرفاوي"
facet="code"
description="المسار المهني لجليل عرفاوي: أكثر من 20 سنة من الخبرة في تطوير البرمجيات، من مطوّر مبتدئ إلى مطوّر رئيسي ومدير تقني."
>
<section dir="rtl" lang="ar" class="relative z-20 max-w-3xl mx-auto my-12 px-7 lg:px-0">
<div class="mb-10">
<a href="/ar/برمجة" 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="M9 5l7 7-7 7" />
</svg>
</a>
<h1 class="text-3xl sm:text-4xl font-bold text-white">المسار</h1>
<p class="mt-3 text-white/60 text-lg">أكثر من 20 سنة من الخبرة في تطوير البرمجيات.</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) : 'الحاضر';
return (
<div class="relative pr-8 pb-10 border-r-2 border-white/[0.1] last:pb-0">
<div
class:list={[
"absolute -right-[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>