window.onerror = function(msg, url, line) { console.error('ERREUR JS :', msg, line); }; const state = { isReturnTrip: false, profile: { firstName: 'Marie', lastName: 'Dupont', phone: '06 12 34 56 78', email: 'marie@email.com', address: '' }, customerType: 'particulier', billingAddress: '', company: { name: '', siret: '', vat: '', billingEmail: '' }, drivers: [ { id: 'karim', name: 'Karim', photo: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face', status: 'Disponible', vehicle: 'Mercedes Classe E', rate: 2, rides: 18, favorite: true, available: true, phone: '+33612345678' }, { id: 'sofiane', name: 'Sofiane', photo: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=100&h=100&fit=crop&crop=face', status: 'Disponible', vehicle: 'Tesla Model 3', rate: 2.2, rides: 11, favorite: false, available: true, phone: '+33623456789' }, { id: 'nadia', name: 'Nadia', photo: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop&crop=face', status: 'Occupé', vehicle: 'Peugeot 508', rate: 1.9, rides: 7, favorite: false, available: false, phone: '+33634567890' }, { id: 'rachid', name: 'Rachid', photo: 'https://images.unsplash.com/photo-1531123897727-8f129e1688ce?w=100&h=100&fit=crop&crop=face', status: 'Hors ligne', vehicle: 'Toyota Corolla', rate: 2, rides: 5, favorite: false, available: false, phone: '+33645678901' } ], favoriteAddresses: [ { id:'home', label:'Maison', tag:'maison', icon:'home', address:'12 Rue de la Paix, Paris' }, { id:'work', label:'Travail', tag:'travail', icon:'briefcase', address:'Bureau, Paris' }, { id:'airport', label:'Aéroport', tag:'aéroport', icon:'plane', address:'Aéroport CDG, Terminal 2' }, { id:'station', label:'Gare', tag:'gare', icon:'train', address:'Gare de Lyon, Paris' } ], rides: [ { id: 1, date: "Aujourd'hui à 14:30", from: '12 Rue de la Paix', to: 'Aéroport CDG', driver: 'Karim', status: 'Confirmée', amount: '52 €', filter: 'today', vehicle: 'Mercedes Classe E', distance: '24 km', rate: 2, passengers: 1, luggage: 1, animal: false }, { id: 2, date: 'Envoyée il y a 5 min', from: 'Domicile', to: 'Gare de Lyon', driver: 'Demande groupée', status: 'En attente', amount: null, filter: 'today', vehicle: '-', distance: '-', rate: null, passengers: 1, luggage: 1, animal: false }, { id: 3, date: 'Demain à 09:00', from: 'Orly', to: 'La Défense', driver: 'Sofiane', status: 'Confirmée', amount: '45 €', filter: 'upcoming', vehicle: 'Tesla Model 3', distance: '22 km', rate: 2.2, passengers: 2, luggage: 2, animal: false }, { id: 4, date: 'Hier à 18:15', from: 'Bureau', to: 'Domicile', driver: 'Karim', status: 'Terminée', amount: '28 €', filter: 'past', vehicle: 'Mercedes Classe E', distance: '14 km', rate: 2, passengers: 1, luggage: 0, animal: false }, { id: 5, date: '12/01/2026', from: 'Domicile', to: 'Gare du Nord', driver: 'Nadia', status: 'Annulée', amount: '-', filter: 'cancelled', vehicle: 'Peugeot 508', distance: '-', rate: 1.9, passengers: 1, luggage: 1, animal: false } ], relatives: [ { firstName: 'Lucas', lastName: 'Dupont', phone: '06 23 45 67 89' } ], segment: 'fav', when: 'now', passengers: 1, luggage: 1, animal: false, forOther: false, currentRide: null }; const views = ['home', 'drivers', 'rides', 'profile']; function showView(name) { views.forEach(v => { const el = document.getElementById('view-' + v); if (el) { el.classList.add('hidden'); el.classList.remove('flex'); el.classList.remove('block'); } }); const target = document.getElementById('view-' + name); if (target) { target.classList.remove('hidden'); if (target.tagName.toLowerCase() === 'main') { target.classList.add('block'); } else { target.classList.add('block'); } target.scrollTop = 0; } document.querySelectorAll('.nav-btn').forEach(btn => { if (btn.dataset.view === name) { btn.classList.remove('text-white/40'); btn.classList.add('text-emerald-400'); } else { btn.classList.remove('text-emerald-400'); btn.classList.add('text-white/40'); } }); } function openModal(id) { const el = document.getElementById(id); if (!el) return; el.classList.remove('hidden'); void el.offsetWidth; el.classList.add('active'); lucide.createIcons(); } function closeModal(id) { const el = document.getElementById(id); if (!el) return; el.classList.remove('active'); setTimeout(() => el.classList.add('hidden'), 300); } function renderDrivers() { const container = document.getElementById('drivers-list'); if (!container) return; if (state.drivers.length === 0) { container.innerHTML = '

Aucun chauffeur dans votre réseau.

'; lucide.createIcons(); return; } container.innerHTML = state.drivers.map(d => { const statusColor = d.status === 'Disponible' ? 'text-emerald-400' : d.status === 'Occupé' ? 'text-amber-400' : 'text-white/40'; return `

${d.name}

${d.status}

${d.vehicle} • ${d.rate.toFixed(1).replace('.0','')} €/km • ${d.rides} courses

${d.phone ? `` : ''}
`; }).join(''); lucide.createIcons(); } function setFavoriteDriver(id) { state.drivers.forEach(d => d.favorite = (d.id === id)); renderDrivers(); renderSelectedDriver(); renderEstimate(); } function removeDriver(id) { const wasFav = state.drivers.find(d => d.id === id)?.favorite; state.drivers = state.drivers.filter(d => d.id !== id); if (wasFav && state.drivers.length > 0) { state.drivers[0].favorite = true; } renderDrivers(); renderSelectedDriver(); renderEstimate(); } function selectDriver(id) { setFavoriteDriver(id); setSegment('fav'); showView('home'); } function selectDriverFromModal(id) { setFavoriteDriver(id); setSegment('fav'); renderSelectedDriver(); renderEstimate(); closeModal('modal-select-driver'); closeModal('modal-available-drivers'); } function renderSelectedDriver() { const block = document.getElementById('driver-block'); if (!block) return; if (state.segment === 'group') { block.innerHTML = `

Tous mes chauffeurs

Demande groupée

`; } else { const fav = state.drivers.find(d => d.favorite) || state.drivers[0]; if (!fav) { block.innerHTML = '

Aucun chauffeur favori

'; lucide.createIcons(); return; } block.innerHTML = `

${fav.name}

${fav.status}

${fav.phone ? `` : ''}
`; } block.classList.add('cursor-pointer'); block.onclick = openSelectDriverSheet; lucide.createIcons(); } function renderEstimate() { const dep = document.getElementById('input-depart')?.value?.trim(); const arr = document.getElementById('input-arrivee')?.value?.trim(); const block = document.getElementById('estimate-block'); const priceEl = document.getElementById('estimate-price'); const preview = document.getElementById('route-preview'); if (!dep || !arr) { block?.classList.add('hidden'); preview?.classList.add('hidden'); return; } block?.classList.remove('hidden'); preview?.classList.remove('hidden'); const distance = 12; let price = 0; if (state.segment === 'fav') { const fav = state.drivers.find(d => d.favorite) || state.drivers[0]; if (fav) price = distance * fav.rate; } else { const availableRates = state.drivers.filter(d => d.available).map(d => d.rate); const minRate = availableRates.length > 0 ? Math.min(...availableRates) : 0; price = distance * minRate; } if (priceEl) priceEl.textContent = price.toFixed(2).replace('.00','') + ' €'; } function setSegment(type) { state.segment = type; const favBtn = document.getElementById('seg-fav'); const groupBtn = document.getElementById('seg-group'); if (type === 'fav') { favBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'; groupBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all text-white/45 hover:text-white/70'; } else { groupBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'; favBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all text-white/45 hover:text-white/70'; } renderSelectedDriver(); renderEstimate(); } function addStop() { const container = document.getElementById('extra-stops'); const div = document.createElement('div'); div.className = 'flex items-center gap-3 bg-[#0b0b0f] border border-white/10 rounded-xl px-3 py-3 animate-fade-in'; div.innerHTML = `
`; container.appendChild(div); lucide.createIcons(); } function setWhen(type) { state.when = type; const btnNow = document.getElementById('btn-now'); const btnLater = document.getElementById('btn-later'); if (type === 'now') { btnNow.className = 'press flex-1 py-2.5 rounded-xl border text-sm font-medium transition-all bg-emerald-500/10 border-emerald-500/30 text-emerald-400'; btnLater.className = 'press flex-1 py-2.5 rounded-xl border text-sm font-medium transition-all bg-transparent border-white/10 text-white/45'; } else { btnNow.className = 'press flex-1 py-2.5 rounded-xl border text-sm font-medium transition-all bg-transparent border-white/10 text-white/45'; btnLater.className = 'press flex-1 py-2.5 rounded-xl border text-sm font-medium transition-all bg-emerald-500/10 border-emerald-500/30 text-emerald-400'; openModal('modal-datetime'); } } function confirmDateTime() { closeModal('modal-datetime'); } function adjust(key, delta) { state[key] = Math.max(0, state[key] + delta); if (key === 'passengers' && state[key] < 1) state[key] = 1; const el = document.getElementById('val-' + key); if (el) el.textContent = state[key]; } function toggleAnimal() { state.animal = !state.animal; const btn = document.getElementById('btn-animal'); if (state.animal) { btn.textContent = 'Oui'; btn.classList.remove('border-white/10','text-white/45'); btn.classList.add('border-emerald-500/30','bg-emerald-500/10','text-emerald-400'); } else { btn.textContent = 'Non'; btn.classList.add('border-white/10','text-white/45'); btn.classList.remove('border-emerald-500/30','bg-emerald-500/10','text-emerald-400'); } } function toggleForOther() { state.forOther = !state.forOther; const btn = document.getElementById('btn-for-other'); const fields = document.getElementById('fields-for-other'); if (state.forOther) { btn.textContent = 'Oui'; btn.classList.remove('border-white/10','text-white/45'); btn.classList.add('border-emerald-500/30','bg-emerald-500/10','text-emerald-400'); fields.classList.remove('hidden'); } else { btn.textContent = 'Non'; btn.classList.add('border-white/10','text-white/45'); btn.classList.remove('border-emerald-500/30','bg-emerald-500/10','text-emerald-400'); fields.classList.add('hidden'); } } function sendRequest() { state.isReturnTrip = false; renderReturnBadge(); openModal('modal-loading'); const title = document.getElementById('loading-title'); const sub = document.getElementById('loading-sub'); title.textContent = 'Demande envoyée'; if (state.segment === 'group') { sub.textContent = 'Vos chauffeurs de confiance reçoivent la demande…'; setTimeout(() => { sub.textContent = 'Karim consulte…'; }, 1800); setTimeout(() => { sub.textContent = 'Sofiane consulte…'; }, 2800); setTimeout(() => { sub.textContent = 'Sofiane confirme votre trajet'; title.textContent = 'Course confirmée'; }, 3800); setTimeout(() => { closeModal('modal-loading'); openModal('modal-return'); }, 4800); } else { const fav = state.drivers.find(d => d.favorite) || { name: 'Karim' }; sub.textContent = fav.name + ' consulte votre demande…'; setTimeout(() => { sub.textContent = 'Votre chauffeur vérifie sa disponibilité'; }, 1800); setTimeout(() => { sub.textContent = fav.name + ' confirme votre trajet'; title.textContent = 'Course confirmée'; }, 3200); setTimeout(() => { closeModal('modal-loading'); openModal('modal-return'); }, 4200); } } function renderReturnBadge() { const badge = document.getElementById('return-badge'); if (!badge) return; if (state.isReturnTrip) { badge.classList.remove('hidden'); } else { badge.classList.add('hidden'); } } function handleReturn(yes) { closeModal('modal-return'); if (yes) { const dep = document.getElementById('input-depart').value; const arr = document.getElementById('input-arrivee').value; document.getElementById('input-depart').value = arr; document.getElementById('input-arrivee').value = dep; document.getElementById('extra-stops').innerHTML = ''; state.isReturnTrip = true; renderReturnBadge(); renderEstimate(); window.scrollTo({top:0, behavior:'smooth'}); } else { document.getElementById('input-depart').value = ''; document.getElementById('input-arrivee').value = ''; document.getElementById('extra-stops').innerHTML = ''; state.isReturnTrip = false; renderReturnBadge(); renderEstimate(); } } function showManualCode() { document.getElementById('manual-code-area').classList.remove('hidden'); } function addManualCode() { const val = document.getElementById('manual-code').value; if (val.trim()) { closeModal('modal-qr'); } } function renderRides(filter) { const filters = ['today','upcoming','cancelled','past']; filters.forEach(f => { const btn = document.getElementById('filter-' + f); if (!btn) return; if (f === filter) { btn.className = 'press px-3 py-1.5 rounded-full text-xs font-medium bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'; } else { btn.className = 'press px-3 py-1.5 rounded-full text-xs font-medium bg-[#151821] text-white/60 border border-white/10'; } }); const list = document.getElementById('rides-list'); const filtered = state.rides.filter(r => r.filter === filter); if (filtered.length === 0) { list.innerHTML = '

Aucune course dans cette catégorie.

'; return; } list.innerHTML = filtered.map(r => { const statusColor = r.status === 'Confirmée' ? 'bg-emerald-500/10 text-emerald-400' : r.status === 'En attente' ? 'bg-amber-500/10 text-amber-400' : r.status === 'Annulée' ? 'bg-red-500/10 text-red-400' : 'bg-blue-500/10 text-blue-400'; return `
${r.date} ${r.status}

${r.from} → ${r.to}

Chauffeur : ${r.driver}

${r.amount ? `

${r.amount}

` : ''}
`; }).join(''); } function openRideDetail(id) { const ride = state.rides.find(r => r.id === id); if (!ride) return; state.currentRide = ride; const content = document.getElementById('ride-detail-content'); const statusColor = ride.status === 'Confirmée' ? 'text-emerald-400' : ride.status === 'En attente' ? 'text-amber-400' : ride.status === 'Annulée' ? 'text-red-400' : 'text-blue-400'; let docButton = ''; if (ride.status === 'Annulée') { docButton = '

Aucun document disponible pour une course annulée.

'; } else if (ride.filter === 'today' || ride.filter === 'upcoming') { docButton = ``; } else if (ride.filter === 'past') { docButton = ``; } content.innerHTML = `
Date / Heure ${ride.date}
Trajet ${ride.from} → ${ride.to}
Chauffeur ${ride.driver}
Véhicule ${ride.vehicle}
Distance ${ride.distance}
${ride.rate ? `
Tarif/km${ride.rate} €/km
` : ''} ${ride.amount && ride.amount !== '-' ? `
Montant${ride.amount}
` : ''}
Statut ${ride.status}
Passagers ${ride.passengers}
Bagages ${ride.luggage}
${docButton}
`; openModal('modal-ride-detail'); } function openDocument(type) { const ride = state.currentRide; if (!ride) return; if (type === 'bdc') { document.getElementById('bdc-date').textContent = new Date().toLocaleDateString('fr-FR'); document.getElementById('bdc-datetime').textContent = ride.date; document.getElementById('bdc-trajet').textContent = ride.from + ' → ' + ride.to; document.getElementById('bdc-distance').textContent = 'Distance estimée : ' + (ride.distance || '12 km'); document.getElementById('bdc-rate').textContent = 'Tarif kilométrique : ' + (ride.rate ? ride.rate + ' €/km' : 'sur devis'); document.getElementById('bdc-price').textContent = 'Prix indicatif TTC : ' + (ride.amount || '24 €'); openModal('modal-bdc'); } else if (type === 'invoice') { document.getElementById('invoice-date').textContent = new Date().toLocaleDateString('fr-FR'); document.getElementById('invoice-prestation').textContent = ride.date; document.getElementById('invoice-time').textContent = ride.date.split('à')[1]?.trim() || '14:30'; openModal('modal-invoice'); } } function renderProfile() { const container = document.getElementById('relatives-list'); if (!container) return; container.innerHTML = state.relatives.map(r => `

${r.firstName} ${r.lastName}

${r.phone}

`).join(''); } function addRelative() { const first = document.getElementById('rel-firstname').value.trim(); const last = document.getElementById('rel-lastname').value.trim(); const phone = document.getElementById('rel-phone').value.trim(); if (!first || !last) return; state.relatives.push({ firstName: first, lastName: last, phone: phone || '—' }); document.getElementById('rel-firstname').value = ''; document.getElementById('rel-lastname').value = ''; document.getElementById('rel-phone').value = ''; renderProfile(); closeModal('modal-add-relative'); } function toggleFaq(btn) { const answer = btn.nextElementSibling; const icon = btn.querySelector('.faq-icon'); if (answer.classList.contains('hidden')) { answer.classList.remove('hidden'); icon.style.transform = 'rotate(180deg)'; } else { answer.classList.add('hidden'); icon.style.transform = 'rotate(0deg)'; } } function openSelectDriverSheet() { const container = document.getElementById('select-driver-list'); if (!container) return; if (state.drivers.length === 0) { container.innerHTML = '

Aucun chauffeur.

'; } else { container.innerHTML = state.drivers.map(d => { const statusColor = d.status === 'Disponible' ? 'text-emerald-400' : d.status === 'Occupé' ? 'text-amber-400' : 'text-white/40'; return `

${d.name}

${d.status}

${d.vehicle} • ${d.rate.toFixed(1).replace('.0','')} €/km

${d.phone ? `` : ''}
`; }).join(''); } openModal('modal-select-driver'); } function openAvailableDriversSheet() { const container = document.getElementById('available-drivers-list'); if (!container) return; const available = state.drivers.filter(d => d.available); if (available.length === 0) { container.innerHTML = '

Aucun chauffeur disponible.

'; } else { container.innerHTML = available.map(d => `

${d.name}

Disponible

${d.vehicle}

${d.phone ? `` : ''}
`).join(''); } openModal('modal-available-drivers'); } function renderFavoriteAddressPills() { const departContainer = document.getElementById('favorite-depart-pills'); const arriveeContainer = document.getElementById('favorite-arrivee-pills'); if (!departContainer || !arriveeContainer) return; const pills = (target) => state.favoriteAddresses.map(a => ` `).join(''); departContainer.innerHTML = pills('depart'); arriveeContainer.innerHTML = pills('arrivee'); lucide.createIcons(); } function setFavoriteAddress(target, id) { const addr = state.favoriteAddresses.find(a => a.id === id); if (!addr) return; if (target === 'depart') { const input = document.getElementById('input-depart'); if (input) input.value = addr.address; } else if (target === 'arrivee') { const input = document.getElementById('input-arrivee'); if (input) input.value = addr.address; } renderEstimate(); } function renderFavoriteAddressesProfile() { const container = document.getElementById('profile-favorite-addresses'); if (!container) return; if (state.favoriteAddresses.length === 0) { container.innerHTML = '

Aucune adresse favorite.

'; return; } container.innerHTML = state.favoriteAddresses.map(a => `

${a.label}

${a.address}

${a.tag}
`).join(''); lucide.createIcons(); } function addFavoriteAddress() { const label = document.getElementById('addr-label').value.trim(); const address = document.getElementById('addr-address').value.trim(); const tag = document.getElementById('addr-tag').value.trim() || label.toLowerCase(); const icon = document.getElementById('addr-icon')?.value || 'map-pin'; if (!label || !address) return; const id = 'addr_' + Date.now(); state.favoriteAddresses.push({ id, label, tag, icon, address }); document.getElementById('addr-label').value = ''; document.getElementById('addr-address').value = ''; document.getElementById('addr-tag').value = ''; if (document.getElementById('addr-icon')) document.getElementById('addr-icon').value = 'map-pin'; closeModal('modal-add-address'); renderFavoriteAddressesProfile(); renderFavoriteAddressPills(); } let editingAddressId = null; function openEditAddress(id) { const addr = state.favoriteAddresses.find(a => a.id === id); if (!addr) return; editingAddressId = id; document.getElementById('edit-addr-id').value = id; document.getElementById('edit-addr-label').value = addr.label; document.getElementById('edit-addr-address').value = addr.address; document.getElementById('edit-addr-tag').value = addr.tag; const iconSelect = document.getElementById('edit-addr-icon'); if (iconSelect) iconSelect.value = addr.icon || 'map-pin'; openModal('modal-edit-address'); } function saveEditedAddress() { if (!editingAddressId) return; const addr = state.favoriteAddresses.find(a => a.id === editingAddressId); if (!addr) return; addr.label = document.getElementById('edit-addr-label').value.trim(); addr.address = document.getElementById('edit-addr-address').value.trim(); addr.tag = document.getElementById('edit-addr-tag').value.trim(); const iconSelect = document.getElementById('edit-addr-icon'); if (iconSelect) addr.icon = iconSelect.value; editingAddressId = null; closeModal('modal-edit-address'); renderFavoriteAddressesProfile(); renderFavoriteAddressPills(); } function deleteFavoriteAddress(id) { if (!id && editingAddressId) id = editingAddressId; if (!id) return; state.favoriteAddresses = state.favoriteAddresses.filter(a => a.id !== id); editingAddressId = null; closeModal('modal-edit-address'); renderFavoriteAddressesProfile(); renderFavoriteAddressPills(); } function setCustomerType(type) { state.customerType = type; const partBtn = document.getElementById('seg-type-particulier'); const proBtn = document.getElementById('seg-type-professionnel'); const companyFields = document.getElementById('company-fields'); if (type === 'particulier') { partBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'; proBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all text-white/45 hover:text-white/70'; if (companyFields) companyFields.classList.add('hidden'); } else { proBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'; partBtn.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all text-white/45 hover:text-white/70'; if (companyFields) companyFields.classList.remove('hidden'); } } function saveProfile() { const first = document.getElementById('profile-firstname').value.trim(); const last = document.getElementById('profile-lastname').value.trim(); const phone = document.getElementById('profile-phone').value.trim(); const email = document.getElementById('profile-email').value.trim(); const address = document.getElementById('profile-address').value.trim(); if (!first || !last) return; state.profile = { firstName: first, lastName: last, phone, email, address }; state.billingAddress = address; const nameDisplay = document.getElementById('profile-name-display'); const contactDisplay = document.getElementById('profile-contact-display'); const typeDisplay = document.getElementById('profile-type-display'); if (nameDisplay) nameDisplay.textContent = first + ' ' + last; if (contactDisplay) contactDisplay.textContent = (phone ? phone + ' • ' : '') + (email || ''); if (typeDisplay) { if (state.customerType === 'professionnel' && state.company.name) { typeDisplay.textContent = 'Professionnel • ' + state.company.name; } else { typeDisplay.textContent = state.customerType === 'particulier' ? 'Particulier' : 'Professionnel'; } } if (state.customerType === 'professionnel') { state.company.name = document.getElementById('company-name').value.trim(); state.company.siret = document.getElementById('company-siret').value.trim(); state.company.vat = document.getElementById('company-vat').value.trim(); state.company.billingEmail = document.getElementById('company-billing-email').value.trim(); } closeModal('modal-edit-profile'); } window.addEventListener('DOMContentLoaded', () => { lucide.createIcons(); showView('home'); renderDrivers(); renderSelectedDriver(); renderRides('today'); renderProfile(); renderFavoriteAddressPills(); renderFavoriteAddressesProfile(); const today = new Date().toISOString().split('T')[0]; const dp = document.getElementById('date-picker'); if (dp) dp.value = today; const tp = document.getElementById('time-picker'); if (tp) tp.value = '14:30'; const depInput = document.getElementById('input-depart'); const arrInput = document.getElementById('input-arrivee'); if (depInput) depInput.addEventListener('input', renderEstimate); if (arrInput) arrInput.addEventListener('input', renderEstimate); });