Report hotspot config

This commit is contained in:
nemunaire 2026-01-01 17:32:46 +07:00
commit c443fce24f
8 changed files with 244 additions and 160 deletions

View file

@ -149,43 +149,6 @@ async function disconnectWifi() {
}
}
async function updateHotspot() {
const ssid = document.getElementById('hotspotName').value;
const password = document.getElementById('hotspotPassword').value;
const channel = parseInt(document.getElementById('hotspotChannel').value);
if (!ssid || ssid.length > 32) {
showToast('warning', 'Attention', 'SSID invalide (1-32 caractères)');
return;
}
if (!password || password.length < 8 || password.length > 63) {
showToast('warning', 'Attention', 'Mot de passe invalide (8-63 caractères)');
return;
}
showLoading(true);
try {
const response = await fetch('/api/hotspot/config', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ssid, password, channel })
});
if (response.ok) {
showToast('success', 'Configuration', 'Hotspot configuré avec succès');
} else {
throw new Error('Configuration failed');
}
} catch (error) {
console.error('Error configuring hotspot:', error);
showToast('error', 'Erreur', 'Échec de la configuration');
} finally {
showLoading(false);
}
}
async function toggleHotspot() {
const toggle = document.getElementById('hotspotToggle');
const enabled = toggle.checked;
@ -286,9 +249,12 @@ function updateStatusDisplay(status) {
const hotspotText = hotspotStatus.querySelector('.status-text');
const hotspotToggle = document.getElementById('hotspotToggle');
if (status.hotspotEnabled) {
const isHotspotEnabled = status.hotspotStatus && status.hotspotStatus.state === 'ENABLED';
if (isHotspotEnabled) {
hotspotDot.className = 'status-dot active';
hotspotText.textContent = 'Hotspot actif';
const numStations = status.hotspotStatus.numStations || 0;
hotspotText.textContent = `Hotspot actif (${numStations} client${numStations > 1 ? 's' : ''})`;
hotspotToggle.checked = true;
} else {
hotspotDot.className = 'status-dot offline';
@ -296,7 +262,10 @@ function updateStatusDisplay(status) {
hotspotToggle.checked = false;
}
appState.hotspotEnabled = status.hotspotEnabled;
appState.hotspotEnabled = isHotspotEnabled;
// Update hotspot details if available
updateHotspotDetails(status.hotspotStatus);
// Check if connectedSSID changed and refresh WiFi list if needed
const connectedSSIDChanged = appState.connectedSSID !== status.connectedSSID;
@ -409,11 +378,21 @@ function addLogEntry(log) {
const timestamp = new Date(log.timestamp).toLocaleTimeString('fr-FR');
logEntry.innerHTML = `
<span class="log-timestamp">${timestamp}</span>
<span class="log-source">[${escapeHtml(log.source)}]</span>
<span class="log-message">${escapeHtml(log.message)}</span>
`;
const timestampSpan = document.createElement('span');
timestampSpan.className = 'log-timestamp';
timestampSpan.textContent = timestamp;
const sourceSpan = document.createElement('span');
sourceSpan.className = 'log-source';
sourceSpan.textContent = `[${log.source}]`;
const messageSpan = document.createElement('span');
messageSpan.className = 'log-message';
messageSpan.textContent = log.message;
logEntry.appendChild(timestampSpan);
logEntry.appendChild(sourceSpan);
logEntry.appendChild(messageSpan);
logContainer.appendChild(logEntry);
@ -422,6 +401,55 @@ function addLogEntry(log) {
}
}
function createHotspotInfoItem(label, value) {
const item = document.createElement('div');
item.className = 'hotspot-info-item';
const labelSpan = document.createElement('span');
labelSpan.className = 'info-label';
labelSpan.textContent = label + ':';
const valueSpan = document.createElement('span');
valueSpan.className = 'info-value';
valueSpan.textContent = value;
item.appendChild(labelSpan);
item.appendChild(valueSpan);
return item;
}
function updateHotspotDetails(hotspotStatus) {
const detailsContainer = document.getElementById('hotspotDetails');
if (!detailsContainer) return;
// Clear existing content
detailsContainer.innerHTML = '';
if (!hotspotStatus || hotspotStatus.state !== 'ENABLED') {
detailsContainer.appendChild(createHotspotInfoItem('État', 'Inactif'));
return;
}
detailsContainer.appendChild(createHotspotInfoItem('État', hotspotStatus.state));
if (hotspotStatus.ssid) {
detailsContainer.appendChild(createHotspotInfoItem('SSID', hotspotStatus.ssid));
}
if (hotspotStatus.channel) {
detailsContainer.appendChild(createHotspotInfoItem('Canal', `${hotspotStatus.channel} (${hotspotStatus.frequency} MHz)`));
}
if (hotspotStatus.numStations !== undefined) {
detailsContainer.appendChild(createHotspotInfoItem('Clients connectés', hotspotStatus.numStations.toString()));
}
if (hotspotStatus.bssid) {
detailsContainer.appendChild(createHotspotInfoItem('BSSID', hotspotStatus.bssid));
}
}
// ===== WebSocket Functions =====
function connectWebSocket() {

View file

@ -133,7 +133,7 @@
<svg class="icon" viewBox="0 0 24 24" width="20" height="20">
<path fill="currentColor" d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4M12,6A6,6 0 0,0 6,12A6,6 0 0,0 12,18A6,6 0 0,0 18,12A6,6 0 0,0 12,6M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8Z"/>
</svg>
Configuration Hotspot
Hotspot Status
</h2>
<div class="toggle-switch">
<input type="checkbox" id="hotspotToggle" checked onchange="toggleHotspot()">
@ -141,54 +141,12 @@
</div>
</div>
<div class="form-group">
<label for="hotspotName">
<svg class="input-icon" viewBox="0 0 24 24" width="16" height="16">
<path fill="currentColor" d="M12,6A10,10 0 0,0 2,16C2,16.5 2.04,17 2.11,17.5L6,13.61C6,13.61 9.26,15.45 9.26,15.45L11.12,13C11.12,13 12.19,13.53 12.19,13.53C12.19,13.53 13.72,12 13.72,12L12,10.28C12,10.28 14.97,8.12 14.97,8.12L22,15.15C22,14.77 22,14.39 22,14A10,10 0 0,0 12,6Z"/>
</svg>
Nom du réseau (SSID)
</label>
<input type="text" id="hotspotName" value="TravelRouter" placeholder="Nom du hotspot" maxlength="32">
<div class="hotspot-details" id="hotspotDetails">
<div class="hotspot-info-item">
<span class="info-label">État:</span>
<span class="info-value">Chargement...</span>
</div>
</div>
<div class="form-group">
<label for="hotspotPassword">
<svg class="input-icon" viewBox="0 0 24 24" width="16" height="16">
<path fill="currentColor" d="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"/>
</svg>
Mot de passe (8-63 caractères)
</label>
<input type="password" id="hotspotPassword" value="travel123" placeholder="Mot de passe du hotspot" minlength="8" maxlength="63">
</div>
<div class="form-group">
<label for="hotspotChannel">
<svg class="input-icon" viewBox="0 0 24 24" width="16" height="16">
<path fill="currentColor" d="M9,10H7V17H9V10M13,10H11V17H13V10M17,10H15V17H17V10M19,3H18V1H16V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,19H5V8H19V19Z"/>
</svg>
Canal WiFi (2.4GHz)
</label>
<select id="hotspotChannel">
<option value="1">Canal 1 (2412 MHz)</option>
<option value="2">Canal 2 (2417 MHz)</option>
<option value="3">Canal 3 (2422 MHz)</option>
<option value="4">Canal 4 (2427 MHz)</option>
<option value="5">Canal 5 (2432 MHz)</option>
<option value="6" selected>Canal 6 (2437 MHz)</option>
<option value="7">Canal 7 (2442 MHz)</option>
<option value="8">Canal 8 (2447 MHz)</option>
<option value="9">Canal 9 (2452 MHz)</option>
<option value="10">Canal 10 (2457 MHz)</option>
<option value="11">Canal 11 (2462 MHz)</option>
</select>
</div>
<button class="btn btn-primary" onclick="updateHotspot()">
<svg viewBox="0 0 24 24" width="18" height="18">
<path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"/>
</svg>
Mettre à jour la configuration
</button>
</div>
</div>

View file

@ -747,6 +747,39 @@ body {
background: var(--text-secondary);
}
/* Hotspot Details */
.hotspot-details {
margin-top: 1.5rem;
padding: 1rem;
background: var(--background);
border-radius: var(--radius-md);
border: 1px solid var(--border-color);
}
.hotspot-info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 0;
border-bottom: 1px solid var(--border-color);
}
.hotspot-info-item:last-child {
border-bottom: none;
}
.info-label {
font-weight: 500;
color: var(--text-secondary);
font-size: 0.875rem;
}
.info-value {
font-weight: 600;
color: var(--text-primary);
font-size: 0.875rem;
}
/* Responsive Design */
@media (max-width: 1024px) {
.grid {