1 line
21 KiB
JavaScript
1 line
21 KiB
JavaScript
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,78740,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.SEVERITY_COLORS=r.DAMAGE_ZONE_COORDS=void 0,r.DAMAGE_ZONE_COORDS={hood:{x:48,y:8,w:64,h:28},roof:{x:48,y:52,w:64,h:56},trunk:{x:48,y:124,w:64,h:28},"front-bumper":{x:48,y:0,w:64,h:10},"rear-bumper":{x:48,y:150,w:64,h:10},"front-left-fender":{x:20,y:10,w:30,h:35},"front-right-fender":{x:110,y:10,w:30,h:35},"front-left-door":{x:20,y:52,w:30,h:30},"front-right-door":{x:110,y:52,w:30,h:30},"rear-left-door":{x:20,y:82,w:30,h:30},"rear-right-door":{x:110,y:82,w:30,h:30},"rear-left-fender":{x:20,y:112,w:30,h:35},"rear-right-fender":{x:110,y:112,w:30,h:35},windshield:{x:52,y:38,w:56,h:18},"rear-window":{x:52,y:104,w:56,h:18},"left-mirror":{x:8,y:50,w:14,h:10},"right-mirror":{x:138,y:50,w:14,h:10},"front-left-wheel":{x:10,y:24,w:22,h:26},"front-right-wheel":{x:128,y:24,w:22,h:26},"rear-left-wheel":{x:10,y:110,w:22,h:26},"rear-right-wheel":{x:128,y:110,w:22,h:26},interior:{x:55,y:58,w:50,h:44},"under-hood":{x:52,y:10,w:56,h:20},undercarriage:{x:52,y:130,w:56,h:20}},r.SEVERITY_COLORS={SCRATCH:"#F59E0B",DENT:"#EF4444",CRACK:"#8B5CF6",MISSING:"#374151",OTHER:"#6B7280"}},33556,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.FUEL_POLICY_LABELS=void 0,r.FUEL_POLICY_LABELS={FULL_TO_FULL:{en:"Full-to-Full: Return vehicle with a full tank. A refueling fee applies if returned with less fuel.",fr:"Plein à plein : retournez le véhicule avec le plein. Des frais de ravitaillement s'appliquent sinon.",ar:"ممتلئ إلى ممتلئ: يجب إعادة السيارة بخزان ممتلئ. رسوم إضافية في حال الإعادة بمستوى أقل."},FULL_TO_EMPTY:{en:"Full-to-Empty: Vehicle is provided with a full tank. No refund for unused fuel upon return.",fr:"Plein à vide : le véhicule est livré avec le plein. Aucun remboursement n'est accordé pour le carburant non utilisé.",ar:"ممتلئ إلى فارغ: تُسلَّم السيارة بخزان ممتلئ. لا استرداد للوقود غير المستخدم."},SAME_TO_SAME:{en:"Same-to-Same: Return vehicle with the same fuel level as at pickup.",fr:"Même niveau : retournez le véhicule avec le même niveau de carburant qu'au départ.",ar:"نفس المستوى: أعد السيارة بنفس مستوى الوقود عند الاستلام."},PREPAID:{en:"Prepaid Fuel: You pre-purchase a full tank at a fixed rate. Return at any fuel level.",fr:"Carburant prépayé : vous achetez un plein à tarif fixe à l'avance. Retour possible avec n'importe quel niveau.",ar:"الوقود المدفوع مسبقاً: تدفع مقدماً ثمن خزان كامل بسعر ثابت. يمكن إعادة السيارة بأي مستوى."},FREE:{en:"Fuel Included: Fuel cost is included in the rental price.",fr:"Carburant inclus : le coût du carburant est inclus dans le tarif de location.",ar:"الوقود مشمول: تكلفة الوقود مشمولة في سعر الإيجار."}}},89456,(e,t,r)=>{"use strict";function a(e){if(e)return e;let t="object"==typeof globalThis&&"document"in globalThis?globalThis.document?.documentElement?.lang:void 0;return"en"===t||"fr"===t||"ar"===t?t:"en"}function s(e,t="MAD"){return"ar"===a(e)?"درهم":"MAD"}Object.defineProperty(r,"__esModule",{value:!0}),r.PLAN_FEATURES=r.PLAN_PRICES=void 0,r.getCurrencyLabel=s,r.formatCurrency=function(e,t="MAD",r){let i=a(r),n=new Intl.NumberFormat({en:"en-US",fr:"fr-FR",ar:"ar-MA"}[i],{minimumFractionDigits:2,maximumFractionDigits:2}).format(e/100),l=s(i,t);return"en"===i?`${l} ${n}`:`${n} ${l}`},r.PLAN_PRICES={STARTER:{MONTHLY:{MAD:2990},ANNUAL:{MAD:29900}},GROWTH:{MONTHLY:{MAD:3990},ANNUAL:{MAD:39900}},PRO:{MONTHLY:{MAD:99900},ANNUAL:{MAD:999e3}}},r.PLAN_FEATURES={STARTER:["Up to 10 vehicles","1 user account","Basic analytics","Marketplace listing"],GROWTH:["Up to 50 vehicles","5 user accounts","Full analytics","Priority marketplace placement","Custom branding"],PRO:["Unlimited vehicles","Unlimited user accounts","Advanced reports","API access","Dedicated support"]}},82110,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.defaultMarketplaceHomepageContent=r.defaultMarketplaceHomepageSections=void 0,r.cloneMarketplaceHomepageContent=function(){return JSON.parse(JSON.stringify(r.defaultMarketplaceHomepageContent))},r.resolveMarketplaceHomepageSections=function(e){let t=e?.length?e:r.defaultMarketplaceHomepageSections;return t.filter((e,r)=>t.indexOf(e)===r)},r.defaultMarketplaceHomepageSections=["hero","surface","pillars","audiences","features","steps","closing"],r.defaultMarketplaceHomepageContent={en:{sections:r.defaultMarketplaceHomepageSections,heroKicker:"RentalDriveGo",heroTitle:"Marketplace discovery with a sharper front door.",heroBody:"Rental companies run private operations, renters browse a shared marketplace, and every booking ends on the company’s own branded checkout.",startTrial:"Start free trial",exploreVehicles:"Explore vehicles",surfaceLabel:"Marketplace surface",surfaceTitle:"Designed for two audiences at once.",surfaceBody:"Operators need control, renters need confidence. The marketplace should show both without feeling like a template.",liveLabel:"Live network",trustedFleets:"Trusted fleets",brandedFlows:"Branded booking flows",multiTenant:"Multi-tenant operations",companyKicker:"Operator workflow",companyTitle:"Manage inventory, offers, billing, and staff from one control layer.",companyBody:"Publish inventory once, decide what appears publicly, and keep contracts, payments, and reporting isolated per company.",renterKicker:"Renter experience",renterTitle:"Let renters compare quickly, then hand them off to the right company site.",renterBody:"The marketplace works as a discovery engine, not a dead-end aggregator. Search here, reserve there, and pay direct.",pillars:[["Unified publishing","Vehicle photos, pricing, and offers flow from one admin workflow into marketplace discovery and branded booking pages."],["Qualified discovery","Featured offers, location-aware browsing, and company reputation signals help renters narrow options fast."],["Direct revenue path","Bookings move into the company’s own payment flow, so customer ownership and cash collection stay with the business."]].map(([e,t])=>({title:e,body:t})),metrics:[["01","Shared marketplace visibility"],["02","Direct company checkout"],["03","Company-owned payments"]].map(([e,t])=>({value:e,label:t})),featureLabel:"What the product covers",features:["Fleet management with multi-photo uploads","Marketplace offers and redirect booking flow","Branded public booking site per company","Customer CRM, analytics, and billing controls"],stepsTitle:"How companies launch",steps:[["1","Create your company workspace","Pick a plan, launch your 90-day trial, and verify the owner account."],["2","Publish vehicles and offers","Upload photos once and control what appears on the marketplace and branded site."],["3","Accept bookings on your own site","Renters discover your fleet on RentalDriveGo, then pay you directly on your branded booking flow."]].map(([e,t,r])=>({step:e,title:t,body:r})),stepLabel:"Step",readyKicker:"Ready to launch",readyTitle:"The marketplace homepage should explain the product in seconds.",readyBody:"Use the marketplace to attract demand, then move renters into a branded experience that keeps pricing, payments, and trust tied to your company.",viewPricing:"View pricing",createWorkspace:"Create workspace"},fr:{sections:r.defaultMarketplaceHomepageSections,heroKicker:"RentalDriveGo",heroTitle:"Une vitrine marketplace plus claire et plus percutante.",heroBody:"Les entreprises de location gèrent leurs opérations en privé, les clients parcourent une marketplace commune et chaque réservation se finalise sur le parcours de paiement aux couleurs de l'entreprise.",startTrial:"Commencer l’essai gratuit",exploreVehicles:"Explorer les véhicules",surfaceLabel:"Vitrine marketplace",surfaceTitle:"Pensée pour deux audiences à la fois.",surfaceBody:"Les opérateurs veulent du contrôle, les clients veulent de la confiance. La marketplace doit montrer les deux sans ressembler à un modèle générique.",liveLabel:"Réseau actif",trustedFleets:"Flottes fiables",brandedFlows:"Parcours de marque",multiTenant:"Opérations multi-tenant",companyKicker:"Flux opérateur",companyTitle:"Pilotez l’inventaire, les offres, la facturation et l’équipe depuis un seul centre de contrôle.",companyBody:"Publiez une seule fois, choisissez ce qui apparaît publiquement, et gardez contrats, paiements et rapports isolés par entreprise.",renterKicker:"Expérience client",renterTitle:"Laissez les clients comparer rapidement, puis redirigez-les vers le bon site d’entreprise.",renterBody:"La marketplace sert de moteur de découverte, pas d’agrégateur sans suite. Recherche ici, réservation là-bas, paiement direct.",pillars:[["Publication unifiée","Les photos, tarifs et offres circulent depuis un seul flux d’administration vers la découverte marketplace et les pages de réservation de marque."],["Découverte qualifiée","Offres mises en avant, navigation par localisation et signaux de réputation aident les clients à filtrer rapidement."],["Revenus en direct","Les réservations basculent vers le paiement propre à l’entreprise afin de préserver la relation client et l’encaissement."]].map(([e,t])=>({title:e,body:t})),metrics:[["01","Visibilité marketplace partagée"],["02","Paiement direct entreprise"],["03","Paiements gérés par l’entreprise"]].map(([e,t])=>({value:e,label:t})),featureLabel:"Ce que couvre le produit",features:["Gestion de flotte avec téléversement de plusieurs photos","Offres marketplace et redirection vers la réservation","Site public de réservation par entreprise","CRM client, analytics et contrôle de facturation"],stepsTitle:"Comment les entreprises démarrent",steps:[["1","Créez votre espace entreprise","Choisissez un plan, lancez votre essai de 90 jours et vérifiez le compte propriétaire."],["2","Publiez véhicules et offres","Téléversez une seule fois et contrôlez ce qui apparaît sur la marketplace et le site de marque."],["3","Acceptez les réservations sur votre site","Les clients découvrent votre flotte sur RentalDriveGo puis paient directement via votre parcours de réservation."]].map(([e,t,r])=>({step:e,title:t,body:r})),stepLabel:"Étape",readyKicker:"Prêt à démarrer",readyTitle:"La page d’accueil marketplace doit présenter le produit en quelques secondes.",readyBody:"Utilisez la marketplace pour capter la demande, puis orientez les clients vers une expérience de marque où les prix, les paiements et la confiance restent attachés à votre entreprise.",viewPricing:"Voir les tarifs",createWorkspace:"Créer l’espace"},ar:{sections:r.defaultMarketplaceHomepageSections,heroKicker:"RentalDriveGo",heroTitle:"واجهة سوق أكثر وضوحاً وتأثيراً.",heroBody:"شركات التأجير تدير عملياتها بشكل خاص، والمستأجرون يتصفحون سوقاً مشتركاً، وكل حجز ينتهي في صفحة دفع تحمل هوية الشركة ذاتها.",startTrial:"ابدأ التجربة المجانية",exploreVehicles:"استكشف السيارات",surfaceLabel:"واجهة السوق",surfaceTitle:"مصممة لجمهورين في الوقت نفسه.",surfaceBody:"المشغلون يريدون التحكم، والمستأجرون يريدون الثقة. يجب أن تُظهر المنصة الأمرين معاً من دون أن تبدو كقالب عادي.",liveLabel:"شبكة نشطة",trustedFleets:"أساطيل موثوقة",brandedFlows:"مسارات حجز مخصصة",multiTenant:"عمليات متعددة الشركات",companyKicker:"سير عمل المشغل",companyTitle:"تحكم في المخزون والعروض والفوترة والفريق من طبقة تشغيل واحدة.",companyBody:"انشر المخزون مرة واحدة، وحدد ما يظهر للعامة، واحتفظ بالعقود والمدفوعات والتقارير معزولة لكل شركة.",renterKicker:"تجربة المستأجر",renterTitle:"دع المستأجرين يقارنون بسرعة ثم وجّههم إلى موقع الشركة المناسب.",renterBody:"هذه المنصة محرك لاكتشاف الخيارات، وليست مُجمِّعاً بلا مسار واضح. ابحث هنا، احجز هناك، وادفع مباشرة للشركة.",pillars:[["نشر موحد","صور السيارات والأسعار والعروض تنتقل من سير إدارة واحد إلى السوق وصفحات الحجز ذات الهوية الخاصة."],["اكتشاف مؤهل","تساعد العروض المميزة، والتصفح حسب الموقع، وإشارات السمعة المستأجرين على تحديد خياراتهم بسرعة."],["مسار إيراد مباشر","تنتقل الحجوزات إلى صفحة الدفع الخاصة بالشركة حتى تبقى علاقة العميل والتحصيل المالي بيد الشركة نفسها."]].map(([e,t])=>({title:e,body:t})),metrics:[["01","ظهور مشترك في السوق"],["02","دفع مباشر للشركة"],["03","مدفوعات مملوكة للشركة"]].map(([e,t])=>({value:e,label:t})),featureLabel:"ما الذي يقدمه المنتج",features:["إدارة الأسطول مع رفع عدة صور","عروض السوق والتحويل إلى مسار الحجز","موقع حجز عام مخصص لكل شركة","إدارة العملاء والتحليلات والفوترة"],stepsTitle:"كيف تبدأ الشركات",steps:[["1","أنشئ مساحة عمل شركتك","اختر الخطة وابدأ تجربتك لمدة 14 يوماً ثم فعّل حساب المالك."],["2","انشر السيارات والعروض","ارفع الصور مرة واحدة وتحكم فيما يظهر في السوق وفي الموقع المخصص."],["3","استقبل الحجوزات على موقعك","يكتشف المستأجرون أسطولك على RentalDriveGo ثم يدفعون مباشرة عبر مسار الحجز الخاص بك."]].map(([e,t,r])=>({step:e,title:t,body:r})),stepLabel:"الخطوة",readyKicker:"جاهز للانطلاق",readyTitle:"يجب أن تشرح الصفحة الرئيسية قيمة المنصة خلال ثوانٍ.",readyBody:"استخدم السوق لجذب الطلب، ثم انقل المستأجرين إلى تجربة تحمل هوية شركتك، بحيث تبقى الأسعار والمدفوعات والثقة مرتبطة بنشاطك.",viewPricing:"عرض الأسعار",createWorkspace:"إنشاء المساحة"}}},64712,(e,t,r)=>{"use strict";var a=e.e&&e.e.__createBinding||(Object.create?function(e,t,r,a){void 0===a&&(a=r);var s=Object.getOwnPropertyDescriptor(t,r);(!s||("get"in s?!t.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,a,s)}:function(e,t,r,a){void 0===a&&(a=r),e[a]=t[r]}),s=e.e&&e.e.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||a(t,e,r)};Object.defineProperty(r,"__esModule",{value:!0}),s(e.r(78740),r),s(e.r(33556),r),s(e.r(89456),r),s(e.r(82110),r)},62169,e=>{"use strict";var t=e.i(43476),r=e.i(71645),a=e.i(22016),s=e.i(64712),i=e.i(94327),n=e.i(56322);e.s(["default",0,function(){let{language:e}=(0,n.useDashboardI18n)(),[l,o]=(0,r.useState)([]),[c,u]=(0,r.useState)(""),[d,p]=(0,r.useState)(null),m={en:{heading:"Contracts",subtitle:"Generate or reopen rental contracts from any booking.",search:"Search customer, vehicle, plate, contract number…",booking:"Booking",customer:"Customer",vehicle:"Vehicle",dates:"Dates",contract:"Contract",invoice:"Invoice",total:"Total",status:"Status",action:"Action",open:"Open contract",generate:"Generate contract",empty:"No bookings found."},fr:{heading:"Contrats",subtitle:"Générez ou rouvrez un contrat de location depuis n’importe quelle réservation.",search:"Rechercher client, véhicule, plaque, numéro de contrat…",booking:"Réservation",customer:"Client",vehicle:"Véhicule",dates:"Dates",contract:"Contrat",invoice:"Facture",total:"Total",status:"Statut",action:"Action",open:"Ouvrir le contrat",generate:"Générer le contrat",empty:"Aucune réservation trouvée."},ar:{heading:"العقود",subtitle:"أنشئ أو افتح عقد التأجير من أي حجز.",search:"ابحث بالعميل أو السيارة أو اللوحة أو رقم العقد…",booking:"الحجز",customer:"العميل",vehicle:"المركبة",dates:"التواريخ",contract:"العقد",invoice:"الفاتورة",total:"الإجمالي",status:"الحالة",action:"الإجراء",open:"فتح العقد",generate:"إنشاء العقد",empty:"لم يتم العثور على حجوزات."}}[e];(0,r.useEffect)(()=>{(0,i.apiFetch)("/reservations?pageSize=100").then(e=>o(e??[])).catch(e=>p(e.message??"Failed to load contracts"))},[]);let h=(0,r.useMemo)(()=>{let e=c.trim().toLowerCase();return e?l.filter(t=>`${t.customer.firstName} ${t.customer.lastName}`.toLowerCase().includes(e)||t.customer.email.toLowerCase().includes(e)||`${t.vehicle.make} ${t.vehicle.model}`.toLowerCase().includes(e)||t.vehicle.licensePlate.toLowerCase().includes(e)||(t.contractNumber??"").toLowerCase().includes(e)||(t.invoiceNumber??"").toLowerCase().includes(e)):l},[l,c]),f="fr"===e?"fr-FR":"ar"===e?"ar-MA":"en-US",x=e=>new Date(e).toLocaleString(f,{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"});return(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h2",{className:"text-xl font-semibold text-slate-900",children:m.heading}),(0,t.jsx)("p",{className:"mt-1 text-sm text-slate-500",children:m.subtitle})]}),(0,t.jsx)("input",{value:c,onChange:e=>u(e.target.value),placeholder:m.search,className:"input-field w-full lg:max-w-md"})]}),(0,t.jsx)("div",{className:"card overflow-hidden",children:d?(0,t.jsx)("div",{className:"p-6 text-sm text-red-600",children:d}):(0,t.jsx)("div",{className:"overflow-x-auto",children:(0,t.jsxs)("table",{className:"w-full",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"border-b border-slate-200 bg-slate-50",children:[(0,t.jsx)("th",{className:"px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-slate-500",children:m.customer}),(0,t.jsx)("th",{className:"px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-slate-500",children:m.vehicle}),(0,t.jsx)("th",{className:"px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-slate-500",children:m.dates}),(0,t.jsx)("th",{className:"px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-slate-500",children:m.contract}),(0,t.jsx)("th",{className:"px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-slate-500",children:m.invoice}),(0,t.jsx)("th",{className:"px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-slate-500",children:m.status}),(0,t.jsx)("th",{className:"px-6 py-3 text-right text-xs font-medium uppercase tracking-wide text-slate-500",children:m.total}),(0,t.jsx)("th",{className:"px-6 py-3 text-right text-xs font-medium uppercase tracking-wide text-slate-500",children:m.action})]})}),(0,t.jsxs)("tbody",{className:"divide-y divide-slate-100",children:[h.map(e=>(0,t.jsxs)("tr",{children:[(0,t.jsxs)("td",{className:"px-6 py-4 text-sm",children:[(0,t.jsxs)("p",{className:"font-semibold text-slate-900",children:[e.customer.firstName," ",e.customer.lastName]}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:e.customer.email})]}),(0,t.jsxs)("td",{className:"px-6 py-4 text-sm text-slate-700",children:[(0,t.jsxs)("p",{children:[e.vehicle.make," ",e.vehicle.model]}),(0,t.jsx)("p",{className:"text-xs text-slate-500",children:e.vehicle.licensePlate})]}),(0,t.jsxs)("td",{className:"px-6 py-4 text-sm text-slate-600",children:[(0,t.jsx)("p",{children:x(e.startDate)}),(0,t.jsx)("p",{children:x(e.endDate)})]}),(0,t.jsx)("td",{className:"px-6 py-4 text-sm text-slate-700",children:e.contractNumber??"—"}),(0,t.jsx)("td",{className:"px-6 py-4 text-sm text-slate-700",children:e.invoiceNumber??"—"}),(0,t.jsx)("td",{className:"px-6 py-4 text-sm",children:(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)("span",{className:"badge-blue",children:e.status}),(0,t.jsx)("span",{className:"badge-gray",children:e.paymentStatus})]})}),(0,t.jsx)("td",{className:"px-6 py-4 text-right text-sm font-semibold text-slate-900",children:(0,s.formatCurrency)(e.totalAmount,"MAD")}),(0,t.jsx)("td",{className:"px-6 py-4 text-right",children:(0,t.jsx)(a.default,{href:`/contracts/${e.id}`,className:"text-sm font-semibold text-blue-700 hover:underline",children:e.contractNumber?m.open:m.generate})})]},e.id)),0===h.length&&(0,t.jsx)("tr",{children:(0,t.jsx)("td",{colSpan:8,className:"px-6 py-10 text-center text-sm text-slate-400",children:m.empty})})]})]})})})]})}])}]); |