From 5afd2bea84d496dda970c39eb97c6d5d03167155 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Mon, 19 Aug 2024 17:49:16 +0900
Subject: [PATCH 01/36] =?UTF-8?q?chore:=20test=20API=20=EC=82=AD=EC=A0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/features/Main/Headline.tsx | 8 --------
1 file changed, 8 deletions(-)
diff --git a/client/src/features/Main/Headline.tsx b/client/src/features/Main/Headline.tsx
index 4f05c807..659e6b58 100644
--- a/client/src/features/Main/Headline.tsx
+++ b/client/src/features/Main/Headline.tsx
@@ -1,12 +1,10 @@
import { memo, useEffect } from "react";
import { motion } from "framer-motion";
-import { RushAPI } from "@/apis/rushAPI.ts";
import { TotalAPI } from "@/apis/totalAPI.ts";
import Keyword from "@/components/Keyword";
import Scroll from "@/components/Scroll";
import { ASCEND, ASCEND_DESCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { RushEventStatusCodeResponse } from "@/types/rushApi.ts";
import { SectionKeyProps } from "@/types/sections.ts";
import { GetTotalEventDateResponse } from "@/types/totalApi.ts";
import { formatEventDateRangeWithDot } from "@/utils/formatDate.ts";
@@ -16,11 +14,6 @@ interface HeadlineProps extends SectionKeyProps {
}
function Headline({ id, handleClickScroll }: HeadlineProps) {
- // DATA RESET TEST API
- const { fetchData: getRushTodayEventTest } = useFetch(() =>
- RushAPI.getRushTodayEventTest()
- );
-
const {
data: totalData,
isSuccess: isSuccessTotalData,
@@ -28,7 +21,6 @@ function Headline({ id, handleClickScroll }: HeadlineProps) {
} = useFetch(() => TotalAPI.getTotal());
useEffect(() => {
- getRushTodayEventTest();
getTotal();
}, []);
From bdf98fcf834fa6302f60f3fe18d154c2d9a937c8 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Mon, 19 Aug 2024 18:38:22 +0900
Subject: [PATCH 02/36] =?UTF-8?q?feat:=20=EC=84=A0=EC=B0=A9=EC=88=9C=20?=
=?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=83=88=EB=A1=9C=EA=B3=A0=EC=B9=A8=20?=
=?UTF-8?q?=EB=B0=8F=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B0=A9?=
=?UTF-8?q?=EC=A7=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/pages/RushGame/index.tsx | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index f526004c..0531f14c 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -6,12 +6,16 @@ import CardOptions from "@/features/RushGame/RushGameSections/CardOptions.tsx";
import Countdown from "@/features/RushGame/RushGameSections/Countdown.tsx";
import FinalResult from "@/features/RushGame/RushGameSections/FinalResult.tsx";
import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx";
+import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToast from "@/hooks/useToast.tsx";
import { writeClipboard } from "@/utils/writeClipboard.ts";
-// TODO: 계속 카운트 다운에 맞춰 매초 렌더링 되는 문제 해결
export default function RushGame() {
+ useBlockNavigation(
+ "이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
+ );
+
const { gameState } = useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
From 47d5f69fe22b685a2f32fa15a33f48940084a332 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Mon, 19 Aug 2024 18:50:17 +0900
Subject: [PATCH 03/36] =?UTF-8?q?feat:=20FinalResult=20=ED=99=94=EB=A9=B4?=
=?UTF-8?q?=EC=97=90=EC=84=9C=20unblockNavigation=20=ED=98=B8=EC=B6=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameSections/FinalResult.tsx | 12 +++++++++---
client/src/pages/RushGame/index.tsx | 4 ++--
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 8d196f37..bd781b88 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -22,7 +22,11 @@ function getWinStatus(ratio: number, oppositeRatio: number): WinStatus {
return ratio > oppositeRatio ? WIN_STATUS.WIN : WIN_STATUS.LOSE;
}
-export default function FinalResult() {
+interface FinalResultProps {
+ unblockNavigation: () => void;
+}
+
+export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
const { gameState, getOptionRatio, getSelectedCardInfo, updateCardOptions } =
useRushGameContext();
@@ -31,12 +35,14 @@ export default function FinalResult() {
data: resultData,
isSuccess: isSuccessRushResult,
fetchData: getRushResult,
- } = useFetch(() =>
- RushAPI.getRushResult(cookies[COOKIE_KEY.ACCESS_TOKEN])
+ } = useFetch(
+ () => RushAPI.getRushResult(cookies[COOKIE_KEY.ACCESS_TOKEN]),
+ false
);
useEffect(() => {
getRushResult();
+ unblockNavigation();
}, []);
useEffect(() => {
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index 0531f14c..47586920 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -12,7 +12,7 @@ import useToast from "@/hooks/useToast.tsx";
import { writeClipboard } from "@/utils/writeClipboard.ts";
export default function RushGame() {
- useBlockNavigation(
+ const { unblockNavigation } = useBlockNavigation(
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
@@ -34,7 +34,7 @@ export default function RushGame() {
return ;
}
case CARD_PHASE.COMPLETED:
- return ;
+ return ;
default:
return null;
}
From 974d8f29f40b1c58fc5f9188ac219ecf7f92d4f6 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 11:12:22 +0900
Subject: [PATCH 04/36] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?=
=?UTF-8?q?=EA=B0=80=20=EC=9D=B4=EB=AF=B8=20=EC=98=B5=EC=85=98=20=EC=84=A0?=
=?UTF-8?q?=ED=83=9D=ED=95=9C=20=ED=9B=84=EC=97=90=EB=8A=94=20=EC=83=88?=
=?UTF-8?q?=EB=A1=9C=EA=B3=A0=EC=B9=A8/=EB=92=A4=EB=A1=9C=EA=B0=80?=
=?UTF-8?q?=EA=B8=B0=20=EB=B0=A9=EC=A7=80=20=ED=92=80=EA=B8=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameSections/SelectedCard.tsx | 13 +++++++++----
client/src/pages/RushGame/index.tsx | 2 +-
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
index ccd692b7..d81384aa 100644
--- a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
+++ b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
@@ -9,11 +9,11 @@ import useToggleContents from "@/hooks/useToggleContents.ts";
import ArrowLeftIcon from "/public/assets/icons/arrow-line-left.svg?react";
import ArrowRightIcon from "/public/assets/icons/arrow-line-right.svg?react";
-interface SelectedCardProps {
+interface SelectedCardDetailsProps {
onClick: () => void;
}
-function SelectedCardDescription({ onClick }: SelectedCardProps) {
+function SelectedCardDescription({ onClick }: SelectedCardDetailsProps) {
return (
@@ -32,7 +32,7 @@ function SelectedCardDescription({ onClick }: SelectedCardProps) {
);
}
-function SelectedCardCurrentRatio({ onClick }: SelectedCardProps) {
+function SelectedCardCurrentRatio({ onClick }: SelectedCardDetailsProps) {
return (
@@ -51,12 +51,17 @@ function SelectedCardCurrentRatio({ onClick }: SelectedCardProps) {
);
}
-export default function SelectedCard() {
+interface SelectedCardProps {
+ unblockNavigation: () => void;
+}
+
+export default function SelectedCard({ unblockNavigation }: SelectedCardProps) {
const { toggleContents, toggle } = useToggleContents({ useDuration: false });
const { fetchRushBalance } = useRushGameContext();
useEffect(() => {
fetchRushBalance();
+ unblockNavigation();
}, []);
return (
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index 47586920..bf236939 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -31,7 +31,7 @@ export default function RushGame() {
if (!gameState.userParticipatedStatus) {
return ;
} else {
- return ;
+ return ;
}
case CARD_PHASE.COMPLETED:
return ;
From 1c0df684d32a47f3bb6d145e4e1bac9a5a1bdb4c Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 11:27:49 +0900
Subject: [PATCH 05/36] =?UTF-8?q?chore:=20=ED=98=84=EC=9E=AC=20=EC=8B=9C?=
=?UTF-8?q?=EA=B0=84=EC=9D=84=20=EC=84=9C=EB=B2=84=20=EC=8B=9C=EA=B0=84?=
=?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/features/Rush/Common/Headline.tsx | 2 +-
client/src/pages/Lottery/index.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/client/src/features/Rush/Common/Headline.tsx b/client/src/features/Rush/Common/Headline.tsx
index 379fb7cf..7a780002 100644
--- a/client/src/features/Rush/Common/Headline.tsx
+++ b/client/src/features/Rush/Common/Headline.tsx
@@ -33,7 +33,7 @@ export function Headline({ id, handleClickScroll }: HeadlineProps) {
// TODO: 당일 이벤트 종료 시 참여 여부를 기준으로 분기 처리 (T: FinalResult() / F: 이벤트 참여 기간 아님)
const startDate = getMsTime(rushData.eventStartDate);
const endDate = getMsTime(rushData.eventEndDate);
- const currentDate = new Date().getTime();
+ const currentDate = getMsTime(rushData.serverTime);
const isEventPeriod = currentDate >= startDate && currentDate <= endDate;
diff --git a/client/src/pages/Lottery/index.tsx b/client/src/pages/Lottery/index.tsx
index 9c6922bc..cca523f5 100644
--- a/client/src/pages/Lottery/index.tsx
+++ b/client/src/pages/Lottery/index.tsx
@@ -47,7 +47,7 @@ export default function Lottery() {
const handleClickShortCut = useCallback(() => {
const startDate = getMsTime(lotteryData.eventStartDate);
const endDate = getMsTime(lotteryData.eventEndDate);
- const currentDate = new Date().getTime();
+ const currentDate = getMsTime(lotteryData.serverDateTime);
const isEventPeriod = currentDate >= startDate && currentDate <= endDate;
From 9ab86d241f4c7335a0973a0e844409219f3a3406 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 13:44:16 +0900
Subject: [PATCH 06/36] =?UTF-8?q?feat:=200%=EC=9D=BC=20=EB=95=8C=20?=
=?UTF-8?q?=ED=94=84=EB=A1=9C=EA=B7=B8=EB=9E=98=EC=8A=A4=EB=B0=94=20?=
=?UTF-8?q?=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameComponents/RushBar.tsx | 13 +++++++++++--
.../RushGame/RushGameComponents/RushProgressBar.tsx | 5 +++++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/client/src/features/RushGame/RushGameComponents/RushBar.tsx b/client/src/features/RushGame/RushGameComponents/RushBar.tsx
index ef9c8cae..aaa51c86 100644
--- a/client/src/features/RushGame/RushGameComponents/RushBar.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushBar.tsx
@@ -7,6 +7,7 @@ const barVariants = cva(`flex items-center`, {
red: "bg-gradient-red",
blue: "bg-gradient-blue",
yellow: "bg-gradient-yellow",
+ gray: "bg-n-neutral-100",
},
status: {
winning: "text-n-neutral-950",
@@ -26,11 +27,19 @@ type BarVariantsProps = VariantProps;
interface BarProps extends BarVariantsProps {
ratio: number;
+ isAllZero: boolean;
}
-export default function RushBar({ ratio, color, status, textAlign }: BarProps) {
+export default function RushBar({ ratio, color, status, textAlign, isAllZero }: BarProps) {
+ const barColor = isAllZero ? "gray" : color;
+ const barStatus = isAllZero ? "losing" : status;
+ const barWidth = isAllZero ? "50%" : `${ratio}%`;
+
return (
-
+
{ratio}%
);
diff --git a/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx b/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
index 0f7a35cb..7e34d907 100644
--- a/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
@@ -12,7 +12,10 @@ export default function RushProgressBar({
rightOptionRatio,
}: RushProgressBarProps) {
const { gameState } = useRushGameContext();
+
const isCompleted = gameState.phase === CARD_PHASE.COMPLETED;
+ const isAllZero = leftOptionRatio === 0 && rightOptionRatio === 0;
+
const leftStatus = isCompleted && leftOptionRatio < rightOptionRatio ? "losing" : "winning";
const rightStatus = isCompleted && rightOptionRatio < leftOptionRatio ? "losing" : "winning";
@@ -23,12 +26,14 @@ export default function RushProgressBar({
color={CARD_COLOR.GREEN}
status={leftStatus}
textAlign="left"
+ isAllZero={isAllZero}
/>
);
From 36365dc7b6bdf7ad59cbd5f1c2de3b43740b4dd3 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 13:47:03 +0900
Subject: [PATCH 07/36] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EC=9D=91?=
=?UTF-8?q?=EB=AA=A8=20=EC=97=AC=EB=B6=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20?=
=?UTF-8?q?FinalResult=20=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushResultOptionDisplay.tsx | 6 ++++-
.../RushGame/RushGameSections/FinalResult.tsx | 26 ++++++++++++-------
client/src/types/rushGame.ts | 1 +
3 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/client/src/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx b/client/src/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx
index b33c8aaf..850b1321 100644
--- a/client/src/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx
@@ -5,12 +5,14 @@ interface RushResultOptionDisplayProps {
mainText: string;
winStatus: WinStatus;
isUserSelected: boolean;
+ userParticipatedStatus: boolean;
}
export default function RushResultOptionDisplay({
mainText,
winStatus,
isUserSelected,
+ userParticipatedStatus,
}: RushResultOptionDisplayProps) {
const categoryType = winStatus === "Win" ? "limited" : "basic";
return (
@@ -21,7 +23,9 @@ export default function RushResultOptionDisplay({
{mainText}
{winStatus}
- {isUserSelected && 당신의 선택}
+ {userParticipatedStatus && isUserSelected && (
+ 당신의 선택
+ )}
);
}
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index bd781b88..1ddc0679 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -58,7 +58,9 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
}
}, [resultData, isSuccessRushResult, updateCardOptions]);
- const isWinner = resultData?.winner;
+ const userParticipatedStatus = gameState.userParticipatedStatus;
+
+ const isWinner = resultData?.isWinner;
const rank = resultData?.rank || 0;
const totalParticipants = resultData?.totalParticipants || 0;
@@ -84,16 +86,18 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
입력하신 전화번호로 경품 수령 관련 메시지가 전송될 예정이에요.
-
- 나의 선착순 등수
-
- {rank}등
-
- / {totalParticipants.toLocaleString("en-US")}명 중
-
+ {userParticipatedStatus && (
+
+ 나의 선착순 등수
+
+ {rank}등
+
+ / {totalParticipants.toLocaleString("en-US")}명 중
+
+
-
-
+ )}
+
최종 밸런스 게임 결과
) => void;
+ updateUserStatus: (token: string) => Promise;
updateUserStatusAndSelectedOption: (token: string, selectedOption: CardOption) => Promise;
getSelectedCardInfo: (option: CardOption) => CardOptionState;
getOptionRatio: (option: CardOption) => number;
From 107a778d8d437b1c31f032f814ef0560aac6956b Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 13:52:41 +0900
Subject: [PATCH 08/36] =?UTF-8?q?fix:=20result=20API=20=EB=8D=B0=EC=9D=B4?=
=?UTF-8?q?=ED=84=B0=20=EB=B0=98=ED=99=98=20=ED=83=80=EC=9E=85=20=EB=B3=80?=
=?UTF-8?q?=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/types/rushApi.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/client/src/types/rushApi.ts b/client/src/types/rushApi.ts
index bf87b6af..4d1c9429 100644
--- a/client/src/types/rushApi.ts
+++ b/client/src/types/rushApi.ts
@@ -40,9 +40,9 @@ export interface GetRushBalanceResponse {
}
export interface GetRushResultResponse {
- winner: boolean;
+ isWinner?: boolean;
leftOption: number;
rightOption: number;
- rank: number;
- totalParticipants: number;
+ rank?: number;
+ totalParticipants?: number;
}
From c59978ef044e00b4948e32ffea89e19597cbf9c5 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 14:27:00 +0900
Subject: [PATCH 09/36] =?UTF-8?q?chore:=20=ED=95=84=EC=9A=94=20=EC=97=86?=
=?UTF-8?q?=EB=8A=94=20TODO=20=EC=82=AD=EC=A0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/features/Rush/Common/Headline.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/client/src/features/Rush/Common/Headline.tsx b/client/src/features/Rush/Common/Headline.tsx
index 7a780002..aad6d7ab 100644
--- a/client/src/features/Rush/Common/Headline.tsx
+++ b/client/src/features/Rush/Common/Headline.tsx
@@ -30,7 +30,6 @@ export function Headline({ id, handleClickScroll }: HeadlineProps) {
const { showToast, ToastComponent } = useToast("이벤트 기간이 아닙니다");
const handleClickShortCut = useCallback(() => {
- // TODO: 당일 이벤트 종료 시 참여 여부를 기준으로 분기 처리 (T: FinalResult() / F: 이벤트 참여 기간 아님)
const startDate = getMsTime(rushData.eventStartDate);
const endDate = getMsTime(rushData.eventEndDate);
const currentDate = getMsTime(rushData.serverTime);
From 07ce1ba1478a399ca068b503522e97122a032d4c Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Tue, 20 Aug 2024 19:38:26 +0900
Subject: [PATCH 10/36] =?UTF-8?q?feat:=20resultAPI=EC=9D=98=20optionId=20?=
=?UTF-8?q?=EC=B6=94=EA=B0=80=20=ED=9B=84=20=EC=82=AC=EC=9A=A9=EC=9E=90?=
=?UTF-8?q?=EA=B0=80=20=EC=84=A0=ED=83=9D=ED=95=9C=20optionId=20=EB=B0=98?=
=?UTF-8?q?=EC=98=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameSections/FinalResult.tsx | 13 ++++++++++---
client/src/types/rushApi.ts | 5 ++++-
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 1ddc0679..1b14ef71 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -28,8 +28,13 @@ interface FinalResultProps {
export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, getOptionRatio, getSelectedCardInfo, updateCardOptions } =
- useRushGameContext();
+ const {
+ gameState,
+ getOptionRatio,
+ getSelectedCardInfo,
+ updateCardOptions,
+ setUserSelectedOption,
+ } = useRushGameContext();
const {
data: resultData,
@@ -47,7 +52,9 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
useEffect(() => {
if (resultData && isSuccessRushResult) {
- const { leftOption, rightOption } = resultData;
+ const { optionId, leftOption, rightOption } = resultData;
+
+ if (optionId) setUserSelectedOption(optionId);
updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
selectionCount: leftOption,
diff --git a/client/src/types/rushApi.ts b/client/src/types/rushApi.ts
index 4d1c9429..660cb652 100644
--- a/client/src/types/rushApi.ts
+++ b/client/src/types/rushApi.ts
@@ -1,3 +1,5 @@
+import { CardOption } from "@/types/rushGame.ts";
+
interface RushEventType {
rushEventId: number;
startDateTime: string;
@@ -34,12 +36,13 @@ export interface GetRushOptionResultResponse {
}
export interface GetRushBalanceResponse {
- optionId: number;
+ optionId: CardOption;
leftOption: number;
rightOption: number;
}
export interface GetRushResultResponse {
+ optionId?: CardOption;
isWinner?: boolean;
leftOption: number;
rightOption: number;
From cd41ede310fe687e507d0b586a0fb5f05b60e7a8 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 00:18:42 +0900
Subject: [PATCH 11/36] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=A7=84?=
=?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20=ED=98=84=EC=9E=AC=20=EA=B2=8C=EC=9E=84?=
=?UTF-8?q?=20=EC=A7=84=ED=96=89=20=EC=83=81=ED=83=9C=20=EB=B0=8F=20?=
=?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B0=B8=EC=97=AC=20=EC=97=AC?=
=?UTF-8?q?=EB=B6=80=20=EC=A0=80=EC=9E=A5=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?=
=?UTF-8?q?=ED=98=84=20=EB=B0=8F=20=EC=B9=B4=EC=9A=B4=ED=8A=B8=20=EB=8B=A4?=
=?UTF-8?q?=EC=9A=B4=20=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 103 +++++-------------
.../RushGameComponents/RushCountdown.tsx | 52 ++++++++-
.../RushGame/RushGameSections/Countdown.tsx | 54 ++++++++-
client/src/hooks/useCountdown.ts | 15 ++-
client/src/pages/RushGame/index.tsx | 35 +++++-
client/src/types/rushGame.ts | 6 +-
6 files changed, 177 insertions(+), 88 deletions(-)
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index 9718f103..e84e9ca7 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -4,7 +4,6 @@ import { useLoaderData } from "react-router-dom";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard";
import { COOKIE_KEY } from "@/constants/cookie.ts";
-import useCountdown from "@/hooks/useCountdown.ts";
import useFetch from "@/hooks/useFetch.ts";
import {
GetRushBalanceResponse,
@@ -17,11 +16,8 @@ import { getMsTime } from "@/utils/getMsTime.ts";
export const RushGameContext = createContext(undefined);
export const RushGameProvider = ({ children }: { children: ReactNode }) => {
- // const navigate = useNavigate();
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
const rushData = useLoaderData() as GetTotalRushEventsResponse;
- const [initialPreCountdown, setInitialPreCountdown] = useState(null);
- const [initialRunCountdown, setInitialRunCountdown] = useState(null);
const [gameState, setGameState] = useState({
phase: CARD_PHASE.NOT_STARTED,
@@ -72,14 +68,13 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
[]
);
- const {
- data: userParticipatedStatus,
- isSuccess: isSuccessUserParticipationStatus,
- fetchData: getRushUserParticipationStatus,
- } = useFetch((token) =>
- RushAPI.getRushUserParticipationStatus(token)
- );
+ const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
+ GetRushUserParticipationStatusResponse,
+ string
+ >((token) => RushAPI.getRushUserParticipationStatus(token));
+ // TODO: 상태 업데이트랑 옵션 업데이트 분리할까? 어차피 setUserSelectedOption이랑 setUserParticipationStatus 함수 다 내려줄건데 뭐하러 이렇게 하남..?
+ // TODO: 그냥 updateUserStatusAndSelectedOption 이 함수 호출해주는 곳에서 RushAPI.getRushUserParticipationStatus 이거 호출해주고, setUserSelectedOption 함수만 받아서 쓰면 될 것 같은데
const updateUserStatusAndSelectedOption = useCallback(
async (token: string, selectedOption: CardOption) => {
await getRushUserParticipationStatus(token);
@@ -89,10 +84,10 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
);
useEffect(() => {
- if (isSuccessUserParticipationStatus && userParticipatedStatus) {
+ if (userParticipatedStatus !== null) {
setUserParticipationStatus(userParticipatedStatus);
}
- }, [isSuccessUserParticipationStatus, userParticipatedStatus]);
+ }, [userParticipatedStatus]);
const getSelectedCardInfo = useCallback(
(option: CardOption) => {
@@ -145,79 +140,39 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
);
useEffect(() => {
- const currentEvent = rushData.events.find(
- (event) => event.rushEventId === rushData.todayEventId
- );
- if (currentEvent) {
- const serverTime = getMsTime(rushData.serverTime);
- const startTime = getMsTime(currentEvent.startDateTime);
- const endTime = getMsTime(currentEvent.endDateTime);
-
- if (
- gameState.phase === CARD_PHASE.NOT_STARTED &&
- rushData.serverTime &&
- currentEvent?.startDateTime
- ) {
- const preCountdown = Math.max(0, Math.floor((startTime - serverTime) / 1000));
- setInitialPreCountdown(preCountdown);
- } else if (
- gameState.phase === CARD_PHASE.IN_PROGRESS &&
- rushData.serverTime &&
- currentEvent?.endDateTime
- ) {
- const runCountdown = Math.max(0, Math.floor((endTime - serverTime) / 1000));
- setInitialRunCountdown(runCountdown);
+ if (rushData) {
+ const currentEvent = rushData.events.find(
+ (event) => event.rushEventId === rushData.todayEventId
+ );
+
+ if (currentEvent) {
+ const serverTime = getMsTime(rushData.serverTime);
+ const startTime = getMsTime(currentEvent.startDateTime);
+ const endTime = getMsTime(currentEvent.endDateTime);
+
+ if (serverTime < startTime) {
+ setGamePhase(CARD_PHASE.NOT_STARTED);
+ } else if (serverTime >= startTime && serverTime <= endTime) {
+ setGamePhase(CARD_PHASE.IN_PROGRESS);
+ } else if (serverTime > endTime) {
+ setGamePhase(CARD_PHASE.COMPLETED);
+ }
}
}
- }, [rushData, gameState.phase]);
-
- const preCountdown = useCountdown(initialPreCountdown || 1);
- const runCountdown = useCountdown(initialRunCountdown || 1);
-
- // TEST COUNTDOWN CODE
- // const preCountdown = useCountdown(5);
- // const runCountdown = useCountdown(20);
-
- useEffect(() => {
- if (preCountdown <= 0 && gameState.phase === CARD_PHASE.NOT_STARTED) {
- setGamePhase(CARD_PHASE.IN_PROGRESS);
- } else if (runCountdown <= 0 && gameState.phase === CARD_PHASE.IN_PROGRESS) {
- setGamePhase(CARD_PHASE.COMPLETED);
- }
- }, [preCountdown, runCountdown]);
-
- // useEffect(() => {
- // const currentEvent = rushData.events.find(
- // (event) => event.rushEventId === rushData.todayEventId
- // );
- //
- // if (currentEvent && gameState.phase === CARD_PHASE.COMPLETED) {
- // const serverTime = getMsTime(rushData.serverTime);
- // const endTime = getMsTime(currentEvent.endDateTime);
- //
- // if (!gameState.userParticipatedStatus) {
- // if (serverTime > endTime) {
- // navigate("/rush");
- // // TODO: 이벤트 참여기간 아닌 분기 처리(이벤트 종료 후 그 당일 12시 직전까지)
- // }
- // } else {
- // // TODO: 참여한 사람일 경우 당일 12시 직전까지 계속 "COMPLETED" 상태 유지
- // // TODO: 12시 지나면 다시 "NOT_STARTED" 상태로 변경
- // }
- // }
- // }, [gameState.phase, gameState.userParticipatedStatus, rushData, navigate]);
+ }, [rushData, setGamePhase]);
return (
{children}
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index 5fcb173b..b05c248d 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -1,5 +1,12 @@
+import { useEffect, useState } from "react";
+import { RushAPI } from "@/apis/rushAPI.ts";
+import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import useCountdown from "@/hooks/useCountdown.ts";
+import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { formatTime } from "@/utils/formatTime.ts";
+import { getMsTime } from "@/utils/getMsTime.ts";
function TimeDisplay({ label, value }: { label: string; value: string }) {
return (
@@ -11,7 +18,50 @@ function TimeDisplay({ label, value }: { label: string; value: string }) {
}
export default function RushCountdown() {
- const { runCountdown } = useRushGameContext();
+ const [initialRunCountdown, setInitialRunCountdown] = useState(null);
+ const { gameState, setGamePhase } = useRushGameContext();
+
+ const {
+ data: rushData,
+ isSuccess: isSuccessRush,
+ fetchData: getRush,
+ } = useFetch(() => RushAPI.getRush());
+
+ useEffect(() => {
+ getRush();
+ }, []);
+
+ useEffect(() => {
+ if (isSuccessRush && rushData) {
+ const currentEvent = rushData.events.find(
+ (event) => event.rushEventId === rushData.todayEventId
+ );
+
+ if (currentEvent) {
+ const serverTime = getMsTime(rushData.serverTime);
+ const endTime = getMsTime(currentEvent.endDateTime);
+
+ setInitialRunCountdown(Math.max(0, Math.floor((endTime - serverTime) / 1000)));
+ }
+ }
+ }, [isSuccessRush, rushData]);
+
+ const runCountdown = useCountdown(initialRunCountdown || null);
+
+ useEffect(() => {
+ if (
+ runCountdown !== null &&
+ runCountdown <= 0 &&
+ gameState.phase === CARD_PHASE.IN_PROGRESS
+ ) {
+ setGamePhase(CARD_PHASE.COMPLETED);
+ }
+ }, [runCountdown, gameState.phase, setGamePhase]);
+
+ if (initialRunCountdown === null || runCountdown === null) {
+ return ;
+ }
+
const minutes = Math.floor((runCountdown % 3600) / 60);
const seconds = runCountdown % 60;
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 0725c441..0b2df2db 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -1,11 +1,63 @@
+import { useEffect, useState } from "react";
import { motion } from "framer-motion";
+import { RushAPI } from "@/apis/rushAPI.ts";
import { Background } from "@/components/Background";
+import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
+import useCountdown from "@/hooks/useCountdown.ts";
+import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { formatTime } from "@/utils/formatTime.ts";
+import { getMsTime } from "@/utils/getMsTime.ts";
function CountdownTimer() {
- const { preCountdown } = useRushGameContext();
+ const [initialPreCountdown, setInitialPreCountdown] = useState(null);
+ const { gameState, setGamePhase } = useRushGameContext();
+
+ const {
+ data: rushData,
+ isSuccess: isSuccessRush,
+ fetchData: getRush,
+ } = useFetch(() => RushAPI.getRush());
+
+ useEffect(() => {
+ getRush();
+ }, []);
+
+ useEffect(() => {
+ if (isSuccessRush && rushData) {
+ const currentEvent = rushData.events.find(
+ (event) => event.rushEventId === rushData.todayEventId
+ );
+
+ if (currentEvent) {
+ const serverTime = getMsTime(rushData.serverTime);
+ const startDateTime = getMsTime(currentEvent.startDateTime);
+
+ setInitialPreCountdown(
+ Math.max(0, Math.floor((startDateTime - serverTime) / 1000))
+ );
+ }
+ }
+ }, [isSuccessRush, rushData]);
+
+ const preCountdown = useCountdown(initialPreCountdown || null);
+
+ useEffect(() => {
+ if (
+ preCountdown !== null &&
+ preCountdown <= 0 &&
+ gameState.phase === CARD_PHASE.NOT_STARTED
+ ) {
+ setGamePhase(CARD_PHASE.IN_PROGRESS);
+ }
+ }, [preCountdown, gameState.phase, setGamePhase]);
+
+ if (initialPreCountdown === null || preCountdown === null) {
+ return ;
+ }
+
const hours = Math.floor(preCountdown / 3600);
const minutes = Math.floor((preCountdown % 3600) / 60);
const seconds = preCountdown % 60;
diff --git a/client/src/hooks/useCountdown.ts b/client/src/hooks/useCountdown.ts
index d56e0494..9b47ba03 100644
--- a/client/src/hooks/useCountdown.ts
+++ b/client/src/hooks/useCountdown.ts
@@ -1,17 +1,24 @@
import { useEffect, useState } from "react";
-export default function useCountdown(initialTime: number) {
- const [time, setTime] = useState(initialTime);
+export default function useCountdown(initialTime: number | null) {
+ const [time, setTime] = useState(initialTime);
useEffect(() => {
setTime(initialTime);
}, [initialTime]);
useEffect(() => {
- if (time < 0) return;
+ if (time === null || time < 0) return;
const timer = setInterval(() => {
- if (time >= 0) setTime((prevTime) => prevTime - 1);
+ setTime((prevTime) => {
+ if (prevTime !== null && prevTime >= 0) {
+ return prevTime - 1;
+ } else {
+ clearInterval(timer);
+ return prevTime;
+ }
+ });
}, 1000);
return () => clearInterval(timer);
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index bf236939..3dafce44 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -1,37 +1,62 @@
+import { useEffect } from "react";
import { motion } from "framer-motion";
+import { useCookies } from "react-cookie";
+import { RushAPI } from "@/apis/rushAPI.ts";
import CTAButton from "@/components/CTAButton";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
+import { COOKIE_KEY } from "@/constants/cookie.ts";
import CardOptions from "@/features/RushGame/RushGameSections/CardOptions.tsx";
import Countdown from "@/features/RushGame/RushGameSections/Countdown.tsx";
import FinalResult from "@/features/RushGame/RushGameSections/FinalResult.tsx";
import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx";
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
+import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToast from "@/hooks/useToast.tsx";
+import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
import { writeClipboard } from "@/utils/writeClipboard.ts";
export default function RushGame() {
+ const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
const { unblockNavigation } = useBlockNavigation(
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
- const { gameState } = useRushGameContext();
+ const { gameState, setUserParticipationStatus } = useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
const handleClickShareButton = () => {
writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
};
+ const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
+ GetRushUserParticipationStatusResponse,
+ string
+ >((token) => RushAPI.getRushUserParticipationStatus(token));
+
+ useEffect(() => {
+ getRushUserParticipationStatus(cookies[COOKIE_KEY.ACCESS_TOKEN]);
+ }, []);
+
+ useEffect(() => {
+ if (userParticipatedStatus !== null) {
+ setUserParticipationStatus(userParticipatedStatus);
+ }
+ }, [userParticipatedStatus]);
+
const renderRushGameContent = () => {
switch (gameState.phase) {
case CARD_PHASE.NOT_STARTED:
return ;
case CARD_PHASE.IN_PROGRESS:
- if (!gameState.userParticipatedStatus) {
- return ;
- } else {
- return ;
+ if (userParticipatedStatus === null) return <>>;
+ else {
+ if (!gameState.userParticipatedStatus) {
+ return ;
+ } else {
+ return ;
+ }
}
case CARD_PHASE.COMPLETED:
return ;
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index f8eb36ed..3bdabf86 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -23,12 +23,12 @@ export interface RushGameContextType {
[key in CardOption]: CardOptionState;
};
};
- preCountdown: number;
- runCountdown: number;
updateCardOptions: (option: CardOption, updates: Partial) => void;
- updateUserStatus: (token: string) => Promise;
updateUserStatusAndSelectedOption: (token: string, selectedOption: CardOption) => Promise;
getSelectedCardInfo: (option: CardOption) => CardOptionState;
getOptionRatio: (option: CardOption) => number;
fetchRushBalance: () => Promise;
+ setUserParticipationStatus: (status: boolean) => void;
+ setGamePhase: (phase: GamePhase) => void;
+ setUserSelectedOption: (option: CardOption) => void;
}
From 2a1da5a0844933774b25481757e759aafde11c0b Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 11:12:40 +0900
Subject: [PATCH 12/36] =?UTF-8?q?feat:=20=EC=98=A4=EB=8A=98=20=EB=82=A0?=
=?UTF-8?q?=EC=A7=9C=20=ED=95=84=ED=84=B0=EB=A7=81=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 9 ++++++---
.../RushGame/RushGameComponents/RushCountdown.tsx | 9 ++++++---
.../src/features/RushGame/RushGameSections/Countdown.tsx | 9 ++++++---
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index e84e9ca7..de318787 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -141,9 +141,12 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
useEffect(() => {
if (rushData) {
- const currentEvent = rushData.events.find(
- (event) => event.rushEventId === rushData.todayEventId
- );
+ const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+
+ const currentEvent = rushData.events.find((event) => {
+ const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
+ });
if (currentEvent) {
const serverTime = getMsTime(rushData.serverTime);
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index b05c248d..2dcc25d3 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -33,9 +33,12 @@ export default function RushCountdown() {
useEffect(() => {
if (isSuccessRush && rushData) {
- const currentEvent = rushData.events.find(
- (event) => event.rushEventId === rushData.todayEventId
- );
+ const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+
+ const currentEvent = rushData.events.find((event) => {
+ const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
+ });
if (currentEvent) {
const serverTime = getMsTime(rushData.serverTime);
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 0b2df2db..6ed687dd 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -27,9 +27,12 @@ function CountdownTimer() {
useEffect(() => {
if (isSuccessRush && rushData) {
- const currentEvent = rushData.events.find(
- (event) => event.rushEventId === rushData.todayEventId
- );
+ const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+
+ const currentEvent = rushData.events.find((event) => {
+ const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
+ });
if (currentEvent) {
const serverTime = getMsTime(rushData.serverTime);
From 276b53891aa6822cbecea0a97c991b370bec7ff2 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 11:20:50 +0900
Subject: [PATCH 13/36] =?UTF-8?q?refactor:=20Context=20=EB=82=B4=EB=B6=80?=
=?UTF-8?q?=20getRushUserParticipationStatus=20API=20=ED=98=B8=EC=B6=9C=20?=
=?UTF-8?q?=EB=B0=96=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 28 +------------
.../RushGameComponents/RushCardComparison.tsx | 39 +++++++++++--------
client/src/types/rushGame.ts | 1 -
3 files changed, 24 insertions(+), 44 deletions(-)
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index de318787..87658fcd 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -5,11 +5,7 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import useFetch from "@/hooks/useFetch.ts";
-import {
- GetRushBalanceResponse,
- GetRushUserParticipationStatusResponse,
- GetTotalRushEventsResponse,
-} from "@/types/rushApi.ts";
+import { GetRushBalanceResponse, GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { CardOption, CardOptionState, GamePhase, RushGameContextType } from "@/types/rushGame";
import { getMsTime } from "@/utils/getMsTime.ts";
@@ -68,27 +64,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
[]
);
- const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
- GetRushUserParticipationStatusResponse,
- string
- >((token) => RushAPI.getRushUserParticipationStatus(token));
-
- // TODO: 상태 업데이트랑 옵션 업데이트 분리할까? 어차피 setUserSelectedOption이랑 setUserParticipationStatus 함수 다 내려줄건데 뭐하러 이렇게 하남..?
- // TODO: 그냥 updateUserStatusAndSelectedOption 이 함수 호출해주는 곳에서 RushAPI.getRushUserParticipationStatus 이거 호출해주고, setUserSelectedOption 함수만 받아서 쓰면 될 것 같은데
- const updateUserStatusAndSelectedOption = useCallback(
- async (token: string, selectedOption: CardOption) => {
- await getRushUserParticipationStatus(token);
- setUserSelectedOption(selectedOption);
- },
- []
- );
-
- useEffect(() => {
- if (userParticipatedStatus !== null) {
- setUserParticipationStatus(userParticipatedStatus);
- }
- }, [userParticipatedStatus]);
-
const getSelectedCardInfo = useCallback(
(option: CardOption) => {
const cardInfo = gameState.cardOptions[option];
@@ -169,7 +144,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
value={{
gameState,
updateCardOptions,
- updateUserStatusAndSelectedOption,
getSelectedCardInfo,
getOptionRatio,
fetchRushBalance,
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
index 3b68313a..23fea807 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useState } from "react";
+import { useEffect } from "react";
import { useCookies } from "react-cookie";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
@@ -6,20 +6,20 @@ import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushCard from "@/features/RushGame/RushGameComponents/RushCard.tsx";
import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
-import { GetTodayRushEventResponse, RushEventStatusCodeResponse } from "@/types/rushApi.ts";
+import {
+ GetRushUserParticipationStatusResponse,
+ GetTodayRushEventResponse,
+ RushEventStatusCodeResponse,
+} from "@/types/rushApi.ts";
import { CardOption } from "@/types/rushGame.ts";
import { getRandomCardColors } from "@/utils/getRandomCardColors.ts";
-const INITIAL_OPTION_NUMBER = -1 as const;
-
export default function RushCardComparison() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const [optionId, setOptionId] = useState(
- INITIAL_OPTION_NUMBER
- );
- const { gameState, updateUserStatusAndSelectedOption, updateCardOptions } =
+ const { gameState, setUserSelectedOption, updateCardOptions, setUserParticipationStatus } =
useRushGameContext();
+ // TODO: getTodayRushEvent -> RushGame 컴포넌트로 옮기기
const {
data: todayRushEventData,
isSuccess: isSuccessTodayRushEvent,
@@ -34,6 +34,11 @@ export default function RushCardComparison() {
({ token, optionId }) => RushAPI.postSelectedRushOptionApply(token, optionId)
);
+ const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
+ GetRushUserParticipationStatusResponse,
+ string
+ >((token) => RushAPI.getRushUserParticipationStatus(token));
+
useEffect(() => {
getTodayRushEvent(cookies[COOKIE_KEY.ACCESS_TOKEN]);
}, []);
@@ -57,18 +62,20 @@ export default function RushCardComparison() {
const handleCardSelection = async (optionId: CardOption) => {
await postSelectedRushOptionApply({ token: cookies[COOKIE_KEY.ACCESS_TOKEN], optionId });
- setOptionId(optionId);
+ setUserSelectedOption(optionId);
};
useEffect(() => {
- if (
- isSuccessPostSelectedRushOption &&
- postSelectedRushOptionResponse === 204 &&
- optionId !== INITIAL_OPTION_NUMBER
- ) {
- updateUserStatusAndSelectedOption(cookies[COOKIE_KEY.ACCESS_TOKEN], optionId);
+ if (isSuccessPostSelectedRushOption && postSelectedRushOptionResponse === 204) {
+ getRushUserParticipationStatus(cookies[COOKIE_KEY.ACCESS_TOKEN]);
+ }
+ }, [isSuccessPostSelectedRushOption, postSelectedRushOptionResponse]);
+
+ useEffect(() => {
+ if (userParticipatedStatus !== null) {
+ setUserParticipationStatus(userParticipatedStatus);
}
- }, [optionId]);
+ }, [userParticipatedStatus]);
const leftOptionData = gameState.cardOptions[CARD_OPTION.LEFT_OPTIONS];
const rightOptionData = gameState.cardOptions[CARD_OPTION.RIGHT_OPTIONS];
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index 3bdabf86..4bee5f73 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -24,7 +24,6 @@ export interface RushGameContextType {
};
};
updateCardOptions: (option: CardOption, updates: Partial) => void;
- updateUserStatusAndSelectedOption: (token: string, selectedOption: CardOption) => Promise;
getSelectedCardInfo: (option: CardOption) => CardOptionState;
getOptionRatio: (option: CardOption) => number;
fetchRushBalance: () => Promise;
From 4c8f181da3bb6a880cbf821debf92ce0f8d39c8b Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 16:41:02 +0900
Subject: [PATCH 14/36] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=9E=AC?=
=?UTF-8?q?=EC=A0=91=EC=86=8D=20=EC=8B=9C=20=EC=9C=A0=EC=A0=80=20=EC=83=81?=
=?UTF-8?q?=ED=83=9C=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=83=81=ED=83=9C=20?=
=?UTF-8?q?=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 11 ++++-
.../RushGameComponents/RushCardComparison.tsx | 37 +++-------------
.../RushCardResultDescription.tsx | 2 +-
.../RushGame/RushGameSections/Countdown.tsx | 2 +-
client/src/pages/RushGame/index.tsx | 42 +++++++++++++++++--
5 files changed, 55 insertions(+), 39 deletions(-)
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index 87658fcd..c486f919 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -51,6 +51,7 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
setGameState((prevState) => ({ ...prevState, userSelectedOption: option }));
}, []);
+ // TODO: set으로 이름 바꾸기
const updateCardOptions = useCallback(
(option: CardOption, updates: Partial) => {
setGameState((prevState) => ({
@@ -64,6 +65,7 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
[]
);
+ // TODO: getter 니까 유틸로?
const getSelectedCardInfo = useCallback(
(option: CardOption) => {
const cardInfo = gameState.cardOptions[option];
@@ -79,6 +81,7 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
[gameState.userSelectedOption, gameState.cardOptions]
);
+ // TODO: 훅으로 빼기
const {
data: rushBalanceData,
isSuccess: isSuccessRushBalance,
@@ -91,7 +94,9 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
useEffect(() => {
if (isSuccessRushBalance && rushBalanceData) {
- const { leftOption, rightOption } = rushBalanceData;
+ const { optionId, leftOption, rightOption } = rushBalanceData;
+
+ setUserSelectedOption(optionId);
updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
selectionCount: leftOption,
@@ -100,8 +105,9 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
selectionCount: rightOption,
});
}
- }, [isSuccessRushBalance, rushBalanceData]);
+ }, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, updateCardOptions]);
+ // TODO: 유틸로 빼기
const getOptionRatio = useCallback(
(option: CardOption): number => {
const total =
@@ -114,6 +120,7 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
[gameState.cardOptions]
);
+ // TODO: dispatch action으로 함수로 빼서 RushGame 컴포넌트에서 함수를 호출해서 초기화해주는 것이 맞다고 생각..
useEffect(() => {
if (rushData) {
const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
index 23fea807..01b2a30f 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
@@ -1,31 +1,22 @@
import { useEffect } from "react";
import { useCookies } from "react-cookie";
import { RushAPI } from "@/apis/rushAPI.ts";
-import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import { CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushCard from "@/features/RushGame/RushGameComponents/RushCard.tsx";
import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import {
GetRushUserParticipationStatusResponse,
- GetTodayRushEventResponse,
RushEventStatusCodeResponse,
} from "@/types/rushApi.ts";
import { CardOption } from "@/types/rushGame.ts";
-import { getRandomCardColors } from "@/utils/getRandomCardColors.ts";
export default function RushCardComparison() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setUserSelectedOption, updateCardOptions, setUserParticipationStatus } =
+ const { gameState, setUserSelectedOption, setUserParticipationStatus, fetchRushBalance } =
useRushGameContext();
- // TODO: getTodayRushEvent -> RushGame 컴포넌트로 옮기기
- const {
- data: todayRushEventData,
- isSuccess: isSuccessTodayRushEvent,
- fetchData: getTodayRushEvent,
- } = useFetch((token) => RushAPI.getTodayRushEvent(token));
-
const {
data: postSelectedRushOptionResponse,
isSuccess: isSuccessPostSelectedRushOption,
@@ -39,27 +30,6 @@ export default function RushCardComparison() {
string
>((token) => RushAPI.getRushUserParticipationStatus(token));
- useEffect(() => {
- getTodayRushEvent(cookies[COOKIE_KEY.ACCESS_TOKEN]);
- }, []);
-
- useEffect(() => {
- if (isSuccessTodayRushEvent && todayRushEventData) {
- const { leftColor, rightColor } = getRandomCardColors();
-
- updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- mainText: todayRushEventData.leftOption.mainText,
- subText: todayRushEventData.leftOption.subText,
- color: leftColor,
- });
- updateCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- mainText: todayRushEventData.rightOption.mainText,
- subText: todayRushEventData.rightOption.subText,
- color: rightColor,
- });
- }
- }, [isSuccessTodayRushEvent, todayRushEventData]);
-
const handleCardSelection = async (optionId: CardOption) => {
await postSelectedRushOptionApply({ token: cookies[COOKIE_KEY.ACCESS_TOKEN], optionId });
setUserSelectedOption(optionId);
@@ -74,6 +44,9 @@ export default function RushCardComparison() {
useEffect(() => {
if (userParticipatedStatus !== null) {
setUserParticipationStatus(userParticipatedStatus);
+ if (userParticipatedStatus && CARD_PHASE.IN_PROGRESS) {
+ fetchRushBalance();
+ }
}
}, [userParticipatedStatus]);
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index 50addc01..67efd7d7 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -45,7 +45,7 @@ export default function RushCardResultDescription() {
token: cookies[COOKIE_KEY.ACCESS_TOKEN],
optionId: gameState.userSelectedOption,
});
- }, []);
+ }, [cookies, gameState.userSelectedOption, getUserResultData]);
useEffect(() => {
if (isSuccessUserResultData && userResultData) {
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 6ed687dd..e05d2933 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -75,7 +75,7 @@ function CountdownTimer() {
:
:
-
+
);
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index 3dafce44..e4fc7f7e 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -3,7 +3,7 @@ import { motion } from "framer-motion";
import { useCookies } from "react-cookie";
import { RushAPI } from "@/apis/rushAPI.ts";
import CTAButton from "@/components/CTAButton";
-import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import { CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import CardOptions from "@/features/RushGame/RushGameSections/CardOptions.tsx";
@@ -14,7 +14,11 @@ import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToast from "@/hooks/useToast.tsx";
-import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
+import {
+ GetRushUserParticipationStatusResponse,
+ GetTodayRushEventResponse,
+} from "@/types/rushApi.ts";
+import { getRandomCardColors } from "@/utils/getRandomCardColors.ts";
import { writeClipboard } from "@/utils/writeClipboard.ts";
export default function RushGame() {
@@ -23,13 +27,42 @@ export default function RushGame() {
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
- const { gameState, setUserParticipationStatus } = useRushGameContext();
+ const { gameState, setUserParticipationStatus, updateCardOptions, fetchRushBalance } =
+ useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
const handleClickShareButton = () => {
writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
};
+ // TODO: 훅으로 빼기
+ const {
+ data: todayRushEventData,
+ isSuccess: isSuccessTodayRushEvent,
+ fetchData: getTodayRushEvent,
+ } = useFetch
((token) => RushAPI.getTodayRushEvent(token));
+
+ useEffect(() => {
+ getTodayRushEvent(cookies[COOKIE_KEY.ACCESS_TOKEN]);
+ }, []);
+
+ useEffect(() => {
+ if (isSuccessTodayRushEvent && todayRushEventData) {
+ const { leftColor, rightColor } = getRandomCardColors();
+
+ updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ mainText: todayRushEventData.leftOption.mainText,
+ subText: todayRushEventData.leftOption.subText,
+ color: leftColor,
+ });
+ updateCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ mainText: todayRushEventData.rightOption.mainText,
+ subText: todayRushEventData.rightOption.subText,
+ color: rightColor,
+ });
+ }
+ }, [isSuccessTodayRushEvent, todayRushEventData]);
+
const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
GetRushUserParticipationStatusResponse,
string
@@ -42,6 +75,9 @@ export default function RushGame() {
useEffect(() => {
if (userParticipatedStatus !== null) {
setUserParticipationStatus(userParticipatedStatus);
+ if (userParticipatedStatus && CARD_PHASE.IN_PROGRESS) {
+ fetchRushBalance();
+ }
}
}, [userParticipatedStatus]);
From cd478e70f263f0e5174865783af7b3ee35d54ea1 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 16:53:30 +0900
Subject: [PATCH 15/36] =?UTF-8?q?rename:=20updateCardOptions=20=ED=95=A8?=
=?UTF-8?q?=EC=88=98=EB=AA=85=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 30 ++++++++-----------
.../RushCardResultDescription.tsx | 5 ++--
.../RushGame/RushGameSections/FinalResult.tsx | 8 ++---
client/src/pages/RushGame/index.tsx | 6 ++--
client/src/types/rushGame.ts | 2 +-
5 files changed, 23 insertions(+), 28 deletions(-)
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index c486f919..260a652b 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -51,19 +51,15 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
setGameState((prevState) => ({ ...prevState, userSelectedOption: option }));
}, []);
- // TODO: set으로 이름 바꾸기
- const updateCardOptions = useCallback(
- (option: CardOption, updates: Partial) => {
- setGameState((prevState) => ({
- ...prevState,
- cardOptions: {
- ...prevState.cardOptions,
- [option]: { ...prevState.cardOptions[option], ...updates },
- },
- }));
- },
- []
- );
+ const setCardOptions = useCallback((option: CardOption, updates: Partial) => {
+ setGameState((prevState) => ({
+ ...prevState,
+ cardOptions: {
+ ...prevState.cardOptions,
+ [option]: { ...prevState.cardOptions[option], ...updates },
+ },
+ }));
+ }, []);
// TODO: getter 니까 유틸로?
const getSelectedCardInfo = useCallback(
@@ -98,14 +94,14 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
setUserSelectedOption(optionId);
- updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
selectionCount: leftOption,
});
- updateCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
selectionCount: rightOption,
});
}
- }, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, updateCardOptions]);
+ }, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, setCardOptions]);
// TODO: 유틸로 빼기
const getOptionRatio = useCallback(
@@ -150,7 +146,7 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
{
if (isSuccessUserResultData && userResultData) {
- updateCardOptions(gameState.userSelectedOption, {
+ setCardOptions(gameState.userSelectedOption, {
mainText: userResultData.mainText,
resultMainText: userResultData.resultMainText,
resultSubText: userResultData.resultSubText,
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 1b14ef71..13a6d5d3 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -32,7 +32,7 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
gameState,
getOptionRatio,
getSelectedCardInfo,
- updateCardOptions,
+ setCardOptions,
setUserSelectedOption,
} = useRushGameContext();
@@ -56,14 +56,14 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
if (optionId) setUserSelectedOption(optionId);
- updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
selectionCount: leftOption,
});
- updateCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
selectionCount: rightOption,
});
}
- }, [resultData, isSuccessRushResult, updateCardOptions]);
+ }, [resultData, isSuccessRushResult, setCardOptions]);
const userParticipatedStatus = gameState.userParticipatedStatus;
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index e4fc7f7e..0f61f84d 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -27,7 +27,7 @@ export default function RushGame() {
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
- const { gameState, setUserParticipationStatus, updateCardOptions, fetchRushBalance } =
+ const { gameState, setUserParticipationStatus, setCardOptions, fetchRushBalance } =
useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
@@ -50,12 +50,12 @@ export default function RushGame() {
if (isSuccessTodayRushEvent && todayRushEventData) {
const { leftColor, rightColor } = getRandomCardColors();
- updateCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
mainText: todayRushEventData.leftOption.mainText,
subText: todayRushEventData.leftOption.subText,
color: leftColor,
});
- updateCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
mainText: todayRushEventData.rightOption.mainText,
subText: todayRushEventData.rightOption.subText,
color: rightColor,
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index 4bee5f73..f6db730d 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -23,7 +23,7 @@ export interface RushGameContextType {
[key in CardOption]: CardOptionState;
};
};
- updateCardOptions: (option: CardOption, updates: Partial) => void;
+ setCardOptions: (option: CardOption, updates: Partial) => void;
getSelectedCardInfo: (option: CardOption) => CardOptionState;
getOptionRatio: (option: CardOption) => number;
fetchRushBalance: () => Promise;
From c88e43de199999134d7b2972f428425d89b5231d Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 17:34:22 +0900
Subject: [PATCH 16/36] =?UTF-8?q?refactor:=20getSelectedCardInfo=20?=
=?UTF-8?q?=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EB=B6=84?=
=?UTF-8?q?=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 17 ----------------
.../RushCardCurrentRatio.tsx | 14 +++++++++----
.../RushCardResultDescription.tsx | 10 ++++++----
.../RushGame/RushGameSections/FinalResult.tsx | 20 ++++++++++---------
client/src/types/rushGame.ts | 1 -
.../src/utils/RushGame/getSelectedCardInfo.ts | 18 +++++++++++++++++
6 files changed, 45 insertions(+), 35 deletions(-)
create mode 100644 client/src/utils/RushGame/getSelectedCardInfo.ts
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index 260a652b..31d16e2d 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -61,22 +61,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
}));
}, []);
- // TODO: getter 니까 유틸로?
- const getSelectedCardInfo = useCallback(
- (option: CardOption) => {
- const cardInfo = gameState.cardOptions[option];
- return {
- mainText: cardInfo.mainText,
- subText: cardInfo.subText,
- resultMainText: cardInfo.resultMainText,
- resultSubText: cardInfo.resultSubText,
- color: cardInfo.color,
- selectionCount: cardInfo.selectionCount,
- };
- },
- [gameState.userSelectedOption, gameState.cardOptions]
- );
-
// TODO: 훅으로 빼기
const {
data: rushBalanceData,
@@ -147,7 +131,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
value={{
gameState,
setCardOptions,
- getSelectedCardInfo,
getOptionRatio,
fetchRushBalance,
setUserParticipationStatus,
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
index b52a276b..a095c9d0 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
@@ -6,6 +6,7 @@ import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgress
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import { CardOption } from "@/types/rushGame.ts";
+import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
import Reload from "/public/assets/icons/reload.svg?react";
const tooltipVariants = cva(`absolute transition-opacity duration-300 ease-in-out`, {
@@ -51,8 +52,7 @@ function getMessage(leftRatio: number, rightRatio: number, userSelectedOption: C
}
export default function RushCardCurrentRatio() {
- const { gameState, getOptionRatio, fetchRushBalance, getSelectedCardInfo } =
- useRushGameContext();
+ const { gameState, getOptionRatio, fetchRushBalance } = useRushGameContext();
const { toggleContents } = useToggleContents();
const leftOptionRatio = getOptionRatio(CARD_OPTION.LEFT_OPTIONS);
@@ -60,8 +60,14 @@ export default function RushCardCurrentRatio() {
const message = getMessage(leftOptionRatio, rightOptionRatio, gameState.userSelectedOption);
- const { mainText: leftMainText } = getSelectedCardInfo(CARD_OPTION.LEFT_OPTIONS);
- const { mainText: rightMainText } = getSelectedCardInfo(CARD_OPTION.RIGHT_OPTIONS);
+ const { mainText: leftMainText } = getSelectedCardInfo({
+ gameState: gameState,
+ option: CARD_OPTION.LEFT_OPTIONS,
+ });
+ const { mainText: rightMainText } = getSelectedCardInfo({
+ gameState: gameState,
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ });
return (
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index 85808262..31cb3eb7 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -9,6 +9,7 @@ import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import { GetRushOptionResultResponse } from "@/types/rushApi.ts";
import { CardOption } from "@/types/rushGame.ts";
+import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
const backgroundGradients = cva(
`flex gap-[35px] w-[834px] h-[400px] rounded-800 py-6 px-[37px] justify-between break-keep`,
@@ -29,7 +30,7 @@ const backgroundGradients = cva(
export default function RushCardResultDescription() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setCardOptions, getSelectedCardInfo, getOptionRatio } = useRushGameContext();
+ const { gameState, setCardOptions, getOptionRatio } = useRushGameContext();
const {
data: userResultData,
@@ -56,9 +57,10 @@ export default function RushCardResultDescription() {
}
}, [isSuccessUserResultData, userResultData]);
- const { mainText, resultMainText, resultSubText, color } = getSelectedCardInfo(
- gameState.userSelectedOption
- );
+ const { mainText, resultMainText, resultSubText, color } = getSelectedCardInfo({
+ gameState: gameState,
+ option: gameState.userSelectedOption,
+ });
const selectedOptionRatio = getOptionRatio(gameState.userSelectedOption);
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 13a6d5d3..3bceb54a 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -11,6 +11,7 @@ import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import { GetRushResultResponse } from "@/types/rushApi.ts";
import { WinStatus } from "@/types/rushGame.ts";
+import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
const MESSAGES = {
WINNING: "축하해요! 선착순 경품 당첨이에요.",
@@ -28,13 +29,8 @@ interface FinalResultProps {
export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const {
- gameState,
- getOptionRatio,
- getSelectedCardInfo,
- setCardOptions,
- setUserSelectedOption,
- } = useRushGameContext();
+ const { gameState, getOptionRatio, setCardOptions, setUserSelectedOption } =
+ useRushGameContext();
const {
data: resultData,
@@ -73,8 +69,14 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const message = isWinner ? MESSAGES.WINNING : MESSAGES.LOSING;
- const { mainText: leftMainText } = getSelectedCardInfo(CARD_OPTION.LEFT_OPTIONS);
- const { mainText: rightMainText } = getSelectedCardInfo(CARD_OPTION.RIGHT_OPTIONS);
+ const { mainText: leftMainText } = getSelectedCardInfo({
+ gameState: gameState,
+ option: CARD_OPTION.LEFT_OPTIONS,
+ });
+ const { mainText: rightMainText } = getSelectedCardInfo({
+ gameState: gameState,
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ });
const leftOptionRatio = getOptionRatio(CARD_OPTION.LEFT_OPTIONS);
const rightOptionRatio = getOptionRatio(CARD_OPTION.RIGHT_OPTIONS);
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index f6db730d..e36d7a99 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -24,7 +24,6 @@ export interface RushGameContextType {
};
};
setCardOptions: (option: CardOption, updates: Partial
) => void;
- getSelectedCardInfo: (option: CardOption) => CardOptionState;
getOptionRatio: (option: CardOption) => number;
fetchRushBalance: () => Promise;
setUserParticipationStatus: (status: boolean) => void;
diff --git a/client/src/utils/RushGame/getSelectedCardInfo.ts b/client/src/utils/RushGame/getSelectedCardInfo.ts
new file mode 100644
index 00000000..3da60bee
--- /dev/null
+++ b/client/src/utils/RushGame/getSelectedCardInfo.ts
@@ -0,0 +1,18 @@
+import { CardOption, RushGameContextType } from "@/types/rushGame.ts";
+
+interface GetSelectedCardInfoProps {
+ gameState: RushGameContextType["gameState"];
+ option: CardOption;
+}
+
+export const getSelectedCardInfo = ({ gameState, option }: GetSelectedCardInfoProps) => {
+ const cardInfo = gameState.cardOptions[option];
+ return {
+ mainText: cardInfo.mainText,
+ subText: cardInfo.subText,
+ resultMainText: cardInfo.resultMainText,
+ resultSubText: cardInfo.resultSubText,
+ color: cardInfo.color,
+ selectionCount: cardInfo.selectionCount,
+ };
+};
From 47ab45b80880a9cde64d4f3b7cdae69b1b12107e Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 17:59:43 +0900
Subject: [PATCH 17/36] =?UTF-8?q?refactor:=20getOptionRatio=20=EC=9C=A0?=
=?UTF-8?q?=ED=8B=B8=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 14 --------------
.../RushGameComponents/RushCardCurrentRatio.tsx | 13 ++++++++++---
.../RushCardResultDescription.tsx | 8 ++++++--
.../RushGame/RushGameSections/FinalResult.tsx | 14 ++++++++++----
client/src/types/rushGame.ts | 1 -
client/src/utils/RushGame/getOptionRatio.ts | 16 ++++++++++++++++
6 files changed, 42 insertions(+), 24 deletions(-)
create mode 100644 client/src/utils/RushGame/getOptionRatio.ts
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index 31d16e2d..b459f1d5 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -87,19 +87,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
}
}, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, setCardOptions]);
- // TODO: 유틸로 빼기
- const getOptionRatio = useCallback(
- (option: CardOption): number => {
- const total =
- gameState.cardOptions[CARD_OPTION.LEFT_OPTIONS].selectionCount +
- gameState.cardOptions[CARD_OPTION.RIGHT_OPTIONS].selectionCount;
- if (total === 0) return 0;
- const ratio = (gameState.cardOptions[option].selectionCount / total) * 100;
- return Math.round(ratio * 100) / 100;
- },
- [gameState.cardOptions]
- );
-
// TODO: dispatch action으로 함수로 빼서 RushGame 컴포넌트에서 함수를 호출해서 초기화해주는 것이 맞다고 생각..
useEffect(() => {
if (rushData) {
@@ -131,7 +118,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
value={{
gameState,
setCardOptions,
- getOptionRatio,
fetchRushBalance,
setUserParticipationStatus,
setGamePhase,
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
index a095c9d0..389ac309 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
@@ -6,6 +6,7 @@ import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgress
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import { CardOption } from "@/types/rushGame.ts";
+import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
import Reload from "/public/assets/icons/reload.svg?react";
@@ -52,11 +53,17 @@ function getMessage(leftRatio: number, rightRatio: number, userSelectedOption: C
}
export default function RushCardCurrentRatio() {
- const { gameState, getOptionRatio, fetchRushBalance } = useRushGameContext();
+ const { gameState, fetchRushBalance } = useRushGameContext();
const { toggleContents } = useToggleContents();
- const leftOptionRatio = getOptionRatio(CARD_OPTION.LEFT_OPTIONS);
- const rightOptionRatio = getOptionRatio(CARD_OPTION.RIGHT_OPTIONS);
+ const leftOptionRatio = getOptionRatio({
+ gameState: gameState,
+ option: CARD_OPTION.LEFT_OPTIONS,
+ });
+ const rightOptionRatio = getOptionRatio({
+ gameState: gameState,
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ });
const message = getMessage(leftOptionRatio, rightOptionRatio, gameState.userSelectedOption);
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index 31cb3eb7..f11567cf 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -9,6 +9,7 @@ import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import { GetRushOptionResultResponse } from "@/types/rushApi.ts";
import { CardOption } from "@/types/rushGame.ts";
+import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
const backgroundGradients = cva(
@@ -30,7 +31,7 @@ const backgroundGradients = cva(
export default function RushCardResultDescription() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setCardOptions, getOptionRatio } = useRushGameContext();
+ const { gameState, setCardOptions } = useRushGameContext();
const {
data: userResultData,
@@ -62,7 +63,10 @@ export default function RushCardResultDescription() {
option: gameState.userSelectedOption,
});
- const selectedOptionRatio = getOptionRatio(gameState.userSelectedOption);
+ const selectedOptionRatio = getOptionRatio({
+ gameState: gameState,
+ option: gameState.userSelectedOption,
+ });
return (
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 3bceb54a..7c441281 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -11,6 +11,7 @@ import useFetch from "@/hooks/useFetch.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import { GetRushResultResponse } from "@/types/rushApi.ts";
import { WinStatus } from "@/types/rushGame.ts";
+import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
const MESSAGES = {
@@ -29,8 +30,7 @@ interface FinalResultProps {
export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, getOptionRatio, setCardOptions, setUserSelectedOption } =
- useRushGameContext();
+ const { gameState, setCardOptions, setUserSelectedOption } = useRushGameContext();
const {
data: resultData,
@@ -78,8 +78,14 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
option: CARD_OPTION.RIGHT_OPTIONS,
});
- const leftOptionRatio = getOptionRatio(CARD_OPTION.LEFT_OPTIONS);
- const rightOptionRatio = getOptionRatio(CARD_OPTION.RIGHT_OPTIONS);
+ const leftOptionRatio = getOptionRatio({
+ gameState: gameState,
+ option: CARD_OPTION.LEFT_OPTIONS,
+ });
+ const rightOptionRatio = getOptionRatio({
+ gameState: gameState,
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ });
const leftWinStatus = getWinStatus(leftOptionRatio, rightOptionRatio);
const rightWinStatus = getWinStatus(rightOptionRatio, leftOptionRatio);
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index e36d7a99..667eb6fe 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -24,7 +24,6 @@ export interface RushGameContextType {
};
};
setCardOptions: (option: CardOption, updates: Partial
) => void;
- getOptionRatio: (option: CardOption) => number;
fetchRushBalance: () => Promise;
setUserParticipationStatus: (status: boolean) => void;
setGamePhase: (phase: GamePhase) => void;
diff --git a/client/src/utils/RushGame/getOptionRatio.ts b/client/src/utils/RushGame/getOptionRatio.ts
new file mode 100644
index 00000000..b052ac87
--- /dev/null
+++ b/client/src/utils/RushGame/getOptionRatio.ts
@@ -0,0 +1,16 @@
+import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import { CardOption, RushGameContextType } from "@/types/rushGame.ts";
+
+interface GetOptionRatioProps {
+ gameState: RushGameContextType["gameState"];
+ option: CardOption;
+}
+
+export const getOptionRatio = ({ gameState, option }: GetOptionRatioProps) => {
+ const total =
+ gameState.cardOptions[CARD_OPTION.LEFT_OPTIONS].selectionCount +
+ gameState.cardOptions[CARD_OPTION.RIGHT_OPTIONS].selectionCount;
+ if (total === 0) return 0;
+ const ratio = (gameState.cardOptions[option].selectionCount / total) * 100;
+ return Math.round(ratio * 100) / 100;
+};
From dff318127d52ddcd4e6da98c23ab63bb238f6b47 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 18:07:21 +0900
Subject: [PATCH 18/36] =?UTF-8?q?fix:=20useFetch=20=EC=BD=9C=EB=B0=B1=20?=
=?UTF-8?q?=EC=8C=93=EC=9D=B4=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameComponents/RushCardResultDescription.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index f11567cf..ce991ef6 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -46,7 +46,7 @@ export default function RushCardResultDescription() {
token: cookies[COOKIE_KEY.ACCESS_TOKEN],
optionId: gameState.userSelectedOption,
});
- }, [cookies, gameState.userSelectedOption, getUserResultData]);
+ }, [cookies, gameState.userSelectedOption]);
useEffect(() => {
if (isSuccessUserResultData && userResultData) {
From 9312f4bba591a5c49b902fec5ba347fb3e04215d Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 18:53:56 +0900
Subject: [PATCH 19/36] =?UTF-8?q?refactor:=20rushBalanceData=20=ED=8C=A8?=
=?UTF-8?q?=EC=B9=AD=20=EB=B0=8F=20=EC=83=81=ED=83=9C=20=EC=97=85=EB=8D=B0?=
=?UTF-8?q?=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?=
=?UTF-8?q?=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 34 +---------------
.../RushGameComponents/RushCardComparison.tsx | 5 ++-
.../RushCardCurrentRatio.tsx | 4 +-
.../RushGameSections/SelectedCard.tsx | 4 +-
client/src/hooks/useFetchRushBalance.ts | 40 +++++++++++++++++++
client/src/pages/RushGame/index.tsx | 5 ++-
client/src/types/rushGame.ts | 1 -
7 files changed, 52 insertions(+), 41 deletions(-)
create mode 100644 client/src/hooks/useFetchRushBalance.ts
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index b459f1d5..9a0c8bd4 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -1,18 +1,13 @@
import { ReactNode, createContext, useCallback, useEffect, useState } from "react";
-import { useCookies } from "react-cookie";
import { useLoaderData } from "react-router-dom";
-import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard";
-import { COOKIE_KEY } from "@/constants/cookie.ts";
-import useFetch from "@/hooks/useFetch.ts";
-import { GetRushBalanceResponse, GetTotalRushEventsResponse } from "@/types/rushApi.ts";
+import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { CardOption, CardOptionState, GamePhase, RushGameContextType } from "@/types/rushGame";
import { getMsTime } from "@/utils/getMsTime.ts";
export const RushGameContext = createContext(undefined);
export const RushGameProvider = ({ children }: { children: ReactNode }) => {
- const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
const rushData = useLoaderData() as GetTotalRushEventsResponse;
const [gameState, setGameState] = useState({
@@ -61,32 +56,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
}));
}, []);
- // TODO: 훅으로 빼기
- const {
- data: rushBalanceData,
- isSuccess: isSuccessRushBalance,
- fetchData: getRushBalance,
- } = useFetch((token) => RushAPI.getRushBalance(token));
-
- const fetchRushBalance = useCallback(async (): Promise => {
- await getRushBalance(cookies[COOKIE_KEY.ACCESS_TOKEN]);
- }, [cookies, getRushBalance]);
-
- useEffect(() => {
- if (isSuccessRushBalance && rushBalanceData) {
- const { optionId, leftOption, rightOption } = rushBalanceData;
-
- setUserSelectedOption(optionId);
-
- setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- selectionCount: leftOption,
- });
- setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- selectionCount: rightOption,
- });
- }
- }, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, setCardOptions]);
-
// TODO: dispatch action으로 함수로 빼서 RushGame 컴포넌트에서 함수를 호출해서 초기화해주는 것이 맞다고 생각..
useEffect(() => {
if (rushData) {
@@ -118,7 +87,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
value={{
gameState,
setCardOptions,
- fetchRushBalance,
setUserParticipationStatus,
setGamePhase,
setUserSelectedOption,
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
index 01b2a30f..3b2c869e 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
@@ -5,6 +5,7 @@ import { CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushCard from "@/features/RushGame/RushGameComponents/RushCard.tsx";
import useFetch from "@/hooks/useFetch.ts";
+import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import {
GetRushUserParticipationStatusResponse,
@@ -14,8 +15,8 @@ import { CardOption } from "@/types/rushGame.ts";
export default function RushCardComparison() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setUserSelectedOption, setUserParticipationStatus, fetchRushBalance } =
- useRushGameContext();
+ const { gameState, setUserSelectedOption, setUserParticipationStatus } = useRushGameContext();
+ const fetchRushBalance = useFetchRushBalance();
const {
data: postSelectedRushOptionResponse,
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
index 389ac309..8caafe47 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
@@ -3,6 +3,7 @@ import Tooltip from "@/components/Tooltip";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import RushCurrentOptionDisplay from "@/features/RushGame/RushGameComponents/RushCurrentOptionDisplay.tsx";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
+import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import { CardOption } from "@/types/rushGame.ts";
@@ -53,8 +54,9 @@ function getMessage(leftRatio: number, rightRatio: number, userSelectedOption: C
}
export default function RushCardCurrentRatio() {
- const { gameState, fetchRushBalance } = useRushGameContext();
+ const { gameState } = useRushGameContext();
const { toggleContents } = useToggleContents();
+ const fetchRushBalance = useFetchRushBalance();
const leftOptionRatio = getOptionRatio({
gameState: gameState,
diff --git a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
index d81384aa..a1217608 100644
--- a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
+++ b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
@@ -4,7 +4,7 @@ import { ASCEND, DISSOLVE, SCROLL_MOTION } from "@/constants/animation.ts";
import RushCardCurrentRatio from "@/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx";
import RushCardResultDescription from "@/features/RushGame/RushGameComponents/RushCardResultDescription.tsx";
import RushCountdown from "@/features/RushGame/RushGameComponents/RushCountdown.tsx";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import ArrowLeftIcon from "/public/assets/icons/arrow-line-left.svg?react";
import ArrowRightIcon from "/public/assets/icons/arrow-line-right.svg?react";
@@ -57,7 +57,7 @@ interface SelectedCardProps {
export default function SelectedCard({ unblockNavigation }: SelectedCardProps) {
const { toggleContents, toggle } = useToggleContents({ useDuration: false });
- const { fetchRushBalance } = useRushGameContext();
+ const fetchRushBalance = useFetchRushBalance();
useEffect(() => {
fetchRushBalance();
diff --git a/client/src/hooks/useFetchRushBalance.ts b/client/src/hooks/useFetchRushBalance.ts
new file mode 100644
index 00000000..df9281ff
--- /dev/null
+++ b/client/src/hooks/useFetchRushBalance.ts
@@ -0,0 +1,40 @@
+import { useCallback, useEffect } from "react";
+import { useCookies } from "react-cookie";
+import { RushAPI } from "@/apis/rushAPI.ts";
+import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import { COOKIE_KEY } from "@/constants/cookie.ts";
+import useFetch from "@/hooks/useFetch.ts";
+import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetRushBalanceResponse } from "@/types/rushApi.ts";
+
+export default function useFetchRushBalance() {
+ const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
+ const { setUserSelectedOption, setCardOptions } = useRushGameContext();
+
+ const {
+ data: rushBalanceData,
+ isSuccess: isSuccessRushBalance,
+ fetchData: getRushBalance,
+ } = useFetch((token) => RushAPI.getRushBalance(token));
+
+ const fetchRushBalance = useCallback(async (): Promise => {
+ await getRushBalance(cookies[COOKIE_KEY.ACCESS_TOKEN]);
+ }, [cookies, getRushBalance]);
+
+ useEffect(() => {
+ if (isSuccessRushBalance && rushBalanceData) {
+ const { optionId, leftOption, rightOption } = rushBalanceData;
+
+ setUserSelectedOption(optionId);
+
+ setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ selectionCount: leftOption,
+ });
+ setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ selectionCount: rightOption,
+ });
+ }
+ }, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, setCardOptions]);
+
+ return fetchRushBalance;
+}
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index 0f61f84d..0741a344 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -12,6 +12,7 @@ import FinalResult from "@/features/RushGame/RushGameSections/FinalResult.tsx";
import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx";
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
import useFetch from "@/hooks/useFetch.ts";
+import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToast from "@/hooks/useToast.tsx";
import {
@@ -27,9 +28,9 @@ export default function RushGame() {
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
- const { gameState, setUserParticipationStatus, setCardOptions, fetchRushBalance } =
- useRushGameContext();
+ const { gameState, setUserParticipationStatus, setCardOptions } = useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
+ const fetchRushBalance = useFetchRushBalance();
const handleClickShareButton = () => {
writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index 667eb6fe..a3d4bae4 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -24,7 +24,6 @@ export interface RushGameContextType {
};
};
setCardOptions: (option: CardOption, updates: Partial) => void;
- fetchRushBalance: () => Promise;
setUserParticipationStatus: (status: boolean) => void;
setGamePhase: (phase: GamePhase) => void;
setUserSelectedOption: (option: CardOption) => void;
From b5e604c7add9c9035a64bfe6406f1e215e641c85 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 22:02:09 +0900
Subject: [PATCH 20/36] =?UTF-8?q?refactor:=20todayRushEventData=20?=
=?UTF-8?q?=ED=8C=A8=EC=B9=AD=20=EB=B0=8F=20=EC=83=81=ED=83=9C=20=EC=97=85?=
=?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8A=94=20=EB=A1=9C?=
=?UTF-8?q?=EC=A7=81=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/hooks/useFetchTodayRushEvent.ts | 36 ++++++++++++++++++++++
client/src/pages/RushGame/index.tsx | 36 +++-------------------
2 files changed, 41 insertions(+), 31 deletions(-)
create mode 100644 client/src/hooks/useFetchTodayRushEvent.ts
diff --git a/client/src/hooks/useFetchTodayRushEvent.ts b/client/src/hooks/useFetchTodayRushEvent.ts
new file mode 100644
index 00000000..e2d33a22
--- /dev/null
+++ b/client/src/hooks/useFetchTodayRushEvent.ts
@@ -0,0 +1,36 @@
+import { useEffect } from "react";
+import { RushAPI } from "@/apis/rushAPI.ts";
+import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import useFetch from "@/hooks/useFetch.ts";
+import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetTodayRushEventResponse } from "@/types/rushApi.ts";
+import { getRandomCardColors } from "@/utils/getRandomCardColors";
+
+export const useFetchTodayRushEvent = () => {
+ const { setCardOptions } = useRushGameContext();
+
+ const {
+ data: todayRushEventData,
+ isSuccess: isSuccessTodayRushEvent,
+ fetchData: getTodayRushEvent,
+ } = useFetch((token) => RushAPI.getTodayRushEvent(token));
+
+ useEffect(() => {
+ if (isSuccessTodayRushEvent && todayRushEventData) {
+ const { leftColor, rightColor } = getRandomCardColors();
+
+ setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ mainText: todayRushEventData.leftOption.mainText,
+ subText: todayRushEventData.leftOption.subText,
+ color: leftColor,
+ });
+ setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ mainText: todayRushEventData.rightOption.mainText,
+ subText: todayRushEventData.rightOption.subText,
+ color: rightColor,
+ });
+ }
+ }, [isSuccessTodayRushEvent, todayRushEventData]);
+
+ return { getTodayRushEvent };
+};
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index 0741a344..d922d47d 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -3,7 +3,7 @@ import { motion } from "framer-motion";
import { useCookies } from "react-cookie";
import { RushAPI } from "@/apis/rushAPI.ts";
import CTAButton from "@/components/CTAButton";
-import { CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import CardOptions from "@/features/RushGame/RushGameSections/CardOptions.tsx";
@@ -13,13 +13,10 @@ import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx"
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
import useFetch from "@/hooks/useFetch.ts";
import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
+import { useFetchTodayRushEvent } from "@/hooks/useFetchTodayRushEvent.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToast from "@/hooks/useToast.tsx";
-import {
- GetRushUserParticipationStatusResponse,
- GetTodayRushEventResponse,
-} from "@/types/rushApi.ts";
-import { getRandomCardColors } from "@/utils/getRandomCardColors.ts";
+import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
import { writeClipboard } from "@/utils/writeClipboard.ts";
export default function RushGame() {
@@ -27,8 +24,9 @@ export default function RushGame() {
const { unblockNavigation } = useBlockNavigation(
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
+ const { getTodayRushEvent } = useFetchTodayRushEvent();
- const { gameState, setUserParticipationStatus, setCardOptions } = useRushGameContext();
+ const { gameState, setUserParticipationStatus } = useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
const fetchRushBalance = useFetchRushBalance();
@@ -36,34 +34,10 @@ export default function RushGame() {
writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
};
- // TODO: 훅으로 빼기
- const {
- data: todayRushEventData,
- isSuccess: isSuccessTodayRushEvent,
- fetchData: getTodayRushEvent,
- } = useFetch((token) => RushAPI.getTodayRushEvent(token));
-
useEffect(() => {
getTodayRushEvent(cookies[COOKIE_KEY.ACCESS_TOKEN]);
}, []);
- useEffect(() => {
- if (isSuccessTodayRushEvent && todayRushEventData) {
- const { leftColor, rightColor } = getRandomCardColors();
-
- setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- mainText: todayRushEventData.leftOption.mainText,
- subText: todayRushEventData.leftOption.subText,
- color: leftColor,
- });
- setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- mainText: todayRushEventData.rightOption.mainText,
- subText: todayRushEventData.rightOption.subText,
- color: rightColor,
- });
- }
- }, [isSuccessTodayRushEvent, todayRushEventData]);
-
const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
GetRushUserParticipationStatusResponse,
string
From 270c911c822026e26a6fc2e5125ba5711ca2e150 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 22:28:51 +0900
Subject: [PATCH 21/36] =?UTF-8?q?refactor:=20rushUserParticipationStatus?=
=?UTF-8?q?=20=ED=8C=A8=EC=B9=AD=20=EB=B0=8F=20=EC=83=81=ED=83=9C=20?=
=?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8A=94=20?=
=?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84?=
=?UTF-8?q?=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGameComponents/RushCardComparison.tsx | 27 ++++--------------
.../useFetchRushUserParticipationStatus.ts | 28 +++++++++++++++++++
client/src/hooks/useFetchTodayRushEvent.ts | 4 +--
client/src/pages/RushGame/index.tsx | 28 +++----------------
4 files changed, 39 insertions(+), 48 deletions(-)
create mode 100644 client/src/hooks/useFetchRushUserParticipationStatus.ts
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
index 3b2c869e..0f871898 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
@@ -1,22 +1,19 @@
import { useEffect } from "react";
import { useCookies } from "react-cookie";
import { RushAPI } from "@/apis/rushAPI.ts";
-import { CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushCard from "@/features/RushGame/RushGameComponents/RushCard.tsx";
import useFetch from "@/hooks/useFetch.ts";
-import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
+import { useFetchRushUserParticipationStatus } from "@/hooks/useFetchRushUserParticipationStatus.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
-import {
- GetRushUserParticipationStatusResponse,
- RushEventStatusCodeResponse,
-} from "@/types/rushApi.ts";
+import { RushEventStatusCodeResponse } from "@/types/rushApi.ts";
import { CardOption } from "@/types/rushGame.ts";
export default function RushCardComparison() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setUserSelectedOption, setUserParticipationStatus } = useRushGameContext();
- const fetchRushBalance = useFetchRushBalance();
+ const { gameState, setUserSelectedOption } = useRushGameContext();
+ const { getRushUserParticipationStatus } = useFetchRushUserParticipationStatus();
const {
data: postSelectedRushOptionResponse,
@@ -26,11 +23,6 @@ export default function RushCardComparison() {
({ token, optionId }) => RushAPI.postSelectedRushOptionApply(token, optionId)
);
- const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
- GetRushUserParticipationStatusResponse,
- string
- >((token) => RushAPI.getRushUserParticipationStatus(token));
-
const handleCardSelection = async (optionId: CardOption) => {
await postSelectedRushOptionApply({ token: cookies[COOKIE_KEY.ACCESS_TOKEN], optionId });
setUserSelectedOption(optionId);
@@ -42,15 +34,6 @@ export default function RushCardComparison() {
}
}, [isSuccessPostSelectedRushOption, postSelectedRushOptionResponse]);
- useEffect(() => {
- if (userParticipatedStatus !== null) {
- setUserParticipationStatus(userParticipatedStatus);
- if (userParticipatedStatus && CARD_PHASE.IN_PROGRESS) {
- fetchRushBalance();
- }
- }
- }, [userParticipatedStatus]);
-
const leftOptionData = gameState.cardOptions[CARD_OPTION.LEFT_OPTIONS];
const rightOptionData = gameState.cardOptions[CARD_OPTION.RIGHT_OPTIONS];
diff --git a/client/src/hooks/useFetchRushUserParticipationStatus.ts b/client/src/hooks/useFetchRushUserParticipationStatus.ts
new file mode 100644
index 00000000..11d90ae5
--- /dev/null
+++ b/client/src/hooks/useFetchRushUserParticipationStatus.ts
@@ -0,0 +1,28 @@
+import { useEffect } from "react";
+import { RushAPI } from "@/apis/rushAPI.ts";
+import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import useFetch from "@/hooks/useFetch.ts";
+import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
+import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
+
+export function useFetchRushUserParticipationStatus() {
+ const { setUserParticipationStatus } = useRushGameContext();
+ const fetchRushBalance = useFetchRushBalance();
+
+ const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
+ GetRushUserParticipationStatusResponse,
+ string
+ >((token) => RushAPI.getRushUserParticipationStatus(token));
+
+ useEffect(() => {
+ if (userParticipatedStatus !== null) {
+ setUserParticipationStatus(userParticipatedStatus);
+ if (userParticipatedStatus && CARD_PHASE.IN_PROGRESS) {
+ fetchRushBalance();
+ }
+ }
+ }, [userParticipatedStatus]);
+
+ return { userParticipatedStatus, getRushUserParticipationStatus };
+}
diff --git a/client/src/hooks/useFetchTodayRushEvent.ts b/client/src/hooks/useFetchTodayRushEvent.ts
index e2d33a22..019365f8 100644
--- a/client/src/hooks/useFetchTodayRushEvent.ts
+++ b/client/src/hooks/useFetchTodayRushEvent.ts
@@ -6,7 +6,7 @@ import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import { GetTodayRushEventResponse } from "@/types/rushApi.ts";
import { getRandomCardColors } from "@/utils/getRandomCardColors";
-export const useFetchTodayRushEvent = () => {
+export function useFetchTodayRushEvent() {
const { setCardOptions } = useRushGameContext();
const {
@@ -33,4 +33,4 @@ export const useFetchTodayRushEvent = () => {
}, [isSuccessTodayRushEvent, todayRushEventData]);
return { getTodayRushEvent };
-};
+}
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index d922d47d..82761780 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -1,7 +1,6 @@
import { useEffect } from "react";
import { motion } from "framer-motion";
import { useCookies } from "react-cookie";
-import { RushAPI } from "@/apis/rushAPI.ts";
import CTAButton from "@/components/CTAButton";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
@@ -11,12 +10,10 @@ import Countdown from "@/features/RushGame/RushGameSections/Countdown.tsx";
import FinalResult from "@/features/RushGame/RushGameSections/FinalResult.tsx";
import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx";
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
-import useFetch from "@/hooks/useFetch.ts";
-import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
+import { useFetchRushUserParticipationStatus } from "@/hooks/useFetchRushUserParticipationStatus.ts";
import { useFetchTodayRushEvent } from "@/hooks/useFetchTodayRushEvent.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
import useToast from "@/hooks/useToast.tsx";
-import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
import { writeClipboard } from "@/utils/writeClipboard.ts";
export default function RushGame() {
@@ -25,10 +22,10 @@ export default function RushGame() {
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
const { getTodayRushEvent } = useFetchTodayRushEvent();
-
- const { gameState, setUserParticipationStatus } = useRushGameContext();
+ const { gameState } = useRushGameContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
- const fetchRushBalance = useFetchRushBalance();
+ const { getRushUserParticipationStatus, userParticipatedStatus } =
+ useFetchRushUserParticipationStatus();
const handleClickShareButton = () => {
writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
@@ -36,26 +33,9 @@ export default function RushGame() {
useEffect(() => {
getTodayRushEvent(cookies[COOKIE_KEY.ACCESS_TOKEN]);
- }, []);
-
- const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
- GetRushUserParticipationStatusResponse,
- string
- >((token) => RushAPI.getRushUserParticipationStatus(token));
-
- useEffect(() => {
getRushUserParticipationStatus(cookies[COOKIE_KEY.ACCESS_TOKEN]);
}, []);
- useEffect(() => {
- if (userParticipatedStatus !== null) {
- setUserParticipationStatus(userParticipatedStatus);
- if (userParticipatedStatus && CARD_PHASE.IN_PROGRESS) {
- fetchRushBalance();
- }
- }
- }, [userParticipatedStatus]);
-
const renderRushGameContent = () => {
switch (gameState.phase) {
case CARD_PHASE.NOT_STARTED:
From ab56abd3ee28537a0c405346a1ad796340ec22ae Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 22:38:29 +0900
Subject: [PATCH 22/36] =?UTF-8?q?refactor:=20resultData=20=ED=8C=A8?=
=?UTF-8?q?=EC=B9=AD=20=EB=B0=8F=20=EC=83=81=ED=83=9C=20=EC=97=85=EB=8D=B0?=
=?UTF-8?q?=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?=
=?UTF-8?q?=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameSections/FinalResult.tsx | 33 +++----------------
client/src/hooks/useFetchRushResult.ts | 33 +++++++++++++++++++
2 files changed, 37 insertions(+), 29 deletions(-)
create mode 100644 client/src/hooks/useFetchRushResult.ts
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 7c441281..72bbb822 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -1,15 +1,13 @@
import { useEffect } from "react";
import { motion } from "framer-motion";
import { useCookies } from "react-cookie";
-import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION, WIN_STATUS } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
import RushResultOptionDisplay from "@/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx";
-import useFetch from "@/hooks/useFetch.ts";
+import { useFetchRushResult } from "@/hooks/useFetchRushResult.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
-import { GetRushResultResponse } from "@/types/rushApi.ts";
import { WinStatus } from "@/types/rushGame.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
@@ -30,37 +28,14 @@ interface FinalResultProps {
export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setCardOptions, setUserSelectedOption } = useRushGameContext();
-
- const {
- data: resultData,
- isSuccess: isSuccessRushResult,
- fetchData: getRushResult,
- } = useFetch(
- () => RushAPI.getRushResult(cookies[COOKIE_KEY.ACCESS_TOKEN]),
- false
- );
+ const { gameState } = useRushGameContext();
+ const { getRushResult, resultData } = useFetchRushResult();
useEffect(() => {
- getRushResult();
+ getRushResult(cookies[COOKIE_KEY.ACCESS_TOKEN]);
unblockNavigation();
}, []);
- useEffect(() => {
- if (resultData && isSuccessRushResult) {
- const { optionId, leftOption, rightOption } = resultData;
-
- if (optionId) setUserSelectedOption(optionId);
-
- setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- selectionCount: leftOption,
- });
- setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- selectionCount: rightOption,
- });
- }
- }, [resultData, isSuccessRushResult, setCardOptions]);
-
const userParticipatedStatus = gameState.userParticipatedStatus;
const isWinner = resultData?.isWinner;
diff --git a/client/src/hooks/useFetchRushResult.ts b/client/src/hooks/useFetchRushResult.ts
new file mode 100644
index 00000000..0e0f1878
--- /dev/null
+++ b/client/src/hooks/useFetchRushResult.ts
@@ -0,0 +1,33 @@
+import { useEffect } from "react";
+import { RushAPI } from "@/apis/rushAPI.ts";
+import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import useFetch from "@/hooks/useFetch.ts";
+import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetRushResultResponse } from "@/types/rushApi.ts";
+
+export function useFetchRushResult() {
+ const { setUserSelectedOption, setCardOptions } = useRushGameContext();
+
+ const {
+ data: resultData,
+ isSuccess: isSuccessRushResult,
+ fetchData: getRushResult,
+ } = useFetch((token) => RushAPI.getRushResult(token), false);
+
+ useEffect(() => {
+ if (resultData && isSuccessRushResult) {
+ const { optionId, leftOption, rightOption } = resultData;
+
+ if (optionId) setUserSelectedOption(optionId);
+
+ setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
+ selectionCount: leftOption,
+ });
+ setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
+ selectionCount: rightOption,
+ });
+ }
+ }, [resultData, isSuccessRushResult, setCardOptions]);
+
+ return { getRushResult, resultData };
+}
From 1120dee6a2afdea5b22f0e1b3062976ee954fa86 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 22:50:33 +0900
Subject: [PATCH 23/36] =?UTF-8?q?refactor:=20userResultData=20=ED=8C=A8?=
=?UTF-8?q?=EC=B9=AD=20=EB=B0=8F=20=EC=83=81=ED=83=9C=20=EC=97=85=EB=8D=B0?=
=?UTF-8?q?=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?=
=?UTF-8?q?=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushCardResultDescription.tsx | 26 ++--------------
client/src/hooks/useFetchRushOptionResult.ts | 30 +++++++++++++++++++
2 files changed, 33 insertions(+), 23 deletions(-)
create mode 100644 client/src/hooks/useFetchRushOptionResult.ts
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index ce991ef6..4b7004fd 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -1,14 +1,11 @@
import { useEffect } from "react";
import { cva } from "class-variance-authority";
import { useCookies } from "react-cookie";
-import { RushAPI } from "@/apis/rushAPI.ts";
import Category from "@/components/Category";
import { CARD_COLOR } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
-import useFetch from "@/hooks/useFetch.ts";
+import { useFetchRushOptionResult } from "@/hooks/useFetchRushOptionResult.ts";
import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
-import { GetRushOptionResultResponse } from "@/types/rushApi.ts";
-import { CardOption } from "@/types/rushGame.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
@@ -31,15 +28,8 @@ const backgroundGradients = cva(
export default function RushCardResultDescription() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setCardOptions } = useRushGameContext();
-
- const {
- data: userResultData,
- isSuccess: isSuccessUserResultData,
- fetchData: getUserResultData,
- } = useFetch(
- ({ token, optionId }) => RushAPI.getRushOptionResult(token, optionId)
- );
+ const { gameState } = useRushGameContext();
+ const { getUserResultData } = useFetchRushOptionResult();
useEffect(() => {
getUserResultData({
@@ -48,16 +38,6 @@ export default function RushCardResultDescription() {
});
}, [cookies, gameState.userSelectedOption]);
- useEffect(() => {
- if (isSuccessUserResultData && userResultData) {
- setCardOptions(gameState.userSelectedOption, {
- mainText: userResultData.mainText,
- resultMainText: userResultData.resultMainText,
- resultSubText: userResultData.resultSubText,
- });
- }
- }, [isSuccessUserResultData, userResultData]);
-
const { mainText, resultMainText, resultSubText, color } = getSelectedCardInfo({
gameState: gameState,
option: gameState.userSelectedOption,
diff --git a/client/src/hooks/useFetchRushOptionResult.ts b/client/src/hooks/useFetchRushOptionResult.ts
new file mode 100644
index 00000000..f2dc0542
--- /dev/null
+++ b/client/src/hooks/useFetchRushOptionResult.ts
@@ -0,0 +1,30 @@
+import { useEffect } from "react";
+import { RushAPI } from "@/apis/rushAPI.ts";
+import useFetch from "@/hooks/useFetch.ts";
+import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import { GetRushOptionResultResponse } from "@/types/rushApi.ts";
+import { CardOption } from "@/types/rushGame.ts";
+
+export function useFetchRushOptionResult() {
+ const { gameState, setCardOptions } = useRushGameContext();
+
+ const {
+ data: userResultData,
+ isSuccess: isSuccessUserResultData,
+ fetchData: getUserResultData,
+ } = useFetch(
+ ({ token, optionId }) => RushAPI.getRushOptionResult(token, optionId)
+ );
+
+ useEffect(() => {
+ if (isSuccessUserResultData && userResultData) {
+ setCardOptions(gameState.userSelectedOption, {
+ mainText: userResultData.mainText,
+ resultMainText: userResultData.resultMainText,
+ resultSubText: userResultData.resultSubText,
+ });
+ }
+ }, [isSuccessUserResultData, userResultData]);
+
+ return { getUserResultData };
+}
From b24076e16c36a7120a20b04c81af59dc40c5d995 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 23:27:25 +0900
Subject: [PATCH 24/36] =?UTF-8?q?refactor:=20rushData=20=EB=B0=9B=EC=95=84?=
=?UTF-8?q?=EC=84=9C=20=EA=B2=8C=EC=9E=84=20=EC=B4=88=EA=B8=B0=20=EC=83=81?=
=?UTF-8?q?=ED=83=9C=20=EC=84=A4=EC=A0=95=ED=95=B4=EC=A3=BC=EB=8A=94=20?=
=?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84?=
=?UTF-8?q?=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 33 +------------------------
client/src/pages/RushGame/index.tsx | 10 ++++++--
2 files changed, 9 insertions(+), 34 deletions(-)
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index 9a0c8bd4..f6af304f 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -1,15 +1,10 @@
-import { ReactNode, createContext, useCallback, useEffect, useState } from "react";
-import { useLoaderData } from "react-router-dom";
+import { ReactNode, createContext, useCallback, useState } from "react";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard";
-import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { CardOption, CardOptionState, GamePhase, RushGameContextType } from "@/types/rushGame";
-import { getMsTime } from "@/utils/getMsTime.ts";
export const RushGameContext = createContext(undefined);
export const RushGameProvider = ({ children }: { children: ReactNode }) => {
- const rushData = useLoaderData() as GetTotalRushEventsResponse;
-
const [gameState, setGameState] = useState({
phase: CARD_PHASE.NOT_STARTED,
userParticipatedStatus: false,
@@ -56,32 +51,6 @@ export const RushGameProvider = ({ children }: { children: ReactNode }) => {
}));
}, []);
- // TODO: dispatch action으로 함수로 빼서 RushGame 컴포넌트에서 함수를 호출해서 초기화해주는 것이 맞다고 생각..
- useEffect(() => {
- if (rushData) {
- const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
-
- const currentEvent = rushData.events.find((event) => {
- const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
- return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
- });
-
- if (currentEvent) {
- const serverTime = getMsTime(rushData.serverTime);
- const startTime = getMsTime(currentEvent.startDateTime);
- const endTime = getMsTime(currentEvent.endDateTime);
-
- if (serverTime < startTime) {
- setGamePhase(CARD_PHASE.NOT_STARTED);
- } else if (serverTime >= startTime && serverTime <= endTime) {
- setGamePhase(CARD_PHASE.IN_PROGRESS);
- } else if (serverTime > endTime) {
- setGamePhase(CARD_PHASE.COMPLETED);
- }
- }
- }
- }, [rushData, setGamePhase]);
-
return (
{
writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
};
From 9b1b8db5fe5af54841fff12020f4a2ccbfa35fd6 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Wed, 21 Aug 2024 23:30:50 +0900
Subject: [PATCH 25/36] =?UTF-8?q?refactor:=20=EC=9D=B4=EC=A0=84=20?=
=?UTF-8?q?=EC=BB=A4=EB=B0=8B=EC=97=90=20=EB=8C=80=ED=95=9C=20useSetGamePh?=
=?UTF-8?q?ase=20=ED=9B=85=20=EC=B6=94=EA=B0=80=20=EC=BB=A4=EB=B0=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/hooks/useSetGamePhase.ts | 34 +++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 client/src/hooks/useSetGamePhase.ts
diff --git a/client/src/hooks/useSetGamePhase.ts b/client/src/hooks/useSetGamePhase.ts
new file mode 100644
index 00000000..1b0efd66
--- /dev/null
+++ b/client/src/hooks/useSetGamePhase.ts
@@ -0,0 +1,34 @@
+import { useEffect } from "react";
+import { CARD_PHASE } from "@/constants/Rush/rushCard";
+import { useRushGameStateContext } from "@/hooks/useRushGameStateContext.ts";
+import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
+import { getMsTime } from "@/utils/getMsTime";
+
+export default function useSetGamePhase(rushData: GetTotalRushEventsResponse) {
+ const { setGamePhase } = useRushGameStateContext();
+
+ useEffect(() => {
+ if (rushData) {
+ const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+
+ const currentEvent = rushData.events.find((event) => {
+ const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
+ });
+
+ if (currentEvent) {
+ const serverTime = getMsTime(rushData.serverTime);
+ const startTime = getMsTime(currentEvent.startDateTime);
+ const endTime = getMsTime(currentEvent.endDateTime);
+
+ if (serverTime < startTime) {
+ setGamePhase(CARD_PHASE.NOT_STARTED);
+ } else if (serverTime >= startTime && serverTime <= endTime) {
+ setGamePhase(CARD_PHASE.IN_PROGRESS);
+ } else if (serverTime > endTime) {
+ setGamePhase(CARD_PHASE.COMPLETED);
+ }
+ }
+ }
+ }, [rushData]);
+}
From 7ddf7701e0bf5c4deacb30dc15c0097e8554e643 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 01:26:19 +0900
Subject: [PATCH 26/36] =?UTF-8?q?refactor:=20context=EC=97=90=20flux=20?=
=?UTF-8?q?=ED=8C=A8=ED=84=B4=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 118 +++++++++---------
.../RushGameComponents/RushCardComparison.tsx | 10 +-
.../RushCardCurrentRatio.tsx | 4 +-
.../RushCardResultDescription.tsx | 4 +-
.../RushGameComponents/RushCountdown.tsx | 11 +-
.../RushGameComponents/RushProgressBar.tsx | 4 +-
.../RushGame/RushGameSections/Countdown.tsx | 11 +-
.../RushGame/RushGameSections/FinalResult.tsx | 4 +-
client/src/hooks/useFetchRushBalance.ts | 30 +++--
client/src/hooks/useFetchRushOptionResult.ts | 22 ++--
client/src/hooks/useFetchRushResult.ts | 32 +++--
.../useFetchRushUserParticipationStatus.ts | 7 +-
client/src/hooks/useFetchTodayRushEvent.ts | 34 +++--
client/src/hooks/useRushGameContext.ts | 10 --
.../src/hooks/useRushGameDispatchContext.ts | 11 ++
client/src/hooks/useRushGameStateContext.ts | 11 ++
client/src/hooks/useSetGamePhase.ts | 11 +-
client/src/pages/RushGame/index.tsx | 4 +-
client/src/types/rushGame.ts | 37 ++++--
client/src/utils/RushGame/getOptionRatio.ts | 4 +-
.../src/utils/RushGame/getSelectedCardInfo.ts | 4 +-
21 files changed, 237 insertions(+), 146 deletions(-)
delete mode 100644 client/src/hooks/useRushGameContext.ts
create mode 100644 client/src/hooks/useRushGameDispatchContext.ts
create mode 100644 client/src/hooks/useRushGameStateContext.ts
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index f6af304f..f95a1880 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -1,67 +1,71 @@
-import { ReactNode, createContext, useCallback, useState } from "react";
+import { ReactNode, createContext, useReducer } from "react";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard";
-import { CardOption, CardOptionState, GamePhase, RushGameContextType } from "@/types/rushGame";
+import {
+ RUSH_ACTION,
+ RushGameAction,
+ RushGameDispatchType,
+ RushGameStateType,
+} from "@/types/rushGame";
-export const RushGameContext = createContext(undefined);
+export const RushGameStateContext = createContext(undefined);
+export const RushGameDispatchContext = createContext(undefined);
-export const RushGameProvider = ({ children }: { children: ReactNode }) => {
- const [gameState, setGameState] = useState({
- phase: CARD_PHASE.NOT_STARTED,
- userParticipatedStatus: false,
- userSelectedOption: CARD_OPTION.LEFT_OPTIONS,
- cardOptions: {
- [CARD_OPTION.LEFT_OPTIONS]: {
- mainText: "",
- subText: "",
- resultMainText: "",
- resultSubText: "",
- color: CARD_COLOR.GREEN,
- selectionCount: 0,
- },
- [CARD_OPTION.RIGHT_OPTIONS]: {
- mainText: "",
- subText: "",
- resultMainText: "",
- resultSubText: "",
- color: CARD_COLOR.BLUE,
- selectionCount: 0,
- },
+const initialGameState: RushGameStateType = {
+ phase: CARD_PHASE.NOT_STARTED,
+ userParticipatedStatus: false,
+ userSelectedOption: CARD_OPTION.LEFT_OPTIONS,
+ cardOptions: {
+ [CARD_OPTION.LEFT_OPTIONS]: {
+ mainText: "",
+ subText: "",
+ resultMainText: "",
+ resultSubText: "",
+ color: CARD_COLOR.GREEN,
+ selectionCount: 0,
},
- });
-
- const setGamePhase = useCallback((phase: GamePhase) => {
- setGameState((prevState) => ({ ...prevState, phase }));
- }, []);
-
- const setUserParticipationStatus = useCallback((status: boolean) => {
- setGameState((prevState) => ({ ...prevState, userParticipatedStatus: status }));
- }, []);
+ [CARD_OPTION.RIGHT_OPTIONS]: {
+ mainText: "",
+ subText: "",
+ resultMainText: "",
+ resultSubText: "",
+ color: CARD_COLOR.BLUE,
+ selectionCount: 0,
+ },
+ },
+};
- const setUserSelectedOption = useCallback((option: CardOption) => {
- setGameState((prevState) => ({ ...prevState, userSelectedOption: option }));
- }, []);
+const rushGameReducer = (state: RushGameStateType, action: RushGameAction): RushGameStateType => {
+ switch (action.type) {
+ case RUSH_ACTION.SET_PHASE:
+ return { ...state, phase: action.payload };
+ case RUSH_ACTION.SET_USER_PARTICIPATION:
+ return { ...state, userParticipatedStatus: action.payload };
+ case RUSH_ACTION.SET_USER_OPTION:
+ return { ...state, userSelectedOption: action.payload };
+ case RUSH_ACTION.SET_CARD_OPTIONS:
+ return {
+ ...state,
+ cardOptions: {
+ ...state.cardOptions,
+ [action.payload.option]: {
+ ...state.cardOptions[action.payload.option],
+ ...action.payload.updates,
+ },
+ },
+ };
+ default:
+ return state;
+ }
+};
- const setCardOptions = useCallback((option: CardOption, updates: Partial) => {
- setGameState((prevState) => ({
- ...prevState,
- cardOptions: {
- ...prevState.cardOptions,
- [option]: { ...prevState.cardOptions[option], ...updates },
- },
- }));
- }, []);
+export const RushGameProvider = ({ children }: { children: ReactNode }) => {
+ const [gameState, dispatch] = useReducer(rushGameReducer, initialGameState);
return (
-
- {children}
-
+
+
+ {children}
+
+
);
};
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
index 0f871898..8d82378d 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
@@ -6,13 +6,15 @@ import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushCard from "@/features/RushGame/RushGameComponents/RushCard.tsx";
import useFetch from "@/hooks/useFetch.ts";
import { useFetchRushUserParticipationStatus } from "@/hooks/useFetchRushUserParticipationStatus.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { RushEventStatusCodeResponse } from "@/types/rushApi.ts";
-import { CardOption } from "@/types/rushGame.ts";
+import { CardOption, RUSH_ACTION } from "@/types/rushGame.ts";
export default function RushCardComparison() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState, setUserSelectedOption } = useRushGameContext();
+ const gameState = useRushGameStateContext();
+ const dispatch = useRushGameDispatchContext();
const { getRushUserParticipationStatus } = useFetchRushUserParticipationStatus();
const {
@@ -25,7 +27,7 @@ export default function RushCardComparison() {
const handleCardSelection = async (optionId: CardOption) => {
await postSelectedRushOptionApply({ token: cookies[COOKIE_KEY.ACCESS_TOKEN], optionId });
- setUserSelectedOption(optionId);
+ dispatch({ type: RUSH_ACTION.SET_USER_OPTION, payload: optionId });
};
useEffect(() => {
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
index 8caafe47..2ce0397a 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
@@ -4,7 +4,7 @@ import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import RushCurrentOptionDisplay from "@/features/RushGame/RushGameComponents/RushCurrentOptionDisplay.tsx";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import { CardOption } from "@/types/rushGame.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
@@ -54,7 +54,7 @@ function getMessage(leftRatio: number, rightRatio: number, userSelectedOption: C
}
export default function RushCardCurrentRatio() {
- const { gameState } = useRushGameContext();
+ const gameState = useRushGameStateContext();
const { toggleContents } = useToggleContents();
const fetchRushBalance = useFetchRushBalance();
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index 4b7004fd..ee75ffdb 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -5,7 +5,7 @@ import Category from "@/components/Category";
import { CARD_COLOR } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import { useFetchRushOptionResult } from "@/hooks/useFetchRushOptionResult.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
@@ -28,7 +28,7 @@ const backgroundGradients = cva(
export default function RushCardResultDescription() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState } = useRushGameContext();
+ const gameState = useRushGameStateContext();
const { getUserResultData } = useFetchRushOptionResult();
useEffect(() => {
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index 2dcc25d3..529f3b70 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -3,8 +3,10 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import useCountdown from "@/hooks/useCountdown.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
@@ -19,7 +21,8 @@ function TimeDisplay({ label, value }: { label: string; value: string }) {
export default function RushCountdown() {
const [initialRunCountdown, setInitialRunCountdown] = useState(null);
- const { gameState, setGamePhase } = useRushGameContext();
+ const gameState = useRushGameStateContext();
+ const dispatch = useRushGameDispatchContext();
const {
data: rushData,
@@ -57,9 +60,9 @@ export default function RushCountdown() {
runCountdown <= 0 &&
gameState.phase === CARD_PHASE.IN_PROGRESS
) {
- setGamePhase(CARD_PHASE.COMPLETED);
+ dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.COMPLETED });
}
- }, [runCountdown, gameState.phase, setGamePhase]);
+ }, [runCountdown, gameState.phase]);
if (initialRunCountdown === null || runCountdown === null) {
return ;
diff --git a/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx b/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
index 7e34d907..a1143764 100644
--- a/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
@@ -1,6 +1,6 @@
import { CARD_COLOR, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import RushBar from "@/features/RushGame/RushGameComponents/RushBar.tsx";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
interface RushProgressBarProps {
leftOptionRatio: number;
@@ -11,7 +11,7 @@ export default function RushProgressBar({
leftOptionRatio,
rightOptionRatio,
}: RushProgressBarProps) {
- const { gameState } = useRushGameContext();
+ const gameState = useRushGameStateContext();
const isCompleted = gameState.phase === CARD_PHASE.COMPLETED;
const isAllZero = leftOptionRatio === 0 && rightOptionRatio === 0;
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index e05d2933..c681a845 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -6,14 +6,17 @@ import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import useCountdown from "@/hooks/useCountdown.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
function CountdownTimer() {
const [initialPreCountdown, setInitialPreCountdown] = useState(null);
- const { gameState, setGamePhase } = useRushGameContext();
+ const gameState = useRushGameStateContext();
+ const dispatch = useRushGameDispatchContext();
const {
data: rushData,
@@ -53,9 +56,9 @@ function CountdownTimer() {
preCountdown <= 0 &&
gameState.phase === CARD_PHASE.NOT_STARTED
) {
- setGamePhase(CARD_PHASE.IN_PROGRESS);
+ dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.IN_PROGRESS });
}
- }, [preCountdown, gameState.phase, setGamePhase]);
+ }, [preCountdown, gameState.phase]);
if (initialPreCountdown === null || preCountdown === null) {
return ;
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 72bbb822..30a6919f 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -7,7 +7,7 @@ import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
import RushResultOptionDisplay from "@/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx";
import { useFetchRushResult } from "@/hooks/useFetchRushResult.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { WinStatus } from "@/types/rushGame.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
@@ -28,7 +28,7 @@ interface FinalResultProps {
export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { gameState } = useRushGameContext();
+ const gameState = useRushGameStateContext();
const { getRushResult, resultData } = useFetchRushResult();
useEffect(() => {
diff --git a/client/src/hooks/useFetchRushBalance.ts b/client/src/hooks/useFetchRushBalance.ts
index df9281ff..0650e0c6 100644
--- a/client/src/hooks/useFetchRushBalance.ts
+++ b/client/src/hooks/useFetchRushBalance.ts
@@ -4,12 +4,13 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetRushBalanceResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
export default function useFetchRushBalance() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const { setUserSelectedOption, setCardOptions } = useRushGameContext();
+ const dispatch = useRushGameDispatchContext();
const {
data: rushBalanceData,
@@ -25,16 +26,29 @@ export default function useFetchRushBalance() {
if (isSuccessRushBalance && rushBalanceData) {
const { optionId, leftOption, rightOption } = rushBalanceData;
- setUserSelectedOption(optionId);
+ dispatch({ type: RUSH_ACTION.SET_USER_OPTION, payload: optionId });
- setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- selectionCount: leftOption,
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: CARD_OPTION.LEFT_OPTIONS,
+ updates: {
+ selectionCount: leftOption,
+ },
+ },
});
- setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- selectionCount: rightOption,
+
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ updates: {
+ selectionCount: rightOption,
+ },
+ },
});
}
- }, [isSuccessRushBalance, rushBalanceData, setUserSelectedOption, setCardOptions]);
+ }, [isSuccessRushBalance, rushBalanceData]);
return fetchRushBalance;
}
diff --git a/client/src/hooks/useFetchRushOptionResult.ts b/client/src/hooks/useFetchRushOptionResult.ts
index f2dc0542..567f3af5 100644
--- a/client/src/hooks/useFetchRushOptionResult.ts
+++ b/client/src/hooks/useFetchRushOptionResult.ts
@@ -1,12 +1,14 @@
import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { GetRushOptionResultResponse } from "@/types/rushApi.ts";
-import { CardOption } from "@/types/rushGame.ts";
+import { CardOption, RUSH_ACTION } from "@/types/rushGame.ts";
export function useFetchRushOptionResult() {
- const { gameState, setCardOptions } = useRushGameContext();
+ const gameState = useRushGameStateContext();
+ const dispatch = useRushGameDispatchContext();
const {
data: userResultData,
@@ -18,10 +20,16 @@ export function useFetchRushOptionResult() {
useEffect(() => {
if (isSuccessUserResultData && userResultData) {
- setCardOptions(gameState.userSelectedOption, {
- mainText: userResultData.mainText,
- resultMainText: userResultData.resultMainText,
- resultSubText: userResultData.resultSubText,
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: gameState.userSelectedOption,
+ updates: {
+ mainText: userResultData.mainText,
+ resultMainText: userResultData.resultMainText,
+ resultSubText: userResultData.resultSubText,
+ },
+ },
});
}
}, [isSuccessUserResultData, userResultData]);
diff --git a/client/src/hooks/useFetchRushResult.ts b/client/src/hooks/useFetchRushResult.ts
index 0e0f1878..09c84087 100644
--- a/client/src/hooks/useFetchRushResult.ts
+++ b/client/src/hooks/useFetchRushResult.ts
@@ -2,11 +2,12 @@ import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetRushResultResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
export function useFetchRushResult() {
- const { setUserSelectedOption, setCardOptions } = useRushGameContext();
+ const dispatch = useRushGameDispatchContext();
const {
data: resultData,
@@ -18,16 +19,31 @@ export function useFetchRushResult() {
if (resultData && isSuccessRushResult) {
const { optionId, leftOption, rightOption } = resultData;
- if (optionId) setUserSelectedOption(optionId);
+ if (optionId) {
+ dispatch({ type: RUSH_ACTION.SET_USER_OPTION, payload: optionId });
+ }
- setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- selectionCount: leftOption,
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: CARD_OPTION.LEFT_OPTIONS,
+ updates: {
+ selectionCount: leftOption,
+ },
+ },
});
- setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- selectionCount: rightOption,
+
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ updates: {
+ selectionCount: rightOption,
+ },
+ },
});
}
- }, [resultData, isSuccessRushResult, setCardOptions]);
+ }, [resultData, isSuccessRushResult]);
return { getRushResult, resultData };
}
diff --git a/client/src/hooks/useFetchRushUserParticipationStatus.ts b/client/src/hooks/useFetchRushUserParticipationStatus.ts
index 11d90ae5..de9a53eb 100644
--- a/client/src/hooks/useFetchRushUserParticipationStatus.ts
+++ b/client/src/hooks/useFetchRushUserParticipationStatus.ts
@@ -3,11 +3,12 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import useFetch from "@/hooks/useFetch.ts";
import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
export function useFetchRushUserParticipationStatus() {
- const { setUserParticipationStatus } = useRushGameContext();
+ const dispatch = useRushGameDispatchContext();
const fetchRushBalance = useFetchRushBalance();
const { data: userParticipatedStatus, fetchData: getRushUserParticipationStatus } = useFetch<
@@ -17,7 +18,7 @@ export function useFetchRushUserParticipationStatus() {
useEffect(() => {
if (userParticipatedStatus !== null) {
- setUserParticipationStatus(userParticipatedStatus);
+ dispatch({ type: RUSH_ACTION.SET_USER_PARTICIPATION, payload: userParticipatedStatus });
if (userParticipatedStatus && CARD_PHASE.IN_PROGRESS) {
fetchRushBalance();
}
diff --git a/client/src/hooks/useFetchTodayRushEvent.ts b/client/src/hooks/useFetchTodayRushEvent.ts
index 019365f8..fd7b75e6 100644
--- a/client/src/hooks/useFetchTodayRushEvent.ts
+++ b/client/src/hooks/useFetchTodayRushEvent.ts
@@ -2,12 +2,13 @@ import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useRushGameContext } from "@/hooks/useRushGameContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetTodayRushEventResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
import { getRandomCardColors } from "@/utils/getRandomCardColors";
export function useFetchTodayRushEvent() {
- const { setCardOptions } = useRushGameContext();
+ const dispatch = useRushGameDispatchContext();
const {
data: todayRushEventData,
@@ -19,15 +20,28 @@ export function useFetchTodayRushEvent() {
if (isSuccessTodayRushEvent && todayRushEventData) {
const { leftColor, rightColor } = getRandomCardColors();
- setCardOptions(CARD_OPTION.LEFT_OPTIONS, {
- mainText: todayRushEventData.leftOption.mainText,
- subText: todayRushEventData.leftOption.subText,
- color: leftColor,
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: CARD_OPTION.LEFT_OPTIONS,
+ updates: {
+ mainText: todayRushEventData.leftOption.mainText,
+ subText: todayRushEventData.leftOption.subText,
+ color: leftColor,
+ },
+ },
});
- setCardOptions(CARD_OPTION.RIGHT_OPTIONS, {
- mainText: todayRushEventData.rightOption.mainText,
- subText: todayRushEventData.rightOption.subText,
- color: rightColor,
+
+ dispatch({
+ type: RUSH_ACTION.SET_CARD_OPTIONS,
+ payload: {
+ option: CARD_OPTION.RIGHT_OPTIONS,
+ updates: {
+ mainText: todayRushEventData.rightOption.mainText,
+ subText: todayRushEventData.rightOption.subText,
+ color: rightColor,
+ },
+ },
});
}
}, [isSuccessTodayRushEvent, todayRushEventData]);
diff --git a/client/src/hooks/useRushGameContext.ts b/client/src/hooks/useRushGameContext.ts
deleted file mode 100644
index 45d785b5..00000000
--- a/client/src/hooks/useRushGameContext.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { useContext } from "react";
-import { RushGameContext } from "@/contexts/rushGameContext.tsx";
-
-export const useRushGameContext = () => {
- const context = useContext(RushGameContext);
- if (context === undefined) {
- throw new Error("useRushGameContext must be used within a RushGameProvider");
- }
- return context;
-};
diff --git a/client/src/hooks/useRushGameDispatchContext.ts b/client/src/hooks/useRushGameDispatchContext.ts
new file mode 100644
index 00000000..8222d6d0
--- /dev/null
+++ b/client/src/hooks/useRushGameDispatchContext.ts
@@ -0,0 +1,11 @@
+import { useContext } from "react";
+import { RushGameDispatchContext } from "@/contexts/rushGameContext.tsx";
+import { RushGameDispatchType } from "@/types/rushGame.ts";
+
+export default function useRushGameDispatchContext(): RushGameDispatchType {
+ const context = useContext(RushGameDispatchContext);
+ if (context === undefined) {
+ throw new Error("useRushGameDispatchContext must be used within a RushGameProvider");
+ }
+ return context;
+}
diff --git a/client/src/hooks/useRushGameStateContext.ts b/client/src/hooks/useRushGameStateContext.ts
new file mode 100644
index 00000000..ba5fd6bf
--- /dev/null
+++ b/client/src/hooks/useRushGameStateContext.ts
@@ -0,0 +1,11 @@
+import { useContext } from "react";
+import { RushGameStateContext } from "@/contexts/rushGameContext.tsx";
+import { RushGameStateType } from "@/types/rushGame.ts";
+
+export default function useRushGameStateContext(): RushGameStateType {
+ const context = useContext(RushGameStateContext);
+ if (context === undefined) {
+ throw new Error("useRushGameStateContext must be used within a RushGameProvider");
+ }
+ return context;
+}
diff --git a/client/src/hooks/useSetGamePhase.ts b/client/src/hooks/useSetGamePhase.ts
index 1b0efd66..49c545d7 100644
--- a/client/src/hooks/useSetGamePhase.ts
+++ b/client/src/hooks/useSetGamePhase.ts
@@ -1,11 +1,12 @@
import { useEffect } from "react";
import { CARD_PHASE } from "@/constants/Rush/rushCard";
-import { useRushGameStateContext } from "@/hooks/useRushGameStateContext.ts";
+import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
+import { RUSH_ACTION } from "@/types/rushGame.ts";
import { getMsTime } from "@/utils/getMsTime";
export default function useSetGamePhase(rushData: GetTotalRushEventsResponse) {
- const { setGamePhase } = useRushGameStateContext();
+ const dispatch = useRushGameDispatchContext();
useEffect(() => {
if (rushData) {
@@ -22,11 +23,11 @@ export default function useSetGamePhase(rushData: GetTotalRushEventsResponse) {
const endTime = getMsTime(currentEvent.endDateTime);
if (serverTime < startTime) {
- setGamePhase(CARD_PHASE.NOT_STARTED);
+ dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.NOT_STARTED });
} else if (serverTime >= startTime && serverTime <= endTime) {
- setGamePhase(CARD_PHASE.IN_PROGRESS);
+ dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.IN_PROGRESS });
} else if (serverTime > endTime) {
- setGamePhase(CARD_PHASE.COMPLETED);
+ dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.COMPLETED });
}
}
}
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index b2bd89a5..cf6e98b2 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -13,7 +13,7 @@ import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx"
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
import { useFetchRushUserParticipationStatus } from "@/hooks/useFetchRushUserParticipationStatus.ts";
import { useFetchTodayRushEvent } from "@/hooks/useFetchTodayRushEvent.ts";
-import { useRushGameStateContext } from "@/hooks/useRushGameStateContext.ts";
+import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import useSetGamePhase from "@/hooks/useSetGamePhase.ts";
import useToast from "@/hooks/useToast.tsx";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
@@ -25,7 +25,7 @@ export default function RushGame() {
"이 페이지를 떠나면 모든 변경 사항이 저장되지 않습니다. 페이지를 떠나시겠습니까?"
);
const { getTodayRushEvent } = useFetchTodayRushEvent();
- const { gameState } = useRushGameStateContext();
+ const gameState = useRushGameStateContext();
const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
const { getRushUserParticipationStatus, userParticipatedStatus } =
useFetchRushUserParticipationStatus();
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index a3d4bae4..f2d9788b 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -1,3 +1,4 @@
+import { Dispatch } from "react";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE, WIN_STATUS } from "@/constants/Rush/rushCard.ts";
export type GamePhase = (typeof CARD_PHASE)[keyof typeof CARD_PHASE];
@@ -14,17 +15,29 @@ export interface CardOptionState {
selectionCount: number;
}
-export interface RushGameContextType {
- gameState: {
- phase: GamePhase;
- userParticipatedStatus: boolean;
- userSelectedOption: CardOption;
- cardOptions: {
- [key in CardOption]: CardOptionState;
- };
+export interface RushGameStateType {
+ phase: GamePhase;
+ userParticipatedStatus: boolean;
+ userSelectedOption: CardOption;
+ cardOptions: {
+ [key in CardOption]: CardOptionState;
};
- setCardOptions: (option: CardOption, updates: Partial) => void;
- setUserParticipationStatus: (status: boolean) => void;
- setGamePhase: (phase: GamePhase) => void;
- setUserSelectedOption: (option: CardOption) => void;
}
+
+export const RUSH_ACTION = {
+ SET_PHASE: "SET_PHASE",
+ SET_USER_PARTICIPATION: "SET_USER_PARTICIPATION",
+ SET_USER_OPTION: "SET_USER_OPTION",
+ SET_CARD_OPTIONS: "SET_CARD_OPTIONS",
+} as const;
+
+export type RushGameAction =
+ | { type: typeof RUSH_ACTION.SET_PHASE; payload: GamePhase }
+ | { type: typeof RUSH_ACTION.SET_USER_PARTICIPATION; payload: boolean }
+ | { type: typeof RUSH_ACTION.SET_USER_OPTION; payload: CardOption }
+ | {
+ type: typeof RUSH_ACTION.SET_CARD_OPTIONS;
+ payload: { option: CardOption; updates: Partial };
+ };
+
+export type RushGameDispatchType = Dispatch;
diff --git a/client/src/utils/RushGame/getOptionRatio.ts b/client/src/utils/RushGame/getOptionRatio.ts
index b052ac87..f26176d1 100644
--- a/client/src/utils/RushGame/getOptionRatio.ts
+++ b/client/src/utils/RushGame/getOptionRatio.ts
@@ -1,8 +1,8 @@
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
-import { CardOption, RushGameContextType } from "@/types/rushGame.ts";
+import { CardOption, RushGameStateType } from "@/types/rushGame.ts";
interface GetOptionRatioProps {
- gameState: RushGameContextType["gameState"];
+ gameState: RushGameStateType;
option: CardOption;
}
diff --git a/client/src/utils/RushGame/getSelectedCardInfo.ts b/client/src/utils/RushGame/getSelectedCardInfo.ts
index 3da60bee..59402f04 100644
--- a/client/src/utils/RushGame/getSelectedCardInfo.ts
+++ b/client/src/utils/RushGame/getSelectedCardInfo.ts
@@ -1,7 +1,7 @@
-import { CardOption, RushGameContextType } from "@/types/rushGame.ts";
+import { CardOption, RushGameStateType } from "@/types/rushGame.ts";
interface GetSelectedCardInfoProps {
- gameState: RushGameContextType["gameState"];
+ gameState: RushGameStateType;
option: CardOption;
}
From 47b4249bc92df56f1f772fb8197d7f8b2f6b9f9c Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 10:54:06 +0900
Subject: [PATCH 27/36] =?UTF-8?q?refactor:=20hooks=20=ED=8F=B4=EB=8D=94=20?=
=?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EB=B0=8F=20RushGame=20e?=
=?UTF-8?q?num=20=EB=B3=80=ED=99=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/constants/Rush/rushCard.ts | 40 +++++++++----------
.../CasperCard/MyCasperCardBack.tsx | 2 +-
.../CasperCard/MyCasperCardFront.tsx | 4 +-
.../CasperCustomPanel/CasperCustomPanel.tsx | 4 +-
.../CasperCustomPanel/EyesPanel.tsx | 4 +-
.../CustomProcess/CasperCustomFinish.tsx | 4 +-
.../CustomProcess/CasperCustomFinishing.tsx | 2 +-
.../CustomProcess/CasperCustomForm.tsx | 4 +-
.../CustomProcess/CasperCustomProcess.tsx | 2 +-
.../RushGameComponents/RushCardComparison.tsx | 6 +--
.../RushCardCurrentRatio.tsx | 4 +-
.../RushCardResultDescription.tsx | 4 +-
.../RushGameComponents/RushCountdown.tsx | 4 +-
.../RushGameComponents/RushProgressBar.tsx | 2 +-
.../RushGame/RushGameSections/Countdown.tsx | 4 +-
.../RushGame/RushGameSections/FinalResult.tsx | 4 +-
.../RushGameSections/SelectedCard.tsx | 2 +-
.../useCasperCustomDispatchContext.ts | 4 +-
.../useCasperCustomStateContext.ts | 4 +-
.../usePhoneNumberDispatchContext.ts | 4 +-
.../usePhoneNumberStateContext.ts | 4 +-
.../useRushGameDispatchContext.ts | 0
.../{ => Contexts}/useRushGameStateContext.ts | 0
.../{ => RushGame}/useFetchRushBalance.ts | 2 +-
.../useFetchRushOptionResult.ts | 4 +-
.../{ => RushGame}/useFetchRushResult.ts | 2 +-
.../useFetchRushUserParticipationStatus.ts | 4 +-
.../{ => RushGame}/useFetchTodayRushEvent.ts | 4 +-
.../hooks/{ => RushGame}/useSetGamePhase.ts | 6 +--
client/src/hooks/useAuth.ts | 4 +-
client/src/pages/RushGame/index.tsx | 8 ++--
client/src/types/rushGame.ts | 28 ++++++-------
32 files changed, 87 insertions(+), 87 deletions(-)
rename client/src/hooks/{ => Contexts}/useCasperCustomDispatchContext.ts (70%)
rename client/src/hooks/{ => Contexts}/useCasperCustomStateContext.ts (70%)
rename client/src/hooks/{ => Contexts}/usePhoneNumberDispatchContext.ts (70%)
rename client/src/hooks/{ => Contexts}/usePhoneNumberStateContext.ts (70%)
rename client/src/hooks/{ => Contexts}/useRushGameDispatchContext.ts (100%)
rename client/src/hooks/{ => Contexts}/useRushGameStateContext.ts (100%)
rename client/src/hooks/{ => RushGame}/useFetchRushBalance.ts (95%)
rename client/src/hooks/{ => RushGame}/useFetchRushOptionResult.ts (88%)
rename client/src/hooks/{ => RushGame}/useFetchRushResult.ts (94%)
rename client/src/hooks/{ => RushGame}/useFetchRushUserParticipationStatus.ts (87%)
rename client/src/hooks/{ => RushGame}/useFetchTodayRushEvent.ts (95%)
rename client/src/hooks/{ => RushGame}/useSetGamePhase.ts (88%)
diff --git a/client/src/constants/Rush/rushCard.ts b/client/src/constants/Rush/rushCard.ts
index 86a3e75f..d0b8c8b0 100644
--- a/client/src/constants/Rush/rushCard.ts
+++ b/client/src/constants/Rush/rushCard.ts
@@ -1,23 +1,23 @@
-export const CARD_PHASE = {
- NOT_STARTED: "NOT_STARTED",
- IN_PROGRESS: "IN_PROGRESS",
- COMPLETED: "COMPLETED",
-} as const;
+export const enum CARD_PHASE {
+ NOT_STARTED = "NOT_STARTED",
+ IN_PROGRESS = "IN_PROGRESS",
+ COMPLETED = "COMPLETED",
+}
-export const CARD_COLOR = {
- BLUE: "blue",
- RED: "red",
- YELLOW: "yellow",
- GREEN: "green",
-} as const;
+export enum CARD_COLOR {
+ BLUE = "blue",
+ RED = "red",
+ YELLOW = "yellow",
+ GREEN = "green",
+}
-export const CARD_OPTION = {
- LEFT_OPTIONS: 1,
- RIGHT_OPTIONS: 2,
-} as const;
+export const enum CARD_OPTION {
+ LEFT_OPTIONS = 1,
+ RIGHT_OPTIONS = 2,
+}
-export const WIN_STATUS = {
- WIN: "Win",
- LOSE: "Lose",
- TIE: "Tie",
-} as const;
+export const enum WIN_STATUS {
+ WIN = "Win",
+ LOSE = "Lose",
+ TIE = "Tie",
+}
diff --git a/client/src/features/CasperCustom/CasperCard/MyCasperCardBack.tsx b/client/src/features/CasperCustom/CasperCard/MyCasperCardBack.tsx
index 6749f62d..89a0558b 100644
--- a/client/src/features/CasperCustom/CasperCard/MyCasperCardBack.tsx
+++ b/client/src/features/CasperCustom/CasperCard/MyCasperCardBack.tsx
@@ -1,5 +1,5 @@
import { CASPER_SIZE_OPTION } from "@/constants/CasperCustom/casper";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import { CasperCardBackUI } from "./CasperCardBackUI";
interface MyCasperCardBackProps {
diff --git a/client/src/features/CasperCustom/CasperCard/MyCasperCardFront.tsx b/client/src/features/CasperCustom/CasperCard/MyCasperCardFront.tsx
index 924ba2f5..1844704d 100644
--- a/client/src/features/CasperCustom/CasperCard/MyCasperCardFront.tsx
+++ b/client/src/features/CasperCustom/CasperCard/MyCasperCardFront.tsx
@@ -1,7 +1,7 @@
import { memo, useCallback } from "react";
import { CASPER_SIZE_OPTION } from "@/constants/CasperCustom/casper";
-import useCasperCustomDispatchContext from "@/hooks/useCasperCustomDispatchContext";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomDispatchContext from "@/hooks/Contexts/useCasperCustomDispatchContext.ts";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import { CASPER_ACTION } from "@/types/casperCustom";
import { CasperCardFrontUI } from "./CasperCardFrontUI";
diff --git a/client/src/features/CasperCustom/CasperCustomPanel/CasperCustomPanel.tsx b/client/src/features/CasperCustom/CasperCustomPanel/CasperCustomPanel.tsx
index 7c3b331d..d7ec2324 100644
--- a/client/src/features/CasperCustom/CasperCustomPanel/CasperCustomPanel.tsx
+++ b/client/src/features/CasperCustom/CasperCustomPanel/CasperCustomPanel.tsx
@@ -1,8 +1,8 @@
import { useCallback, useEffect } from "react";
import { cva } from "class-variance-authority";
import { CASPER_OPTION, CUSTOM_OPTION, OPTION_TYPE } from "@/constants/CasperCustom/casper";
-import useCasperCustomDispatchContext from "@/hooks/useCasperCustomDispatchContext";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomDispatchContext from "@/hooks/Contexts/useCasperCustomDispatchContext.ts";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import { CASPER_ACTION } from "@/types/casperCustom";
import { CustomOptionImageItem } from "./CustomOptionImageItem";
import { EyesPanel as EyesPanelComponent } from "./EyesPanel";
diff --git a/client/src/features/CasperCustom/CasperCustomPanel/EyesPanel.tsx b/client/src/features/CasperCustom/CasperCustomPanel/EyesPanel.tsx
index 827c4e60..97d4d299 100644
--- a/client/src/features/CasperCustom/CasperCustomPanel/EyesPanel.tsx
+++ b/client/src/features/CasperCustom/CasperCustomPanel/EyesPanel.tsx
@@ -6,8 +6,8 @@ import {
OPTION_TYPE,
POSITION_OPTION,
} from "@/constants/CasperCustom/casper";
-import useCasperCustomDispatchContext from "@/hooks/useCasperCustomDispatchContext";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomDispatchContext from "@/hooks/Contexts/useCasperCustomDispatchContext.ts";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import { CASPER_ACTION } from "@/types/casperCustom";
import { CasperCustomPanelLayout } from "./CasperCustomPanelLayout";
import { EyesOptionImageItem } from "./EyesOptionImageItem";
diff --git a/client/src/features/CasperCustom/CustomProcess/CasperCustomFinish.tsx b/client/src/features/CasperCustom/CustomProcess/CasperCustomFinish.tsx
index d1092a5d..7091adb7 100644
--- a/client/src/features/CasperCustom/CustomProcess/CasperCustomFinish.tsx
+++ b/client/src/features/CasperCustom/CustomProcess/CasperCustomFinish.tsx
@@ -10,8 +10,8 @@ import { DISSOLVE } from "@/constants/animation";
import { SCROLL_MOTION } from "@/constants/animation";
import { COOKIE_KEY } from "@/constants/cookie";
import { MyCasperCardFront } from "@/features/CasperCustom/CasperCard/MyCasperCardFront";
-import useCasperCustomDispatchContext from "@/hooks/useCasperCustomDispatchContext";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomDispatchContext from "@/hooks/Contexts/useCasperCustomDispatchContext.ts";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import useFetch from "@/hooks/useFetch";
import useToast from "@/hooks/useToast";
import { CASPER_ACTION } from "@/types/casperCustom";
diff --git a/client/src/features/CasperCustom/CustomProcess/CasperCustomFinishing.tsx b/client/src/features/CasperCustom/CustomProcess/CasperCustomFinishing.tsx
index 74c53203..6906a8fe 100644
--- a/client/src/features/CasperCustom/CustomProcess/CasperCustomFinishing.tsx
+++ b/client/src/features/CasperCustom/CustomProcess/CasperCustomFinishing.tsx
@@ -4,7 +4,7 @@ import { CASPER_SIZE_OPTION } from "@/constants/CasperCustom/casper";
import { DISSOLVE } from "@/constants/animation";
import { SCROLL_MOTION } from "@/constants/animation";
import { CasperFlipCard } from "@/features/CasperCustom/CasperCard/CasperFlipCard";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import useToast from "@/hooks/useToast";
import type { CasperCardType } from "@/types/casper";
diff --git a/client/src/features/CasperCustom/CustomProcess/CasperCustomForm.tsx b/client/src/features/CasperCustom/CustomProcess/CasperCustomForm.tsx
index b58d4d49..25be67ec 100644
--- a/client/src/features/CasperCustom/CustomProcess/CasperCustomForm.tsx
+++ b/client/src/features/CasperCustom/CustomProcess/CasperCustomForm.tsx
@@ -9,8 +9,8 @@ import { DISSOLVE } from "@/constants/animation";
import { SCROLL_MOTION } from "@/constants/animation";
import { COOKIE_KEY } from "@/constants/cookie";
import { MyCasperCardFront } from "@/features/CasperCustom/CasperCard/MyCasperCardFront";
-import useCasperCustomDispatchContext from "@/hooks/useCasperCustomDispatchContext";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomDispatchContext from "@/hooks/Contexts/useCasperCustomDispatchContext.ts";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import useFetch from "@/hooks/useFetch";
import { CASPER_ACTION } from "@/types/casperCustom";
import { CasperInformationType, PostCasperResponse } from "@/types/lotteryApi";
diff --git a/client/src/features/CasperCustom/CustomProcess/CasperCustomProcess.tsx b/client/src/features/CasperCustom/CustomProcess/CasperCustomProcess.tsx
index bc03fef7..ff680835 100644
--- a/client/src/features/CasperCustom/CustomProcess/CasperCustomProcess.tsx
+++ b/client/src/features/CasperCustom/CustomProcess/CasperCustomProcess.tsx
@@ -6,7 +6,7 @@ import { CUSTOM_OPTION_ARRAY } from "@/constants/CasperCustom/customStep";
import { DISSOLVE } from "@/constants/animation";
import { SCROLL_MOTION } from "@/constants/animation";
import { MyCasperCardFront } from "@/features/CasperCustom/CasperCard/MyCasperCardFront";
-import useCasperCustomStateContext from "@/hooks/useCasperCustomStateContext";
+import useCasperCustomStateContext from "@/hooks/Contexts/useCasperCustomStateContext.ts";
import { getCasperOptionDescription } from "@/utils/CasperCustom/getCasperOptionDescription";
interface CasperCustomProcessProps {
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
index 8d82378d..75eb6a85 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardComparison.tsx
@@ -4,10 +4,10 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushCard from "@/features/RushGame/RushGameComponents/RushCard.tsx";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
+import { useFetchRushUserParticipationStatus } from "@/hooks/RushGame/useFetchRushUserParticipationStatus.ts";
import useFetch from "@/hooks/useFetch.ts";
-import { useFetchRushUserParticipationStatus } from "@/hooks/useFetchRushUserParticipationStatus.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { RushEventStatusCodeResponse } from "@/types/rushApi.ts";
import { CardOption, RUSH_ACTION } from "@/types/rushGame.ts";
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
index 2ce0397a..667115f9 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
@@ -3,8 +3,8 @@ import Tooltip from "@/components/Tooltip";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import RushCurrentOptionDisplay from "@/features/RushGame/RushGameComponents/RushCurrentOptionDisplay.tsx";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
-import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
+import useFetchRushBalance from "@/hooks/RushGame/useFetchRushBalance.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import { CardOption } from "@/types/rushGame.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index ee75ffdb..153708da 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -4,8 +4,8 @@ import { useCookies } from "react-cookie";
import Category from "@/components/Category";
import { CARD_COLOR } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
-import { useFetchRushOptionResult } from "@/hooks/useFetchRushOptionResult.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
+import { useFetchRushOptionResult } from "@/hooks/RushGame/useFetchRushOptionResult.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index 529f3b70..95917b2c 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -1,10 +1,10 @@
import { useEffect, useState } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
import useCountdown from "@/hooks/useCountdown.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
diff --git a/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx b/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
index a1143764..a8c9f4a4 100644
--- a/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushProgressBar.tsx
@@ -1,6 +1,6 @@
import { CARD_COLOR, CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import RushBar from "@/features/RushGame/RushGameComponents/RushBar.tsx";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
interface RushProgressBarProps {
leftOptionRatio: number;
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index c681a845..138c29bc 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -4,10 +4,10 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { Background } from "@/components/Background";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
import useCountdown from "@/hooks/useCountdown.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 30a6919f..2ec4ae16 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -6,8 +6,8 @@ import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
import RushResultOptionDisplay from "@/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx";
-import { useFetchRushResult } from "@/hooks/useFetchRushResult.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
+import { useFetchRushResult } from "@/hooks/RushGame/useFetchRushResult.ts";
import { WinStatus } from "@/types/rushGame.ts";
import { getOptionRatio } from "@/utils/RushGame/getOptionRatio.ts";
import { getSelectedCardInfo } from "@/utils/RushGame/getSelectedCardInfo.ts";
diff --git a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
index a1217608..61cf20b7 100644
--- a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
+++ b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
@@ -4,7 +4,7 @@ import { ASCEND, DISSOLVE, SCROLL_MOTION } from "@/constants/animation.ts";
import RushCardCurrentRatio from "@/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx";
import RushCardResultDescription from "@/features/RushGame/RushGameComponents/RushCardResultDescription.tsx";
import RushCountdown from "@/features/RushGame/RushGameComponents/RushCountdown.tsx";
-import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
+import useFetchRushBalance from "@/hooks/RushGame/useFetchRushBalance.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import ArrowLeftIcon from "/public/assets/icons/arrow-line-left.svg?react";
import ArrowRightIcon from "/public/assets/icons/arrow-line-right.svg?react";
diff --git a/client/src/hooks/useCasperCustomDispatchContext.ts b/client/src/hooks/Contexts/useCasperCustomDispatchContext.ts
similarity index 70%
rename from client/src/hooks/useCasperCustomDispatchContext.ts
rename to client/src/hooks/Contexts/useCasperCustomDispatchContext.ts
index 63be8868..bcc4aa36 100644
--- a/client/src/hooks/useCasperCustomDispatchContext.ts
+++ b/client/src/hooks/Contexts/useCasperCustomDispatchContext.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
-import { CasperCustomDispatchType } from "@/types/casperCustom";
-import { CasperCustomDispatchContext } from "../contexts/casperCustomContext";
+import { CasperCustomDispatchType } from "@/types/casperCustom.ts";
+import { CasperCustomDispatchContext } from "../../contexts/casperCustomContext.tsx";
export default function useCasperCustomDispatchContext(): CasperCustomDispatchType {
const context = useContext(CasperCustomDispatchContext);
diff --git a/client/src/hooks/useCasperCustomStateContext.ts b/client/src/hooks/Contexts/useCasperCustomStateContext.ts
similarity index 70%
rename from client/src/hooks/useCasperCustomStateContext.ts
rename to client/src/hooks/Contexts/useCasperCustomStateContext.ts
index 31979d6d..cc7b6ff9 100644
--- a/client/src/hooks/useCasperCustomStateContext.ts
+++ b/client/src/hooks/Contexts/useCasperCustomStateContext.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
-import { CasperCustomStateType } from "@/types/casperCustom";
-import { CasperCustomStateContext } from "../contexts/casperCustomContext";
+import { CasperCustomStateType } from "@/types/casperCustom.ts";
+import { CasperCustomStateContext } from "../../contexts/casperCustomContext.tsx";
export default function useCasperCustomStateContext(): CasperCustomStateType {
const context = useContext(CasperCustomStateContext);
diff --git a/client/src/hooks/usePhoneNumberDispatchContext.ts b/client/src/hooks/Contexts/usePhoneNumberDispatchContext.ts
similarity index 70%
rename from client/src/hooks/usePhoneNumberDispatchContext.ts
rename to client/src/hooks/Contexts/usePhoneNumberDispatchContext.ts
index 195b48e7..090e1b54 100644
--- a/client/src/hooks/usePhoneNumberDispatchContext.ts
+++ b/client/src/hooks/Contexts/usePhoneNumberDispatchContext.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
-import { PhoneNumberDispatchType } from "@/types/phoneNumber";
-import { PhoneNumberDispatchContext } from "../contexts/phoneNumberContext";
+import { PhoneNumberDispatchType } from "@/types/phoneNumber.ts";
+import { PhoneNumberDispatchContext } from "../../contexts/phoneNumberContext.tsx";
export default function usePhoneNumberDispatchContext(): PhoneNumberDispatchType {
const context = useContext(PhoneNumberDispatchContext);
diff --git a/client/src/hooks/usePhoneNumberStateContext.ts b/client/src/hooks/Contexts/usePhoneNumberStateContext.ts
similarity index 70%
rename from client/src/hooks/usePhoneNumberStateContext.ts
rename to client/src/hooks/Contexts/usePhoneNumberStateContext.ts
index 286f38b9..475a4fc7 100644
--- a/client/src/hooks/usePhoneNumberStateContext.ts
+++ b/client/src/hooks/Contexts/usePhoneNumberStateContext.ts
@@ -1,6 +1,6 @@
import { useContext } from "react";
-import { PhoneNumberStateType } from "@/types/phoneNumber";
-import { PhoneNumberStateContext } from "../contexts/phoneNumberContext";
+import { PhoneNumberStateType } from "@/types/phoneNumber.ts";
+import { PhoneNumberStateContext } from "../../contexts/phoneNumberContext.tsx";
export default function usePhoneNumberStateContext(): PhoneNumberStateType {
const context = useContext(PhoneNumberStateContext);
diff --git a/client/src/hooks/useRushGameDispatchContext.ts b/client/src/hooks/Contexts/useRushGameDispatchContext.ts
similarity index 100%
rename from client/src/hooks/useRushGameDispatchContext.ts
rename to client/src/hooks/Contexts/useRushGameDispatchContext.ts
diff --git a/client/src/hooks/useRushGameStateContext.ts b/client/src/hooks/Contexts/useRushGameStateContext.ts
similarity index 100%
rename from client/src/hooks/useRushGameStateContext.ts
rename to client/src/hooks/Contexts/useRushGameStateContext.ts
diff --git a/client/src/hooks/useFetchRushBalance.ts b/client/src/hooks/RushGame/useFetchRushBalance.ts
similarity index 95%
rename from client/src/hooks/useFetchRushBalance.ts
rename to client/src/hooks/RushGame/useFetchRushBalance.ts
index 0650e0c6..4a0573be 100644
--- a/client/src/hooks/useFetchRushBalance.ts
+++ b/client/src/hooks/RushGame/useFetchRushBalance.ts
@@ -3,8 +3,8 @@ import { useCookies } from "react-cookie";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetRushBalanceResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
diff --git a/client/src/hooks/useFetchRushOptionResult.ts b/client/src/hooks/RushGame/useFetchRushOptionResult.ts
similarity index 88%
rename from client/src/hooks/useFetchRushOptionResult.ts
rename to client/src/hooks/RushGame/useFetchRushOptionResult.ts
index 567f3af5..1c06dd86 100644
--- a/client/src/hooks/useFetchRushOptionResult.ts
+++ b/client/src/hooks/RushGame/useFetchRushOptionResult.ts
@@ -1,8 +1,8 @@
import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
import { GetRushOptionResultResponse } from "@/types/rushApi.ts";
import { CardOption, RUSH_ACTION } from "@/types/rushGame.ts";
diff --git a/client/src/hooks/useFetchRushResult.ts b/client/src/hooks/RushGame/useFetchRushResult.ts
similarity index 94%
rename from client/src/hooks/useFetchRushResult.ts
rename to client/src/hooks/RushGame/useFetchRushResult.ts
index 09c84087..42fbe25a 100644
--- a/client/src/hooks/useFetchRushResult.ts
+++ b/client/src/hooks/RushGame/useFetchRushResult.ts
@@ -1,8 +1,8 @@
import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetRushResultResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
diff --git a/client/src/hooks/useFetchRushUserParticipationStatus.ts b/client/src/hooks/RushGame/useFetchRushUserParticipationStatus.ts
similarity index 87%
rename from client/src/hooks/useFetchRushUserParticipationStatus.ts
rename to client/src/hooks/RushGame/useFetchRushUserParticipationStatus.ts
index de9a53eb..642d4518 100644
--- a/client/src/hooks/useFetchRushUserParticipationStatus.ts
+++ b/client/src/hooks/RushGame/useFetchRushUserParticipationStatus.ts
@@ -1,9 +1,9 @@
import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
+import useFetchRushBalance from "@/hooks/RushGame/useFetchRushBalance.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useFetchRushBalance from "@/hooks/useFetchRushBalance.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetRushUserParticipationStatusResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
diff --git a/client/src/hooks/useFetchTodayRushEvent.ts b/client/src/hooks/RushGame/useFetchTodayRushEvent.ts
similarity index 95%
rename from client/src/hooks/useFetchTodayRushEvent.ts
rename to client/src/hooks/RushGame/useFetchTodayRushEvent.ts
index fd7b75e6..299a4970 100644
--- a/client/src/hooks/useFetchTodayRushEvent.ts
+++ b/client/src/hooks/RushGame/useFetchTodayRushEvent.ts
@@ -1,11 +1,11 @@
import { useEffect } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
import useFetch from "@/hooks/useFetch.ts";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
import { GetTodayRushEventResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
-import { getRandomCardColors } from "@/utils/getRandomCardColors";
+import { getRandomCardColors } from "@/utils/getRandomCardColors.ts";
export function useFetchTodayRushEvent() {
const dispatch = useRushGameDispatchContext();
diff --git a/client/src/hooks/useSetGamePhase.ts b/client/src/hooks/RushGame/useSetGamePhase.ts
similarity index 88%
rename from client/src/hooks/useSetGamePhase.ts
rename to client/src/hooks/RushGame/useSetGamePhase.ts
index 49c545d7..1017115b 100644
--- a/client/src/hooks/useSetGamePhase.ts
+++ b/client/src/hooks/RushGame/useSetGamePhase.ts
@@ -1,9 +1,9 @@
import { useEffect } from "react";
-import { CARD_PHASE } from "@/constants/Rush/rushCard";
-import useRushGameDispatchContext from "@/hooks/useRushGameDispatchContext.ts";
+import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
+import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
-import { getMsTime } from "@/utils/getMsTime";
+import { getMsTime } from "@/utils/getMsTime.ts";
export default function useSetGamePhase(rushData: GetTotalRushEventsResponse) {
const dispatch = useRushGameDispatchContext();
diff --git a/client/src/hooks/useAuth.ts b/client/src/hooks/useAuth.ts
index d9ada041..8ad42a08 100644
--- a/client/src/hooks/useAuth.ts
+++ b/client/src/hooks/useAuth.ts
@@ -3,9 +3,9 @@ import { useCookies } from "react-cookie";
import { useLocation, useNavigate } from "react-router-dom";
import { AuthAPI } from "@/apis/authAPI";
import { COOKIE_KEY } from "@/constants/cookie";
+import usePhoneNumberDispatchContext from "@/hooks/Contexts/usePhoneNumberDispatchContext.ts";
+import usePhoneNumberStateContext from "@/hooks/Contexts/usePhoneNumberStateContext.ts";
import useFetch from "@/hooks/useFetch";
-import usePhoneNumberDispatchContext from "@/hooks/usePhoneNumberDispatchContext";
-import usePhoneNumberStateContext from "@/hooks/usePhoneNumberStateContext";
import { PostAuthResponse } from "@/types/authApi";
import { PHONE_NUMBER_ACTION } from "@/types/phoneNumber";
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index cf6e98b2..1670d0d9 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -10,11 +10,11 @@ import CardOptions from "@/features/RushGame/RushGameSections/CardOptions.tsx";
import Countdown from "@/features/RushGame/RushGameSections/Countdown.tsx";
import FinalResult from "@/features/RushGame/RushGameSections/FinalResult.tsx";
import SelectedCard from "@/features/RushGame/RushGameSections/SelectedCard.tsx";
+import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
+import { useFetchRushUserParticipationStatus } from "@/hooks/RushGame/useFetchRushUserParticipationStatus.ts";
+import { useFetchTodayRushEvent } from "@/hooks/RushGame/useFetchTodayRushEvent.ts";
+import useSetGamePhase from "@/hooks/RushGame/useSetGamePhase.ts";
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
-import { useFetchRushUserParticipationStatus } from "@/hooks/useFetchRushUserParticipationStatus.ts";
-import { useFetchTodayRushEvent } from "@/hooks/useFetchTodayRushEvent.ts";
-import useRushGameStateContext from "@/hooks/useRushGameStateContext.ts";
-import useSetGamePhase from "@/hooks/useSetGamePhase.ts";
import useToast from "@/hooks/useToast.tsx";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { writeClipboard } from "@/utils/writeClipboard.ts";
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index f2d9788b..60f7711f 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -1,10 +1,10 @@
import { Dispatch } from "react";
import { CARD_COLOR, CARD_OPTION, CARD_PHASE, WIN_STATUS } from "@/constants/Rush/rushCard.ts";
-export type GamePhase = (typeof CARD_PHASE)[keyof typeof CARD_PHASE];
-export type CardColor = (typeof CARD_COLOR)[keyof typeof CARD_COLOR];
-export type CardOption = (typeof CARD_OPTION)[keyof typeof CARD_OPTION];
-export type WinStatus = (typeof WIN_STATUS)[keyof typeof WIN_STATUS];
+export type GamePhase = CARD_PHASE;
+export type CardColor = CARD_COLOR;
+export type CardOption = CARD_OPTION;
+export type WinStatus = WIN_STATUS;
export interface CardOptionState {
mainText: string;
@@ -24,19 +24,19 @@ export interface RushGameStateType {
};
}
-export const RUSH_ACTION = {
- SET_PHASE: "SET_PHASE",
- SET_USER_PARTICIPATION: "SET_USER_PARTICIPATION",
- SET_USER_OPTION: "SET_USER_OPTION",
- SET_CARD_OPTIONS: "SET_CARD_OPTIONS",
-} as const;
+export enum RUSH_ACTION {
+ SET_PHASE = "SET_PHASE",
+ SET_USER_PARTICIPATION = "SET_USER_PARTICIPATION",
+ SET_USER_OPTION = "SET_USER_OPTION",
+ SET_CARD_OPTIONS = "SET_CARD_OPTIONS",
+}
export type RushGameAction =
- | { type: typeof RUSH_ACTION.SET_PHASE; payload: GamePhase }
- | { type: typeof RUSH_ACTION.SET_USER_PARTICIPATION; payload: boolean }
- | { type: typeof RUSH_ACTION.SET_USER_OPTION; payload: CardOption }
+ | { type: RUSH_ACTION.SET_PHASE; payload: GamePhase }
+ | { type: RUSH_ACTION.SET_USER_PARTICIPATION; payload: boolean }
+ | { type: RUSH_ACTION.SET_USER_OPTION; payload: CardOption }
| {
- type: typeof RUSH_ACTION.SET_CARD_OPTIONS;
+ type: RUSH_ACTION.SET_CARD_OPTIONS;
payload: { option: CardOption; updates: Partial };
};
From a9aad6f2838a945c6a83594a9b3d40d6b699141c Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 11:54:19 +0900
Subject: [PATCH 28/36] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=B2=A4=ED=8A=B8?=
=?UTF-8?q?=20=EA=B3=B5=EC=9C=A0=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?=
=?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20FinalResult=20UX=20=EA=B0=9C?=
=?UTF-8?q?=EC=84=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/contexts/rushGameContext.tsx | 4 +-
.../RushGameComponents/RushShareLink.tsx | 28 +++++
.../RushGame/RushGameSections/CardOptions.tsx | 40 +++----
.../RushGame/RushGameSections/Countdown.tsx | 2 +
.../RushGame/RushGameSections/FinalResult.tsx | 100 ++++++++++--------
.../RushGameSections/SelectedCard.tsx | 26 +++--
client/src/pages/RushGame/index.tsx | 22 +---
client/src/types/rushGame.ts | 2 +-
8 files changed, 125 insertions(+), 99 deletions(-)
create mode 100644 client/src/features/RushGame/RushGameComponents/RushShareLink.tsx
diff --git a/client/src/contexts/rushGameContext.tsx b/client/src/contexts/rushGameContext.tsx
index f95a1880..7a56b586 100644
--- a/client/src/contexts/rushGameContext.tsx
+++ b/client/src/contexts/rushGameContext.tsx
@@ -1,5 +1,5 @@
import { ReactNode, createContext, useReducer } from "react";
-import { CARD_COLOR, CARD_OPTION, CARD_PHASE } from "@/constants/Rush/rushCard";
+import { CARD_COLOR, CARD_OPTION } from "@/constants/Rush/rushCard";
import {
RUSH_ACTION,
RushGameAction,
@@ -11,7 +11,7 @@ export const RushGameStateContext = createContext
export const RushGameDispatchContext = createContext(undefined);
const initialGameState: RushGameStateType = {
- phase: CARD_PHASE.NOT_STARTED,
+ phase: null,
userParticipatedStatus: false,
userSelectedOption: CARD_OPTION.LEFT_OPTIONS,
cardOptions: {
diff --git a/client/src/features/RushGame/RushGameComponents/RushShareLink.tsx b/client/src/features/RushGame/RushGameComponents/RushShareLink.tsx
new file mode 100644
index 00000000..7644c61e
--- /dev/null
+++ b/client/src/features/RushGame/RushGameComponents/RushShareLink.tsx
@@ -0,0 +1,28 @@
+import { motion } from "framer-motion";
+import CTAButton from "@/components/CTAButton";
+import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
+import useToast from "@/hooks/useToast.tsx";
+import { writeClipboard } from "@/utils/writeClipboard.ts";
+
+export default function RushShareLink() {
+ const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
+
+ const handleClickShareButton = () => {
+ writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
+ };
+
+ return (
+ <>
+
+
+ 우리 편에 투표할 친구를 불러오세요!
+
+
+
+ {ToastComponent}
+ >
+ );
+}
diff --git a/client/src/features/RushGame/RushGameSections/CardOptions.tsx b/client/src/features/RushGame/RushGameSections/CardOptions.tsx
index e6d573ae..42b2008b 100644
--- a/client/src/features/RushGame/RushGameSections/CardOptions.tsx
+++ b/client/src/features/RushGame/RushGameSections/CardOptions.tsx
@@ -2,29 +2,33 @@ import { motion } from "framer-motion";
import { ASCEND, DISSOLVE, SCROLL_MOTION } from "@/constants/animation.ts";
import RushCardComparison from "@/features/RushGame/RushGameComponents/RushCardComparison.tsx";
import RushCountdown from "@/features/RushGame/RushGameComponents/RushCountdown.tsx";
+import RushShareLink from "@/features/RushGame/RushGameComponents/RushShareLink.tsx";
import useToggleContents from "@/hooks/useToggleContents.ts";
export default function CardOptions() {
const { toggleContents } = useToggleContents();
return (
-
- {toggleContents ? (
-
- 2개의 후보 중 하나를 선택해주세요
-
- ) : (
-
-
-
- )}
-
-
+ <>
+
+ {toggleContents ? (
+
+ 2개의 후보 중 하나를 선택해주세요
+
+ ) : (
+
+
+
+ )}
+
+
+
+ >
);
}
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 138c29bc..f44d35bf 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -4,6 +4,7 @@ import { RushAPI } from "@/apis/rushAPI.ts";
import { Background } from "@/components/Background";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
+import RushShareLink from "@/features/RushGame/RushGameComponents/RushShareLink.tsx";
import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
import useCountdown from "@/hooks/useCountdown.ts";
@@ -100,6 +101,7 @@ export default function Countdown() {
이제 곧 하단에 밸런스 게임 주제가 공개돼요!
+
>
);
}
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 2ec4ae16..23e32e59 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -6,6 +6,7 @@ import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import RushProgressBar from "@/features/RushGame/RushGameComponents/RushProgressBar.tsx";
import RushResultOptionDisplay from "@/features/RushGame/RushGameComponents/RushResultOptionDisplay.tsx";
+import RushShareLink from "@/features/RushGame/RushGameComponents/RushShareLink.tsx";
import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
import { useFetchRushResult } from "@/hooks/RushGame/useFetchRushResult.ts";
import { WinStatus } from "@/types/rushGame.ts";
@@ -39,8 +40,8 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const userParticipatedStatus = gameState.userParticipatedStatus;
const isWinner = resultData?.isWinner;
- const rank = resultData?.rank || 0;
- const totalParticipants = resultData?.totalParticipants || 0;
+ const rank = resultData?.rank;
+ const totalParticipants = resultData?.totalParticipants;
const message = isWinner ? MESSAGES.WINNING : MESSAGES.LOSING;
@@ -65,54 +66,61 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const leftWinStatus = getWinStatus(leftOptionRatio, rightOptionRatio);
const rightWinStatus = getWinStatus(rightOptionRatio, leftOptionRatio);
+ const isValidData =
+ isWinner !== undefined && rank !== undefined && totalParticipants !== undefined;
+ if (!isValidData) return null;
+
return (
-
- {message}
-
- *이 화면은 밤 12시 이후 재접속이 불가능합니다.
- 입력하신 전화번호로 경품 수령 관련 메시지가 전송될 예정이에요.
-
-
- {userParticipatedStatus && (
-
- 나의 선착순 등수
-
- {rank}등
-
- / {totalParticipants.toLocaleString("en-US")}명 중
-
+ <>
+
+ {message}
+
+ *이 화면은 밤 12시 이후 재접속이 불가능합니다.
+ 입력하신 전화번호로 경품 수령 관련 메시지가 전송될 예정이에요.
+
+
+ {userParticipatedStatus && (
+
+ 나의 선착순 등수
+
+ {rank}등
+
+ / {totalParticipants.toLocaleString("en-US")}명 중
+
+
-
- )}
-
-
최종 밸런스 게임 결과
-
-
-
+ 최종 밸런스 게임 결과
+
+
+
+
+
-
-
-
+
+
+ >
);
}
diff --git a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
index 61cf20b7..8a7543b7 100644
--- a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
+++ b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
@@ -4,6 +4,7 @@ import { ASCEND, DISSOLVE, SCROLL_MOTION } from "@/constants/animation.ts";
import RushCardCurrentRatio from "@/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx";
import RushCardResultDescription from "@/features/RushGame/RushGameComponents/RushCardResultDescription.tsx";
import RushCountdown from "@/features/RushGame/RushGameComponents/RushCountdown.tsx";
+import RushShareLink from "@/features/RushGame/RushGameComponents/RushShareLink.tsx";
import useFetchRushBalance from "@/hooks/RushGame/useFetchRushBalance.ts";
import useToggleContents from "@/hooks/useToggleContents.ts";
import ArrowLeftIcon from "/public/assets/icons/arrow-line-left.svg?react";
@@ -65,16 +66,19 @@ export default function SelectedCard({ unblockNavigation }: SelectedCardProps) {
}, []);
return (
-
-
- {toggleContents ? (
-
- ) : (
-
- )}
-
+ <>
+
+
+ {toggleContents ? (
+
+ ) : (
+
+ )}
+
+
+ >
);
}
diff --git a/client/src/pages/RushGame/index.tsx b/client/src/pages/RushGame/index.tsx
index 1670d0d9..d3d8ac44 100644
--- a/client/src/pages/RushGame/index.tsx
+++ b/client/src/pages/RushGame/index.tsx
@@ -1,10 +1,7 @@
import { useEffect } from "react";
-import { motion } from "framer-motion";
import { useCookies } from "react-cookie";
import { useLoaderData } from "react-router-dom";
-import CTAButton from "@/components/CTAButton";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
-import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
import CardOptions from "@/features/RushGame/RushGameSections/CardOptions.tsx";
import Countdown from "@/features/RushGame/RushGameSections/Countdown.tsx";
@@ -15,9 +12,7 @@ import { useFetchRushUserParticipationStatus } from "@/hooks/RushGame/useFetchRu
import { useFetchTodayRushEvent } from "@/hooks/RushGame/useFetchTodayRushEvent.ts";
import useSetGamePhase from "@/hooks/RushGame/useSetGamePhase.ts";
import { useBlockNavigation } from "@/hooks/useBlockNavigation.ts";
-import useToast from "@/hooks/useToast.tsx";
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
-import { writeClipboard } from "@/utils/writeClipboard.ts";
export default function RushGame() {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
@@ -26,23 +21,19 @@ export default function RushGame() {
);
const { getTodayRushEvent } = useFetchTodayRushEvent();
const gameState = useRushGameStateContext();
- const { showToast, ToastComponent } = useToast("🔗 링크가 복사되었어요!");
const { getRushUserParticipationStatus, userParticipatedStatus } =
useFetchRushUserParticipationStatus();
const rushData = useLoaderData() as GetTotalRushEventsResponse;
useSetGamePhase(rushData);
- const handleClickShareButton = () => {
- writeClipboard(import.meta.env.VITE_RUSH_URL, showToast);
- };
-
useEffect(() => {
getTodayRushEvent(cookies[COOKIE_KEY.ACCESS_TOKEN]);
getRushUserParticipationStatus(cookies[COOKIE_KEY.ACCESS_TOKEN]);
}, []);
const renderRushGameContent = () => {
+ if (gameState.phase === null) return null;
switch (gameState.phase) {
case CARD_PHASE.NOT_STARTED:
return ;
@@ -65,17 +56,6 @@ export default function RushGame() {
return (
{renderRushGameContent()}
-
-
- 우리 편에 투표할 친구를 불러오세요!
-
-
-
-
- {ToastComponent}
);
}
diff --git a/client/src/types/rushGame.ts b/client/src/types/rushGame.ts
index 60f7711f..7ba18812 100644
--- a/client/src/types/rushGame.ts
+++ b/client/src/types/rushGame.ts
@@ -16,7 +16,7 @@ export interface CardOptionState {
}
export interface RushGameStateType {
- phase: GamePhase;
+ phase: GamePhase | null;
userParticipatedStatus: boolean;
userSelectedOption: CardOption;
cardOptions: {
From 5c02ed30a8afa29d49d89ec5ccba070e60aa079a Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 12:06:09 +0900
Subject: [PATCH 29/36] =?UTF-8?q?refactor:=20Countdown=20UX=20=EA=B0=9C?=
=?UTF-8?q?=EC=84=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGame/RushGameSections/Countdown.tsx | 73 +++++++++----------
1 file changed, 36 insertions(+), 37 deletions(-)
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index f44d35bf..05221c36 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -14,41 +14,9 @@ import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
-function CountdownTimer() {
- const [initialPreCountdown, setInitialPreCountdown] = useState(null);
+function CountdownTimer({ initialPreCountdown }: { initialPreCountdown: number | null }) {
const gameState = useRushGameStateContext();
const dispatch = useRushGameDispatchContext();
-
- const {
- data: rushData,
- isSuccess: isSuccessRush,
- fetchData: getRush,
- } = useFetch(() => RushAPI.getRush());
-
- useEffect(() => {
- getRush();
- }, []);
-
- useEffect(() => {
- if (isSuccessRush && rushData) {
- const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
-
- const currentEvent = rushData.events.find((event) => {
- const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
- return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
- });
-
- if (currentEvent) {
- const serverTime = getMsTime(rushData.serverTime);
- const startDateTime = getMsTime(currentEvent.startDateTime);
-
- setInitialPreCountdown(
- Math.max(0, Math.floor((startDateTime - serverTime) / 1000))
- );
- }
- }
- }, [isSuccessRush, rushData]);
-
const preCountdown = useCountdown(initialPreCountdown || null);
useEffect(() => {
@@ -61,9 +29,7 @@ function CountdownTimer() {
}
}, [preCountdown, gameState.phase]);
- if (initialPreCountdown === null || preCountdown === null) {
- return ;
- }
+ if (preCountdown === null) return null;
const hours = Math.floor(preCountdown / 3600);
const minutes = Math.floor((preCountdown % 3600) / 60);
@@ -95,12 +61,45 @@ function TimeDisplay({ label, value }: { label: string; value: string }) {
}
export default function Countdown() {
+ const [initialPreCountdown, setInitialPreCountdown] = useState(null);
+ const {
+ data: rushData,
+ isSuccess: isSuccessRush,
+ fetchData: getRush,
+ } = useFetch(() => RushAPI.getRush());
+
+ useEffect(() => {
+ getRush();
+ }, []);
+
+ useEffect(() => {
+ if (isSuccessRush && rushData) {
+ const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+
+ const currentEvent = rushData.events.find((event) => {
+ const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
+ });
+
+ if (currentEvent) {
+ const serverTime = getMsTime(rushData.serverTime);
+ const startDateTime = getMsTime(currentEvent.startDateTime);
+
+ setInitialPreCountdown(
+ Math.max(0, Math.floor((startDateTime - serverTime) / 1000))
+ );
+ }
+ }
+ }, [isSuccessRush, rushData]);
+
+ if (initialPreCountdown === null) return null;
+
return (
<>
이제 곧 하단에 밸런스 게임 주제가 공개돼요!
-
+
>
);
From bd01cee54a983cb8d790365c882f3e971ebb324c Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 12:07:53 +0900
Subject: [PATCH 30/36] =?UTF-8?q?refactor:=20CountdownTimer=20=EC=9D=B8?=
=?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EB=B6=84=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/features/RushGame/RushGameSections/Countdown.tsx | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 05221c36..fec51b7e 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -14,7 +14,11 @@ import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
-function CountdownTimer({ initialPreCountdown }: { initialPreCountdown: number | null }) {
+interface CountdownTimerProps {
+ initialPreCountdown: number | null;
+}
+
+function CountdownTimer({ initialPreCountdown }: CountdownTimerProps) {
const gameState = useRushGameStateContext();
const dispatch = useRushGameDispatchContext();
const preCountdown = useCountdown(initialPreCountdown || null);
From 48aa9af7c17fad9677019eb60d569fe4beeba72f Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 12:13:12 +0900
Subject: [PATCH 31/36] =?UTF-8?q?feat:=20=ED=86=A0=EA=B8=80=20=EB=B2=84?=
=?UTF-8?q?=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=8B=A4=EC=8B=9C?=
=?UTF-8?q?=EA=B0=84=20=EB=B9=84=EC=9C=A8=20=EB=B0=98=EC=98=81=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushGameComponents/RushCardResultDescription.tsx | 2 ++
.../features/RushGame/RushGameSections/SelectedCard.tsx | 9 +++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
index 153708da..8e3cc1e8 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardResultDescription.tsx
@@ -48,6 +48,8 @@ export default function RushCardResultDescription() {
option: gameState.userSelectedOption,
});
+ if (selectedOptionRatio === null) return null;
+
return (
diff --git a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
index 8a7543b7..161da784 100644
--- a/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
+++ b/client/src/features/RushGame/RushGameSections/SelectedCard.tsx
@@ -60,6 +60,11 @@ export default function SelectedCard({ unblockNavigation }: SelectedCardProps) {
const { toggleContents, toggle } = useToggleContents({ useDuration: false });
const fetchRushBalance = useFetchRushBalance();
+ const selectedCardToggle = () => {
+ toggle();
+ fetchRushBalance();
+ };
+
useEffect(() => {
fetchRushBalance();
unblockNavigation();
@@ -73,9 +78,9 @@ export default function SelectedCard({ unblockNavigation }: SelectedCardProps) {
>
{toggleContents ? (
-
+
) : (
-
+
)}
From 45985ff3b298cfa5d195d69d4d5acaec488ed2e7 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 14:46:06 +0900
Subject: [PATCH 32/36] =?UTF-8?q?refactor:=20=EB=82=A0=EC=A7=9C=EC=99=80?=
=?UTF-8?q?=20=EC=8B=9C=EA=B0=84=20=EB=B6=84=EB=A6=AC=ED=95=98=EB=8A=94=20?=
=?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=9C=A0=ED=8B=B8=EB=A1=9C=20=EB=B9=BC?=
=?UTF-8?q?=EA=B8=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../features/RushGame/RushGameComponents/RushCountdown.tsx | 5 +++--
client/src/utils/parseIsoDateTime.ts | 3 +++
2 files changed, 6 insertions(+), 2 deletions(-)
create mode 100644 client/src/utils/parseIsoDateTime.ts
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index 95917b2c..224dd2a6 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -9,6 +9,7 @@ import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
+import parseIsoDateTime from "@/utils/parseIsoDateTime.ts";
function TimeDisplay({ label, value }: { label: string; value: string }) {
return (
@@ -36,10 +37,10 @@ export default function RushCountdown() {
useEffect(() => {
if (isSuccessRush && rushData) {
- const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+ const serverDate = parseIsoDateTime(rushData.serverTime);
const currentEvent = rushData.events.find((event) => {
- const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ const eventDate = parseIsoDateTime(event.startDateTime);
return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
});
diff --git a/client/src/utils/parseIsoDateTime.ts b/client/src/utils/parseIsoDateTime.ts
new file mode 100644
index 00000000..537f7d87
--- /dev/null
+++ b/client/src/utils/parseIsoDateTime.ts
@@ -0,0 +1,3 @@
+export default function parseIsoDateTime(dateTime: string) {
+ return new Date(dateTime).toISOString().split("T")[0];
+}
From e1dc865bbd33c830aacbf44ff0f9bcfd8de805f0 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 14:47:36 +0900
Subject: [PATCH 33/36] =?UTF-8?q?refactor:=20parseIsoDateTime=20=EC=A0=81?=
=?UTF-8?q?=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/features/RushGame/RushGameSections/Countdown.tsx | 5 +++--
client/src/hooks/RushGame/useSetGamePhase.ts | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index fec51b7e..0e942e45 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -13,6 +13,7 @@ import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
import { formatTime } from "@/utils/formatTime.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
+import parseIsoDateTime from "@/utils/parseIsoDateTime.ts";
interface CountdownTimerProps {
initialPreCountdown: number | null;
@@ -78,10 +79,10 @@ export default function Countdown() {
useEffect(() => {
if (isSuccessRush && rushData) {
- const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+ const serverDate = parseIsoDateTime(rushData.serverTime);
const currentEvent = rushData.events.find((event) => {
- const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ const eventDate = parseIsoDateTime(event.startDateTime);
return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
});
diff --git a/client/src/hooks/RushGame/useSetGamePhase.ts b/client/src/hooks/RushGame/useSetGamePhase.ts
index 1017115b..92ddd633 100644
--- a/client/src/hooks/RushGame/useSetGamePhase.ts
+++ b/client/src/hooks/RushGame/useSetGamePhase.ts
@@ -4,16 +4,17 @@ import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchCont
import { GetTotalRushEventsResponse } from "@/types/rushApi.ts";
import { RUSH_ACTION } from "@/types/rushGame.ts";
import { getMsTime } from "@/utils/getMsTime.ts";
+import parseIsoDateTime from "@/utils/parseIsoDateTime.ts";
export default function useSetGamePhase(rushData: GetTotalRushEventsResponse) {
const dispatch = useRushGameDispatchContext();
useEffect(() => {
if (rushData) {
- const serverDate = new Date(rushData.serverTime).toISOString().split("T")[0];
+ const serverDate = parseIsoDateTime(rushData.serverTime);
const currentEvent = rushData.events.find((event) => {
- const eventDate = new Date(event.startDateTime).toISOString().split("T")[0];
+ const eventDate = parseIsoDateTime(event.startDateTime);
return eventDate === serverDate && event.rushEventId === rushData.todayEventId;
});
From 0a8f50956e9d29465ed0144d23da8e15a72a9391 Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 14:50:29 +0900
Subject: [PATCH 34/36] =?UTF-8?q?refactor:=20timeout=20if=20=EC=A1=B0?=
=?UTF-8?q?=EA=B1=B4=EB=AC=B8=20=EC=83=81=EC=88=98=EB=A1=9C=20=EB=B6=84?=
=?UTF-8?q?=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../features/RushGame/RushGameComponents/RushCountdown.tsx | 6 +++---
client/src/features/RushGame/RushGameSections/Countdown.tsx | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index 224dd2a6..b5f63d3c 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -56,11 +56,11 @@ export default function RushCountdown() {
const runCountdown = useCountdown(initialRunCountdown || null);
useEffect(() => {
- if (
+ const isTimeout =
runCountdown !== null &&
runCountdown <= 0 &&
- gameState.phase === CARD_PHASE.IN_PROGRESS
- ) {
+ gameState.phase === CARD_PHASE.IN_PROGRESS;
+ if (isTimeout) {
dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.COMPLETED });
}
}, [runCountdown, gameState.phase]);
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 0e942e45..92e16933 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -25,11 +25,11 @@ function CountdownTimer({ initialPreCountdown }: CountdownTimerProps) {
const preCountdown = useCountdown(initialPreCountdown || null);
useEffect(() => {
- if (
+ const isTimeout =
preCountdown !== null &&
preCountdown <= 0 &&
- gameState.phase === CARD_PHASE.NOT_STARTED
- ) {
+ gameState.phase === CARD_PHASE.NOT_STARTED;
+ if (isTimeout) {
dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.IN_PROGRESS });
}
}, [preCountdown, gameState.phase]);
From 895057fcde96d7af063190db46b3b0890a5a3dff Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 15:39:45 +0900
Subject: [PATCH 35/36] =?UTF-8?q?refactor:=20Suspense=20=EC=B6=94=EA=B0=80?=
=?UTF-8?q?=20=EB=B0=8F=20=EA=B4=80=EB=A0=A8=20=EC=BB=B4=ED=8F=AC=EB=84=8C?=
=?UTF-8?q?=ED=8A=B8=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/components/Suspense/index.tsx | 9 ++++
.../RushGameComponents/RushCountdown.tsx | 28 ++++++-------
.../RushGame/RushGameSections/Countdown.tsx | 42 +++++++++----------
.../RushGame/RushGameSections/FinalResult.tsx | 22 ++++++----
4 files changed, 59 insertions(+), 42 deletions(-)
create mode 100644 client/src/components/Suspense/index.tsx
diff --git a/client/src/components/Suspense/index.tsx b/client/src/components/Suspense/index.tsx
new file mode 100644
index 00000000..865309f9
--- /dev/null
+++ b/client/src/components/Suspense/index.tsx
@@ -0,0 +1,9 @@
+import { PropsWithChildren } from "react";
+
+interface SuspenseProps extends PropsWithChildren {
+ isLoading?: boolean;
+}
+
+export default function Suspense({ children, isLoading = false }: SuspenseProps) {
+ return <>{isLoading ? <>> : children}>;
+}
diff --git a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
index b5f63d3c..a3c30f22 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCountdown.tsx
@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { RushAPI } from "@/apis/rushAPI.ts";
+import Suspense from "@/components/Suspense";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import useRushGameDispatchContext from "@/hooks/Contexts/useRushGameDispatchContext.ts";
import useRushGameStateContext from "@/hooks/Contexts/useRushGameStateContext.ts";
@@ -60,28 +61,27 @@ export default function RushCountdown() {
runCountdown !== null &&
runCountdown <= 0 &&
gameState.phase === CARD_PHASE.IN_PROGRESS;
+
if (isTimeout) {
dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.COMPLETED });
}
}, [runCountdown, gameState.phase]);
- if (initialRunCountdown === null || runCountdown === null) {
- return ;
- }
-
- const minutes = Math.floor((runCountdown % 3600) / 60);
- const seconds = runCountdown % 60;
+ const minutes = Math.floor(((runCountdown ?? 0) % 3600) / 60);
+ const seconds = (runCountdown ?? 0) % 60;
return (
-
- 밸런스 게임 결과 공개까지 남은 시간
-
-
+
+
+ 밸런스 게임 결과 공개까지 남은 시간
+
+
+
);
}
diff --git a/client/src/features/RushGame/RushGameSections/Countdown.tsx b/client/src/features/RushGame/RushGameSections/Countdown.tsx
index 92e16933..e0d7c7f3 100644
--- a/client/src/features/RushGame/RushGameSections/Countdown.tsx
+++ b/client/src/features/RushGame/RushGameSections/Countdown.tsx
@@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
import { motion } from "framer-motion";
import { RushAPI } from "@/apis/rushAPI.ts";
import { Background } from "@/components/Background";
+import Suspense from "@/components/Suspense";
import { CARD_PHASE } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import RushShareLink from "@/features/RushGame/RushGameComponents/RushShareLink.tsx";
@@ -29,30 +30,31 @@ function CountdownTimer({ initialPreCountdown }: CountdownTimerProps) {
preCountdown !== null &&
preCountdown <= 0 &&
gameState.phase === CARD_PHASE.NOT_STARTED;
+
if (isTimeout) {
dispatch({ type: RUSH_ACTION.SET_PHASE, payload: CARD_PHASE.IN_PROGRESS });
}
}, [preCountdown, gameState.phase]);
- if (preCountdown === null) return null;
-
- const hours = Math.floor(preCountdown / 3600);
- const minutes = Math.floor((preCountdown % 3600) / 60);
- const seconds = preCountdown % 60;
+ const hours = Math.floor((preCountdown ?? 0) / 3600);
+ const minutes = Math.floor(((preCountdown ?? 0) % 3600) / 60);
+ const seconds = (preCountdown ?? 0) % 60;
return (
-
-
- 밸런스 게임 주제 공개까지 남은 시간
-
-
-
+
+
+
+ 밸런스 게임 주제 공개까지 남은 시간
+
+
+
+
);
}
@@ -97,15 +99,13 @@ export default function Countdown() {
}
}, [isSuccessRush, rushData]);
- if (initialPreCountdown === null) return null;
-
return (
- <>
+
이제 곧 하단에 밸런스 게임 주제가 공개돼요!
- >
+
);
}
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index 23e32e59..eefc8e05 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -1,6 +1,7 @@
import { useEffect } from "react";
import { motion } from "framer-motion";
import { useCookies } from "react-cookie";
+import Suspense from "@/components/Suspense";
import { CARD_OPTION, WIN_STATUS } from "@/constants/Rush/rushCard.ts";
import { ASCEND, SCROLL_MOTION } from "@/constants/animation.ts";
import { COOKIE_KEY } from "@/constants/cookie.ts";
@@ -66,12 +67,19 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const leftWinStatus = getWinStatus(leftOptionRatio, rightOptionRatio);
const rightWinStatus = getWinStatus(rightOptionRatio, leftOptionRatio);
- const isValidData =
- isWinner !== undefined && rank !== undefined && totalParticipants !== undefined;
- if (!isValidData) return null;
+ function formatNumber(value?: number): string {
+ if (value === undefined) return "";
+ return value.toLocaleString("en-US");
+ }
+
+ const formattedRank = formatNumber(rank);
+ const formattedTotalParticipants = formatNumber(totalParticipants);
+
+ const isNotValidData =
+ isWinner === undefined || rank === undefined || totalParticipants === undefined;
return (
- <>
+
나의 선착순 등수
- {rank}등
+ {formattedRank}등
- / {totalParticipants.toLocaleString("en-US")}명 중
+ / {formattedTotalParticipants}명 중
@@ -121,6 +129,6 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
- >
+
);
}
From a4b635843bd61d6cde6846a905e1ada62d42378b Mon Sep 17 00:00:00 2001
From: sooyeoniya
Date: Thu, 22 Aug 2024 15:51:16 +0900
Subject: [PATCH 36/36] =?UTF-8?q?refactor:=20getOptionRatio,=20getSelected?=
=?UTF-8?q?CardInfo=20props=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../RushCardCurrentRatio.tsx | 16 +++++++--------
.../RushCardResultDescription.tsx | 14 ++++++-------
.../RushGame/RushGameSections/FinalResult.tsx | 20 +++++++------------
client/src/utils/RushGame/getOptionRatio.ts | 14 +++++++------
.../src/utils/RushGame/getSelectedCardInfo.ts | 10 ++++++----
5 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
index 667115f9..d6d8dd83 100644
--- a/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
+++ b/client/src/features/RushGame/RushGameComponents/RushCardCurrentRatio.tsx
@@ -54,27 +54,27 @@ function getMessage(leftRatio: number, rightRatio: number, userSelectedOption: C
}
export default function RushCardCurrentRatio() {
- const gameState = useRushGameStateContext();
+ const { userSelectedOption, cardOptions } = useRushGameStateContext();
const { toggleContents } = useToggleContents();
const fetchRushBalance = useFetchRushBalance();
const leftOptionRatio = getOptionRatio({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.LEFT_OPTIONS,
});
const rightOptionRatio = getOptionRatio({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.RIGHT_OPTIONS,
});
- const message = getMessage(leftOptionRatio, rightOptionRatio, gameState.userSelectedOption);
+ const message = getMessage(leftOptionRatio, rightOptionRatio, userSelectedOption);
const { mainText: leftMainText } = getSelectedCardInfo({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.LEFT_OPTIONS,
});
const { mainText: rightMainText } = getSelectedCardInfo({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.RIGHT_OPTIONS,
});
@@ -90,13 +90,13 @@ export default function RushCardCurrentRatio() {
mainText={leftMainText}
userSelectedOptionRatio={leftOptionRatio}
oppositeOptionRatio={rightOptionRatio}
- isUserSelected={gameState.userSelectedOption === CARD_OPTION.LEFT_OPTIONS}
+ isUserSelected={userSelectedOption === CARD_OPTION.LEFT_OPTIONS}
/>
{
getUserResultData({
token: cookies[COOKIE_KEY.ACCESS_TOKEN],
- optionId: gameState.userSelectedOption,
+ optionId: userSelectedOption,
});
- }, [cookies, gameState.userSelectedOption]);
+ }, [cookies, userSelectedOption]);
const { mainText, resultMainText, resultSubText, color } = getSelectedCardInfo({
- gameState: gameState,
- option: gameState.userSelectedOption,
+ cardOptions: cardOptions,
+ option: userSelectedOption,
});
const selectedOptionRatio = getOptionRatio({
- gameState: gameState,
- option: gameState.userSelectedOption,
+ cardOptions: cardOptions,
+ option: userSelectedOption,
});
if (selectedOptionRatio === null) return null;
diff --git a/client/src/features/RushGame/RushGameSections/FinalResult.tsx b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
index eefc8e05..82e52117 100644
--- a/client/src/features/RushGame/RushGameSections/FinalResult.tsx
+++ b/client/src/features/RushGame/RushGameSections/FinalResult.tsx
@@ -30,7 +30,7 @@ interface FinalResultProps {
export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const [cookies] = useCookies([COOKIE_KEY.ACCESS_TOKEN]);
- const gameState = useRushGameStateContext();
+ const { cardOptions, userParticipatedStatus, userSelectedOption } = useRushGameStateContext();
const { getRushResult, resultData } = useFetchRushResult();
useEffect(() => {
@@ -38,8 +38,6 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
unblockNavigation();
}, []);
- const userParticipatedStatus = gameState.userParticipatedStatus;
-
const isWinner = resultData?.isWinner;
const rank = resultData?.rank;
const totalParticipants = resultData?.totalParticipants;
@@ -47,20 +45,20 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
const message = isWinner ? MESSAGES.WINNING : MESSAGES.LOSING;
const { mainText: leftMainText } = getSelectedCardInfo({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.LEFT_OPTIONS,
});
const { mainText: rightMainText } = getSelectedCardInfo({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.RIGHT_OPTIONS,
});
const leftOptionRatio = getOptionRatio({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.LEFT_OPTIONS,
});
const rightOptionRatio = getOptionRatio({
- gameState: gameState,
+ cardOptions: cardOptions,
option: CARD_OPTION.RIGHT_OPTIONS,
});
@@ -107,17 +105,13 @@ export default function FinalResult({ unblockNavigation }: FinalResultProps) {
diff --git a/client/src/utils/RushGame/getOptionRatio.ts b/client/src/utils/RushGame/getOptionRatio.ts
index f26176d1..f57c6c01 100644
--- a/client/src/utils/RushGame/getOptionRatio.ts
+++ b/client/src/utils/RushGame/getOptionRatio.ts
@@ -1,16 +1,18 @@
import { CARD_OPTION } from "@/constants/Rush/rushCard.ts";
-import { CardOption, RushGameStateType } from "@/types/rushGame.ts";
+import { CardOption, CardOptionState } from "@/types/rushGame.ts";
interface GetOptionRatioProps {
- gameState: RushGameStateType;
+ cardOptions: {
+ [key in CardOption]: CardOptionState;
+ };
option: CardOption;
}
-export const getOptionRatio = ({ gameState, option }: GetOptionRatioProps) => {
+export const getOptionRatio = ({ cardOptions, option }: GetOptionRatioProps) => {
const total =
- gameState.cardOptions[CARD_OPTION.LEFT_OPTIONS].selectionCount +
- gameState.cardOptions[CARD_OPTION.RIGHT_OPTIONS].selectionCount;
+ cardOptions[CARD_OPTION.LEFT_OPTIONS].selectionCount +
+ cardOptions[CARD_OPTION.RIGHT_OPTIONS].selectionCount;
if (total === 0) return 0;
- const ratio = (gameState.cardOptions[option].selectionCount / total) * 100;
+ const ratio = (cardOptions[option].selectionCount / total) * 100;
return Math.round(ratio * 100) / 100;
};
diff --git a/client/src/utils/RushGame/getSelectedCardInfo.ts b/client/src/utils/RushGame/getSelectedCardInfo.ts
index 59402f04..3e431951 100644
--- a/client/src/utils/RushGame/getSelectedCardInfo.ts
+++ b/client/src/utils/RushGame/getSelectedCardInfo.ts
@@ -1,12 +1,14 @@
-import { CardOption, RushGameStateType } from "@/types/rushGame.ts";
+import { CardOption, CardOptionState } from "@/types/rushGame.ts";
interface GetSelectedCardInfoProps {
- gameState: RushGameStateType;
+ cardOptions: {
+ [key in CardOption]: CardOptionState;
+ };
option: CardOption;
}
-export const getSelectedCardInfo = ({ gameState, option }: GetSelectedCardInfoProps) => {
- const cardInfo = gameState.cardOptions[option];
+export const getSelectedCardInfo = ({ cardOptions, option }: GetSelectedCardInfoProps) => {
+ const cardInfo = cardOptions[option];
return {
mainText: cardInfo.mainText,
subText: cardInfo.subText,