'use client'; import { createContext, useContext, useEffect, useState } from 'react'; import { useNavigate } from 'react-router'; import { contextOutsideScope } from '@/utils/labels'; interface INavigationContext { push: (path: string, newTab?: boolean) => void; replace: (path: string) => void; back: () => void; forward: () => void; canBack: () => boolean; isBlocked: boolean; setIsBlocked: (value: boolean) => void; } const NavigationContext = createContext(null); export const useConceptNavigation = () => { const context = useContext(NavigationContext); if (!context) { throw new Error(contextOutsideScope('useConceptNavigation', 'NavigationState')); } return context; }; export const NavigationState = ({ children }: React.PropsWithChildren) => { const router = useNavigate(); const [isBlocked, setIsBlocked] = useState(false); function validate() { return !isBlocked || confirm('Изменения не сохранены. Вы уверены что хотите совершить переход?'); } function canBack() { return !!window.history && window.history?.length !== 0; } function push(path: string, newTab?: boolean) { if (newTab) { window.open(`${path}`, '_blank'); return; } if (validate()) { Promise.resolve(router(path, { viewTransition: true })).catch(console.error); setIsBlocked(false); } } function replace(path: string) { if (validate()) { Promise.resolve(router(path, { replace: true, viewTransition: true })).catch(console.error); setIsBlocked(false); } } function back() { if (validate()) { Promise.resolve(router(-1)).catch(console.error); setIsBlocked(false); } } function forward() { if (validate()) { Promise.resolve(router(1)).catch(console.error); setIsBlocked(false); } } return ( {children} ); }; export function useBlockNavigation(isBlocked: boolean) { const router = useConceptNavigation(); useEffect(() => { router.setIsBlocked(isBlocked); return () => router.setIsBlocked(false); }, [router, isBlocked]); }