jalil.arfaoui.net/src/pages/ar/برمجة/index.astro

208 lines
11 KiB
Text
Raw Normal View History

---
import { getCollection } from "astro:content";
import { getLocalizedCollection } from "../../../utils/content-i18n";
import { Image } from "astro:assets";
import Layout from "../../../layouts/main.astro";
import Link from "../../../components/Link.astro";
import FeaturedRecommendation from "../../../components/code/FeaturedRecommendation.astro";
import ProjectCard from "../../../components/code/ProjectCard.astro";
import ValueItem from "../../../components/code/ValueItem.astro";
import LinkedInIcon from "../../../components/icons/LinkedInIcon.astro";
import MaltIcon from "../../../components/icons/MaltIcon.astro";
import StackOverflowIcon from "../../../components/icons/StackOverflowIcon.astro";
import GitHubIcon from "../../../components/icons/GitHubIcon.astro";
import ForgejoIcon from "../../../components/icons/ForgejoIcon.astro";
import { getProjectBaseSlug, getProjectsBasePath } from "../../../utils/i18n";
import logoTiqa from "../../../assets/images/logo-tiqa-blanc.png";
const locale = "ar";
const projectsBasePath = getProjectsBasePath(locale);
const experiences = (await getLocalizedCollection("experiences", locale))
.filter((e) => !e.data.draft)
.sort((a, b) => {
const endA = a.data.endDate ?? '9999-12';
const endB = b.data.endDate ?? '9999-12';
if (endA !== endB) return endB > endA ? 1 : -1;
return b.data.startDate > a.data.startDate ? 1 : -1;
});
const recentExperiences = experiences.filter((e) => e.data.featured).slice(0, 4);
const projects = (await getLocalizedCollection("projects", locale))
.filter((p) => !p.data.draft && p.data.category === "dev" && p.data.featured)
.sort((a, b) => b.data.date!.getTime() - a.data.date!.getTime());
const recommendations = (await getCollection("recommendations"))
.filter((r) => r.data.featured)
.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
const recommendationTexts = recommendations.map((rec) => ({
...rec,
text: rec.body || '',
}));
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="المسار المهني لجليل عرفاوي: مطوّر مستقل متخصص في Software Craftsmanship، TDD، DDD. TypeScript، PHP، Elixir."
>
<section dir="rtl" lang="ar" class="relative z-20 max-w-3xl mx-auto my-16 px-7 lg:px-0">
<div class="mb-16">
<span class="inline-block px-3 py-1 text-sm text-purple-200/80 bg-white/[0.06] border border-white/[0.08] rounded-full mb-5">مطوّر مستقل · ألبي</span>
<h1 class="text-5xl sm:text-6xl font-semibold text-white font-display tracking-wide">حِرَفيّ البرمجيات</h1>
<div class="mt-6 mb-6 w-16 h-0.5 bg-gradient-to-l from-purple-400 to-transparent rounded-full"></div>
<div class="space-y-4 text-lg text-white/60 leading-relaxed max-w-2xl">
<p>
TDD، Clean Code، Domain-Driven Design: هذه طريقتي في بناء البرمجيات. أرافق الفرق كمطوّر أول، أو قائد تقني، أو مدرب تقني. أدواتي: TypeScript/JavaScript، وكذلك PHP وElixir.
</p>
<p>
ما يميّزني ربّما: أهتمّ بجودة الكود بقدر اهتمامي بما ينتجه. أفضّل البرمجيات الحرّة والأدوات التي تلبّي احتياجات حقيقية. أتساءل أيضًا عن التحيّزات التي ندرجها في الكود، والتي تُديم علاقات اجتماعية تستحقّ المساءلة.
</p>
<p>
أُدرّس البرمجة في <Link href="https://www.univ-jfc.fr/" external>جامعة شامبوليون</Link> وأنشّط مجتمع <Link href="https://www.meetup.com/software-crafters-albi/" external>Software Crafters Albi</Link> منذ 2018.
</p>
</div>
</div>
<div class="mb-20 -mx-7 px-7 py-8 bg-white/[0.03] rounded-2xl">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-white ">المسار</h2>
<a href="/ar/برمجة/مسار" class="text-sm text-purple-200 hover:text-white transition-colors">&larr; عرض الكل</a>
</div>
<div class="relative mr-3">
<div class="absolute right-0 top-1.5 bottom-1.5 w-px bg-purple-300/20"></div>
{recentExperiences.map((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-7 pb-6 last:pb-0">
<div class:list={[
"absolute right-0 top-1.5 w-2.5 h-2.5 rounded-full translate-x-1/2 border-2",
isOngoing
? "bg-purple-400 border-purple-400/50 shadow-[0_0_8px_rgba(168,85,247,0.4)]"
: "bg-transparent border-purple-300/30"
]} />
{isOngoing && (
<div class="absolute right-0 top-1.5 w-2.5 h-2.5 rounded-full translate-x-1/2 bg-purple-400/50 animate-ping" />
)}
<span class:list={[isOngoing ? "text-purple-200" : "text-white/55"]}>
{start} — {end}
</span>
<p class="font-semibold text-white text-lg mt-0.5">{exp.data.role}</p>
<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 class="relative pr-7 pt-2 flex items-center gap-3">
<span class="text-purple-300/40 tracking-[0.3em]">...</span>
<a href="/ar/برمجة/مسار" class="text-purple-200 hover:text-white transition-colors">
عرض المسار الكامل &larr;
</a>
</div>
</div>
</div>
<div class="mb-20 -mx-7 px-7 py-8 bg-white/[0.03] rounded-2xl">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-white ">المشاريع</h2>
<a href="/ar/برمجة/مشاريع" class="text-sm text-purple-200 hover:text-white transition-colors">&larr; عرض الكل</a>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
{projects.map((project) => (
<ProjectCard
title={project.data.title}
description={project.data.description}
technologies={project.data.technologies}
featured={project.data.featured}
detailUrl={`${projectsBasePath}/${getProjectBaseSlug(project.id)}`}
lang={locale}
/>
))}
</div>
</div>
{recommendationTexts.length > 0 && (
<div class="mb-20">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-white ">التوصيات</h2>
<a href="/ar/برمجة/توصيات" class="text-sm text-purple-200 hover:text-white transition-colors">&larr; عرض الكل</a>
</div>
<div class="space-y-5">
{recommendationTexts.map((rec) => (
<FeaturedRecommendation
author={rec.data.author}
authorRole={rec.data.authorRole}
company={rec.data.company}
text={rec.text}
avatar={rec.data.avatar}
url={rec.data.url}
/>
))}
</div>
</div>
)}
<div class="mb-20">
<h2 class="text-2xl font-bold text-white mb-6">القيم والمنهج</h2>
<ul class="space-y-4 text-white/80">
<ValueItem>حركة <Link href="http://manifesto.softwarecraftsmanship.org/#/fr-fr" external>Software Craftsmanship</Link></ValueItem>
<ValueItem>الفائدة الاجتماعية للمطوّر</ValueItem>
<ValueItem>الفخر بالعمل، دون غرور</ValueItem>
<ValueItem>منهج <strong class="text-white">Domain Driven Design</strong></ValueItem>
<ValueItem>تنظيم <Link href="https://agilemanifesto.org/iso/fr/manifesto.html" external>أجايل</Link>: التكرار والتحسين المستمر</ValueItem>
</ul>
</div>
<div class="mb-20">
<h2 class="text-2xl font-bold text-white mb-6">المجتمع والتدريس</h2>
<p class="text-white/60 leading-relaxed">
أنشّط مجتمع <Link href="https://www.meetup.com/software-crafters-albi/" external>Software Crafters Albi</Link> منذ 2018. أستاذ هندسة البرمجيات في <Link href="https://www.univ-jfc.fr/" external>جامعة شامبوليون</Link> في ألبي منذ 2019.
</p>
</div>
<div class="mb-20">
<h2 class="text-2xl font-bold text-white mb-6">على الإنترنت</h2>
<div class="flex flex-wrap gap-x-6 gap-y-3">
<a href="https://www.linkedin.com/in/jalil" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 text-white/50 hover:text-white transition-colors">
<LinkedInIcon size={18} /> LinkedIn
</a>
<a href="https://www.malt.fr/profile/jalilarfaoui" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 text-white/50 hover:text-white transition-colors">
<MaltIcon size={18} /> Malt
</a>
<a href="https://stackexchange.com/users/54164/jalil" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 text-white/50 hover:text-white transition-colors">
<StackOverflowIcon size={18} /> Stack Overflow
</a>
<a href="https://github.com/JalilArfaoui" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 text-white/50 hover:text-white transition-colors">
<GitHubIcon size={18} /> GitHub
</a>
<a href="https://forge.tiqa.fr" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-2 text-white/50 hover:text-white transition-colors">
<ForgejoIcon size={18} /> Forge شخصية
</a>
</div>
</div>
<div class="text-center pt-10 border-t border-white/[0.06]">
<Image src={logoTiqa} alt="شعار Tiqa" class="mx-auto mb-4" width={160} />
<p class="text-sm text-white/30">
<strong class="text-white/45">SAS Tiqa</strong><br />
12, rue Fabre d'Églantine — 81 000 Albi, France<br />
811 917 871 RCS Albi
</p>
</div>
</section>
</Layout>