sbt-idp/cope2n-fe/src/components/form-blocker/form-blocker.tsx
2024-01-31 11:08:20 +07:00

48 lines
1.4 KiB
TypeScript

import { ExclamationCircleOutlined } from '@ant-design/icons';
import { t } from '@lingui/macro';
import { Modal } from 'antd';
import { ANT_PREFIX_CLASS } from 'consts';
import React, { useEffect, useRef, useState } from 'react';
import { unstable_useBlocker as useBlocker } from 'react-router-dom';
function FormBlocker({ block }) {
const [isBlocking, setIsBlocking] = useState(false);
const [hasShownModal, setHasShownModal] = useState(false); // prevent multiple modals from showing
const nextLocationRef = useRef(null);
useBlocker((transition) => {
if (block) {
setIsBlocking(true);
nextLocationRef.current = transition.nextLocation;
setHasShownModal(false);
return !isBlocking;
}
return false;
});
useEffect(() => {
if (isBlocking && !hasShownModal) {
setHasShownModal(true);
Modal.confirm({
title: t`You have unsaved changes!`,
content: t`Are you sure you want to leave without saving?`,
icon: <ExclamationCircleOutlined />,
closable: true,
prefixCls: ANT_PREFIX_CLASS,
onOk() {
setIsBlocking(true);
window.location.href = nextLocationRef.current.pathname;
},
onCancel() {
setIsBlocking(false);
},
});
}
}, [isBlocking, nextLocationRef, hasShownModal]);
return <div key={block as unknown as React.Key}></div>;
}
export default FormBlocker;