feat(admin): phase 1 — hash-router
AdminRouter wraps existing switchTab for deep-linking. - frontend/js/admin/router.js (new, 102L): parse/navigate/current/on/off, recursion guard via _navigating flag - admin.html: +1 <script> before admin.js - admin.js: switchTab(btn, opts) + initAdminRouter IIFE for hashchange dispatch Backward compat: all 21 onclick=switchTab(this) callsites continue working. F5 / back / forward / deep-link verified. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
(будет обновляться после каждой фазы)
|
||||
|
||||
- ⬜ Phase 1 not started — старый switchTab всё ещё единственный роутер
|
||||
- ✅ Phase 1 implemented — `window.AdminRouter` обёртывает старый `switchTab` (hash ↔ tab двусторонне). `switchTab` принимает 2-й аргумент `{ fromRouter: true }` для предотвращения рекурсии. Default = `#stats`. Файлы: `frontend/js/admin/router.js` (новый), `frontend/admin.html` (+1 строка), `frontend/js/admin/admin.js` (модификация `switchTab` + IIFE `initAdminRouter`).
|
||||
- ⬜ Phase 2 not started — все 13 секций в admin.js монолите
|
||||
- ⬜ Phase 3-6 not started
|
||||
|
||||
@@ -19,6 +19,23 @@
|
||||
- **Phase 6 depends on Phase 2:** deep page для user/session — это новые sections в той же структуре
|
||||
- **Phase 6 removes** старую `.user-panel` overlay из admin.html — фазы 1-5 НЕ должны её удалять
|
||||
|
||||
## Router Contract (Phase 1)
|
||||
|
||||
```js
|
||||
// Subscribe in any future module:
|
||||
AdminRouter.on('change', ({ route, params, raw }) => { /* ... */ });
|
||||
|
||||
// Programmatic deep-link without polluting history:
|
||||
AdminRouter.navigate('#users/123', { replace: true, silent: true });
|
||||
```
|
||||
|
||||
- Events emitted: `'change'` only (payload: parsed route).
|
||||
- Late subscribers do NOT receive replay — call `AdminRouter.current()` on init.
|
||||
- `silent: true` suppresses the synchronous emit but native `hashchange` still fires;
|
||||
the internal `_navigating` flag in router.js prevents the listener from re-firing.
|
||||
- `switchTab(btn, { fromRouter: true })` — call from router handlers to skip the
|
||||
reverse-sync write to `location.hash` (avoids redundant `replaceState`).
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Существующая структура (что менять / что НЕ менять)
|
||||
|
||||
Reference in New Issue
Block a user