import { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef } from 'react' import Modal from 'react-bootstrap/Modal' import BackArrow from '@/svgs/arrow-left-line.svg' import { useRouter } from 'next/router' import ActionDropdown from './action-dropdown' export const ShowModalContext = createContext(() => null) export function ShowModalProvider ({ children }) { const [modal, showModal] = useModal() const contextValue = showModal return ( {children} {modal} ) } export function useShowModal () { return useContext(ShowModalContext) } export default function useModal () { const modalStack = useRef([]) const [render, forceUpdate] = useReducer(x => x + 1, 0) const getCurrentContent = useCallback(() => { return modalStack.current[modalStack.current.length - 1] }, []) const onBack = useCallback(() => { getCurrentContent()?.options?.onClose?.() modalStack.current.pop() forceUpdate() }, []) // this is called on every navigation due to below useEffect const onClose = useCallback(() => { while (modalStack.current.length) { getCurrentContent()?.options?.onClose?.() modalStack.current.pop() } forceUpdate() }, []) const router = useRouter() useEffect(() => { const maybeOnClose = () => { const content = getCurrentContent() const { persistOnNavigate } = content?.options || {} if (!persistOnNavigate) { onClose() } } router.events.on('routeChangeStart', maybeOnClose) return () => router.events.off('routeChangeStart', maybeOnClose) }, [router.events, onClose, getCurrentContent]) const modal = useMemo(() => { if (modalStack.current.length === 0) { return null } const content = getCurrentContent() const { overflow, keepOpen, fullScreen } = content.options || {} const className = fullScreen ? 'fullscreen' : '' return (
{overflow &&
{overflow}
} {modalStack.current.length > 1 ?
: null}
X
{content.node}
) }, [render]) const showModal = useCallback( (getContent, options) => { const ref = { node: getContent(onClose), options } if (options?.replaceModal) { modalStack.current = [ref] } else { modalStack.current.push(ref) } forceUpdate() }, [onClose] ) return [modal, showModal] }