Files
Maven/cmd/mavweb/dash.html
T
kami 7a95097cc7 feat: web UI redesign with PWA support, voice page, and mobile layout
- Redesign dash/history/notifications/trace pages with unified CSS framework
  (ui.css): cards, badges, scrollable tables, responsive grid, PWA shell.
- Add /voice page with chat-bubble transcript, listening indicator, and
  push-to-talk button for voice interaction.
- Add mavweb.js: client-side JS for live transcript polling, auto-scroll,
  push-to-talk, and service-worker registration.
- Update PWA manifest, icon, and service-worker for installable web app.
- Add WebAuthn credential management (register/list/delete) with modal UI.
- Update main.go: /voice route, WebAuthn handlers, new page navigation.
- Update handlers_test.go for new voice and WebAuthn routes.
2026-07-10 15:49:18 +04:00

51 lines
1.8 KiB
HTML

{{template "shellTop" "dash"}}
<h1>Dashboard</h1>
<section class=card>
<h2 class=card-title>
<span class="dot dot-ok" style="margin-right:4px"></span>
presence
</h2>
<p>
<span class="status-{{.Presence.Bucket}}">{{.Presence.Bucket}}</span>
— score {{printf "%.2f" .Presence.Score}}
<span class=hint>({{ago .Presence.Updated}})</span>
</p>
<div class=hint id=updated>updates every 10s</div>
</section>
<section class=card>
<div class=section-header>
<h2>nudges</h2>
</div>
<div class=scroll><table class=mono id=nudges><tr><th>when<th>rule<th>chan<th>outcome<th>message</tr>
{{range .Nudges}}<tr><td>{{ago .Ts}}<td>{{.Rule}}<td><span class=badge>{{.Channel}}</span><td class={{.Outcome}}>{{.Outcome}}<td>{{.Message}}</tr>{{end}}
</table></div>
</section>
<section class=card>
<div class=section-header>
<h2>facts</h2>
</div>
<div class=scroll><table class=mono id=facts><tr><th>when<th>kind<th>key<th>value<th>source<th>conf</tr>
{{range .Facts}}<tr><td>{{ago .Ts}}<td>{{.Kind}}<td class=key>{{.Key}}<td>{{.Value}}<td>{{.Source}}<td>{{printf "%.2f" .Confidence}}</tr>{{end}}
</table></div>
</section>
<section class=card>
<div class=section-header>
<h2>notes</h2>
</div>
<div class=scroll><table class=mono id=notes><tr><th>when<th>source<th>text</tr>
{{range .Notes}}<tr><td>{{ago .Ts}}<td>{{.Source}}<td>{{.Text}}</tr>{{end}}
</table></div>
</section>
{{template "shellBottom"}}
<script>
setInterval(() => fetch('/dash').then(r => r.text()).then(html => {
const p = new DOMParser(), d = p.parseFromString(html, 'text/html');
for (const id of ['nudges', 'facts', 'notes']) {
const old = document.getElementById(id), nu = d.getElementById(id);
if (old && nu) old.replaceWith(nu);
}
document.getElementById('updated').textContent = 'updated ' + new Date().toLocaleTimeString();
}), 10000);
</script>
</html>