coolfrxcrazy commited on
Commit
a6846e9
1 Parent(s): 97b0716

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +400 -0
index.html ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vehicle Dashboard</title>
8
+ <script
9
+ src="https://maps.googleapis.com/maps/api/js?key=AIzaSyByFSdw5BlX97jCavPq1-mZySQfqAlFbDs&libraries=geometry"></script>
10
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
12
+ <style>
13
+ /* General styling */
14
+ body {
15
+ font-family: Arial, sans-serif;
16
+ margin: 0;
17
+ background-color: #f0f0f0;
18
+ }
19
+
20
+ /* Dashboard styling */
21
+ .dashboard {
22
+ background-color: #e0e0e0;
23
+ display: flex;
24
+ justify-content: space-between;
25
+ align-items: center;
26
+ padding: 20px;
27
+ margin-bottom: 10px;
28
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
29
+ }
30
+
31
+ /* Grid background */
32
+ body {
33
+ background-image: linear-gradient(#d3d3d3 1px, transparent 1px),
34
+ linear-gradient(90deg, #d3d3d3 1px, transparent 1px);
35
+ background-size: 40px 40px;
36
+ }
37
+
38
+ /* Icon and text styling */
39
+ .dashboard-item {
40
+ display: flex;
41
+ align-items: center;
42
+ }
43
+
44
+ .dashboard-item i {
45
+ font-size: 24px;
46
+ margin-right: 10px;
47
+ }
48
+
49
+ .dashboard-item .label {
50
+ font-size: 18px;
51
+ font-weight: bold;
52
+ }
53
+
54
+ .dashboard-item .cost {
55
+ font-size: 16px;
56
+ color: #666;
57
+ }
58
+
59
+ .timestamp {
60
+ font-size: 18px;
61
+ font-weight: bold;
62
+ color: #333;
63
+ }
64
+
65
+ /* Map container */
66
+ #map {
67
+ height: 500px;
68
+ width: 100%;
69
+ }
70
+
71
+ /* Form buttons */
72
+ #routeForm {
73
+ display: flex;
74
+ justify-content: center;
75
+ margin-top: 20px;
76
+ }
77
+
78
+ #routeForm button {
79
+ margin: 10px;
80
+ padding: 10px 20px;
81
+ font-size: 16px;
82
+ background-color: #4caf50;
83
+ color: white;
84
+ border: none;
85
+ cursor: pointer;
86
+ }
87
+
88
+ #routeForm button:hover {
89
+ background-color: #45a049;
90
+ }
91
+
92
+ /* Align buttons below the map */
93
+ #routeForm {
94
+ display: flex;
95
+ flex-direction: row;
96
+ justify-content: center;
97
+ margin-top: 20px;
98
+ }
99
+ </style>
100
+ </head>
101
+
102
+ <body>
103
+ <!-- Dashboard Section -->
104
+ <div class="dashboard">
105
+ <div class="dashboard-item">
106
+ <i class="fas fa-truck"></i>
107
+ <div>
108
+ <span class="label">Truck: </span>
109
+ <span class="cost" id="truckCost">{{ truck_cost }} SAR</span>
110
+ </div>
111
+ </div>
112
+ <div class="dashboard-item">
113
+ <i class="fas fa-car"></i>
114
+ <div>
115
+ <span class="label">Car: </span>
116
+ <span class="cost" id="carCost">{{ car_cost }} SAR</span>
117
+ </div>
118
+ </div>
119
+ <div class="dashboard-item">
120
+ <i class="fas fa-motorcycle"></i>
121
+ <div>
122
+ <span class="label">Motorbike: </span>
123
+ <span class="cost" id="motorbikeCost">{{ motorbike_cost }} SAR</span>
124
+ </div>
125
+ </div>
126
+ <div class="dashboard-item">
127
+ <i class="fas fa-tachometer-alt"></i>
128
+ <div>
129
+ <span class="label">Total Vehicles: </span>
130
+ <span class="cost" id="vehicleCounter">{{ total_vehicles }}</span>
131
+ </div>
132
+ </div>
133
+ <div class="dashboard-item">
134
+ <i class="fas fa-clock"></i>
135
+ <div class="timestamp" id="timestamp"></div>
136
+ </div>
137
+ </div>
138
+
139
+ <!-- Google Map Section -->
140
+ <div id="map" style="height: 500px; width: 100%"></div>
141
+
142
+ <!-- Form Section (Buttons below the map) -->
143
+ <form id="routeForm">
144
+ <input type="hidden" id="startLatLng" />
145
+ <input type="hidden" id="endLatLng" />
146
+ <button type="submit" disabled>Get Route</button>
147
+ <button type="button" id="resetBtn">Reset</button>
148
+ </form>
149
+
150
+ <!-- JavaScript for Real-time Timestamp -->
151
+ <script>
152
+ // Initialize variables
153
+ let map, routePath, startMarker, endMarker;
154
+ let startLatLng = null;
155
+ let endLatLng = null;
156
+ let avoidedRoutePaths = []; // Store the avoided route paths
157
+
158
+ // Update timestamp every second
159
+ function updateTime() {
160
+ const now = new Date();
161
+ const formattedTime = now.toLocaleString("en-US", {
162
+ year: "numeric",
163
+ month: "long",
164
+ day: "numeric",
165
+ hour: "2-digit",
166
+ minute: "2-digit",
167
+ second: "2-digit",
168
+ });
169
+ document.getElementById("timestamp").innerText = formattedTime;
170
+ }
171
+ setInterval(updateTime, 1000); // Update time every second
172
+
173
+ // Initialize the map
174
+ function initMap() {
175
+ map = new google.maps.Map(document.getElementById("map"), {
176
+ center: { lat: 24.7136, lng: 46.6753 }, // Riyadh coordinates
177
+ zoom: 12,
178
+ });
179
+
180
+ // Add click event listener to capture start and end locations
181
+ map.addListener("click", function (event) {
182
+ handleMapClick(event.latLng);
183
+ });
184
+
185
+ // Load and display avoided routes
186
+ loadAvoidedRoutes();
187
+ }
188
+
189
+ // Load avoided routes from the server and display them on the map
190
+ function loadAvoidedRoutes() {
191
+ $.ajax({
192
+ url: "/get-avoided-routes",
193
+ type: "GET",
194
+ success: function (response) {
195
+ if (response.status === "success") {
196
+ drawAvoidedRoutes(response.avoided_routes); // Draw avoided routes in red
197
+ } else {
198
+ alert("Failed to load avoided routes.");
199
+ }
200
+ },
201
+ error: function () {
202
+ alert("Failed to retrieve the avoided routes.");
203
+ },
204
+ });
205
+ }
206
+
207
+ // Draw the avoided routes in red
208
+ function drawAvoidedRoutes(avoidedRoutes) {
209
+ // Remove any existing avoided routes
210
+ avoidedRoutePaths.forEach((path) => path.setMap(null));
211
+ avoidedRoutePaths = [];
212
+
213
+ avoidedRoutes.forEach((route) => {
214
+ const decodedPolyline = google.maps.geometry.encoding.decodePath(
215
+ route.overview_polyline
216
+ );
217
+ const avoidedPath = new google.maps.Polyline({
218
+ path: decodedPolyline,
219
+ geodesic: true,
220
+ strokeColor: "#FF0000", // Red color for avoided routes
221
+ strokeOpacity: 0.7,
222
+ strokeWeight: 4,
223
+ });
224
+ avoidedPath.setMap(map);
225
+ avoidedRoutePaths.push(avoidedPath); // Store the avoided route
226
+ });
227
+ }
228
+
229
+ // Handle clicks on the map to select start and end points
230
+ function handleMapClick(latLng) {
231
+ if (!startLatLng) {
232
+ // Set the start marker
233
+ startLatLng = latLng;
234
+ placeMarker(latLng, "Start");
235
+ $("#startLatLng").val(latLng.lat() + "," + latLng.lng());
236
+
237
+ // Log the start point for debugging
238
+ console.log("Start LatLng set: ", $("#startLatLng").val());
239
+ } else if (!endLatLng) {
240
+ // Set the end marker
241
+ endLatLng = latLng;
242
+ placeMarker(latLng, "End");
243
+ $("#endLatLng").val(latLng.lat() + "," + latLng.lng());
244
+
245
+ // Log the end point for debugging
246
+ console.log("End LatLng set: ", $("#endLatLng").val());
247
+
248
+ // Enable the "Get Route" button after both points are selected
249
+ $("button[type=submit]").prop("disabled", false);
250
+ }
251
+ }
252
+
253
+ // Place marker for the selected location (start or end)
254
+ function placeMarker(latLng, label) {
255
+ let marker = new google.maps.Marker({
256
+ position: latLng,
257
+ map: map,
258
+ label: label,
259
+ draggable: false,
260
+ });
261
+
262
+ if (label === "Start") {
263
+ if (startMarker) startMarker.setMap(null); // Remove old marker
264
+ startMarker = marker;
265
+ } else if (label === "End") {
266
+ if (endMarker) endMarker.setMap(null); // Remove old marker
267
+ endMarker = marker;
268
+ }
269
+ }
270
+
271
+ // Form submission handler to and draw the route
272
+ $("#routeForm").on("submit", function (e) {
273
+ e.preventDefault();
274
+
275
+ const start = $("#startLatLng").val();
276
+ const end = $("#endLatLng").val();
277
+
278
+ // Debugging: Log the start and end values before sending
279
+ console.log("Submitting Start: ", start);
280
+ console.log("Submitting End: ", end);
281
+
282
+ if (!start || !end) {
283
+ alert("Start and End points are required.");
284
+ return;
285
+ }
286
+
287
+ $.ajax({
288
+ url: "/calculate-route",
289
+ type: "POST",
290
+ contentType: "application/json",
291
+ data: JSON.stringify({ start, end }),
292
+ success: function (response) {
293
+ if (response.status === "success") {
294
+ drawMainRoute(response.route.overview_polyline); // Draw the main route in blue
295
+ } else {
296
+ alert(response.message); // Show the error message
297
+ }
298
+ },
299
+ error: function (xhr, status, error) {
300
+ console.error("Error: ", error);
301
+ alert("Failed to retrieve the route. Please try again.");
302
+ },
303
+ });
304
+ });
305
+
306
+ // Draw the main route in blue
307
+ function drawMainRoute(polyline) {
308
+ const decodedPolyline =
309
+ google.maps.geometry.encoding.decodePath(polyline);
310
+ if (routePath) {
311
+ routePath.setMap(null); // Remove the old route
312
+ }
313
+
314
+ routePath = new google.maps.Polyline({
315
+ path: decodedPolyline,
316
+ geodesic: true,
317
+ strokeColor: "#0000FF", // Blue color for main route
318
+ strokeOpacity: 1.0,
319
+ strokeWeight: 4,
320
+ });
321
+
322
+ routePath.setMap(map);
323
+ map.fitBounds(getBounds(decodedPolyline)); // Adjust the map to fit the route
324
+ }
325
+
326
+ // Get the bounds for the polyline
327
+ function getBounds(decodedPolyline) {
328
+ const bounds = new google.maps.LatLngBounds();
329
+ decodedPolyline.forEach((point) => {
330
+ bounds.extend(point);
331
+ });
332
+ return bounds;
333
+ }
334
+
335
+ // Reset button handler: clear markers, route, and form
336
+ $("#resetBtn").on("click", function () {
337
+ // Remove markers and route from the map
338
+ if (startMarker) startMarker.setMap(null);
339
+ if (endMarker) endMarker.setMap(null);
340
+ if (routePath) routePath.setMap(null);
341
+
342
+ // Remove avoided routes
343
+ avoidedRoutePaths.forEach((path) => path.setMap(null));
344
+ avoidedRoutePaths = [];
345
+
346
+ // Clear stored start/end points
347
+ startLatLng = null;
348
+ endLatLng = null;
349
+
350
+ // Clear hidden input fields and disable "Get Route" button
351
+ $("#startLatLng").val("");
352
+ $("#endLatLng").val("");
353
+ $("button[type=submit]").prop("disabled", true);
354
+
355
+ // Reload avoided routes
356
+ loadAvoidedRoutes();
357
+ });
358
+
359
+ // Initialize the map
360
+ initMap();
361
+
362
+ // Update timestamp every second
363
+ function updateTime() {
364
+ const now = new Date();
365
+ const formattedTime = now.toLocaleString("en-US", {
366
+ year: "numeric",
367
+ month: "long",
368
+ day: "numeric",
369
+ hour: "2-digit",
370
+ minute: "2-digit",
371
+ second: "2-digit",
372
+ });
373
+ document.getElementById("timestamp").innerText = formattedTime;
374
+ }
375
+ setInterval(updateTime, 1000); // Update time every second
376
+
377
+ // Function to fetch updated vehicle information from the server
378
+ function fetchVehicleInfo() {
379
+ $.ajax({
380
+ url: "/get-vehicle-info",
381
+ type: "GET",
382
+ success: function (response) {
383
+ // Update the dashboard values with the latest info
384
+ $("#truckCost").text(response.truck_cost + " SAR");
385
+ $("#carCost").text(response.car_cost + " SAR");
386
+ $("#motorbikeCost").text(response.motorbike_cost + " SAR");
387
+ $("#vehicleCounter").text(response.total_vehicles);
388
+ },
389
+ error: function (xhr, status, error) {
390
+ console.error("Error fetching vehicle info:", error);
391
+ },
392
+ });
393
+ }
394
+
395
+ // Fetch the vehicle info every second
396
+ setInterval(fetchVehicleInfo, 1000); // Update the dashboard every second
397
+ </script>
398
+ </body>
399
+
400
+ </html>