diff --git a/services/web-ui/public/js/auth-guard.js b/services/web-ui/public/js/auth-guard.js index 67851d8..2c26a31 100644 --- a/services/web-ui/public/js/auth-guard.js +++ b/services/web-ui/public/js/auth-guard.js @@ -6,7 +6,67 @@ * (When AUTH_ENABLED=false the endpoint returns a synthetic guest user, * so the redirect only fires in production auth-enabled mode.) * - On success, populate the sidebar user widget and wire up the logout button. + * - Side effect: marks any sidebar link pointing at editor.html with an + * "IN DEV" badge, so we don't have to touch every HTML file individually. */ + +// ── Cross-page IN-DEV markers ───────────────────────────────────────────── +// Add (page-name → label) here to flag a sidebar item without editing all +// 13 HTML files. The CSS + DOM patch runs once on every page. +const IN_DEV_PAGES = { + 'editor.html': 'IN DEV', +}; + +(function tagInDevNavItems() { + // 1. Inject the badge styles once. Kept inline so we don't add another + // HTTP request per page — and so the rule can't get out of sync with + // the auth-guard that toggles it. + if (!document.getElementById('in-dev-style')) { + const style = document.createElement('style'); + style.id = 'in-dev-style'; + style.textContent = ` + .nav-item.is-in-dev { position: relative; } + .nav-item.is-in-dev .nav-dev-badge { + margin-left: auto; + font-size: 9px; + font-weight: 700; + letter-spacing: 0.12em; + padding: 2px 6px; + border-radius: 4px; + background: oklch(28% 0.14 80 / 0.45); + color: oklch(85% 0.16 85); + border: 1px solid oklch(50% 0.16 80 / 0.55); + text-transform: uppercase; + line-height: 1; + flex-shrink: 0; + } + .nav-item.is-in-dev:hover .nav-dev-badge { + background: oklch(32% 0.16 80 / 0.55); + } + `; + document.head.appendChild(style); + } + + // 2. Walk every sidebar nav-item link and tag the ones whose href matches + // a known in-dev page. Href is matched case-insensitively against the + // final path segment so '/editor.html', 'editor.html', and absolute + // URLs all hit. + const links = document.querySelectorAll('.nav-item'); + links.forEach((a) => { + const href = (a.getAttribute('href') || '').toLowerCase(); + const last = href.split('/').pop().split('?')[0]; + const label = IN_DEV_PAGES[last]; + if (!label) return; + if (a.querySelector('.nav-dev-badge')) return; // idempotent + a.classList.add('is-in-dev'); + const badge = document.createElement('span'); + badge.className = 'nav-dev-badge'; + badge.textContent = label; + a.appendChild(badge); + }); +})(); + +// ── Auth + user widget ──────────────────────────────────────────────────── (async () => { try { const r = await fetch('/api/v1/auth/me', { credentials: 'include' });