Skip to content

Instantly share code, notes, and snippets.

@MEDEV-GROUP
Last active February 17, 2025 17:10
Show Gist options
  • Select an option

  • Save MEDEV-GROUP/071a0c2edc33c94b6aa6df91703dcdc3 to your computer and use it in GitHub Desktop.

Select an option

Save MEDEV-GROUP/071a0c2edc33c94b6aa6df91703dcdc3 to your computer and use it in GitHub Desktop.
<!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