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.
This commit is contained in:
Jalil Arfaoui 2026-02-22 01:30:06 +01:00
parent 575f67665b
commit a3732887f5
122 changed files with 2597 additions and 769 deletions

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,22 +0,0 @@
---
const { logo, dates, role, company, description } = Astro.props;
---
<div class="relative flex flex-col justify-start pl-12">
<div
class="absolute top-0 left-0 z-40 flex items-center justify-center -translate-x-1/2 bg-white border rounded-full dark:bg-neutral-950 w-14 h-14 border-neutral-300 dark:border-neutral-700"
>
<img src={logo} alt={company} class="w-8 h-8" />
</div>
<p
class="text-xs uppercase text-neutral-400 dark:text-neutral-500 trackign-widest"
>
{dates}
</p>
<h3 class="my-1 text-lg font-bold dark:text-neutral-100">{role}</h3>
<p class="mb-1 text-sm font-medium dark:text-neutral-300">{company}</p>
<p class="text-sm font-light text-neutral-600 dark:text-neutral-400">
{description}
</p>
</div>

View file

@ -0,0 +1,79 @@
---
import SkillBadge from './SkillBadge.astro';
interface Props {
role: string;
company: string;
companyUrl?: string;
location?: string;
startDate: string;
endDate?: string;
technologies?: string[];
description: string;
type: string;
locale?: string;
}
const { role, company, companyUrl, location, startDate, endDate, technologies, description, type, locale = 'fr' } = Astro.props;
const presentLabel: Record<string, string> = { fr: "Présent", en: "Present", ar: "الحاضر" };
function formatPeriod(start: string, end: string | undefined, lang: string): string {
const formatMonth = (dateStr: string) => {
const [year, month] = dateStr.split('-');
const date = new Date(parseInt(year), parseInt(month) - 1);
const locales: Record<string, string> = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' };
return date.toLocaleDateString(locales[lang] || 'fr-FR', { year: 'numeric', month: 'short' });
};
const startFormatted = formatMonth(start);
const endFormatted = end ? formatMonth(end) : presentLabel[lang] || presentLabel.fr;
return `${startFormatted} — ${endFormatted}`;
}
const period = formatPeriod(startDate, endDate, locale);
const isOngoing = !endDate;
const typeIcons: Record<string, string> = {
employment: '🏢',
freelance: '💼',
teaching: '🎓',
community: '🤝',
entrepreneurship: '🚀',
};
---
<div class="relative pl-8 pb-10 border-l-2 border-neutral-200 dark:border-neutral-700 last:pb-0">
<div class="absolute -left-[9px] top-1 w-4 h-4 rounded-full border-2 border-neutral-300 dark:border-neutral-600 bg-white dark:bg-neutral-950"
class:list={[{ 'border-indigo-500 dark:border-indigo-400': isOngoing }]}
>
{isOngoing && <div class="absolute inset-1 rounded-full bg-indigo-500 dark:bg-indigo-400" />}
</div>
<div class="mb-1 flex items-center gap-2 flex-wrap">
<span class="text-xs text-neutral-500 dark:text-neutral-500">{typeIcons[type] || '💼'} {period}</span>
{location && <span class="text-xs text-neutral-400 dark:text-neutral-600">· {location}</span>}
</div>
<h3 class="text-lg font-bold text-neutral-900 dark:text-neutral-100">
{role}
</h3>
<p class="text-sm font-medium text-indigo-600 dark:text-indigo-400 mb-2">
{companyUrl ? (
<a href={companyUrl} target="_blank" rel="noopener noreferrer" class="hover:underline">{company}</a>
) : (
company
)}
</p>
<div class="text-sm text-neutral-600 dark:text-neutral-400 leading-relaxed mb-3 prose prose-sm dark:prose-invert max-w-none" set:html={description} />
{technologies && technologies.length > 0 && (
<div class="flex flex-wrap gap-1.5">
{technologies.map((tech) => (
<span class="inline-block px-2 py-0.5 text-xs rounded-full bg-neutral-100 dark:bg-neutral-800 text-neutral-600 dark:text-neutral-400">
{tech}
</span>
))}
</div>
)}
</div>

View file

@ -0,0 +1,39 @@
---
import ExperienceCard from './ExperienceCard.astro';
interface Experience {
role: string;
company: string;
companyUrl?: string;
location?: string;
startDate: string;
endDate?: string;
technologies?: string[];
type: string;
renderedHtml: string;
}
interface Props {
experiences: Experience[];
locale?: string;
}
const { experiences, locale = 'fr' } = Astro.props;
---
<div class="relative">
{experiences.map((exp) => (
<ExperienceCard
role={exp.role}
company={exp.company}
companyUrl={exp.companyUrl}
location={exp.location}
startDate={exp.startDate}
endDate={exp.endDate}
technologies={exp.technologies}
description={exp.renderedHtml}
type={exp.type}
locale={locale}
/>
))}
</div>

View file

@ -0,0 +1,48 @@
---
import { Image } from "astro:assets";
import type { ImageMetadata } from "astro";
interface Props {
author: string;
authorRole: string;
company: string;
text: string;
avatar?: ImageMetadata;
}
const { author, authorRole, company, text, avatar } = Astro.props;
const truncated = text.length > 200 ? text.slice(0, 200).replace(/\s+\S*$/, '') + '...' : text;
const initials = author
.split(' ')
.map((n) => n[0])
.slice(0, 2)
.join('')
.toUpperCase();
---
<blockquote class="facet-card rounded-xl bg-white/[0.06] border border-white/[0.1] p-5 hover:bg-white/[0.1] transition-colors duration-200">
<p class="text-sm text-white/70 leading-relaxed italic">
"{truncated}"
</p>
<div class="mt-3 flex items-center gap-2.5">
{avatar ? (
<Image
src={avatar}
alt={author}
width={28}
height={28}
class="flex-shrink-0 w-7 h-7 rounded-full object-cover"
/>
) : (
<div class="flex-shrink-0 w-7 h-7 rounded-full bg-white/10 flex items-center justify-center">
<span class="text-[10px] font-bold text-white/70">{initials}</span>
</div>
)}
<cite class="not-italic text-xs">
<span class="font-semibold text-white/90">{author}</span>
<span class="text-white/40"> · {authorRole}, {company}</span>
</cite>
</div>
</blockquote>

View file

@ -0,0 +1,23 @@
---
interface Props {
title: string;
description: string;
href: string;
icon: string;
}
const { title, description, href, icon } = Astro.props;
---
<a
href={href}
class="facet-card group block rounded-2xl bg-white/[0.06] border border-white/[0.1] p-6 hover:bg-white/[0.12] hover:border-white/[0.2] hover:scale-[1.02] transition-all duration-300 no-underline"
>
<div class="text-3xl mb-3 opacity-80 group-hover:opacity-100 group-hover:scale-110 transition-all duration-300 inline-block">{icon}</div>
<h3 class="text-lg font-bold text-white mb-2 group-hover:text-purple-200 transition-colors">
{title}
</h3>
<p class="text-sm text-white/55 leading-relaxed group-hover:text-white/70 transition-colors">
{description}
</p>
</a>

View file

@ -0,0 +1,57 @@
---
interface Props {
title: string;
description: string;
technologies?: string[];
url?: string;
github?: string;
featured?: boolean;
}
const { title, description, technologies, url, github, featured = false } = Astro.props;
---
<div class:list={[
"facet-card rounded-2xl border p-6 flex flex-col h-full transition-all duration-300 hover:scale-[1.02]",
featured
? "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="flex items-start justify-between mb-2">
<h3 class="text-lg font-bold text-white">
{title}
</h3>
{featured && (
<span class="text-[10px] font-semibold px-2 py-0.5 rounded-full bg-purple-400/20 text-purple-200 border border-purple-300/20">
Featured
</span>
)}
</div>
<p class="text-sm text-white/60 leading-relaxed flex-1 mb-4">
{description}
</p>
{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>
))}
</div>
)}
<div class="flex gap-4">
{url && (
<a href={url} target="_blank" rel="noopener noreferrer" class="text-sm font-medium text-purple-200 hover:text-white transition-colors">
Voir le site &rarr;
</a>
)}
{github && (
<a href={github} target="_blank" rel="noopener noreferrer" class="text-sm font-medium text-white/50 hover:text-white transition-colors">
GitHub &rarr;
</a>
)}
</div>
</div>

View file

@ -0,0 +1,66 @@
---
import { Image } from "astro:assets";
import type { ImageMetadata } from "astro";
interface Props {
author: string;
authorRole: string;
company: string;
text: string;
date: Date;
avatar?: ImageMetadata;
lang?: string;
}
const { author, authorRole, company, text, date, avatar, lang = 'fr' } = Astro.props;
const dateLocales: Record<string, string> = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' };
const formattedDate = date.toLocaleDateString(dateLocales[lang] || 'fr-FR', {
year: 'numeric',
month: 'long',
});
const initials = author
.split(' ')
.map((n) => n[0])
.slice(0, 2)
.join('')
.toUpperCase();
const colors = [
'from-violet-400 to-purple-500',
'from-fuchsia-400 to-pink-500',
'from-indigo-400 to-blue-500',
'from-purple-400 to-indigo-500',
'from-pink-400 to-rose-500',
];
const colorIndex = author.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0) % colors.length;
const avatarGradient = colors[colorIndex];
---
<article class="facet-card group relative rounded-2xl bg-white/[0.07] backdrop-blur-sm border border-white/[0.12] p-6 flex flex-col h-full hover:bg-white/[0.12] hover:border-white/[0.2] transition-all duration-300">
<div class="absolute top-5 right-6 text-6xl font-serif text-white/[0.06] leading-none select-none pointer-events-none" aria-hidden="true">"</div>
<p class="text-white/80 leading-relaxed flex-1 text-[0.9rem]" set:html={text} />
<div class="mt-5 pt-4 border-t border-white/[0.08] flex items-center gap-3">
{avatar ? (
<Image
src={avatar}
alt={author}
width={40}
height={40}
class="flex-shrink-0 w-10 h-10 rounded-full object-cover"
/>
) : (
<div class={`flex-shrink-0 w-10 h-10 rounded-full bg-gradient-to-br ${avatarGradient} flex items-center justify-center`}>
<span class="text-xs font-bold text-white">{initials}</span>
</div>
)}
<cite class="not-italic min-w-0">
<span class="block font-semibold text-white text-sm truncate">{author}</span>
<span class="block text-xs text-white/50 truncate">{authorRole} · {company}</span>
<span class="block text-xs text-white/30 mt-0.5">{formattedDate}</span>
</cite>
</div>
</article>

View file

@ -0,0 +1,11 @@
---
interface Props {
name: string;
}
const { name } = Astro.props;
---
<span class="inline-block px-3 py-1.5 text-sm font-medium rounded-full bg-white/[0.08] text-white/80 border border-white/[0.1] hover:bg-white/[0.15] hover:text-white transition-all duration-200">
{name}
</span>

View file

@ -0,0 +1,22 @@
---
import SkillBadge from './SkillBadge.astro';
interface Props {
name: string;
skills: string[];
}
const { name, skills } = Astro.props;
---
<div class="facet-card mb-8 rounded-2xl bg-white/[0.04] border border-white/[0.08] p-6">
<h3 class="text-base font-bold text-white mb-4 flex items-center gap-2">
<span class="w-1 h-5 rounded-full bg-purple-400/60"></span>
{name}
</h3>
<div class="flex flex-wrap gap-2">
{skills.map((skill) => (
<SkillBadge name={skill} />
))}
</div>
</div>

View file

@ -1,37 +0,0 @@
---
import projects from "../../data/projects.json";
import Button from "../button.astro";
import Project from "../project.astro";
---
<section class="max-w-4xl mx-auto px-7 lg:px-0">
<h2
class="text-2xl font-bold leading-10 tracking-tight text-neutral-900 dark:text-neutral-100"
>
My Projects
</h2>
<p class="mb-6 text-base text-neutral-600 dark:text-neutral-400">
Here are some of my recent projects. I'm always working on something new, so
check back often!
</p>
<div
class="grid items-stretch w-full sm:grid-cols-2 md:grid-cols-3 gap-7 mt-7"
>
{
projects.map((project) => {
return (
<Project
name={project.name}
description={project.description}
image={project.image}
url={project.url}
/>
)
})
}
</div>
<div class="flex items-center justify-center w-full py-5">
<Button text="View All My Projects" link="/projects" />
</div>
</section>

View file

@ -1,37 +0,0 @@
---
const { text } = Astro.props;
---
<div class="relative my-32">
<div class="relative w-full pl-5 overflow-x-hidden md:pl-0">
<div
class="absolute w-full h-px bg-gradient-to-r from-transparent to-white md:from-white dark:from-transparent dark:to-neutral-950 md:dark:from-neutral-950 md:via-transparent md:dark:via-transparent md:to-white md:dark:to-neutral-950"
>
</div>
<div
class="w-full h-px border-t border-dashed border-neutral-300 dark:border-neutral-600"
>
</div>
</div>
<div
class="absolute flex items-center justify-center w-auto h-auto px-3 py-1.5 uppercase tracking-widest space-x-1 text-[0.6rem] md:-translate-x-1/2 -translate-y-1/2 border rounded-full bg-white dark:bg-neutral-900 text-neutral-400 left-0 md:ml-0 ml-5 md:left-1/2 border-neutral-100 dark:border-neutral-800 shadow-sm"
>
<p class="leading-none">{text}</p>
<div
class="flex items-center justify-center w-5 h-5 translate-x-1 border rounded-full border-neutral-100 dark:border-neutral-800"
>
<svg
class="w-3 h-3"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 4.5v15m0 0l6.75-6.75M12 19.5l-6.75-6.75"></path></svg
>
</div>
</div>
</div>

View file

@ -1,87 +0,0 @@
---
import Button from "../button.astro";
import PostsLoop from "../posts-loop.astro";
const feed = "https://feed.miantiao.me/";
---
<section class="max-w-4xl mx-auto px-7 lg:px-0">
<h2
class="text-2xl font-bold leading-10 tracking-tight text-neutral-900 dark:text-neutral-100"
>
My Writings
</h2>
<p class="mb-6 text-base text-neutral-600 dark:text-neutral-400">
Along with coding I also like to write about life and technology. Here are
some of my recent posts.
</p>
<div class="w-full max-w-4xl mx-auto my-7 xl:px-0">
<div
class="flex flex-col items-start justify-start md:flex-row md:space-x-7"
>
<div class="w-full md:w-2/3 space-y-7">
<PostsLoop count="3" />
<div class="flex items-center justify-center w-full py-5">
<Button text="View All My Writing" link="/posts" />
</div>
</div>
<div class="w-full mt-10 md:w-1/3 md:mt-0">
<form
method="get"
action={feed}
class="p-6 border border-dashed rounded-2xl border-neutral-300 dark:border-neutral-600"
>
<div class="relative flex items-center space-x-2">
<svg
class="flex-none w-6 h-6 text-neutral-700 dark:text-neutral-200"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 01-2.25 2.25M16.5 7.5V18a2.25 2.25 0 002.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 002.25 2.25h13.5M6 7.5h3v3H6v-3z"
></path></svg
>
<h2
class="flex text-sm font-semibold text-neutral-900 dark:text-neutral-100"
>
Subscribe my blog
</h2>
</div>
<p class="mt-2 text-sm text-neutral-600 dark:text-neutral-400">
Get my blog updates via <a
class="font-bold"
href={`https://feedly.com/i/subscription/feed%2F${encodeURIComponent(feed)}`}
>Feedly</a
>, <a
class="font-bold"
href={`https://www.inoreader.com/feed/${encodeURIComponent(feed)}`}
>Inoreader</a
> or <a class="font-bold" href={feed}>RSS</a>.
</p>
<div class="flex flex-col items-center w-full mt-4 space-y-3">
<input
type="url"
readonly
placeholder="Email address"
aria-label="Email address"
required=""
value={feed}
class="w-full h-10 px-3 text-sm border border-dashed rounded-md focus:ring-0 focus:outline-black border-neutral-400 dark:border-neutral-600 dark:bg-neutral-800 dark:placeholder-neutral-400 dark:text-white"
/>
<button
type="submit"
class="block w-full px-4 py-2 mt-5 text-xs font-semibold text-center duration-300 ease-out border rounded bg-neutral-900 dark:bg-neutral-100 dark:hover:border-neutral-300 dark:text-neutral-800 dark:hover:bg-neutral-950 dark:hover:text-neutral-100 text-neutral-100 border-neutral-900 hover:bg-white hover:text-neutral-900"
>Subscribe</button
>
</div>
</form>
</div>
</div>
</div>
</section>

View file

@ -1,65 +0,0 @@
---
const { name, description, url, image } = Astro.props;
---
<a
href={url}
target="_blank"
class="relative flex flex-col items-stretch duration-300 ease-out p-7 sm:p-3 group h-100 rounded-2xl"
>
<span
class="absolute inset-0 z-20 block w-full h-full duration-300 ease-out bg-transparent border border-transparent border-dashed group-hover:-translate-x-1 group-hover:-translate-y-1 group-hover:border group-hover:border-neutral-300 dark:group-hover:border-neutral-600 group-hover:border-dashed rounded-2xl group-hover:bg-white dark:group-hover:bg-neutral-950"
></span>
<span
class="absolute inset-0 z-10 block w-full h-full duration-300 ease-out border border-dashed rounded-2xl border-neutral-300 dark:border-neutral-600 group-hover:translate-x-1 group-hover:translate-y-1"
></span>
<span
class="relative z-30 block duration-300 ease-out group-hover:-translate-x-1 group-hover:-translate-y-1"
>
<span class="block w-full">
<img src={image} class="w-full h-auto rounded-lg aspect-[16/9]" />
</span>
<span class="block w-full px-1 mt-5 mb-1 sm:mt-3">
<span
class="flex items-center mb-0 text-base font-semibold tracking-tight text-neutral-900 dark:text-neutral-100"
>
<span>{name}</span>
<svg
class="group-hover:translate-x-0 group-hover:translate-y-0 -rotate-45 translate-y-1 -translate-x-1 w-2.5 h-2.5 stroke-current ml-1 transition-all ease-in-out duration-200 transform"
viewBox="0 0 13 15"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
><g
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
><g
id="svg"
transform="translate(0.666667, 2.333333)"
stroke="currentColor"
stroke-width="2.4"
><g
><polyline
class="transition-all duration-200 ease-out opacity-0 delay-0 group-hover:opacity-100"
points="5.33333333 0 10.8333333 5.5 5.33333333 11"
></polyline><line
class="transition-all duration-200 ease-out transform -translate-x-1 opacity-0 group-hover:translate-x-0 group-hover:opacity-100 group-hover:ml-0"
x1="10.8333333"
y1="5.5"
x2="0.833333333"
y2="5.16666667"></line></g
></g
></g
></svg
>
</span>
<span class="text-sm text-neutral-600 dark:text-neutral-400"
>{description}</span
>
</span>
</span>
</a>

View file

@ -33,12 +33,11 @@ const blogCollection = defineCollection({
});
const projectsCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/projects" }),
loader: glob({ pattern: "**/*.md", base: "./src/content/projects", ...stripExtension('md') }),
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
dateFormatted: z.string(),
category: z.enum(['dev', 'comedy', 'photo']),
technologies: z.array(z.string()).optional(),
url: z.string().url().optional(),
@ -48,6 +47,39 @@ const projectsCollection = defineCollection({
featured: z.boolean().default(false),
draft: z.boolean().default(false),
lang: z.enum(['fr', 'en', 'ar']).default('fr'),
}).transform((data) => ({
...data,
dateFormatted: formatDate(data.date, data.lang),
})),
});
const experiencesCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/experiences", ...stripExtension('md') }),
schema: z.object({
role: z.string(),
company: z.string(),
companyUrl: z.string().url().optional(),
location: z.string().optional(),
startDate: z.string(),
endDate: z.string().optional(),
technologies: z.array(z.string()).optional(),
type: z.enum(['employment', 'freelance', 'teaching', 'community', 'entrepreneurship']),
featured: z.boolean().default(false),
draft: z.boolean().default(false),
lang: z.enum(['fr', 'en', 'ar']).default('fr'),
}),
});
const recommendationsCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/recommendations" }),
schema: ({ image }) => z.object({
author: z.string(),
authorRole: z.string(),
company: z.string(),
avatar: image().optional(),
date: z.date(),
relationship: z.string().optional(),
lang: z.enum(['fr', 'en']).default('fr'),
}),
});
@ -97,6 +129,8 @@ const photoCategoriesCollection = defineCollection({
export const collections = {
blog: blogCollection,
projects: projectsCollection,
experiences: experiencesCollection,
recommendations: recommendationsCollection,
talks: talksCollection,
photoBlogPosts: photoBlogPostsCollection,
photoCategories: photoCategoriesCollection,

View file

@ -0,0 +1,13 @@
---
role: "مهندس معماري للواجهات"
company: "ARaymond"
companyUrl: "https://www.araymond.com/"
location: "غرونوبل"
startDate: "2022-01"
endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance"
lang: "ar"
---
مهندس معماري للواجهات الأمامية للتطبيقات الداخلية لشركة رائدة عالميًا في التثبيت الصناعي. إعداد monorepo Nx، الانتقال إلى Vite، تحديد معايير تطوير الواجهات.

View file

@ -0,0 +1,13 @@
---
role: "Frontend Architect"
company: "ARaymond"
companyUrl: "https://www.araymond.com/"
location: "Grenoble"
startDate: "2022-01"
endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance"
lang: "en"
---
Frontend architect for internal applications at a world leader in industrial fastening. Set up Nx monorepo, migration to Vite, definition of frontend development standards.

View file

@ -0,0 +1,13 @@
---
role: "Architecte frontend"
company: "ARaymond"
companyUrl: "https://www.araymond.com/"
location: "Grenoble"
startDate: "2022-01"
endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance"
lang: "fr"
---
Architecte frontend pour les applications internes d'un leader mondial de la fixation industrielle. Mise en place d'un monorepo Nx, migration vers Vite, définition des standards de développement frontend.

View file

@ -0,0 +1,12 @@
---
role: "أستاذ هندسة البرمجيات"
company: "جامعة شامبوليون"
companyUrl: "https://www.univ-jfc.fr/"
location: "ألبي"
startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching"
lang: "ar"
---
أستاذ هندسة البرمجيات في ماستر AMINJ وليسانس معلوماتية. تدريس أفضل ممارسات التطوير، TDD، الكود النظيف، هندسة البرمجيات.

View file

@ -0,0 +1,12 @@
---
role: "Software Engineering Professor"
company: "Université Champollion"
companyUrl: "https://www.univ-jfc.fr/"
location: "Albi"
startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching"
lang: "en"
---
Software engineering professor in Master AMINJ and Bachelor in Computer Science. Teaching development best practices, TDD, Clean Code, software architecture.

View file

@ -0,0 +1,12 @@
---
role: "Enseignant en génie logiciel"
company: "Université Champollion"
companyUrl: "https://www.univ-jfc.fr/"
location: "Albi"
startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching"
lang: "fr"
---
Enseignant en génie logiciel en Master AMINJ et Licence informatique. Cours sur les bonnes pratiques de développement, TDD, Clean Code, architecture logicielle.

View file

@ -0,0 +1,13 @@
---
role: "حرفي برمجيات / مؤسس مشارك"
company: "DisMoi"
companyUrl: "https://github.com/dis-moi"
location: "عن بُعد"
startDate: "2019-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
type: "entrepreneurship"
lang: "ar"
---
مؤسّس مشارك ومطوّر رئيسي لـ DisMoi، إضافة متصفّح في مجال التكنولوجيا المدنية تتيح إضافة معلومات سياقية على أي صفحة ويب. مشروع مفتوح المصدر مدعوم من منظمات التحقق من المعلومات.

View file

@ -0,0 +1,13 @@
---
role: "Software Craftsman / Cofounder"
company: "DisMoi"
companyUrl: "https://github.com/dis-moi"
location: "Remote"
startDate: "2019-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
type: "entrepreneurship"
lang: "en"
---
Cofounder and lead developer of DisMoi, a civic tech browser extension that adds contextual information to any web page. Open source project supported by fact-checking organizations.

View file

@ -0,0 +1,13 @@
---
role: "Software Craftsman / Cofondateur"
company: "DisMoi"
companyUrl: "https://github.com/dis-moi"
location: "Remote"
startDate: "2019-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
type: "entrepreneurship"
lang: "fr"
---
Cofondateur et développeur principal de DisMoi, une extension navigateur civic tech permettant d'ajouter de l'information contextuelle sur n'importe quelle page web. Projet open source soutenu par des organisations de vérification des faits.

View file

@ -0,0 +1,13 @@
---
role: "مدرّس تطوير"
company: "ESN 81"
companyUrl: "https://www.esn81.fr/"
location: "كاستر"
startDate: "2020-09"
endDate: "2021-06"
technologies: ["JavaScript", "Node.js"]
type: "teaching"
lang: "ar"
---
تدريس أفضل ممارسات التطوير وNode.js لطلاب التكوين المهني.

View file

@ -0,0 +1,13 @@
---
role: "Development Teacher"
company: "ESN 81"
companyUrl: "https://www.esn81.fr/"
location: "Castres"
startDate: "2020-09"
endDate: "2021-06"
technologies: ["JavaScript", "Node.js"]
type: "teaching"
lang: "en"
---
Teaching development best practices and Node.js to vocational training students.

View file

@ -0,0 +1,13 @@
---
role: "Enseignant en développement"
company: "ESN 81"
companyUrl: "https://www.esn81.fr/"
location: "Castres"
startDate: "2020-09"
endDate: "2021-06"
technologies: ["JavaScript", "Node.js"]
type: "teaching"
lang: "fr"
---
Enseignement des bonnes pratiques de développement et de Node.js à des étudiants en formation professionnelle.

View file

@ -0,0 +1,12 @@
---
role: "مطوّر ويب"
company: "eThemis"
location: "فرساي"
startDate: "2002-06"
endDate: "2002-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL"]
type: "employment"
lang: "ar"
---
أوّل منصب كمطوّر. تطوير ويب لشركة نشر برمجيات قانونية.

View file

@ -0,0 +1,12 @@
---
role: "Web Developer"
company: "eThemis"
location: "Versailles"
startDate: "2002-06"
endDate: "2002-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL"]
type: "employment"
lang: "en"
---
First developer position. Web development for a legal software publishing company.

View file

@ -0,0 +1,12 @@
---
role: "Développeur web"
company: "eThemis"
location: "Versailles"
startDate: "2002-06"
endDate: "2002-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL"]
type: "employment"
lang: "fr"
---
Premier poste de développeur. Développement web pour une société d'édition de logiciels juridiques.

View file

@ -0,0 +1,12 @@
---
role: "مهندس برمجيات أول"
company: "eThemis"
location: "فرساي"
startDate: "2011-01"
endDate: "2015-12"
technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"]
type: "employment"
lang: "ar"
---
مطوّر أول في شركة نشر برمجيات قانونية. تصميم وتطوير تطبيقات ويب مهنية لمتخصصي القانون. تطبيق الممارسات الأجايل في الفريق.

View file

@ -0,0 +1,12 @@
---
role: "Senior Software Engineer"
company: "eThemis"
location: "Versailles"
startDate: "2011-01"
endDate: "2015-12"
technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"]
type: "employment"
lang: "en"
---
Senior developer at a legal software publishing company. Design and development of business web applications for legal professionals. Implementation of agile practices within the team.

View file

@ -0,0 +1,12 @@
---
role: "Ingénieur logiciel senior"
company: "eThemis"
location: "Versailles"
startDate: "2011-01"
endDate: "2015-12"
technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"]
type: "employment"
lang: "fr"
---
Développeur senior dans une société d'édition de logiciels juridiques. Conception et développement d'applications web métier pour les professionnels du droit. Mise en place de pratiques agiles dans l'équipe.

View file

@ -0,0 +1,12 @@
---
role: "مطوّر ويب وبرمجيات"
company: "مستقل"
location: "إيل دو فرانس"
startDate: "2003-01"
endDate: "2006-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL", "Linux"]
type: "freelance"
lang: "ar"
---
تطوير ويب مستقل. إنشاء مواقع وتطبيقات ويب مخصّصة. تطوير مشاريع شخصية: N.Gine (نظام إدارة محتوى خاص)، ICU (منصة مشاركة صور)، Débats.co (نقاش سياسي تعاوني). أفضل مشروع برمجة لدفعة 2003 في UVSQ.

View file

@ -0,0 +1,12 @@
---
role: "Web & Software Developer"
company: "Freelance"
location: "Île-de-France"
startDate: "2003-01"
endDate: "2006-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL", "Linux"]
type: "freelance"
lang: "en"
---
Freelance web development. Creation of custom websites and web applications. Development of personal projects: N.Gine (proprietary CMS), ICU (photo sharing platform), Débats.co (collaborative political debate). Best programming project of the 2003 class at UVSQ.

View file

@ -0,0 +1,12 @@
---
role: "Développeur web & logiciel"
company: "Indépendant"
location: "Île-de-France"
startDate: "2003-01"
endDate: "2006-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL", "Linux"]
type: "freelance"
lang: "fr"
---
Développement web en freelance. Création de sites et applications web sur mesure. Développement de projets personnels : N.Gine (CMS propriétaire), ICU (plateforme de partage photo), Débats.co (débat politique collaboratif). Meilleur projet de programmation de la promo 2003 à l'UVSQ.

View file

@ -0,0 +1,13 @@
---
role: "مدير تقني"
company: "GoBuild (Go-Decision)"
companyUrl: "https://www.gobuild.fr"
location: "ليون"
startDate: "2020-06"
endDate: "2022-01"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
type: "employment"
lang: "ar"
---
مدير تقني لشركة ناشئة متخصصة في نمذجة المباني. مسؤول عن الهندسة التقنية والتوظيف ومرافقة فريق التطوير. تطبيق ممارسات Software Craftsmanship.

View file

@ -0,0 +1,13 @@
---
role: "CTO"
company: "GoBuild (Go-Decision)"
companyUrl: "https://www.gobuild.fr"
location: "Lyon"
startDate: "2020-06"
endDate: "2022-01"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
type: "employment"
lang: "en"
---
CTO of a startup specializing in building modeling. Responsible for technical architecture, recruitment and mentoring of the development team. Implementation of Software Craftsmanship practices.

View file

@ -0,0 +1,13 @@
---
role: "CTO"
company: "GoBuild (Go-Decision)"
companyUrl: "https://www.gobuild.fr"
location: "Lyon"
startDate: "2020-06"
endDate: "2022-01"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
type: "employment"
lang: "fr"
---
CTO d'une startup spécialisée dans la modélisation de bâtiments. Responsable de l'architecture technique, du recrutement et de l'accompagnement de l'équipe de développement. Mise en place des pratiques Software Craftsmanship.

View file

@ -0,0 +1,13 @@
---
role: "مهندس برمجيات fullstack"
company: "Libeo"
companyUrl: "https://www.libeo.io/"
location: "عن بُعد"
startDate: "2021-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"]
type: "freelance"
lang: "ar"
---
تطوير منصة دفع B2B. تحسين جودة الكود وتطبيق ممارسات TDD.

View file

@ -0,0 +1,13 @@
---
role: "Fullstack Software Engineer"
company: "Libeo"
companyUrl: "https://www.libeo.io/"
location: "Remote"
startDate: "2021-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"]
type: "freelance"
lang: "en"
---
Development of a B2B payment platform. Code quality improvement and implementation of TDD practices.

View file

@ -0,0 +1,13 @@
---
role: "Ingénieur logiciel fullstack"
company: "Libeo"
companyUrl: "https://www.libeo.io/"
location: "Remote"
startDate: "2021-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"]
type: "freelance"
lang: "fr"
---
Développement d'une plateforme de paiement B2B. Amélioration de la qualité du code et mise en place de pratiques TDD.

View file

@ -0,0 +1,13 @@
---
role: "مهندس برمجيات أول"
company: "Obat"
companyUrl: "https://www.obat.fr/"
location: "عن بُعد"
startDate: "2023-02"
endDate: "2024-01"
technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"]
type: "freelance"
lang: "ar"
---
تطوير تطبيق SaaS لإدارة قطاع البناء. تحسين الهندسة المعمارية وتطبيق أفضل الممارسات (TDD، الكود النظيف).

View file

@ -0,0 +1,13 @@
---
role: "Senior Software Engineer"
company: "Obat"
companyUrl: "https://www.obat.fr/"
location: "Remote"
startDate: "2023-02"
endDate: "2024-01"
technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"]
type: "freelance"
lang: "en"
---
Development of a SaaS management application for the construction industry. Architecture improvement and implementation of best practices (TDD, Clean Code).

View file

@ -0,0 +1,13 @@
---
role: "Ingénieur logiciel senior"
company: "Obat"
companyUrl: "https://www.obat.fr/"
location: "Remote"
startDate: "2023-02"
endDate: "2024-01"
technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"]
type: "freelance"
lang: "fr"
---
Développement d'une application SaaS de gestion pour le secteur du bâtiment. Amélioration de l'architecture et mise en place de bonnes pratiques (TDD, Clean Code).

View file

@ -0,0 +1,13 @@
---
role: "مؤسّس ومدير عام"
company: "Team Logics"
location: "فرساي"
startDate: "2007-01"
endDate: "2011-12"
technologies: ["PHP", "CakePHP", "JavaScript", "MySQL", "Linux"]
type: "entrepreneurship"
featured: true
lang: "ar"
---
مؤسّس ومدير وكالة ويب. إدارة فريق من 6 أشخاص. عملاء: ALD Automotive، Joué Club، Consuel، وغيرهم. تصميم وتطوير وإدارة مشاريع ويب مخصّصة.

View file

@ -0,0 +1,13 @@
---
role: "Founder & CEO"
company: "Team Logics"
location: "Versailles"
startDate: "2007-01"
endDate: "2011-12"
technologies: ["PHP", "CakePHP", "JavaScript", "MySQL", "Linux"]
type: "entrepreneurship"
featured: true
lang: "en"
---
Founded and led a web agency. Managed a team of 6. Clients: ALD Automotive, Joué Club, Consuel, and others. Design, development and management of custom web projects.

View file

@ -0,0 +1,13 @@
---
role: "Fondateur & CEO"
company: "Team Logics"
location: "Versailles"
startDate: "2007-01"
endDate: "2011-12"
technologies: ["PHP", "CakePHP", "JavaScript", "MySQL", "Linux"]
type: "entrepreneurship"
featured: true
lang: "fr"
---
Fondateur et dirigeant d'une agence web. Direction d'une équipe de 6 personnes. Clients : ALD Automotive, Joué Club, Consuel, et d'autres. Conception, développement et gestion de projets web sur mesure.

View file

@ -0,0 +1,15 @@
---
role: "مطوّر رئيسي"
company: "Urssaf Caisse nationale"
companyUrl: "https://www.urssaf.fr/"
location: "عن بُعد / باريس"
startDate: "2024-02"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"]
type: "freelance"
featured: true
lang: "ar"
---
مطوّر رئيسي لموقع [mon-entreprise.urssaf.fr](https://mon-entreprise.urssaf.fr/)، المساعد الرسمي لروّاد الأعمال في فرنسا. أكثر من 20 محاكيًا منشورًا على المواقع العامّة، مليون مستخدم شهريًا.
هندسة وتطوير باستخدام لغة [Publicodes](https://publi.codes/) لنمذجة قواعد الحساب الاجتماعي-الضريبي. تعاون مع فريق beta.gouv.

View file

@ -0,0 +1,15 @@
---
role: "Lead Developer"
company: "Urssaf Caisse nationale"
companyUrl: "https://www.urssaf.fr/"
location: "Remote / Paris"
startDate: "2024-02"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"]
type: "freelance"
featured: true
lang: "en"
---
Lead developer of [mon-entreprise.urssaf.fr](https://mon-entreprise.urssaf.fr/), the official assistant for entrepreneurs in France. Over 20 simulators deployed on public websites, one million users per month.
Architecture and development with the [Publicodes](https://publi.codes/) language for modeling socio-fiscal calculation rules. Collaboration with the beta.gouv team.

View file

@ -0,0 +1,15 @@
---
role: "Lead Developer"
company: "Urssaf Caisse nationale"
companyUrl: "https://www.urssaf.fr/"
location: "Remote / Paris"
startDate: "2024-02"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"]
type: "freelance"
featured: true
lang: "fr"
---
Lead developer de [mon-entreprise.urssaf.fr](https://mon-entreprise.urssaf.fr/), l'assistant officiel des créateurs d'entreprise en France. Plus de 20 simulateurs diffusés sur les sites publics, un million d'usagers par mois.
Architecture et développement avec le langage [Publicodes](https://publi.codes/) pour la modélisation des règles de calcul socio-fiscales. Collaboration avec l'équipe beta.gouv.

View file

@ -0,0 +1,13 @@
---
role: "مطوّر واجهات رئيسي Travel"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
location: "باريس"
startDate: "2016-02"
endDate: "2018-01"
technologies: ["JavaScript", "React.js", "Redux", "Webpack", "RxJS"]
type: "employment"
lang: "ar"
---
مطوّر واجهات رئيسي لفريق Travel. ترحيل تطبيق قديم إلى React/Redux. تطبيق الاختبارات الآلية وأفضل ممارسات التطوير.

View file

@ -0,0 +1,13 @@
---
role: "Travel Front Lead Developer"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
location: "Paris"
startDate: "2016-02"
endDate: "2018-01"
technologies: ["JavaScript", "React.js", "Redux", "Webpack", "RxJS"]
type: "employment"
lang: "en"
---
Frontend lead developer for the Travel team. Migration from a legacy application to React/Redux. Implementation of automated testing and development best practices.

View file

@ -0,0 +1,13 @@
---
role: "Travel Front Lead Developer"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
location: "Paris"
startDate: "2016-02"
endDate: "2018-01"
technologies: ["JavaScript", "React.js", "Redux", "Webpack", "RxJS"]
type: "employment"
lang: "fr"
---
Lead developer frontend de l'équipe Travel. Migration d'une application legacy vers React/Redux. Mise en place des tests automatisés et des bonnes pratiques de développement.

View file

@ -0,0 +1,14 @@
---
role: "قائد تقني Travel"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
location: "باريس"
startDate: "2018-01"
endDate: "2019-06"
technologies: ["TypeScript", "React.js", "Redux", "redux-saga", "Node.js"]
type: "employment"
featured: true
lang: "ar"
---
قائد تقني لفريق Travel (8 مطوّرين) في Veepee (سابقًا vente-privee.com). إشراف تقني، مراجعة الكود، تحديد الهندسة. مؤسّس مشارك لبرنامج التدريب الداخلي React Academy.

View file

@ -0,0 +1,14 @@
---
role: "Travel Tech Lead"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
location: "Paris"
startDate: "2018-01"
endDate: "2019-06"
technologies: ["TypeScript", "React.js", "Redux", "redux-saga", "Node.js"]
type: "employment"
featured: true
lang: "en"
---
Tech Lead of the Travel team (8 developers) at Veepee (formerly vente-privee.com). Technical mentoring, code reviews, architecture definition. Co-founded the internal React Academy training program.

View file

@ -0,0 +1,14 @@
---
role: "Travel Tech Lead"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
location: "Paris"
startDate: "2018-01"
endDate: "2019-06"
technologies: ["TypeScript", "React.js", "Redux", "redux-saga", "Node.js"]
type: "employment"
featured: true
lang: "fr"
---
Tech Lead de l'équipe Travel (8 développeurs) chez Veepee (ex vente-privee.com). Encadrement technique, revues de code, définition de l'architecture. Cofondateur du programme de formation interne React Academy.

View file

@ -0,0 +1,12 @@
---
title: "Débats.co"
description: "منصّة تعاونية لتلخيص النقاشات المجتمعية. ويكيبيديا المواقف."
date: 2015-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
url: "https://debats.co"
featured: true
lang: "ar"
---
منصّة تعاونية لرسم خريطة الحجج المؤيدة والمعارضة حول القضايا المجتمعية الكبرى. كل نقاش مُهيكل بمواقف الشخصيات العامّة، موثّقة وقابلة للتحقق.

View file

@ -0,0 +1,12 @@
---
title: "Débats.co"
description: "Collaborative platform for synthesizing public debates. The Wikipedia of public stances."
date: 2015-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
url: "https://debats.co"
featured: true
lang: "en"
---
Collaborative platform for mapping arguments for and against on major societal issues. Each debate is structured with public figures' positions, sourced and verifiable.

View file

@ -0,0 +1,12 @@
---
title: "Débats.co"
description: "Plateforme collaborative de synthèse des débats de société. Le Wikipédia des prises de position."
date: 2015-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
url: "https://debats.co"
featured: true
lang: "fr"
---
Plateforme collaborative permettant de cartographier les arguments pour et contre sur les grands sujets de société. Chaque débat est structuré avec les positions des personnalités publiques, sourcées et vérifiables.

View file

@ -0,0 +1,14 @@
---
title: "DisMoi"
description: "إضافة متصفّح في مجال التكنولوجيا المدنية تضيف معلومات سياقية على أي صفحة ويب."
date: 2019-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
github: "https://github.com/dis-moi"
featured: true
lang: "ar"
---
إضافة متصفّح مفتوحة المصدر تتيح لمساهمين موثوقين (صحفيون، جمعيات، مدقّقو حقائق) إضافة معلومات سياقية مباشرة على صفحات الويب التي يزورها المستخدمون.
مشروع شارك في تأسيسه وتطويره من 2019 إلى 2021، مدعوم من منظمات التحقق من المعلومات.

View file

@ -0,0 +1,14 @@
---
title: "DisMoi"
description: "Civic tech browser extension that adds contextual information to any web page."
date: 2019-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
github: "https://github.com/dis-moi"
featured: true
lang: "en"
---
Open source browser extension allowing trusted contributors (journalists, associations, fact-checkers) to add contextual information directly on web pages visited by users.
Project co-founded and developed from 2019 to 2021, supported by fact-checking organizations.

View file

@ -0,0 +1,14 @@
---
title: "DisMoi"
description: "Extension navigateur civic tech pour ajouter de l'information contextuelle sur n'importe quelle page web."
date: 2019-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
github: "https://github.com/dis-moi"
featured: true
lang: "fr"
---
Extension navigateur open source permettant à des contributeurs de confiance (journalistes, associations, fact-checkers) d'ajouter des informations contextuelles directement sur les pages web visitées par les utilisateurs.
Projet cofondé et développé de 2019 à 2021, soutenu par des organisations de vérification des faits.

View file

@ -0,0 +1,11 @@
---
title: "DNS.Surf"
description: "أداة استعلام DNS عالمية. استعلام خوادم DNS من مناطق مختلفة."
date: 2023-01-01
category: "dev"
technologies: ["JavaScript"]
url: "https://dns.surf"
lang: "ar"
---
أداة عبر الإنترنت للتحقق من استعلام DNS لنطاق من مناطق مختلفة حول العالم. مفيدة لتشخيص مشاكل انتشار DNS.

View file

@ -0,0 +1,11 @@
---
title: "DNS.Surf"
description: "Worldwide DNS resolution tool. Query DNS servers from different regions."
date: 2023-01-01
category: "dev"
technologies: ["JavaScript"]
url: "https://dns.surf"
lang: "en"
---
Online tool to check DNS resolution of a domain from different regions worldwide. Useful for diagnosing DNS propagation issues.

View file

@ -0,0 +1,11 @@
---
title: "DNS.Surf"
description: "Outil de résolution DNS mondiale. Interroge les serveurs DNS de différentes régions."
date: 2023-01-01
category: "dev"
technologies: ["JavaScript"]
url: "https://dns.surf"
lang: "fr"
---
Outil en ligne permettant de vérifier la résolution DNS d'un domaine depuis différentes régions du monde. Utile pour diagnostiquer les problèmes de propagation DNS.

View file

@ -0,0 +1,11 @@
---
title: "Email.ML"
description: "خدمة بريد إلكتروني مؤقت بتصميم بسيط."
date: 2023-01-01
category: "dev"
technologies: ["JavaScript"]
url: "https://email.ml"
lang: "ar"
---
خدمة بريد إلكتروني مؤقت بتصميم أنيق. استقبال رسائل على عنوان يُمكن التخلّص منه، بدون تسجيل.

View file

@ -0,0 +1,11 @@
---
title: "Email.ML"
description: "Minimalist temporary email service."
date: 2023-01-01
category: "dev"
technologies: ["JavaScript"]
url: "https://email.ml"
lang: "en"
---
Temporary email service with a clean design. Receive emails on a disposable address, no signup required.

View file

@ -0,0 +1,11 @@
---
title: "Email.ML"
description: "Service d'email temporaire minimaliste."
date: 2023-01-01
category: "dev"
technologies: ["JavaScript"]
url: "https://email.ml"
lang: "fr"
---
Service d'email temporaire au design épuré. Permet de recevoir des emails sur une adresse jetable, sans inscription.

View file

@ -0,0 +1,11 @@
---
title: "GoBuild"
description: "SaaS لنمذجة المباني للمهنيين في قطاع البناء."
date: 2020-06-01
category: "dev"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
url: "https://www.gobuild.fr"
lang: "ar"
---
تطبيق SaaS يتيح لمهنيي البناء نمذجة وتقدير مشاريعهم. طُوّر بصفتي مديرًا تقنيًا من 2020 إلى 2022.

View file

@ -0,0 +1,11 @@
---
title: "GoBuild"
description: "SaaS building modeling platform for construction professionals."
date: 2020-06-01
category: "dev"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
url: "https://www.gobuild.fr"
lang: "en"
---
SaaS application enabling construction professionals to model and estimate their building projects. Developed as CTO from 2020 to 2022.

View file

@ -0,0 +1,11 @@
---
title: "GoBuild"
description: "SaaS de modélisation de bâtiments pour les professionnels du BTP."
date: 2020-06-01
category: "dev"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
url: "https://www.gobuild.fr"
lang: "fr"
---
Application SaaS permettant aux professionnels du bâtiment de modéliser et chiffrer leurs projets de construction. Développé en tant que CTO de 2020 à 2022.

View file

@ -0,0 +1,10 @@
---
title: "ICU"
description: "منصة مشاركة صور عبر الإنترنت، مشروع شخصي تاريخي."
date: 2005-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "ar"
---
منصة مشاركة صور طُوّرت في 2005، قبل عصر الشبكات الاجتماعية بكثير. أحد أوّل المشاريع الشخصية التي علّمتني تطوير الويب بعمق.

View file

@ -0,0 +1,10 @@
---
title: "ICU"
description: "Online photo sharing platform, a historical personal project."
date: 2005-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "en"
---
Photo sharing platform developed in 2005, well before the social media era. One of the first personal projects that taught me web development in depth.

View file

@ -0,0 +1,10 @@
---
title: "ICU"
description: "Plateforme de partage de photos en ligne, projet personnel historique."
date: 2005-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "fr"
---
Plateforme de partage de photos développée en 2005, bien avant l'ère des réseaux sociaux. Un des premiers projets personnels qui m'a permis d'apprendre le développement web en profondeur.

View file

@ -0,0 +1,15 @@
---
title: "mon-entreprise.urssaf.fr"
description: "المساعد الرسمي لروّاد الأعمال في فرنسا. أكثر من 20 محاكيًا اجتماعيًا-ضريبيًا، مليون مستخدم شهريًا."
date: 2024-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js"]
url: "https://mon-entreprise.urssaf.fr/"
github: "https://github.com/betagouv/mon-entreprise"
featured: true
lang: "ar"
---
محاكيات اشتراكات اجتماعية وضرائب ومساعدات لمؤسسي الشركات. مشروع مفتوح المصدر تقوده Urssaf وbeta.gouv.fr، يستخدمه أكثر من مليون شخص شهريًا.
يعتمد محرّك الحساب على [Publicodes](https://publi.codes/)، لغة تصريحية لنمذجة القواعد الاجتماعية-الضريبية الفرنسية.

View file

@ -0,0 +1,15 @@
---
title: "mon-entreprise.urssaf.fr"
description: "The official assistant for entrepreneurs in France. Over 20 socio-fiscal simulators, one million users per month."
date: 2024-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js"]
url: "https://mon-entreprise.urssaf.fr/"
github: "https://github.com/betagouv/mon-entreprise"
featured: true
lang: "en"
---
Social contribution, tax and startup aid simulators. Open source project led by Urssaf and beta.gouv.fr, used by over one million people every month.
The calculation engine relies on [Publicodes](https://publi.codes/), a declarative language for modeling French socio-fiscal rules.

View file

@ -0,0 +1,15 @@
---
title: "mon-entreprise.urssaf.fr"
description: "L'assistant officiel des créateurs d'entreprise en France. Plus de 20 simulateurs socio-fiscaux, un million d'usagers par mois."
date: 2024-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js"]
url: "https://mon-entreprise.urssaf.fr/"
github: "https://github.com/betagouv/mon-entreprise"
featured: true
lang: "fr"
---
Simulateurs de cotisations sociales, d'impôts et d'aides aux créateurs d'entreprise. Projet open source porté par l'Urssaf et beta.gouv.fr, utilisé par plus d'un million de personnes chaque mois.
Le moteur de calcul repose sur [Publicodes](https://publi.codes/), un langage déclaratif pour modéliser les règles socio-fiscales françaises.

View file

@ -0,0 +1,10 @@
---
title: "N.Gine"
description: "نظام إدارة محتوى خاص بُني من الصفر، استُخدم للعديد من مشاريع العملاء."
date: 2004-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "ar"
---
نظام إدارة محتوى (CMS) بُني من الصفر. استُخدم كأساس تقني لعديد من مواقع عملاء وكالة Team Logics. مشروع تكويني علّمني هندسة البرمجيات عبر الممارسة.

View file

@ -0,0 +1,10 @@
---
title: "N.Gine"
description: "Proprietary CMS built from scratch, used for many client projects."
date: 2004-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "en"
---
Content management system (CMS) built from scratch. Used as the technical foundation for many client websites at the Team Logics agency. A formative project that taught me software architecture through practice.

View file

@ -0,0 +1,10 @@
---
title: "N.Gine"
description: "CMS propriétaire développé de zéro, utilisé pour de nombreux projets clients."
date: 2004-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "fr"
---
Système de gestion de contenu (CMS) développé de zéro. Utilisé comme base technique pour de nombreux sites clients de l'agence Team Logics. Un projet formateur qui m'a enseigné l'architecture logicielle par la pratique.

View file

@ -0,0 +1,8 @@
---
author: "Anne Marchadier Valmont"
authorRole: "Responsable administratif"
company: "4CAD Group"
date: 2009-08-19
lang: "fr"
---
Jalil et son équipe de Team Logics savent accompagner l'entreprise dans ses projets et être force de proposition grâce à leur sens de la créativité et leur expertise dans le web. En plus de ces qualités, le sens du service est un maître mot pour l'équipe. Anne Marchadier ; ex Responsable Administrative d'e-THEMIS.

View file

@ -0,0 +1,8 @@
---
author: "Antoine Wolff"
authorRole: "Développeur, graphiste et chef de projet"
company: "LeCollectif"
date: 2020-12-07
lang: "fr"
---
J'ai travaillé avec Jalil sur différents projets de développements web (JS, React, PHP,...) et d'applications mobiles. Passionné, consciencieux et efficace, c'est toujours un plaisir de travailler en équipe avec lui. J'ai beaucoup appris à ces côtés.

View file

@ -0,0 +1,8 @@
---
author: "Benoit Sarda"
authorRole: "Sr Solution Architect, Manuf"
company: "Amazon Web Services (AWS)"
date: 2011-12-07
lang: "fr"
---
Jalil est sérieux, déterminé, diligent, très agréable et ouvert. Ses nombreuses compétences et domaines d'expertise lui permettent de mener à bien nombre de projets développement et web. Il est également un très bon manager, à l'écoute de tous, encadrant et dirigeant ses équipes avec efficacité et sérénité.

View file

@ -0,0 +1,8 @@
---
author: "Benoit Talbot"
authorRole: "Consultant technico-fonctionel Sage ERP X3"
company: "Concept ERP"
date: 2015-01-29
lang: "fr"
---
Toujours disponible et hautement compétant techniquement, Jalil est un collègue très précieux et humainement très agréable. L'essayer c'est l'adopter! Benoit

View file

@ -0,0 +1,8 @@
---
author: "Bouchra Ghaoui"
authorRole: "Senior Engagement Manager"
company: "Capgemini"
date: 2011-12-09
lang: "fr"
---
Jalil est un très bon manager toujours à l'écoute de ses équipes et de ses clients afin de mener à bien tous ses projets. il est également très compétent sur le plan technique pour ce qui est du développement d'applications Web ou Winform avec différent langages de programmation (C# .Net, JAVA, PHP, ASP .Net, HTML, CSS...)

View file

@ -0,0 +1,8 @@
---
author: "Daniel Gall"
authorRole: "Consultant"
company: "Taos Conseil"
date: 2011-12-07
lang: "fr"
---
Nous avons fait développer par jalil un site Web dont les spécifications étaient floues. Il a su s'adapter et adapter la conception, et faire évoluer son produit au fur et à mesure de l'avancement et des découvertes que nous faisions. il est resté serein devant les difficultés, etcela a permis de mener à bien le projet.

View file

@ -0,0 +1,8 @@
---
author: "Grégoire Lacoste"
authorRole: "Chief Product Officer"
company: "CertifiCall"
date: 2020-12-08
lang: "fr"
---
J'ai eu la chance de travailler avec Jalil sur plusieurs projets d'applications react/node ou php, son expérience, sa vision claire et sa pédagogie a toute épreuve en font un partenaire incontournable pour un projet réussi

View file

@ -0,0 +1,8 @@
---
author: "Guillaume Gendrillon"
authorRole: "Lead designer Information Voyageur et signalétique"
company: "RATPgroup"
date: 2011-12-05
lang: "fr"
---
Jalil est une personne de confiance, efficace et rigoureux ayant l'amour de son travail.

View file

@ -0,0 +1,8 @@
---
author: "Laurent Perez"
authorRole: "Senior Developer"
company: "itk"
date: 2009-09-07
lang: "en"
---
Open minded and very professional

View file

@ -0,0 +1,8 @@
---
author: "Matthieu Diouron"
authorRole: "Director of Business Development"
company: "T-Systems France"
date: 2009-09-09
lang: "fr"
---
Jalil est un prestataire qui sait maitriser les dernières technologies du web sans jamais perdre de vue l'objectif final du client. Cette valeur ajoutée s'est donc révélée être une clé du succès du site que nous avons mis en place pour un groupement de cinémas.

View file

@ -0,0 +1,8 @@
---
author: "Maxime Boudier"
authorRole: "Staff Web Engineer"
company: "SNCF Connect & Tech"
date: 2020-12-12
lang: "fr"
---
Une des personnes avec qui j'ai préféré travailler. En plus d'être passionné, très bon techniquement et j'en passe.. Jalil est une personne qu'on apprécie pour ses qualités humaines. J'ai beaucoup appris de toi Jalil, sur plusieurs plans, j'espère que nos chemin se re-croiseront.

View file

@ -0,0 +1,8 @@
---
author: "Olivier Cornudet"
authorRole: "Consultant manager"
company: "e-THEMIS"
date: 2015-02-11
lang: "fr"
---
En plus de ses qualités techniques, Jalil combine un bon relationnel des qualités d'écoutes et une bonne capacité à se mettre à la place des utilisateurs des solutions qu'il réalise.

View file

@ -0,0 +1,8 @@
---
author: "Pascal Gentil"
authorRole: "Chef de projet Sage X3"
company: "YOUR PARTNER"
date: 2015-02-08
lang: "fr"
---
J'ai le plaisir de travailler avec Jalil dans le cadre de déploiements de solutions chez nos clients. Il est toujours de bonne composition, disponible et prêt à rendre service. Ses qualités professionnelles sont reconnues par tous.

View file

@ -0,0 +1,8 @@
---
author: "Vanessa Boissard"
authorRole: "Psychologue sociale"
company: "AlterAlliance"
date: 2011-12-05
lang: "fr"
---
Jalil est un excellent manager et responsable de mission. Il fait à la fois du très bon travail et dirige merveilleusement ses équipes.

View file

@ -1,37 +0,0 @@
[
{
"dates": "2023 · Présent",
"role": "Consultant Développeur Senior",
"company": "Urssaf Caisse nationale",
"description": "Mission freelance - Architecture et développement d'applications métier.",
"logo": ""
},
{
"dates": "2018 · Présent",
"role": "Organisateur",
"company": "Software Crafters Albi",
"description": "Animation de la communauté locale de développeurs passionnés par le craft.",
"logo": ""
},
{
"dates": "2015 · 2016",
"role": "Fondateur",
"company": "while42",
"description": "Réseau mondial de développeurs expatriés - communauté d'entraide et de partage.",
"logo": ""
},
{
"dates": "2003 · 2006",
"role": "Créateur",
"company": "Projets personnels",
"description": "N.Gine (CMS propriétaire), ICU (plateforme de partage photo), Débats.co (débat politique collaboratif).",
"logo": ""
},
{
"dates": "2001 · 2003",
"role": "Étudiant",
"company": "UVSQ - Université de Versailles",
"description": "Meilleur projet de programmation de l'année 2003.",
"logo": ""
}
]

View file

@ -1,14 +0,0 @@
[
{
"name": "Email.ML",
"description": "Minimalist temporary Email.",
"image": "/assets/images/projects/email.ml.png",
"url": "https://email.ml"
},
{
"name": "DNS.Surf",
"description": "Querying DNS Resolution Results in Different Regions Worldwide.",
"image": "/assets/images/projects/dns.surf.png",
"url": "https://dns.surf"
}
]

28
src/data/skills.json Normal file
View file

@ -0,0 +1,28 @@
{
"categories": [
{
"name": { "fr": "Langages", "en": "Languages", "ar": "اللغات" },
"skills": ["TypeScript", "JavaScript", "PHP", "Elixir", "Kotlin", "Haskell", "Java", "C#", "SQL", "HTML"]
},
{
"name": { "fr": "Frameworks & Librairies", "en": "Frameworks & Libraries", "ar": "الأطر والمكتبات" },
"skills": ["React.js", "Redux", "Node.js", "NestJS", "Symfony", "CakePHP", "Eleventy", "RxJS", "Ramda", "redux-saga", "Publicodes"]
},
{
"name": { "fr": "Pratiques", "en": "Practices", "ar": "الممارسات" },
"skills": ["TDD", "Clean Code", "Software Craftsmanship", "Domain Driven Design", "Hexagonal Architecture", "Functional Programming", "OOP"]
},
{
"name": { "fr": "Outils & Infrastructure", "en": "Tools & Infrastructure", "ar": "الأدوات والبنية التحتية" },
"skills": ["Docker", "Git", "Webpack", "Vite", "Nx", "GNU Make", "Linux", "GitHub", "PostgreSQL", "MongoDB", "Subversion"]
},
{
"name": { "fr": "APIs & Protocoles", "en": "APIs & Protocols", "ar": "واجهات وبروتوكولات" },
"skills": ["REST", "GraphQL"]
},
{
"name": { "fr": "Autres", "en": "Other", "ar": "أخرى" },
"skills": ["Team Lead", "Project Management", "Training", "E-commerce", "Web Extension", "Android", "Photography"]
}
]
}

Some files were not shown because too many files have changed in this diff Show more