feat(ui): hash router — each page has a shareable URL (#35)
- #/health, #/events, #/reaction-logs, etc. - Browser back/forward navigation works - Refresh preserves current page - No new dependencies (hand-rolled hash router) Closes #35 小橘 🍊(NEKO Team)
This commit is contained in:
parent
d06d000ec0
commit
0c22885f4a
File diff suppressed because one or more lines are too long
@ -27,12 +27,44 @@ type Page =
|
||||
| 'reaction-logs'
|
||||
| 'request-logs'
|
||||
|
||||
const VALID_PAGES: Set<string> = new Set([
|
||||
'health', 'object-defs', 'objects', 'event-defs', 'events',
|
||||
'projection-defs', 'projections', 'reactions', 'api-keys',
|
||||
'reaction-logs', 'request-logs',
|
||||
])
|
||||
|
||||
function getPageFromHash(): Page {
|
||||
const hash = window.location.hash.replace(/^#\/?/, '')
|
||||
return VALID_PAGES.has(hash) ? (hash as Page) : 'health'
|
||||
}
|
||||
|
||||
function setHash(page: Page) {
|
||||
window.history.pushState(null, '', `#/${page}`)
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [page, setPage] = useState<Page>('health')
|
||||
const [page, setPageState] = useState<Page>(getPageFromHash)
|
||||
const [needsAuth, setNeedsAuth] = useState(false)
|
||||
const [tokenInput, setTokenInput] = useState('')
|
||||
const [checking, setChecking] = useState(true)
|
||||
|
||||
// Sync hash → state on popstate (browser back/forward)
|
||||
useEffect(() => {
|
||||
const onHashChange = () => setPageState(getPageFromHash())
|
||||
window.addEventListener('hashchange', onHashChange)
|
||||
window.addEventListener('popstate', onHashChange)
|
||||
return () => {
|
||||
window.removeEventListener('hashchange', onHashChange)
|
||||
window.removeEventListener('popstate', onHashChange)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Navigate: update hash + state
|
||||
const setPage = (p: Page) => {
|
||||
setHash(p)
|
||||
setPageState(p)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
if (!getToken()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user