diff --git a/client/src/features/CasperCustom/CasperCustomFinish.tsx b/client/src/features/CasperCustom/CasperCustomFinish.tsx index 54c4e1ed..4e0b8914 100644 --- a/client/src/features/CasperCustom/CasperCustomFinish.tsx +++ b/client/src/features/CasperCustom/CasperCustomFinish.tsx @@ -21,9 +21,13 @@ import ArrowIcon from "/public/assets/icons/arrow.svg?react"; interface CasperCustomFinishProps { handleResetStep: () => void; + unblockNavigation: () => void; } -export function CasperCustomFinish({ handleResetStep }: CasperCustomFinishProps) { +export function CasperCustomFinish({ + handleResetStep, + unblockNavigation, +}: CasperCustomFinishProps) { const [cookies] = useCookies([COOKIE_TOKEN_KEY]); const { @@ -41,6 +45,8 @@ export function CasperCustomFinish({ handleResetStep }: CasperCustomFinishProps) if (!cookies[COOKIE_TOKEN_KEY]) { return; } + + unblockNavigation(); getApplyCount(); }, [cookies]); diff --git a/client/src/features/CasperCustom/CasperCustomFinishing.tsx b/client/src/features/CasperCustom/CasperCustomFinishing.tsx index e99b4681..a5befcba 100644 --- a/client/src/features/CasperCustom/CasperCustomFinishing.tsx +++ b/client/src/features/CasperCustom/CasperCustomFinishing.tsx @@ -27,13 +27,18 @@ export function CasperCustomFinishing({ navigateNextStep }: CasperCustomFinishin useEffect(() => { showToast(); - setTimeout(() => { + const flipTimer = setTimeout(() => { setIsFlipped(true); }, 3000); - setTimeout(() => { + const navigateTimer = setTimeout(() => { navigateNextStep(); }, 6000); + + return () => { + clearTimeout(flipTimer); + clearTimeout(navigateTimer); + }; }, []); return ( diff --git a/client/src/hooks/useBlockNavigation.ts b/client/src/hooks/useBlockNavigation.ts new file mode 100644 index 00000000..e43d4c0c --- /dev/null +++ b/client/src/hooks/useBlockNavigation.ts @@ -0,0 +1,37 @@ +import { useEffect, useState } from "react"; +import { unstable_usePrompt, useLocation } from "react-router-dom"; + +export function useBlockNavigation(message: string) { + const location = useLocation(); + const [isBlocking, setIsBlocking] = useState(false); + + unstable_usePrompt({ when: isBlocking, message }); + + const unblockNavigation = () => { + setIsBlocking(false); + }; + + const handleBeforeUnload = (e: BeforeUnloadEvent) => { + if (isBlocking) { + e.preventDefault(); + e.returnValue = ""; + } + }; + + useEffect(() => { + setIsBlocking(true); + + return () => { + setIsBlocking(false); + }; + }, [location]); + useEffect(() => { + window.addEventListener("beforeunload", handleBeforeUnload); + + return () => { + window.removeEventListener("beforeunload", handleBeforeUnload); + }; + }, [isBlocking]); + + return { unblockNavigation }; +} diff --git a/client/src/pages/CasperCustom/index.tsx b/client/src/pages/CasperCustom/index.tsx index 91655af9..6155e1d9 100644 --- a/client/src/pages/CasperCustom/index.tsx +++ b/client/src/pages/CasperCustom/index.tsx @@ -14,12 +14,17 @@ import { CasperCustomForm, CasperCustomProcess, } from "@/features/CasperCustom"; +import { useBlockNavigation } from "@/hooks/useBlockNavigation"; import useHeaderStyleObserver from "@/hooks/useHeaderStyleObserver"; import { SCROLL_MOTION } from "../../constants/animation"; const INITIAL_STEP = 0; export default function CasperCustom() { + const { unblockNavigation } = useBlockNavigation( + "이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?" + ); + const containerRef = useHeaderStyleObserver({ darkSections: [CASPER_CUSTOM_SECTIONS.CUSTOM], }); @@ -28,7 +33,7 @@ export default function CasperCustom() { const selectedStep = CUSTOM_STEP_OPTION_ARRAY[selectedStepIdx]; const handleClickNextStep = () => { - setSelectedStepIdx(selectedStepIdx + 1); + setSelectedStepIdx((prevSelectedIdx) => prevSelectedIdx + 1); }; const handleResetStep = () => { @@ -43,7 +48,12 @@ export default function CasperCustom() { } else if (selectedStep === CUSTOM_STEP_OPTION.FINISHING) { return ; } else if (selectedStep === CUSTOM_STEP_OPTION.FINISH) { - return ; + return ( + + ); } return <>; }; diff --git a/client/src/types/lotteryApi.ts b/client/src/types/lotteryApi.ts index 3b7d9c40..55b5253d 100644 --- a/client/src/types/lotteryApi.ts +++ b/client/src/types/lotteryApi.ts @@ -24,8 +24,7 @@ export interface GetApplyCountResponse { } export interface GetLotteryResponse { - lotteryEventId: number; eventStartDate: string; eventEndDate: string; - winnerCount: number; + activePeriod: number; }