diff --git a/addons/mymach_fleet_intelligence/static/src/js/dashboard.js b/addons/mymach_fleet_intelligence/static/src/js/dashboard.js
index c0defd4..f4d6a6b 100644
--- a/addons/mymach_fleet_intelligence/static/src/js/dashboard.js
+++ b/addons/mymach_fleet_intelligence/static/src/js/dashboard.js
@@ -6,413 +6,387 @@ document.addEventListener("DOMContentLoaded", function() {
var logsData = JSON.parse(telemetryEl.getAttribute('data-logs') || '[]');
var googleMapsApiKey = telemetryEl.getAttribute('data-gmaps-key') || '';
- var map;
- var activePolylines = [];
- var activeMarkers = [];
+ // Arka planda sunucudan JSON rotasını çek
+ fetch('/mymach_fleet_intelligence/static/src/data/history.json?t=' + new Date().getTime())
+ .then(function(res) {
+ if (!res.ok) throw new Error('History not found');
+ return res.json();
+ })
+ .then(function(historyData) {
+ initDashboard(historyData);
+ })
+ .catch(function(e) {
+ // Dosya yoksa veya hata varsa boş rotayla başlat
+ initDashboard([]);
+ });
- var isGoogleLoaded = false;
- if (googleMapsApiKey) {
- if (typeof google !== 'undefined' && google.maps) {
- isGoogleLoaded = true;
- }
- }
+ function initDashboard(serverHistory) {
+ var map;
+ var activePolylines = [];
+ var activeMarkers = [];
- if (isGoogleLoaded) {
- map = new google.maps.Map(document.getElementById('map'), {
- center: {lat: 41.0766, lng: 29.0124},
- zoom: 12,
- mapTypeId: 'hybrid', // Google Uydu + Yol Haritası
- zoomControl: true,
- zoomControlOptions: { position: google.maps.ControlPosition.RIGHT_BOTTOM },
- mapTypeControl: false
- });
- } else {
- map = L.map('map', { zoomControl: false }).setView([41.0766, 29.0124], 12);
- L.control.zoom({ position: 'bottomright' }).addTo(map);
-
- // Yüksek Detaylı Esri World Imagery Uydu Haritası Katmanı
- L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
- attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
- maxZoom: 19
- }).addTo(map);
-
- // Şehir ve Yol Etiketleri Katmanı (Uydu üzerine)
- L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}{r}.png', {
- subdomains: 'abcd',
- maxZoom: 19
- }).addTo(map);
- }
-
- // Mavi Başlangıç İğnesi (Google Maps Stilinde)
- function createBlueStartIcon() {
- return L.divIcon({
- className: 'custom-blue-start-marker',
- html: '
',
- iconSize: [26, 26],
- iconAnchor: [13, 26]
- });
- }
-
- // Kırmızı Bitiş Hedef İğnesi (Google Maps Stilinde)
- function createRedEndIcon() {
- return L.divIcon({
- className: 'custom-red-end-marker',
- html: '',
- iconSize: [26, 26],
- iconAnchor: [13, 26]
- });
- }
-
- // Yol Üzeri Türkçe Çağrı Kutucuğu (Callout Badge)
- function createCalloutIcon(text, bgHex) {
- var bg = bgHex || '#2563eb';
- return L.divIcon({
- className: 'custom-callout-marker',
- html: '' + text + '
',
- iconSize: [130, 26],
- iconAnchor: [65, 13]
- });
- }
-
- var vehicleAnimationTimer = null;
-
- // Canlı Hareket Eden Araç İkonu (SVG 🚘 + Anlık Hız Göstergeli)
- function createLiveCarIcon(driverTag, speedText) {
- return L.divIcon({
- className: 'custom-live-car-marker',
- html: '' +
- '
' +
- '🚘 ' + (driverTag || 'Sürücü') + ' • ' + (speedText || '55 km/s') + '' +
- '
' +
- '
' +
- '🚗' +
- '
' +
- '
',
- iconSize: [140, 55],
- iconAnchor: [70, 52]
- });
- }
-
- function animateMovingVehicle(routePoints, vehicle) {
- if (vehicleAnimationTimer) {
- clearInterval(vehicleAnimationTimer);
- vehicleAnimationTimer = null;
- }
- if (!routePoints || routePoints.length === 0) return;
-
- // Canlı Takip Modu: Arabayı her zaman rotanın EN SON (en güncel) noktasına koy.
- var lastPoint = routePoints[routePoints.length - 1];
- var speedStr = vehicle.gps_speed ? vehicle.gps_speed + " km/s" : "0 km/s";
-
- var staticCar = L.marker(lastPoint, {
- icon: createLiveCarIcon(vehicle.driver_tag, speedStr)
- }).addTo(map);
- activeMarkers.push(staticCar);
-
- // Haritayı doğrudan bu son noktaya odakla (Zoom)
- map.setView(lastPoint, 16);
- }
-
- function selectDriver(vehicle) {
- if (vehicleAnimationTimer) {
- clearInterval(vehicleAnimationTimer);
- vehicleAnimationTimer = null;
+ var isGoogleLoaded = false;
+ if (googleMapsApiKey) {
+ if (typeof google !== 'undefined' && google.maps) {
+ isGoogleLoaded = true;
+ }
}
if (isGoogleLoaded) {
- activePolylines.forEach(function(p) { p.setMap(null); });
- activeMarkers.forEach(function(m) { m.setMap(null); });
+ map = new google.maps.Map(document.getElementById('map'), {
+ center: {lat: 41.0766, lng: 29.0124},
+ zoom: 12,
+ mapTypeId: 'hybrid', // Google Uydu + Yol Haritası
+ zoomControl: true,
+ zoomControlOptions: { position: google.maps.ControlPosition.RIGHT_BOTTOM },
+ mapTypeControl: false
+ });
} else {
- activePolylines.forEach(function(p) { map.removeLayer(p); });
- activeMarkers.forEach(function(m) { map.removeLayer(m); });
+ map = L.map('map', { zoomControl: false }).setView([41.0766, 29.0124], 12);
+ L.control.zoom({ position: 'bottomright' }).addTo(map);
+
+ // Yüksek Detaylı Esri World Imagery Uydu Haritası Katmanı
+ L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
+ attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
+ maxZoom: 19
+ }).addTo(map);
+
+ // Şehir ve Yol Etiketleri Katmanı (Uydu üzerine)
+ L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}{r}.png', {
+ subdomains: 'abcd',
+ maxZoom: 19
+ }).addTo(map);
}
- activePolylines = [];
- activeMarkers = [];
- var greenPts = vehicle.green_route || [];
- var redPts = vehicle.red_route || [];
- var alt1Pts = vehicle.alt1 || [];
- var alt2Pts = vehicle.alt2 || [];
-
- if (isGoogleLoaded) {
- if (greenPts.length > 0) {
- var polyGreen = new google.maps.Polyline({
- path: greenPts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
- strokeColor: '#10b981',
- strokeOpacity: 0.95,
- strokeWeight: 7,
- map: map
- });
- activePolylines.push(polyGreen);
- }
- if (redPts.length > 0) {
- var polyRed = new google.maps.Polyline({
- path: redPts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
- strokeColor: '#ef4444',
- strokeOpacity: 0.95,
- strokeWeight: 7,
- map: map
- });
- activePolylines.push(polyRed);
- }
- var polyAlt1 = new google.maps.Polyline({
- path: alt1Pts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
- strokeColor: '#64748b',
- strokeOpacity: 0.55,
- strokeWeight: 4,
- map: map
+ // Yol Üzeri Türkçe Çağrı Kutucuğu (Callout Badge)
+ function createCalloutIcon(text, bgHex) {
+ var bg = bgHex || '#2563eb';
+ return L.divIcon({
+ className: 'custom-callout-marker',
+ html: '' + text + '
',
+ iconSize: [130, 26],
+ iconAnchor: [65, 13]
});
- var polyAlt2 = new google.maps.Polyline({
- path: alt2Pts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
- strokeColor: '#64748b',
- strokeOpacity: 0.55,
- strokeWeight: 4,
- map: map
+ }
+
+ var vehicleAnimationTimer = null;
+
+ // Canlı Hareket Eden Araç İkonu (SVG 🚘 + Anlık Hız Göstergeli)
+ function createLiveCarIcon(driverTag, speedText) {
+ return L.divIcon({
+ className: 'custom-live-car-marker',
+ html: '' +
+ '
' +
+ '🚘 ' + (driverTag || 'Sürücü') + ' • ' + (speedText || '55 km/s') + '' +
+ '
' +
+ '
' +
+ '🚗' +
+ '
' +
+ '
',
+ iconSize: [140, 55],
+ iconAnchor: [70, 52]
});
- activePolylines.push(polyAlt1, polyAlt2);
+ }
- var allPts = greenPts.concat(redPts).concat(alt1Pts).concat(alt2Pts);
- if (allPts.length > 0) {
- var startPt = greenPts[0] || allPts[0];
- var endPt = redPts.length > 0 ? redPts[redPts.length - 1] : (greenPts[greenPts.length - 1] || allPts[allPts.length - 1]);
- var mStart = new google.maps.Marker({ position: {lat: startPt[0], lng: startPt[1]}, map: map, title: "Başlangıç Noktası" });
- var mEnd = new google.maps.Marker({ position: {lat: endPt[0], lng: endPt[1]}, map: map, title: vehicle.destination });
- activeMarkers.push(mStart, mEnd);
-
- var bounds = new google.maps.LatLngBounds();
- allPts.forEach(function(p) { bounds.extend({lat: p[0], lng: p[1]}); });
- map.fitBounds(bounds);
+ function animateMovingVehicle(routePoints, vehicle) {
+ if (vehicleAnimationTimer) {
+ clearInterval(vehicleAnimationTimer);
+ vehicleAnimationTimer = null;
}
+ if (!routePoints || routePoints.length === 0) return;
- } else {
- // Leaflet.js Görsel Çizimler (Uydu Temalı)
+ // Canlı Takip Modu: Arabayı her zaman rotanın EN SON (en güncel) noktasına koy.
+ var lastPoint = routePoints[routePoints.length - 1];
+ var speedStr = vehicle.gps_speed ? vehicle.gps_speed + " km/s" : "0 km/s";
- // 1. Alternatif Gri Yollar
- var polyAlt1 = L.polyline(alt1Pts, { color: '#64748b', weight: 4, opacity: 0.6, dashArray: '8, 6' }).addTo(map);
- var polyAlt2 = L.polyline(alt2Pts, { color: '#64748b', weight: 4, opacity: 0.6, dashArray: '8, 6' }).addTo(map);
- activePolylines.push(polyAlt1, polyAlt2);
+ var staticCar = L.marker(lastPoint, {
+ icon: createLiveCarIcon(vehicle.driver_tag, speedStr)
+ }).addTo(map);
+ activeMarkers.push(staticCar);
+
+ // Haritayı doğrudan bu son noktaya odakla (Zoom)
+ map.setView(lastPoint, 16);
+ }
- // 2. Yeşil Ana Rota Çizgisi
- if (greenPts.length > 0) {
- var polyGreen = L.polyline(greenPts, { color: '#10b981', weight: 8, opacity: 0.95, lineCap: 'round', lineJoin: 'round' }).addTo(map);
- activePolylines.push(polyGreen);
+ function selectDriver(vehicle) {
+ if (vehicleAnimationTimer) {
+ clearInterval(vehicleAnimationTimer);
+ vehicleAnimationTimer = null;
}
- // 3. Kırmızı 1 km+ Sapma Çizgisi
- if (redPts.length > 0) {
- var polyRed = L.polyline(redPts, { color: '#ef4444', weight: 8, opacity: 0.95, lineCap: 'round', lineJoin: 'round' }).addTo(map);
- activePolylines.push(polyRed);
+ if (isGoogleLoaded) {
+ activePolylines.forEach(function(p) { p.setMap(null); });
+ activeMarkers.forEach(function(m) { m.setMap(null); });
+ } else {
+ activePolylines.forEach(function(p) { map.removeLayer(p); });
+ activeMarkers.forEach(function(m) { map.removeLayer(m); });
}
+ activePolylines = [];
+ activeMarkers = [];
- var allPts = greenPts.concat(redPts);
- // Başlangıç ve Bitiş İğnelerini (Mavi/Kırmızı) Canlı Radarda Gizliyoruz (Sadece araba ve çizgi görünecek)
- // Kırmızı Yol Üzerindeki "1.5 km Sapma" Çağrı Kutucuğu
+ var greenPts = vehicle.green_route || [];
+ var redPts = vehicle.red_route || [];
+ var alt1Pts = vehicle.alt1 || [];
+ var alt2Pts = vehicle.alt2 || [];
+
+ if (isGoogleLoaded) {
+ if (greenPts.length > 0) {
+ var polyGreen = new google.maps.Polyline({
+ path: greenPts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
+ strokeColor: '#10b981',
+ strokeOpacity: 0.95,
+ strokeWeight: 7,
+ map: map
+ });
+ activePolylines.push(polyGreen);
+ }
if (redPts.length > 0) {
- var midRedIdx = Math.floor(redPts.length / 2);
- var mRedCallout = L.marker(redPts[midRedIdx], { icon: createCalloutIcon(vehicle.deviation_label, '#ef4444') }).addTo(map);
- activeMarkers.push(mRedCallout);
+ var polyRed = new google.maps.Polyline({
+ path: redPts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
+ strokeColor: '#ef4444',
+ strokeOpacity: 0.95,
+ strokeWeight: 7,
+ map: map
+ });
+ activePolylines.push(polyRed);
+ }
+ var polyAlt1 = new google.maps.Polyline({
+ path: alt1Pts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
+ strokeColor: '#64748b',
+ strokeOpacity: 0.55,
+ strokeWeight: 4,
+ map: map
+ });
+ var polyAlt2 = new google.maps.Polyline({
+ path: alt2Pts.map(function(p) { return {lat: p[0], lng: p[1]}; }),
+ strokeColor: '#64748b',
+ strokeOpacity: 0.55,
+ strokeWeight: 4,
+ map: map
+ });
+ activePolylines.push(polyAlt1, polyAlt2);
+
+ var allPts = greenPts.concat(redPts).concat(alt1Pts).concat(alt2Pts);
+ if (allPts.length > 0) {
+ var startPt = greenPts[0] || allPts[0];
+ var endPt = redPts.length > 0 ? redPts[redPts.length - 1] : (greenPts[greenPts.length - 1] || allPts[allPts.length - 1]);
+
+ var bounds = new google.maps.LatLngBounds();
+ allPts.forEach(function(p) { bounds.extend({lat: p[0], lng: p[1]}); });
+ map.fitBounds(bounds);
}
- // Rotada Gerçek Zamanlı Canlı Hareket Eden Araç Animasyonunu Başlat
- animateMovingVehicle(allPts, vehicle);
+ } else {
+ // Leaflet.js Görsel Çizimler (Uydu Temalı)
+
+ // 1. Alternatif Gri Yollar
+ var polyAlt1 = L.polyline(alt1Pts, { color: '#64748b', weight: 4, opacity: 0.6, dashArray: '8, 6' }).addTo(map);
+ var polyAlt2 = L.polyline(alt2Pts, { color: '#64748b', weight: 4, opacity: 0.6, dashArray: '8, 6' }).addTo(map);
+ activePolylines.push(polyAlt1, polyAlt2);
- var group = new L.featureGroup([polyAlt1, polyAlt2].concat(activePolylines));
- map.fitBounds(group.getBounds(), { padding: [50, 50] });
+ // 2. Yeşil Ana Rota Çizgisi
+ if (greenPts.length > 0) {
+ var polyGreen = L.polyline(greenPts, { color: '#10b981', weight: 8, opacity: 0.95, lineCap: 'round', lineJoin: 'round' }).addTo(map);
+ activePolylines.push(polyGreen);
+ }
+
+ // 3. Kırmızı 1 km+ Sapma Çizgisi
+ if (redPts.length > 0) {
+ var polyRed = L.polyline(redPts, { color: '#ef4444', weight: 8, opacity: 0.95, lineCap: 'round', lineJoin: 'round' }).addTo(map);
+ activePolylines.push(polyRed);
+ }
+
+ var allPts = greenPts.concat(redPts);
+ if (allPts.length > 0) {
+ var startPt = greenPts[0] || allPts[0];
+ var endPt = redPts.length > 0 ? redPts[redPts.length - 1] : (greenPts[greenPts.length - 1] || allPts[allPts.length - 1]);
+
+ // Başlangıç ve Bitiş İğnelerini (Mavi/Kırmızı) Canlı Radarda Gizliyoruz (Sadece araba ve çizgi görünecek)
+ // Kırmızı Yol Üzerindeki "1.5 km Sapma" Çağrı Kutucuğu
+ if (redPts.length > 0) {
+ var midRedIdx = Math.floor(redPts.length / 2);
+ var mRedCallout = L.marker(redPts[midRedIdx], { icon: createCalloutIcon(vehicle.deviation_label, '#ef4444') }).addTo(map);
+ activeMarkers.push(mRedCallout);
+ }
+
+ // Rotada Gerçek Zamanlı Canlı Hareket Eden Araç Animasyonunu Başlat
+ animateMovingVehicle(allPts, vehicle);
+
+ var group = new L.featureGroup([polyAlt1, polyAlt2].concat(activePolylines));
+ map.fitBounds(group.getBounds(), { padding: [50, 50] });
+ }
+ }
+
+ // Yüzen Detay Kartını Güncelle
+ var overlayEl = document.getElementById('driver_info_overlay');
+ if (overlayEl) {
+ var badgeBg = vehicle.is_violation ? 'rgba(239, 68, 68, 0.25)' : (vehicle.is_manager_approved ? 'rgba(56, 189, 248, 0.25)' : 'rgba(16, 185, 129, 0.25)');
+ var badgeBorder = vehicle.is_violation ? '#ef4444' : (vehicle.is_manager_approved ? '#38bdf8' : '#10b981');
+ var badgeText = vehicle.is_violation ? '#ef4444' : (vehicle.is_manager_approved ? '#38bdf8' : '#10b981');
+ var badgeTitle = vehicle.is_violation
+ ? vehicle.badge_violation
+ : (vehicle.is_manager_approved ? vehicle.badge_approved : vehicle.badge_ok);
+
+ overlayEl.style.display = 'block';
+ overlayEl.innerHTML =
+ '' +
+ '
' +
+ '
' + (vehicle.driver_tag_str || '') + ' - ' + vehicle.driver_name + '
' +
+ '' + vehicle.license_plate + ' (' + vehicle.name + ')' +
+ '' +
+ '
' +
+ vehicle.label_score + ' ' + vehicle.score +
+ '' +
+ '
' +
+ '' +
+ badgeTitle +
+ '
' +
+ '' +
+ '
' +
+ 'Personel Evi / Konaklama:' +
+ '' + (vehicle.driver_home_address || 'Bilinmiyor') + '' +
+ '
' +
+ '
' +
+ 'Başlangıç Noktası:' +
+ '' + (vehicle.start_location || 'Canlı GPS Konumu') + '' +
+ '
' +
+ '
' +
+ 'Ulaşım Hedefi:' +
+ '' + (vehicle.destination || 'Gerçek Zamanlı Aktif İzleme') + '' +
+ '
' +
+ '
' +
+ 'Planlanan / Gidilen Mesafe:' +
+ '' + vehicle.planned_km + ' KM / ' + vehicle.driven_km + ' KM' +
+ '
' +
+ '
' +
+ 'Rota Sapma Durumu:' +
+ '' + vehicle.deviation_label + '' +
+ '
' +
+ '
' +
+ 'Şirket Politikası:' +
+ '' + vehicle.policy_desc + '' +
+ '
' +
+ '
';
}
}
- // Yüzen Detay Kartını Güncelle
- var overlayEl = document.getElementById('driver_info_overlay');
- if (overlayEl) {
- var badgeBg = vehicle.is_violation ? 'rgba(239, 68, 68, 0.25)' : (vehicle.is_manager_approved ? 'rgba(56, 189, 248, 0.25)' : 'rgba(16, 185, 129, 0.25)');
- var badgeBorder = vehicle.is_violation ? '#ef4444' : (vehicle.is_manager_approved ? '#38bdf8' : '#10b981');
- var badgeText = vehicle.is_violation ? '#ef4444' : (vehicle.is_manager_approved ? '#38bdf8' : '#10b981');
- var badgeTitle = vehicle.is_violation
- ? vehicle.badge_violation
- : (vehicle.is_manager_approved ? vehicle.badge_approved : vehicle.badge_ok);
+ var tableBody = document.getElementById('vehicleTableBody');
+ if (tableBody) {
+ tableBody.innerHTML = '';
+ var movingCount = 0;
+ var parkedCount = 0;
+ var offlineCount = 0;
- overlayEl.style.display = 'block';
- overlayEl.innerHTML =
- '' +
- '
' +
- '
' + (vehicle.driver_tag_str || '') + ' - ' + vehicle.driver_name + '
' +
- '' + vehicle.license_plate + ' (' + vehicle.name + ')' +
- '' +
- '
' +
- vehicle.label_score + ' ' + vehicle.score +
- '' +
- '
' +
- '' +
- badgeTitle +
- '
' +
- '' +
- '
' +
- 'Personel Evi / Konaklama:' +
- '' + (vehicle.driver_home_address || 'Bilinmiyor') + '' +
- '
' +
- '
' +
- 'Başlangıç Noktası:' +
- '' + (vehicle.start_location || 'Canlı GPS Konumu') + '' +
- '
' +
- '
' +
- 'Ulaşım Hedefi:' +
- '' + (vehicle.destination || 'Gerçek Zamanlı Aktif İzleme') + '' +
- '
' +
- '
' +
- 'Planlanan / Gidilen Mesafe:' +
- '' + vehicle.planned_km + ' KM / ' + vehicle.driven_km + ' KM' +
- '
' +
- '
' +
- 'Rota Sapma Durumu:' +
- '' + vehicle.deviation_label + '' +
- '
' +
- '
' +
- 'Şirket Politikası:' +
- '' + vehicle.policy_desc + '' +
- '
' +
- '
';
- }
- }
+ vehiclesData.forEach(function(v, idx) {
+ // Sunucudan (Odoo JSON dosyası) gelen rotayı ezici olarak kullan
+ if (serverHistory && serverHistory.length > 0) {
+ v.green_route = serverHistory;
+ }
- var tableBody = document.getElementById('vehicleTableBody');
- if (tableBody) {
- tableBody.innerHTML = '';
- var movingCount = 0;
- var parkedCount = 0;
- var offlineCount = 0;
+ // Basit bir kural: Hızı 0'dan büyük olanlar HAREKETLİ, 0 olanlar PARK, veri olmayanlar ÇEVRİMDIŞI.
+ var speedStr = "0 km/s";
+ if (v.gps_speed !== undefined) {
+ if (v.gps_speed > 0) {
+ movingCount++;
+ speedStr = v.gps_speed + " km/s";
+ } else {
+ parkedCount++;
+ speedStr = "0 km/s";
+ }
+ } else {
+ // Test verilerinde gps_speed olmayabilir, fake data üzerinden simüle et
+ var randomStatus = Math.random();
+ if (randomStatus > 0.4) { movingCount++; speedStr = Math.floor(Math.random() * 80 + 20) + " km/s"; }
+ else if (randomStatus > 0.1) { parkedCount++; speedStr = "0 km/s"; }
+ else { offlineCount++; speedStr = "Offline"; }
+ }
- vehiclesData.forEach(function(v, idx) {
- // === Tarayıcı Tabanlı Rota Çizgisi Geçmişi (Frontend History) ===
- var historyKey = 'mymach_route_' + v.id;
- var history = [];
- try {
- history = JSON.parse(localStorage.getItem(historyKey) || '[]');
- } catch(e) {}
+ var tr = document.createElement('tr');
+ tr.style.cursor = 'pointer';
+ tr.style.transition = 'all 0.2s ease';
+ tr.style.borderBottom = '1px solid rgba(255,255,255,0.05)';
+
+ var isRev = v.is_violation;
+ var badgeStyle = isRev
+ ? 'background: rgba(239, 68, 68, 0.2); color: #ef4444; border: 1px solid rgba(239, 68, 68, 0.4);'
+ : (v.is_manager_approved
+ ? 'background: rgba(56, 189, 248, 0.2); color: #38bdf8; border: 1px solid rgba(56, 189, 248, 0.4);'
+ : 'background: rgba(16, 185, 129, 0.2); color: #10b981; border: 1px solid rgba(16, 185, 129, 0.4);');
+ var statusLabel = isRev ? (v.badge_violation) : (v.is_manager_approved ? v.badge_approved : v.badge_ok);
+
+ tr.innerHTML =
+ '' +
+ '' + (v.driver_tag_str || '') + ' - ' + v.driver_name + ' ' +
+ '' + v.license_plate + '' +
+ ' | ' +
+ '' +
+ '' + speedStr + '' +
+ ' | ' +
+ '' +
+ '' +
+ statusLabel +
+ '' +
+ ' | ';
+
+ tr.addEventListener('click', function() {
+ var children = tableBody.children;
+ for (var i = 0; i < children.length; i++) {
+ children[i].style.background = 'transparent';
+ }
+ tr.style.background = 'rgba(56, 189, 248, 0.2)';
+ selectDriver(v);
+ });
+
+ tableBody.appendChild(tr);
+
+ if (idx === 0) {
+ tr.style.background = 'rgba(56, 189, 248, 0.2)';
+ setTimeout(function() { selectDriver(v); }, 300);
+ }
+ });
+
+ // Metrikleri DOM'a yaz
+ var mMoving = document.getElementById('metric_moving');
+ if (mMoving) mMoving.textContent = movingCount;
- if (v.green_route && v.green_route.length > 0) {
- var currentLat = v.green_route[0][0];
- var currentLon = v.green_route[0][1];
-
- var addPoint = true;
- if (history.length > 0) {
- var lastPt = history[history.length - 1];
- // Sadece BİREBİR aynı koordinatsa ekleme. (Hafif bir GPS oynamasını bile kaydetmek için)
- if (lastPt[0] === currentLat && lastPt[1] === currentLon) {
- addPoint = false;
+ var mParked = document.getElementById('metric_parked');
+ if (mParked) mParked.textContent = parkedCount;
+
+ var mOffline = document.getElementById('metric_offline');
+ if (mOffline) mOffline.textContent = offlineCount;
+ }
+
+ var miniChartEl = document.getElementById('miniChart');
+ if (miniChartEl) {
+ var ctx = miniChartEl.getContext('2d');
+ new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz'],
+ datasets: [{
+ label: 'KM Trend',
+ data: [2200, 2500, 2100, 2800, 3100, 2700],
+ borderColor: '#00f2fe',
+ backgroundColor: 'rgba(0, 242, 254, 0.05)',
+ borderWidth: 2,
+ tension: 0.4,
+ fill: true
+ }]
+ },
+ options: {
+ responsive: true,
+ plugins: { legend: { display: false } },
+ scales: {
+ x: { grid: { display: false }, ticks: { color: '#94a3b8' } },
+ y: { grid: { color: 'rgba(255,255,255,0.05)' }, ticks: { color: '#94a3b8' } }
}
}
- if (addPoint) {
- history.push([currentLat, currentLon]);
- if (history.length > 300) history = history.slice(-300); // 300 noktayı hafızada tut
- localStorage.setItem(historyKey, JSON.stringify(history));
- }
- v.green_route = history;
- }
-
- // Basit bir kural: Hızı 0'dan büyük olanlar HAREKETLİ, 0 olanlar PARK, veri olmayanlar ÇEVRİMDIŞI.
- var speedStr = "0 km/s";
- if (v.gps_speed !== undefined) {
- if (v.gps_speed > 0) {
- movingCount++;
- speedStr = v.gps_speed + " km/s";
- } else {
- parkedCount++;
- speedStr = "0 km/s";
- }
- } else {
- // Test verilerinde gps_speed olmayabilir, fake data üzerinden simüle et
- var randomStatus = Math.random();
- if (randomStatus > 0.4) { movingCount++; speedStr = Math.floor(Math.random() * 80 + 20) + " km/s"; }
- else if (randomStatus > 0.1) { parkedCount++; speedStr = "0 km/s"; }
- else { offlineCount++; speedStr = "Offline"; }
- }
-
- var tr = document.createElement('tr');
- tr.style.cursor = 'pointer';
- tr.style.transition = 'all 0.2s ease';
- tr.style.borderBottom = '1px solid rgba(255,255,255,0.05)';
-
- var isRev = v.is_violation;
- var badgeStyle = isRev
- ? 'background: rgba(239, 68, 68, 0.2); color: #ef4444; border: 1px solid rgba(239, 68, 68, 0.4);'
- : (v.is_manager_approved
- ? 'background: rgba(56, 189, 248, 0.2); color: #38bdf8; border: 1px solid rgba(56, 189, 248, 0.4);'
- : 'background: rgba(16, 185, 129, 0.2); color: #10b981; border: 1px solid rgba(16, 185, 129, 0.4);');
- var statusLabel = isRev ? (v.badge_violation) : (v.is_manager_approved ? v.badge_approved : v.badge_ok);
-
- tr.innerHTML =
- '' +
- '' + (v.driver_tag_str || '') + ' - ' + v.driver_name + ' ' +
- '' + v.license_plate + '' +
- ' | ' +
- '' +
- '' + speedStr + '' +
- ' | ' +
- '' +
- '' +
- statusLabel +
- '' +
- ' | ';
-
- tr.addEventListener('click', function() {
- var children = tableBody.children;
- for (var i = 0; i < children.length; i++) {
- children[i].style.background = 'transparent';
- }
- tr.style.background = 'rgba(56, 189, 248, 0.2)';
- selectDriver(v);
});
-
- tableBody.appendChild(tr);
-
- if (idx === 0) {
- tr.style.background = 'rgba(56, 189, 248, 0.2)';
- setTimeout(function() { selectDriver(v); }, 300);
- }
- });
-
- // Metrikleri DOM'a yaz
- var mMoving = document.getElementById('metric_moving');
- if (mMoving) mMoving.textContent = movingCount;
+ }
- var mParked = document.getElementById('metric_parked');
- if (mParked) mParked.textContent = parkedCount;
-
- var mOffline = document.getElementById('metric_offline');
- if (mOffline) mOffline.textContent = offlineCount;
- }
-
- var miniChartEl = document.getElementById('miniChart');
- if (miniChartEl) {
- var ctx = miniChartEl.getContext('2d');
- new Chart(ctx, {
- type: 'line',
- data: {
- labels: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz'],
- datasets: [{
- label: 'KM Trend',
- data: [2200, 2500, 2100, 2800, 3100, 2700],
- borderColor: '#00f2fe',
- backgroundColor: 'rgba(0, 242, 254, 0.05)',
- borderWidth: 2,
- tension: 0.4,
- fill: true
- }]
- },
- options: {
- responsive: true,
- plugins: { legend: { display: false } },
- scales: {
- x: { grid: { display: false }, ticks: { color: '#94a3b8' } },
- y: { grid: { color: 'rgba(255,255,255,0.05)' }, ticks: { color: '#94a3b8' } }
- }
- }
- });
+ // --- 10 Saniyede Bir Sayfayı Tam Ekran Yenileyerek Görüntüyü Güncelleyen Kod ---
+ setInterval(function() {
+ window.location.reload();
+ }, 15000);
}
});