Turn Publisher into multi-page app with license manager v1.1.0.
Hash router with publish, licenses, generate, stats, and settings pages backed by license server admin API. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
/** @typedef {{ path: string; title: string; render: (root: HTMLElement) => void | (() => void) }} Route */
|
||||
|
||||
/** @type {Route[]} */
|
||||
const routes = [];
|
||||
|
||||
/** @type {(() => void) | null} */
|
||||
let cleanup = null;
|
||||
|
||||
/** @param {Route} route */
|
||||
export function registerRoute(route) {
|
||||
routes.push(route);
|
||||
}
|
||||
|
||||
/** @param {string} hashPath */
|
||||
export function navigate(hashPath) {
|
||||
const path = hashPath.startsWith('#') ? hashPath : `#${hashPath}`;
|
||||
if (location.hash !== path) {
|
||||
location.hash = path;
|
||||
} else {
|
||||
renderCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
function currentPath() {
|
||||
const hash = location.hash.replace(/^#/, '') || '/publish';
|
||||
return hash.startsWith('/') ? hash : `/${hash}`;
|
||||
}
|
||||
|
||||
function findRoute() {
|
||||
const path = currentPath();
|
||||
return routes.find((r) => r.path === path) ?? routes.find((r) => r.path === '/publish');
|
||||
}
|
||||
|
||||
function updateNav() {
|
||||
const path = currentPath();
|
||||
document.querySelectorAll('.nav a').forEach((a) => {
|
||||
const href = a.getAttribute('href') ?? '';
|
||||
a.classList.toggle('active', href === `#${path}`);
|
||||
});
|
||||
}
|
||||
|
||||
function renderCurrent() {
|
||||
const route = findRoute();
|
||||
const root = document.getElementById('page-root');
|
||||
if (!root || !route) return;
|
||||
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
cleanup = null;
|
||||
}
|
||||
|
||||
root.innerHTML = '';
|
||||
document.title = `${route.title} — TTRPG Player Publisher`;
|
||||
updateNav();
|
||||
|
||||
const result = route.render(root);
|
||||
if (typeof result === 'function') {
|
||||
cleanup = result;
|
||||
}
|
||||
}
|
||||
|
||||
export function startRouter() {
|
||||
window.addEventListener('hashchange', renderCurrent);
|
||||
if (!location.hash) {
|
||||
location.hash = '#/publish';
|
||||
} else {
|
||||
renderCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
export function getCurrentPath() {
|
||||
return currentPath();
|
||||
}
|
||||
Reference in New Issue
Block a user