// primitives.jsx — shared building blocks for MonVTC screens // Loaded after React + Babel, before screens-*.jsx and app.jsx. const { useState, useMemo, useEffect, useRef } = React; /* ── Icon set ────────────────────────────────────────────── */ function Icon({ name, size = 16, ...rest }) { const paths = { pin: <>, dot: , arrowRight: <>, arrowLeft: <>, chevronRight: , chevronDown: , check: , plus: <>, user: <>, users: <>, cal: <>, clock: <>, car: <>, van: <>, star: , starHalf: , shield: , bolt: , sparkle: <>, phone: , mail: <>, msg: , search: <>, menu: <>, eye: <>, settings: <>, bell: <>, cards: <>, heart: , download: <>, edit: <>, trash: <>, filter: <>, lock: <>, apple: , google: <>, }; const p = paths[name] || paths.dot; return ( {p} ); } /* ── Logo ────────────────────────────────────────────────── */ function Logo({ size = 1, light }) { return ( m monvtc.fr ); } /* ── Header / nav ────────────────────────────────────────── */ function SiteHeader({ active = 'home', minimal }) { const items = [ ['Réserver', 'book'], ['Services', 'services'], ['Tarifs', 'pricing'], ['Entreprise', 'biz'], ['Aide', 'help'], ]; return (
{!minimal && ( )}
+33 1 86 65 12 40
); } /* ── Footer ─────────────────────────────────────────────── */ function SiteFooter() { const cols = [ ['Société', ['À propos', 'Notre flotte', 'Chauffeurs', 'Carrières', 'Presse']], ['Services', ['Aéroport', 'Mise à disposition', 'Événementiel', 'Longue distance', 'Entreprise']], ['Aide', ['Centre d\'aide', 'Contact', 'Annulation', 'Facturation', 'Politique tarifaire']], ['Légal', ['Mentions légales', 'CGV', 'Confidentialité', 'Cookies']], ]; return (

Service VTC haut de gamme à Paris et en Île-de-France. Disponible 24/7 avec chauffeurs professionnels.

EVTC certifié ISO 9001
{cols.map(([title, links]) => (
{title}
    {links.map(l =>
  • {l}
  • )}
))}
© 2026 monvtc.fr — SAS au capital de 50 000 € FR · € Disponible 24/7
); } /* ── Status pill ─────────────────────────────────────────── */ function Status({ kind, label }) { const m = { confirmed: ['mv-badge-ok', 'Confirmé'], pending: ['mv-badge-warn', 'En attente'], enroute: ['mv-badge-info', 'Chauffeur en route'], completed: ['', 'Terminé'], cancelled: ['mv-badge-bad', 'Annulé'], }; const [cls, txt] = m[kind] || ['', label]; return {label || txt}; } /* ── Stars row ─────────────────────────────────────────── */ function Stars({ n = 5, size = 12 }) { return ( {Array.from({ length: 5 }).map((_, i) => ( ))} ); } /* ── Image placeholder via Unsplash ──────────────────── */ function UImage({ id, w = 800, h = 600, alt = '', style, className }) { // Curated photo IDs from Unsplash. We construct the canonical CDN URL. return ( {alt} ); } /* ── Phone frame ─────────────────────────────────── */ function PhoneFrame({ children, style }) { return (
{/* status bar */}
9:41
{children}
{/* home indicator */}
); } Object.assign(window, { Icon, Logo, SiteHeader, SiteFooter, Status, Stars, UImage, PhoneFrame });