// Pacifictrans Go - Interactive Web Platform Logic let currentTariffs = { tarifaPasajeroFija: 35000, precioBasePaquete: 25000, precioKmPaquete: 1200, factorPaquetes: { sobre: 1.0, mediano: 1.6, grande: 2.2 }, seguroBasePaquete: 5000, porcentajeComisionAdmin: 15, costoPenalidadCancelacion: 15000, radioMaxPoolingMetros: 4000 }; document.addEventListener('DOMContentLoaded', () => { initTabs(); initPassengerCalculator(); initFreightCalculator(); initRadarSimulation(); initTariffsManager(); fetchTariffs(); }); // TABS NAVIGATION function initTabs() { const tabBtns = document.querySelectorAll('.tab-btn'); const tabContents = document.querySelectorAll('.tab-content'); tabBtns.forEach(btn => { btn.addEventListener('click', () => { const targetId = btn.getAttribute('data-tab'); tabBtns.forEach(b => b.classList.remove('active')); tabContents.forEach(c => c.classList.remove('active')); btn.classList.add('active'); const targetEl = document.getElementById(targetId); if (targetEl) targetEl.classList.add('active'); }); }); } // CARGA DINÁMICA DE TARIFAS DESDE EL BACKEND / MONGODB async function fetchTariffs() { try { const res = await fetch('/api/tariffs'); if (res.ok) { const data = await res.json(); if (data.config) { currentTariffs = { ...currentTariffs, ...data.config }; syncTariffsToUI(); } } } catch (err) { console.warn('⚠️ [Tarifas API]: Modo local/offline activo, utilizando tarifas por defecto.', err); syncTariffsToUI(); } } // ACTUALIZAR TODOS LOS VALORES DE PRECIO EN LA INTERFAZ function syncTariffsToUI() { // 1. Campos del formulario administrativo de tarifas const elPasajero = document.getElementById('cfg-tarifa-pasajero'); const elBasePaquete = document.getElementById('cfg-base-paquete'); const elKmPaquete = document.getElementById('cfg-km-paquete'); const elSobre = document.getElementById('cfg-factor-sobre'); const elMediano = document.getElementById('cfg-factor-mediano'); const elGrande = document.getElementById('cfg-factor-grande'); const elSeguro = document.getElementById('cfg-seguro-base'); const elComision = document.getElementById('cfg-comision'); const elPenalidad = document.getElementById('cfg-penalidad'); const elRadio = document.getElementById('cfg-radio-pooling'); if (elPasajero) elPasajero.value = currentTariffs.tarifaPasajeroFija; if (elBasePaquete) elBasePaquete.value = currentTariffs.precioBasePaquete; if (elKmPaquete) elKmPaquete.value = currentTariffs.precioKmPaquete; if (elSobre && currentTariffs.factorPaquetes) elSobre.value = currentTariffs.factorPaquetes.sobre || 1.0; if (elMediano && currentTariffs.factorPaquetes) elMediano.value = currentTariffs.factorPaquetes.mediano || 1.6; if (elGrande && currentTariffs.factorPaquetes) elGrande.value = currentTariffs.factorPaquetes.grande || 2.2; if (elSeguro) elSeguro.value = currentTariffs.seguroBasePaquete; if (elComision) elComision.value = currentTariffs.porcentajeComisionAdmin; if (elPenalidad) elPenalidad.value = currentTariffs.costoPenalidadCancelacion; if (elRadio) elRadio.value = currentTariffs.radioMaxPoolingMetros; // 2. Precios en módulo de reservas de pasajeros const formattedPasajero = `$${currentTariffs.tarifaPasajeroFija.toLocaleString('es-CO')} COP`; const totalPriceEl = document.querySelector('.total-price'); if (totalPriceEl) totalPriceEl.textContent = formattedPasajero; const btnBook = document.getElementById('btn-book-pool'); if (btnBook && !btnBook.disabled) { btnBook.innerHTML = ` Confirmar y Pagar Cupo (${formattedPasajero}) `; } // 3. Recalcular módulo de mensajería y fletes if (window.recalculateFreight) { window.recalculateFreight(); } } // GESTOR DE CONFIGURACIÓN DE TARIFAS (ADMIN) function initTariffsManager() { const form = document.getElementById('form-tariffs-config'); const statusEl = document.getElementById('tariffs-save-status'); if (!form) return; form.addEventListener('submit', async (e) => { e.preventDefault(); const btn = document.getElementById('btn-save-tariffs'); if (btn) { btn.disabled = true; btn.innerHTML = '⏳ Guardando en MongoDB...'; } const payload = { tarifaPasajeroFija: parseFloat(document.getElementById('cfg-tarifa-pasajero')?.value || '35000'), precioBasePaquete: parseFloat(document.getElementById('cfg-base-paquete')?.value || '25000'), precioKmPaquete: parseFloat(document.getElementById('cfg-km-paquete')?.value || '1200'), factorPaquetes: { sobre: parseFloat(document.getElementById('cfg-factor-sobre')?.value || '1.0'), mediano: parseFloat(document.getElementById('cfg-factor-mediano')?.value || '1.6'), grande: parseFloat(document.getElementById('cfg-factor-grande')?.value || '2.2') }, seguroBasePaquete: parseFloat(document.getElementById('cfg-seguro-base')?.value || '5000'), porcentajeComisionAdmin: parseFloat(document.getElementById('cfg-comision')?.value || '15'), costoPenalidadCancelacion: parseFloat(document.getElementById('cfg-penalidad')?.value || '15000'), radioMaxPoolingMetros: parseFloat(document.getElementById('cfg-radio-pooling')?.value || '4000') }; try { const res = await fetch('/api/tariffs', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (res.ok) { const data = await res.json(); currentTariffs = { ...currentTariffs, ...data.config }; syncTariffsToUI(); if (statusEl) { statusEl.innerHTML = `✅ ¡Tarifas guardadas y sincronizadas en MongoDB! Pasajero: $${payload.tarifaPasajeroFija.toLocaleString('es-CO')} COP | Base Flete: $${payload.precioBasePaquete.toLocaleString('es-CO')} COP.`; statusEl.style.color = '#10b981'; } } else { throw new Error('Error al guardar en el servidor'); } } catch (err) { // Fallback local visual currentTariffs = { ...currentTariffs, ...payload }; syncTariffsToUI(); if (statusEl) { statusEl.innerHTML = `✅ Tarifas actualizadas en la plataforma: Pasajero: $${payload.tarifaPasajeroFija.toLocaleString('es-CO')} COP.`; statusEl.style.color = '#10b981'; } } finally { if (btn) { btn.disabled = false; btn.innerHTML = '💾 Guardar y Aplicar Nuevas Tarifas'; } } }); } // PASSENGER POOLING & BOOKING LOGIC function initPassengerCalculator() { const originSelect = document.getElementById('pool-origin'); const addressGroup = document.getElementById('cali-address-group'); const buenaStopGroup = document.getElementById('buena-stop-group'); const bookBtn = document.getElementById('btn-book-pool'); const poolDots = document.querySelectorAll('.seat-dot'); const poolBadge = document.getElementById('pool-status-badge'); let currentSeatsFilled = 3; // Starts at 3/4 for instant visual demonstration function updateOriginDestination() { if (!originSelect) return; const isCali = originSelect.value === 'CALI'; if (addressGroup) { addressGroup.style.display = isCali ? 'block' : 'none'; } if (buenaStopGroup) { buenaStopGroup.style.display = isCali ? 'block' : 'none'; } } if (originSelect) { originSelect.addEventListener('change', updateOriginDestination); updateOriginDestination(); } if (bookBtn) { bookBtn.addEventListener('click', async (e) => { e.preventDefault(); bookBtn.disabled = true; bookBtn.innerHTML = ` Procesando Agrupación Geoespacial... `; setTimeout(() => { currentSeatsFilled = 4; updateSeatVisuals(currentSeatsFilled); if (poolBadge) { poolBadge.innerHTML = `🚨 ¡CUPO COMPLETO (4/4)! Viaje en estado POOL_COMPLETED. Notificando a la Administración para asignar conductor óptimo según lugar de residencia en Cali.`; poolBadge.style.background = 'rgba(245, 158, 11, 0.15)'; poolBadge.style.borderColor = 'rgba(245, 158, 11, 0.4)'; poolBadge.style.color = '#fbbf24'; } const alertBox = document.getElementById('pool-dispatch-alert'); if (alertBox) { alertBox.style.display = 'block'; alertBox.scrollIntoView({ behavior: 'smooth' }); } bookBtn.disabled = false; const formatted = `$${currentTariffs.tarifaPasajeroFija.toLocaleString('es-CO')} COP`; bookBtn.innerHTML = `✅ Cupo Reservado Exitosamente (${formatted})`; }, 1200); }); } function updateSeatVisuals(count) { poolDots.forEach((dot, index) => { dot.classList.remove('active', 'pending'); if (index < count) { dot.classList.add('active'); } else if (index === count) { dot.classList.add('pending'); } }); const seatCounter = document.getElementById('seat-counter-text'); if (seatCounter) seatCounter.textContent = `${count}/4 Pasajeros`; } updateSeatVisuals(currentSeatsFilled); } // FREIGHT & PARCEL CALCULATOR CON TARIFAS CONFIGURABLES function initFreightCalculator() { const packageTypeSelect = document.getElementById('package-type'); const declaredValueInput = document.getElementById('declared-value'); const totalPriceEl = document.getElementById('freight-total-price'); const baseCostEl = document.getElementById('freight-base-cost'); const distCostEl = document.getElementById('freight-dist-cost'); const insuranceCostEl = document.getElementById('freight-insurance-cost'); const KM_DIST = 115; // Corredor Cali - Buenaventura window.recalculateFreight = function() { const rawFactor = parseFloat(packageTypeSelect?.value || '1.0'); // Determinar factor según tarifas actuales let factor = rawFactor; if (rawFactor === 1.0 && currentTariffs.factorPaquetes?.sobre) { factor = currentTariffs.factorPaquetes.sobre; } else if (rawFactor === 1.6 && currentTariffs.factorPaquetes?.mediano) { factor = currentTariffs.factorPaquetes.mediano; } else if (rawFactor === 2.2 && currentTariffs.factorPaquetes?.grande) { factor = currentTariffs.factorPaquetes.grande; } const declaredValue = parseFloat(declaredValueInput?.value || '0'); const basePrice = currentTariffs.precioBasePaquete || 25000; const costPerKm = currentTariffs.precioKmPaquete || 1200; const distancePart = KM_DIST * costPerKm; const subtotal = (basePrice + distancePart) * factor; const seguro = Math.round(declaredValue * 0.01) + (currentTariffs.seguroBasePaquete || 0); const total = Math.round(subtotal + seguro); if (baseCostEl) baseCostEl.textContent = `$${basePrice.toLocaleString('es-CO')} COP`; if (distCostEl) distCostEl.textContent = `$${Math.round(distancePart * factor).toLocaleString('es-CO')} COP`; if (insuranceCostEl) insuranceCostEl.textContent = `$${seguro.toLocaleString('es-CO')} COP`; if (totalPriceEl) totalPriceEl.textContent = `$${total.toLocaleString('es-CO')} COP`; }; if (packageTypeSelect) packageTypeSelect.addEventListener('change', window.recalculateFreight); if (declaredValueInput) declaredValueInput.addEventListener('input', window.recalculateFreight); window.recalculateFreight(); } // RADAR FLEET SIMULATION & LIVE DATA function initRadarSimulation() { const radarContainer = document.getElementById('radar-canvas-container'); if (!radarContainer) return; const activeDrivers = [ { id: '1', nombre: 'Carlos Mario G.', vehiculo: 'Renault Duster (WLZ-890)', barrio: 'Granada (Comuna 2)', distCali: '1.2 km', lat: 3.455, lng: -76.535, estado: 'DISPONIBLE' }, { id: '2', nombre: 'Hernán Darío P.', vehiculo: 'Toyota Fortuner (VBF-312)', barrio: 'San Antonio (Comuna 3)', distCali: '2.4 km', lat: 3.448, lng: -76.541, estado: 'ASIGNADO' }, { id: '3', nombre: 'Mauricio V.', vehiculo: 'Chevrolet Tracker (HJK-456)', barrio: 'El Ingenio (Comuna 17)', distCali: '6.8 km', lat: 3.385, lng: -76.529, estado: 'DISPONIBLE' }, { id: '4', nombre: 'Javier Restrepo', vehiculo: 'Nissan Kicks (RTY-789)', barrio: 'Limonar (Comuna 19)', distCali: '5.1 km', lat: 3.402, lng: -76.538, estado: 'EN_RUTA' } ]; const driverListEl = document.getElementById('suggested-drivers-list'); if (driverListEl) { driverListEl.innerHTML = activeDrivers.map((d, index) => `
#${index + 1} ${d.nombre}
${d.vehiculo}
🏠 Residencia en Cali: ${d.barrio}
Distancia al 1er Pasajero: ${d.distCali}
${d.estado}
`).join(''); } } // Ventana de asignación y disparo de notificación WhatsApp window.asignarConductorDemo = function(conductor, barrio) { const resultDiv = document.getElementById('schedule-dispatch-result'); if (resultDiv) { resultDiv.style.display = 'block'; resultDiv.innerHTML = `

✅ Conductor Asignado por Residencia: ${conductor} (${barrio})

🚀 Disparo Inmediato de Notificación WhatsApp Ejecutado: Los 4 pasajeros han recibido su confirmación oficial con el conductor asignado, vehículo, hora estimada escalonada de recogida y enlace de Waze / mapa en vivo.

📲 [Evolution API WhatsApp Status: 201 Created] Enviado a los 4 Pasajeros + Conductor.
`; resultDiv.scrollIntoView({ behavior: 'smooth' }); } };