diff --git a/src/components/GoToDebateEndButton/GoToDebateEndButton.tsx b/src/components/GoToDebateEndButton/GoToDebateEndButton.tsx
new file mode 100644
index 00000000..a94bbc4f
--- /dev/null
+++ b/src/components/GoToDebateEndButton/GoToDebateEndButton.tsx
@@ -0,0 +1,31 @@
+import clsx from 'clsx';
+import { useNavigate } from 'react-router-dom';
+
+interface GoToDebateEndButtonProps {
+ tableId: number;
+ className?: string;
+}
+
+export default function GoToDebateEndButton({
+ tableId,
+ className = '',
+}: GoToDebateEndButtonProps) {
+ const navigate = useNavigate();
+ const handleClick = (tableId: number) => {
+ navigate(`/table/customize/${tableId}/end`);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/GoToHomeButton/GoToHomeButton.tsx b/src/components/GoToHomeButton/GoToHomeButton.tsx
deleted file mode 100644
index 5d80226b..00000000
--- a/src/components/GoToHomeButton/GoToHomeButton.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { useNavigate } from 'react-router-dom';
-
-export default function GoToHomeButton() {
- const navigate = useNavigate();
-
- const handleClick = () => {
- navigate('/');
- };
-
- return (
-
- );
-}
diff --git a/src/page/DebateEndPage/DebateEndPage.tsx b/src/page/DebateEndPage/DebateEndPage.tsx
index bb535cf2..c695f400 100644
--- a/src/page/DebateEndPage/DebateEndPage.tsx
+++ b/src/page/DebateEndPage/DebateEndPage.tsx
@@ -3,27 +3,33 @@ import { useNavigate, useParams } from 'react-router-dom';
import clapImage from '../../assets/debateEnd/clap.png';
import feedbackTimerImage from '../../assets/debateEnd/feedback_timer.png';
import voteStampImage from '../../assets/debateEnd/vote_stamp.png';
-import GoToHomeButton from '../../components/GoToHomeButton/GoToHomeButton';
import usePostPoll from '../../hooks/mutations/useCreatePoll';
import MenuCard from './components/MenuCard';
+import GoToOverviewButton from './components/GoToOverviewButton';
export default function DebateEndPage() {
- const { id: tableId } = useParams();
+ const { id } = useParams();
+ const tableId = Number(id);
const navigate = useNavigate();
const handleFeedbackClick = () => {
navigate(`/table/customize/${tableId}/end/feedback`);
};
-
const handleVoteClick = (pollId: number) => {
- navigate(`/table/customize/${pollId}/end/vote`);
+ navigate(`/table/customize/${tableId}/end/vote/${pollId}`);
};
const { mutate } = usePostPoll(handleVoteClick);
+
const backgroundStyle = {
background:
'radial-gradient(50% 50% at 50% 50%, #fecd4c21 0%, #ffffff42 100%)',
};
+ // 테이블 ID 검증
+ if (!id || isNaN(tableId)) {
+ throw new Error('테이블 ID가 올바르지 않습니다.');
+ }
+
return (
{
- if (!tableId) return; // NaN 방지
- mutate(Number(tableId));
- }}
+ onClick={() => mutate(tableId)}
ariaLabel="승패투표 생성 및 진행"
/>
-
+
);
diff --git a/src/page/DebateEndPage/components/GoToOverviewButton.tsx b/src/page/DebateEndPage/components/GoToOverviewButton.tsx
new file mode 100644
index 00000000..6300edf7
--- /dev/null
+++ b/src/page/DebateEndPage/components/GoToOverviewButton.tsx
@@ -0,0 +1,33 @@
+import clsx from 'clsx';
+import { RiCalendarScheduleLine } from 'react-icons/ri';
+import { useNavigate } from 'react-router-dom';
+
+interface GoToOverviewButtonProps {
+ tableId: number;
+ className?: string;
+}
+
+export default function GoToOverviewButton({
+ tableId,
+ className = '',
+}: GoToOverviewButtonProps) {
+ const navigate = useNavigate();
+ const handleClick = (tableId: number) => {
+ navigate(`/overview/customize/${tableId}`);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/page/DebateVotePage/DebateVotePage.tsx b/src/page/DebateVotePage/DebateVotePage.tsx
index dd08bcb1..70061bdc 100644
--- a/src/page/DebateVotePage/DebateVotePage.tsx
+++ b/src/page/DebateVotePage/DebateVotePage.tsx
@@ -5,26 +5,30 @@ import DefaultLayout from '../../layout/defaultLayout/DefaultLayout';
import { useGetPollInfo } from '../../hooks/query/useGetPollInfo';
import ErrorIndicator from '../../components/ErrorIndicator/ErrorIndicator';
import useFetchEndPoll from '../../hooks/mutations/useFetchEndPoll';
+import GoToDebateEndButton from '../../components/GoToDebateEndButton/GoToDebateEndButton';
export default function DebateVotePage() {
- const { id: pollIdParam } = useParams();
- const pollId = pollIdParam ? Number(pollIdParam) : NaN;
- const isValidPollId = !!pollIdParam && !Number.isNaN(pollId);
const navigate = useNavigate();
const baseUrl =
import.meta.env.MODE !== 'production'
? undefined
: import.meta.env.VITE_SHARE_BASE_URL;
+
+ // 매개변수 검증
+ const { pollId: rawPollId, tableId: rawTableId } = useParams();
+ const pollId = rawPollId ? Number(rawPollId) : NaN;
+ const isPollIdValid = !!rawPollId && !Number.isNaN(pollId);
+ const tableId = rawTableId ? Number(rawTableId) : NaN;
+ const isTableIdValid = !!rawTableId && !Number.isNaN(tableId);
+ const isArgsValid = isPollIdValid && isTableIdValid;
+
const voteUrl = useMemo(() => {
return `${baseUrl}/vote/${pollId}`;
}, [baseUrl, pollId]);
const handleGoToResult = () => {
- navigate(`/table/customize/${pollId}/end/vote/result`);
+ navigate(`/table/customize/${tableId}/end/vote/${pollId}/result`);
};
- const handleGoHome = () => {
- navigate('/');
- };
const {
data,
isLoading: isFetching,
@@ -32,7 +36,7 @@ export default function DebateVotePage() {
isRefetching,
refetch,
isRefetchError,
- } = useGetPollInfo(pollId, { refetchInterval: 5000, enabled: isValidPollId });
+ } = useGetPollInfo(pollId, { refetchInterval: 5000, enabled: isArgsValid });
const { mutate } = useFetchEndPoll(handleGoToResult);
const participants = data?.voterNames;
@@ -48,7 +52,8 @@ export default function DebateVotePage() {
);
}
- if (!isValidPollId) {
+
+ if (!isArgsValid) {
return (
@@ -59,6 +64,7 @@ export default function DebateVotePage() {
);
}
+
return (
@@ -108,21 +114,15 @@ export default function DebateVotePage() {
-
+
+
-
diff --git a/src/page/DebateVoteResultPage/DebateVoteResultPage.tsx b/src/page/DebateVoteResultPage/DebateVoteResultPage.tsx
index 69c19682..4c6cac66 100644
--- a/src/page/DebateVoteResultPage/DebateVoteResultPage.tsx
+++ b/src/page/DebateVoteResultPage/DebateVoteResultPage.tsx
@@ -7,11 +7,18 @@ import VoteDetailResult from './components/VoteDetailResult';
import { useGetPollInfo } from '../../hooks/query/useGetPollInfo';
import ErrorIndicator from '../../components/ErrorIndicator/ErrorIndicator';
import { TeamKey } from '../../type/type';
+import { useState } from 'react';
+import DialogModal from '../../components/DialogModal/DialogModal';
export default function DebateVoteResultPage() {
- const { id: pollIdParam } = useParams();
+ // 매개변수 검증
+ const { pollId: rawPollId, tableId: rawTableId } = useParams();
+ const pollId = rawPollId ? Number(rawPollId) : NaN;
+ const isPollIdValid = !!rawPollId && !Number.isNaN(pollId);
+ const tableId = rawTableId ? Number(rawTableId) : NaN;
+ const isTableIdValid = !!rawTableId && !Number.isNaN(tableId);
+ const isArgsValid = isPollIdValid && isTableIdValid;
- const pollId = pollIdParam ? Number(pollIdParam) : NaN;
- const isValidPollId = !!pollIdParam && !Number.isNaN(pollId);
+ const [isConfirmed, setIsConfirmed] = useState(false);
const navigate = useNavigate();
const {
@@ -21,13 +28,15 @@ export default function DebateVoteResultPage() {
isRefetching,
refetch,
isRefetchError,
- } = useGetPollInfo(pollId, { enabled: isValidPollId });
+ } = useGetPollInfo(pollId, { enabled: isArgsValid });
const handleGoHome = () => {
navigate('/');
};
const isLoading = isFetching || isRefetching;
const isError = isFetchError || isRefetchError;
- const { openModal, ModalWrapper } = useModal();
+ const { openModal, ModalWrapper, closeModal } = useModal({
+ onClose: () => setIsConfirmed(false),
+ });
const getWinner = (result: {
prosTeamName: string;
@@ -55,7 +64,7 @@ export default function DebateVoteResultPage() {
}
};
- if (!isValidPollId) {
+ if (!isArgsValid) {
return (
@@ -96,38 +105,57 @@ export default function DebateVoteResultPage() {
-
+
-
+ {isConfirmed ? (
+
+ ) : (
+ closeModal(),
+ }}
+ right={{
+ text: '네',
+ onClick: () => setIsConfirmed(true),
+ isBold: true,
+ }}
+ >
+
+ 정말로 세부 결과를 공개할까요?
+
+
+ )}
);
diff --git a/src/page/DebateVoteResultPage/components/VoteDetailResult.tsx b/src/page/DebateVoteResultPage/components/VoteDetailResult.tsx
index 64eae086..e22a2bcf 100644
--- a/src/page/DebateVoteResultPage/components/VoteDetailResult.tsx
+++ b/src/page/DebateVoteResultPage/components/VoteDetailResult.tsx
@@ -44,14 +44,14 @@ export default function VoteDetailResult({
{/* 하단 CTA 바 */}
-
+
);
diff --git a/src/page/TimerPage/FeedbackTimerPage.tsx b/src/page/TimerPage/FeedbackTimerPage.tsx
index 1bf02ccd..d1f488cd 100644
--- a/src/page/TimerPage/FeedbackTimerPage.tsx
+++ b/src/page/TimerPage/FeedbackTimerPage.tsx
@@ -1,10 +1,18 @@
import { useFeedbackTimer } from './hooks/useFeedbackTimer';
import FeedbackTimer from './components/FeedbackTimer';
import DefaultLayout from '../../layout/defaultLayout/DefaultLayout';
-import GoToHomeButton from '../../components/GoToHomeButton/GoToHomeButton';
+import GoToDebateEndButton from '../../components/GoToDebateEndButton/GoToDebateEndButton';
+import { useParams } from 'react-router-dom';
export default function FeedbackTimerPage() {
const feedbackTimerInstance = useFeedbackTimer();
+ const { id } = useParams();
+ const tableId = Number(id);
+
+ // 테이블 ID 검증 로직
+ if (!id || isNaN(tableId)) {
+ throw new Error('테이블 ID가 올바르지 않습니다.');
+ }
return (
@@ -13,7 +21,7 @@ export default function FeedbackTimerPage() {
-
+
diff --git a/src/routes/routes.tsx b/src/routes/routes.tsx
index 9bf5a5d5..6310ae14 100644
--- a/src/routes/routes.tsx
+++ b/src/routes/routes.tsx
@@ -55,12 +55,12 @@ const routesConfig = [
requiresAuth: true,
},
{
- path: '/table/customize/:id/end/vote',
+ path: '/table/customize/:tableId/end/vote/:pollId',
element: ,
requiresAuth: true,
},
{
- path: '/table/customize/:id/end/vote/result',
+ path: '/table/customize/:tableId/end/vote/:pollId/result',
element: ,
requiresAuth: true,
},