Files
stroy-bot-monorepo/src/webparts/stroyBot/app/routing/RouterContext.tsx
T
Тимур Городецкий d606f8371c feat: weather conditions check from stroy-bot-main
Ports the weather check added to stroy-bot-main on 2026-10-16: daily
station weather, report positions with weather per shift and the AI
assessment of working conditions. Opens as ?page=weather&start=&end=
instead of the #weathercheck hash, and hub dates survive the way back.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 09:47:02 +05:00

59 lines
2.3 KiB
TypeScript

import * as React from 'react';
import { buildSearch, IRoute, parseRoute } from './routes';
interface INavigateOptions {
/** Заменить текущую запись истории (replaceState), а не добавить новую. */
replace?: boolean;
}
interface IRouterValue {
route: IRoute;
/** Перейти в раздел: меняет адрес (history.pushState) и перерисовывает приложение. */
navigate: (route: IRoute, options?: INavigateOptions) => void;
/** Полный адрес раздела — для настоящих ссылок (Ctrl+клик, «открыть в новой вкладке»). */
buildHref: (route: IRoute) => string;
}
const RouterContext = React.createContext<IRouterValue | undefined>(undefined);
function readCurrentRoute(): IRoute {
return parseRoute(window.location.search);
}
function buildHref(route: IRoute): string {
return `${window.location.pathname}${buildSearch(route, window.location.search)}`;
}
export const RouterProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [route, setRoute] = React.useState<IRoute>(readCurrentRoute);
// Кнопки «назад/вперёд» браузера меняют адрес без нашего участия — перечитываем маршрут.
React.useEffect(() => {
const onPopState = (): void => setRoute(readCurrentRoute());
window.addEventListener('popstate', onPopState);
return () => window.removeEventListener('popstate', onPopState);
}, []);
const navigate = React.useCallback((next: IRoute, options: INavigateOptions = {}): void => {
if (options.replace) {
window.history.replaceState(undefined, '', buildHref(next));
} else {
window.history.pushState(undefined, '', buildHref(next));
}
setRoute(next);
window.scrollTo(0, 0);
}, []);
const value = React.useMemo<IRouterValue>(() => ({ route, navigate, buildHref }), [route, navigate]);
return <RouterContext.Provider value={value}>{children}</RouterContext.Provider>;
};
export function useRouter(): IRouterValue {
const router = React.useContext(RouterContext);
if (!router) {
throw new Error('useRouter: компонент отрисован вне RouterProvider');
}
return router;
}