292 lines
14 KiB
XML
292 lines
14 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<odoo>
|
||
<template id="dashboard_template" name="MyMach Fleet Dashboard">
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8"/>
|
||
<title>MyMach Otonom Telemetri & Güvenlik Kontrol Merkezi</title>
|
||
<!-- Premium Fonts & Icons -->
|
||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&display=swap" rel="stylesheet"/>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"/>
|
||
|
||
<!-- Leaflet.js Harita Kütüphanesi -->
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
|
||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||
|
||
<!-- Google Maps API (Kullanıcı parametre girdiyse yüklenir) -->
|
||
<script t-if="google_maps_api_key" t-att-src="'https://maps.googleapis.com/maps/api/js?key=' + google_maps_api_key"/>
|
||
|
||
<!-- Chart.js -->
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||
|
||
<style>
|
||
* {
|
||
box-sizing: border-box;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
body {
|
||
font-family: 'Outfit', sans-serif;
|
||
background: #0d0f12;
|
||
color: #e2e8f0;
|
||
overflow: hidden;
|
||
height: 100vh;
|
||
display: flex;
|
||
}
|
||
/* Sol Telemetri Paneli */
|
||
.sidebar {
|
||
width: 38%;
|
||
height: 100vh;
|
||
background: rgba(15, 22, 28, 0.9);
|
||
backdrop-filter: blur(20px);
|
||
border-right: 1px solid rgba(255, 255, 255, 0.05);
|
||
padding: 25px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20px;
|
||
overflow-y: auto;
|
||
z-index: 10;
|
||
box-shadow: 10px 0 30px rgba(0,0,0,0.5);
|
||
}
|
||
/* Sağ Canlı Harita */
|
||
.map-container {
|
||
width: 62%;
|
||
height: 100vh;
|
||
position: relative;
|
||
}
|
||
#map {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
/* Glassmorphism Kartları */
|
||
.card {
|
||
background: rgba(255, 255, 255, 0.03);
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
border-radius: 16px;
|
||
padding: 20px;
|
||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
|
||
backdrop-filter: blur(4px);
|
||
}
|
||
.header-title {
|
||
font-size: 24px;
|
||
font-weight: 800;
|
||
background: linear-gradient(45deg, #00f2fe, #4facfe);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
.subtitle {
|
||
font-size: 12px;
|
||
color: #94a3b8;
|
||
text-transform: uppercase;
|
||
letter-spacing: 2px;
|
||
margin-bottom: 10px;
|
||
}
|
||
/* Tablo Stilleri */
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin-top: 10px;
|
||
font-size: 13px;
|
||
}
|
||
th {
|
||
text-align: left;
|
||
color: #94a3b8;
|
||
padding: 10px;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
font-weight: 600;
|
||
}
|
||
td {
|
||
padding: 12px 10px;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.03);
|
||
}
|
||
/* Durum Rozetleri */
|
||
.badge {
|
||
padding: 4px 8px;
|
||
border-radius: 20px;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
.badge-success { background: rgba(16, 185, 129, 0.15); color: #10b981; border: 1px solid rgba(16, 185, 129, 0.2); }
|
||
.badge-warning { background: rgba(245, 158, 11, 0.15); color: #f59e0b; border: 1px solid rgba(245, 158, 11, 0.2); }
|
||
.badge-danger { background: rgba(239, 68, 68, 0.15); color: #ef4444; border: 1px solid rgba(239, 68, 68, 0.2); }
|
||
|
||
/* Yakıt Barı */
|
||
.progress-bar-container {
|
||
width: 100%;
|
||
height: 6px;
|
||
background: rgba(255,255,255,0.1);
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
margin-top: 5px;
|
||
}
|
||
.progress-bar {
|
||
height: 100%;
|
||
background: linear-gradient(90deg, #10b981, #34d399);
|
||
border-radius: 10px;
|
||
}
|
||
.progress-bar.low {
|
||
background: linear-gradient(90deg, #ef4444, #f87171);
|
||
}
|
||
/* Neon Efektli Pulse Animasyonu */
|
||
.pulse {
|
||
border-radius: 50%;
|
||
height: 12px;
|
||
width: 12px;
|
||
position: absolute;
|
||
left: -6px;
|
||
top: -6px;
|
||
animation: pulsate 1.5s ease-out infinite;
|
||
opacity: 0;
|
||
}
|
||
.pulse-red {
|
||
box-shadow: 0 0 12px 6px rgba(239, 68, 68, 0.8);
|
||
background: #ef4444;
|
||
}
|
||
.pulse-green {
|
||
box-shadow: 0 0 12px 6px rgba(16, 185, 129, 0.8);
|
||
background: #10b981;
|
||
}
|
||
@keyframes pulsate {
|
||
0% { transform: scale(0.1, 0.1); opacity: 0.0; }
|
||
50% { opacity: 1.0; }
|
||
100% { transform: scale(1.2, 1.2); opacity: 0.0; }
|
||
}
|
||
|
||
/* Yeni Sefere Başla Butonu */
|
||
.start-trip-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 15px;
|
||
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
||
color: white;
|
||
text-decoration: none;
|
||
padding: 15px 20px;
|
||
border-radius: 14px;
|
||
font-weight: 800;
|
||
font-size: 16px;
|
||
box-shadow: 0 10px 25px rgba(16, 185, 129, 0.4);
|
||
transition: all 0.3s ease;
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
text-align: left;
|
||
cursor: pointer;
|
||
}
|
||
.start-trip-btn:hover {
|
||
transform: translateY(-3px) scale(1.02);
|
||
box-shadow: 0 15px 30px rgba(16, 185, 129, 0.6);
|
||
color: white;
|
||
}
|
||
.start-trip-btn i {
|
||
font-size: 28px;
|
||
}
|
||
.start-trip-btn small {
|
||
display: block;
|
||
font-size: 11px;
|
||
font-weight: 400;
|
||
opacity: 0.85;
|
||
margin-top: 2px;
|
||
}
|
||
.metric-card {
|
||
flex: 1;
|
||
text-align: center;
|
||
padding: 15px 10px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- Sol Arayüz Paneli -->
|
||
<div class="sidebar">
|
||
<div class="card" style="display: flex; justify-content: space-between; align-items: center; padding: 15px 20px;">
|
||
<div>
|
||
<div class="header-title" style="font-size: 20px;">
|
||
<i class="fa-solid fa-satellite-dish fa-beat" style="color: #38bdf8;"></i> MYMACH FİLO AĞI
|
||
</div>
|
||
<p style="font-size: 11px; color: #94a3b8; margin-top: 5px;">
|
||
Otonom Telemetri & Güvenlik
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<!-- METRİKLER (HAREKETLİ, PARK, ÇEVRİMDIŞI) -->
|
||
<div class="metrics-row" style="display: flex; gap: 10px;">
|
||
<div class="card metric-card">
|
||
<div style="font-size: 24px; font-weight: 800; color: #10b981;" id="metric_moving">0</div>
|
||
<div style="font-size: 11px; color: #94a3b8; letter-spacing: 1px;">HAREKETLİ</div>
|
||
</div>
|
||
<div class="card metric-card">
|
||
<div style="font-size: 24px; font-weight: 800; color: #ef4444;" id="metric_parked">0</div>
|
||
<div style="font-size: 11px; color: #94a3b8; letter-spacing: 1px;">PARK HALİNDE</div>
|
||
</div>
|
||
<div class="card metric-card">
|
||
<div style="font-size: 24px; font-weight: 800; color: #6b7280;" id="metric_offline">0</div>
|
||
<div style="font-size: 11px; color: #94a3b8; letter-spacing: 1px;">ÇEVRİMDIŞI</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Canlı Sürücü ve Araç Listesi Tablosu -->
|
||
<div class="card" style="flex-grow: 1; display: flex; flex-direction: column;">
|
||
<div class="subtitle">Sürücü Seçimi & Rota Denetimi</div>
|
||
<div style="flex-grow: 1; overflow-y: auto;">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Sürücü / Araç</th>
|
||
<th>Hız</th>
|
||
<th>Durum</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="vehicleTableBody">
|
||
<!-- JS ile doldurulacak -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Sağ Canlı Harita Paneli -->
|
||
<div class="map-container">
|
||
<div id="map"></div>
|
||
<!-- Yüzen Personel Rota & Sapma Bilgi Kartı -->
|
||
<div id="driver_info_overlay" style="position: absolute; top: 20px; left: 20px; z-index: 1000; width: 340px; background: rgba(15, 23, 42, 0.9); backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.15); border-radius: 14px; padding: 18px; box-shadow: 0 10px 30px rgba(0,0,0,0.6); display: none;">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Verileri HTML Data Elementinde Depola (JS Kaçış Çakışmalarını Önler) -->
|
||
<div id="mymach_telemetry_data"
|
||
t-att-data-vehicles="vehicles_json"
|
||
t-att-data-logs="logs_json"
|
||
t-att-data-gmaps-key="google_maps_api_key"
|
||
style="display: none;"/>
|
||
|
||
<!-- Harita ve Tablo İşleme Kodları (Statik Dosyadan Yüklenir - QWeb Çakışmalarını Önler) -->
|
||
<script type="text/javascript" src="/mymach_fleet_intelligence/static/src/js/dashboard.js?v=6"></script>
|
||
</body>
|
||
</html>
|
||
</template>
|
||
|
||
<!-- OWL İstemci Aksiyonu (Client Action) -->
|
||
<record id="action_mymach_fleet_dashboard_client" model="ir.actions.client">
|
||
<field name="name">Canlı Harita</field>
|
||
<field name="tag">mymach_fleet_dashboard_client_action</field>
|
||
</record>
|
||
|
||
<!-- Ana Menü Altında Canlı Harita Menüsü -->
|
||
<menuitem id="menu_mymach_fleet_dashboard"
|
||
name="Canlı Harita"
|
||
parent="menu_mymach_fleet_intelligence_root"
|
||
action="action_mymach_fleet_dashboard_client"
|
||
sequence="4"
|
||
groups="mymach_fleet_intelligence.group_mymach_fleet_manager"/>
|
||
</odoo>
|