'use client'; import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { globalIDs } from '@/utils/constants'; interface INavigationContext{ push: (path: string) => 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('useConceptNavigation has to be used within '); } return context; } interface NavigationStateProps { children: React.ReactNode } export const NavigationState = ({ children }: NavigationStateProps) => { const router = useNavigate(); const { pathname } = useLocation(); const [isBlocked, setIsBlocked] = useState(false); const validate = useCallback( () => { return ( !isBlocked || confirm('Изменения не сохранены. Вы уверены что хотите совершить переход?') ); }, [isBlocked]); const canBack = useCallback(() => (!!window.history && window.history?.length !== 0), []); const scrollTop = useCallback( () => { window.scrollTo(0, 0); const mainScroll = document.getElementById(globalIDs.main_scroll); if (mainScroll) { mainScroll.scroll(0,0); } }, []); const push = useCallback( (path: string) => { if (validate()) { scrollTop(); router(path); setIsBlocked(false); } }, [router, validate, scrollTop]); const replace = useCallback( (path: string) => { if (validate()) { scrollTop(); router(path, {replace: true}); setIsBlocked(false); } }, [router, validate, scrollTop]); const back = useCallback( () => { if (validate()) { scrollTop(); router(-1); setIsBlocked(false); } }, [router, validate, scrollTop]); const forward = useCallback( () => { if (validate()) { scrollTop(); router(1); setIsBlocked(false); } }, [router, validate, scrollTop]); useEffect(() => { scrollTop(); }, [pathname, scrollTop]); return ( {children} ); } export function useBlockNavigation(isBlocked: boolean) { const router = useConceptNavigation(); useEffect( () => { router.setIsBlocked(isBlocked); return () => router.setIsBlocked(false); }, [router, isBlocked]); }