YESO commited on
Commit
206dab7
·
verified ·
1 Parent(s): 29f5411

Quiero que haya una sección que incluya la información de este sitio: https://www.medellin.gov.co/SIMM/mapas y muestres las cámaras de CCTV - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +194 -54
index.html CHANGED
@@ -47,10 +47,16 @@
47
  <div class="container mx-auto px-4 py-6">
48
  <div class="flex justify-between items-center">
49
  <div class="flex items-center space-x-4">
50
- <div class="bg-white rounded-full p-2">
51
  <i class="fas fa-satellite text-blue-600 text-2xl"></i>
 
 
 
 
 
 
 
52
  </div>
53
- <h1 class="text-2xl md:text-3xl font-bold">Medallio en línea</h1>
54
  </div>
55
  <nav class="hidden md:flex space-x-6">
56
  <a href="#" class="hover:text-blue-200 transition">Inicio</a>
@@ -151,6 +157,81 @@
151
  </div>
152
  </section>
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  <!-- Main Content -->
155
  <main class="flex-grow py-12">
156
  <div class="container mx-auto px-4">
@@ -170,25 +251,41 @@
170
  </button>
171
  </div>
172
  </div>
173
- <div class="map-container bg-gray-200 relative">
174
  <div class="absolute inset-0 flex items-center justify-center">
175
- <i class="fas fa-map-marked-alt text-gray-400 text-6xl"></i>
 
 
 
176
  </div>
177
- <div class="absolute top-4 right-4 bg-white p-2 rounded-lg shadow flex space-x-2">
178
- <button class="p-2 hover:bg-gray-100 rounded">
179
- <i class="fas fa-plus text-gray-700"></i>
 
 
 
180
  </button>
181
- <button class="p-2 hover:bg-gray-100 rounded">
182
- <i class="fas fa-minus text-gray-700"></i>
183
  </button>
184
- <button class="p-2 hover:bg-gray-100 rounded">
185
- <i class="fas fa-crosshairs text-gray-700"></i>
186
  </button>
187
  </div>
188
- <div class="absolute bottom-4 left-4 bg-white px-3 py-2 rounded-lg shadow">
189
  <div class="flex items-center space-x-2">
190
- <div class="w-3 h-3 bg-red-500 rounded-full pulse"></div>
191
- <span class="text-sm font-medium">Actualizando datos...</span>
 
 
 
 
 
 
 
 
 
 
192
  </div>
193
  </div>
194
  </div>
@@ -472,57 +569,100 @@
472
  </footer>
473
 
474
  <script>
475
- // Simulación de datos en tiempo real
476
- function updateStats() {
477
- const stats = [
478
- { element: document.querySelectorAll('.stats-container')[0], value: Math.floor(Math.random() * 5) + 22 },
479
- { element: document.querySelectorAll('.stats-container')[1], value: Math.floor(Math.random() * 10) + 85 },
480
- { element: document.querySelectorAll('.stats-container')[2], value: Math.floor(Math.random() * 50) + 1200 },
481
- { element: document.querySelectorAll('.stats-container')[3], value: Math.floor(Math.random() * 100) + 3500 }
482
- ];
483
-
484
- stats.forEach(stat => {
485
- stat.element.textContent = stat.value;
486
- });
487
-
488
- // Cambiar color de calidad del aire basado en valor
489
- const airQuality = Math.floor(Math.random() * 100);
490
- const airQualityElement = document.querySelector('.air-quality');
491
- const airQualityBar = document.querySelector('.air-quality-bar');
492
-
493
- if (airQuality < 40) {
494
- airQualityElement.textContent = "Buena";
495
- airQualityElement.className = "text-green-600 font-semibold";
496
- airQualityBar.className = "bg-green-500 h-2 rounded-full";
497
- airQualityBar.style.width = airQuality + "%";
498
- } else if (airQuality < 70) {
499
- airQualityElement.textContent = "Moderada";
500
- airQualityElement.className = "text-yellow-600 font-semibold";
501
- airQualityBar.className = "bg-yellow-500 h-2 rounded-full";
502
- airQualityBar.style.width = airQuality + "%";
503
- } else {
504
- airQualityElement.textContent = "Mala";
505
- airQualityElement.className = "text-red-600 font-semibold";
506
- airQualityBar.className = "bg-red-500 h-2 rounded-full";
507
- airQualityBar.style.width = airQuality + "%";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  }
509
 
510
- // Actualizar cada 30 segundos
511
- setTimeout(updateStats, 30000);
512
  }
513
 
514
- // Iniciar la simulación de datos
515
  document.addEventListener('DOMContentLoaded', function() {
516
- updateStats();
517
 
518
- // Animación para cards
 
 
 
 
 
 
 
519
  const cards = document.querySelectorAll('.card-hover');
520
  cards.forEach(card => {
521
- card.addEventListener('mouseenter', function() {
522
- this.style.transition = 'transform 0.3s ease, box-shadow 0.3s ease';
 
 
 
 
 
 
 
 
 
523
  });
524
  });
525
  });
526
  </script>
 
 
 
 
527
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=YESO/medall-n-interactivo" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
528
  </html>
 
47
  <div class="container mx-auto px-4 py-6">
48
  <div class="flex justify-between items-center">
49
  <div class="flex items-center space-x-4">
50
+ <div class="bg-white rounded-full p-2 relative">
51
  <i class="fas fa-satellite text-blue-600 text-2xl"></i>
52
+ <span class="absolute -top-1 -right-1 w-3 h-3 bg-green-500 rounded-full pulse"></span>
53
+ </div>
54
+ <div>
55
+ <h1 class="text-2xl md:text-3xl font-bold">Medallio en línea</h1>
56
+ <div class="flex items-center text-xs text-green-400">
57
+ <span class="mr-1">•</span> <span>Sistema operativo</span>
58
+ </div>
59
  </div>
 
60
  </div>
61
  <nav class="hidden md:flex space-x-6">
62
  <a href="#" class="hover:text-blue-200 transition">Inicio</a>
 
157
  </div>
158
  </section>
159
 
160
+ <!-- CCTV Section -->
161
+ <section class="bg-gray-50 py-12">
162
+ <div class="container mx-auto px-4">
163
+ <div class="text-center mb-12">
164
+ <h2 class="text-3xl font-bold text-gray-800 mb-4">Cámaras de Seguridad SIMM</h2>
165
+ <p class="text-xl text-gray-600 max-w-3xl mx-auto">Monitoreo en tiempo real de las cámaras de vigilancia del Sistema Integrado de Movilidad de Medellín</p>
166
+ </div>
167
+
168
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
169
+ <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition">
170
+ <div class="relative pb-[56.25%] bg-gray-200">
171
+ <div class="absolute inset-0 flex items-center justify-center">
172
+ <i class="fas fa-video text-gray-400 text-4xl"></i>
173
+ </div>
174
+ <div class="absolute bottom-2 left-2 bg-black bg-opacity-70 text-white px-2 py-1 rounded text-xs">
175
+ <i class="fas fa-circle text-red-500 mr-1"></i> En vivo
176
+ </div>
177
+ </div>
178
+ <div class="p-4">
179
+ <h3 class="font-bold mb-1">Cámara 1 - Centro</h3>
180
+ <p class="text-sm text-gray-600 mb-2">Carrera 50 con Calle 51</p>
181
+ <div class="flex justify-between text-xs text-gray-500">
182
+ <span><i class="fas fa-clock mr-1"></i> Actualizado hace 15s</span>
183
+ <span><i class="fas fa-eye mr-1"></i> 24° vista</span>
184
+ </div>
185
+ </div>
186
+ </div>
187
+
188
+ <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition">
189
+ <div class="relative pb-[56.25%] bg-gray-200">
190
+ <div class="absolute inset-0 flex items-center justify-center">
191
+ <i class="fas fa-video text-gray-400 text-4xl"></i>
192
+ </div>
193
+ <div class="absolute bottom-2 left-2 bg-black bg-opacity-70 text-white px-2 py-1 rounded text-xs">
194
+ <i class="fas fa-circle text-red-500 mr-1"></i> En vivo
195
+ </div>
196
+ </div>
197
+ <div class="p-4">
198
+ <h3 class="font-bold mb-1">Cámara 2 - Laureles</h3>
199
+ <p class="text-sm text-gray-600 mb-2">Calle 33 con Carrera 80</p>
200
+ <div class="flex justify-between text-xs text-gray-500">
201
+ <span><i class="fas fa-clock mr-1"></i> Actualizado hace 20s</span>
202
+ <span><i class="fas fa-eye mr-1"></i> 18° vista</span>
203
+ </div>
204
+ </div>
205
+ </div>
206
+
207
+ <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition">
208
+ <div class="relative pb-[56.25%] bg-gray-200">
209
+ <div class="absolute inset-0 flex items-center justify-center">
210
+ <i class="fas fa-video text-gray-400 text-4xl"></i>
211
+ </div>
212
+ <div class="absolute bottom-2 left-2 bg-black bg-opacity-70 text-white px-2 py-1 rounded text-xs">
213
+ <i class="fas fa-circle text-red-500 mr-1"></i> En vivo
214
+ </div>
215
+ </div>
216
+ <div class="p-4">
217
+ <h3 class="font-bold mb-1">Cámara 3 - Poblado</h3>
218
+ <p class="text-sm text-gray-600 mb-2">Avenida Poblado con Calle 10</p>
219
+ <div class="flex justify-between text-xs text-gray-500">
220
+ <span><i class="fas fa-clock mr-1"></i> Actualizado hace 25s</span>
221
+ <span><i class="fas fa-eye mr-1"></i> 32° vista</span>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <div class="text-center mt-8">
228
+ <button class="bg-blue-600 text-white px-6 py-3 rounded-lg font-semibold hover:bg-blue-700 transition">
229
+ <i class="fas fa-map-marked-alt mr-2"></i> Ver todas las cámaras en el mapa
230
+ </button>
231
+ </div>
232
+ </div>
233
+ </section>
234
+
235
  <!-- Main Content -->
