// CeyRide — Shared UI Components
// ── FX rate constant — update this when the rate changes significantly ──
const CR_USD_RATE = 320; // LKR per 1 USD (approx)
// Vehicle image — uses real photo if available, striped placeholder otherwise
function VehiclePlaceholder({ type = "Car", color = "#E84800", width = "100%", height = 180, imageUrl, style: extraStyle }) {
if (imageUrl) {
return (
setHovered(true)}
onMouseLeave={() => setHovered(false)}
style={{
background: '#fff', borderRadius: 20,
overflow: 'hidden', cursor: 'pointer',
boxShadow: hovered ? '0 12px 40px rgba(20,20,19,0.12)' : '0 2px 12px rgba(20,20,19,0.06)',
transition: 'all 0.25s ease',
transform: hovered ? 'translateY(-4px)' : 'translateY(0)'
}}>
{/* Image */}
{/* Issue #9 fix — spec-correct badge labels driven by new capability flags */}
{hasOwnerDriver && }
{hasSelfDrive && }
{/* Content */}
{v.brand} {v.model}
{v.seats} seats · {v.location}
{showFromLabel && from }
Rs. {fromPrice.toLocaleString()}
≈ USD {Math.round(fromPrice / CR_USD_RATE)}/day
{v.rating} ({v.reviews} reviews)
{/* Issue #2 fix — route through mode selector, never directly to booking */}
);
}
// Section title component
function SectionTitle({ eyebrow, title, subtitle, center = false }) {
return (