v0.19.0 frontend: /docs/* route tree + flyout nav + sessions browser
Reorganizes the /docs surface from a single DOCS.md route into a hub with a left-side flyout nav and three new sub-routes for the on-site sessions browser (roadmap item #30): /docs → redirect to /docs/user-guide /docs/user-guide → existing DOCS.md content /docs/sessions → redirect to /docs/sessions/about /docs/sessions/about → README.md of ohm-session-history /docs/sessions/<NNNN> → per-session transcript index /docs/sessions/<NNNN>/<f> → per-transcript view The flyout is a persistent left sidebar on desktop and a slide-out drawer on mobile (toggled by a ☰ button in the docs header). Its session list is driven by the /api/docs/sessions/manifest fetch — loading shows a skeleton; 502 shows an inline retry; empty manifest shows only the "About" row. Each sub-route owns its own empty-state / error handling: - 404 transcripts render "This transcript isn't published yet" with a link back to the parent session index, no JS crash. - 502 (gitea unreachable) renders a retry button. - Manifest 404 is mapped to {} server-side so the flyout renders cleanly with no error banner when no sessions are published yet. Analytics (per SPEC §21): - new EVENTS.DOC_VIEWED ("Doc Viewed") fires on each sub-route mount with `section`: 'user-guide' | 'sessions/about' | 'sessions/<NNNN>' | 'sessions/<NNNN>/<filename>'. - every interactive nav element carries aria-label + data-amp-track-name so autocapture rows are readable. The existing v0.14.0 Docs.jsx component is dropped — its content moved verbatim into DocsUserGuide.jsx; the new layout subsumes the back-button + signed-out home affordances it used to carry. All four new sub-routes reuse the existing MarkdownPreview renderer (marked + mermaid lazy-load) so no second markdown library lands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+29
-4
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Routes, Route, Link, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { Routes, Route, Link, Navigate, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { getMe, subscribeToNotifications } from './api'
|
||||
import { anonymize, EVENTS, identify, track } from './lib/analytics'
|
||||
import Catalog from './components/Catalog.jsx'
|
||||
@@ -12,7 +12,11 @@ import Landing from './components/Landing.jsx'
|
||||
import Login from './components/Login.jsx'
|
||||
import BetaPending from './components/BetaPending.jsx'
|
||||
import Philosophy from './components/Philosophy.jsx'
|
||||
import Docs from './components/Docs.jsx'
|
||||
import DocsLayout from './components/DocsLayout.jsx'
|
||||
import DocsUserGuide from './components/DocsUserGuide.jsx'
|
||||
import DocsSessionsAbout from './components/DocsSessionsAbout.jsx'
|
||||
import DocsSessionIndex from './components/DocsSessionIndex.jsx'
|
||||
import DocsSessionTranscript from './components/DocsSessionTranscript.jsx'
|
||||
import NotificationSettings from './components/NotificationSettings.jsx'
|
||||
import Admin from './components/Admin.jsx'
|
||||
import AcceptInvitation from './components/AcceptInvitation.jsx'
|
||||
@@ -233,7 +237,13 @@ export default function App() {
|
||||
itself establishes the session on success. */}
|
||||
<Route path="/invites/claim" element={<InviteClaim />} />
|
||||
<Route path="/philosophy" element={<PhilosophyWithSidebar viewer={viewer} />} />
|
||||
<Route path="/docs" element={<DocsWithSidebar viewer={viewer} />} />
|
||||
{/* v0.19.0 / roadmap item #30 — /docs/* is a hub with sub-nav.
|
||||
The bare /docs path redirects to the user guide; sessions
|
||||
browser lives at /docs/sessions/*. See DocsLayout.jsx
|
||||
for the flyout shape and CHANGELOG v0.19.0 for the
|
||||
upgrade path. */}
|
||||
<Route path="/docs" element={<Navigate to="/docs/user-guide" replace />} />
|
||||
<Route path="/docs/*" element={<DocsWithSidebar viewer={viewer} />} />
|
||||
{/* §14.5 / §14.6: cookie-consent companions to /philosophy.
|
||||
Available to anonymous and authenticated viewers alike. */}
|
||||
<Route path="/privacy" element={<PolicyShell><Privacy /></PolicyShell>} />
|
||||
@@ -303,9 +313,24 @@ function PhilosophyWithSidebar({ viewer }) {
|
||||
}
|
||||
|
||||
function DocsWithSidebar({ viewer }) {
|
||||
// v0.19.0 / roadmap item #30 — the `/docs/*` surface is a flyout
|
||||
// shell with sub-routes. The shell (sidebar + content area) is the
|
||||
// DocsLayout outlet host; the sub-routes mount their respective
|
||||
// pages into the outlet. Bare `/docs/sessions` redirects to the
|
||||
// sessions about page so deep-linkers and the flyout's "Sessions"
|
||||
// header both land somewhere coherent.
|
||||
return (
|
||||
<main className="chrome-pane">
|
||||
<Docs authenticated={!!viewer} />
|
||||
<Routes>
|
||||
<Route element={<DocsLayout authenticated={!!viewer} />}>
|
||||
<Route index element={<Navigate to="user-guide" replace />} />
|
||||
<Route path="user-guide" element={<DocsUserGuide />} />
|
||||
<Route path="sessions" element={<Navigate to="about" replace />} />
|
||||
<Route path="sessions/about" element={<DocsSessionsAbout />} />
|
||||
<Route path="sessions/:nnnn" element={<DocsSessionIndex />} />
|
||||
<Route path="sessions/:nnnn/:filename" element={<DocsSessionTranscript />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user