ConceptPortal-public/rsconcept/frontend/src/context/NagivationContext.tsx

97 lines
2.3 KiB
TypeScript
Raw Normal View History

'use client';
2023-09-05 00:23:53 +03:00
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { unstable_usePrompt, useLocation, useNavigate } from 'react-router-dom';
import { globalIDs } from '@/utils/constants';
2023-09-05 00:23:53 +03:00
interface INagivationContext{
push: (path: string) => void
replace: (path: string) => void
back: () => void
forward: () => void
canBack: () => boolean
isBlocked: boolean
setIsBlocked: (value: boolean) => void
2023-09-05 00:23:53 +03:00
}
const NagivationContext = createContext<INagivationContext | null>(null);
export const useConceptNavigation = () => {
const context = useContext(NagivationContext);
if (!context) {
throw new Error('useConceptNavigation has to be used within <NavigationState.Provider>');
}
return context;
}
interface NavigationStateProps {
children: React.ReactNode
}
export const NavigationState = ({ children }: NavigationStateProps) => {
const router = useNavigate();
2023-09-05 00:23:53 +03:00
const { pathname } = useLocation();
const [isBlocked, setIsBlocked] = useState(false);
unstable_usePrompt({
when: isBlocked,
message: 'Изменения не сохранены. Вы уверены что хотите совершить переход?'
});
const canBack = useCallback(
() => {
return (!!window.history && window.history?.length !== 0);
}, []);
const scrollTop = useCallback(
() => {
2023-09-05 00:23:53 +03:00
window.scrollTo(0, 0);
const mainScroll = document.getElementById(globalIDs.main_scroll);
if (mainScroll) {
mainScroll.scroll(0,0);
}
}, []);
2023-09-05 00:23:53 +03:00
const push = useCallback(
(path: string) => {
2023-09-05 00:23:53 +03:00
scrollTop();
setIsBlocked(false);
router(path);
}, [router, scrollTop]);
2023-09-05 00:23:53 +03:00
const replace = useCallback(
(path: string) => {
2023-09-05 00:23:53 +03:00
scrollTop();
setIsBlocked(false);
router(path, {replace: true});
}, [router, scrollTop]);
2023-09-05 00:23:53 +03:00
const back = useCallback(
() => {
scrollTop();
setIsBlocked(false);
router(-1);
}, [router, scrollTop]);
const forward = useCallback(
() => {
2023-09-05 00:23:53 +03:00
scrollTop();
setIsBlocked(false);
router(1);
}, [router, scrollTop]);
2023-09-05 00:23:53 +03:00
useEffect(() => {
scrollTop();
}, [pathname, scrollTop]);
2023-09-05 00:23:53 +03:00
return (
<NagivationContext.Provider value={{
push, replace, back, forward,
canBack, isBlocked, setIsBlocked
}}>
{children}
</NagivationContext.Provider>);
2023-09-05 00:23:53 +03:00
}