Files
maze32/web/provision.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>