diff --git a/packages/client/src/app/routes/Router.tsx b/packages/client/src/app/routes/Router.tsx index 4e0c3379..7af549b3 100644 --- a/packages/client/src/app/routes/Router.tsx +++ b/packages/client/src/app/routes/Router.tsx @@ -13,6 +13,7 @@ import QnA from '@/pages/qna'; import GuestQnA from '@/pages/guest-qna'; import QuizList from '@/pages/quiz-list'; import QuizMasterSession from '@/pages/quiz-master-session'; +import Leaderboard from '@/pages/leaderboard'; export default function Router() { return ( @@ -31,6 +32,7 @@ export default function Router() { } /> } /> + } /> } /> ); diff --git a/packages/client/src/pages/leaderboard/index.tsx b/packages/client/src/pages/leaderboard/index.tsx new file mode 100644 index 00000000..674e7c31 --- /dev/null +++ b/packages/client/src/pages/leaderboard/index.tsx @@ -0,0 +1,3 @@ +export default function Leaderboard() { + return
Leaderboard
; +} diff --git a/packages/client/src/pages/quiz-master-session/index.tsx b/packages/client/src/pages/quiz-master-session/index.tsx index 9c09c976..7a80b627 100644 --- a/packages/client/src/pages/quiz-master-session/index.tsx +++ b/packages/client/src/pages/quiz-master-session/index.tsx @@ -1,5 +1,7 @@ -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; + +import { getCookie } from '@/shared/utils/cookie'; import { CustomButton } from '@/shared/ui/buttons'; import AnswerGraph from '@/pages/quiz-master-session/ui/AnswerChart'; import RecentSubmittedAnswers from './ui/RecentSubmittedAnswers'; @@ -19,12 +21,14 @@ import { export default function QuizMasterSession() { const { pinCode } = useParams(); + const navigate = useNavigate(); const socket = getQuizSocket(); const [masterStatistics, setMasterStatistics] = useState(INITIAL_MASTER_STATISTICS); const [quizData, setQuizData] = useState(INITIAL_QUIZ_DATA); const [tick, setTick] = useState(INITIAL_TICK); const [quizIndex, setQuizIndex] = useState(0); + const [isLastQuiz, setIsLastQuiz] = useState(false); const initQuizData = () => { setQuizData(INITIAL_QUIZ_DATA); @@ -33,6 +37,11 @@ export default function QuizMasterSession() { }; const handleNextQuiz = () => { + if (isLastQuiz) { + socket.emit('end quiz', { pinCode, sid: getCookie('sid') }); + navigate('/quiz/session/end'); + return; + } initQuizData(); setQuizIndex((prev) => prev + 1); socket.emit('show quiz', { pinCode }); @@ -42,8 +51,9 @@ export default function QuizMasterSession() { socket.emit('show quiz', { pinCode }); const handleShowQuiz = (response: ShowQuizResponse) => { - const { currentQuizData } = response; + const { currentQuizData, isLast } = response; setQuizData(currentQuizData); + setIsLastQuiz(isLast); }; const handleMasterStatistics = (response: MasterStatisticsResponse) => { setMasterStatistics(response); diff --git a/packages/client/src/pages/quiz-session/index.tsx b/packages/client/src/pages/quiz-session/index.tsx index d990167f..c66f8b4f 100644 --- a/packages/client/src/pages/quiz-session/index.tsx +++ b/packages/client/src/pages/quiz-session/index.tsx @@ -1,18 +1,20 @@ import { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; import { getQuizSocket } from '@/shared/utils/socket'; import QuizBox from './ui/QuizBox'; import QuizEnd from './ui/QuizEnd'; import QuizHeader from './ui/QuizHeader'; import QuizLoading from './ui/QuizLoading'; -import { toastController } from '@/features/toast/model/toastController'; +// import { toastController } from '@/features/toast/model/toastController'; import { QuizData } from '@youquiz/shared/interfaces/utils/quizdata.interface'; import { ShowQuizResponse, TimerTickResponse } from '@youquiz/shared/interfaces/response'; import { INITIAL_QUIZ_DATA, INITIAL_TICK } from '@/shared/constants/initialState'; export default function QuizSession() { const socket = getQuizSocket(); - const toast = toastController(); + // const toast = toastController(); + const navigate = useNavigate(); const [isLoading, setIsLoading] = useState(true); const [isQuizEnd, setIsQuizEnd] = useState(false); const [tick, setTick] = useState(INITIAL_TICK); @@ -52,7 +54,7 @@ export default function QuizSession() { setIsLoading(false); }) .catch(() => { - toast.error('문제 로딩에 실패했습니다.'); + // toast.error('문제 로딩에 실패했습니다.'); setIsLoading(false); }); @@ -64,6 +66,11 @@ export default function QuizSession() { setIsQuizEnd(true); }; + const handleQuizEnd = () => { + navigate('/quiz/session/end'); + }; + + socket.on('end quiz', handleQuizEnd); socket.on('timer tick', handleTick); socket.on('time end', handleTimeEnd); diff --git a/packages/client/src/pages/quiz-session/ui/AfterQuizSubmit.tsx b/packages/client/src/pages/quiz-session/ui/AfterQuizSubmit.tsx index 8c6753bc..671a7a96 100644 --- a/packages/client/src/pages/quiz-session/ui/AfterQuizSubmit.tsx +++ b/packages/client/src/pages/quiz-session/ui/AfterQuizSubmit.tsx @@ -2,16 +2,20 @@ import StatisticsGroup from '@/pages/quiz-master-session/ui/StatisticsGroup'; import { ParticipantStatisticsResponse } from '@youquiz/shared/interfaces/response'; interface AfterQuizSubmitProps { participantStatistics: ParticipantStatisticsResponse; + submitOrder: number; } -export default function AfterQuizSubmit({ participantStatistics }: AfterQuizSubmitProps) { +export default function AfterQuizSubmit({ + participantStatistics, + submitOrder, +}: AfterQuizSubmitProps) { return (
-
- 나는 몇 등이지? - +
+ 나는 몇 번째로 제출했을까? + {submitOrder}번째로 제출했습니다!
diff --git a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx index 11b71de2..a181ee38 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx @@ -23,6 +23,8 @@ export default function QuizBox({ quiz, tick }: QuizBoxProps) { const [participantStatistics, setParticipantStatistics] = useState( INITIAL_PARTICIPANT_STATISTICS, ); + const [submitOrder, setSubmitOrder] = useState(0); + const easyButtonRef = useRef(null); const hardButtonRef = useRef(null); const socket = getQuizSocket(); @@ -40,12 +42,18 @@ export default function QuizBox({ quiz, tick }: QuizBoxProps) { }; const handleSubmit = () => { - socket.emit('submit answer', { - selectedAnswer: selectedAnswer, - sid: getCookie('sid'), - pinCode: pinCode, - submitTime: tick.elapsedTime, - }); + socket.emit( + 'submit answer', + { + selectedAnswer: selectedAnswer, + sid: getCookie('sid'), + pinCode: pinCode, + submitTime: tick.elapsedTime, + }, + (response: any) => { + setSubmitOrder(response.submitOrder); + }, + ); setHasSubmitted(true); }; @@ -166,7 +174,9 @@ export default function QuizBox({ quiz, tick }: QuizBoxProps) {
- {hasSubmitted && } + {hasSubmitted && ( + + )} ); } diff --git a/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx b/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx index 9c4dee5c..bea67635 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx @@ -1,4 +1,20 @@ -export default function QuizLoading() { +import { useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { getQuizSocket } from '@/shared/utils/socket'; +import { getCookie } from '@/shared/utils/cookie'; + +export default function QuizEnd() { + const socket = getQuizSocket(); + const { pinCode } = useParams(); + + const [ranking, setRanking] = useState([]); + + useEffect(() => { + socket.emit('show ranking', { pinCode, sid: getCookie('sid') }, (response: any) => { + setRanking(response); + }); + }, []); + return (
@@ -9,18 +25,22 @@ export default function QuizLoading() {
+
{ranking.rankerDatas?.[1]?.nickname}
+
{ranking.rankerDatas?.[0]?.nickname}
+
{ranking.rankerDatas?.[2]?.nickname}
- 나는 몇 등? - #10 + {ranking.myNickname}님은? + {ranking.myRank + 1}등 + {ranking.myScore}점