sidimedsidi commited on
Commit
c3ba2a1
·
verified ·
1 Parent(s): 234f156

Manual changes saved

Browse files
Files changed (1) hide show
  1. index.html +0 -611
index.html CHANGED
@@ -1,611 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="fr">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Vaccination Insight Atlas - Tableau de Bord</title>
7
- <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
- <script src="https://cdn.tailwindcss.com"></script>
9
- <script src="https://unpkg.com/feather-icons"></script>
10
- <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
- <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
12
- <script>
13
- tailwind.config = {
14
- theme: {
15
- extend: {
16
- colors: {
17
- primary: '#3B82F6',
18
- secondary: '#10B981'
19
- }
20
- }
21
- }
22
- }
23
- // Global variable for vaccination data
24
- let vaccinationData = [];
25
- // Load vaccination data from provided dataset
26
- async function fetchVaccinationData() {
27
- try {
28
- // Use the provided dataset directly
29
- vaccinationData = [
30
- {
31
- formNumber: "1",
32
- investigator: "محمد الشيخ حمادي",
33
- whatsapp: "20830384",
34
- wilaya: "Hodh El Chargui",
35
- commune: "Beribavar",
36
- vaccinationPoint: "القاسمية",
37
- gpsLatitude: 18.091472,
38
- gpsLongitude: -15.985392,
39
- population: 2000,
40
- childrenEligible: 60,
41
- zeroDoseChildren: 60,
42
- energySource: "Énergie solaire",
43
- hasVaccinationCalendar: "Non"
44
- },
45
- {
46
- formNumber: "2",
47
- investigator: "الطالب ولد محمد",
48
- whatsapp: "48386889",
49
- wilaya: "Hodh El Chargui",
50
- commune: "Bangou",
51
- vaccinationPoint: ".الاجواد",
52
- gpsLatitude: 18.091227,
53
- gpsLongitude: -15.988698,
54
- population: 2700,
55
- childrenEligible: 70,
56
- zeroDoseChildren: 70,
57
- energySource: "Énergie solaire",
58
- hasVaccinationCalendar: "Non"
59
- },
60
- {
61
- formNumber: "3",
62
- investigator: "Ba Issa Moussa",
63
- whatsapp: "30 49 62 12",
64
- wilaya: "Hodh El Chargui",
65
- commune: "Beribavar",
66
- vaccinationPoint: "Beribava",
67
- gpsLatitude: 18.090534,
68
- gpsLongitude: -15.988827,
69
- population: 2000,
70
- childrenEligible: 150,
71
- zeroDoseChildren: 20,
72
- energySource: "Énergie solaire",
73
- hasVaccinationCalendar: "Oui"
74
- },
75
- {
76
- formNumber: "4",
77
- investigator: "الشيخ / سيدأحمد",
78
- whatsapp: "20099692",
79
- wilaya: "Hodh El Chargui",
80
- commune: "Néma",
81
- vaccinationPoint: "Nema",
82
- gpsLatitude: 18.09086,
83
- gpsLongitude: -15.985048,
84
- population: 39015,
85
- childrenEligible: 0,
86
- zeroDoseChildren: 15,
87
- energySource: "Électricité",
88
- hasVaccinationCalendar: "Oui"
89
- },
90
- {
91
- formNumber: "5",
92
- investigator: "علي وزان ميصاره",
93
- whatsapp: "48983333",
94
- wilaya: "Hodh El Chargui",
95
- commune: "Beribavar",
96
- vaccinationPoint: "السليمانية",
97
- gpsLatitude: 18.092084,
98
- gpsLongitude: -15.988956,
99
- population: 940,
100
- childrenEligible: 25,
101
- zeroDoseChildren: 25,
102
- energySource: "Énergie solaire",
103
- hasVaccinationCalendar: "Non"
104
- },
105
- {
106
- formNumber: "6",
107
- investigator: "Ahmed Haide",
108
- whatsapp: "44479100",
109
- wilaya: "Hodh El Chargui",
110
- commune: "Ghlig Ehel Beye",
111
- vaccinationPoint: "Ghlig ehel beye",
112
- gpsLatitude: 16.008531,
113
- gpsLongitude: -8.796833,
114
- population: 806,
115
- childrenEligible: 29,
116
- zeroDoseChildren: 6,
117
- energySource: "Énergie solaire",
118
- hasVaccinationCalendar: "Oui"
119
- },
120
- {
121
- formNumber: "7",
122
- investigator: "Mohamed Souleimane elemine",
123
- whatsapp: "27118586",
124
- wilaya: "Hodh El Chargui",
125
- commune: "Bassikounou",
126
- vaccinationPoint: "Hbib sid'ahmed",
127
- gpsLatitude: 15.866728,
128
- gpsLongitude: -5.952468,
129
- population: 204000,
130
- childrenEligible: 9180,
131
- zeroDoseChildren: 0,
132
- energySource: "Électricité",
133
- hasVaccinationCalendar: "Oui"
134
- },
135
- {
136
- formNumber: "8",
137
- investigator: "Déh Ainine Allen'dide",
138
- whatsapp: "26010443",
139
- wilaya: "Hodh El Chargui",
140
- commune: "Ghlig Ehel Beye",
141
- vaccinationPoint: "Poste de santé zegnoun",
142
- gpsLatitude: 16.004008,
143
- gpsLongitude: -8.522187,
144
- population: 1137,
145
- childrenEligible: 50,
146
- zeroDoseChildren: 12,
147
- energySource: "Énergie solaire",
148
- hasVaccinationCalendar: "Oui"
149
- },
150
- {
151
- formNumber: "9",
152
- investigator: "محمد الامين المحفوط",
153
- whatsapp: "22618223",
154
- wilaya: "Hodh El Chargui",
155
- commune: "Ksar El Barka",
156
- vaccinationPoint: "كصر البركة",
157
- gpsLatitude: 15.733826,
158
- gpsLongitude: -8.790646,
159
- population: 5040,
160
- childrenEligible: 1200,
161
- zeroDoseChildren: 100,
162
- energySource: "Énergie solaire",
163
- hasVaccinationCalendar: "Oui"
164
- },
165
- {
166
- formNumber: "10",
167
- investigator: "Med Mokhtar El Mamy",
168
- whatsapp: "48040504",
169
- wilaya: "Hodh El Chargui",
170
- commune: "Ghlig Ehel Beye",
171
- vaccinationPoint: "Bouleklal",
172
- gpsLatitude: 9.2,
173
- gpsLongitude: 14.5,
174
- population: 1850,
175
- childrenEligible: 65,
176
- zeroDoseChildren: 4,
177
- energySource: "Énergie solaire",
178
- hasVaccinationCalendar: "Oui"
179
- },
180
- {
181
- formNumber: "11",
182
- investigator: "Ahmedou Mohamed",
183
- whatsapp: "28669929",
184
- wilaya: "Hodh El Chargui",
185
- commune: "Feirenni",
186
- vaccinationPoint: "Oumnour",
187
- gpsLatitude: 16.623975,
188
- gpsLongitude: -7.265648,
189
- population: 3200,
190
- childrenEligible: 108,
191
- zeroDoseChildren: 0,
192
- energySource: "Énergie solaire",
193
- hasVaccinationCalendar: "Oui"
194
- }
195
- ];
196
-
197
- updateDashboardStatistics();
198
- initializeCharts();
199
- updateDistanceTable();
200
-
201
- // Show success alert
202
- document.getElementById('alert').className = 'bg-green-50 border border-green-200 rounded-xl p-4 mb-8';
203
- document.getElementById('alert').innerHTML = `
204
- <div class="flex items-center">
205
- <i data-feather="check-circle" class="w-5 h-5 text-green-600 mr-3"></i>
206
- <div>
207
- <h4 class="text-sm font-semibold text-green-800">
208
- ✅ Données Connectées - Base de Données Locale
209
- </h4>
210
- <p class="text-sm text-green-700">
211
- Système connecté à la base de données locale - Données chargées avec succès
212
- </p>
213
- </div>
214
- `;
215
- feather.replace();
216
-
217
- } catch (error) {
218
- console.log('Data loading error:', error);
219
-
220
- // Show error alert
221
- document.getElementById('alert').className = 'bg-red-50 border border-red-200 rounded-xl p-4 mb-8';
222
- document.getElementById('alert').innerHTML = `
223
- <div class="flex items-center">
224
- <i data-feather="alert-triangle" class="w-5 h-5 text-red-600 mr-3"></i>
225
- <div>
226
- <h4 class="text-sm font-semibold text-red-800">
227
- ⚠️ Erreur de Chargement des Données
228
- </h4>
229
- <p class="text-sm text-red-700">
230
- Erreur lors du chargement des données - Vérifiez la connexion
231
- </p>
232
- </div>
233
- `;
234
- feather.replace();
235
- }
236
- }
237
- // Initialize data on page load
238
- document.addEventListener('DOMContentLoaded', function() {
239
- fetchVaccinationData();
240
- });
241
- function updateDashboardStatistics() {
242
- const totalChildren = vaccinationData.reduce((sum, item) => sum + item.childrenEligible, 0);
243
- const totalVaccinated = vaccinationData.reduce((sum, item) => sum + (item.childrenEligible - item.zeroDoseChildren), 0);
244
- const totalZeroDose = vaccinationData.reduce((sum, item) => sum + item.zeroDoseChildren, 0);
245
- const coverageRate = totalChildren > 0 ? Math.round((totalVaccinated / totalChildren) * 100) : 0;
246
-
247
- // Update statistics cards
248
- const statCards = document.querySelectorAll('.stat-card');
249
- if (statCards.length >= 4) {
250
- statCards[0].querySelector('.text-2xl').textContent = totalChildren.toLocaleString();
251
- statCards[1].querySelector('.text-2xl').textContent = totalVaccinated.toLocaleString();
252
- statCards[2].querySelector('.text-2xl').textContent = totalZeroDose.toLocaleString();
253
- statCards[3].querySelector('.text-2xl').textContent = coverageRate + '%';
254
- }
255
- }
256
- function initializeCharts() {
257
- // Commune distribution chart
258
- const communeData = {};
259
- vaccinationData.forEach(item => {
260
- if (!communeData[item.commune]) {
261
- communeData[item.commune] = 0;
262
- }
263
- communeData[item.commune] += item.childrenEligible;
264
- });
265
-
266
- const communeTrace = {
267
- x: Object.keys(communeData),
268
- y: Object.values(communeData),
269
- type: 'bar',
270
- marker: {
271
- color: '#3B82F6'
272
- }
273
- };
274
-
275
- Plotly.newPlot('commune-bar-chart', [communeTrace], {
276
- margin: { t: 0, r: 0, b: 30, l: 40 },
277
- paper_bgcolor: 'rgba(0,0,0,0)',
278
- plot_bgcolor: 'rgba(0,0,0,0)',
279
- font: { size: 12 }
280
- });
281
-
282
- // Energy source pie chart
283
- const energyData = {};
284
- vaccinationData.forEach(item => {
285
- if (!energyData[item.energySource]) {
286
- energyData[item.energySource] = 0;
287
- }
288
- energyData[item.energySource]++;
289
- });
290
-
291
- const energyTrace = {
292
- values: Object.values(energyData),
293
- labels: Object.keys(energyData),
294
- type: 'pie',
295
- marker: {
296
- colors: ['#3B82F6', '#10B981', '#F59E0B'],
297
- textinfo: 'label+percent',
298
- insidetextorientation: 'radial'
299
- };
300
-
301
- Plotly.newPlot('energy-pie-chart', [energyTrace], {
302
- margin: { t: 0, r: 0, b: 0, l: 0 },
303
- paper_bgcolor: 'rgba(0,0,0,0)',
304
- showlegend: true
305
- });
306
- }
307
-
308
- function updateDistanceTable() {
309
- const tableBody = document.querySelector('table tbody');
310
- tableBody.innerHTML = '';
311
-
312
- vaccinationData.forEach(item => {
313
- const row = document.createElement('tr');
314
- row.className = 'hover:bg-gray-50';
315
-
316
- row.innerHTML = `
317
- <td class="px-4 py-3 text-sm text-gray-900">${item.commune}</td>
318
- <td class="px-4 py-3 text-sm text-gray-900">${item.vaccinationPoint}</td>
319
- <td class="px-4 py-3 text-sm text-gray-900">
320
- ${calculateDistance(item.gpsLatitude, item.gpsLongitude).toFixed(2)}
321
- </td>
322
- `;
323
- tableBody.appendChild(row);
324
- });
325
- }
326
-
327
- function calculateDistance(lat, lon) {
328
- // Simplified distance calculation (for demonstration)
329
- const baseLat = 18.091472;
330
- const baseLon = -15.985392;
331
-
332
- const R = 6371; // Earth's radius in km
333
- const dLat = (lat - baseLat) * Math.PI / 180;
334
- const dLon = (lon - baseLon) * Math.PI / 180;
335
- const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
336
- Math.cos(baseLat * Math.PI / 180) * Math.cos(lat * Math.PI / 180) *
337
- Math.sin(dLon/2) * Math.sin(dLon/2);
338
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
339
- return R * c;
340
- }
341
- </script>
342
- <style>
343
- .gradient-bg {
344
- background: linear-gradient(135deg, #3B82F6 0%, #10B981 100%);
345
- }
346
- .card-hover {
347
- transition: all 0.3s ease;
348
- }
349
- .card-hover:hover {
350
- transform: translateY(-5px);
351
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
352
- }
353
- .stat-card {
354
- background: rgba(255, 255, 255, 0.1);
355
- backdrop-filter: blur(10px);
356
- border: 1px solid rgba(255, 255, 255, 0.2);
357
- }
358
- </style>
359
- </head>
360
- <body class="bg-gray-50 min-h-screen">
361
- <!-- Header -->
362
- <header class="gradient-bg text-white shadow-lg">
363
- <div class="container mx-auto px-4 py-6">
364
- <div class="flex flex-col md:flex-row justify-between items-center">
365
- <div class="flex items-center space-x-3 mb-4 md:mb-0">
366
- <i data-feather="shield" class="w-8 h-8"></i>
367
- <h1 class="text-2xl font-bold">Vaccination Insight Atlas</h1>
368
- <span class="text-sm bg-white/20 px-2 py-1 rounded-full">💉 Suivi en Temps Réel</span>
369
- </div>
370
- <div class="flex items-center space-x-4">
371
- <a href="personnel.html" class="bg-white/20 hover:bg-white/30 px-4 py-2 rounded-lg transition duration-200">
372
- <i data-feather="users" class="w-4 h-4 inline mr-2"></i>
373
- Gestion du Personnel
374
- </a>
375
- <div class="flex items-center space-x-2">
376
- <i data-feather="map-pin" class="w-5 h-5"></i>
377
- <span class="text-lg">Hodh El Chargui</span>
378
- </div>
379
- </div>
380
- </header>
381
-
382
- <!-- Main Content -->
383
- <main class="container mx-auto px-4 py-8">
384
- <!-- Control Panel -->
385
- <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
386
- <!-- Wilaya Selection -->
387
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
388
- <label class="block text-sm font-semibold text-gray-700 mb-3">
389
- <i data-feather="map" class="w-4 h-4 inline mr-2"></i>
390
- Sélectionnez une Wilaya
391
- </label>
392
- <select class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent">
393
- <option value="Hodh El Chargui" selected>Hodh El Chargui</option>
394
- </select>
395
- </div>
396
-
397
- <!-- Commune Selection -->
398
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
399
- <label class="block text-sm font-semibold text-gray-700 mb-3">
400
- <i data-feather="home" class="w-4 h-4 inline mr-2"></i>
401
- Sélectionnez une Commune
402
- </label>
403
- <select class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" multiple>
404
- <option value="Beribavar">Beribavar</option>
405
- <option value="Bangou">Bangou</option>
406
- <option value="Néma">Néma</option>
407
- <option value="Ghlig Ehel Beye">Ghlig Ehel Beye</option>
408
- <option value="Bassikounou">Bassikounou</option>
409
- <option value="Amourj">Amourj</option>
410
- <option value="Feirenni">Feirenni</option>
411
- </select>
412
- </div>
413
-
414
- <!-- Energy Source Selection -->
415
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
416
- <label class="block text-sm font-semibold text-gray-700 mb-3">
417
- <i data-feather="battery" class="w-4 h-4 inline mr-2"></i>
418
- Sources d'Énergie
419
- </label>
420
- <select class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent" multiple>
421
- <option value="Énergie solaire">Énergie solaire</option>
422
- <option value="Électricité">Électricité</option>
423
- <option value="Gaz">Gaz</option>
424
- </select>
425
- </div>
426
- </div>
427
-
428
- <!-- Sliders Section -->
429
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
430
- <!-- Children Age Slider -->
431
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
432
- <label class="block text-sm font-semibold text-gray-700 mb-4">
433
- <i data-feather="users" class="w-4 h-4 inline mr-2"></i>
434
- Âge des Enfants (Minimum)
435
- </label>
436
- <input type="range" min="0" max="100" value="0" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider">
437
- <div class="flex justify-between text-xs text-gray-500 mt-2">
438
- <span>0</span>
439
- <span>100</span>
440
- </div>
441
- </div>
442
-
443
- <!-- Zero Dose Slider -->
444
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
445
- <label class="block text-sm font-semibold text-gray-700 mb-4">
446
- <i data-feather="alert-triangle" class="w-4 h-4 inline mr-2"></i>
447
- Enfants Zéro Dose (Maximum)
448
- </label>
449
- <input type="range" min="0" max="100" value="0" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider">
450
- <div class="flex justify-between text-xs text-gray-500 mt-2">
451
- <span>0</span>
452
- <span>100</span>
453
- </div>
454
- </div>
455
- </div>
456
- <!-- Statistics Cards -->
457
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
458
- <div class="stat-card rounded-xl p-4 text-center text-white">
459
- <i data-feather="users" class="w-6 h-6 mx-auto mb-2"></i>
460
- <div class="text-2xl font-bold" id="total-children">0</div>
461
- <div class="text-sm opacity-80">Enfants en âge</div>
462
- </div>
463
- <div class="stat-card rounded-xl p-4 text-center text-white">
464
- <i data-feather="check-circle" class="w-6 h-6 mx-auto mb-2"></i>
465
- <div class="text-2xl font-bold" id="total-vaccinated">0</div>
466
- <div class="text-sm opacity-80">Vaccinés</div>
467
- </div>
468
- <div class="stat-card rounded-xl p-4 text-center text-white">
469
- <i data-feather="alert-triangle" class="w-6 h-6 mx-auto mb-2"></i>
470
- <div class="text-2xl font-bold" id="total-zero-dose">0</div>
471
- <div class="text-sm opacity-80">Zéro Dose</div>
472
- </div>
473
- <div class="stat-card rounded-xl p-4 text-center text-white">
474
- <i data-feather="map-pin" class="w-6 h-6 mx-auto mb-2"></i>
475
- <div class="text-2xl font-bold" id="coverage-rate">0%</div>
476
- <div class="text-sm opacity-80">Couverture</div>
477
- </div>
478
- </div>
479
- <!-- Interactive Map -->
480
- <div class="bg-white rounded-xl shadow-lg p-6 mb-8 card-hover">
481
- <div class="flex items-center justify-between mb-4">
482
- <h2 class="text-xl font-semibold text-gray-800">
483
- <i data-feather="map" class="w-5 h-5 inline mr-2"></i>
484
- Carte Interactive des Points de Vaccination
485
- </h2>
486
- <button class="bg-primary hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition duration-200" onclick="fetchVaccinationData()">
487
- <i data-feather="refresh-cw" class="w-4 h-4 inline mr-2"></i>
488
- Actualiser les Données API
489
- </button>
490
- </div>
491
- <div id="vaccination-map" class="w-full h-96 rounded-lg border border-gray-200">
492
- <!-- Map placeholder -->
493
- <div class="w-full h-full flex items-center justify-center text-gray-500">
494
- <i data-feather="map" class="w-12 h-12 mb-2"></i>
495
- <p>Chargement des données en temps réel...</p>
496
- </div>
497
- </div>
498
- </div>
499
-
500
- <!-- Charts Grid -->
501
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
502
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
503
- <h3 class="text-lg font-semibold text-gray-800 mb-4">
504
- <i data-feather="bar-chart-2" class="w-5 h-5 inline mr-2"></i>
505
- Répartition par Commune
506
- </h3>
507
- <div id="commune-bar-chart" class="w-full h-64"></div>
508
- </div>
509
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
510
- <h3 class="text-lg font-semibold text-gray-800 mb-4">
511
- <i data-feather="pie-chart" class="w-5 h-5 inline mr-2"></i>
512
- Sources d'Énergie
513
- </h3>
514
- <div id="energy-pie-chart" class="w-full h-64"></div>
515
- </div>
516
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
517
- <h3 class="text-lg font-semibold text-gray-800 mb-4">
518
- <i data-feather="trending-up" class="w-5 h-5 inline mr-2"></i>
519
- Couverture Vaccinale
520
- </h3>
521
- <div id="vaccination-coverage-chart" class="w-full h-64"></div>
522
- </div>
523
- <div class="bg-white rounded-xl shadow-lg p-6 card-hover">
524
- <h3 class="text-lg font-semibold text-gray-800 mb-4">
525
- <i data-feather="activity" class="w-5 h-5 inline mr-2"></i>
526
- Corrélation
527
- </h3>
528
- <div id="correlation-scatter-chart" class="w-full h-64"></div>
529
- </div>
530
- </div>
531
-
532
- <!-- Distance Table -->
533
- <div class="bg-white rounded-xl shadow-lg p-6 mb-8 card-hover">
534
- <h3 class="text-lg font-semibold text-gray-800 mb-4">
535
- <i data-feather="navigation" class="w-5 h-5 inline mr-2"></i>
536
- Tableau des Distances
537
- </h3>
538
- <div class="overflow-x-auto">
539
- <table class="w-full table-auto">
540
- <thead class="bg-gray-50">
541
- <tr>
542
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
543
- Commune
544
- </th>
545
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
546
- Point de Vaccination
547
- </th>
548
- <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
549
- Distance (km)
550
- </th>
551
- </tr>
552
- </thead>
553
- <tbody class="divide-y divide-gray-200">
554
- <!-- Table will be populated dynamically with real data -->
555
- </tbody>
556
- </table>
557
- </div>
558
- </div>
559
- <!-- Alert Section -->
560
- <div id="alert" class="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-8">
561
- <div class="flex items-center">
562
- <i data-feather="database" class="w-5 h-5 text-blue-600 mr-3"></i>
563
- <div>
564
- <h4 class="text-sm font-semibold text-blue-800">
565
- 📊 Chargement des Données Locales...
566
- </h4>
567
- <p class="text-sm text-blue-700">
568
- Connexion à la base de données locale en cours
569
- </p>
570
- <p class="text-xs text-blue-600 mt-1">
571
- Le système charge les données de vaccination depuis la source locale.
572
- </p>
573
- </div>
574
- </div>
575
- </main>
576
-
577
- <!-- Footer -->
578
- <footer class="gradient-bg text-white py-8 mt-12">
579
- <div class="container mx-auto px-4 text-center">
580
- <div class="flex justify-center space-x-6 mb-4">
581
- <i data-feather="heart" class="w-5 h-5"></i>
582
- <p class="text-sm opacity-80">
583
- Système de Suivi Vaccinal - Hodh El Chargui
584
- </p>
585
- <p class="text-xs opacity-60 mt-2">
586
- Développé pour optimiser la couverture vaccinale
587
- </p>
588
- </div>
589
- </footer>
590
- <script>
591
- feather.replace();
592
-
593
- // Interactive slider effects
594
- document.querySelectorAll('.slider').forEach(slider => {
595
- slider.addEventListener('input', function() {
596
- const value = (this.value - this.min) / (this.max - this.min) * 100;
597
- this.style.background = `linear-gradient(to right, #3B82F6 ${value}%, #E5E7EB ${value}%)`;
598
- });
599
- });
600
-
601
- // Initialize with gradient
602
- document.querySelectorAll('.slider').forEach(slider => {
603
- const value = (slider.value - slider.min) / (slider.max - slider.min) * 100;
604
- slider.style.background = `linear-gradient(to right, #3B82F6 ${value}%, #E5E7EB ${value}%)`;
605
- });
606
-
607
- // Auto-refresh data every 5 minutes
608
- setInterval(fetchVaccinationData, 300000);
609
- </script>
610
- </body>
611
- </html>