diff --git a/src/components/calendar/index.tsx b/src/components/calendar/index.tsx index 848f1c02..9485b7ad 100644 --- a/src/components/calendar/index.tsx +++ b/src/components/calendar/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import classNames from 'classnames/bind'; @@ -47,6 +47,8 @@ const Calendar = ({ gameId }: CalendarProps) => { const { multiState, toggleClick } = useMultiState(['scheduleModal', 'confirmModal', 'errorModal']); const currentDeviceType = useDeviceType(); + const modalRef = useRef(null); + const yearString = currentYear.toString(); const monthString = currentMonth.toString().padStart(2, '0'); @@ -75,7 +77,7 @@ const Calendar = ({ gameId }: CalendarProps) => { queryKey: QUERY_KEYS.myActivities.getDetailReservationList(gameId, scheduleId!, 'pending'), }); }, - onError: () => toggleClick('errorModal'), + onError: () => handleToggleErrorModal(), }); const dropdownOptions = getScheduleDropdownOption(dailySchedules); @@ -98,7 +100,7 @@ const Calendar = ({ gameId }: CalendarProps) => { const handleScheduleClick = (date: string) => { setActiveDate(date); - toggleClick('scheduleModal'); + handleToggleScheduleModal(); }; const handleConfirmClick = (scheduleId: number, reservationId: number, status: ReservationStatus) => { @@ -106,24 +108,24 @@ const Calendar = ({ gameId }: CalendarProps) => { setReservationId(reservationId); setReservationStatus(status); - toggleClick('scheduleModal'); - toggleClick('confirmModal'); + handleToggleScheduleModal(); + handleToggleConfirmModal(); }; const handleChangeReservationStatus = () => { changeStatusMutation({ activityId: gameId, reservationId: reservationId!, status: { status: reservationStatus } }); - toggleClick('confirmModal'); + handleToggleConfirmModal(); }; - const handleCloseScheduleModal = () => { + const handleToggleScheduleModal = () => { toggleClick('scheduleModal'); }; - const handleCloseConfirmModal = () => { + const handleToggleConfirmModal = () => { toggleClick('confirmModal'); }; - const handleCloseErrorModal = () => { + const handleToggleErrorModal = () => { toggleClick('errorModal'); }; @@ -131,6 +133,19 @@ const Calendar = ({ gameId }: CalendarProps) => { if (currentDeviceType !== 'PC') setIsCalendar(false); }, [currentDeviceType]); + useEffect(() => { + const listener = (event: MouseEvent) => { + if (!modalRef.current || modalRef.current.contains(event.target as Node)) return; + handleToggleScheduleModal(); + }; + + document.addEventListener('mousedown', listener); + + return () => { + document.removeEventListener('mousedown', listener); + }; + }, [modalRef, handleToggleScheduleModal]); + return ( <>
@@ -155,16 +170,17 @@ const Calendar = ({ gameId }: CalendarProps) => { {isSuccess && dropdownOptions.length !== 0 && ( } @@ -174,7 +190,7 @@ const Calendar = ({ gameId }: CalendarProps) => { { 확인 - 취소 + 취소 } /> 닫기} + renderButton={닫기} > ); diff --git a/src/components/commons/modals/CustomCommonModal.tsx b/src/components/commons/modals/CustomCommonModal.tsx index 264ce77a..9d9ad76f 100644 --- a/src/components/commons/modals/CustomCommonModal.tsx +++ b/src/components/commons/modals/CustomCommonModal.tsx @@ -1,6 +1,6 @@ import Image from 'next/image'; -import { ReactNode, MouseEventHandler, useState, useEffect } from 'react'; +import { ReactNode, MouseEventHandler, useState, useEffect, RefObject } from 'react'; import classNames from 'classnames/bind'; @@ -18,9 +18,17 @@ type CustomCommonModalProps = { title: string; renderContent: ReactNode; isCalendar: boolean; + modalRef: RefObject; }; -export const CustomCommonModal = ({ openModal, onClose, title, renderContent, isCalendar }: CustomCommonModalProps) => { +export const CustomCommonModal = ({ + openModal, + onClose, + title, + renderContent, + isCalendar, + modalRef, +}: CustomCommonModalProps) => { const [isOpen, setIsOpen] = useState(false); useEffect(() => { @@ -38,7 +46,11 @@ export const CustomCommonModal = ({ openModal, onClose, title, renderContent, is return ( isOpen && (
-
+