Files
nebuleair_pro_4g/html/wifi.html
PaulVua ea2642685c fix(ui): logo dynamique ne s'affichait pas (innerHTML n'exécute pas les scripts)
Le script dans topbar.html ne s'exécutait pas car innerHTML ignore les
balises <script>. Déplacé la logique dans un fichier JS séparé
(topbar-logo.js) avec MutationObserver pour détecter l'insertion du topbar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:43:38 +01:00

446 lines
18 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NebuleAir</title>
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<style>
body {
overflow-x: hidden;
}
#sidebar a.nav-link {
position: relative;
display: flex;
align-items: center;
}
#sidebar a.nav-link:hover {
background-color: rgba(0, 0, 0, 0.5);
}
#sidebar a.nav-link svg {
margin-right: 8px; /* Add spacing between icons and text */
}
#sidebar {
transition: transform 0.3s ease-in-out;
}
.offcanvas-backdrop {
z-index: 1040;
}
</style>
</head>
<body>
<!-- Topbar -->
<span id="topbar"></span>
<!-- Sidebar Offcanvas for Mobile -->
<div class="offcanvas offcanvas-start text-white bg-dark" tabindex="-1" id="sidebarOffcanvas" aria-labelledby="sidebarOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="sidebarOffcanvasLabel">NebuleAir</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body" id="sidebar_mobile">
</div>
</div>
<div class="container-fluid mt-5">
<div class="row">
<aside class="col-md-2 col-lg-1 d-none d-md-block vh-100 position-fixed bg-dark text-white" id="sidebar">
</aside>
<!-- Main content -->
<main class="col-md-10 ms-sm-auto col-lg-11 offset-md-2 offset-lg-1 px-md-4">
<h1 class="mt-4">Connection WIFI</h1>
<p>La connexion WIFI n'est pas obligatoire mais elle vous permet d'effectuer des mises à jour et d'activer le contrôle à distance.</p>
<h3>Status
<span id="wifi-status" class="badge">Loading...</span>
</h3>
<div class="row mb-3">
<div class="col-sm-4">
<div class="card text-dark bg-light">
<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>
</table>
</div>
</div>
</div>
<div class="col-sm-8">
<div class="card text-dark bg-light">
<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>
</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>
</div>
</div>
<div>
</main>
</div>
</div>
<!-- JAVASCRIPT -->
<!-- Link Ajax locally -->
<script src="assets/jquery/jquery-3.7.1.min.js"></script>
<!-- Link Bootstrap JS and Popper.js locally -->
<script src="assets/js/bootstrap.bundle.js"></script>
<!-- i18n translation system -->
<script src="assets/js/i18n.js"></script>
<script src="assets/js/topbar-logo.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
console.log("DOMContentLoaded");
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(error => console.error(`Error loading ${file}:`, error));
});
});
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
// 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 wifi_connect(SSID, PASS){
console.log("Connecting to wifi");
console.log(SSID);
console.log(PASS);
if (typeof PASS === 'undefined') {
console.log("Need to add password");
//open bootstrap modal to ask for password
var myModal = new bootstrap.Modal(document.getElementById('myModal'));
//modifiy modal title
document.getElementById('myModalLabel').innerHTML = "Enter password for "+SSID;
//add input field to modal body
document.getElementById('myModalBody').innerHTML = "<input type='text' id='wifi_pass' class='form-control' placeholder='Password'>";
//add button to modal footer
document.getElementById('myModalFooter').innerHTML = "<button type='button' class='btn btn-secondary' data-bs-dismiss='modal'>Close</button><button type='button' class='btn btn-primary' onclick='wifi_connect(\""+SSID+"\", document.getElementById(\"wifi_pass\").value)'>Se connecter</button>";
myModal.show();
} else {
console.log("Will try to connect to "+SSID+" with password "+PASS);
console.log("Start PHP script:");
// Close modal
var myModal = bootstrap.Modal.getInstance(document.getElementById('myModal'));
if (myModal) {
myModal.hide();
}
$.ajax({
url: 'launcher.php?type=wifi_connect&SSID='+SSID+'&pass='+PASS,
dataType: 'json', // Changed to JSON
method: 'GET',
success: function(response) {
console.log(response);
// Show connection status message
showConnectionStatus(response);
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
alert('Error: Could not start connection process');
}
});
}
}
function showConnectionStatus(response) {
// Get user language (default to French)
const lang = localStorage.getItem('language') || 'fr';
const instructions = response.instructions[lang] || response.instructions['fr'];
// Create overlay with instructions
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-primary 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' ? 'Reconnexion à' : 'Reconnecting to'}:
<strong class="text-white">${response.ssid}</strong>
</p>
<p class="text-muted">
${lang === 'fr' ? 'Nom du capteur' : 'Sensor name'}:
<strong class="text-white">${response.deviceName}</strong>
</p>
</div>
<div class="mt-4">
<small class="text-muted">
${lang === 'fr' ? 'Cette fenêtre va se fermer automatiquement...' : 'This window will close automatically...'}
</small>
</div>
</div>
`;
document.body.appendChild(overlay);
// Auto-close after 30 seconds (gives time to read)
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");
// Clear the existing table body
tableBody.innerHTML = "";
// Loop through the wifiNetworks array and create rows
response.forEach(network => {
const row = document.createElement("tr");
// 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);
/*
const signalCell = document.createElement("td");
signalCell.textContent = network.SIGNAL;
row.appendChild(signalCell);
*/
// 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
// 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}`);
//Trigger function as soon as the button is clicked
button.addEventListener("click", () => wifi_connect(network.SSID));
// 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);
}
});
}
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;
//get device Name
const deviceName = data.deviceName;
// 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);
}
}
// 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));
}
</script>
</body>
</html>