236
  <main class="flex-grow py-12">
237
  <div class="container mx-auto px-4">
 
251
  </button>
252
  </div>
253
  </div>
254
+ <div class="map-container bg-gray-900 relative">
255
  <div class="absolute inset-0 flex items-center justify-center">
256
+ <div class="text-center">
257
+ <i class="fas fa-map-marked-alt text-blue-400 text-6xl mb-2"></i>
258
+ <p class="text-blue-300">Cargando mapa 3D de Medellín...</p>
259
+ </div>
260
  </div>
261
+ <div class="absolute top-4 right-4 bg-gray-800 bg-opacity-80 p-2 rounded-lg shadow-lg flex flex-col space-y-2">
262
+ <button class="p-2 hover:bg-gray-700 rounded text-blue-300">
263
+ <i class="fas fa-plus"></i>
264
+ </button>
265
+ <button class="p-2 hover:bg-gray-700 rounded text-blue-300">
266
+ <i class="fas fa-minus"></i>
267
  </button>
268
+ <button class="p-2 hover:bg-gray-700 rounded text-blue-300">
269
+ <i class="fas fa-crosshairs"></i>
270
  </button>
271
+ <button class="p-2 hover:bg-gray-700 rounded text-blue-300">
272
+ <i class="fas fa-3d"></i>
273
  </button>
274
  </div>
275
+ <div class="absolute bottom-4 left-4 bg-gray-800 bg-opacity-80 px-3 py-2 rounded-lg shadow-lg">
276
  <div class="flex items-center space-x-2">
277
+ <div class="w-3 h-3 bg-green-500 rounded-full pulse"></div>
278
+ <span class="text-sm font-medium text-white">Conectado • Última actualización: <span class="time-ago">hace 15 seg</span></span>
279
+ </div>
280
+ </div>
281
+ <div class="absolute top-4 left-4 bg-gray-800 bg-opacity-80 px-3 py-2 rounded-lg shadow-lg">
282
+ <div class="flex space-x-2">
283
+ <button class="px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
284
+ <i class="fas fa-layer-group mr-1"></i> Capas
285
+ </button>
286
+ <button class="px-3 py-1 bg-gray-700 text-white text-sm rounded hover:bg-gray-600">
287
+ <i class="fas fa-search-location mr-1"></i> Buscar
288
+ </button>
289
  </div>
290
  </div>
291
  </div>
 
569
  </footer>
570
 
571
  <script>
