Newer
Older
smart-home-server / device_interface_dev / setup.html
<!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 &amp; 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>