// router.jsx — Lightweight hash-based SPA router
//
// Uses window.location.hash (#/path/to/page) so the site works from any
// static file server with no URL rewriting needed.
//
// Routes:
// #/ → Homepage
// #/artists → Artists index
// #/artists/:slug → Artist profile
// #/events → Events index (list view)
// #/events/:slug → Event detail
// #/news → News & stories index
// #/news/:slug → News article
// #/about → About the Council (coming soon)
// #/contact → Contact (coming soon)
// ─── Router context ───────────────────────────────────────────────
const RouterCtx = React.createContext({ path: '/', segments: [] });
function useRouter() {
return React.useContext(RouterCtx);
}
// ─── Navigation ───────────────────────────────────────────────────
function navigate(to) {
window.location.hash = '#' + to;
// Scroll to top immediately (not smooth — this is a page change)
window.scrollTo(0, 0);
}
// Link component — renders a proper that also calls navigate()
// so the scroll-to-top fires even if the hash doesn't change.
function Link({ to, children, style, className, onClick }) {
const handleClick = (e) => {
e.preventDefault();
if (onClick) onClick(e);
navigate(to);
};
return (
{children}
);
}
// ─── Hash parsing ─────────────────────────────────────────────────
function parseHash(hash) {
// Strip leading # and optional /
const raw = (hash || '').replace(/^#\/?/, '');
const [pathPart] = raw.split('?');
const segments = pathPart ? pathPart.split('/').filter(Boolean) : [];
return { path: '/' + pathPart, segments };
}
// ─── RouterProvider ───────────────────────────────────────────────
function RouterProvider({ children }) {
const [loc, setLoc] = React.useState(() => parseHash(window.location.hash));
React.useEffect(() => {
const handler = () => setLoc(parseHash(window.location.hash));
window.addEventListener('hashchange', handler);
return () => window.removeEventListener('hashchange', handler);
}, []);
return (
{children}
);
}
// ─── Page resolution ─────────────────────────────────────────────
// Returns { page, id } for the current hash location.
function useCurrentPage() {
const { segments } = useRouter();
const [section, id] = segments;
switch (section) {
case undefined:
case '': return { page: 'home', id: null };
case 'artists':return { page: id ? 'artist-profile' : 'artists', id: id || null };
case 'events': return { page: id ? 'event-detail' : 'events', id: id || null };
case 'news': return { page: id ? 'news-article' : 'news', id: id || null };
case 'about': return { page: 'about', id: null };
case 'contact':return { page: 'contact', id: null };
default: return { page: '404', id: null };
}
}
Object.assign(window, { RouterProvider, Link, navigate, useRouter, useCurrentPage });