diff --git a/static/app.js b/static/app.js new file mode 100644 index 0000000..ebd91e6 --- /dev/null +++ b/static/app.js @@ -0,0 +1,247 @@ +// État global de l'application +let appState = { + selectedWifi: null, + hotspotEnabled: true, + connectedDevices: [], + wifiNetworks: [], + uptime: 0, + dataUsage: 0 +}; + +// Simulation de données +const mockWifiNetworks = [ + { ssid: "Hotel_WiFi", signal: 4, security: "WPA2", channel: 6 }, + { ssid: "Starbucks_Free", signal: 3, security: "Open", channel: 11 }, + { ssid: "AndroidAP", signal: 2, security: "WPA2", channel: 1 }, + { ssid: "iPhone_Hotspot", signal: 5, security: "WPA2", channel: 6 }, + { ssid: "Guest_Network", signal: 1, security: "WPA", channel: 11 } +]; + +const mockDevices = [ + { name: "iPhone 13", type: "mobile", mac: "AA:BB:CC:DD:EE:FF", ip: "192.168.1.101" }, + { name: "MacBook Pro", type: "laptop", mac: "11:22:33:44:55:66", ip: "192.168.1.102" }, + { name: "iPad", type: "tablet", mac: "77:88:99:AA:BB:CC", ip: "192.168.1.103" } +]; + +// Initialisation +document.addEventListener('DOMContentLoaded', function() { + initializeApp(); + startPeriodicUpdates(); +}); + +function initializeApp() { + updateWifiList(); + updateDevicesList(); + updateStats(); + addLog("Système", "Interface web initialisée"); +} + +function updateWifiList() { + const wifiList = document.getElementById('wifiList'); + wifiList.innerHTML = ''; + + mockWifiNetworks.forEach((network, index) => { + const wifiItem = document.createElement('div'); + wifiItem.className = 'wifi-item'; + wifiItem.onclick = () => selectWifi(network, wifiItem); + + wifiItem.innerHTML = ` +
+ ${network.ssid} +
${network.security} • Canal ${network.channel}
+
+
+ ${generateSignalBars(network.signal)} +
+ `; + + wifiList.appendChild(wifiItem); + }); +} + +function generateSignalBars(strength) { + const bars = []; + for (let i = 1; i <= 5; i++) { + const height = i * 3; + const active = i <= strength ? 'active' : ''; + bars.push(`
`); + } + return `
${bars.join('')}
`; +} + +function selectWifi(network, element) { + // Retirer la sélection précédente + document.querySelectorAll('.wifi-item').forEach(item => { + item.classList.remove('selected'); + }); + + // Ajouter la sélection + element.classList.add('selected'); + appState.selectedWifi = network; + + addLog("WiFi", `Réseau sélectionné: ${network.ssid}`); +} + +function updateDevicesList() { + const devicesList = document.getElementById('devicesList'); + devicesList.innerHTML = ''; + + mockDevices.forEach(device => { + const deviceCard = document.createElement('div'); + deviceCard.className = 'device-card'; + + const deviceIcon = getDeviceIcon(device.type); + + deviceCard.innerHTML = ` + ${deviceIcon} +
${device.name}
+
${device.ip}
+ `; + + devicesList.appendChild(deviceCard); + }); + + document.getElementById('connectedDevices').textContent = mockDevices.length; +} + +function getDeviceIcon(type) { + const icons = { + mobile: '', + laptop: '', + tablet: '' + }; + return icons[type] || icons.mobile; +} + +function updateStats() { + appState.uptime += 1; + appState.dataUsage += Math.random() * 0.5; + + const hours = Math.floor(appState.uptime / 3600); + const minutes = Math.floor((appState.uptime % 3600) / 60); + const seconds = appState.uptime % 60; + + document.getElementById('uptime').textContent = + `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; + + document.getElementById('dataUsage').textContent = `${appState.dataUsage.toFixed(1)} MB`; +} + +function addLog(source, message) { + const logContainer = document.getElementById('logContainer'); + const timestamp = new Date().toLocaleTimeString(); + const logEntry = document.createElement('div'); + logEntry.className = 'log-entry'; + logEntry.innerHTML = `[${timestamp}] ${source}: ${message}`; + + logContainer.appendChild(logEntry); + logContainer.scrollTop = logContainer.scrollHeight; +} + +function showNotification(message, type = 'success') { + const notification = document.getElementById('notification'); + notification.textContent = message; + notification.className = `notification ${type}`; + notification.classList.add('show'); + + setTimeout(() => { + notification.classList.remove('show'); + }, 3000); +} + +// Fonctions d'action +function scanWifi() { + const scanBtn = document.getElementById('scanBtn'); + const originalText = scanBtn.textContent; + + scanBtn.innerHTML = '
Scan en cours...'; + + setTimeout(() => { + updateWifiList(); + scanBtn.textContent = originalText; + showNotification('Scan terminé - Réseaux mis à jour'); + addLog("WiFi", "Scan des réseaux terminé"); + }, 2000); +} + +function connectToWifi() { + if (!appState.selectedWifi) { + showNotification('Veuillez sélectionner un réseau WiFi', 'error'); + return; + } + + const password = document.getElementById('wifiPassword').value; + if (!password && appState.selectedWifi.security !== 'Open') { + showNotification('Mot de passe requis', 'error'); + return; + } + + const connectBtn = document.getElementById('connectBtn'); + const originalText = connectBtn.textContent; + + connectBtn.innerHTML = '
Connexion...'; + + setTimeout(() => { + connectBtn.textContent = originalText; + showNotification(`Connecté à ${appState.selectedWifi.ssid}`); + addLog("WiFi", `Connexion établie avec ${appState.selectedWifi.ssid}`); + + // Mettre à jour le statut + document.getElementById('connectionStatus').innerHTML = ` +
+ Connecté à ${appState.selectedWifi.ssid} + `; + }, 3000); +} + +function updateHotspot() { + const name = document.getElementById('hotspotName').value; + const password = document.getElementById('hotspotPassword').value; + const channel = document.getElementById('hotspotChannel').value; + + if (!name || !password) { + showNotification('Nom et mot de passe requis', 'error'); + return; + } + + showNotification('Configuration du hotspot mise à jour'); + addLog("Hotspot", `Configuration mise à jour: ${name} (Canal ${channel})`); +} + +function toggleHotspot() { + appState.hotspotEnabled = !appState.hotspotEnabled; + const btn = document.getElementById('hotspotBtn'); + + if (appState.hotspotEnabled) { + btn.textContent = 'Arrêter le hotspot'; + showNotification('Hotspot activé'); + addLog("Hotspot", "Hotspot activé"); + } else { + btn.textContent = 'Démarrer le hotspot'; + showNotification('Hotspot désactivé'); + addLog("Hotspot", "Hotspot désactivé"); + } +} + +function clearLogs() { + document.getElementById('logContainer').innerHTML = ''; + addLog("Système", "Logs effacés"); +} + +// Mises à jour périodiques +function startPeriodicUpdates() { + setInterval(updateStats, 1000); + setInterval(() => { + // Simulation de nouveaux logs + if (Math.random() > 0.95) { + const events = [ + "Nouveau client connecté", + "Paquet routé vers l'extérieur", + "Vérification de la connexion", + "Mise à jour des tables de routage" + ]; + const randomEvent = events[Math.floor(Math.random() * events.length)]; + addLog("Système", randomEvent); + } + }, 5000); +} diff --git a/static/index.html b/static/index.html index 010827a..dbb7131 100644 --- a/static/index.html +++ b/static/index.html @@ -4,346 +4,7 @@ WiFi Repeater Control - +
@@ -378,7 +39,7 @@ Connexion WiFi Externe - +
@@ -394,7 +55,7 @@ - + @@ -407,7 +68,7 @@ Configuration Hotspot - +
@@ -442,7 +103,7 @@ Appareils connectés - +
@@ -455,11 +116,11 @@ Logs système - +
- + @@ -469,254 +130,6 @@
- + - \ No newline at end of file + diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..3ea544a --- /dev/null +++ b/static/style.css @@ -0,0 +1,338 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + padding: 20px; +} + +.container { + max-width: 1200px; + margin: 0 auto; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + border-radius: 20px; + padding: 30px; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); +} + +.header { + text-align: center; + margin-bottom: 40px; + padding-bottom: 20px; + border-bottom: 2px solid #e0e0e0; +} + +.header h1 { + color: #333; + font-size: 2.5em; + margin-bottom: 10px; +} + +.status-indicator { + display: inline-flex; + align-items: center; + gap: 10px; + padding: 10px 20px; + border-radius: 25px; + font-weight: 500; + margin-top: 10px; +} + +.status-online { + background: #d4edda; + color: #155724; +} + +.status-offline { + background: #f8d7da; + color: #721c24; +} + +.status-dot { + width: 12px; + height: 12px; + border-radius: 50%; + background: currentColor; + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); + gap: 30px; + margin-bottom: 30px; +} + +.card { + background: white; + border-radius: 15px; + padding: 25px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.card:hover { + transform: translateY(-5px); + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15); +} + +.card h2 { + color: #333; + margin-bottom: 20px; + font-size: 1.4em; + display: flex; + align-items: center; + gap: 10px; +} + +.icon { + width: 24px; + height: 24px; + fill: currentColor; +} + +.form-group { + margin-bottom: 20px; +} + +.form-group label { + display: block; + margin-bottom: 8px; + color: #555; + font-weight: 500; +} + +.form-group input, .form-group select { + width: 100%; + padding: 12px 16px; + border: 2px solid #e0e0e0; + border-radius: 8px; + font-size: 16px; + transition: border-color 0.3s ease; +} + +.form-group input:focus, .form-group select:focus { + outline: none; + border-color: #667eea; +} + +.btn { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + padding: 12px 24px; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: transform 0.2s ease, box-shadow 0.2s ease; + width: 100%; +} + +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3); +} + +.btn:active { + transform: translateY(0); +} + +.btn-secondary { + background: #6c757d; + margin-top: 10px; +} + +.btn-danger { + background: #dc3545; +} + +.wifi-list { + max-height: 300px; + overflow-y: auto; + border: 1px solid #e0e0e0; + border-radius: 8px; + margin-bottom: 20px; +} + +.wifi-item { + padding: 12px 16px; + border-bottom: 1px solid #f0f0f0; + cursor: pointer; + transition: background-color 0.2s ease; + display: flex; + justify-content: space-between; + align-items: center; +} + +.wifi-item:hover { + background-color: #f8f9fa; +} + +.wifi-item:last-child { + border-bottom: none; +} + +.wifi-item.selected { + background-color: #e7f3ff; + border-left: 4px solid #667eea; +} + +.wifi-signal { + display: flex; + align-items: center; + gap: 8px; +} + +.signal-strength { + width: 20px; + height: 20px; + position: relative; +} + +.signal-bars { + display: flex; + gap: 2px; + align-items: flex-end; +} + +.signal-bar { + width: 3px; + background: #ccc; + border-radius: 1px; +} + +.signal-bar.active { + background: #28a745; +} + +.devices-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 15px; +} + +.device-card { + background: #f8f9fa; + border-radius: 10px; + padding: 15px; + text-align: center; + transition: transform 0.2s ease; +} + +.device-card:hover { + transform: scale(1.05); +} + +.device-icon { + width: 40px; + height: 40px; + margin: 0 auto 10px; + fill: #667eea; +} + +.log-container { + background: #1a1a1a; + color: #00ff00; + padding: 20px; + border-radius: 10px; + font-family: 'Courier New', monospace; + font-size: 14px; + max-height: 300px; + overflow-y: auto; + line-height: 1.4; +} + +.log-entry { + margin-bottom: 5px; +} + +.log-timestamp { + color: #888; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 20px; +} + +.stat-card { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 20px; + border-radius: 10px; + text-align: center; +} + +.stat-value { + font-size: 2em; + font-weight: bold; + margin-bottom: 5px; +} + +.stat-label { + font-size: 0.9em; + opacity: 0.9; +} + +.loading { + display: inline-block; + width: 20px; + height: 20px; + border: 3px solid #f3f3f3; + border-top: 3px solid #667eea; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.notification { + position: fixed; + top: 20px; + right: 20px; + padding: 15px 20px; + border-radius: 10px; + color: white; + font-weight: 500; + z-index: 1000; + transform: translateX(100%); + transition: transform 0.3s ease; +} + +.notification.show { + transform: translateX(0); +} + +.notification.success { + background: #28a745; +} + +.notification.error { + background: #dc3545; +} + +@media (max-width: 768px) { + .grid { + grid-template-columns: 1fr; + } + + .container { + padding: 20px; + } +}