web: owner-only /admin with the Reader roster and Poll Lane status (#102)
The only operational surface was /healthz and a fold-out roster inside the owner's own reading page. This gives the owner a page: two sections of facts on the same measured sheet, no cards. - admin.go holds every route that reaches past the acting Reader, listed once in adminRoutes() and wrapped in requireOwner at registration - a missing gate is visible in the route list rather than hidden inside a handler. A non-owner gets 404, the same answer revoke already gave. - Lane figures arrive through the LaneReporter seam, so the page reads the running poller rather than a table. newRouter converts a nil *Poller to a nil interface: a typed nil would make the page claim a poller exists. - The roster moves out of the reading page and gains the Sighting counters, the blocked verdict and Clear marks. Clearing restores a privilege, so it is a plain ghost button; --danger stays with revocation. - --patina is the page's one accent, held at the weight of the other action accents. Neither --ember (new chapter) nor --danger (destruction) is borrowed for system health.
This commit is contained in:
@@ -28,6 +28,10 @@
|
||||
<a href="/?lib=novel&tab=all" class="{{if eq .Lib "novel"}}active{{end}}"
|
||||
{{if eq .Lib "novel"}}aria-current="page"{{end}}>Novels</a>
|
||||
</nav>
|
||||
{{/* The owner's only difference on this page: a link out to the
|
||||
administrative one. It sits beside Log out rather than in the library
|
||||
switch — that switch says which library, not which page. */}}
|
||||
{{if .Owner}}<a class="ghost" href="/admin">Admin</a>{{end}}
|
||||
<form method="post" action="/logout">
|
||||
<button type="submit" class="ghost">Log out</button>
|
||||
</form>
|
||||
@@ -76,8 +80,6 @@
|
||||
|
||||
{{template "setup" .}}
|
||||
|
||||
{{if .Owner}}{{template "readers" .}}{{end}}
|
||||
|
||||
{{template "keyrow" .}}
|
||||
|
||||
{{template "recent" .}}
|
||||
|
||||
Reference in New Issue
Block a user