Last active
February 17, 2025 17:10
-
-
Save MEDEV-GROUP/071a0c2edc33c94b6aa6df91703dcdc3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Test Socket.IO - Chef de District</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.min.js"></script> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| .container { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 20px; | |
| } | |
| .connection-status { | |
| padding: 10px; | |
| margin-bottom: 20px; | |
| border-radius: 4px; | |
| } | |
| .connected { | |
| background-color: #d4edda; | |
| color: #155724; | |
| } | |
| .disconnected { | |
| background-color: #f8d7da; | |
| color: #721c24; | |
| } | |
| .incident-list { | |
| border: 1px solid #ddd; | |
| padding: 15px; | |
| border-radius: 4px; | |
| height: 600px; | |
| overflow-y: auto; | |
| } | |
| .incident-card { | |
| background-color: #f8f9fa; | |
| border-left: 4px solid #084298; | |
| padding: 10px; | |
| margin-bottom: 10px; | |
| border-radius: 4px; | |
| } | |
| .incident-card.HIGH { | |
| border-left-color: #dc3545; | |
| } | |
| .incident-card.MEDIUM { | |
| border-left-color: #ffc107; | |
| } | |
| .incident-card.LOW { | |
| border-left-color: #0dcaf0; | |
| } | |
| .log-panel { | |
| background-color: #f8f9fa; | |
| padding: 15px; | |
| border-radius: 4px; | |
| height: 600px; | |
| overflow-y: auto; | |
| } | |
| .log-entry { | |
| font-family: monospace; | |
| margin-bottom: 5px; | |
| font-size: 14px; | |
| } | |
| .config-panel { | |
| margin-bottom: 20px; | |
| padding: 15px; | |
| background-color: #e9ecef; | |
| border-radius: 4px; | |
| } | |
| input[type="text"], | |
| input[type="password"] { | |
| width: 300px; | |
| padding: 8px; | |
| margin-right: 10px; | |
| } | |
| button { | |
| padding: 8px 15px; | |
| background-color: #0d6efd; | |
| color: white; | |
| border: none; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| } | |
| button:disabled { | |
| background-color: #6c757d; | |
| cursor: not-allowed; | |
| } | |
| .timestamp { | |
| font-size: 12px; | |
| color: #6c757d; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Test Socket.IO - Interface Chef de District</h1> | |
| <div class="config-panel"> | |
| <div> | |
| <input type="text" id="serverUrl" value="http://46.202.170.228:3005" placeholder="URL du serveur"> | |
| <input type="text" id="tokenInput" placeholder="JWT Token"> | |
| <button id="connectBtn">Connecter</button> | |
| <button id="disconnectBtn" disabled>Déconnecter</button> | |
| </div> | |
| </div> | |
| <div id="status" class="connection-status disconnected"> | |
| Déconnecté | |
| </div> | |
| <div class="container"> | |
| <div> | |
| <h2>Incidents en temps réel</h2> | |
| <div id="incidentList" class="incident-list"></div> | |
| </div> | |
| <div> | |
| <h2>Logs de connexion</h2> | |
| <div id="logPanel" class="log-panel"></div> | |
| </div> | |
| </div> | |
| <script> | |
| //script.js | |
| let socket = null; | |
| // Éléments DOM | |
| const serverUrlInput = document.getElementById('serverUrl'); | |
| const tokenInput = document.getElementById('tokenInput'); | |
| const connectBtn = document.getElementById('connectBtn'); | |
| const disconnectBtn = document.getElementById('disconnectBtn'); | |
| const statusDiv = document.getElementById('status'); | |
| const incidentList = document.getElementById('incidentList'); | |
| const logPanel = document.getElementById('logPanel'); | |
| // Fonctions utilitaires | |
| function addLog(message, type = 'info') { | |
| const logEntry = document.createElement('div'); | |
| logEntry.className = 'log-entry'; | |
| const timestamp = new Date().toLocaleTimeString(); | |
| logEntry.innerHTML = `<span class="timestamp">${timestamp}</span> [${type}] ${message}`; | |
| logPanel.appendChild(logEntry); | |
| logPanel.scrollTop = logPanel.scrollHeight; | |
| } | |
| function formatTimestamp(timestamp) { | |
| const date = new Date(timestamp); | |
| return date.toLocaleString('fr-FR', { | |
| year: 'numeric', | |
| month: '2-digit', | |
| day: '2-digit', | |
| hour: '2-digit', | |
| minute: '2-digit', | |
| second: '2-digit' | |
| }); | |
| } | |
| function createMediaList(media) { | |
| if (!media || media.length === 0) return ''; | |
| return ` | |
| <div class="media-section"> | |
| <h4>Fichiers attachés:</h4> | |
| <ul> | |
| ${media.map(m => ` | |
| <li> | |
| ${m.type} - ${m.url} | |
| </li> | |
| `).join('')} | |
| </ul> | |
| </div> | |
| `; | |
| } | |
| function addIncident(incident) { | |
| console.log('Données d\'incident reçues:', incident); | |
| const incidentCard = document.createElement('div'); | |
| incidentCard.className = `incident-card ${incident.data.severity.toLowerCase()}`; | |
| incidentCard.id = `incident-${incident.data.id}`; | |
| const createdAt = formatTimestamp(incident.data.created_at); | |
| const notificationTime = formatTimestamp(incident.metadata.timestamp); | |
| incidentCard.innerHTML = ` | |
| <div class="incident-header"> | |
| <span class="incident-id">#${incident.data.id}</span> | |
| <span class="timestamp">${createdAt}</span> | |
| </div> | |
| <div class="incident-body"> | |
| <h3>${incident.data.type}</h3> | |
| <div class="severity-badge ${incident.data.severity.toLowerCase()}"> | |
| ${incident.data.severity} | |
| </div> | |
| <p class="description">${incident.data.description}</p> | |
| <div class="incident-details"> | |
| <p> | |
| <strong>Position:</strong> | |
| <a href="https://www.google.com/maps?q=${incident.data.location.latitude},${incident.data.location.longitude}" | |
| target="_blank"> | |
| ${incident.data.location.latitude.toFixed(6)}, | |
| ${incident.data.location.longitude.toFixed(6)} | |
| </a> | |
| </p> | |
| <p> | |
| <strong>Signalé par:</strong> | |
| ${incident.data.reporter.fullname} | |
| ${incident.data.reporter.matricule ? `(${incident.data.reporter.matricule})` : ''} | |
| </p> | |
| </div> | |
| ${incident.data.media ? createMediaList(incident.data.media) : ''} | |
| </div> | |
| <div class="incident-footer"> | |
| <span class="notification-time">Notification reçue: ${notificationTime}</span> | |
| </div> | |
| `; | |
| // Ajouter au début de la liste | |
| incidentList.insertBefore(incidentCard, incidentList.firstChild); | |
| // Animation d'entrée | |
| requestAnimationFrame(() => { | |
| incidentCard.classList.add('show'); | |
| }); | |
| } | |
| function updateConnectionStatus(connected) { | |
| statusDiv.className = `connection-status ${connected ? 'connected' : 'disconnected'}`; | |
| statusDiv.textContent = connected ? 'Connecté' : 'Déconnecté'; | |
| connectBtn.disabled = connected; | |
| disconnectBtn.disabled = !connected; | |
| // Ajouter une notification visuelle | |
| const notification = document.createElement('div'); | |
| notification.className = `connection-notification ${connected ? 'success' : 'error'}`; | |
| notification.textContent = connected ? 'Connexion établie' : 'Connexion perdue'; | |
| document.body.appendChild(notification); | |
| setTimeout(() => { | |
| notification.remove(); | |
| }, 3000); | |
| } | |
| // Gestionnaire de connexion | |
| connectBtn.addEventListener('click', () => { | |
| if (socket) { | |
| addLog('Déconnexion de la session précédente...', 'warning'); | |
| socket.disconnect(); | |
| } | |
| const serverUrl = serverUrlInput.value.trim(); | |
| const token = tokenInput.value.trim(); | |
| if (!serverUrl || !token) { | |
| addLog('URL du serveur et token requis', 'error'); | |
| return; | |
| } | |
| addLog(`Tentative de connexion à ${serverUrl}...`); | |
| socket = io(serverUrl, { | |
| auth: { token }, | |
| transports: ['websocket'], | |
| reconnection: true, | |
| reconnectionAttempts: 5, | |
| reconnectionDelay: 1000, | |
| reconnectionDelayMax: 5000, | |
| timeout: 20000 | |
| }); | |
| // Événements de connexion | |
| socket.on('connect', () => { | |
| addLog('Connecté au serveur', 'success'); | |
| updateConnectionStatus(true); | |
| }); | |
| socket.on('connect_error', (error) => { | |
| addLog(`Erreur de connexion: ${error.message}`, 'error'); | |
| updateConnectionStatus(false); | |
| }); | |
| socket.on('disconnect', (reason) => { | |
| addLog(`Déconnecté: ${reason}`, 'warning'); | |
| updateConnectionStatus(false); | |
| }); | |
| // Événement principal des incidents | |
| socket.on('incident:new', (incident) => { | |
| console.log('Nouvel incident reçu:', incident); | |
| addLog(`Nouvel incident signalé: ${incident.data.type} (${incident.data.severity})`); | |
| addIncident(incident); | |
| }); | |
| // Debug: logger tous les événements | |
| socket.onAny((eventName, ...args) => { | |
| console.log(`[DEBUG] Événement '${eventName}' reçu:`, args); | |
| }); | |
| }); | |
| // Gestionnaire de déconnexion | |
| disconnectBtn.addEventListener('click', () => { | |
| if (socket) { | |
| socket.disconnect(); | |
| socket = null; | |
| addLog('Déconnexion manuelle', 'info'); | |
| updateConnectionStatus(false); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment