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'
|
| 'reaction-logs'
|
||||||
| 'request-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() {
|
function App() {
|
||||||
const [page, setPage] = useState<Page>('health')
|
const [page, setPageState] = useState<Page>(getPageFromHash)
|
||||||
const [needsAuth, setNeedsAuth] = useState(false)
|
const [needsAuth, setNeedsAuth] = useState(false)
|
||||||
const [tokenInput, setTokenInput] = useState('')
|
const [tokenInput, setTokenInput] = useState('')
|
||||||
const [checking, setChecking] = useState(true)
|
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(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!getToken()) {
|
if (!getToken()) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user