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.
This commit is contained in:
+17
-13
@@ -1,25 +1,28 @@
|
||||
<!doctype html><meta charset=utf-8>
|
||||
<meta name=viewport content="width=device-width,initial-scale=1">
|
||||
<title>maven · history</title>
|
||||
<link rel=stylesheet href=/ui.css>
|
||||
{{template "nav" "history"}}
|
||||
<main class=page>
|
||||
<h1>command history</h1>
|
||||
<p class=muted>{{len .Facts}} facts shown (newest first)</p>
|
||||
{{template "shellTop" "history"}}
|
||||
<h1>Command History</h1>
|
||||
{{if .Facts}}
|
||||
<p class=hint>{{len .Facts}} facts shown (newest first)</p>
|
||||
<div id=msg class=msg hidden></div>
|
||||
<div class=scroll><table class=mono>
|
||||
<tr><th>when<th>kind<th>key<th>value<th>source<th>conf<th></tr>
|
||||
{{range .Facts}}{{if .VoidsID}}<tr class=voided>{{else}}<tr>{{end}}
|
||||
{{range .Facts}}<tr class="{{if .VoidsID}}voided{{end}}">
|
||||
<td>{{if .VoidsID}}<span class=void-badge>⨯ voided</span>{{end}}{{.Ts.Format "2006-01-02 15:04"}}</td>
|
||||
<td>{{.Kind}}</td>
|
||||
<td class=key>{{.Key}}</td>
|
||||
<td class=val>{{.Value}}</td>
|
||||
<td class=muted>{{.Source}}</td>
|
||||
<td class=hint>{{.Source}}</td>
|
||||
<td>{{printf "%.2f" .Confidence}}</td>
|
||||
<td>{{if not .VoidsID}}<button class=btn onclick="revert('{{.Key}}',this)">revert</button>{{end}}</td>
|
||||
<td>{{if not .VoidsID}}<button class="btn btn-sm" onclick="revert('{{.Key}}',this)">revert</button>{{end}}</td>
|
||||
</tr>{{end}}
|
||||
</table></div>
|
||||
</main>
|
||||
{{else}}
|
||||
<div class=empty>
|
||||
<svg class=icon width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
||||
<div>no facts recorded yet</div>
|
||||
<div class=hint>facts appear here when maven observes or records events</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{template "shellBottom"}}
|
||||
<script>
|
||||
const msg=document.getElementById('msg');
|
||||
function revert(key,btn){
|
||||
@@ -30,7 +33,7 @@ function revert(key,btn){
|
||||
msg.className=ok?'msg msg-ok':'msg msg-err';
|
||||
msg.hidden=false;
|
||||
msg.textContent=ok?'reverted ✓':(data.error||'revert failed');
|
||||
if(ok) btn.closest('tr').className='voided';
|
||||
if(ok){btn.closest('tr').className='voided';btn.disabled=true;}
|
||||
}).catch(e=>{
|
||||
msg.className='msg msg-err';
|
||||
msg.hidden=false;
|
||||
@@ -39,3 +42,4 @@ function revert(key,btn){
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user