Printio/templates/internet.html
2025-10-27 22:24:25 -07:00

289 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WiFi Configuration</title>
<link rel="icon" type="image/x-icon" href="/static/images/favicon.ico" />
<link rel="stylesheet" href="/static/css/styles.css" />
<link rel="stylesheet" href="/static/fontawesome/css/all.min.css" />
<style>
:root{
--bg: #0b0d10;
--panel: #12161b;
--card: #141a20;
--muted: #c7d1db;
--primary: #3b82f6;
--primary-700: #1d4ed8;
--ring: rgba(59,130,246,.35);
--radius: 14px;
--gap: 16px;
--ok: #22c55e;
--warn: #f59e0b;
--err: #ef4444;
}
html, body { height:100%; }
body{
margin:0; color:var(--muted);
background: linear-gradient(180deg, #0b0d10 0%, #0e1217 100%);
font: 500 16px/1.4 system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, sans-serif;
-webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
a{ color: inherit; }
/* Navbar inject target */
#navbar { position: sticky; top:0; z-index: 100; backdrop-filter: blur(6px); }
.wrapper{ max-width: 1100px; margin: 0 auto; padding: 24px 16px 56px; }
/* Header */
.page-header{ display:flex; align-items:center; gap:16px; justify-content:flex-start; margin: 4px 0 12px; }
.page-header .header-img{ width:auto; height:72px; margin:0; position:static !important; filter: drop-shadow(0 4px 14px rgba(0,0,0,.4)); }
h1{ font-size: clamp(22px, 3vw, 32px); font-weight: 700; letter-spacing:.2px; margin:0; }
.subtitle{ opacity:.9; font-size:.95rem; margin-top:6px; }
/* Cards */
details.card{ background: var(--card); border: 1px solid rgba(255,255,255,.06); border-radius: var(--radius);
overflow:hidden; box-shadow: 0 10px 30px rgba(0,0,0,.35); margin-bottom: 18px; }
details.card[open]{ box-shadow: 0 16px 38px rgba(0,0,0,.45); }
details.card > summary{ list-style:none; display:flex; align-items:center; gap:10px; cursor:pointer;
padding: 14px 16px; background: linear-gradient(180deg, rgba(255,255,255,.03), rgba(255,255,255,.00)); font-weight:700; }
details.card > summary::-webkit-details-marker{ display:none; }
.chev{ width: 10px; height:10px; border-right:2px solid var(--muted); border-bottom:2px solid var(--muted);
transform: rotate(-45deg); transition: transform .18s ease; margin-right: 4px; opacity:.9; }
details.card[open] > summary .chev{ transform: rotate(45deg); }
.card-body{ padding: 14px 16px 16px; display:grid; gap:18px; background: var(--panel); border-top: 1px solid rgba(255,255,255,.06); }
/* Actions / Buttons */
.actions{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.actions .small-btn-group{ margin-left:auto; display:flex; gap:10px; flex-wrap:wrap; }
button.btn{ background: var(--primary); color:white; border:1px solid rgba(255,255,255,.08); border-radius: 10px;
padding: 10px 14px; font-weight:700; letter-spacing:.2px; cursor:pointer;
transition: transform .06s ease, background .15s ease, box-shadow .15s ease; min-width:140px; }
button.btn:hover{ background: var(--primary-700); }
button.btn:active{ transform: translateY(1px); }
button.btn[disabled]{ opacity:.5; cursor:not-allowed; }
button.btn.success{ background: var(--ok); }
button.btn.warn{ background: var(--warn); color:#0b0d10; }
button.btn.alt{ background: #64748b; }
/* Status badges/text */
.status{ font-size: 1rem; opacity:.95; }
.status.ok{ color: var(--ok); }
.status.err{ color: var(--err); }
.status.warn{ color: var(--warn); }
/* Table */
.network-list{ width:100%; max-height: 320px; overflow:auto; border:1px solid rgba(255,255,255,.08);
background:#0f141a; border-radius: 12px; }
table#networksTable{ width:100%; border-collapse: separate; border-spacing: 0; }
#networksTable thead th{
position: sticky; top:0; background: #0f1620; color:#dbe7f3;
text-align:left; padding:10px 12px; font-weight:700; border-bottom:1px solid rgba(255,255,255,.08);
}
#networksTable tbody td{ padding:10px 12px; border-bottom:1px solid rgba(255,255,255,.06); white-space: nowrap; }
#networksTable tbody tr{ cursor:pointer; }
#networksTable tbody tr:hover{ background: rgba(59,130,246,.08); }
#networksTable tbody tr.selected{ background: rgba(34,197,94,.18); }
/* Grid helpers */
.grid-2{ display:grid; grid-template-columns: 1fr; gap: var(--gap); }
@media (min-width: 900px){ .grid-2{ grid-template-columns: 1.2fr .8fr; } }
/* Keep original IDs styling overrides (safely) */
#label-status{ display:block; margin-top: 6px; }
#scanStatus{ min-height: 20px; }
</style>
</head>
<body>
<div id="navbar"></div>
<script>
fetch('/static/html/nav.html').then(r=>r.text()).then(html=>{ document.getElementById('navbar').innerHTML = html; });
</script>
<main class="wrapper">
<header class="page-header">
<img src="/static/images/internet_icon.png" alt="internet" class="header-img" />
<div>
<h1>WiFi Internet Access</h1>
<div class="subtitle"><span id="label-status">Status:</span></div>
</div>
</header>
<!-- Networks card -->
<details class="card" open>
<summary><span class="chev"></span>Networks</summary>
<div class="card-body">
<div class="actions">
<button class="btn" id="scanButton" onclick="scanWifi()"><i class="fa-solid fa-wifi"></i> Scan</button>
<div class="small-btn-group">
<button class="btn alt" id="forgetButton" onclick="checkForgetNetworks()"><i class="fa-regular fa-trash-can"></i> Forget all</button>
<button class="btn success" id="testButton" onclick="checkInternetAccess()"><i class="fa-solid fa-globe"></i> Test Internet</button>
</div>
</div>
<div id="scanStatus" class="status"></div>
<div class="grid-2">
<div class="network-list">
<table id="networksTable">
<thead>
<tr>
<th>SSID</th>
<th>Freq</th>
<th>Signal</th>
<th>Bssid</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="actions" style="align-items:flex-start;">
<button class="btn warn" id="connectToNetworkButton" onclick="connectToNetwork()">
<i class="fa-solid fa-plug"></i> Connect
</button>
</div>
</div>
</div>
</details>
<!-- Connection status -->
<details class="card">
<summary><span class="chev"></span>Connection Status</summary>
<div class="card-body">
<div class="status" id="connectionStatus"></div>
</div>
</details>
<!-- Notice -->
<details class="card">
<summary><span class="chev"></span>Notice</summary>
<div class="card-body">
<label id="label-wifi">*WPA3 is not currently supported. If your hotspot/Access Point is set for WPA3, please change it to WPA2 before trying to connect.</label>
</div>
</details>
</main>
<script>
window.onload = function() { OnPageLoad(); };
function scanWifi() {
console.log("Starting WiFi scan...");
document.getElementById('connectionStatus').innerText = "";
const ss = document.getElementById('scanStatus');
ss.innerText = "Scanning for networks...";
fetch('/wifi_scan')
.then(response => response.json())
.then(data => {
console.log("Scan complete. Data received:", data);
ss.innerText = "Scan complete.";
let tableBody = document.getElementById('networksTable').getElementsByTagName('tbody')[0];
tableBody.innerHTML = '';
(data.networks || []).forEach(network => {
let row = tableBody.insertRow();
row.insertCell(0).textContent = network.ssid || '';
row.insertCell(1).textContent = network.Freq || '';
row.insertCell(2).textContent = network.signal || '';
row.insertCell(3).textContent = network.bssid || '';
row.addEventListener('click', function() {
const rows = document.querySelectorAll('#networksTable tbody tr');
rows.forEach(r => r.classList.remove('selected'));
row.classList.add('selected');
});
});
})
.catch(error => {
console.error("Error during scan:", error);
ss.innerText = "Error during scan.";
});
}
function connectToNetwork() {
console.log("Attempting to connect to network...");
const table = document.getElementById('networksTable');
const selectedRow = table.querySelector('tbody tr.selected');
if (!selectedRow) {
document.getElementById('connectionStatus').innerText = "Please select a network to connect to.";
return;
}
const ssid = selectedRow.cells[0].textContent;
const bssid = selectedRow.cells[3].textContent;
const password = prompt("Enter the WiFi password for " + ssid + ":");
if (!password) {
document.getElementById('connectionStatus').innerText = "Connection cancelled.";
return;
}
document.getElementById('connectionStatus').innerText = "Please wait...";
document.getElementById('connectToNetworkButton').disabled = true;
document.getElementById('scanButton').disabled = true;
document.getElementById('testButton').disabled = true;
document.getElementById('forgetButton').disabled = true;
fetch('/wifi_connect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ssid: ssid, bssid: bssid, password: password })
})
.then(response => response.json())
.then(data => {
console.log("Connection attempt result:", data);
document.getElementById('connectionStatus').innerText = data.message;
checkWifiStatus();
})
.catch(error => {
console.error("Error during connection attempt:", error);
document.getElementById('connectionStatus').innerText = "Error during connection attempt.";
})
.finally(() => {
document.getElementById('connectToNetworkButton').disabled = false;
document.getElementById('scanButton').disabled = false;
document.getElementById('testButton').disabled = false;
document.getElementById('forgetButton').disabled = false;
});
}
function checkInternetAccess() {
fetch('/wifi_test')
.then(response => response.json())
.then(data => {
const statusMessage = data.success ? "Internet Access Ok" : "No Internet Access";
alert(statusMessage);
})
.catch(error => {
console.error("Error checking internet access:", error);
alert("Error checking internet access.");
});
}
function checkForgetNetworks() {
fetch('/wifi_forget')
.then(response => response.json())
.then(data => {
const statusMessage = data.success ? "All networks forgotten" : "Nothing happened";
alert(statusMessage);
})
.catch(error => {
console.error("Error forgetting networks:", error);
alert("Error forgetting networks.");
});
}
function checkWifiStatus() {
fetch('/wifi_status')
.then(response => response.json())
.then(data => {
console.log("Data received:", data);
document.getElementById('label-status').innerText = "Status: " + (data.msg || '...');
})
.catch(error => {
console.error("Error getting wifi status:", error);
document.getElementById('label-status').innerText = "Status: ...";
});
}
function OnPageLoad(){ checkWifiStatus(); }
</script>
</body>
</html>