export type PublicSiteLanguage = 'en' | 'fr' | 'ar' export const PUBLIC_SITE_LANGUAGE_COOKIE = 'public-site-language' export function isPublicSiteLanguage(value: string | null | undefined): value is PublicSiteLanguage { return value === 'en' || value === 'fr' || value === 'ar' } export type PublicSiteDictionary = { lang: string dir: 'ltr' | 'rtl' siteNameFallback: string rentalCompanyFallback: string nav: { about: string vehicles: string offers: string pricing: string blog: string contact: string bookCar: string siteNavigation: string } home: { heroTitleFallback: string heroDescription: string viewOffers: string viewPricing: string contactCompany: string heroImageMissing: string activeOffers: string seeAllOffers: string noActiveOffers: string publishedVehicles: string available: (count: number) => string viewVehicle: string } about: { eyebrow: string defaultTagline: string location: string phone: string email: string whatsapp: string locationMissing: string phoneMissing: string emailMissing: string whatsappMissing: string heroImageMissing: string directBookingTitle: string directBookingBody: string publishedFleetTitle: string publishedFleetBody: string marketplaceReadyTitle: string marketplaceReadyBody: string companyDetails: string companyAddressMissing: string } contact: { title: string description: string } offers: { title: string empty: string noDescription: string bookOffer: string } pricing: { eyebrow: string title: string description: string popular: string acceptedPaymentMethods: string paymentsDescription: string faq: { paymentMethodsQuestion: string paymentMethodsAnswer: string connectPaymentsQuestion: string connectPaymentsAnswer: string supportedCurrenciesQuestion: string supportedCurrenciesAnswer: string } plans: { starterDescription: string growthDescription: string proDescription: string starterFeatures: string[] growthFeatures: string[] proFeatures: string[] } } blog: { eyebrow: string title: string description: string draftPlaceholder: string posts: Array<{ title: string excerpt: string category: string }> } vehicles: { title: string available: (count: number) => string noVehiclesTitle: string noVehiclesBody: string clearFilters: string noPhoto: string seats: (count: number) => string perDay: string viewDetails: string filters: { title: string clearAll: string category: string transmission: string maxPricePerDay: string upTo: string } unavailable: { eyebrow: string title: string body: string backHome: string } detail: { perDay: string bookNow: string back: string availableFrom: string unavailableNoDate: string } } booking: { loadingForm: string eyebrow: string title: string steps: { selectDates: string driverDetails: string reviewBooking: string payment: string } loadingVehicle: string vehicleNotFound: string vehicleLoadError: string vehicleAvailableFrom: (date: string) => string vehicleUnavailableNoDate: string bookingOptionsLoadError: string startDate: string endDate: string continueToDriverDetails: string firstName: string lastName: string email: string phone: string driverLicense: string nationality: string dateOfBirth: string licenseIssued: string licenseExpiry: string insuranceAndPickupPolicies: string insuranceHint: string requiredCoverage: string none: string noOptionalInsurance: string additionalDriver: string charge: string promoCode: string enterCode: string apply: string appliedPromo: (title: string, discount: number) => string back: string reviewBookingCta: string confirmReservation: string processing: string reservationCreated: string manualApprovalRequired: string totalDue: string currency: string paymentMethod: string paymentMethods: { amanpay: { title: string; description: string } paypal: { title: string; description: string } cash: { title: string; description: string } } redirectingToPayment: string confirmPayAtPickup: string payWith: (provider: string) => string summary: { vehicle: string dates: string primaryDriver: string email: string driverLicense: string licenseExpiry: string additionalDriver: string promoCode: string discount: (discount: number) => string total: string } validation: { pickStartDate: string pickEndDate: string endDateAfterStart: string firstNameRequired: string lastNameRequired: string validEmailRequired: string driverLicenseRequired: string dateOfBirthRequired: string licenseExpiryRequired: string licenseIssueDateRequired: string additionalDriverFirstNameRequired: string additionalDriverLastNameRequired: string additionalDriverLicenseRequired: string } promo: { invalid: string unavailable: string } submit: { failed: string network: string } payment: { initiateFailed: string network: string } } confirmation: { eyebrow: string title: string description: string bookingSummary: string vehicle: string customer: string email: string dates: string total: string reference: string status: string browseMoreVehicles: string backHome: string } } const dictionaries: Record = { en: { lang: 'en', dir: 'ltr', siteNameFallback: 'Company site', rentalCompanyFallback: 'Rental company', nav: { about: 'About', vehicles: 'Vehicles', offers: 'Offers', pricing: 'Pricing', blog: 'Blog', contact: 'Contact', bookCar: 'Book a car', siteNavigation: 'Site navigation', }, home: { heroTitleFallback: 'Book directly with the rental company.', heroDescription: 'This branded site handles booking and payment directly. Marketplace discovery routes renters here for checkout.', viewOffers: 'View offers', viewPricing: 'View pricing', contactCompany: 'Contact company', heroImageMissing: 'Hero image not configured yet.', activeOffers: 'Active offers', seeAllOffers: 'See all offers', noActiveOffers: 'No active offers right now.', publishedVehicles: 'Published vehicles', available: (count) => `${count} available`, viewVehicle: 'View vehicle', }, about: { eyebrow: 'About', defaultTagline: 'This company uses RentalDriveGo to publish vehicles, run bookings, and accept direct rental payments.', location: 'Location', phone: 'Phone', email: 'Email', whatsapp: 'WhatsApp', locationMissing: 'Location not published yet', phoneMissing: 'Phone not published yet', emailMissing: 'Email not published yet', whatsappMissing: 'WhatsApp not published yet', heroImageMissing: 'Add a hero image in branding settings to personalize this page.', directBookingTitle: 'Direct booking', directBookingBody: 'Renters book and pay directly on the company site instead of checking out on the marketplace.', publishedFleetTitle: 'Published fleet', publishedFleetBody: 'Vehicle photos, pricing, and availability are managed from the private dashboard and published here automatically.', marketplaceReadyTitle: 'Marketplace ready', marketplaceReadyBody: 'Marketplace discovery redirects qualified renters into this branded site for final booking and payment.', companyDetails: 'Company details', companyAddressMissing: 'A public address has not been configured yet.', }, contact: { title: 'Contact', description: "Use the company's public contact details or extend this page to call the `/site/:slug/contact` endpoint.", }, offers: { title: 'Offers', empty: 'No offers are available right now.', noDescription: 'No description provided.', bookOffer: 'Book with this offer', }, pricing: { eyebrow: 'Pricing', title: 'Plans for growing rental operations', description: 'Choose a plan that matches your fleet size and booking volume. The design spec supports AmanPay and PayPal, plus MAD, USD, and EUR billing.', popular: 'Popular', acceptedPaymentMethods: 'Accepted payment methods', paymentsDescription: 'Pay securely with AmanPay or PayPal. Supported currencies: MAD, USD, EUR.', faq: { paymentMethodsQuestion: 'Which payment methods are supported?', paymentMethodsAnswer: 'Companies can use AmanPay or PayPal for subscriptions, and renters pay companies directly through the company-configured payment methods.', connectPaymentsQuestion: 'Can I start before connecting payments?', connectPaymentsAnswer: 'Yes. Trialing companies can configure branding, fleet, and offers before activating their live payment setup.', supportedCurrenciesQuestion: 'Which currencies are supported?', supportedCurrenciesAnswer: 'The current design supports MAD, USD, and EUR across subscription billing and rental pricing.', }, plans: { starterDescription: 'For smaller fleets that need direct bookings and a branded web presence.', growthDescription: 'For operators scaling marketing, offers, and multi-role workflows.', proDescription: 'For larger operators that need branding control and deeper operational flexibility.', starterFeatures: ['Branded booking site', 'Fleet publishing', 'Marketplace visibility', 'Basic team access'], growthFeatures: ['Everything in Starter', 'Featured marketplace offers', 'Advanced pricing rules', 'Expanded reporting'], proFeatures: ['Custom branding', 'Priority onboarding', 'Advanced operations', 'White-label polish'], }, }, blog: { eyebrow: 'Blog', title: 'Insights for rental operators', description: 'The design spec includes a standard blog route. This page seeds that route with editorial-style placeholders that can later be replaced by CMS-backed content.', draftPlaceholder: 'Draft article placeholder', posts: [ { title: 'How direct booking changes rental margins', excerpt: 'Why moving renters from marketplace discovery into a branded booking experience protects pricing and customer relationships.', category: 'Operations', }, { title: 'What to publish on a modern rental fleet page', excerpt: 'A practical checklist for vehicle photos, specs, pricing clarity, and trust signals that convert browsers into bookings.', category: 'Marketing', }, { title: 'Using promotions without breaking your pricing model', excerpt: 'Featured offers work best when they are time-bound, measurable, and attached to actual fleet strategy.', category: 'Revenue', }, ], }, vehicles: { title: 'Our Fleet', available: (count) => `${count} vehicle${count !== 1 ? 's' : ''} available`, noVehiclesTitle: 'No vehicles match your filters.', noVehiclesBody: 'Try adjusting the category, price, or transmission filter.', clearFilters: 'Clear filters', noPhoto: 'No photo', seats: (count) => `${count} seats`, perDay: 'per day', viewDetails: 'View details', filters: { title: 'Filters', clearAll: 'Clear all', category: 'Category', transmission: 'Transmission', maxPricePerDay: 'Max price / day', upTo: 'Up to', }, unavailable: { eyebrow: 'Site unavailable', title: 'Vehicle details are temporarily unavailable.', body: 'The public site is running, but the local database is not reachable right now.', backHome: 'Back to home', }, detail: { perDay: '/ day', bookNow: 'Book now', back: 'Back', availableFrom: 'Available from', unavailableNoDate: 'This vehicle is temporarily unavailable for new reservations.', }, }, booking: { loadingForm: 'Loading booking form...', eyebrow: 'Booking flow', title: 'Complete your reservation', steps: { selectDates: 'Select dates', driverDetails: 'Driver details', reviewBooking: 'Review booking', payment: 'Payment', }, loadingVehicle: 'Loading vehicle...', vehicleNotFound: 'Vehicle not found.', vehicleLoadError: 'Could not load vehicle details.', vehicleAvailableFrom: (date) => `This vehicle can only be reserved starting ${date}.`, vehicleUnavailableNoDate: 'This vehicle is temporarily unavailable for new reservations.', bookingOptionsLoadError: 'Could not load booking options.', startDate: 'Start date', endDate: 'End date', continueToDriverDetails: 'Continue to driver details ->', firstName: 'First name', lastName: 'Last name', email: 'Email', phone: 'Phone', driverLicense: 'Driver license', nationality: 'Nationality', dateOfBirth: 'Date of birth', licenseIssued: 'License issued', licenseExpiry: 'License expiry', insuranceAndPickupPolicies: 'Insurance and pickup policies', insuranceHint: 'Select optional protection before confirming your reservation.', requiredCoverage: 'Required coverage', none: 'None', noOptionalInsurance: 'No optional insurance add-ons are available for this company.', additionalDriver: 'Additional driver', charge: 'Charge', promoCode: 'Promo code', enterCode: 'Enter code', apply: 'Apply', appliedPromo: (title, discount) => `✓ "${title}" applied - ${discount}% off`, back: '<- Back', reviewBookingCta: 'Review booking ->', confirmReservation: 'Confirm reservation', processing: 'Processing...', reservationCreated: '✓ Reservation created - choose how you would like to pay', manualApprovalRequired: 'Driver license review is required before online payment. You can confirm with pay-at-pickup or wait for staff approval.', totalDue: 'Total due', currency: 'Currency', paymentMethod: 'Payment method', paymentMethods: { amanpay: { title: 'AmanPay', description: 'Secure online payment via AmanPay' }, paypal: { title: 'PayPal', description: 'Pay with your PayPal account or card' }, cash: { title: 'Pay at pickup', description: 'Pay cash or by card when you pick up the vehicle' }, }, redirectingToPayment: 'Redirecting to payment...', confirmPayAtPickup: 'Confirm - pay at pickup', payWith: (provider) => `Pay with ${provider} ->`, summary: { vehicle: 'Vehicle', dates: 'Dates', primaryDriver: 'Primary driver', email: 'Email', driverLicense: 'Driver license', licenseExpiry: 'License expiry', additionalDriver: 'Additional driver', promoCode: 'Promo code', discount: (discount) => `Discount (${discount}%)`, total: 'Total', }, validation: { pickStartDate: 'Pick a start date.', pickEndDate: 'Pick an end date.', endDateAfterStart: 'End date must be after start date.', firstNameRequired: 'First name required.', lastNameRequired: 'Last name required.', validEmailRequired: 'Valid email required.', driverLicenseRequired: 'Driver license required.', dateOfBirthRequired: 'Date of birth required.', licenseExpiryRequired: 'License expiry required.', licenseIssueDateRequired: 'License issue date required.', additionalDriverFirstNameRequired: 'Additional driver first name required.', additionalDriverLastNameRequired: 'Additional driver last name required.', additionalDriverLicenseRequired: 'Additional driver license required.', }, promo: { invalid: 'Invalid or expired promo code.', unavailable: 'Could not validate promo code. Please try again.', }, submit: { failed: 'Booking failed. Please try again.', network: 'Network error. Please check your connection and try again.', }, payment: { initiateFailed: 'Payment could not be initiated.', network: 'Network error. Please try again.', }, }, confirmation: { eyebrow: 'Reservation saved', title: 'Booking request received.', description: 'The reservation has been created in draft status and will be confirmed by staff or after payment.', bookingSummary: 'Booking summary', vehicle: 'Vehicle', customer: 'Customer', email: 'Email', dates: 'Dates', total: 'Total', reference: 'Reference', status: 'Status', browseMoreVehicles: 'Browse more vehicles', backHome: 'Back to home', }, }, fr: { lang: 'fr', dir: 'ltr', siteNameFallback: "Site de l'entreprise", rentalCompanyFallback: 'Société de location', nav: { about: 'À propos', vehicles: 'Véhicules', offers: 'Offres', pricing: 'Tarifs', blog: 'Blog', contact: 'Contact', bookCar: 'Réserver une voiture', siteNavigation: 'Navigation du site', }, home: { heroTitleFallback: "Réservez directement auprès de l'entreprise de location.", heroDescription: 'Ce site de marque gère directement la réservation et le paiement. La découverte sur la marketplace redirige les locataires ici pour finaliser la commande.', viewOffers: 'Voir les offres', viewPricing: 'Voir les tarifs', contactCompany: "Contacter l'entreprise", heroImageMissing: "L'image principale n'est pas encore configurée.", activeOffers: 'Offres actives', seeAllOffers: 'Voir toutes les offres', noActiveOffers: "Aucune offre active pour le moment.", publishedVehicles: 'Véhicules publiés', available: (count) => `${count} disponible${count > 1 ? 's' : ''}`, viewVehicle: 'Voir le véhicule', }, about: { eyebrow: 'À propos', defaultTagline: 'Cette entreprise utilise RentalDriveGo pour publier ses véhicules, gérer les réservations et accepter des paiements directs.', location: 'Localisation', phone: 'Téléphone', email: 'E-mail', whatsapp: 'WhatsApp', locationMissing: 'Localisation non publiée', phoneMissing: 'Téléphone non publié', emailMissing: 'E-mail non publié', whatsappMissing: 'WhatsApp non publié', heroImageMissing: 'Ajoutez une image principale dans les paramètres de marque pour personnaliser cette page.', directBookingTitle: 'Réservation directe', directBookingBody: "Les locataires réservent et paient directement sur le site de l'entreprise au lieu de finaliser sur la marketplace.", publishedFleetTitle: 'Flotte publiée', publishedFleetBody: 'Les photos, tarifs et disponibilités des véhicules sont gérés depuis le tableau de bord privé et publiés ici automatiquement.', marketplaceReadyTitle: 'Prêt pour la marketplace', marketplaceReadyBody: 'La découverte sur la marketplace redirige les locataires qualifiés vers ce site de marque pour la réservation finale et le paiement.', companyDetails: "Détails de l'entreprise", companyAddressMissing: "Aucune adresse publique n'a encore été configurée.", }, contact: { title: 'Contact', description: "Utilisez les coordonnées publiques de l'entreprise ou étendez cette page pour appeler l'endpoint `/site/:slug/contact`.", }, offers: { title: 'Offres', empty: "Aucune offre n'est disponible pour le moment.", noDescription: 'Aucune description fournie.', bookOffer: 'Réserver avec cette offre', }, pricing: { eyebrow: 'Tarifs', title: 'Des formules pour faire grandir votre activité', description: 'Choisissez une formule adaptée à la taille de votre flotte et à votre volume de réservations. La spécification prend en charge AmanPay et PayPal, ainsi que la facturation en MAD, USD et EUR.', popular: 'Populaire', acceptedPaymentMethods: 'Moyens de paiement acceptés', paymentsDescription: 'Payez en toute sécurité avec AmanPay ou PayPal. Devises prises en charge : MAD, USD, EUR.', faq: { paymentMethodsQuestion: 'Quels moyens de paiement sont pris en charge ?', paymentMethodsAnswer: "Les entreprises peuvent utiliser AmanPay ou PayPal pour les abonnements, et les locataires paient directement l'entreprise via les méthodes configurées par celle-ci.", connectPaymentsQuestion: 'Puis-je commencer avant de connecter les paiements ?', connectPaymentsAnswer: "Oui. Les entreprises en essai peuvent configurer leur marque, leur flotte et leurs offres avant d'activer leur configuration de paiement en direct.", supportedCurrenciesQuestion: 'Quelles devises sont prises en charge ?', supportedCurrenciesAnswer: 'Le design actuel prend en charge MAD, USD et EUR pour la facturation des abonnements et les tarifs de location.', }, plans: { starterDescription: 'Pour les petites flottes qui ont besoin de réservations directes et d’une présence web de marque.', growthDescription: 'Pour les opérateurs qui développent leur marketing, leurs offres et leurs workflows multi-rôles.', proDescription: 'Pour les grands opérateurs qui ont besoin de contrôle de marque et d’une flexibilité opérationnelle plus profonde.', starterFeatures: ['Site de réservation de marque', 'Publication de flotte', 'Visibilité marketplace', "Accès d'équipe basique"], growthFeatures: ['Tout le contenu de Starter', 'Offres marketplace mises en avant', 'Règles tarifaires avancées', 'Reporting élargi'], proFeatures: ['Marque personnalisée', 'Onboarding prioritaire', 'Opérations avancées', 'Finition white-label'], }, }, blog: { eyebrow: 'Blog', title: 'Analyses pour les opérateurs de location', description: 'La spécification inclut une route blog standard. Cette page alimente cette route avec des espaces réservés éditoriaux qui pourront ensuite être remplacés par un contenu relié à un CMS.', draftPlaceholder: "Brouillon d'article", posts: [ { title: 'Comment la réservation directe change les marges', excerpt: 'Pourquoi déplacer les locataires de la découverte marketplace vers une expérience de réservation de marque protège les prix et la relation client.', category: 'Opérations', }, { title: "Que publier sur une page de flotte moderne", excerpt: 'Une checklist pratique pour les photos, spécifications, clarté des prix et signaux de confiance qui convertissent les visiteurs en réservations.', category: 'Marketing', }, { title: 'Utiliser des promotions sans casser votre modèle tarifaire', excerpt: 'Les offres mises en avant fonctionnent mieux lorsqu’elles sont limitées dans le temps, mesurables et alignées sur une vraie stratégie de flotte.', category: 'Revenus', }, ], }, vehicles: { title: 'Notre flotte', available: (count) => `${count} véhicule${count > 1 ? 's' : ''} disponible${count > 1 ? 's' : ''}`, noVehiclesTitle: 'Aucun véhicule ne correspond à vos filtres.', noVehiclesBody: 'Essayez de modifier le filtre de catégorie, de prix ou de transmission.', clearFilters: 'Effacer les filtres', noPhoto: 'Pas de photo', seats: (count) => `${count} places`, perDay: 'par jour', viewDetails: 'Voir les détails', filters: { title: 'Filtres', clearAll: 'Tout effacer', category: 'Catégorie', transmission: 'Transmission', maxPricePerDay: 'Prix max / jour', upTo: "Jusqu'à", }, unavailable: { eyebrow: 'Site indisponible', title: 'Les détails du véhicule sont temporairement indisponibles.', body: 'Le site public fonctionne, mais la base de données locale est actuellement inaccessible.', backHome: "Retour à l'accueil", }, detail: { perDay: '/ jour', bookNow: 'Réserver maintenant', back: 'Retour', availableFrom: 'Disponible à partir du', unavailableNoDate: 'Ce véhicule est temporairement indisponible pour les nouvelles réservations.', }, }, booking: { loadingForm: 'Chargement du formulaire...', eyebrow: 'Parcours de réservation', title: 'Finalisez votre réservation', steps: { selectDates: 'Choisir les dates', driverDetails: 'Informations conducteur', reviewBooking: 'Vérifier la réservation', payment: 'Paiement', }, loadingVehicle: 'Chargement du véhicule...', vehicleNotFound: 'Véhicule introuvable.', vehicleLoadError: 'Impossible de charger les détails du véhicule.', vehicleAvailableFrom: (date) => `Ce véhicule ne peut être réservé qu’à partir du ${date}.`, vehicleUnavailableNoDate: 'Ce véhicule est temporairement indisponible pour les nouvelles réservations.', bookingOptionsLoadError: 'Impossible de charger les options de réservation.', startDate: 'Date de début', endDate: 'Date de fin', continueToDriverDetails: 'Continuer vers les informations conducteur ->', firstName: 'Prénom', lastName: 'Nom', email: 'E-mail', phone: 'Téléphone', driverLicense: 'Permis de conduire', nationality: 'Nationalité', dateOfBirth: 'Date de naissance', licenseIssued: 'Permis délivré le', licenseExpiry: 'Expiration du permis', insuranceAndPickupPolicies: 'Assurance et politiques de remise', insuranceHint: 'Sélectionnez une protection optionnelle avant de confirmer votre réservation.', requiredCoverage: 'Couverture obligatoire', none: 'Aucune', noOptionalInsurance: "Aucune assurance optionnelle n'est disponible pour cette entreprise.", additionalDriver: 'Conducteur additionnel', charge: 'Frais', promoCode: 'Code promo', enterCode: 'Entrer le code', apply: 'Appliquer', appliedPromo: (title, discount) => `✓ "${title}" appliqué - ${discount}% de réduction`, back: '<- Retour', reviewBookingCta: 'Vérifier la réservation ->', confirmReservation: 'Confirmer la réservation', processing: 'Traitement...', reservationCreated: '✓ Réservation créée - choisissez votre mode de paiement', manualApprovalRequired: 'La vérification du permis est requise avant le paiement en ligne. Vous pouvez confirmer avec paiement au retrait ou attendre la validation du personnel.', totalDue: 'Total à payer', currency: 'Devise', paymentMethod: 'Mode de paiement', paymentMethods: { amanpay: { title: 'AmanPay', description: 'Paiement en ligne sécurisé via AmanPay' }, paypal: { title: 'PayPal', description: 'Payez avec votre compte PayPal ou votre carte' }, cash: { title: 'Paiement au retrait', description: 'Payez en espèces ou par carte lors de la récupération du véhicule' }, }, redirectingToPayment: 'Redirection vers le paiement...', confirmPayAtPickup: 'Confirmer - payer au retrait', payWith: (provider) => `Payer avec ${provider} ->`, summary: { vehicle: 'Véhicule', dates: 'Dates', primaryDriver: 'Conducteur principal', email: 'E-mail', driverLicense: 'Permis', licenseExpiry: 'Expiration du permis', additionalDriver: 'Conducteur additionnel', promoCode: 'Code promo', discount: (discount) => `Réduction (${discount}%)`, total: 'Total', }, validation: { pickStartDate: 'Choisissez une date de début.', pickEndDate: 'Choisissez une date de fin.', endDateAfterStart: 'La date de fin doit être après la date de début.', firstNameRequired: 'Le prénom est requis.', lastNameRequired: 'Le nom est requis.', validEmailRequired: 'Un e-mail valide est requis.', driverLicenseRequired: 'Le permis de conduire est requis.', dateOfBirthRequired: 'La date de naissance est requise.', licenseExpiryRequired: "La date d'expiration du permis est requise.", licenseIssueDateRequired: 'La date de délivrance du permis est requise.', additionalDriverFirstNameRequired: 'Le prénom du conducteur additionnel est requis.', additionalDriverLastNameRequired: 'Le nom du conducteur additionnel est requis.', additionalDriverLicenseRequired: 'Le permis du conducteur additionnel est requis.', }, promo: { invalid: 'Code promo invalide ou expiré.', unavailable: 'Impossible de valider le code promo. Réessayez.', }, submit: { failed: 'La réservation a échoué. Réessayez.', network: 'Erreur réseau. Vérifiez votre connexion puis réessayez.', }, payment: { initiateFailed: 'Le paiement n’a pas pu être démarré.', network: 'Erreur réseau. Réessayez.', }, }, confirmation: { eyebrow: 'Réservation enregistrée', title: 'Demande de réservation reçue.', description: 'La réservation a été créée en brouillon et sera confirmée par le personnel ou après paiement.', bookingSummary: 'Résumé de réservation', vehicle: 'Véhicule', customer: 'Client', email: 'E-mail', dates: 'Dates', total: 'Total', reference: 'Référence', status: 'Statut', browseMoreVehicles: 'Voir plus de véhicules', backHome: "Retour à l'accueil", }, }, ar: { lang: 'ar', dir: 'rtl', siteNameFallback: 'موقع الشركة', rentalCompanyFallback: 'شركة تأجير', nav: { about: 'من نحن', vehicles: 'المركبات', offers: 'العروض', pricing: 'الأسعار', blog: 'المدونة', contact: 'اتصل بنا', bookCar: 'احجز سيارة', siteNavigation: 'روابط الموقع', }, home: { heroTitleFallback: 'احجز مباشرة مع شركة التأجير.', heroDescription: 'هذا الموقع المخصص للعلامة التجارية يدير الحجز والدفع مباشرة. الاكتشاف عبر المنصة يحول المستأجرين إلى هنا لإتمام الحجز.', viewOffers: 'عرض العروض', viewPricing: 'عرض الأسعار', contactCompany: 'التواصل مع الشركة', heroImageMissing: 'لم يتم إعداد صورة رئيسية بعد.', activeOffers: 'العروض النشطة', seeAllOffers: 'عرض كل العروض', noActiveOffers: 'لا توجد عروض نشطة حالياً.', publishedVehicles: 'المركبات المنشورة', available: (count) => `${count} متاح`, viewVehicle: 'عرض المركبة', }, about: { eyebrow: 'من نحن', defaultTagline: 'تستخدم هذه الشركة RentalDriveGo لنشر المركبات وإدارة الحجوزات وقبول مدفوعات الإيجار المباشرة.', location: 'الموقع', phone: 'الهاتف', email: 'البريد الإلكتروني', whatsapp: 'واتساب', locationMissing: 'لم يتم نشر الموقع بعد', phoneMissing: 'لم يتم نشر الهاتف بعد', emailMissing: 'لم يتم نشر البريد الإلكتروني بعد', whatsappMissing: 'لم يتم نشر واتساب بعد', heroImageMissing: 'أضف صورة رئيسية من إعدادات العلامة التجارية لتخصيص هذه الصفحة.', directBookingTitle: 'حجز مباشر', directBookingBody: 'يقوم المستأجرون بالحجز والدفع مباشرة على موقع الشركة بدلاً من إتمام العملية في المنصة.', publishedFleetTitle: 'أسطول منشور', publishedFleetBody: 'تتم إدارة صور المركبات والأسعار والتوفر من لوحة التحكم الخاصة ونشرها هنا تلقائياً.', marketplaceReadyTitle: 'جاهز للمنصة', marketplaceReadyBody: 'الاكتشاف عبر المنصة يوجه المستأجرين المؤهلين إلى هذا الموقع المخصص لإتمام الحجز والدفع.', companyDetails: 'تفاصيل الشركة', companyAddressMissing: 'لم يتم إعداد عنوان عام بعد.', }, contact: { title: 'اتصل بنا', description: 'استخدم بيانات الاتصال العامة للشركة أو وسّع هذه الصفحة لاستدعاء نقطة النهاية `/site/:slug/contact`.', }, offers: { title: 'العروض', empty: 'لا توجد عروض متاحة حالياً.', noDescription: 'لا يوجد وصف متاح.', bookOffer: 'احجز بهذا العرض', }, pricing: { eyebrow: 'الأسعار', title: 'خطط تناسب نمو عمليات التأجير', description: 'اختر الخطة التي تناسب حجم أسطولك وحجم الحجوزات. يدعم التصميم AmanPay وPayPal إلى جانب الفوترة بعملات MAD وUSD وEUR.', popular: 'الأكثر شيوعاً', acceptedPaymentMethods: 'وسائل الدفع المقبولة', paymentsDescription: 'ادفع بأمان عبر AmanPay أو PayPal. العملات المدعومة: MAD وUSD وEUR.', faq: { paymentMethodsQuestion: 'ما وسائل الدفع المدعومة؟', paymentMethodsAnswer: 'يمكن للشركات استخدام AmanPay أو PayPal للاشتراكات، بينما يدفع المستأجرون مباشرة للشركات عبر الوسائل التي تضبطها الشركة.', connectPaymentsQuestion: 'هل يمكنني البدء قبل ربط وسائل الدفع؟', connectPaymentsAnswer: 'نعم. يمكن للشركات في الفترة التجريبية إعداد العلامة التجارية والأسطول والعروض قبل تفعيل الدفع المباشر.', supportedCurrenciesQuestion: 'ما العملات المدعومة؟', supportedCurrenciesAnswer: 'يدعم التصميم الحالي MAD وUSD وEUR عبر فوترة الاشتراكات وتسعير الإيجارات.', }, plans: { starterDescription: 'للأساطيل الصغيرة التي تحتاج إلى حجوزات مباشرة وحضور ويب مخصص للعلامة التجارية.', growthDescription: 'للمشغلين الذين يوسعون التسويق والعروض وتدفقات العمل متعددة الأدوار.', proDescription: 'للمشغلين الأكبر الذين يحتاجون إلى تحكم أعمق بالعلامة التجارية ومرونة تشغيلية أكبر.', starterFeatures: ['موقع حجز مخصص', 'نشر الأسطول', 'الظهور في المنصة', 'وصول أساسي للفريق'], growthFeatures: ['كل ما في Starter', 'عروض مميزة في المنصة', 'قواعد تسعير متقدمة', 'تقارير موسعة'], proFeatures: ['علامة تجارية مخصصة', 'تهيئة أولوية', 'عمليات متقدمة', 'لمسة وايت ليبل'], }, }, blog: { eyebrow: 'المدونة', title: 'رؤى لمشغلي التأجير', description: 'يتضمن التصميم مساراً قياسياً للمدونة. تملأ هذه الصفحة هذا المسار بمحتوى تمهيدي يمكن استبداله لاحقاً بمحتوى من نظام إدارة محتوى.', draftPlaceholder: 'مسودة مقال', posts: [ { title: 'كيف يغير الحجز المباشر هوامش الربح', excerpt: 'نقل المستأجرين من الاكتشاف عبر المنصة إلى تجربة حجز تحمل علامتك يحمي التسعير وعلاقة العميل.', category: 'العمليات', }, { title: 'ماذا تنشر في صفحة أسطول حديثة', excerpt: 'قائمة عملية لصور المركبات والمواصفات ووضوح الأسعار وعناصر الثقة التي تحول الزائر إلى حجز.', category: 'التسويق', }, { title: 'استخدام العروض دون إفساد نموذج التسعير', excerpt: 'تعمل العروض المميزة بشكل أفضل عندما تكون محددة زمنياً وقابلة للقياس ومرتبطة باستراتيجية أسطول حقيقية.', category: 'الإيرادات', }, ], }, vehicles: { title: 'أسطولنا', available: (count) => `${count} مركبة متاحة`, noVehiclesTitle: 'لا توجد مركبات تطابق عوامل التصفية.', noVehiclesBody: 'حاول تعديل فلاتر الفئة أو السعر أو ناقل الحركة.', clearFilters: 'مسح الفلاتر', noPhoto: 'لا توجد صورة', seats: (count) => `${count} مقاعد`, perDay: 'في اليوم', viewDetails: 'عرض التفاصيل', filters: { title: 'الفلاتر', clearAll: 'مسح الكل', category: 'الفئة', transmission: 'ناقل الحركة', maxPricePerDay: 'الحد الأقصى للسعر / يوم', upTo: 'حتى', }, unavailable: { eyebrow: 'الموقع غير متاح', title: 'تفاصيل المركبة غير متاحة مؤقتاً.', body: 'الموقع العام يعمل، لكن قاعدة البيانات المحلية غير متاحة حالياً.', backHome: 'العودة للرئيسية', }, detail: { perDay: '/ يوم', bookNow: 'احجز الآن', back: 'رجوع', availableFrom: 'متاح ابتداءً من', unavailableNoDate: 'هذه المركبة غير متاحة مؤقتاً للحجوزات الجديدة.', }, }, booking: { loadingForm: 'جاري تحميل نموذج الحجز...', eyebrow: 'خطوات الحجز', title: 'أكمل حجزك', steps: { selectDates: 'اختيار التواريخ', driverDetails: 'بيانات السائق', reviewBooking: 'مراجعة الحجز', payment: 'الدفع', }, loadingVehicle: 'جاري تحميل المركبة...', vehicleNotFound: 'المركبة غير موجودة.', vehicleLoadError: 'تعذر تحميل تفاصيل المركبة.', vehicleAvailableFrom: (date) => `يمكن حجز هذه المركبة ابتداءً من ${date}.`, vehicleUnavailableNoDate: 'هذه المركبة غير متاحة مؤقتاً للحجوزات الجديدة.', bookingOptionsLoadError: 'تعذر تحميل خيارات الحجز.', startDate: 'تاريخ البداية', endDate: 'تاريخ النهاية', continueToDriverDetails: 'المتابعة إلى بيانات السائق ->', firstName: 'الاسم الأول', lastName: 'اسم العائلة', email: 'البريد الإلكتروني', phone: 'الهاتف', driverLicense: 'رخصة القيادة', nationality: 'الجنسية', dateOfBirth: 'تاريخ الميلاد', licenseIssued: 'تاريخ إصدار الرخصة', licenseExpiry: 'تاريخ انتهاء الرخصة', insuranceAndPickupPolicies: 'التأمين وسياسات الاستلام', insuranceHint: 'اختر حماية اختيارية قبل تأكيد الحجز.', requiredCoverage: 'التغطية المطلوبة', none: 'لا يوجد', noOptionalInsurance: 'لا توجد إضافات تأمين اختيارية متاحة لهذه الشركة.', additionalDriver: 'سائق إضافي', charge: 'الرسوم', promoCode: 'رمز ترويجي', enterCode: 'أدخل الرمز', apply: 'تطبيق', appliedPromo: (title, discount) => `✓ تم تطبيق "${title}" بخصم ${discount}%`, back: '<- رجوع', reviewBookingCta: 'مراجعة الحجز ->', confirmReservation: 'تأكيد الحجز', processing: 'جارٍ المعالجة...', reservationCreated: '✓ تم إنشاء الحجز - اختر طريقة الدفع', manualApprovalRequired: 'مراجعة رخصة القيادة مطلوبة قبل الدفع الإلكتروني. يمكنك التأكيد مع الدفع عند الاستلام أو انتظار موافقة الموظفين.', totalDue: 'المبلغ المستحق', currency: 'العملة', paymentMethod: 'طريقة الدفع', paymentMethods: { amanpay: { title: 'AmanPay', description: 'دفع إلكتروني آمن عبر AmanPay' }, paypal: { title: 'PayPal', description: 'ادفع عبر حساب PayPal أو البطاقة' }, cash: { title: 'الدفع عند الاستلام', description: 'ادفع نقداً أو بالبطاقة عند استلام المركبة' }, }, redirectingToPayment: 'جارٍ التحويل إلى الدفع...', confirmPayAtPickup: 'تأكيد - الدفع عند الاستلام', payWith: (provider) => `ادفع عبر ${provider} ->`, summary: { vehicle: 'المركبة', dates: 'التواريخ', primaryDriver: 'السائق الرئيسي', email: 'البريد الإلكتروني', driverLicense: 'رخصة القيادة', licenseExpiry: 'انتهاء الرخصة', additionalDriver: 'سائق إضافي', promoCode: 'الرمز الترويجي', discount: (discount) => `الخصم (${discount}%)`, total: 'الإجمالي', }, validation: { pickStartDate: 'اختر تاريخ البداية.', pickEndDate: 'اختر تاريخ النهاية.', endDateAfterStart: 'يجب أن يكون تاريخ النهاية بعد تاريخ البداية.', firstNameRequired: 'الاسم الأول مطلوب.', lastNameRequired: 'اسم العائلة مطلوب.', validEmailRequired: 'البريد الإلكتروني الصحيح مطلوب.', driverLicenseRequired: 'رخصة القيادة مطلوبة.', dateOfBirthRequired: 'تاريخ الميلاد مطلوب.', licenseExpiryRequired: 'تاريخ انتهاء الرخصة مطلوب.', licenseIssueDateRequired: 'تاريخ إصدار الرخصة مطلوب.', additionalDriverFirstNameRequired: 'الاسم الأول للسائق الإضافي مطلوب.', additionalDriverLastNameRequired: 'اسم العائلة للسائق الإضافي مطلوب.', additionalDriverLicenseRequired: 'رخصة السائق الإضافي مطلوبة.', }, promo: { invalid: 'الرمز الترويجي غير صالح أو منتهي.', unavailable: 'تعذر التحقق من الرمز الترويجي. حاول مرة أخرى.', }, submit: { failed: 'فشل الحجز. حاول مرة أخرى.', network: 'خطأ في الشبكة. تحقق من الاتصال ثم حاول مرة أخرى.', }, payment: { initiateFailed: 'تعذر بدء عملية الدفع.', network: 'خطأ في الشبكة. حاول مرة أخرى.', }, }, confirmation: { eyebrow: 'تم حفظ الحجز', title: 'تم استلام طلب الحجز.', description: 'تم إنشاء الحجز بحالة مسودة وسيتم تأكيده من قبل الموظفين أو بعد الدفع.', bookingSummary: 'ملخص الحجز', vehicle: 'المركبة', customer: 'العميل', email: 'البريد الإلكتروني', dates: 'التواريخ', total: 'الإجمالي', reference: 'المرجع', status: 'الحالة', browseMoreVehicles: 'تصفح المزيد من المركبات', backHome: 'العودة للرئيسية', }, }, } export function getPublicSiteDictionary(language: PublicSiteLanguage): PublicSiteDictionary { return dictionaries[language] }