dashboard-nanobot/frontend/src/utils/appRoute.ts

52 lines
1.6 KiB
TypeScript

import { useEffect, useState } from 'react';
export type AppRoute =
| { kind: 'dashboard' }
| { kind: 'dashboard-skills' }
| { kind: 'bot'; botId: string };
function parsePathname(pathname: string): AppRoute {
const raw = String(pathname || '/').trim() || '/';
if (/^\/dashboard\/skills\/?$/i.test(raw)) {
return { kind: 'dashboard-skills' };
}
const botMatch = raw.match(/^\/bot\/([^/?#]+)/i);
if (botMatch?.[1]) {
try {
return { kind: 'bot', botId: decodeURIComponent(botMatch[1]).trim() };
} catch {
return { kind: 'bot', botId: String(botMatch[1]).trim() };
}
}
return { kind: 'dashboard' };
}
export function readCompactModeFromUrl(): boolean {
if (typeof window === 'undefined') return false;
const params = new URLSearchParams(window.location.search);
const compactRaw = (params.get('compact') || params.get('h5') || params.get('mobile') || '').trim().toLowerCase();
return ['1', 'true', 'yes', 'on'].includes(compactRaw);
}
export function useAppRoute(): AppRoute {
const [route, setRoute] = useState<AppRoute>(() =>
typeof window === 'undefined' ? { kind: 'dashboard' } : parsePathname(window.location.pathname),
);
useEffect(() => {
if (typeof window === 'undefined') return;
const apply = () => {
const next = parsePathname(window.location.pathname);
setRoute(next);
if (window.location.pathname === '/') {
window.history.replaceState({}, '', '/dashboard');
}
};
apply();
window.addEventListener('popstate', apply);
return () => window.removeEventListener('popstate', apply);
}, []);
return route;
}