// Cars search panel — additive. Renders inside the existing glass search panel when // mode === "cars". Accent: --grass. Cars are a MOCK subgraph (Duffel has no car API), // so results come from EHT_API's client-side fallback until a real provider is wired. const CarSearchPanel = () => { const [pickupOpen, setPickupOpen] = useState(false); const [dropoffOpen, setDropoffOpen] = useState(false); const [pickup, setPickup] = useState(AIRPORTS.find(a => a.code === "LAX") || AIRPORTS[0]); const [dropoff, setDropoff] = useState(null); // null = same as pickup const [pickupDate, setPickupDate] = useState(""); const [dropoffDate, setDropoffDate] = useState(""); const [age, setAge] = useState(30); const [loading, setLoading] = useState(false); const [results, setResults] = useState(null); const [booking, setBooking] = useState(null); const choices = useMemo(() => AIRPORTS.map(a => ({ code: a.code, city: a.city, country: a.name })), []); async function runSearch() { setLoading(true); setResults(null); const list = await EHT_API.searchCars({ pickupLocation: `${pickup.city} (${pickup.code})`, dropoffLocation: dropoff ? `${dropoff.city} (${dropoff.code})` : `${pickup.city} (${pickup.code})`, pickupDate: pickupDate ? pickupDate + "T10:00" : undefined, dropoffDate: dropoffDate ? dropoffDate + "T10:00" : undefined, driverAge: age, }); setLoading(false); setResults(list); } const dropdownOpen = pickupOpen || dropoffOpen; return (
{/* Field row — white row with grass accent, matches flights style */}
} accent="var(--grass)" value={pickup.city} sub={pickup.code} onClick={() => { setPickupOpen(o => !o); setDropoffOpen(false); }} open={pickupOpen}> {pickupOpen && { setPickup(AIRPORTS.find(a => a.code === c.code)); setPickupOpen(false); }} placeholder="City or airport" />} } accent="var(--grass)" value={dropoff ? dropoff.city : "Same as pick-up"} sub={dropoff ? dropoff.code : "one location"} onClick={() => { setDropoffOpen(o => !o); setPickupOpen(false); }} open={dropoffOpen}> {dropoffOpen && { setDropoff(c.code === "SAME" ? null : AIRPORTS.find(a => a.code === c.code)); setDropoffOpen(false); }} placeholder="City or airport" />}
{/* ── Push-content spacer (animates when dropdown is open) ── */}
{/* Quick filter chips — light theme */}
{["Automatic", "SUV", "Unlimited miles", "Free cancellation"].map((c) => ( ))} demo inventory · provider-ready schema
{(loading || results) && ( setResults(null)} loading={loading} count={results?.length || 0} accent="var(--grass)"> {results?.map((c) => setBooking(c)} />)} {results && results.length === 0 && } )} {booking && ( setBooking(null)} onConfirm={async () => ({ reference: "EHT-CAR-" + Math.random().toString(36).slice(2, 8).toUpperCase(), _mock: true })} /> )}
); }; window.CarSearchPanel = CarSearchPanel;