feat(ui): one consistent navbar on every page (TODO.md L3)

This commit is contained in:
2026-08-26 15:39:42 -04:00
parent 0a46f07fa8
commit b2d8696741
19 changed files with 2122 additions and 678 deletions
+18 -18
View File
@@ -29,9 +29,10 @@
*
* Phase 19: the viewer joins the shared header (assets/header.js) — the
* whoami fetch is the module's cached promise (one request per page,
* shared with initSharedHeader's toggling), and the bar gains the New
* chat button: on a non-chat page "new chat" means going to the chat,
* fresh (clear the phase-14 conversation key, then navigate to "/").
* shared with initSharedHeader's toggling). Phase 34 task 02: the New
* chat binding is module-owned (assets/header.js, the SINGLE one) — on
* this non-chat page it clears the phase-14 conversation key and
* navigates to the chat's empty state.
*
* Phase 26 (import safety): the modal module imports renderDocument
* from THIS file on the chat/sources pages, so everything
@@ -41,7 +42,7 @@
* fetch, no New Chat binding.
*/
import { clearChatStorage, fetchIsAdmin, initSharedHeader } from "./header.js";
import { fetchIsAdmin, initSharedHeader } from "./header.js";
function fmtDate(iso) {
try {
@@ -71,6 +72,9 @@ function metaBadge(cls, text) {
* document-derived string is a text node. */
export function renderDocument(doc, { titleEl, metaEl, contentEl }) {
titleEl.textContent = doc.title;
// Phase 34 task 04: the titlebar title ellipsizes — the full title
// stays reachable on hover via the `title` attribute.
titleEl.setAttribute("title", doc.title);
const pathCode = document.createElement("code");
pathCode.className = "doc-path";
@@ -149,16 +153,19 @@ if (document.querySelector("#doc-title")) {
function showNotFound() {
titleEl.textContent = "Document not found";
titleEl.removeAttribute("title"); // no stale full-title tooltip
document.title = "Document not found · Brain of Reese";
metaEl.replaceChildren();
contentEl.replaceChildren();
notFoundEl.hidden = false;
}
/* Phase 19: the shared header controls (Sign in / Sign out — exactly
* one visible) are toggled here; the viewer has no nav, so there is
* no #nav-sources for the module to touch. Independent of the doc
* fetch (its own IIFE — load() below never waits on it).
/* Phase 19 (phase 34 task 03, owner confirmation 2026-08-26): the
* viewer now carries the SAME standard bar as every other page —
* nav incl. the admin-only links, Tuning toggle, Sync, New chat, the
* auth pair — all toggled here on the module's cached whoami.
* Independent of the doc fetch (its own IIFE — load() below never
* waits on it).
* (fetchIsAdmin is imported for parity with the other header
* consumers — the module's cached promise is the single whoami per
* page either way.) */
@@ -166,16 +173,9 @@ if (document.querySelector("#doc-title")) {
await initSharedHeader();
})();
/* Phase 19: New chat on a non-chat page means "go to the chat,
* fresh": clear the phase-14 conversation key, then land on the chat
* page — its empty state, since the conversation is gone from storage. */
const newChatBtn = document.querySelector("#new-chat-btn");
if (newChatBtn) {
newChatBtn.addEventListener("click", () => {
clearChatStorage();
window.location.href = "/";
});
}
/* The New chat binding is module-owned (assets/header.js, phase 34
* task 02 — the SINGLE binding): on this non-chat page it clears the
* phase-14 conversation key and navigates to the chat's empty state. */
async function load() {
try {