Compare commits
No commits in common. "6714bb62a67f9c318f0669f3319f8d02c01670f1" and "578c6733db92c4ff03a0750c93cadfdfd1516432" have entirely different histories.
6714bb62a6
...
578c6733db
12 changed files with 59 additions and 87 deletions
|
|
@ -14,35 +14,28 @@ const { title, description, technologies, featured = false, detailUrl, lang = 'f
|
|||
|
||||
const isRtl = lang === 'ar';
|
||||
const readMoreLabel = t('projects', 'readMore', lang);
|
||||
const primaryTechs = technologies?.slice(0, 3) ?? [];
|
||||
const secondaryTechs = technologies?.slice(3) ?? [];
|
||||
---
|
||||
|
||||
<a href={detailUrl} class:list={[
|
||||
"project-card group relative rounded-2xl border p-6 flex flex-col h-full transition-all duration-300 hover:scale-[1.02] no-underline overflow-hidden",
|
||||
"facet-card rounded-2xl border p-6 flex flex-col h-full transition-all duration-300 hover:scale-[1.02] no-underline",
|
||||
featured
|
||||
? "bg-white/[0.10] border-purple-300/20"
|
||||
: "bg-white/[0.05] border-white/[0.08]",
|
||||
? "bg-white/[0.12] border-purple-300/20 hover:bg-white/[0.18] hover:border-purple-300/30"
|
||||
: "bg-white/[0.06] border-white/[0.1] hover:bg-white/[0.12] hover:border-white/[0.2]",
|
||||
]}>
|
||||
<div class="mb-3">
|
||||
<h3 class="text-xl font-bold text-white">
|
||||
<div class="mb-2">
|
||||
<h3 class="text-lg font-bold text-white">
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<p class="text-white/60 leading-relaxed flex-1 mb-5">
|
||||
<p class="text-sm text-white/60 leading-relaxed flex-1 mb-4">
|
||||
{description}
|
||||
</p>
|
||||
|
||||
{(primaryTechs.length > 0 || secondaryTechs.length > 0) && (
|
||||
<div class="flex flex-wrap gap-1.5 mb-5">
|
||||
{primaryTechs.map((tech) => (
|
||||
<span class="inline-block px-2.5 py-1 text-xs font-medium rounded-full bg-purple-400/15 text-purple-200 border border-purple-300/15">
|
||||
{tech}
|
||||
</span>
|
||||
))}
|
||||
{secondaryTechs.map((tech) => (
|
||||
<span class="inline-block px-2.5 py-1 text-xs rounded-full bg-white/[0.05] text-white/40 border border-white/[0.06]">
|
||||
{technologies && technologies.length > 0 && (
|
||||
<div class="flex flex-wrap gap-1.5 mb-4">
|
||||
{technologies.map((tech) => (
|
||||
<span class="inline-block px-2 py-0.5 text-xs rounded-full bg-white/[0.08] text-white/60 border border-white/[0.08]">
|
||||
{tech}
|
||||
</span>
|
||||
))}
|
||||
|
|
@ -57,11 +50,3 @@ const secondaryTechs = technologies?.slice(3) ?? [];
|
|||
)}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.project-card:hover {
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border-color: rgba(168, 85, 247, 0.25);
|
||||
box-shadow: 0 0 24px rgba(168, 85, 247, 0.08), 0 4px 16px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
---
|
||||
|
||||
<li class="flex items-start gap-4">
|
||||
<span class="w-4 h-0.5 bg-purple-400/60 mt-3 flex-shrink-0"></span>
|
||||
<span><slot /></span>
|
||||
</li>
|
||||
|
|
@ -7,7 +7,6 @@ startDate: "2022-01"
|
|||
endDate: "2023-01"
|
||||
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
|
||||
type: "freelance"
|
||||
featured: true
|
||||
lang: "ar"
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ startDate: "2022-01"
|
|||
endDate: "2023-01"
|
||||
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
|
||||
type: "freelance"
|
||||
featured: true
|
||||
lang: "en"
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ startDate: "2022-01"
|
|||
endDate: "2023-01"
|
||||
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
|
||||
type: "freelance"
|
||||
featured: true
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ location: "ألبي"
|
|||
startDate: "2019-09"
|
||||
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
|
||||
type: "teaching"
|
||||
featured: true
|
||||
lang: "ar"
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ location: "Albi"
|
|||
startDate: "2019-09"
|
||||
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
|
||||
type: "teaching"
|
||||
featured: true
|
||||
lang: "en"
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ location: "Albi"
|
|||
startDate: "2019-09"
|
||||
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
|
||||
type: "teaching"
|
||||
featured: true
|
||||
lang: "fr"
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ const recommendationCount = (await getCollection("recommendations")).length;
|
|||
---
|
||||
|
||||
<Layout
|
||||
title="جليل عرفاوي - مطوّر • مصوّر • ممثل ارتجالي"
|
||||
description="جليل عرفاوي: مطوّر مستقل (Software Craftsmanship، TDD، DDD)، مصوّر وممثل مقيم في ألبي، فرنسا."
|
||||
title="جليل عرفاوي - حِرَفي برمجة • ممثل ارتجالي • مصوّر"
|
||||
description="جليل عرفاوي: مطوّر مستقل (Software Craftsmanship، TDD، DDD)، ممثل ارتجالي ومصوّر مقيم في ألبي، فرنسا."
|
||||
>
|
||||
<!-- Hero Section -->
|
||||
<div dir="rtl" lang="ar" class="relative z-20 w-full max-w-6xl mx-auto mt-16 px-7 md:mt-24 lg:mt-32 xl:px-0">
|
||||
|
|
@ -28,7 +28,7 @@ const recommendationCount = (await getCollection("recommendations")).length;
|
|||
جليل عرفاوي
|
||||
</h1>
|
||||
<h2 class="mb-6 text-xl font-medium text-neutral-600 dark:text-neutral-300 md:text-2xl">
|
||||
مطوّر • مصوّر • ممثل
|
||||
حِرَفي برمجة • ممثل ارتجالي • مصوّر
|
||||
</h2>
|
||||
<p class="mb-8 text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed">
|
||||
أكتب الكود من أجل عالم أكثر عدلًا، وأصعد على الخشبة لأجل الباقي. أو العكس.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ 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 { getProjectBaseSlug, getProjectsBasePath } from "../../utils/i18n";
|
||||
import logoTiqa from "../../assets/images/logo-tiqa-blanc.png";
|
||||
|
||||
|
|
@ -16,7 +15,7 @@ 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 recentExperiences = experiences.filter((e) => e.data.featured).slice(0, 4);
|
||||
const recentExperiences = experiences.slice(0, 4);
|
||||
|
||||
const projects = (await getCollection("projects"))
|
||||
.filter((p) => p.data.lang === locale && !p.data.draft && p.data.category === "dev" && p.data.featured)
|
||||
|
|
@ -45,10 +44,8 @@ function formatMonth(dateStr: string) {
|
|||
>
|
||||
<section 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">Développeur freelance · Albi</span>
|
||||
<h1 class="text-5xl sm:text-6xl font-semibold text-white font-display tracking-wide">Artisan du logiciel</h1>
|
||||
<div class="mt-6 mb-6 w-16 h-0.5 bg-gradient-to-r from-purple-400 to-transparent rounded-full"></div>
|
||||
<div class="space-y-4 text-lg text-white/60 leading-relaxed max-w-2xl">
|
||||
<h1 class="text-4xl sm:text-5xl font-semibold text-white font-display tracking-wide">Artisan du logiciel</h1>
|
||||
<div class="mt-6 space-y-4 text-lg text-white/60 leading-relaxed max-w-2xl">
|
||||
<p>
|
||||
TDD, Clean Code, Domain-Driven Design : c'est ma façon de construire du logiciel. J'accompagne les équipes comme développeur senior, tech lead ou coach technique. Ma stack : TypeScript/JavaScript, mais aussi PHP et Elixir.
|
||||
</p>
|
||||
|
|
@ -66,42 +63,30 @@ function formatMonth(dateStr: string) {
|
|||
<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 →</a>
|
||||
</div>
|
||||
<div class="relative ml-3">
|
||||
<div class="absolute left-0 top-1.5 bottom-1.5 w-px bg-purple-300/20"></div>
|
||||
<div class="divide-y divide-white/[0.08]">
|
||||
{recentExperiences.map((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-7 pb-6 last:pb-0">
|
||||
<div class:list={[
|
||||
"absolute left-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 left-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 class="py-4 first:pt-0 last:pb-0">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="min-w-0">
|
||||
<p class="font-semibold text-white text-sm">{exp.data.role}</p>
|
||||
<p class="text-sm text-white/45 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>
|
||||
<span class:list={["text-sm whitespace-nowrap flex-shrink-0", isOngoing ? "text-purple-200" : "text-white/35"]}>
|
||||
{start} — {end}
|
||||
</span>
|
||||
</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 →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -147,12 +132,27 @@ function formatMonth(dateStr: string) {
|
|||
|
||||
<div class="mb-16">
|
||||
<h2 class="text-2xl font-bold text-white mb-6">Valeurs & Approche</h2>
|
||||
<ul class="space-y-4 text-white/80">
|
||||
<ValueItem>Le mouvement <Link href="http://manifesto.softwarecraftsmanship.org/#/fr-fr" external>Software Craftsmanship</Link></ValueItem>
|
||||
<ValueItem>L'utilité sociale du développeur</ValueItem>
|
||||
<ValueItem>Être fier de son travail, mais sans égo</ValueItem>
|
||||
<ValueItem>Approche <strong class="text-white">Domain Driven Design</strong></ValueItem>
|
||||
<ValueItem>Organisation <Link href="https://agilemanifesto.org/iso/fr/manifesto.html" external>agile</Link> : itération et amélioration continue</ValueItem>
|
||||
<ul class="space-y-3 text-white/60">
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1 h-1 rounded-full bg-purple-300/60 mt-2.5 flex-shrink-0"></span>
|
||||
<span>Le mouvement <Link href="http://manifesto.softwarecraftsmanship.org/#/fr-fr" external>Software Craftsmanship</Link></span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1 h-1 rounded-full bg-purple-300/60 mt-2.5 flex-shrink-0"></span>
|
||||
<span>L'utilité sociale du développeur</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1 h-1 rounded-full bg-purple-300/60 mt-2.5 flex-shrink-0"></span>
|
||||
<span>Être fier de son travail, mais sans égo</span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1 h-1 rounded-full bg-purple-300/60 mt-2.5 flex-shrink-0"></span>
|
||||
<span>Approche <strong class="text-white">Domain Driven Design</strong></span>
|
||||
</li>
|
||||
<li class="flex items-start gap-3">
|
||||
<span class="w-1 h-1 rounded-full bg-purple-300/60 mt-2.5 flex-shrink-0"></span>
|
||||
<span>Organisation <Link href="https://agilemanifesto.org/iso/fr/manifesto.html" external>agile</Link> : itération et amélioration continue</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ const recommendationCount = (await getCollection("recommendations")).length;
|
|||
---
|
||||
|
||||
<Layout
|
||||
title="Jalil Arfaoui - Software Craftsman • Photographer • Improv Actor"
|
||||
description="Jalil Arfaoui: freelance developer (Software Craftsmanship, TDD, DDD), photographer and actor based in Albi, France."
|
||||
title="Jalil Arfaoui - Software Craftsman • Improv Actor • Photographer"
|
||||
description="Jalil Arfaoui: freelance developer (Software Craftsmanship, TDD, DDD), improv actor and photographer based in Albi, France."
|
||||
>
|
||||
<!-- Hero Section -->
|
||||
<div class="relative z-20 w-full max-w-6xl mx-auto mt-16 px-7 md:mt-24 lg:mt-32 xl:px-0">
|
||||
|
|
@ -28,7 +28,7 @@ const recommendationCount = (await getCollection("recommendations")).length;
|
|||
Jalil Arfaoui
|
||||
</h1>
|
||||
<h2 class="mb-6 text-xl font-medium text-neutral-600 dark:text-neutral-300 md:text-2xl">
|
||||
Software Craftsman • Photographer • Actor
|
||||
Software Craftsman • Improv Actor • Photographer
|
||||
</h2>
|
||||
<p class="mb-8 text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed">
|
||||
I write code for a fairer world and get on stage for the rest. Or the other way around.
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ const recommendationCount = (await getCollection("recommendations")).length;
|
|||
---
|
||||
|
||||
<Layout
|
||||
title="Jalil Arfaoui - Développeur artisan • Photographe • Comédien improvisateur"
|
||||
description="Jalil Arfaoui : développeur freelance, photographe et comédien improvisateur basé à Albi."
|
||||
title="Jalil Arfaoui - Développeur artisan • Comédien improvisateur • Photographe"
|
||||
description="Jalil Arfaoui : développeur freelance (Software Craftsmanship, TDD, DDD), comédien improvisateur et photographe basé à Albi."
|
||||
>
|
||||
<!-- Hero Section -->
|
||||
<div class="relative z-20 w-full max-w-6xl mx-auto mt-16 px-7 md:mt-24 lg:mt-32 xl:px-0">
|
||||
|
|
@ -28,7 +28,7 @@ const recommendationCount = (await getCollection("recommendations")).length;
|
|||
Jalil Arfaoui
|
||||
</h1>
|
||||
<h2 class="mb-6 text-xl font-medium text-neutral-600 dark:text-neutral-300 md:text-2xl">
|
||||
Développeur • Photographe • Comédien
|
||||
Développeur artisan • Comédien improvisateur • Photographe
|
||||
</h2>
|
||||
<p class="mb-8 text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed">
|
||||
Je code pour un monde plus juste et je monte sur scène pour le reste. Ou l'inverse.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue