Compare commits

...

15 commits

Author SHA1 Message Date
ebd074b866 Théâtre : section La Pièce (Compagnie AspiRêves, mise en scène Michel Cals) 2026-03-12 00:29:13 +01:00
f88a17b0ee Logos clients dans la mini-timeline /code (FR/EN/AR) 2026-03-12 00:28:06 +01:00
3d67c2a320 Urssaf : Télétravail / Montreuil 2026-03-12 00:03:36 +01:00
677142a7c4 Lieux : télétravail en FR, Remote en EN, Veepee Saint-Denis 2026-03-12 00:01:59 +01:00
663ce9a879 DisMoi : Remote / Bordeaux 2026-03-12 00:00:59 +01:00
973b2faa04 Libeo : Remote / Paris 2026-03-12 00:00:34 +01:00
5dfdbd88ba GoBuild : Remote / Lyon 2026-03-12 00:00:13 +01:00
78a72bfb92 Parcours : dates/lieux plus visibles en mode nuit (opacité 80%, taille sm), ARaymond Remote / Grenoble 2026-03-11 23:59:36 +01:00
6b3ceef903 GoBuild : type employment → freelance 2026-03-11 23:48:58 +01:00
0a4ed28fc0 Correction des dates et lieux des expériences d'après l'export LinkedIn 2026-03-11 23:47:32 +01:00
c8f444993d Ajout logo ESN 81 2026-03-11 23:36:12 +01:00
52aaa0a5aa Ajout logo GoBuild (Go-Decision) 2026-03-11 23:33:56 +01:00
88ed94dca3 Ajout logo Team Logics 2026-03-11 23:29:37 +01:00
f32cd09940 Tri des expériences par date de fin décroissante puis date de début (parcours et /code, FR/EN/AR) 2026-03-11 23:21:54 +01:00
366d18764b Héritage i18n : les fichiers EN/AR ne surchargent que les champs traduits, les métadonnées partagées sont héritées de la base FR
Ajout de getLocalizedCollection/getLocalizedEntry dans content-i18n.ts pour fusionner automatiquement les entrées localisées avec leur base FR. Schémas adaptés (champs partagés optionnels), 78 fichiers de contenu allégés, consommateurs migrés.
2026-03-11 23:17:19 +01:00
120 changed files with 369 additions and 567 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -1,7 +1,8 @@
--- ---
import { getCollection, render } from "astro:content"; import { render } from "astro:content";
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import { t, getDateLocale, type Locale } from "../../utils/i18n"; import { t, getDateLocale, type Locale } from "../../utils/i18n";
import { getLocalizedCollection } from "../../utils/content-i18n";
import "../../styles/exp-card.css"; import "../../styles/exp-card.css";
interface Props { interface Props {
@ -53,9 +54,14 @@ function computeDuration(startStr: string, endStr?: string) {
return formatDuration(years, months); return formatDuration(years, months);
} }
const experiences = (await getCollection("experiences")) const experiences = (await getLocalizedCollection("experiences", locale))
.filter((e) => e.data.lang === locale && !e.data.draft) .filter((e) => !e.data.draft)
.sort((a, b) => (b.data.startDate > a.data.startDate ? 1 : -1)); .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 presentLabel = t('career', 'present', locale); const presentLabel = t('career', 'present', locale);
const logoAltPrefix = t('career', 'logoAlt', locale); const logoAltPrefix = t('career', 'logoAlt', locale);
@ -107,11 +113,11 @@ const logoAltPrefix = t('career', 'logoAlt', locale);
<span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}> <span class:list={["inline-block px-2 py-0.5 text-[11px] font-medium rounded-full border", colors.badge]}>
{label} {label}
</span> </span>
<span class="exp-meta text-xs"> <span class="exp-meta text-sm">
{start} — {end} {start} — {end}
</span> </span>
<span class="exp-meta text-xs">· {duration}</span> <span class="exp-meta text-sm">· {duration}</span>
{exp.data.location && <span class="exp-meta text-xs">· {exp.data.location}</span>} {exp.data.location && <span class="exp-meta text-sm">· {exp.data.location}</span>}
</div> </div>
<h3 class="text-xl font-bold pe-20">{exp.data.role}</h3> <h3 class="text-xl font-bold pe-20">{exp.data.role}</h3>

View file

