// Router.jsx — minimal hash-based router.
// Routes are like #/, #/services, #/services/cloud-solutions, #/about, #/contact, #/blog
const RouterContext = React.createContext({ path: '/', params: {}, navigate: () => {} });
function parseHash() {
const h = (window.location.hash || '#/').replace(/^#/, '');
const clean = h.startsWith('/') ? h : '/' + h;
return clean.split('?')[0] || '/';
}
function useRouter() {
return React.useContext(RouterContext);
}
function RouterProvider({ children }) {
const [path, setPath] = React.useState(parseHash());
React.useEffect(() => {
const onChange = () => {
const next = parseHash();
setPath(next);
// Scroll to top on route change
window.scrollTo({ top: 0, behavior: 'instant' });
};
window.addEventListener('hashchange', onChange);
if (!window.location.hash) {
window.history.replaceState(null, '', '#/');
}
return () => window.removeEventListener('hashchange', onChange);
}, []);
const navigate = React.useCallback((to) => {
if (to.startsWith('#')) to = to.slice(1);
if (!to.startsWith('/')) to = '/' + to;
if (to === path) return;
window.location.hash = to;
}, [path]);
return (
{children}
);
}
// Link component — uses navigate, falls back to anchor
function Link({ to, children, className, style, onClick, ...rest }) {
const { navigate } = useRouter();
const handle = (e) => {
e.preventDefault();
if (onClick) onClick(e);
navigate(to);
};
return (
{children}
);
}
window.RouterProvider = RouterProvider;
window.useRouter = useRouter;
window.Link = Link;