`).join('');
mapMarkers.clearLayers();
const statusColors = { "On Trip": "#22c55e", "Idle": "#3b82f6", "In Workshop": "#f97316" };
vehicles.forEach(v => {
const marker = L.circleMarker([v.lat, v.lon], { radius: 8, color: '#fff', weight: 2, fillColor: statusColors[v.status] || '#64748b', fillOpacity: 1.0 }).bindPopup(`${v.id}
${v.driver}`).on('click', () => showVehicleDetails(v.id)); mapMarkers.addLayer(marker); }); }; showVehicleDetails = (vehicleId) => { const vehicle = vehicles.find(v => v.id === vehicleId); const vTrips = tripLogs.filter(t => t.vehicleId === vehicleId); const totalDist = vTrips.reduce((s,t)=>s+t.dist, 0); const totalFuel = vTrips.reduce((s,t)=>s+t.fuel, 0); const fuelEff = totalFuel > 0 ? (totalDist/totalFuel).toFixed(1) : 'N/A'; document.getElementById('vehicle-detail-title').textContent = vehicle.id; document.getElementById('vehicle-detail-content').innerHTML = `
${d.name} ${d.score} `).join('');
const today = new Date('2025-06-30');
document.getElementById('fleet-maint-tbody').innerHTML = vehicles.sort((a,b) => new Date(a.nextMaint) - new Date(b.nextMaint)).map(v => {
const isOverdue = new Date(v.nextMaint) < today;
return `${v.id} ${new Date(v.nextMaint).toLocaleDateString()} ${isOverdue ? 'OVERDUE' : 'Upcoming'} `;
}).join('');
};
renderManagementUI = () => {
elements.vehicleTbody.innerHTML = vehicles.map(v => `${v.id} ${v.driver} `).join('');
elements.tripTbody.innerHTML = tripLogs.map(t => `${t.vehicleId} ${t.dist} km ${t.fuel} L `).join('');
document.getElementById('add-trip-vehicle').innerHTML = vehicles.map(v => ``).join('');
};
window.fleetDownloadPDF = (contentId) => {
html2canvas(document.getElementById(contentId), { scale: 2 }).then(canvas => {
const pdf = new jspdf.jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' });
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 40, 40, pdf.internal.pageSize.getWidth() - 80, 0);
pdf.save(`Fleet_${contentId.split('-')[0]}_Report.pdf`);
});
};
initialize();
});
${v.driver}`).on('click', () => showVehicleDetails(v.id)); mapMarkers.addLayer(marker); }); }; showVehicleDetails = (vehicleId) => { const vehicle = vehicles.find(v => v.id === vehicleId); const vTrips = tripLogs.filter(t => t.vehicleId === vehicleId); const totalDist = vTrips.reduce((s,t)=>s+t.dist, 0); const totalFuel = vTrips.reduce((s,t)=>s+t.fuel, 0); const fuelEff = totalFuel > 0 ? (totalDist/totalFuel).toFixed(1) : 'N/A'; document.getElementById('vehicle-detail-title').textContent = vehicle.id; document.getElementById('vehicle-detail-content').innerHTML = `
Driver: ${vehicle.driver}
Status: ${vehicle.status}
Next Maintenance: ${new Date(vehicle.nextMaint).toLocaleDateString()}
Trips Logged: ${vTrips.length}
Avg. Fuel Efficiency: ${fuelEff} km/L
`; }; renderPerformanceAnalytics = () => { const fuelData = vehicles.map(v => { const vTrips = tripLogs.filter(t => t.vehicleId === v.id); const totalDist = vTrips.reduce((s,t)=>s+t.dist, 0); const totalFuel = vTrips.reduce((s,t)=>s+t.fuel, 0); return totalFuel > 0 ? totalDist / totalFuel : 0; }); renderChart('fleet-fuel-chart', 'bar', { labels: vehicles.map(v => v.id), datasets: [{ label: 'km/L', data: fuelData, backgroundColor: 'rgba(8, 145, 178, 0.7)' }] }, { responsive: true, maintainAspectRatio: false, indexAxis: 'y' }); const driverScores = vehicles.map(v => ({ name: v.driver, score: (100 - (tripLogs.filter(t=>t.vehicleId===v.id).reduce((s,t)=>s+(t.braking || 0),0) * 5)).toFixed(0) })).sort((a,b) => b.score - a.score); document.getElementById('fleet-driver-tbody').innerHTML = driverScores.map(d => `