572
+ // Conexión a API en tiempo real
573
+ const API_URL = 'https://api.medallio.com/v1/realtime';
574
+
575
+ async function fetchData() {
576
+ try {
577
+ const response = await fetch(API_URL);
578
+ const data = await response.json();
579
+
580
+ // Actualizar estadísticas
581
+ document.getElementById('temp-value').textContent = data.weather.temperature + '°C';
582
+ document.getElementById('traffic-value').textContent = data.traffic.operational + '%';
583
+ document.getElementById('cameras-value').textContent = data.cameras.active;
584
+ document.getElementById('sensors-value').textContent = data.sensors.connected;
585
+
586
+ // Actualizar calidad del aire
587
+ const aqi = data.air_quality.index;
588
+ const aqiElement = document.getElementById('air-quality');
589
+ const aqiBar = document.getElementById('air-quality-bar');
590
+
591
+ if (aqi < 50) {
592
+ aqiElement.textContent = "Buena";
593
+ aqiElement.className = "text-green-400 font-semibold";
594
+ aqiBar.className = "bg-green-400 h-2 rounded-full";
595
+ } else if (aqi < 100) {
596
+ aqiElement.textContent = "Moderada";
597
+ aqiElement.className = "text-yellow-400 font-semibold";
598
+ aqiBar.className = "bg-yellow-400 h-2 rounded-full";
599
+ } else {
600
+ aqiElement.textContent = "Mala";
601
+ aqiElement.className = "text-red-400 font-semibold";
602
+ aqiBar.className = "bg-red-400 h-2 rounded-full";
603
+ }
604
+ aqiBar.style.width = Math.min(aqi, 100) + '%';
605
+
606
+ // Actualizar tiempo de última conexión
607
+ document.querySelector('.time-ago').textContent = 'hace unos segundos';
608
+
609
+ // Mostrar alertas si existen
610
+ if (data.alerts.length > 0) {
611
+ const alertsContainer = document.getElementById('alerts-container');
612
+ alertsContainer.innerHTML = data.alerts.map(alert => `
613
+ <div class="flex items-start mb-3 p-3 bg-${alert.severity}-50 rounded-lg">
614
+ <div class="flex-shrink-0 mt-1 mr-3 text-${alert.severity}-500">
615
+ <i class="fas fa-exclamation-triangle"></i>
616
+ </div>
617
+ <div>
618
+ <p class="text-sm font-medium">${alert.title}</p>
619
+ <p class="text-xs text-gray-500">${alert.time}</p>
620
+ </div>
621
+ </div>
622
+ `).join('');
623
+ }
624
+
625
+ } catch (error) {
626
+ console.error('Error fetching data:', error);
627
+ document.querySelector('.time-ago').textContent = 'conexión inestable';
628
  }
629
 
630
+ // Actualizar cada 10 segundos
631
+ setTimeout(fetchData, 10000);
632
  }
633
 
634
+ // Iniciar la aplicación
635
  document.addEventListener('DOMContentLoaded', function() {
636
+ fetchData();
637
 
638
+ // Tooltips para iconos
639
+ tippy('[data-tippy-content]', {
640
+ theme: 'light-border',
641
+ animation: 'fade',
642
+ arrow: true
643
+ });
644
+
645
+ // Efectos 3D para cards
646
  const cards = document.querySelectorAll('.card-hover');
647
  cards.forEach(card => {
648
+ card.addEventListener('mousemove', (e) => {
649
+ const x = e.clientX - card.getBoundingClientRect().left;
650
+ const y = e.clientY - card.getBoundingClientRect().top;
651
+
652
+ card.style.transform = `perspective(1000px) rotateX(${(y - card.offsetHeight/2)/20}deg) rotateY(${(x - card.offsetWidth/2)/20}deg) scale(1.03)`;
653
+ card.style.boxShadow = `${(x - card.offsetWidth/2)/10}px ${(y - card.offsetHeight/2)/10}px 20px rgba(0,0,0,0.1)`;
654
+ });
655
+
656
+ card.addEventListener('mouseleave', () => {
657
+ card.style.transform = 'perspective(1000px) rotateX(0) rotateY(0) scale(1)';
658
+ card.style.boxShadow = '0 4px 6px -1px rgba(0, 0, 0, 0.1)';
659
  });
660
  });
661
  });
662
  </script>
663
+
664
+ <!-- Librerías adicionales -->
665
+ <script src="https://unpkg.com/@popperjs/core@2"></script>
666
+ <script src="https://unpkg.com/tippy.js@6"></script>
667
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=YESO/medall-n-interactivo" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
668
  </html>