48 lines
4.8 KiB
HTML
48 lines
4.8 KiB
HTML
<!doctype html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>maze32 — настройка сети</title>
|
|
<style>
|
|
:root{color-scheme:dark;--bg:#09070f;--panel:#281445;--accent:#38e8d1;--ok:#68dc78;--warn:#ffd45c;--bad:#ff647c}
|
|
*{box-sizing:border-box}body{margin:0;min-height:100vh;background:radial-gradient(circle at top,#211138,var(--bg) 58%);color:#f4efff;font:16px/1.45 ui-monospace,SFMono-Regular,Consolas,monospace;padding:24px}
|
|
main{width:min(620px,100%);margin:auto;background:var(--panel);border:2px solid #8058b7;box-shadow:8px 8px 0 #10071d;padding:clamp(18px,5vw,36px)}
|
|
h1{margin:0;color:var(--accent);letter-spacing:.08em}p{margin:.55rem 0 1.3rem}.status{border-left:4px solid var(--warn);padding:.7rem 1rem;background:#160d27}
|
|
label{display:block;margin:1rem 0 .35rem}input,select,button{width:100%;min-height:48px;border:2px solid #8058b7;background:#10091d;color:#fff;font:inherit;padding:.65rem}
|
|
input:focus,select:focus,button:focus{outline:3px solid var(--accent);outline-offset:2px}button{margin-top:1rem;border-color:var(--accent);color:var(--accent);font-weight:700;cursor:pointer}button:disabled{opacity:.45;cursor:wait}.danger{border-color:var(--bad);color:var(--bad)}
|
|
#message[data-kind="ok"]{color:var(--ok)}#message[data-kind="error"]{color:var(--bad)}small{color:#c9badd}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<h1>MAZE32 // WI-FI</h1>
|
|
<p>Поможем коробочке найти интернет. Сам лабиринт в интернет не убежит.</p>
|
|
<div class="status" id="status">Проверяем сетевой режим…</div>
|
|
<button id="scan" type="button">Сканировать сети</button>
|
|
<form id="form">
|
|
<label for="networks">Найденные сети</label>
|
|
<select id="networks"><option value="">Выберите сеть или введите имя ниже</option></select>
|
|
<label for="ssid">Имя сети (SSID)</label>
|
|
<input id="ssid" name="ssid" maxlength="32" required autocomplete="off">
|
|
<label for="password">Пароль</label>
|
|
<input id="password" name="password" type="password" maxlength="63" autocomplete="new-password" aria-describedby="password-help">
|
|
<small id="password-help">Оставьте пустым для открытой сети; иначе нужно 8–63 символа.</small>
|
|
<button id="save" type="submit">Сохранить и подключиться</button>
|
|
</form>
|
|
<button id="reset" class="danger" type="button">Удалить настройки сети</button>
|
|
<p id="message" role="status" aria-live="polite"></p>
|
|
</main>
|
|
<script>
|
|
const $=id=>document.getElementById(id),message=(text,kind='')=>{$('message').textContent=text;$('message').dataset.kind=kind};
|
|
async function json(url,options){const response=await fetch(url,options),body=await response.json().catch(()=>({}));if(!response.ok)throw new Error(body.error||'Устройство не ответило');return body}
|
|
async function status(){try{const value=await json('/api/wifi/status');$('status').textContent=value.state==='provisioning'?`Точка настройки: ${value.accessPointSsid}`:value.state==='station_connected'?`Подключено. Адрес: ${value.ip}`:`Состояние: ${value.state}`}catch(error){$('status').textContent=error.message}}
|
|
$('networks').addEventListener('change',event=>{if(event.target.value)$('ssid').value=event.target.value});
|
|
$('scan').addEventListener('click',async()=>{const button=$('scan');button.disabled=true;message('Ищем Wi-Fi…');try{const value=await json('/api/wifi/scan'),select=$('networks');select.length=1;for(const network of value.networks){const option=document.createElement('option');option.value=network.ssid;option.textContent=`${network.ssid||'<скрытая>'} (${network.rssi} dBm${network.secure?', 🔒':''})`;select.append(option)}message(`Найдено сетей: ${value.networks.length}`,'ok')}catch(error){message(error.message,'error')}finally{button.disabled=false}});
|
|
$('form').addEventListener('submit',async event=>{event.preventDefault();const button=$('save');button.disabled=true;message('Сохраняем настройки…');try{const value=await json('/api/wifi/config',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ssid:$('ssid').value,password:$('password').value})});$('password').value='';message(value.message,'ok');setTimeout(status,14000)}catch(error){message(error.message,'error')}finally{button.disabled=false}});
|
|
$('reset').addEventListener('click',async()=>{const button=$('reset');button.disabled=true;try{const value=await json('/api/wifi/reset',{method:'POST'});$('password').value='';message(value.message,'ok');setTimeout(status,1000)}catch(error){message(error.message,'error')}finally{button.disabled=false}});
|
|
status();
|
|
</script>
|
|
</body>
|
|
</html>
|