// Shared components for VIP Motors prototype const { useState, useEffect, useRef, useMemo } = React; // ── Logo ────────────────────────────────────────────────────────── function Logo({ variant = "white", height = 28 }) { const src = variant === "white" ? "media/logo-white.webp" : "media/logo-dark.webp"; return ( VIP Motors ); } // ── Icons (inline minimal SVG) ──────────────────────────────────── function Icon({ name, size = 16 }) { const s = size; const stroke = { fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }; switch (name) { case "arrow": return ; case "arrow-up-right": return ; case "close": return ; case "phone": return ; case "whatsapp": return ; case "mail": return ; case "pin": return ; case "menu": return ; case "filter": return ; case "back": return ; case "share": return ; case "heart": return ; case "check": return ; case "globe": return ; case "camera": return ; default: return null; } } // ── Navbar ──────────────────────────────────────────────────────── function Nav({ route, navigate, onEnquire, tweaks }) { const [scrolled, setScrolled] = useState(false); const [mobileOpen, setMobileOpen] = useState(false); const [lang, setLang] = useState("EN"); const onPaper = route === "sell" || route === "contact"; useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 20); window.addEventListener("scroll", onScroll); return () => window.removeEventListener("scroll", onScroll); }, []); const links = [ { k: "inventory", label: "Inventory" }, { k: "sell", label: "Sell / Trade-in" }, { k: "finance", label: "Finance" }, { k: "about", label: "About" }, { k: "contact", label: "Contact" } ]; const bg = scrolled || onPaper ? (onPaper ? "rgba(246,245,243,0.92)" : "rgba(11,12,14,0.82)") : "transparent"; const color = onPaper ? "var(--ink-on-paper)" : "var(--text)"; const borderB = scrolled || onPaper ? `1px solid ${onPaper ? "var(--rule)" : "var(--line)"}` : "1px solid transparent"; return (
); } // ── Vehicle Card ────────────────────────────────────────────────── function VehicleCard({ v, onOpen, onEnquire, paper }) { return (
onOpen(v.slug)}>
{`${v.year} {v.badges && v.badges.length > 0 && (
{v.badges.slice(0, 2).map(b => ( {b} ))}
)}
{v.year} · {v.body}
{v.make} {v.model}
{v.headline && (
{v.headline}
)}
Request price
); } // ── Modal ───────────────────────────────────────────────────────── function Modal({ open, onClose, title, children }) { useEffect(() => { if (!open) return; const onKey = (e) => e.key === "Escape" && onClose(); document.addEventListener("keydown", onKey); document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = ""; }; }, [open, onClose]); if (!open) return null; return (
e.stopPropagation()}>
{title}
{children}
); } // ── Enquiry form ────────────────────────────────────────────────── function EnquiryForm({ vehicle, type = "Enquire", onSubmitted }) { const [data, setData] = useState({ name: "", phone: "", email: "", message: "" }); const [sent, setSent] = useState(false); const update = (k) => (e) => setData({ ...data, [k]: e.target.value }); const onSubmit = (e) => { e.preventDefault(); setSent(true); setTimeout(() => onSubmitted && onSubmitted(), 1600); }; if (sent) { return (
Enquiry received.
A specialist will respond within one business day, typically by WhatsApp.
); } return (
{vehicle && (
{vehicle.year} · {type.toUpperCase()}
{vehicle.make} {vehicle.model}
)}