v1.4.5 — Page WiFi: oublier réseau + badge hotspot sidebar + refonte UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
PaulVua
2026-03-17 17:28:46 +01:00
parent 5a2b3bb19d
commit 6e17f39a2c
7 changed files with 549 additions and 210 deletions

View File

@@ -54,56 +54,143 @@
<h3>Status
<span id="wifi-status" class="badge">Loading...</span>
<button id="btn-forget-wifi" class="btn btn-outline-danger btn-sm ms-2" style="display:none;" onclick="wifi_forget()">Oublier le réseau</button>
</h3>
<div class="row mb-3">
<div class="col-sm-4">
<div class="card text-dark bg-light">
<!-- Connection Info Card (shown when connected to WiFi) -->
<div class="col-sm-6" id="card-connection-info" style="display:none;">
<div class="card border-success">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">Connexion WiFi</h5>
</div>
<div class="card-body">
<h5 class="card-title">WIFI / Ethernet</h5>
<p class="card-text">General information.</p>
<button class="btn btn-primary" onclick="get_internet()">Get Data</button>
<table class="table table-striped-columns">
<tbody id="data-table-body_internet_general"></tbody>
<div id="connection-info-loading" class="text-center py-3">
<div class="spinner-border spinner-border-sm text-primary" role="status"></div>
<span class="ms-2">Chargement...</span>
</div>
<table class="table table-sm mb-0" id="connection-info-table" style="display:none;">
<tbody>
<tr>
<td class="text-muted" style="width:40%">SSID</td>
<td><strong id="info-ssid">-</strong></td>
</tr>
<tr>
<td class="text-muted">Signal</td>
<td><span id="info-signal-bar"></span> <span id="info-signal">-</span></td>
</tr>
<tr>
<td class="text-muted">Adresse IP</td>
<td><code id="info-ip">-</code></td>
</tr>
<tr>
<td class="text-muted">Passerelle</td>
<td><code id="info-gateway">-</code></td>
</tr>
<tr>
<td class="text-muted">Hostname</td>
<td><code id="info-hostname">-</code></td>
</tr>
<tr>
<td class="text-muted">Frequence</td>
<td id="info-freq">-</td>
</tr>
<tr>
<td class="text-muted">Securite</td>
<td id="info-security">-</td>
</tr>
</tbody>
</table>
<button class="btn btn-outline-primary btn-sm mt-2" onclick="get_internet()">Rafraichir</button>
</div>
</div>
</div>
<div class="col-sm-8">
<div class="card text-dark bg-light">
<!-- Ethernet Card -->
<div class="col-sm-6" id="card-ethernet">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Ethernet</h5>
</div>
<div class="card-body">
<h5 class="card-title">Wifi Scan</h5>
<p class="card-text">Scan des réseaux WIFI disponibles.</p>
<button class="btn btn-primary" onclick="wifi_scan()">Scan</button>
<table class="table">
<tbody id="data-table-body_wifi_scan"></tbody>
</table>
<table class="table table-sm mb-0">
<tbody>
<tr>
<td class="text-muted" style="width:40%">Etat</td>
<td id="info-eth-status">-</td>
</tr>
<tr>
<td class="text-muted">Adresse IP</td>
<td><code id="info-eth-ip">-</code></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Modal WIFI PASSWORD -->
<!-- filled with JS -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="myModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="myModalBody">
...
</div>
<div class="modal-footer" id="myModalFooter">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
<!-- Hotspot Info Card (shown when in hotspot mode) -->
<div class="col-sm-6" id="card-hotspot-info" style="display:none;">
<div class="card border-warning">
<div class="card-header bg-warning">
<h5 class="card-title mb-0">Mode Hotspot</h5>
</div>
<div class="card-body">
<p class="mb-1">Le capteur n'est connecte a aucun reseau WiFi.</p>
<p class="text-muted mb-0">Utilisez le scan ci-dessous pour vous connecter a un reseau.</p>
</div>
</div>
</div>
</div>
<!-- WiFi Scan Card (hidden when connected) -->
<div class="row mb-3" id="card-wifi-scan" style="display:none;">
<div class="col-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Reseaux WiFi disponibles</h5>
<button class="btn btn-primary btn-sm" onclick="wifi_scan()">Scan</button>
</div>
<div class="card-body">
<div id="wifi-scan-empty" class="text-center text-muted py-3">
Cliquez sur "Scan" pour rechercher les reseaux WiFi.
</div>
<table class="table table-hover mb-0" id="wifi-scan-table" style="display:none;">
<thead>
<tr>
<th>SSID</th>
<th>Signal</th>
<th>Securite</th>
<th></th>
</tr>
</thead>
<tbody id="data-table-body_wifi_scan"></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Modal WIFI PASSWORD -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="myModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="myModalBody">
...
</div>
<div class="modal-footer" id="myModalFooter">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<div>
@@ -147,34 +234,67 @@
});
function get_internet(){
console.log("Getting internet general infos");
$.ajax({
url: 'launcher.php?type=internet',
dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log(response);
let tableBody = document.getElementById('data-table-body_internet_general');
tableBody.innerHTML = ''; // Clear existing table content
function load_ethernet_info() {
$.ajax({
url: 'launcher.php?type=internet',
dataType: 'json',
method: 'GET',
success: function(response) {
const eth = response.ethernet;
document.getElementById('info-eth-status').textContent = eth.connection || '-';
document.getElementById('info-eth-ip').textContent = eth.IP || '-';
}
});
}
// Iterate through the data and create rows
for (let key in response) {
let row = `
<tr>
<td>${key}</td>
<td>${response[key].connection}</td>
<td>${response[key].IP ? response[key].IP : "No IP"}</td>
</tr>
`;
tableBody.innerHTML += row; // Append row to table body
}
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function getSignalBadge(signal) {
const val = parseInt(signal, 10);
if (isNaN(val)) return '';
let color, label;
if (val >= 70) { color = 'success'; label = 'Excellent'; }
else if (val >= 50) { color = 'primary'; label = 'Bon'; }
else if (val >= 30) { color = 'warning'; label = 'Faible'; }
else { color = 'danger'; label = 'Tres faible'; }
return `<span class="badge text-bg-${color}">${val}% — ${label}</span>`;
}
function get_internet(){
console.log("Getting internet general infos");
document.getElementById('connection-info-loading').style.display = '';
document.getElementById('connection-info-table').style.display = 'none';
$.ajax({
url: 'launcher.php?type=internet',
dataType: 'json',
method: 'GET',
success: function(response) {
console.log(response);
const wifi = response.wifi;
const eth = response.ethernet;
// WiFi info
document.getElementById('info-ssid').textContent = wifi.ssid || '-';
document.getElementById('info-signal').innerHTML = wifi.signal ? getSignalBadge(wifi.signal) : '-';
document.getElementById('info-ip').textContent = wifi.IP || '-';
document.getElementById('info-gateway').textContent = wifi.gateway || '-';
document.getElementById('info-hostname').textContent = wifi.hostname || '-';
document.getElementById('info-freq').textContent = wifi.frequency ? wifi.frequency + ' MHz' : '-';
document.getElementById('info-security').textContent = wifi.security || '-';
// Ethernet info
const ethStatus = eth.connection || '-';
document.getElementById('info-eth-status').textContent = ethStatus;
document.getElementById('info-eth-ip').textContent = eth.IP || '-';
document.getElementById('connection-info-loading').style.display = 'none';
document.getElementById('connection-info-table').style.display = '';
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
document.getElementById('connection-info-loading').innerHTML = '<span class="text-danger">Erreur de chargement</span>';
}
});
}
function wifi_connect(SSID, PASS){
@@ -293,151 +413,208 @@ function get_internet(){
}, 30000);
}
function wifi_forget(){
if (!confirm('Oublier le réseau WiFi actuel et passer en mode hotspot ?')) return;
$.ajax({
url: 'launcher.php?type=wifi_forget',
dataType: 'json',
method: 'GET',
success: function(response) {
console.log(response);
showForgetStatus(response);
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
alert('Error: Could not forget WiFi network');
}
});
}
function showForgetStatus(response) {
const lang = localStorage.getItem('language') || 'fr';
const instructions = response.instructions[lang] || response.instructions['fr'];
const overlay = document.createElement('div');
overlay.id = 'connection-status-overlay';
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
color: white;
`;
overlay.innerHTML = `
<div style="max-width: 600px; padding: 40px; text-align: center;">
<div class="spinner-border text-warning mb-4" role="status" style="width: 4rem; height: 4rem;">
<span class="visually-hidden">Loading...</span>
</div>
<h2 class="mb-4">${instructions.title}</h2>
<div class="alert alert-info text-start" role="alert">
<ol class="mb-0" style="padding-left: 20px;">
<li class="mb-2"><strong>${instructions.step1}</strong></li>
<li class="mb-2">${instructions.step2}</li>
<li class="mb-2">${instructions.step3}</li>
<li class="mb-2">${instructions.step4}</li>
</ol>
</div>
<div class="alert alert-warning text-start" role="alert">
<strong>Important:</strong> ${instructions.warning}
</div>
<div class="mt-4">
<p class="text-muted">
${lang === 'fr' ? 'Hotspot' : 'Hotspot'}:
<strong class="text-white">${response.deviceName}</strong>
</p>
</div>
</div>
`;
document.body.appendChild(overlay);
setTimeout(() => {
if (document.getElementById('connection-status-overlay')) {
document.getElementById('connection-status-overlay').remove();
}
}, 30000);
}
function wifi_scan(){
console.log("Scanning Wifi");
$.ajax({
url: 'launcher.php?type=wifi_scan',
dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log(response);
const tableBody = document.getElementById("data-table-body_wifi_scan");
console.log("Scanning Wifi");
document.getElementById('wifi-scan-empty').innerHTML = '<div class="spinner-border spinner-border-sm text-primary" role="status"></div> Scan en cours...';
// Clear the existing table body
tableBody.innerHTML = "";
$.ajax({
url: 'launcher.php?type=wifi_scan',
dataType: 'json',
method: 'GET',
success: function(response) {
console.log(response);
const tableBody = document.getElementById("data-table-body_wifi_scan");
tableBody.innerHTML = "";
// Loop through the wifiNetworks array and create rows
response.forEach(network => {
const row = document.createElement("tr");
if (response.length === 0) {
document.getElementById('wifi-scan-empty').textContent = 'Aucun reseau WiFi trouve.';
document.getElementById('wifi-scan-empty').style.display = '';
document.getElementById('wifi-scan-table').style.display = 'none';
return;
}
// Create and append cells for SSID, BARS, and SIGNAL
const ssidCell = document.createElement("td");
// Truncate SSID to 25 characters
const truncatedSSID = network.SSID.length > 20 ? network.SSID.substring(0, 20) + '...' : network.SSID;
ssidCell.textContent = truncatedSSID;
row.appendChild(ssidCell);
document.getElementById('wifi-scan-empty').style.display = 'none';
document.getElementById('wifi-scan-table').style.display = '';
/*
const signalCell = document.createElement("td");
signalCell.textContent = network.SIGNAL;
row.appendChild(signalCell);
*/
response.forEach(network => {
const row = document.createElement("tr");
// Create a button
const buttonCell = document.createElement("td");
const button = document.createElement("button");
button.textContent = "Connect"; // Button text
button.classList.add("btn", "btn-primary"); // Bootstrap button classes
// SSID
const ssidCell = document.createElement("td");
const truncatedSSID = network.SSID.length > 25 ? network.SSID.substring(0, 25) + '...' : network.SSID;
ssidCell.textContent = truncatedSSID;
row.appendChild(ssidCell);
// Determine button color based on SIGNAL value
const signalValue = parseInt(network.SIGNAL, 10); // Assuming SIGNAL is a numeric value
// Calculate color based on the signal strength
let buttonColor;
if (signalValue >= 100) {
buttonColor = "success"; // Green for strong signal
} else if (signalValue >= 50) {
buttonColor = "warning"; // Yellow for moderate signal
} else {
buttonColor = "danger"; // Red for weak signal
}
// Add Bootstrap button classes along with color
button.classList.add("btn", `btn-${buttonColor}`);
// Signal with badge
const signalCell = document.createElement("td");
signalCell.innerHTML = getSignalBadge(network.SIGNAL);
row.appendChild(signalCell);
// Security
const securityCell = document.createElement("td");
securityCell.textContent = network.SECURITY || '--';
securityCell.classList.add('text-muted');
row.appendChild(securityCell);
//Trigger function as soon as the button is clicked
button.addEventListener("click", () => wifi_connect(network.SSID));
// Connect button
const buttonCell = document.createElement("td");
buttonCell.classList.add('text-end');
const button = document.createElement("button");
button.textContent = "Connecter";
button.classList.add("btn", "btn-primary", "btn-sm");
button.addEventListener("click", () => wifi_connect(network.SSID));
buttonCell.appendChild(button);
row.appendChild(buttonCell);
// Append the button to the button cell
buttonCell.appendChild(button);
row.appendChild(buttonCell);
// Append the row to the table body
tableBody.appendChild(row);
});
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
tableBody.appendChild(row);
});
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
document.getElementById('wifi-scan-empty').innerHTML = '<span class="text-danger">Erreur lors du scan</span>';
}
});
}
function confirmSubmit() {
// You can display a simple confirmation message or customize the behavior
return confirm("Are you sure you want to connect to this Wi-Fi network?");
}
window.onload = function() {
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
.then(response => response.json()) // Parse response as JSON
.then(data => {
console.log("Getting config file (onload)");
//get device ID
const deviceID = data.deviceID.trim().toUpperCase();
//document.getElementById('pageTitle_plus_ID').innerText = 'token: ' + deviceID;
$.ajax({
url: 'launcher.php?type=get_config_sqlite',
dataType: 'json',
method: 'GET',
success: function(data) {
console.log("Getting SQLite config table (wifi page):");
console.log(data);
//get device Name
const deviceName = data.deviceName;
// WiFi connection status — toggle cards
const WIFI_statusElement = document.getElementById("wifi-status");
console.log("WIFI is: " + data.WIFI_status);
// Function to update sidebar device name
function updateSidebarDeviceName(deviceName) {
const elements = document.querySelectorAll('.sideBar_sensorName');
if (elements.length > 0) {
elements.forEach((element) => {
element.innerText = deviceName;
});
console.log("Device name updated in sidebar:", deviceName);
}
}
if (data.WIFI_status === "connected") {
WIFI_statusElement.textContent = "Connected";
WIFI_statusElement.className = "badge text-bg-success";
document.getElementById('btn-forget-wifi').style.display = 'inline-block';
document.getElementById('card-connection-info').style.display = '';
document.getElementById('card-hotspot-info').style.display = 'none';
document.getElementById('card-wifi-scan').style.display = 'none';
// Auto-load connection details
get_internet();
} else if (data.WIFI_status === "hotspot") {
WIFI_statusElement.textContent = "Hotspot";
WIFI_statusElement.className = "badge text-bg-warning";
document.getElementById('btn-forget-wifi').style.display = 'none';
document.getElementById('card-connection-info').style.display = 'none';
document.getElementById('card-hotspot-info').style.display = '';
document.getElementById('card-wifi-scan').style.display = '';
} else {
WIFI_statusElement.textContent = "Unknown";
WIFI_statusElement.className = "badge text-bg-secondary";
document.getElementById('btn-forget-wifi').style.display = 'none';
document.getElementById('card-connection-info').style.display = 'none';
document.getElementById('card-hotspot-info').style.display = 'none';
document.getElementById('card-wifi-scan').style.display = '';
}
// Update device name immediately and with retries to handle async sidebar loading
if (deviceName) {
updateSidebarDeviceName(deviceName);
// Retry after delays to catch async sidebar load
setTimeout(() => updateSidebarDeviceName(deviceName), 100);
setTimeout(() => updateSidebarDeviceName(deviceName), 500);
//device name html page title
document.title = deviceName;
}
//get wifi connection status
const WIFI_statusElement = document.getElementById("wifi-status");
console.log("WIFI is: " + data.WIFI_status);
if (data.WIFI_status === "connected") {
WIFI_statusElement.textContent = "Connected";
WIFI_statusElement.className = "badge text-bg-success";
} else if (data.WIFI_status === "hotspot") {
WIFI_statusElement.textContent = "Hotspot";
WIFI_statusElement.className = "badge text-bg-warning";
} else {
WIFI_statusElement.textContent = "Unknown";
WIFI_statusElement.className = "badge text-bg-secondary";
}
//get local RTC
$.ajax({
url: 'launcher.php?type=RTC_time',
dataType: 'text', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log("Local RTC: " + response);
const RTC_Element = document.getElementById("RTC_time");
RTC_Element.textContent = response;
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
})
.catch(error => console.error('Error loading config.json:', error));
// Always load ethernet info
load_ethernet_info();
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
// Load RTC time
$.ajax({
url: 'launcher.php?type=RTC_time',
dataType: 'text',
method: 'GET',
success: function(response) {
const RTC_Element = document.getElementById("RTC_time");
if (RTC_Element) RTC_Element.textContent = response;
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
</script>