/** * ============================================ * RESERVATION.JS - Système de réservation * Smart Parking - BTS CIEL IR * ============================================ */ // Tarifs const PRICING = { 30: 2, // 30 min = 2€ 60: 3, // 1h = 3€ 120: 5, // 2h = 5€ 240: 8, // 4h = 8€ 480: 15 // 8h (journée) = 15€ }; // Horaires disponibles const TIME_SLOTS = [ '06:00', '06:30', '07:00', '07:30', '08:00', '08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00', '18:30', '19:00', '19:30', '20:00', '20:30', '21:00', '21:30', '22:00' ]; // État de la réservation en cours let currentReservation = null; // Initialisation document.addEventListener('DOMContentLoaded', () => { console.log('📅 Initialisation du système de réservation...'); initReservationForm(); initDatePicker(); initTimeSlots(); initPricePreview(); initPaymentModal(); }); /** * Initialise le formulaire de réservation */ function initReservationForm() { const form = document.getElementById('reservationForm'); if (!form) return; form.addEventListener('submit', handleReservationSubmit); } /** * Initialise le sélecteur de date */ function initDatePicker() { const dateInput = document.getElementById('resDate'); if (!dateInput) return; // Date minimum = aujourd'hui const today = new Date().toISOString().split('T')[0]; dateInput.min = today; dateInput.value = today; } /** * Initialise les créneaux horaires */ function initTimeSlots() { const select = document.getElementById('resStartTime'); if (!select) return; TIME_SLOTS.forEach(time => { const option = document.createElement('option'); option.value = time; option.textContent = time; select.appendChild(option); }); // Sélectionner l'heure actuelle + 1h const now = new Date(); const currentHour = now.getHours(); const currentMinutes = now.getMinutes(); const nextSlot = TIME_SLOTS.find(t => { const [h, m] = t.split(':').map(Number); return h > currentHour || (h === currentHour && m > currentMinutes); }); if (nextSlot) { select.value = nextSlot; } } /** * Initialise la prévisualisation du prix */ function initPricePreview() { const durationSelect = document.getElementById('resDuration'); if (!durationSelect) return; durationSelect.addEventListener('change', updatePricePreview); // Prix initial updatePricePreview(); } /** * Met à jour la prévisualisation du prix */ function updatePricePreview() { const duration = parseInt(document.getElementById('resDuration').value); const price = PRICING[duration] || 0; document.getElementById('previewPrice').textContent = price + '€'; } /** * Gère la soumission du formulaire */ function handleReservationSubmit(e) { e.preventDefault(); const user = JSON.parse(localStorage.getItem('smart_parking_user') || 'null'); if (!user) { Dashboard.showToast('Veuillez vous connecter', 'error'); return; } const spotId = parseInt(document.getElementById('resSpot').value); const date = document.getElementById('resDate').value; const startTime = document.getElementById('resStartTime').value; const duration = parseInt(document.getElementById('resDuration').value); const vehicle = document.getElementById('resVehicle').value; if (!spotId || !date || !startTime || !vehicle) { Dashboard.showToast('Veuillez remplir tous les champs', 'error'); return; } // Vérifier que la place est toujours libre const spots = JSON.parse(localStorage.getItem('smart_parking_spots') || '[]'); const spot = spots.find(s => s.id === spotId); if (!spot || spot.status !== 'free') { Dashboard.showToast('Cette place n\'est plus disponible', 'error'); // Rafraîchir la carte if (window.ParkingMap) { window.ParkingMap.refresh(); } return; } // Calculer l'heure de fin const [hours, minutes] = startTime.split(':').map(Number); const endDate = new Date(date + 'T' + startTime); endDate.setMinutes(endDate.getMinutes() + duration); const endTime = endDate.toTimeString().slice(0, 5); // Créer la réservation currentReservation = { id: Date.now(), userId: user.id, userName: user.name, spotId: spotId, spotNumber: spot.number, date: date, startTime: startTime, endTime: endTime, duration: duration, vehicle: vehicle.toUpperCase(), price: PRICING[duration], status: 'pending', createdAt: new Date().toISOString() }; // Afficher le modal de paiement showPaymentModal(); } /** * Initialise le modal de paiement */ function initPaymentModal() { // Fermer le modal document.getElementById('closePaymentModal')?.addEventListener('click', hidePaymentModal); document.getElementById('cancelPaymentBtn')?.addEventListener('click', hidePaymentModal); // Confirmer le paiement document.getElementById('confirmPaymentBtn')?.addEventListener('click', confirmPayment); } /** * Affiche le modal de paiement */ function showPaymentModal() { if (!currentReservation) return; const modal = document.getElementById('paymentModal'); // Remplir le récapitulatif document.getElementById('paySpot').textContent = 'Place ' + currentReservation.spotNumber; document.getElementById('payDate').textContent = formatDate(currentReservation.date); document.getElementById('payTime').textContent = currentReservation.startTime + ' - ' + currentReservation.endTime; document.getElementById('payDuration').textContent = formatDuration(currentReservation.duration); document.getElementById('payTotal').textContent = currentReservation.price + '€'; // Générer le QR code generateQRCode(); // Afficher le modal modal.classList.remove('hidden'); } /** * Cache le modal de paiement */ function hidePaymentModal() { document.getElementById('paymentModal').classList.add('hidden'); } /** * Génère le QR code */ function generateQRCode() { const container = document.getElementById('qrcode'); container.innerHTML = ''; // Générer un code de paiement unique const paymentCode = 'PARK' + Date.now().toString().slice(-8); document.getElementById('paymentCode').textContent = paymentCode; // Créer le QR code const qrData = JSON.stringify({ type: 'parking_payment', reservationId: currentReservation.id, amount: currentReservation.price, code: paymentCode }); // Utiliser QRCode.js si disponible, sinon afficher un faux QR if (typeof QRCode !== 'undefined') { new QRCode(container, { text: qrData, width: 200, height: 200, colorDark: '#000000', colorLight: '#ffffff', correctLevel: QRCode.CorrectLevel.M }); } else { // Fallback - afficher un QR code simulé container.innerHTML = `