// Rental page with filters, fleet grid, and detail drawer with floorplan const { useState: useStateR, useMemo: useMemoR } = React; function FilterBar({ filters, setFilters, count }) { const groups = { type: { label: 'Type', options: ['All', 'Solo', 'Couples', 'Family', 'Group'] }, sleeps: { label: 'Sleeps', options: ['Any', '2', '4', '5+'] }, transmission: { label: 'Transmission', options: ['Any', 'Auto', 'Manual'] }, license: { label: 'License', options: ['Any', 'B/D', 'D', 'E'] }, }; return (
{Object.entries(groups).map(([key, g]) => (
{g.label} {g.options.map(opt => ( ))}
))} {count} VANS · 04 AVAILABLE
); } function RentalCard({ vehicle, onOpen }) { return (
onOpen(vehicle)}>
{vehicle.tag} {vehicle.available ? 'Available' : 'Booked'}
{vehicle.name}
{vehicle.sub}
Sleeps {vehicle.sleeps} {vehicle.seats} seats {vehicle.length} {vehicle.transmission}
RM {vehicle.price}/ night
View
); } function Floorplan() { const [active, setActive] = useStateR(FLOORPLAN_HOTSPOTS[0].id); const cur = FLOORPLAN_HOTSPOTS.find(h => h.id === active); return (

Interior floorplan

TAP HOTSPOTS
{/* Body outline */} {/* Cab area */} {/* Driver/passenger seats */} {/* Bed (over cab) */} BED {/* Kitchen */} {/* Dinette */} DINETTE {/* Wet bath */} WC {/* Lounge/storage */} {/* Hotspots */} {FLOORPLAN_HOTSPOTS.map(h => ( setActive(h.id)}> {FLOORPLAN_HOTSPOTS.indexOf(h) + 1} ))}
{cur.label}

{cur.desc}

); } function RentalDrawer({ vehicle, onClose, bookingState, onBook }) { const [tab, setTab] = useStateR('overview'); if (!vehicle) return null; const nights = bookingState?.start && bookingState?.end ? Math.ceil((bookingState.end - bookingState.start) / 86400000) : 0; const total = nights * vehicle.price; return ( <>
{vehicle.tag.toUpperCase()} / {vehicle.id.toUpperCase()}
{vehicle.gallery.map((src, i) => (
))}
{vehicle.sub}

{vehicle.name}

{[ { id: 'overview', label: 'Overview' }, { id: 'specs', label: 'Specs' }, { id: 'floorplan', label: 'Floorplan' }, { id: 'price', label: 'Pricing' }, ].map(t => ( ))}
{tab === 'overview' && (

{vehicle.desc}

{[ { icon: , label: 'Sleeps', val: vehicle.sleeps }, { icon: , label: 'Seats', val: vehicle.seats }, { icon: , label: 'Length', val: vehicle.length }, { icon: , label: 'License', val: vehicle.license }, ].map((s, i) => (
{s.icon}
{s.label.toUpperCase()}
{s.val}
))}

What's included

    {['Unlimited Peninsula miles', 'Comprehensive insurance', 'RFID + first tank fuel', 'Bedding & towel set', 'Camp chairs & table', '24/7 roadside support'].map(item => (
  • {item}
  • ))}
)} {tab === 'specs' && (
{Object.entries(vehicle.specs).map(([k, v]) => (
{k}
{v}
))}
)} {tab === 'floorplan' && } {tab === 'price' && (
Daily rate RM {vehicle.price}
Nights × {nights || '—'}
Comprehensive insurance Included
Peninsular miles Unlimited
Subtotal RM {total ? total.toLocaleString() : '—'}

Free cancellation up to 14 days before pickup. No deposit on weeknight pickups. Final price confirmed by our team within 1 hour.

)}
{bookingState?.start && bookingState?.end ? `${formatDate(bookingState.start)} → ${formatDate(bookingState.end)} · ${nights} NIGHTS` : 'NO DATES SELECTED'} {total ? `RM ${total.toLocaleString()}` : `RM ${vehicle.price} / night`}
); } function RentalPage({ bookingState, setBookingState, onToast }) { const [filters, setFilters] = useStateR({ type: 'All', sleeps: 'Any', transmission: 'Any', license: 'Any' }); const [openVehicle, setOpenVehicle] = useStateR(null); const filtered = useMemoR(() => { return FLEET.filter(v => { if (filters.type !== 'All' && v.tag !== filters.type) return false; if (filters.sleeps !== 'Any') { if (filters.sleeps === '5+' && v.sleeps < 5) return false; else if (filters.sleeps !== '5+' && String(v.sleeps) !== filters.sleeps) return false; } if (filters.transmission !== 'Any' && v.transmission !== filters.transmission) return false; if (filters.license !== 'Any' && v.license !== filters.license) return false; return true; }); }, [filters]); const onBook = (v) => { setOpenVehicle(null); onToast(`${v.name} reserved — our team will confirm within 1 hour.`); }; return (
Rental fleet · Klang HQ

Six builds. Pick the one that's already going where you're going.

Every motorhome below is hand-built and maintained in our Klang workshop. Photographed exactly as you'll find it. Pick a date, lock the keys.

{filtered.map(v => )}
{filtered.length === 0 && (

Nothing matches that combination — yet.

Loosen a filter, or call our team. We sometimes hold builds back for repeat customers.

)}
{openVehicle && ( setOpenVehicle(null)} bookingState={bookingState} onBook={onBook} /> )}
); } window.RentalPage = RentalPage;