almeira-web/transporte-cali-buenaventura/backend/public/js/app.js

196 lines
8.7 KiB
JavaScript

// Pacifictrans Go - Interactive Web Platform Logic
document.addEventListener('DOMContentLoaded', () => {
initTabs();
initPassengerCalculator();
initFreightCalculator();
initRadarSimulation();
});
// 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');
});
});
}
// 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 = `
<svg class="animate-spin" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10" stroke-opacity="0.25"></circle>
<path d="M12 2a10 10 0 0 1 10 10" stroke="currentColor"></path>
</svg> Procesando Agrupación Geoespacial...
`;
setTimeout(() => {
currentSeatsFilled = 4;
updateSeatVisuals(currentSeatsFilled);
if (poolBadge) {
poolBadge.innerHTML = `🚨 <strong>¡CUPO COMPLETO (4/4)!</strong> Viaje en estado <code>POOL_COMPLETED</code>. 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;
bookBtn.innerHTML = `✅ Cupo Reservado Exitosamente ($35.000 COP)`;
}, 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
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 BASE_PRICE = 25000;
const KM_DIST = 115; // Corredor Cali - Buenaventura
const COST_PER_KM = 1200;
function calculateFreight() {
const factor = parseFloat(packageTypeSelect?.value || '1.0');
const declaredValue = parseFloat(declaredValueInput?.value || '0');
const distancePart = KM_DIST * COST_PER_KM; // 138,000
const subtotal = (BASE_PRICE + distancePart) * factor;
const seguro = Math.round(declaredValue * 0.01);
const total = Math.round(subtotal + seguro);
if (baseCostEl) baseCostEl.textContent = `$${BASE_PRICE.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', calculateFreight);
if (declaredValueInput) declaredValueInput.addEventListener('input', calculateFreight);
calculateFreight();
}
// RADAR FLEET SIMULATION & LIVE DATA
function initRadarSimulation() {
const radarContainer = document.getElementById('radar-canvas-container');
if (!radarContainer) return;
// Conductores activos simulados con su residencia en Cali
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) => `
<div class="driver-card">
<div>
<strong style="color: #fff; font-size: 1.05rem;">#${index + 1} ${d.nombre}</strong>
<div style="font-size: 0.85rem; color: #94a3b8;">${d.vehiculo}</div>
<div style="font-size: 0.82rem; color: #06b6d4; margin-top: 3px;">
🏠 Residencia en Cali: <strong>${d.barrio}</strong>
</div>
<span class="driver-tag">Distancia al 1er Pasajero: ${d.distCali}</span>
</div>
<div style="text-align: right;">
<span style="display: inline-block; padding: 4px 10px; border-radius: 6px; font-size: 0.75rem; font-weight: 700; background: ${d.estado === 'DISPONIBLE' ? 'rgba(16, 185, 129, 0.2)' : 'rgba(245, 158, 11, 0.2)'}; color: ${d.estado === 'DISPONIBLE' ? '#10b981' : '#f59e0b'};">
${d.estado}
</span>
<button onclick="asignarConductorDemo('${d.nombre}', '${d.barrio}')" style="margin-top: 8px; display: block; background: #0f172a; border: 1px solid rgba(6, 182, 212, 0.4); color: #06b6d4; font-size: 0.8rem; padding: 5px 12px; border-radius: 6px; cursor: pointer;">
Asignar y Programar
</button>
</div>
</div>
`).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 = `
<div style="background: rgba(16, 185, 129, 0.15); border: 1px solid rgba(16, 185, 129, 0.4); border-radius: 12px; padding: 1.25rem; color: #10b981;">
<h4 style="margin-bottom: 0.5rem; font-size: 1.1rem; color: #fff;">✅ Conductor Asignado por Residencia: <strong>${conductor}</strong> (${barrio})</h4>
<p style="color: #cbd5e1; font-size: 0.92rem; margin-bottom: 0.75rem;">
🚀 <strong>Disparo Inmediato de Notificación WhatsApp Ejecutado:</strong>
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.
</p>
<div style="background: rgba(0,0,0,0.4); padding: 0.75rem; border-radius: 8px; font-family: monospace; font-size: 0.85rem; color: #6ee7b7;">
📲 [Evolution API WhatsApp Status: 201 Created] Enviado a los 4 Pasajeros + Conductor.
</div>
</div>
`;
resultDiv.scrollIntoView({ behavior: 'smooth' });
}
};