<!DOCTYPE html>
<!-- saved from url=(0019)http://192.168.4.1/ -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WiFi setup</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
margin: 0;
padding: 0;
outline: none;
box-sizing: border-box;
}
body {
background: #000;
color: #fefefe;
font-family: sans-serif;
}
.container {
width: 100%;
max-width: 1000px;
margin-left: auto;
margin-right: auto;
}
.window {
width: 100%;
margin: 40px 0;
border: 4px solid #fefefe;
}
.window-heading {
padding: 15px 30px;
background: #fefefe;
color: black;
width: max-content;
min-width: 320px;
text-transform: uppercase;
}
.window-content {
padding: 30px;
}
.row {
display: flex;
flex-direction: row;
gap: 30px;
}
.col {
width: 100%;
}
p, .mb {
margin-bottom: 15px;
}
.mt {
margin-top: 15px;
}
.mt-2 {
margin-top: 30px;
}
.wifi-list-header {
margin-bottom: 15px;
display: flex;
flex-direction: row;
gap: 30px;
justify-content: space-between;
width: 100%;
align-items: center;
}
.wifi-list-header .heading, .window-content .sub-heading {
font-size: 18px;
font-weight: 600;
}
.wifi-list-container {
width: 100%;
}
.wifi-list {
width: 100%;
}
.wifi-list-body {
width: 100%;
display: flex;
flex-direction: column;
gap: 15px;
}
.wifi-row {
width: 100%;
position: relative;
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 15px;
}
.wifi-row button, .signal, .wifi-list-header button, .btn {
width: 100%;
background: #fefefe;
border: 2px solid #fefefe;
color: #000;
padding: 15px 20px;
text-align: left;
font-size: 18px;
font-weight: 600;
position: relative;
transition-duration: .2s;
transition-property: border-color, background, color;
}
.btn:hover, .wifi-row button:hover, .wifi-list-header button:hover {
background: #1dd3b0;
border-color: #1dd3b0;
}
.wifi-row button:before, .btn:before {
content: "►";
display: block;
position: absolute;
right: 20px;
}
.wifi-row .signal, .wifi-list-header button {
width: 75px;
min-width: 75px;
height: 100%;
border: 2px solid #fefefe;
display: flex;
padding: 15px;
justify-content: center;
}
.wifi-list-header button {
font-size: 36px;
height: 54px;
display: flex;
align-items: center;
}
.wifi-row .signal {
color: #fefefe;
background: transparent;
}
.signal-bar {
display: none;
}
footer {
padding: 0 30px;
}
.window-content .sub-heading {
height: 54px;
display: flex;
align-items: center;
}
.form-group {
display: flex;
flex-direction: column;
gap: 10px;
}
.form-group .btn {
background: #1dd3b0;
border-color: #1dd3b0;
}
.form-group .btn:hover {
border-color: #17ffc4;
background: #17ffc4;
}
.form-control {
width: 100%;
height: 54px;
border: 2px solid #1dd3b0;
color: #1dd3b0;
background: transparent;
padding: 15px 20px;
font-size: 18px;
font-weight: 600;
transition-duration: .2s;
transition-property: border-color;
}
.form-control::placeholder {
color: #ccc;
}
.form-control:focus {
border-color: #17ffc4;
}
.error-box {
min-height: 54px;
display: flex;
align-items: center;
font-size: 18px;
font-weight: 600;
color: #f72585;
padding: 15px 20px;
border: 2px solid #f72585;
}
.scanning {
min-height: 54px;
display: flex;
align-items: center;
font-size: 18px;
font-weight: 600;
color: #1dd3b0;
padding: 15px 20px;
border: 2px solid #1dd3b0;
}
@media (max-width: 900px) {
.window-content > .row {
flex-direction: column;
}
}
</style>
</head>
<body>
<div class="container">
<main class="window">
<div class="window-heading">
<h3>WiFi setup</h3>
</div>
<div class="window-content">
<div class="row">
<div class="col">
<p class="sub-heading">
Connect the device to your home WiFi network.
</p>
<form method="POST" action="http://192.168.4.1/save_wifi">
<div class="form-container mb">
<div class="form-group mb">
<label class="form-label">WiFi SSID</label>
<input name="ssid" class="form-control" placeholder="MyWiFi">
</div>
<div class="form-group mb">
<label class="form-label">Password</label>
<input name="pass" type="password" class="form-control" placeholder="Password">
</div>
<div class="form-group mb">
<button type="submit" class="btn btn-primary">
Save & reboot
</button>
</div>
</div>
</form>
<div class="mt-2 mb">
<h5 class="mb">Last Wi-Fi SSID: (Empty)</h5>
<form method="POST" action="http://192.168.4.1/wifi_confirm">
<button class="btn" type="submit">This connection is correct</button>
</form>
</div>
</div>
<div class="col">
<div class="wifi-list-container"><div class="wifi-list"><div class="wifi-list-header"> <div class="heading">Wi-Fi networks</div> <button type="button" onclick="load_wifi_networks()">⟳</button></div><div class="wifi-list-body"><div class='scanning'>Scanning...</div><div class='error-box'>Scanning ERROR</div><div class="wifi-row" data-ssid="super_subnet" data-signal="100" data-secured="1"><button type="button">super_subnet [lock]</button><div class="signal"><div class="signal-bar"><div class="signal-bar-fill" style="width: 100%;"></div></div><div class="signal-percent">100%</div></div></div><div class="wifi-row" data-ssid="super_subnet_iot" data-signal="90" data-secured="1"><button type="button">super_subnet_iot [lock]</button><div class="signal"><div class="signal-bar"><div class="signal-bar-fill" style="width: 90%;"></div></div><div class="signal-percent">90%</div></div></div><div class="wifi-row" data-ssid="super_subnet" data-signal="88" data-secured="1"><button type="button">super_subnet [lock]</button><div class="signal"><div class="signal-bar"><div class="signal-bar-fill" style="width: 88%;"></div></div><div class="signal-percent">88%</div></div></div><div class="wifi-row" data-ssid="super_subnet_iot" data-signal="60" data-secured="1"><button type="button">super_subnet_iot [lock]</button><div class="signal"><div class="signal-bar"><div class="signal-bar-fill" style="width: 60%;"></div></div><div class="signal-percent">60%</div></div></div><div class="wifi-row" data-ssid="super_subnet" data-signal="34" data-secured="1"><button type="button">super_subnet [lock]</button><div class="signal"><div class="signal-bar"><div class="signal-bar-fill" style="width: 34%;"></div></div><div class="signal-percent">34%</div></div></div></div></div></div>
</div>
</div>
</div>
</main>
<footer class="mt">
<p>ESP SmartHome Device</p>
</footer>
</div>
<script>
async function load_wifi_networks() {
const box = document.querySelector(".wifi-list-container");
if (!box) return;
box.innerHTML = "<div class='scanning'>Scanning...</div>";
try {
const res = await fetch("/wifi_scan", { cache: "no-store" });
if (!res.ok) throw new Error("HTTP " + res.status);
const data = await res.json();
if (!data || data.status !== "ok") {
box.innerHTML = "<div class='error-box'>Response ERROR</div>";
return;
}
const list = Array.isArray(data.networks) ? data.networks : [];
if (list.length === 0) {
box.innerHTML = "<div class='no-result'>Networks not found</div>";
return;
}
list.sort((a, b) => (b.signal || 0) - (a.signal || 0));
let html = "";
html += "<div class='wifi-list'>";
html += "<div class='wifi-list-header'>";
html += " <div class='heading'>Wi-Fi networks</div>";
html += " <button type='button' onclick='load_wifi_networks()'>Rescan</button>";
html += "</div>";
html += "<div class='wifi-list-body'>";
for (const net of list) {
const ssid = (net.ssid ?? "");
if(!ssid.length) continue;
const secured = !!net.secured;
const p = Math.max(0, Math.min(100, Number(net.signal ?? 0)));
html += "<div class='wifi-row' data-ssid='" + encodeURIComponent(ssid) + "' data-signal='" + p + "' data-secured='" + (secured ? "1" : "0") + "'></div>";
}
html += "</div></div>";
box.innerHTML = html;
const rows = box.querySelectorAll(".wifi-row");
rows.forEach((row) => {
const ssid = decodeURIComponent(row.getAttribute("data-ssid") || "");
const p = Number(row.getAttribute("data-signal") || "0");
const secured = row.getAttribute("data-secured") === "1";
const btn = document.createElement("button");
btn.type = "button";
btn.onclick = () => {
const inp = document.querySelector("input[name=ssid]");
if (inp) inp.value = ssid;
};
btn.textContent = ssid + (secured ? " 🔒" : "");
const sig = document.createElement("div");
sig.classList.add("signal");
const bar = document.createElement("div");
bar.classList.add("signal-bar");
const fill = document.createElement("div");
fill.classList.add("signal-bar-fill");
fill.style.width = p + "%";
bar.appendChild(fill);
const perc = document.createElement("div");
perc.classList.add("signal-percent");
perc.textContent = p + "%";
sig.appendChild(bar);
sig.appendChild(perc);
row.appendChild(btn);
row.appendChild(sig);
});
} catch (e) {
box.innerHTML = "<div class='error-box'>Scanning ERROR</div>";
}
}
document.addEventListener("DOMContentLoaded", () => {
// load_wifi_networks();
});
</script>
</body></html>