/* ============================================================ Rent-a-Car — Mobility & Fleet service page ============================================================ */ /* date helper — YYYY-MM-DD with day offset */ function nigerToday(offsetDays = 0) { const d = new Date(Date.now() + offsetDays * 86400000); return d.toISOString().slice(0, 10); } const FLEET_CATS = [ { k: "all", label: { en: "All", fr: "Tous" } }, { k: "sedan", label: { en: "Sedans", fr: "Berlines" } }, { k: "suv", label: { en: "SUVs & 4x4", fr: "SUV & 4x4" } }, { k: "van", label: { en: "Vans", fr: "Vans" } }, { k: "pickup", label: { en: "Pickups", fr: "Pickups" } }, ]; /* Fleet now loads live from Supabase (see gg-supabase.js). window.GG_DATA.fleet is filled before React mounts. */ const FLEET = (window.GG_DATA && window.GG_DATA.fleet) || []; /* Local fleet images — exact match per model */ /* Fleet images: local fallback merged live with Supabase paths via Proxy */ const RAC_VEHICLE_PHOTOS_LOCAL = { "Toyota Corolla": "assets/fleet/toyota-corolla.jpg", "Hyundai Elantra": "assets/fleet/elantra.jpg", "Toyota RAV4": "assets/fleet/toyota-rav4.webp", "Toyota Land Cruiser": "assets/fleet/land-cruiser.jpg", "Mercedes Sprinter": "assets/fleet/mercedes-sprinter.png", "Toyota HiAce": "assets/fleet/toyota-hiace.webp", "Toyota Hilux D/Cab": "assets/fleet/toyota-hilux.jpg", "Ford Ranger": "assets/fleet/ford-ranger.jpg", "Kia Sportage": "assets/fleet/kia-sportage.jpg", "Toyota Prado": "assets/fleet/toyota-prado.jpg", "Mitsubishi L200": "assets/fleet/mitsubishi-triton.jpg", "Toyota Coaster": "assets/fleet/toyota-coaster.jpg", }; const RAC_VEHICLE_PHOTOS = new Proxy(RAC_VEHICLE_PHOTOS_LOCAL, { get(local, key) { const live = (window.GG_DATA && window.GG_DATA.fleetImgs) || {}; return live[key] || local[key]; }, }); function RACImg({ name, cover }) { const [err, setErr] = useState(false); const src = RAC_VEHICLE_PHOTOS[name] || "assets/fleet/land-cruiser.jpg"; if (err) return
; return (
{name} setErr(true)} loading="lazy" />
); } /* ---------- Google-Maps-style pick-up autocomplete ---------- */ const NIGER_PLACES = [ { main: "A\u00e9roport International Diori Hamani", sec: "Niamey · Airport pick-up", branch: true }, { main: "Guero\u2019s Group \u2014 Niamey Centre", sec: "Bd de l\u2019Ind\u00e9pendance, Niamey", branch: true }, { main: "Guero\u2019s Group \u2014 Rive Droite", sec: "Route de Torodi, Niamey", branch: true }, { main: "Plateau", sec: "Niamey, Niger" }, { main: "Yantala", sec: "Niamey, Niger" }, { main: "Lazaret", sec: "Niamey, Niger" }, { main: "Kouara Kano", sec: "Niamey, Niger" }, { main: "Gamkall\u00e9", sec: "Niamey, Niger" }, { main: "Maradi", sec: "R\u00e9gion de Maradi, Niger" }, { main: "Zinder", sec: "R\u00e9gion de Zinder, Niger" }, { main: "Agadez", sec: "R\u00e9gion d\u2019Agadez, Niger" }, { main: "Tahoua", sec: "R\u00e9gion de Tahoua, Niger" }, { main: "Dosso", sec: "R\u00e9gion de Dosso, Niger" }, { main: "Arlit", sec: "R\u00e9gion d\u2019Agadez, Niger" }, { main: "Tillab\u00e9ri", sec: "R\u00e9gion de Tillab\u00e9ri, Niger" }, { main: "Diffa", sec: "R\u00e9gion de Diffa, Niger" }, ]; function GoogleAttribution() { return (
{L("powered by", "fourni par")} Google
); } function PlacesAutocomplete({ defaultValue }) { const [value, setValue] = useState(defaultValue || ""); const [open, setOpen] = useState(false); const [active, setActive] = useState(0); const boxRef = useRef(null); useEffect(() => { const h = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setOpen(false); }; document.addEventListener("mousedown", h); return () => document.removeEventListener("mousedown", h); }, []); const q = value.trim().toLowerCase(); const matches = (q === "" ? NIGER_PLACES : NIGER_PLACES.filter((p) => (p.main + " " + p.sec).toLowerCase().includes(q))).slice(0, 6); const choose = (p) => { setValue(p.main); setOpen(false); }; const onKey = (e) => { if (!open || !matches.length) return; if (e.key === "ArrowDown") { e.preventDefault(); setActive((a) => Math.min(a + 1, matches.length - 1)); } else if (e.key === "ArrowUp") { e.preventDefault(); setActive((a) => Math.max(a - 1, 0)); } else if (e.key === "Enter") { e.preventDefault(); if (matches[active]) choose(matches[active]); } else if (e.key === "Escape") setOpen(false); }; return (
{ setValue(e.target.value); setOpen(true); setActive(0); }} onFocus={() => setOpen(true)} onKeyDown={onKey} placeholder={L("Search a city, branch or airport", "Ville, agence ou a\u00e9roport")} style={inpStyle} autoComplete="off" /> {open && (
{matches.length === 0 ? (
{L("No matching place", "Aucun lieu trouv\u00e9")}
) : matches.map((p, i) => ( ))}
)}
); } /* ---------- Corporate / fleet-sales contact modal ---------- */ function FleetSalesModal({ onClose }) { const [done, setDone] = useState(false); useEffect(() => { document.body.classList.add("no-scroll"); return () => document.body.classList.remove("no-scroll"); }, []); return ReactDOM.createPortal(
e.stopPropagation()} style={{ background: "var(--paper)", borderRadius: 6, width: "min(560px,100%)", maxHeight: "90vh", overflow: "auto", boxShadow: "0 40px 80px -30px rgba(0,0,0,.6)" }}>
{done ? (

{L("Request received!", "Demande envoy\u00e9e !")}

{L("Our fleet-sales team will get back to you within one business day to build a tailored proposal.", "Notre \u00e9quipe flotte vous recontacte sous un jour ouvr\u00e9 pour b\u00e2tir une proposition sur mesure.")}

) : (
{ e.preventDefault(); setDone(true); }}>
{L("For business", "Pour les entreprises")}

{L("Talk to fleet sales", "Parler aux ventes flotte")}

{L("Tell us about your team and we\u2019ll put together monthly or annual leasing options.", "Parlez-nous de vos besoins et nous pr\u00e9parons des options de location mensuelle ou annuelle.")}