export const defaultLocale = 'fr'; export const locales = ['fr', 'en', 'ar'] as const; export type Locale = typeof locales[number]; export function getLocaleFromUrl(url: URL): Locale { const [, locale] = url.pathname.split('/'); if (locales.includes(locale as Locale)) { return locale as Locale; } return defaultLocale; } export function getLocalizedPath(path: string, locale: Locale): string { if (locale === defaultLocale) { return path; } return `/${locale}${path}`; } export function removeLocaleFromPath(path: string): string { const segments = path.split('/').filter(Boolean); if (locales.includes(segments[0] as Locale)) { segments.shift(); } return '/' + segments.join('/'); } export interface LocalizedContent { fr: string; en: string; ar: string; } export const translations = { nav: { home: { fr: 'Accueil', en: 'Home', ar: 'الرئيسية' }, pro: { fr: 'Pro', en: 'Pro', ar: 'مهني' }, comedy: { fr: 'Comédie', en: 'Comedy', ar: 'كوميديا' }, photo: { fr: 'Photo', en: 'Photo', ar: 'تصوير' }, blog: { fr: 'Blog', en: 'Blog', ar: 'مدونة' }, about: { fr: 'À propos', en: 'About', ar: 'حول' }, projects: { fr: 'Projets', en: 'Projects', ar: 'مشاريع' }, talks: { fr: 'Talks', en: 'Talks', ar: 'محاضرات' }, gallery: { fr: 'Galerie', en: 'Gallery', ar: 'معرض' }, shows: { fr: 'Spectacles', en: 'Shows', ar: 'عروض' }, now: { fr: 'Maintenant', en: 'Now', ar: 'الآن' }, uses: { fr: 'Utilise', en: 'Uses', ar: 'يستخدم' }, }, common: { siteName: { fr: 'Jalil Arfaoui', en: 'Jalil Arfaoui', ar: 'جليل عرفاوي' }, readMore: { fr: 'Lire la suite', en: 'Read more', ar: 'اقرأ المزيد' }, backToHome: { fr: 'Retour à l\'accueil', en: 'Back to home', ar: 'العودة إلى الرئيسية' }, publishedOn: { fr: 'Publié le', en: 'Published on', ar: 'نشر في' }, by: { fr: 'par', en: 'by', ar: 'بواسطة' }, allPosts: { fr: 'Tous les articles', en: 'All posts', ar: 'جميع المقالات' }, recentPosts: { fr: 'Articles récents', en: 'Recent posts', ar: 'المقالات الأخيرة' }, categories: { fr: 'Catégories', en: 'Categories', ar: 'الفئات' }, tags: { fr: 'Tags', en: 'Tags', ar: 'علامات' }, search: { fr: 'Rechercher', en: 'Search', ar: 'بحث' }, darkMode: { fr: 'Mode sombre', en: 'Dark mode', ar: 'الوضع الداكن' }, lightMode: { fr: 'Mode clair', en: 'Light mode', ar: 'الوضع الفاتح' }, }, categories: { pro: { fr: 'Professionnel', en: 'Professional', ar: 'مهني' }, comedy: { fr: 'Comédie', en: 'Comedy', ar: 'كوميديا' }, photo: { fr: 'Photographie', en: 'Photography', ar: 'تصوير' }, dev: { fr: 'Développement', en: 'Development', ar: 'تطوير' }, }, photo: { galleryTitle: { fr: 'Galerie Photo', en: 'Photo Gallery', ar: 'معرض الصور' }, blogTitle: { fr: 'Blog Photo', en: 'Photo Blog', ar: 'مدونة الصور' }, photoFeed: { fr: 'Fil Photo', en: 'Photo Feed', ar: 'سلسلة الصور' }, categories: { fr: 'Catégories', en: 'Categories', ar: 'الفئات' }, browseByTheme: { fr: 'Parcourir les photos par thème', en: 'Browse photos by theme', ar: 'تصفّح الصور حسب الموضوع' }, feedDescription: { fr: 'Parcourir les séries chronologiques, reportages et histoires en images', en: 'Browse chronological series, reports and stories in images', ar: 'تصفّح السلاسل الزمنية والتقارير والقصص المصوّرة' }, viewFeed: { fr: 'Voir le fil', en: 'View feed', ar: 'عرض السلسلة' }, featured: { fr: 'À la une', en: 'Featured', ar: 'مميّز' }, about: { fr: 'À propos', en: 'About', ar: 'نبذة' }, contact: { fr: 'Contact', en: 'Contact', ar: 'تواصل' }, fullscreen: { fr: 'Plein écran', en: 'Fullscreen', ar: 'شاشة كاملة' }, close: { fr: 'Fermer', en: 'Close', ar: 'إغلاق' }, previousImage: { fr: 'Image précédente', en: 'Previous image', ar: 'الصورة السابقة' }, nextImage: { fr: 'Image suivante', en: 'Next image', ar: 'الصورة التالية' }, goToImage: { fr: "Aller à l'image", en: 'Go to image', ar: 'انتقل إلى الصورة' }, }, pages: { home: { title: { fr: 'Jalil Arfaoui', en: 'Jalil Arfaoui', ar: 'جليل عرفاوي' }, subtitle: { fr: 'Développeur • Comédien • Photographe', en: 'Developer • Comedian • Photographer', ar: 'مطور • ممثل كوميدي • مصور' }, description: { fr: 'Bienvenue dans mon univers créatif où le code rencontre l\'art', en: 'Welcome to my creative universe where code meets art', ar: 'مرحبًا بكم في عالمي الإبداعي حيث يلتقي الكود بالفن' } }, pro: { title: { fr: 'Parcours Professionnel', en: 'Professional Journey', ar: 'المسار المهني' }, description: { fr: 'Développeur passionné par le Software Craftsmanship', en: 'Developer passionate about Software Craftsmanship', ar: 'مطور شغوف بحرفية البرمجيات' } }, comedy: { title: { fr: 'Univers Comédie', en: 'Comedy Universe', ar: 'عالم الكوميديا' }, description: { fr: 'Acteur et créateur de contenus humoristiques', en: 'Actor and creator of humorous content', ar: 'ممثل ومنشئ محتوى فكاهي' } }, photo: { title: { fr: 'Portfolio Photo', en: 'Photo Portfolio', ar: 'معرض الصور' }, description: { fr: 'Capturer l\'instant, raconter une histoire', en: 'Capturing the moment, telling a story', ar: 'التقاط اللحظة، سرد قصة' } } } }; /** Helper de traduction typé */ export function t(section: keyof typeof translations, key: string, locale: Locale): string { const sectionData = translations[section] as Record; return sectionData?.[key]?.[locale] ?? sectionData?.[key]?.fr ?? key; } /** Chemin de base photo selon la langue */ export function getPhotoBasePath(locale: Locale): string { if (locale === 'ar') return '/ar/تصوير'; if (locale === 'en') return '/en/photo'; return '/photo'; } /** Chemin du blog photo selon la langue */ export function getPhotoBlogPath(locale: Locale): string { return `${getPhotoBasePath(locale)}/${locale === 'ar' ? 'مدونة' : 'blog'}`; } /** Chemin des albums photo selon la langue */ export function getPhotoAlbumsPath(locale: Locale): string { return `${getPhotoBasePath(locale)}/${locale === 'ar' ? 'ألبومات' : 'albums'}`; } /** Chemin "À propos" selon la langue */ export function getAboutPath(locale: Locale): string { if (locale === 'en') return '/en/about'; if (locale === 'ar') return '/ar/نبذة-عني'; return '/a-propos'; } /** Locale pour les dates */ export function getDateLocale(locale: Locale): string { const dateLocales: Record = { fr: 'fr-FR', en: 'en-US', ar: 'ar-SA' }; return dateLocales[locale]; } /** ID de catégorie localisé (portraits → portraits.en pour EN) */ export function getCategoryEntryId(categoryId: string, locale: Locale): string { return locale === 'fr' ? categoryId : `${categoryId}.${locale}`; } /** Chemin d'accueil selon la langue */ export function getHomePath(locale: Locale): string { return locale === 'fr' ? '/' : `/${locale}`; } /** Slug de base d'un photo blog post depuis son id (ex: "2015/enigma.en.md" → "enigma") */ export function getPostBaseSlug(postId: string): string { return postId.replace(/^\d{4}\//, '').replace(/\.(en|ar)?\.mdx?$/, ''); }