Discovered Networks
+| SSID | +Ch | +Signal | +Security | +Clients | +
|---|---|---|---|---|
|
+ Start scanning to discover networks
+ |
+ ||||
diff --git a/static/css/index.css b/static/css/index.css index 7c449e7..6cddb5b 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -3143,120 +3143,515 @@ header h1 .tagline { background: var(--text-dim); } -/* WiFi Layout Container - side by side layout */ +/* WiFi Layout Container - 3-column layout */ .wifi-layout-container { display: flex; - gap: 15px; + flex-direction: column; + gap: 10px; padding: 15px; background: var(--bg-secondary); margin: 0 15px 10px 15px; border: 1px solid var(--border-color); - height: calc(100vh - 200px); /* Take most of the available height */ + height: calc(100vh - 200px); min-height: 400px; } -/* WiFi Visualizations */ -.wifi-visuals { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; - flex: 1; - overflow-y: auto; - padding-right: 10px; -} - -/* WiFi Device List (right column) */ -.wifi-device-list { - width: 350px; - min-width: 300px; - background: var(--bg-primary); +/* WiFi Status Bar */ +.wifi-status-bar { + display: flex; + gap: 20px; + padding: 8px 12px; + background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 4px; + font-size: 11px; +} + +.wifi-status-item { display: flex; - flex-direction: column; + align-items: center; + gap: 6px; +} + +.wifi-status-label { + color: var(--text-dim); +} + +.wifi-status-value { + color: var(--accent-cyan); + font-weight: 600; +} + +.wifi-status-indicator { + width: 8px; + height: 8px; + border-radius: 50%; + background: #666; +} + +.wifi-status-indicator.idle { background: #666; } +.wifi-status-indicator.scanning { background: var(--accent-green); animation: pulse 1s infinite; } +.wifi-status-indicator.error { background: var(--accent-red); } + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +/* WiFi Main Content - 3 columns */ +.wifi-main-content { + display: grid; + grid-template-columns: 1fr 280px 280px; + gap: 10px; + flex: 1; + min-height: 0; overflow: hidden; } -.wifi-device-list-header { +/* WiFi Networks Panel (LEFT) */ +.wifi-networks-panel { + display: flex; + flex-direction: column; + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 4px; + overflow: hidden; +} + +.wifi-networks-header { padding: 10px 12px; background: var(--bg-tertiary); border-bottom: 1px solid var(--border-color); display: flex; justify-content: space-between; align-items: center; + flex-wrap: wrap; + gap: 8px; } -.wifi-device-list-header h5 { +.wifi-networks-header h5 { margin: 0; color: var(--accent-cyan); font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.5px; } -.wifi-device-list-header .device-count { +.wifi-network-filters { + display: flex; + gap: 4px; +} + +.wifi-filter-btn { + padding: 4px 8px; + font-size: 10px; + background: var(--bg-secondary); + border: 1px solid var(--border-color); + border-radius: 3px; color: var(--text-dim); + cursor: pointer; + transition: all 0.2s; +} + +.wifi-filter-btn:hover { + background: var(--bg-tertiary); + color: var(--text-primary); +} + +.wifi-filter-btn.active { + background: var(--accent-cyan); + color: #000; + border-color: var(--accent-cyan); +} + +.wifi-networks-table-wrapper { + flex: 1; + overflow-y: auto; +} + +.wifi-networks-table { + width: 100%; + border-collapse: collapse; font-size: 11px; } -.wifi-device-list-content { +.wifi-networks-table thead { + position: sticky; + top: 0; + background: var(--bg-tertiary); + z-index: 1; +} + +.wifi-networks-table th { + padding: 8px 10px; + text-align: left; + color: var(--text-dim); + font-weight: 500; + border-bottom: 1px solid var(--border-color); + white-space: nowrap; + cursor: pointer; +} + +.wifi-networks-table th:hover { + color: var(--accent-cyan); +} + +.wifi-networks-table th.sortable::after { + content: ' \2195'; + opacity: 0.3; +} + +.wifi-networks-table td { + padding: 8px 10px; + border-bottom: 1px solid var(--border-color); + vertical-align: middle; +} + +.wifi-network-row { + cursor: pointer; + transition: background 0.15s; +} + +.wifi-network-row:hover { + background: rgba(0, 255, 255, 0.05); +} + +.wifi-network-row.selected { + background: rgba(0, 255, 255, 0.1); + border-left: 2px solid var(--accent-cyan); +} + +.wifi-network-row .essid { + font-weight: 500; + color: var(--text-primary); +} + +.wifi-network-row .badge { + display: inline-block; + padding: 2px 5px; + font-size: 9px; + border-radius: 3px; + margin-left: 6px; +} + +.wifi-network-row .badge-hidden { + background: rgba(255, 165, 0, 0.2); + color: var(--accent-orange); +} + +.wifi-network-row .badge-new { + background: rgba(0, 255, 0, 0.2); + color: var(--accent-green); +} + +.wifi-network-row .rssi-value { + font-family: monospace; + font-weight: 600; +} + +.wifi-network-row .rssi-value.signal-strong { color: var(--accent-green); } +.wifi-network-row .rssi-value.signal-medium { color: var(--accent-yellow); } +.wifi-network-row .rssi-value.signal-weak { color: var(--accent-orange); } +.wifi-network-row .rssi-value.signal-very-weak { color: var(--accent-red); } + +.wifi-network-row .security-badge { + display: inline-block; + padding: 2px 6px; + font-size: 9px; + border-radius: 3px; +} + +.wifi-network-row .security-badge.security-wpa3 { background: rgba(0, 255, 0, 0.15); color: var(--accent-green); } +.wifi-network-row .security-badge.security-wpa { background: rgba(0, 255, 255, 0.15); color: var(--accent-cyan); } +.wifi-network-row .security-badge.security-wep { background: rgba(255, 165, 0, 0.15); color: var(--accent-orange); } +.wifi-network-row .security-badge.security-open { background: rgba(255, 0, 0, 0.15); color: var(--accent-red); } + +.wifi-network-placeholder td { + text-align: center; + padding: 40px 20px; +} + +.wifi-network-placeholder .placeholder-text { + color: var(--text-dim); +} + +/* WiFi Radar Panel (CENTER) */ +.wifi-radar-panel { + display: flex; + flex-direction: column; + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 4px; + padding: 12px; +} + +.wifi-radar-panel h5 { + margin: 0 0 10px 0; + color: var(--accent-cyan); + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.wifi-radar-container { flex: 1; - overflow-y: auto; - padding: 10px; + display: flex; + align-items: center; + justify-content: center; + min-height: 200px; } -/* WiFi network cards in device list - more compact */ -.wifi-network-card { - margin-bottom: 8px; - padding: 10px !important; +.wifi-zone-summary { + display: flex; + justify-content: center; + gap: 20px; + padding-top: 12px; + border-top: 1px solid var(--border-color); + margin-top: 12px; } -.wifi-network-card .header { - font-size: 12px; +.wifi-zone { + text-align: center; } -/* WiFi client cards in device list */ -.wifi-client-card { - margin-bottom: 8px; - padding: 10px !important; - border-left-color: var(--accent-purple) !important; - background: rgba(153, 51, 255, 0.05); +.wifi-zone-count { + display: block; + font-size: 20px; + font-weight: 600; + line-height: 1; } -.wifi-client-card .header { - font-size: 12px; -} - -.wifi-client-card .sensor-data { +.wifi-zone-label { font-size: 10px; + color: var(--text-dim); } -.wifi-network-card .sensor-data { +.wifi-zone.near .wifi-zone-count { color: var(--accent-green); } +.wifi-zone.mid .wifi-zone-count { color: var(--accent-yellow); } +.wifi-zone.far .wifi-zone-count { color: var(--accent-red); } + +/* WiFi Analysis Panel (RIGHT) */ +.wifi-analysis-panel { + display: flex; + flex-direction: column; + gap: 10px; +} + +.wifi-channel-section, +.wifi-security-section { + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 4px; + padding: 12px; +} + +.wifi-channel-section { + flex: 1; +} + +.wifi-channel-section h5, +.wifi-security-section h5 { + margin: 0 0 10px 0; + color: var(--accent-cyan); + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.wifi-channel-tabs { + display: flex; + gap: 4px; + margin-bottom: 10px; +} + +.channel-band-tab { + flex: 1; + padding: 6px 10px; font-size: 10px; + background: var(--bg-tertiary); + border: 1px solid var(--border-color); + border-radius: 4px; + color: var(--text-dim); + cursor: pointer; + transition: all 0.2s; } -.wifi-network-card .preset-btn { - font-size: 9px !important; - padding: 3px 6px !important; +.channel-band-tab:hover { + background: var(--bg-secondary); +} + +.channel-band-tab.active { + background: var(--accent-cyan); + color: #000; + border-color: var(--accent-cyan); +} + +.wifi-channel-chart { + min-height: 120px; +} + +.wifi-security-stats { + display: flex; + flex-direction: column; + gap: 6px; +} + +.wifi-security-item { + display: flex; + align-items: center; + gap: 8px; + font-size: 11px; +} + +.wifi-security-dot { + width: 10px; + height: 10px; + border-radius: 2px; +} + +.wifi-security-item.wpa3 .wifi-security-dot { background: var(--accent-green); } +.wifi-security-item.wpa2 .wifi-security-dot { background: var(--accent-cyan); } +.wifi-security-item.wep .wifi-security-dot { background: var(--accent-orange); } +.wifi-security-item.open .wifi-security-dot { background: var(--accent-red); } + +.wifi-security-count { + margin-left: auto; + font-weight: 600; + color: var(--text-primary); +} + +/* WiFi Detail Drawer */ +.wifi-detail-drawer { + display: none; + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 4px; + overflow: hidden; +} + +.wifi-detail-drawer.open { + display: block; +} + +.wifi-detail-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 15px; + background: var(--bg-tertiary); + border-bottom: 1px solid var(--border-color); +} + +.wifi-detail-title { + display: flex; + flex-direction: column; + gap: 2px; +} + +.wifi-detail-essid { + font-size: 14px; + font-weight: 600; + color: var(--text-primary); +} + +.wifi-detail-bssid { + font-size: 11px; + font-family: monospace; + color: var(--text-dim); +} + +.wifi-detail-close { + background: none; + border: none; + color: var(--text-dim); + font-size: 20px; + cursor: pointer; + padding: 0 5px; +} + +.wifi-detail-close:hover { + color: var(--accent-red); +} + +.wifi-detail-content { + padding: 15px; +} + +.wifi-detail-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 15px; +} + +.wifi-detail-stat { + display: flex; + flex-direction: column; + gap: 3px; +} + +.wifi-detail-stat .label { + font-size: 10px; + color: var(--text-dim); + text-transform: uppercase; +} + +.wifi-detail-stat .value { + font-size: 13px; + font-weight: 500; + color: var(--text-primary); +} + +.wifi-detail-clients { + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid var(--border-color); +} + +.wifi-detail-clients h6 { + margin: 0 0 10px 0; + font-size: 11px; + color: var(--accent-cyan); + text-transform: uppercase; +} + +/* WiFi Responsive */ +@media (max-width: 1400px) { + .wifi-main-content { + grid-template-columns: 1fr 240px 240px; + } } @media (max-width: 1200px) { .wifi-layout-container { - flex-direction: column; height: auto; max-height: calc(100vh - 200px); } - .wifi-visuals { - grid-template-columns: 1fr; - max-height: 50vh; + .wifi-main-content { + grid-template-columns: 1fr 1fr; + grid-template-rows: auto auto; } - .wifi-device-list { - width: 100%; - min-width: auto; + .wifi-networks-panel { + grid-column: span 2; max-height: 300px; } } +@media (max-width: 768px) { + .wifi-main-content { + grid-template-columns: 1fr; + } + + .wifi-networks-panel { + grid-column: span 1; + } + + .wifi-detail-grid { + grid-template-columns: repeat(2, 1fr); + } +} + /* Bluetooth Layout Container */ .bt-layout-container { display: flex; diff --git a/static/js/modes/wifi.js b/static/js/modes/wifi.js index 4141e1b..c02bca0 100644 --- a/static/js/modes/wifi.js +++ b/static/js/modes/wifi.js @@ -95,13 +95,13 @@ const WiFiMode = (function() { scanModeQuick: document.getElementById('wifiScanModeQuick'), scanModeDeep: document.getElementById('wifiScanModeDeep'), - // Status + // Status bar scanStatus: document.getElementById('wifiScanStatus'), networkCount: document.getElementById('wifiNetworkCount'), clientCount: document.getElementById('wifiClientCount'), hiddenCount: document.getElementById('wifiHiddenCount'), - // Network list + // Network table networkTable: document.getElementById('wifiNetworkTable'), networkTableBody: document.getElementById('wifiNetworkTableBody'), networkFilters: document.getElementById('wifiNetworkFilters'), @@ -111,9 +111,30 @@ const WiFiMode = (function() { channelChart: document.getElementById('wifiChannelChart'), channelBandTabs: document.getElementById('wifiChannelBandTabs'), - // Detail panel - detailPanel: document.getElementById('wifiDetailPanel'), - detailContent: document.getElementById('wifiDetailContent'), + // Zone summary + zoneImmediate: document.getElementById('wifiZoneImmediate'), + zoneNear: document.getElementById('wifiZoneNear'), + zoneFar: document.getElementById('wifiZoneFar'), + + // Security counts + wpa3Count: document.getElementById('wpa3Count'), + wpa2Count: document.getElementById('wpa2Count'), + wepCount: document.getElementById('wepCount'), + openCount: document.getElementById('openCount'), + + // Detail drawer + detailDrawer: document.getElementById('wifiDetailDrawer'), + detailEssid: document.getElementById('wifiDetailEssid'), + detailBssid: document.getElementById('wifiDetailBssid'), + detailRssi: document.getElementById('wifiDetailRssi'), + detailChannel: document.getElementById('wifiDetailChannel'), + detailBand: document.getElementById('wifiDetailBand'), + detailSecurity: document.getElementById('wifiDetailSecurity'), + detailCipher: document.getElementById('wifiDetailCipher'), + detailVendor: document.getElementById('wifiDetailVendor'), + detailClients: document.getElementById('wifiDetailClients'), + detailFirstSeen: document.getElementById('wifiDetailFirstSeen'), + detailClientList: document.getElementById('wifiDetailClientList'), // Interface select interfaceSelect: document.getElementById('wifiInterfaceSelect'), @@ -747,72 +768,56 @@ const WiFiMode = (function() { // ========================================================================== function updateDetailPanel(bssid) { - if (!elements.detailPanel || !elements.detailContent) return; + if (!elements.detailDrawer) return; const network = networks.get(bssid); if (!network) { - elements.detailPanel.style.display = 'none'; + closeDetail(); return; } - elements.detailPanel.style.display = 'block'; - elements.detailContent.innerHTML = ` -
${escapeHtml(network.bssid)}
-