import { DialogTrigger } from '@radix-ui/react-dialog'; import clsx from 'clsx'; import type { PropsWithChildren } from 'react'; import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import type { ButtonProps } from '../button'; import { Button } from '../button'; import type { ModalProps } from './modal'; import { Modal } from './modal'; import * as styles from './styles.css'; export interface ConfirmModalProps extends ModalProps { confirmButtonOptions?: Omit; onConfirm?: (() => void) | (() => Promise); onCancel?: () => void; confirmText?: React.ReactNode; cancelText?: React.ReactNode; cancelButtonOptions?: Omit; reverseFooter?: boolean; autoFocusConfirm?: boolean; } export const ConfirmModal = ({ children, confirmButtonOptions, confirmText = 'Confirm', cancelText = 'Cancel', cancelButtonOptions, reverseFooter, onConfirm, onCancel, width = 480, autoFocusConfirm = true, ...props }: ConfirmModalProps) => { // 서버에서 데이터 가져오기 // useEffect(() => { // const fetchData = async () => { // try { // const productsResponse = await axios.get('/api/auth/arms/pdService'); // setProductOptions( // productsResponse.data.map((item: any) => ({ // key: item.name, // cat: item.category, // })) // ); // // const versionsResponse = await axios.get('/api/auth/arms/pdServiceVersion + 선택한 제품(서비스)'); // setVersionOptions( // versionsResponse.data.map((item: any) => ({ // key: item.version, // cat: item.category, // })) // ); // } catch (error) { // console.error('데이터 로드 실패:', error); // } // }; // // fetchData(); // }, []); const onConfirmClick = useCallback(() => { Promise.resolve(onConfirm?.()).catch((err) => { console.error(err); }); }, [onConfirm]); return ( { e.stopPropagation(); onCancel?.(); }, }} width={width} closeButtonOptions={{ onClick: onCancel, }} {...props} > {children ? (
{children}
) : null}
); }; interface OpenConfirmModalOptions { autoClose?: boolean; onSuccess?: () => void; } interface ConfirmModalContextProps { modalProps: ConfirmModalProps; openConfirmModal: ( props?: ConfirmModalProps, options?: OpenConfirmModalOptions ) => void; closeConfirmModal: () => void; } const ConfirmModalContext = createContext({ modalProps: { open: false }, openConfirmModal: () => {}, closeConfirmModal: () => {}, }); export const ConfirmModalProvider = ({ children }: PropsWithChildren) => { const [modalProps, setModalProps] = useState({ open: false, }); const setLoading = useCallback((value: boolean) => { setModalProps((prev) => ({ ...prev, confirmButtonOptions: { ...prev.confirmButtonOptions, loading: value, }, })); }, []); const closeConfirmModal = useCallback(() => { setModalProps({ open: false }); }, []); const openConfirmModal = useCallback( (props?: ConfirmModalProps, options?: OpenConfirmModalOptions) => { const { autoClose = true, onSuccess } = options ?? {}; if (!props) { setModalProps({ open: true }); return; } const { onConfirm: _onConfirm, ...otherProps } = props; const onConfirm = () => { setLoading(true); return Promise.resolve(_onConfirm?.()) .then(() => onSuccess?.()) .catch(console.error) .finally(() => setLoading(false)) .finally(() => autoClose && closeConfirmModal()); }; setModalProps({ ...otherProps, onConfirm, open: true }); }, [closeConfirmModal, setLoading] ); const onOpenChange = useCallback( (open: boolean) => { modalProps.onOpenChange?.(open); setModalProps((props) => ({ ...props, open })); }, [modalProps] ); return ( {children} ); }; export const useConfirmModal = () => { const context = useContext(ConfirmModalContext); if (!context) { throw new Error( 'useConfirmModal must be used within a ConfirmModalProvider' ); } return { openConfirmModal: context.openConfirmModal, closeConfirmModal: context.closeConfirmModal, }; };