window.onerror = function(msg, url, line) {
console.error('ERREUR JS :', msg, line);
};
const state = {
isReturnTrip: false,
mode: 'course',
disposalDuration: 120,
customWelcome: 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.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}
`;
}
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 setMode(mode) {
state.mode = mode;
const segCourse = document.getElementById('seg-mode-course');
const segDisposal = document.getElementById('seg-mode-disposal');
const courseInputs = document.getElementById('course-inputs');
const disposalFields = document.getElementById('disposal-fields');
const btnDetails = document.getElementById('btn-details');
const btnSend = document.getElementById('btn-send');
if (mode === 'course') {
segCourse.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';
segDisposal.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all text-white/45 hover:text-white/70';
courseInputs?.classList.remove('hidden');
disposalFields?.classList.add('hidden');
if (btnDetails) btnDetails.classList.remove('hidden');
if (btnSend) btnSend.textContent = 'Envoyer la demande';
} else {
segDisposal.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';
segCourse.className = 'press flex-1 py-2 rounded-lg text-xs font-medium transition-all text-white/45 hover:text-white/70';
courseInputs?.classList.add('hidden');
disposalFields?.classList.remove('hidden');
if (btnDetails) btnDetails.classList.add('hidden');
if (btnSend) btnSend.textContent = 'Demander une mise à disposition';
renderDisposalPrice();
}
}
function renderDisposalPrice() {
const priceEl = document.getElementById('disposal-price');
if (!priceEl) return;
const hours = state.disposalDuration / 60;
const price = hours * 40;
priceEl.textContent = price.toFixed(0) + ' €';
}
function adjustDuration(delta) {
const newDuration = state.disposalDuration + delta;
if (newDuration < 120) return;
state.disposalDuration = newDuration;
const hours = Math.floor(state.disposalDuration / 60);
const mins = state.disposalDuration % 60;
const label = document.getElementById('disposal-duration');
if (label) label.textContent = hours + 'h' + (mins === 0 ? '00' : mins.toString().padStart(2, '0'));
renderDisposalPrice();
}
function toggleChip(btn) {
const isActive = btn.classList.contains('bg-emerald-500/10');
if (isActive) {
btn.classList.remove('bg-emerald-500/10', 'border-emerald-500/20', 'text-emerald-400');
btn.classList.add('border-white/10', 'text-white/55');
} else {
btn.classList.remove('border-white/10', 'text-white/55');
btn.classList.add('bg-emerald-500/10', 'border-emerald-500/20', 'text-emerald-400');
}
}
function toggleCustomWelcome() {
state.customWelcome = !state.customWelcome;
const btn = document.getElementById('btn-custom-welcome');
const fields = document.getElementById('custom-welcome-fields');
if (state.customWelcome) {
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 setNeed(btn, value) {
document.querySelectorAll('.need-chip').forEach(c => {
c.classList.remove('bg-emerald-500/10','border-emerald-500/20','text-emerald-400');
c.classList.add('border-white/10','text-white/55');
});
btn.classList.remove('border-white/10','text-white/55');
btn.classList.add('bg-emerald-500/10','border-emerald-500/20','text-emerald-400');
const otherField = document.getElementById('need-other-field');
if (value === 'other') {
otherField?.classList.remove('hidden');
} else {
otherField?.classList.add('hidden');
}
}
function sendRequest() {
if (state.mode === 'disposal') {
openModal('modal-loading');
const title = document.getElementById('loading-title');
const sub = document.getElementById('loading-sub');
title.textContent = 'Demande envoyée';
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 mise à disposition'; title.textContent = 'Prestation confirmée'; }, 3200);
setTimeout(() => { closeModal('modal-loading'); }, 4200);
return;
}
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 => `
`).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 dd = document.getElementById('disposal-date');
if (dd) dd.value = today;
const dt = document.getElementById('disposal-time');
if (dt) dt.value = '09:00';
const depInput = document.getElementById('input-depart');
const arrInput = document.getElementById('input-arrivee');
if (depInput) depInput.addEventListener('input', renderEstimate);
if (arrInput) arrInput.addEventListener('input', renderEstimate);
});