@ -3,7 +3,7 @@ import CategoryNav from './CategoryNav.astro';
import HeroViewport from './HeroViewport.astro'; import HeroViewport from './HeroViewport.astro';
import Lightbox from './Lightbox.astro'; import Lightbox from './Lightbox.astro';
import { Picture } from 'astro:assets'; import { Picture } from 'astro:assets';
import { getEntry } from 'astro:content'; import { getLocalizedEntry } from '../../utils/content-i18n';
import { getCategoryEntryId, type Locale } from '../../utils/i18n'; import { getCategoryEntryId, type Locale } from '../../utils/i18n';
interface Props { interface Props {
@ -13,10 +13,9 @@ interface Props {
const { category, lang = 'fr' } = Astro.props; const { category, lang = 'fr' } = Astro.props;
// Récupérer les métadonnées de la catégorie (localisées avec fallback FR) // Récupérer les métadonnées de la catégorie (localisées avec fusion FR)
const entryId = getCategoryEntryId(category, lang); const entryId = getCategoryEntryId(category, lang);
const categoryData = await getEntry('photoCategories', entryId) const categoryData = await getLocalizedEntry('photoCategories', entryId, lang);
?? await getEntry('photoCategories', category);
// Auto-détection des images du dossier de la catégorie // Auto-détection des images du dossier de la catégorie
const allImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/photos/categories/**/*.{jpg,jpeg,png,webp}'); const allImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/photos/categories/**/*.{jpg,jpeg,png,webp}');

View file

@ -1,5 +1,5 @@
--- ---
import { getCollection } from 'astro:content'; import { getLocalizedCollection } from '../../utils/content-i18n';
import HomeIcon from '../icons/HomeIcon.astro'; import HomeIcon from '../icons/HomeIcon.astro';
import { t, getPhotoBasePath, getPhotoBlogPath, getPhotoAlbumsPath, getHomePath, type Locale } from '../../utils/i18n'; import { t, getPhotoBasePath, getPhotoBlogPath, getPhotoAlbumsPath, getHomePath, type Locale } from '../../utils/i18n';
@ -15,10 +15,8 @@ const photoBasePath = getPhotoBasePath(lang);
const homePath = getHomePath(lang); const homePath = getHomePath(lang);
// Récupérer les catégories depuis la collection, filtrées par langue // Récupérer les catégories depuis la collection, filtrées par langue
const allCategories = await getCollection('photoCategories'); const localizedCategories = await getLocalizedCollection('photoCategories', lang);
const langCategories = allCategories.filter(c => (c.data.lang ?? 'fr') === lang); const sortedCategories = localizedCategories.sort((a, b) => (a.data.order || 99) - (b.data.order || 99));
const effectiveCategories = langCategories.length > 0 ? langCategories : allCategories.filter(c => (c.data.lang ?? 'fr') === 'fr');
const sortedCategories = effectiveCategories.sort((a, b) => (a.data.order || 99) - (b.data.order || 99));
// Extraire l'id de base (sans suffixe de langue) // Extraire l'id de base (sans suffixe de langue)
const categories = sortedCategories.map(cat => ({ const categories = sortedCategories.map(cat => ({

View file

@ -1,5 +1,5 @@
--- ---
import { getCollection } from 'astro:content'; import { getLocalizedCollection } from '../../utils/content-i18n';
import { t, getPhotoBlogPath, getPhotoAlbumsPath, type Locale } from '../../utils/i18n'; import { t, getPhotoBlogPath, getPhotoAlbumsPath, type Locale } from '../../utils/i18n';
interface Props { interface Props {
@ -9,10 +9,8 @@ interface Props {
const { lang = 'fr' } = Astro.props; const { lang = 'fr' } = Astro.props;
// Récupérer les catégories filtrées par langue // Récupérer les catégories filtrées par langue
const allCategories = await getCollection('photoCategories'); const sortedCategories = (await getLocalizedCollection('photoCategories', lang))
const langCategories = allCategories.filter(c => (c.data.lang ?? 'fr') === lang); .sort((a, b) => (a.data.order || 99) - (b.data.order || 99));
const effectiveCategories = langCategories.length > 0 ? langCategories : allCategories.filter(c => (c.data.lang ?? 'fr') === 'fr');
const sortedCategories = effectiveCategories.sort((a, b) => (a.data.order || 99) - (b.data.order || 99));
--- ---
<section id="explore-section" class="explore-section"> <section id="explore-section" class="explore-section">

View file

@ -1,5 +1,5 @@
--- ---
import { getCollection } from 'astro:content'; import { getLocalizedCollection } from '../../utils/content-i18n';
import { t, type Locale } from '../../utils/i18n'; import { t, type Locale } from '../../utils/i18n';
interface Props { interface Props {
@ -15,12 +15,10 @@ const { images, albumTitle = '', showCategory = false, category = '', lang = 'fr
const imagesForJS = JSON.stringify(images); const imagesForJS = JSON.stringify(images);
// Construire les labels depuis la collection filtrée par langue // Construire les labels depuis la collection filtrée par langue
const allCategories = await getCollection('photoCategories'); const localizedCategories = await getLocalizedCollection('photoCategories', lang);
const langCategories = allCategories.filter(c => (c.data.lang ?? 'fr') === lang);
const effectiveCategories = langCategories.length > 0 ? langCategories : allCategories.filter(c => (c.data.lang ?? 'fr') === 'fr');
const categoryLabels: Record<string, string> = { const categoryLabels: Record<string, string> = {
'blog': t('photo', 'photoFeed', lang), 'blog': t('photo', 'photoFeed', lang),
...Object.fromEntries(effectiveCategories.map(cat => [cat.id.replace(/\.(en|ar)$/, ''), cat.data.title])) ...Object.fromEntries(localizedCategories.map(cat => [cat.id.replace(/\.(en|ar)$/, ''), cat.data.title]))
}; };
--- ---

View file

@ -2,7 +2,7 @@
import PhotoLayout from '../../../layouts/PhotoLayout.astro'; import PhotoLayout from '../../../layouts/PhotoLayout.astro';
import CategoryGrid from '../CategoryGrid.astro'; import CategoryGrid from '../CategoryGrid.astro';
import { getCategoryEntryId, type Locale } from '../../../utils/i18n'; import { getCategoryEntryId, type Locale } from '../../../utils/i18n';
import { getEntry } from 'astro:content'; import { getLocalizedEntry } from '../../../utils/content-i18n';
interface Props { interface Props {
category: string; category: string;
@ -13,8 +13,7 @@ const { category, lang = 'fr' } = Astro.props;
// Récupérer le titre localisé pour le title de la page // Récupérer le titre localisé pour le title de la page
const entryId = getCategoryEntryId(category, lang); const entryId = getCategoryEntryId(category, lang);
const categoryData = await getEntry('photoCategories', entryId) const categoryData = await getLocalizedEntry('photoCategories', entryId, lang);
?? await getEntry('photoCategories', category);
const categoryLabel = categoryData?.data.title || category; const categoryLabel = categoryData?.data.title || category;
const categorySubtitle = categoryData?.data.subtitle || ""; const categorySubtitle = categoryData?.data.subtitle || "";

View file

@ -1,7 +1,7 @@
--- ---
import PhotoLayout from '../../../layouts/PhotoLayout.astro'; import PhotoLayout from '../../../layouts/PhotoLayout.astro';
import CategoryNav from '../CategoryNav.astro'; import CategoryNav from '../CategoryNav.astro';
import { getCollection } from 'astro:content'; import { getLocalizedCollection } from '../../../utils/content-i18n';
import { Picture } from 'astro:assets'; import { Picture } from 'astro:assets';
import { t, getPhotoBlogPath, getDateLocale, getPostBaseSlug, type Locale } from '../../../utils/i18n'; import { t, getPhotoBlogPath, getDateLocale, getPostBaseSlug, type Locale } from '../../../utils/i18n';
@ -20,8 +20,7 @@ const allImages = import.meta.glob<{ default: ImageMetadata }>(
); );
// Récupération des posts photo filtrés par langue // Récupération des posts photo filtrés par langue
const allPhotoBlogPosts = (await getCollection('photoBlogPosts')) const allPhotoBlogPosts = await getLocalizedCollection('photoBlogPosts', lang);
.filter(post => (post.data.lang ?? 'fr') === lang);
// Tri par date (plus récent en premier) // Tri par date (plus récent en premier)
const sortedPosts = allPhotoBlogPosts.sort((a, b) => const sortedPosts = allPhotoBlogPosts.sort((a, b) =>

View file

@ -37,19 +37,19 @@ const projectsCollection = defineCollection({
schema: z.object({ schema: z.object({
title: z.string(), title: z.string(),
description: z.string(), description: z.string(),
date: z.date(), date: z.date().optional(),
category: z.enum(['dev', 'comedy', 'photo']), category: z.enum(['dev', 'comedy', 'photo']).optional(),
technologies: z.array(z.string()).optional(), technologies: z.array(z.string()).optional(),
url: z.string().url().optional(), url: z.string().url().optional(),
github: z.string().url().optional(), github: z.string().url().optional(),
image: z.string().optional(), image: z.string().optional(),
imageAlt: z.string().optional(), imageAlt: z.string().optional(),
featured: z.boolean().default(false), featured: z.boolean().optional(),
draft: z.boolean().default(false), draft: z.boolean().optional(),
lang: z.enum(['fr', 'en', 'ar']).default('fr'), lang: z.enum(['fr', 'en', 'ar']).default('fr'),
}).transform((data) => ({ }).transform((data) => ({
...data, ...data,
dateFormatted: formatDate(data.date, data.lang), dateFormatted: data.date ? formatDate(data.date, data.lang) : undefined,
})), })),
}); });
@ -57,16 +57,16 @@ const experiencesCollection = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/experiences", ...stripExtension('md') }), loader: glob({ pattern: "**/*.md", base: "./src/content/experiences", ...stripExtension('md') }),
schema: z.object({ schema: z.object({
role: z.string(), role: z.string(),
company: z.string(), company: z.string().optional(),
companyUrl: z.string().url().optional(), companyUrl: z.string().url().optional(),
logo: z.string().optional(), logo: z.string().optional(),
location: z.string().optional(), location: z.string().optional(),
startDate: z.string(), startDate: z.string().optional(),
endDate: z.string().optional(), endDate: z.string().optional(),
technologies: z.array(z.string()).optional(), technologies: z.array(z.string()).optional(),
type: z.enum(['employment', 'freelance', 'teaching', 'community', 'entrepreneurship']), type: z.enum(['employment', 'freelance', 'teaching', 'community', 'entrepreneurship']).optional(),
featured: z.boolean().default(false), featured: z.boolean().optional(),
draft: z.boolean().default(false), draft: z.boolean().optional(),
lang: z.enum(['fr', 'en', 'ar']).default('fr'), lang: z.enum(['fr', 'en', 'ar']).default('fr'),
}), }),
}); });
@ -110,11 +110,11 @@ const photoBlogPostsCollection = defineCollection({
schema: z.object({ schema: z.object({
title: z.string(), title: z.string(),
description: z.string(), description: z.string(),
date: z.date(), date: z.date().optional(),
coverImage: z.string(), coverImage: z.string().optional(),
tags: z.array(z.string()).optional(), tags: z.array(z.string()).optional(),
featured: z.boolean().default(false), featured: z.boolean().optional(),
draft: z.boolean().default(false), draft: z.boolean().optional(),
lang: z.enum(['fr', 'en', 'ar']).default('fr'), lang: z.enum(['fr', 'en', 'ar']).default('fr'),
}), }),
}); });

View file

@ -1,14 +1,6 @@
--- ---
role: "مهندس معماري للواجهات" role: "مهندس معماري للواجهات"
company: "ARaymond" location: "عن بُعد / غرونوبل"
companyUrl: "https://www.araymond.com/"
logo: "araymond.png"
location: "غرونوبل"
startDate: "2022-01"
endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,14 +1,6 @@
--- ---
role: "Frontend Architect" role: "Frontend Architect"
company: "ARaymond" location: "Remote / Grenoble"
companyUrl: "https://www.araymond.com/"
logo: "araymond.png"
location: "Grenoble"
startDate: "2022-01"
endDate: "2023-01"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Architecte frontend"
company: "ARaymond" company: "ARaymond"
companyUrl: "https://www.araymond.com/" companyUrl: "https://www.araymond.com/"
logo: "araymond.png" logo: "araymond.png"
location: "Grenoble" location: "Télétravail / Grenoble"
startDate: "2022-01" startDate: "2022-07"
endDate: "2023-01" endDate: "2023-07"
technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"] technologies: ["TypeScript", "React.js", "Redux", "Nx", "Vite"]
type: "freelance" type: "freelance"
featured: true featured: true

View file

@ -1,13 +1,6 @@
--- ---
role: "أستاذ هندسة البرمجيات" role: "أستاذ هندسة البرمجيات"
company: "جامعة شامبوليون"
companyUrl: "https://www.univ-jfc.fr/"
logo: "champollion.png"
location: "ألبي" location: "ألبي"
startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,5 @@
--- ---
role: "Software Engineering Professor" role: "Software Engineering Professor"
company: "Université Champollion"
companyUrl: "https://www.univ-jfc.fr/"
logo: "champollion.png"
location: "Albi"
startDate: "2019-09"
technologies: ["TypeScript", "JavaScript", "Node.js", "TDD", "Clean Code"]
type: "teaching"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -1,13 +1,6 @@
--- ---
role: "حرفي برمجيات / مؤسس مشارك" role: "حرفي برمجيات / مؤسس مشارك"
company: "DisMoi" location: "عن بُعد / بوردو"
companyUrl: "https://github.com/dis-moi"
logo: "dismoi.png"
location: "عن بُعد"
startDate: "2019-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
type: "entrepreneurship"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,6 @@
--- ---
role: "Software Craftsman / Cofounder" role: "Software Craftsman / Cofounder"
company: "DisMoi" location: "Remote / Bordeaux"
companyUrl: "https://github.com/dis-moi"
logo: "dismoi.png"
location: "Remote"
startDate: "2019-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
type: "entrepreneurship"
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Software Craftsman / Cofondateur"
company: "DisMoi" company: "DisMoi"
companyUrl: "https://github.com/dis-moi" companyUrl: "https://github.com/dis-moi"
logo: "dismoi.png" logo: "dismoi.png"
location: "Remote" location: "Télétravail / Bordeaux"
startDate: "2019-01" startDate: "2019-02"
endDate: "2021-06" endDate: "2021-04"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"] technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "Node.js"]
type: "entrepreneurship" type: "entrepreneurship"
lang: "fr" lang: "fr"

View file

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

View file

@ -1,12 +1,5 @@
--- ---
role: "Development Teacher" 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" lang: "en"
--- ---

View file

@ -2,9 +2,10 @@
role: "Enseignant en développement" role: "Enseignant en développement"
company: "ESN 81" company: "ESN 81"
companyUrl: "https://www.esn81.fr/" companyUrl: "https://www.esn81.fr/"
logo: "esn81.png"
location: "Castres" location: "Castres"
startDate: "2020-09" startDate: "2020-01"
endDate: "2021-06" endDate: "2021-07"
technologies: ["JavaScript", "Node.js"] technologies: ["JavaScript", "Node.js"]
type: "teaching" type: "teaching"
lang: "fr" lang: "fr"

View file

@ -1,13 +1,6 @@
--- ---
role: "مطوّر ويب" role: "مطوّر ويب"
company: "e-Themis" location: "بور مارلي"
companyUrl: "https://www.e-themis.com/"
logo: "ethemis.png"
location: "فرساي"
startDate: "2002-06"
endDate: "2002-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL"]
type: "employment"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,5 @@
--- ---
role: "Web Developer" role: "Web Developer"
company: "e-Themis"
companyUrl: "https://www.e-themis.com/"
logo: "ethemis.png"
location: "Versailles"
startDate: "2002-06"
endDate: "2002-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL"]
type: "employment"
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Développeur web"
company: "e-Themis" company: "e-Themis"
companyUrl: "https://www.e-themis.com/" companyUrl: "https://www.e-themis.com/"
logo: "ethemis.png" logo: "ethemis.png"
location: "Versailles" location: "Port-Marly"
startDate: "2002-06" startDate: "2002-02"
endDate: "2002-12" endDate: "2002-11"
technologies: ["PHP", "JavaScript", "HTML", "MySQL"] technologies: ["PHP", "JavaScript", "HTML", "MySQL"]
type: "employment" type: "employment"
lang: "fr" lang: "fr"

View file

@ -1,13 +1,6 @@
--- ---
role: "مهندس برمجيات أول" role: "مهندس برمجيات أول"
company: "e-Themis" location: "سان جيرمان أون لاي"
companyUrl: "https://www.e-themis.com/"
logo: "ethemis.png"
location: "فرساي"
startDate: "2011-01"
endDate: "2015-12"
technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"]
type: "employment"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,5 @@
--- ---
role: "Senior Software Engineer" role: "Senior Software Engineer"
company: "e-Themis"
companyUrl: "https://www.e-themis.com/"
logo: "ethemis.png"
location: "Versailles"
startDate: "2011-01"
endDate: "2015-12"
technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"]
type: "employment"
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Ingénieur logiciel senior"
company: "e-Themis" company: "e-Themis"
companyUrl: "https://www.e-themis.com/" companyUrl: "https://www.e-themis.com/"
logo: "ethemis.png" logo: "ethemis.png"
location: "Versailles" location: "Saint-Germain-en-Laye"
startDate: "2011-01" startDate: "2011-12"
endDate: "2015-12" endDate: "2015-06"
technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"] technologies: ["PHP", "Symfony", "JavaScript", "MySQL", "Linux"]
type: "employment" type: "employment"
lang: "fr" lang: "fr"

View file

@ -1,11 +1,6 @@
--- ---
role: "مطوّر ويب وبرمجيات" role: "مطوّر ويب وبرمجيات"
company: "مستقل" location: "شاتو"
location: "إيل دو فرانس"
startDate: "2003-01"
endDate: "2006-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL", "Linux"]
type: "freelance"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,11 +1,5 @@
--- ---
role: "Web & Software Developer" 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" lang: "en"
--- ---

View file

@ -1,8 +1,8 @@
--- ---
role: "Développeur web & logiciel" role: "Développeur web & logiciel"
company: "Indépendant" company: "Indépendant"
location: "Île-de-France" location: "Chatou"
startDate: "2003-01" startDate: "2003-08"
endDate: "2006-12" endDate: "2006-12"
technologies: ["PHP", "JavaScript", "HTML", "MySQL", "Linux"] technologies: ["PHP", "JavaScript", "HTML", "MySQL", "Linux"]
type: "freelance" type: "freelance"

View file

@ -1,12 +1,6 @@
--- ---
role: "مدير تقني" role: "مدير تقني"
company: "GoBuild (Go-Decision)" location: "عن بُعد / ليون"
companyUrl: "https://www.gobuild.fr"
location: "ليون"
startDate: "2020-06"
endDate: "2022-01"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
type: "employment"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,12 +1,6 @@
--- ---
role: "CTO" role: "CTO"
company: "GoBuild (Go-Decision)" location: "Remote / Lyon"
companyUrl: "https://www.gobuild.fr"
location: "Lyon"
startDate: "2020-06"
endDate: "2022-01"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
type: "employment"
lang: "en" lang: "en"
--- ---

View file

@ -2,11 +2,12 @@
role: "CTO" role: "CTO"
company: "GoBuild (Go-Decision)" company: "GoBuild (Go-Decision)"
companyUrl: "https://www.gobuild.fr" companyUrl: "https://www.gobuild.fr"
location: "Lyon" logo: "go-decision.png"
startDate: "2020-06" location: "Télétravail / Lyon"
endDate: "2022-01" startDate: "2020-02"
endDate: "2022-06"
technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"] technologies: ["TypeScript", "React.js", "Elixir", "PostgreSQL", "Docker"]
type: "employment" type: "freelance"
lang: "fr" lang: "fr"
--- ---

View file

@ -1,13 +1,6 @@
--- ---
role: "مهندس برمجيات fullstack" role: "مهندس برمجيات fullstack"
company: "Libeo" location: "عن بُعد / باريس"
companyUrl: "https://www.libeo.io/"
logo: "libeo.png"
location: "عن بُعد"
startDate: "2021-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"]
type: "freelance"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,6 @@
--- ---
role: "Fullstack Software Engineer" role: "Fullstack Software Engineer"
company: "Libeo" location: "Remote / Paris"
companyUrl: "https://www.libeo.io/"
logo: "libeo.png"
location: "Remote"
startDate: "2021-01"
endDate: "2021-06"
technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"]
type: "freelance"
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Ingénieur logiciel fullstack"
company: "Libeo" company: "Libeo"
companyUrl: "https://www.libeo.io/" companyUrl: "https://www.libeo.io/"
logo: "libeo.png" logo: "libeo.png"
location: "Remote" location: "Télétravail / Paris"
startDate: "2021-01" startDate: "2021-02"
endDate: "2021-06" endDate: "2021-05"
technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"] technologies: ["TypeScript", "React.js", "Node.js", "GraphQL"]
type: "freelance" type: "freelance"
lang: "fr" lang: "fr"

View file

@ -1,13 +1,6 @@
--- ---
role: "مهندس برمجيات أول" role: "مهندس برمجيات أول"
company: "Obat"
companyUrl: "https://www.obat.fr/"
logo: "obat.png"
location: "عن بُعد" location: "عن بُعد"
startDate: "2023-02"
endDate: "2024-01"
technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"]
type: "freelance"
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,6 @@
--- ---
role: "Senior Software Engineer" role: "Senior Software Engineer"
company: "Obat"
companyUrl: "https://www.obat.fr/"
logo: "obat.png"
location: "Remote" location: "Remote"
startDate: "2023-02"
endDate: "2024-01"
technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"]
type: "freelance"
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Ingénieur logiciel senior"
company: "Obat" company: "Obat"
companyUrl: "https://www.obat.fr/" companyUrl: "https://www.obat.fr/"
logo: "obat.png" logo: "obat.png"
location: "Remote" location: "Télétravail"
startDate: "2023-02" startDate: "2023-12"
endDate: "2024-01" endDate: "2024-04"
technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"] technologies: ["TypeScript", "React.js", "Node.js", "NestJS", "PostgreSQL"]
type: "freelance" type: "freelance"
lang: "fr" lang: "fr"

View file

@ -1,12 +1,6 @@
--- ---
role: "مؤسّس ومدير عام" role: "مؤسّس ومدير عام"
company: "Team Logics"
location: "فرساي" location: "فرساي"
startDate: "2007-01"
endDate: "2011-12"
technologies: ["PHP", "CakePHP", "JavaScript", "MySQL", "Linux"]
type: "entrepreneurship"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,12 +1,5 @@
--- ---
role: "Founder & CEO" 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" lang: "en"
--- ---

View file

@ -1,9 +1,10 @@
--- ---
role: "Fondateur & CEO" role: "Fondateur & CEO"
company: "Team Logics" company: "Team Logics"
logo: "team-logics.png"
location: "Versailles" location: "Versailles"
startDate: "2007-01" startDate: "2007-01"
endDate: "2011-12" endDate: "2011-11"
technologies: ["PHP", "CakePHP", "JavaScript", "MySQL", "Linux"] technologies: ["PHP", "CakePHP", "JavaScript", "MySQL", "Linux"]
type: "entrepreneurship" type: "entrepreneurship"
featured: true featured: true

View file

@ -1,13 +1,6 @@
--- ---
role: "مطوّر رئيسي" role: "مطوّر رئيسي"
company: "Urssaf Caisse nationale" location: "عن بُعد / مونتروي"
companyUrl: "https://www.urssaf.fr/"
logo: "urssaf.png"
location: "عن بُعد / باريس"
startDate: "2024-02"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"]
type: "freelance"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,13 +1,6 @@
--- ---
role: "Lead Developer" role: "Lead Developer"
company: "Urssaf Caisse nationale" location: "Remote / Montreuil"
companyUrl: "https://www.urssaf.fr/"
logo: "urssaf.png"
location: "Remote / Paris"
startDate: "2024-02"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"]
type: "freelance"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -3,7 +3,7 @@ role: "Lead Developer"
company: "Urssaf Caisse nationale" company: "Urssaf Caisse nationale"
companyUrl: "https://www.urssaf.fr/" companyUrl: "https://www.urssaf.fr/"
logo: "urssaf.png" logo: "urssaf.png"
location: "Remote / Paris" location: "Télétravail / Montreuil"
startDate: "2024-02" startDate: "2024-02"
technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"] technologies: ["TypeScript", "React.js", "Publicodes", "Node.js", "GitHub"]
type: "freelance" type: "freelance"

View file

@ -1,14 +1,6 @@
--- ---
role: "مطوّر رئيسي ← قائد تقني" role: "مطوّر رئيسي ← قائد تقني"
company: "Veepee" location: "سان دوني"
companyUrl: "https://www.veepee.com/"
logo: "veepee.png"
location: "باريس"
startDate: "2016-02"
endDate: "2019-06"
technologies: ["TypeScript", "JavaScript", "React.js", "Redux", "redux-saga", "RxJS", "Node.js", "Webpack"]
type: "freelance"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,14 +1,5 @@
--- ---
role: "Lead Developer → Tech Lead" role: "Lead Developer → Tech Lead"
company: "Veepee"
companyUrl: "https://www.veepee.com/"
logo: "veepee.png"
location: "Paris"
startDate: "2016-02"
endDate: "2019-06"
technologies: ["TypeScript", "JavaScript", "React.js", "Redux", "redux-saga", "RxJS", "Node.js", "Webpack"]
type: "freelance"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -3,9 +3,9 @@ role: "Lead Developer → Tech Lead"
company: "Veepee" company: "Veepee"
companyUrl: "https://www.veepee.com/" companyUrl: "https://www.veepee.com/"
logo: "veepee.png" logo: "veepee.png"
location: "Paris" location: "Saint-Denis"
startDate: "2016-02" startDate: "2016-01"
endDate: "2019-06" endDate: "2019-03"
technologies: ["TypeScript", "JavaScript", "React.js", "Redux", "redux-saga", "RxJS", "Node.js", "Webpack"] technologies: ["TypeScript", "JavaScript", "React.js", "Redux", "redux-saga", "RxJS", "Node.js", "Webpack"]
type: "freelance" type: "freelance"
featured: true featured: true

View file

@ -1,11 +1,6 @@
--- ---
title: "تصوير إيرول" title: "تصوير إيرول"
description: "أراد إيرول صورًا له لإعداد كتاب أعمال. عملنا طوال اليوم لتنويع الأجواء..." description: "أراد إيرول صورًا له لإعداد كتاب أعمال. عملنا طوال اليوم لتنويع الأجواء..."
date: 2011-10-02
coverImage: "18-Eroll-Shooting-1-19.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Shooting Eroll" title: "Shooting Eroll"
description: "Eroll wanted some photos of him in order to have a modeling book. We worked all day in order to have some ambiance variations..." description: "Eroll wanted some photos of him in order to have a modeling book. We worked all day in order to have some ambiance variations..."
date: 2011-10-02
coverImage: "18-Eroll-Shooting-1-19.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Inox Park Paris 2011" title: "Inox Park Paris 2011"
description: "بعد نجاحه في 2010، يعود مهرجان Inox Park Paris إلى جزيرة شاتو في نسخته الثانية. ثلاث مسارح، 15 دي جي، 12 ساعة من الحفل في الهواء الطلق: Tiësto، Joachim Garraud، Sven Väth، Steve Aoki..." description: "بعد نجاحه في 2010، يعود مهرجان Inox Park Paris إلى جزيرة شاتو في نسخته الثانية. ثلاث مسارح، 15 دي جي، 12 ساعة من الحفل في الهواء الطلق: Tiësto، Joachim Garraud، Sven Väth، Steve Aoki..."
date: 2011-09-10
coverImage: "01-Inox-Park-Paris-Chatou-2011.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Inox Park Paris 2011" title: "Inox Park Paris 2011"
description: "After its 2010 success, the Inox Park Paris Electro Festival is back to the island of Chatou for its second edition. Three stages, 15 DJs, 12 hours of outdoor party: Tiësto, Joachim Garraud, Sven Väth, Steve Aoki..." description: "After its 2010 success, the Inox Park Paris Electro Festival is back to the island of Chatou for its second edition. Three stages, 15 DJs, 12 hours of outdoor party: Tiësto, Joachim Garraud, Sven Väth, Steve Aoki..."
date: 2011-09-10
coverImage: "01-Inox-Park-Paris-Chatou-2011.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "عملية المحفظة 2012" title: "عملية المحفظة 2012"
description: "توزيع محافظ مدرسية مجانية في مدارس محرومة من طرف جمعية محلية (JCI)، طنجة، المغرب." description: "توزيع محافظ مدرسية مجانية في مدارس محرومة من طرف جمعية محلية (JCI)، طنجة، المغرب."
date: 2012-09-30
coverImage: "35-Moroccan-Schoolgirls.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Schoolbag Operation 2012" title: "Schoolbag Operation 2012"
description: "During a distribution of free schoolbags in poor schools by a local association (JCI), Tangier, Morocco." description: "During a distribution of free schoolbags in poor schools by a local association (JCI), Tangier, Morocco."
date: 2012-09-30
coverImage: "35-Moroccan-Schoolgirls.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "جولة في طنجة" title: "جولة في طنجة"
description: "جولة فوتوغرافية في شوارع طنجة." description: "جولة فوتوغرافية في شوارع طنجة."
date: 2012-05-26
coverImage: "01-Observer-le-changement.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Tangier Walk" title: "Tangier Walk"
description: "A photographic walk through the streets of Tangier." description: "A photographic walk through the streets of Tangier."
date: 2012-05-26
coverImage: "01-Observer-le-changement.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "هلسنكي" title: "هلسنكي"
description: "اختفى الثلج من هلسنكي وسرعان ما أفسح المجال للربيع..." description: "اختفى الثلج من هلسنكي وسرعان ما أفسح المجال للربيع..."
date: 2013-05-15
coverImage: "01-Library-of-University-of-Helsinki.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Helsinki" title: "Helsinki"
description: "The snow has disappeared from Helsinki and quickly gave way to spring..." description: "The snow has disappeared from Helsinki and quickly gave way to spring..."
date: 2013-05-15
coverImage: "01-Library-of-University-of-Helsinki.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "نزهة في إفران" title: "نزهة في إفران"
description: "نزهة شتوية في جبال الأطلس المتوسط." description: "نزهة شتوية في جبال الأطلس المتوسط."
date: 2013-01-13
coverImage: "03-3.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Ifrane Hike" title: "Ifrane Hike"
description: "Winter hike in the Middle Atlas mountains." description: "Winter hike in the Middle Atlas mountains."
date: 2013-01-13
coverImage: "03-3.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "London Calling" title: "London Calling"
description: "عطلة نهاية أسبوع فوتوغرافية في لندن." description: "عطلة نهاية أسبوع فوتوغرافية في لندن."
date: 2014-07-15
coverImage: "01-The-sky-inside.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "London Calling" title: "London Calling"
description: "A photographic weekend in London." description: "A photographic weekend in London."
date: 2014-07-15
coverImage: "01-The-sky-inside.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "أحد سيكواني" title: "أحد سيكواني"
description: "نزهة يوم أحد على ضفاف نهر السين." description: "نزهة يوم أحد على ضفاف نهر السين."
date: 2014-05-18
coverImage: "04-La-Defense-seen-from-Pont-de-Suresnes-2.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Sequanian Sunday" title: "Sequanian Sunday"
description: "A sunday walk near the Seine." description: "A sunday walk near the Seine."
date: 2014-05-18
coverImage: "04-La-Defense-seen-from-Pont-de-Suresnes-2.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "تجوال في مدينة طنجة القديمة" title: "تجوال في مدينة طنجة القديمة"
description: "أثناء التجوال في أزقة طنجة القديمة، صادفت ساعاتيًا، ونجّارًا، وقمرًا عملاقًا..." description: "أثناء التجوال في أزقة طنجة القديمة، صادفت ساعاتيًا، ونجّارًا، وقمرًا عملاقًا..."
date: 2014-08-10
coverImage: "01-The-watchmaker.jpg"
tags: []
featured: true
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Wandering Tangier Medina" title: "Wandering Tangier Medina"
description: "Walking in the streets of the old Tangier, met a watchmaker, a carpenter and a super-moon..." description: "Walking in the streets of the old Tangier, met a watchmaker, a carpenter and a super-moon..."
date: 2014-08-10
coverImage: "01-The-watchmaker.jpg"
tags: []
featured: true
draft: false
lang: en lang: en
--- ---

View file

@ -4,11 +4,6 @@ description: |
إنيغما كانت مسابقة بحث عن الكنز بين المدارس نظّمها المركز العالي للدراسات CESIM يوم السبت، تحت عنوان «البحث عن كنز ابن بطوطة المنسي». 4 فرق طنجاوية دُعيت لتمثيل مؤسساتها. إنيغما كانت مسابقة بحث عن الكنز بين المدارس نظّمها المركز العالي للدراسات CESIM يوم السبت، تحت عنوان «البحث عن كنز ابن بطوطة المنسي». 4 فرق طنجاوية دُعيت لتمثيل مؤسساتها.
تغطية. تغطية.
date: 2015-04-25
coverImage: "01-Enigma-v1.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -4,11 +4,6 @@ description: |
Enigma was an inter-school treasure hunt organized this saturday by the CESIM, on the theme "In search of forgotten treasure of Ibn Battuta". 4 Tangier teams were invited to represent their respective institutions. Enigma was an inter-school treasure hunt organized this saturday by the CESIM, on the theme "In search of forgotten treasure of Ibn Battuta". 4 Tangier teams were invited to represent their respective institutions.
Recap. Recap.
date: 2015-04-25
coverImage: "01-Enigma-v1.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Field of Stones" title: "Field of Stones"
description: "كواليس تصوير غلاف ألبوم ماركو وولتر. أراد أن تُلتقط الصورة في سينماتيك طنجة. لا وقت، لا إضاءة، لكن لا خيار. حاولنا تقديم أفضل ما لدينا..." description: "كواليس تصوير غلاف ألبوم ماركو وولتر. أراد أن تُلتقط الصورة في سينماتيك طنجة. لا وقت، لا إضاءة، لكن لا خيار. حاولنا تقديم أفضل ما لدينا..."
date: 2015-04-02
coverImage: "01-Marco-Wolter-Field-of-Stones-2.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Field of Stones" title: "Field of Stones"
description: "Making of the album cover for Marco Wolter. He wanted it to be shot in the Cinémathèque of Tangier. We had no time, no light, but no choice. We tried to make the best of it..." description: "Making of the album cover for Marco Wolter. He wanted it to be shot in the Cinémathèque of Tangier. We had no time, no light, but no choice. We tried to make the best of it..."
date: 2015-04-02
coverImage: "01-Marco-Wolter-Field-of-Stones-2.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "لا رياح في لاس كويفاس" title: "لا رياح في لاس كويفاس"
description: "كان من المفترض أن يكون يومًا مثاليًا لتطيير طائرتنا الورقية: مشمس وعاصف. مشمس كان، لكن الرياح لم تأتِ أبدًا." description: "كان من المفترض أن يكون يومًا مثاليًا لتطيير طائرتنا الورقية: مشمس وعاصف. مشمس كان، لكن الرياح لم تأتِ أبدًا."
date: 2015-01-10
coverImage: "13-No-wind-at-Las-Cuevas.jpg"
tags: []
featured: false
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "No Wind at Las Cuevas" title: "No Wind at Las Cuevas"
description: "It was supposed to be a perfect day for flying our kite: sunny and windy. Sunny it was, but the wind never came." description: "It was supposed to be a perfect day for flying our kite: sunny and windy. Sunny it was, but the wind never came."
date: 2015-01-10
coverImage: "13-No-wind-at-Las-Cuevas.jpg"
tags: []
featured: false
draft: false
lang: en lang: en
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "زفاف أورور وتوما" title: "زفاف أورور وتوما"
description: "كان لي شرف ومتعة أن أكون شاهد توما في زفافه الجميل مع أورور. ليس سهلًا التصوير في نفس الوقت، لكن كل الصور مليئة بالحب." description: "كان لي شرف ومتعة أن أكون شاهد توما في زفافه الجميل مع أورور. ليس سهلًا التصوير في نفس الوقت، لكن كل الصور مليئة بالحب."
date: 2015-09-26
coverImage: "10-Mariage-Aurore-Thomas-10.jpg"
tags: []
featured: true
draft: false
lang: ar lang: ar
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Wedding Aurore & Thomas" title: "Wedding Aurore & Thomas"
description: "I had the honor and pleasure to be Thomas' best man for his beautiful wedding with Aurore. Not easy to shoot pictures though, but all of them are filled with love." description: "I had the honor and pleasure to be Thomas' best man for his beautiful wedding with Aurore. Not easy to shoot pictures though, but all of them are filled with love."
date: 2015-09-26
coverImage: "10-Mariage-Aurore-Thomas-10.jpg"
tags: []
featured: true
draft: false
lang: en lang: en
--- ---

View file

@ -1,6 +1,5 @@
{ {
"title": "ثقافات وتقاليد", "title": "ثقافات وتقاليد",
"subtitle": "ثراء التقاليد الإنسانية", "subtitle": "ثراء التقاليد الإنسانية",
"order": 4,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Cultures & Traditions", "title": "Cultures & Traditions",
"subtitle": "Richness of human traditions", "subtitle": "Richness of human traditions",
"order": 4,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "محرّكات", "title": "محرّكات",
"subtitle": "ميكانيكا وقوة في حركة", "subtitle": "ميكانيكا وقوة في حركة",
"order": 7,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Engines", "title": "Engines",
"subtitle": "Mechanics and power in motion", "subtitle": "Mechanics and power in motion",
"order": 7,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "يوميات", "title": "يوميات",
"subtitle": "لحظات من الحياة اليومية", "subtitle": "لحظات من الحياة اليومية",
"order": 8,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Everyday Life", "title": "Everyday Life",
"subtitle": "Moments of everyday life", "subtitle": "Moments of everyday life",
"order": 8,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "موسيقى واحتفالات", "title": "موسيقى واحتفالات",
"subtitle": "نغمات وأغانٍ واهتزازات تحتفي بلحظات حياتنا الكبيرة والصغيرة", "subtitle": "نغمات وأغانٍ واهتزازات تحتفي بلحظات حياتنا الكبيرة والصغيرة",
"order": 5,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Music & Celebrations", "title": "Music & Celebrations",
"subtitle": "Notes, songs and vibrations celebrating life's big and small moments", "subtitle": "Notes, songs and vibrations celebrating life's big and small moments",
"order": 5,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "طبيعة", "title": "طبيعة",
"subtitle": "سحر العالم الطبيعي", "subtitle": "سحر العالم الطبيعي",
"order": 3,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Nature", "title": "Nature",
"subtitle": "The magic of the natural world", "subtitle": "The magic of the natural world",
"order": 3,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "مناظر طبيعية", "title": "مناظر طبيعية",
"subtitle": "جمال المناظر والأماكن", "subtitle": "جمال المناظر والأماكن",
"order": 2,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Landscapes", "title": "Landscapes",
"subtitle": "Beauty of landscapes and places", "subtitle": "Beauty of landscapes and places",
"order": 2,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "بورتريهات", "title": "بورتريهات",
"subtitle": "تعابير ومشاعر ملتقطة", "subtitle": "تعابير ومشاعر ملتقطة",
"order": 1,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Portraits", "title": "Portraits",
"subtitle": "Captured expressions and emotions", "subtitle": "Captured expressions and emotions",
"order": 1,
"lang": "en" "lang": "en"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "رياضة", "title": "رياضة",
"subtitle": "حركة وجهد وتجاوز للذات", "subtitle": "حركة وجهد وتجاوز للذات",
"order": 6,
"lang": "ar" "lang": "ar"
} }

View file

@ -1,6 +1,5 @@
{ {
"title": "Sports", "title": "Sports",
"subtitle": "Movement, effort and pushing limits", "subtitle": "Movement, effort and pushing limits",
"order": 6,
"lang": "en" "lang": "en"
} }

View file

@ -1,11 +1,6 @@
--- ---
title: "Débats.co" title: "Débats.co"
description: "منصّة تعاونية لتلخيص النقاشات المجتمعية. ويكيبيديا المواقف." description: "منصّة تعاونية لتلخيص النقاشات المجتمعية. ويكيبيديا المواقف."
date: 2015-01-01
category: "dev"
technologies: ["Next.js", "React", "TypeScript", "Supabase", "PostgreSQL", "Effect TS"]
url: "https://debats.co"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,11 +1,6 @@
--- ---
title: "Débats.co" title: "Débats.co"
description: "Collaborative platform for synthesizing public debates. The Wikipedia of public stances." description: "Collaborative platform for synthesizing public debates. The Wikipedia of public stances."
date: 2015-01-01
category: "dev"
technologies: ["Next.js", "React", "TypeScript", "Supabase", "PostgreSQL", "Effect TS"]
url: "https://debats.co"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -1,12 +1,6 @@
--- ---
title: "DisMoi" title: "DisMoi"
description: "إضافة متصفّح في مجال التكنولوجيا المدنية تضيف معلومات سياقية على أي صفحة ويب." description: "إضافة متصفّح في مجال التكنولوجيا المدنية تضيف معلومات سياقية على أي صفحة ويب."
date: 2019-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Redux", "Web Extension", "PHP", "Symfony"]
url: "https://www.dismoi.io/"
github: "https://github.com/dis-moi"
featured: true
lang: "ar" lang: "ar"
--- ---

View file

@ -1,12 +1,6 @@
--- ---
title: "DisMoi" title: "DisMoi"
description: "Civic tech browser extension that adds contextual information to any web page." 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", "PHP", "Symfony"]
url: "https://www.dismoi.io/"
github: "https://github.com/dis-moi"
featured: true
lang: "en" lang: "en"
--- ---

View file

@ -1,9 +1,6 @@
--- ---
title: "ICU" title: "ICU"
description: "منصة مشاركة صور عبر الإنترنت، مشروع شخصي تاريخي." description: "منصة مشاركة صور عبر الإنترنت، مشروع شخصي تاريخي."
date: 2005-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "ar" lang: "ar"
--- ---

View file

@ -1,9 +1,6 @@
--- ---
title: "ICU" title: "ICU"
description: "Online photo sharing platform, a historical personal project." description: "Online photo sharing platform, a historical personal project."
date: 2005-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "en" lang: "en"
--- ---

View file

@ -1,12 +1,6 @@
--- ---
title: "mon-entreprise.urssaf.fr" title: "mon-entreprise.urssaf.fr"
description: "المساعد الرسمي لروّاد الأعمال في فرنسا. أكثر من 20 محاكيًا اجتماعيًا-ضريبيًا، مليون مستخدم شهريًا." description: "المساعد الرسمي لروّاد الأعمال في فرنسا. أكثر من 20 محاكيًا اجتماعيًا-ضريبيًا، مليون مستخدم شهريًا."
date: 2024-01-01
category: "dev"
technologies: ["TypeScript", "React.js", "Publicodes", "Redux", "Node.js"]
url: "https://mon-entreprise.urssaf.fr/"
github: "https://github.com/betagouv/mon-entreprise"
featured: false
lang: "ar" lang: "ar"
--- ---

View file

@ -1,12 +1,6 @@
--- ---
title: "mon-entreprise.urssaf.fr" title: "mon-entreprise.urssaf.fr"
description: "The official assistant for entrepreneurs in France. Over 20 socio-fiscal simulators, one million users per month." 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", "Redux", "Node.js"]
url: "https://mon-entreprise.urssaf.fr/"
github: "https://github.com/betagouv/mon-entreprise"
featured: false
lang: "en" lang: "en"
--- ---

View file

@ -1,9 +1,6 @@
--- ---
title: "N.Gine" title: "N.Gine"
description: "نظام إدارة محتوى خاص بُني من الصفر، استُخدم للعديد من مشاريع العملاء." description: "نظام إدارة محتوى خاص بُني من الصفر، استُخدم للعديد من مشاريع العملاء."
date: 2004-01-01
category: "dev"
technologies: ["PHP", "JavaScript", "MySQL"]
lang: "ar" lang: "ar"
--- ---

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