diff --git a/client/src/contexts/ConfirmModalContext.tsx b/client/src/contexts/ConfirmModalContext.tsx new file mode 100644 index 0000000..b18dc1c --- /dev/null +++ b/client/src/contexts/ConfirmModalContext.tsx @@ -0,0 +1,85 @@ +import { Modal } from '@/components/Modal' +import { ComponentChild, createContext } from 'preact' +import { useCallback, useContext, useMemo, useState } from 'preact/hooks' + +type Props = { + children: ComponentChild +} + +type ShowModalProps = { + content: ComponentChild + onConfirm: () => void + onCancel: () => void +} + +type ShowModelResult = { + show: () => void +} + +type ConfirmModalContext = { + createModal: (props: ShowModalProps) => ShowModelResult +} + +type ModalState = { + id: string + props: ShowModalProps +} + +const ConfirmModalContext = createContext(null) + +export const ConfirmModalContextProvider = ({ children }: Props) => { + const [modals, setModals] = useState([] as ModalState[]) + + const createModal = useCallback((props: ShowModalProps) => { + return { + show: () => + setModals((p) => [ + ...p, + { id: new Date().getTime().toString(), props }, + ]), + } + }, []) + + const handleClose = (modal: ModalState) => { + setModals((p) => p.filter((m) => m.id !== modal.id)) + + modal.props.onCancel() + } + + const handleConfirm = (modal: ModalState) => { + setModals((p) => p.filter((m) => m.id !== modal.id)) + + modal.props.onConfirm() + } + + const value = useMemo(() => ({ createModal }), [createModal]) + + return ( + + {children} + {modals.map((m) => ( + handleClose(m)}> + {m.props.content} + + + + ))} + + ) +} + +export const useConfirmModalContext = () => { + const ctx = useContext(ConfirmModalContext) + + if (!ctx) { + throw new Error('useConfirmModalContext used outside context') + } + + return ctx +} + +export const useConfirmModal = (modal: ShowModalProps) => { + const ctx = useConfirmModalContext() + + return ctx.createModal(modal) +}