From 26d3cd7d1cc0a7398dd9972f9b3b3cbdd14d0576 Mon Sep 17 00:00:00 2001 From: byeong Date: Wed, 20 Nov 2024 17:59:24 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20quiz-session=20socket=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/src/pages/quiz-session/index.tsx | 15 +++++++---- .../client/src/pages/quiz-session/type.d.ts | 12 +++++++++ .../src/pages/quiz-session/ui/QuizBox.tsx | 27 +++++++------------ 3 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 packages/client/src/pages/quiz-session/type.d.ts diff --git a/packages/client/src/pages/quiz-session/index.tsx b/packages/client/src/pages/quiz-session/index.tsx index c6d5d628..d630cc6c 100644 --- a/packages/client/src/pages/quiz-session/index.tsx +++ b/packages/client/src/pages/quiz-session/index.tsx @@ -1,4 +1,5 @@ import { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; import { getQuizSocket } from '@/shared/utils/socket'; import QuizBackground from './ui/QuizBackground'; @@ -8,6 +9,7 @@ import QuizLoading from './ui/QuizLoading'; import { toastController } from '@/features/toast/model/toastController'; export default function QuizSession() { + const { pinCode } = useParams(); const socket = getQuizSocket(); const toast = toastController(); const [isLoading, setIsLoading] = useState(true); @@ -15,18 +17,22 @@ export default function QuizSession() { easy: 0, hard: 0, }); - const [quiz, setQuiz] = useState(null); + const [quiz, setQuiz] = useState({ + id: '', + content: '', + choices: [], + }); const totalReactions = reactionStats.easy + reactionStats.hard; const easyPercentage = totalReactions ? (reactionStats.easy / totalReactions) * 100 : 50; useEffect(() => { + socket.emit('show quiz', { pinCode }); // 지워야 됨 const quizPromise = new Promise((resolve, reject) => { - const handleShowQuiz = (data: any) => { + const handleShowQuiz = (data: QuizData) => { setQuiz(data); resolve(data); }; - socket.on('show quiz', handleShowQuiz); const timer = setTimeout(() => { @@ -57,7 +63,6 @@ export default function QuizSession() { }); }, []); - console.log(quiz); return ( <> {isLoading ? ( @@ -66,7 +71,7 @@ export default function QuizSession() {
- +
)} diff --git a/packages/client/src/pages/quiz-session/type.d.ts b/packages/client/src/pages/quiz-session/type.d.ts new file mode 100644 index 00000000..6c1fcf2e --- /dev/null +++ b/packages/client/src/pages/quiz-session/type.d.ts @@ -0,0 +1,12 @@ +interface Choice { + id: number; + quizId: number; + content: string; + isCorrect: boolean; + position: number; +} +interface QuizData { + id: string; + content: string; + choices: Choice[]; +} diff --git a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx index 0c643400..0a136635 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx @@ -9,15 +9,16 @@ interface ReactionData { interface QuizBoxProps { reactionStats: ReactionData; setReactionStats: Dispatch>; + quiz: QuizData; } -export default function QuizBox({ reactionStats, setReactionStats }: QuizBoxProps) { +export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizBoxProps) { const [selectedAnswer, setSelectedAnswer] = useState([]); const [hasSubmitted, setHasSubmitted] = useState(false); const easyButtonRef = useRef(null); const hardButtonRef = useRef(null); const socket = getQuizSocket(); - + console.log(quiz); const handleSelectAnswer = (idx: number) => { setSelectedAnswer((prev) => { if (prev.includes(idx)) { @@ -80,32 +81,22 @@ export default function QuizBox({ reactionStats, setReactionStats }: QuizBoxProp {/* 문제 */}
-

- Python의 기본 자료형에 대한 설명으로 올바른 것은? -

-

- 다음 중 Python의 기본 자료형(Data Type)에 대한 설명으로 가장 적절한 것을 고르시오. -

+

{quiz?.content}

{/* 선택지 */}
- {[ - '문자열(string)은 변경 가능한(mutable) 자료형이다.', - '튜플(tuple)은 변경 불가능한(immutable) 자료형이다.', - '리스트(list)는 변경 불가능한(immutable) 자료형이다.', - '딕셔너리(dictionary)는 정렬된 자료형이다.', - ].map((answer, idx) => ( + {quiz?.choices.map((choice, idx) => ( ))}
From dcf7356022a8ba7c0d25044a5a7da0fcc1ff535e Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 11:23:51 +0900 Subject: [PATCH 02/18] =?UTF-8?q?fix:=20socket=20transports=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20websocket=EC=9C=BC=EB=A1=9C=20=EA=B3=A0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/shared/utils/socket.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/client/src/shared/utils/socket.ts b/packages/client/src/shared/utils/socket.ts index f1bf8c4e..c2f33d92 100644 --- a/packages/client/src/shared/utils/socket.ts +++ b/packages/client/src/shared/utils/socket.ts @@ -4,7 +4,9 @@ let socket: Socket | null = null; export function getQuizSocket(): Socket { if (!socket) { - socket = io(`${import.meta.env.VITE_SERVER_URL}/game`); + socket = io(`${import.meta.env.VITE_SERVER_URL}/game`, { + transports: ['websocket'], + }); } return socket; } From 5cc9cbeb09755c722e64d0a52598e9ed62382ffe Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 11:25:34 +0900 Subject: [PATCH 03/18] =?UTF-8?q?feat:=20User=20Type=20=EC=8B=9D=EB=B3=84?= =?UTF-8?q?=20=EB=B0=8F=20=ED=80=B4=EC=A6=88=20=EC=8B=9C=EC=9E=91=20?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/pages/quiz-wait/index.tsx | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/packages/client/src/pages/quiz-wait/index.tsx b/packages/client/src/pages/quiz-wait/index.tsx index d0b31d81..b1f19e54 100644 --- a/packages/client/src/pages/quiz-wait/index.tsx +++ b/packages/client/src/pages/quiz-wait/index.tsx @@ -6,6 +6,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { getQuizSocket } from '@/shared/utils/socket'; import { getCookie } from '@/shared/utils/cookie'; import { toastController } from '@/features/toast/model/toastController'; +import { apiClient } from '@/shared/api'; const GUEST_DISPLAY_SIZE = { width: 1020, height: 576 }; const SPACING = 10; @@ -24,11 +25,24 @@ export default function QuizWait() { const socket = getQuizSocket(); const navigate = useNavigate(); const toast = toastController(); + const [userType, setUserType] = useState(''); useEffect(() => { socket.on('nickname', (response) => { setGuests([...response]); }); + + socket.on('start quiz', (response) => { + console.log('start quiz', response); + navigate(`/quiz/session/${pinCode}/1`); + }); + + const getUserType = async () => { + const response = await apiClient.get(`/games/${pinCode}/sid/${getCookie('sid')}`); + console.log(response); + setUserType(response.type); + }; + getUserType(); }, []); useLayoutEffect(() => { @@ -55,8 +69,8 @@ export default function QuizWait() { }; const handleQuizStart = () => { - socket.emit('master entry', { classId: '123', sid: getCookie('sid') }); - navigate('/quiz/session'); + socket.emit('start quiz', { sid: getCookie('sid'), pinCode }); + navigate(`/quiz/session/host/${pinCode}/1`); }; return ( @@ -90,15 +104,17 @@ export default function QuizWait() { ))} -
- -
+ {userType === 'master' && ( +
+ +
+ )} ); From d7c5868173fca0337d8f8e7f7701436e127b2c00 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 13:12:14 +0900 Subject: [PATCH 04/18] =?UTF-8?q?fix:=20=ED=80=B4=EC=A6=88=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=20=ED=99=94=EB=A9=B4=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/quiz-session/ui/QuizLoading.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx index 789c0c59..c73bc103 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx @@ -1,29 +1,29 @@ export default function QuizLoading() { return (
-
+
- Leader Board + 🏆 Leader Board
-
+
-
+
2
-
+
1
-
+
3
나는 몇 등? - #10 + #10
From 90fdac5c081eb26ecc982f60813cdf25077dcca0 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 13:42:08 +0900 Subject: [PATCH 05/18] =?UTF-8?q?fix:=20quizLoading=20UI=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 --- packages/client/src/pages/quiz-session/ui/QuizLoading.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx index c73bc103..9c4dee5c 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx @@ -9,15 +9,12 @@ export default function QuizLoading() {
- 2
- 1
- 3
From 18f330a47969969c739c310b9d5ed787749f8673 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 14:38:00 +0900 Subject: [PATCH 06/18] =?UTF-8?q?feat:=20spin=20keyframe=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 --- packages/client/tailwind.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/client/tailwind.config.js b/packages/client/tailwind.config.js index 0ac3ce6b..6b51cf6c 100644 --- a/packages/client/tailwind.config.js +++ b/packages/client/tailwind.config.js @@ -46,6 +46,7 @@ export default { 'progress-20s': 'progress 20s linear forwards', 'progress-30s': 'progress 30s linear forwards', 'slide-out': 'slide-out 0.5s ease-in forwards', + 'spin-slow': 'spin-slow 6s linear infinite', }, keyframes: { progress: { @@ -75,6 +76,10 @@ export default { opacity: 0, }, }, + 'spin-slow': { + from: { transform: 'rotate(0deg)' }, + to: { transform: 'rotate(360deg)' }, + }, }, }, }, From 024c5a32bb806a0e96e518a32b01eee791b9c365 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 14:38:16 +0900 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20quiz=20loading=20UI=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 --- .../src/pages/quiz-session/ui/QuizLoading.tsx | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx index 9c4dee5c..d2c7cca6 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx @@ -1,28 +1,48 @@ -export default function QuizLoading() { +const QuizLoading = () => { return ( -
-
-
- 🏆 Leader Board -
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+ +
+
+
-
-
+ +
+

+ 다음 퀴즈로 이동 중 입니다. +

+ +
+ {[0, 1, 2].map((i) => ( +
+ ))} +
-
-
- 나는 몇 등? - #10 +

+ 잠시만 기다려주세요... +

); -} +}; + +export default QuizLoading; From 07ea6e7f734a8151c79a45f4412a3c8f6fbd3864 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 14:38:26 +0900 Subject: [PATCH 08/18] =?UTF-8?q?feat:=20quiz=20end=20UI=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 --- .../src/pages/quiz-session/ui/QuizEnd.tsx | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 packages/client/src/pages/quiz-session/ui/QuizEnd.tsx diff --git a/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx b/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx new file mode 100644 index 00000000..9c4dee5c --- /dev/null +++ b/packages/client/src/pages/quiz-session/ui/QuizEnd.tsx @@ -0,0 +1,28 @@ +export default function QuizLoading() { + return ( +
+
+
+ 🏆 Leader Board +
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+ 나는 몇 등? + #10 +
+
+
+ ); +} From aef1d0cf5a7b444295bfa2c8160e2c302231044a Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 14:38:45 +0900 Subject: [PATCH 09/18] =?UTF-8?q?feat:=20quiz=20end=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/pages/quiz-session/index.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/quiz-session/index.tsx b/packages/client/src/pages/quiz-session/index.tsx index d630cc6c..21017790 100644 --- a/packages/client/src/pages/quiz-session/index.tsx +++ b/packages/client/src/pages/quiz-session/index.tsx @@ -4,6 +4,7 @@ import { useParams } from 'react-router-dom'; import { getQuizSocket } from '@/shared/utils/socket'; import QuizBackground from './ui/QuizBackground'; 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'; @@ -13,6 +14,7 @@ export default function QuizSession() { const socket = getQuizSocket(); const toast = toastController(); const [isLoading, setIsLoading] = useState(true); + const [isQuizEnd, setIsQuizEnd] = useState(false); const [reactionStats, setReactionStats] = useState({ easy: 0, hard: 0, @@ -27,10 +29,11 @@ export default function QuizSession() { const easyPercentage = totalReactions ? (reactionStats.easy / totalReactions) * 100 : 50; useEffect(() => { - socket.emit('show quiz', { pinCode }); // 지워야 됨 const quizPromise = new Promise((resolve, reject) => { const handleShowQuiz = (data: QuizData) => { setQuiz(data); + setIsLoading(true); + setIsQuizEnd(false); resolve(data); }; socket.on('show quiz', handleShowQuiz); @@ -58,8 +61,8 @@ export default function QuizSession() { setIsLoading(false); }); - socket.emit('timeout', (response: any) => { - console.log(response); + socket.on('timer end', () => { + setIsQuizEnd(true); }); }, []); @@ -74,6 +77,7 @@ export default function QuizSession() {
)} + {isQuizEnd && } ); } From 9f0e3e3bbfa98895ae9959d0c50e4d5fae326069 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 19:06:15 +0900 Subject: [PATCH 10/18] =?UTF-8?q?feat:=20master-session=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/quiz-master-session/index.tsx | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/quiz-master-session/index.tsx b/packages/client/src/pages/quiz-master-session/index.tsx index 748e0af3..44b5bb9f 100644 --- a/packages/client/src/pages/quiz-master-session/index.tsx +++ b/packages/client/src/pages/quiz-master-session/index.tsx @@ -6,6 +6,7 @@ import ProgressBar from '@/shared/ui/progress-bar/ProgressBar'; import { CustomButton } from '@/shared/ui/buttons'; import AnswerGraph from '@/pages/quiz-master-session/ui/AnswerChart'; import RecentSubmittedAnswers from './ui/RecentSubmittedAnswers'; +import { getQuizSocket } from '@/shared/utils/socket'; interface AnswerStat { answer: string; @@ -47,7 +48,8 @@ const statisticsCardItems = [ const limitedTime = 20; export default function QuizMasterSession() { - const { id } = useParams(); + const { pinCode, id } = useParams(); + const socket = getQuizSocket(); const [answerStats, setAnswerStats] = useState([ { answer: '1번', count: 10, color: '#3B82F6' }, @@ -75,7 +77,21 @@ export default function QuizMasterSession() { }); }; + const handleNextQuiz = () => { + socket.emit('start quiz', { pinCode }); + }; + useEffect(() => { + socket.emit('show quiz', { pinCode }); + + socket.emit('total status', { pinCode }, (response: any) => { + console.log(response); + }); + + socket.on('timer end', (response) => { + console.log(response); + }); + const timer = setInterval(() => { tick(); }, 1000); @@ -92,7 +108,7 @@ export default function QuizMasterSession() {

제한 시간 {time}

- +
From 24e5f5d0fff6a338c402409c9aea83c6c851a765 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 19:06:38 +0900 Subject: [PATCH 11/18] =?UTF-8?q?fix:=20show=20quiz=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/pages/quiz-session/index.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/quiz-session/index.tsx b/packages/client/src/pages/quiz-session/index.tsx index 21017790..dd91c7ef 100644 --- a/packages/client/src/pages/quiz-session/index.tsx +++ b/packages/client/src/pages/quiz-session/index.tsx @@ -30,11 +30,13 @@ export default function QuizSession() { useEffect(() => { const quizPromise = new Promise((resolve, reject) => { - const handleShowQuiz = (data: QuizData) => { - setQuiz(data); + const handleShowQuiz = (response: any) => { + const { currentQuizData, isLast } = response; + setQuiz(currentQuizData); setIsLoading(true); setIsQuizEnd(false); - resolve(data); + console.log(response); + resolve(currentQuizData); }; socket.on('show quiz', handleShowQuiz); @@ -61,9 +63,17 @@ export default function QuizSession() { setIsLoading(false); }); + socket.on('tick', (response) => { + console.log('tick', response); + }); + socket.on('timer end', () => { setIsQuizEnd(true); }); + + return () => { + socket.off('timer end', () => {}); + }; }, []); return ( From 2a2f00d6486501ee9df7b991aef9e7a1187a3134 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 19:08:15 +0900 Subject: [PATCH 12/18] =?UTF-8?q?temp:=20=EC=86=8C=EC=BC=93=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EC=9D=91=EB=8B=B5=20=EC=BD=94=EB=93=9C=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 --- .../src/pages/quiz-session/ui/QuizBox.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx index 0a136635..1f590c0d 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx @@ -1,6 +1,7 @@ import { Dispatch, SetStateAction, useState, useRef, useEffect, useCallback } from 'react'; import { getQuizSocket } from '@/shared/utils/socket'; +import { getCookie } from '@/shared/utils/cookie'; interface ReactionData { easy: number; hard: number; @@ -29,7 +30,10 @@ export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizB }; const handleSubmit = () => { - socket.emit('submit answer', { selectAnswer: selectedAnswer }); + socket.emit('submit answer', { + selectAnswer: selectedAnswer, + sid: getCookie('sid'), + }); console.log(selectedAnswer); setHasSubmitted(true); }; @@ -66,6 +70,19 @@ export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizB socket.on('submit answer', handleSubmitUpdate); + socket.on('timer tick', (response) => { + console.log('timer tick', response); + }); + + if (hasSubmitted) { + socket.on('submit status', (response) => { + console.log('submit status', response); + }); + } + + socket.on('timer end', (response) => { + console.log('timer end', response); + }); return () => { socket.off('emoji', handleReactionUpdate); }; From c70f2f81f5204182e22a58fe91a4095a070bead2 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 21 Nov 2024 19:08:57 +0900 Subject: [PATCH 13/18] fix: user type fetch function added --- packages/client/src/pages/quiz-wait/index.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/quiz-wait/index.tsx b/packages/client/src/pages/quiz-wait/index.tsx index e30da557..bf526425 100644 --- a/packages/client/src/pages/quiz-wait/index.tsx +++ b/packages/client/src/pages/quiz-wait/index.tsx @@ -8,6 +8,7 @@ import { getCookie } from '@/shared/utils/cookie'; import { toastController } from '@/features/toast/model/toastController'; import LoadingSpinner from '@/shared/assets/icons/loading-alt-loop.svg?react'; import { useGetUserType } from '@/shared/hooks/useGetUserType'; +import { apiClient } from '@/shared/api'; const GUEST_DISPLAY_SIZE = { width: 940, height: 568 }; const SPACING = 10; @@ -26,18 +27,27 @@ export default function QuizWait() { const socket = getQuizSocket(); const navigate = useNavigate(); const toast = toastController(); + const [userType, setUserType] = useState(''); - const { data: userType } = useGetUserType({ pinCode: pinCode!, sid: getCookie('sid')! }); + // const { data: userType } = useGetUserType({ pinCode: pinCode!, sid: getCookie('sid')! }); useEffect(() => { socket.on('nickname', (response) => { setGuests([...response]); }); + const fetchUserType = async () => { + const response = await apiClient.get(`/games/${pinCode}/sid/${getCookie('sid')}`); + console.log(response); + setUserType(response.type); + }; + socket.on('start quiz', (response) => { console.log('start quiz', response); navigate(`/quiz/session/${pinCode}/1`); }); + + fetchUserType(); }, []); useLayoutEffect(() => { From 03a5ff04e20b42c9fa05ab669e6c937f434c271f Mon Sep 17 00:00:00 2001 From: byeong Date: Sat, 23 Nov 2024 17:49:36 +0900 Subject: [PATCH 14/18] =?UTF-8?q?fix:=20Loading=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20Heigth=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/pages/quiz-session/ui/QuizLoading.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx index d2c7cca6..c5240776 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizLoading.tsx @@ -1,6 +1,6 @@ const QuizLoading = () => { return ( -
+
From 51b35e6cf3900267307f9f41dbc4e9e077b7d4a3 Mon Sep 17 00:00:00 2001 From: byeong Date: Sat, 23 Nov 2024 17:50:34 +0900 Subject: [PATCH 15/18] =?UTF-8?q?feat:=20Animation=20keyframe=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 - floatDown : 아래로 내려오는 애니메이션 - swing : 좌우로 왔다갔다 하는 애니메이션 --- packages/client/tailwind.config.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/client/tailwind.config.js b/packages/client/tailwind.config.js index 6b51cf6c..061e00e8 100644 --- a/packages/client/tailwind.config.js +++ b/packages/client/tailwind.config.js @@ -80,6 +80,21 @@ export default { from: { transform: 'rotate(0deg)' }, to: { transform: 'rotate(360deg)' }, }, + floatDown: { + '0%': { + transform: 'translateY(-100px)', + opacity: 0, + }, + '100%': { + transform: 'translateY(0)', + opacity: 1, + }, + }, + swing: { + '0%': { transform: 'rotate(0deg) translateY(0)' }, + '50%': { transform: 'rotate(30deg) translateY(-20px)' }, + '100%': { transform: 'rotate(0deg) translateY(0)' }, + }, }, }, }, From e80477b790289664b07f4ea7725ac4e729a7a913 Mon Sep 17 00:00:00 2001 From: byeong Date: Sat, 23 Nov 2024 20:09:00 +0900 Subject: [PATCH 16/18] =?UTF-8?q?fix:=20Quiz=20Session=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/src/pages/quiz-session/index.tsx | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/packages/client/src/pages/quiz-session/index.tsx b/packages/client/src/pages/quiz-session/index.tsx index 77827cef..12906e95 100644 --- a/packages/client/src/pages/quiz-session/index.tsx +++ b/packages/client/src/pages/quiz-session/index.tsx @@ -1,5 +1,4 @@ import { useState, useEffect } from 'react'; -import { useParams } from 'react-router-dom'; import { getQuizSocket } from '@/shared/utils/socket'; import QuizBackground from './ui/QuizBackground'; @@ -10,23 +9,24 @@ import QuizLoading from './ui/QuizLoading'; import { toastController } from '@/features/toast/model/toastController'; export default function QuizSession() { - const { pinCode } = useParams(); const socket = getQuizSocket(); const toast = toastController(); const [isLoading, setIsLoading] = useState(true); const [isQuizEnd, setIsQuizEnd] = useState(false); - const [reactionStats, setReactionStats] = useState({ - easy: 0, - hard: 0, - }); + const [tick, setTick] = useState({ currentTime: 0, elapsedTime: 0, remainingTime: 0 }); const [quiz, setQuiz] = useState({ id: '', content: '', choices: [], }); - const totalReactions = reactionStats.easy + reactionStats.hard; - const easyPercentage = totalReactions ? (reactionStats.easy / totalReactions) * 100 : 50; + const handleTick = (response: any) => { + setTick(response); + }; + + const handleTimeEnd = () => { + setIsQuizEnd(true); + }; useEffect(() => { const quizPromise = new Promise((resolve, reject) => { @@ -62,28 +62,22 @@ export default function QuizSession() { setIsLoading(false); }); - socket.on('tick', (response) => { - console.log('tick', response); - }); - - socket.on('timer end', () => { - setIsQuizEnd(true); - }); + socket.on('timer tick', handleTick); + socket.on('time end', handleTimeEnd); return () => { - socket.off('timer end', () => {}); + socket.off('time end', handleTimeEnd); + socket.off('timer tick', handleTick); }; }, []); return ( <> - {isLoading ? ( - - ) : ( -
- - - + {isLoading && !isQuizEnd && } + {!isLoading && !isQuizEnd && ( +
+ +
)} {isQuizEnd && } From eeeccb2f6c965e27bd43f17a3f38a8b7238859c9 Mon Sep 17 00:00:00 2001 From: byeong Date: Sat, 23 Nov 2024 20:09:37 +0900 Subject: [PATCH 17/18] =?UTF-8?q?fix:=20QuizBox=20=EC=86=8C=EC=BC=93=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20Backgroun?= =?UTF-8?q?d=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/quiz-session/ui/QuizBox.tsx | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx index 93107732..bcd7ed18 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizBox.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizBox.tsx @@ -3,25 +3,46 @@ import { Dispatch, SetStateAction, useState, useRef, useEffect, useCallback } fr import { getQuizSocket } from '@/shared/utils/socket'; import { getCookie } from '@/shared/utils/cookie'; import { useParams } from 'react-router-dom'; +import AfterQuizSubmit from './AfterQuizSubmit'; +import QuizBackground from './QuizBackground'; interface ReactionData { easy: number; hard: number; } +export interface StatisticsData { + averageTime: number; + participantRate: number; + solveRate: number; + totalSubmit: number; +} + interface QuizBoxProps { - reactionStats: ReactionData; - setReactionStats: Dispatch>; quiz: QuizData; + tick: { currentTime: number; elapsedTime: number; remainingTime: number }; } -export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizBoxProps) { +export default function QuizBox({ quiz, tick }: QuizBoxProps) { const { pinCode } = useParams(); const [selectedAnswer, setSelectedAnswer] = useState([]); const [hasSubmitted, setHasSubmitted] = useState(false); + const [reactionStats, setReactionStats] = useState({ + easy: 0, + hard: 0, + }); + const [participantStatistics, setParticipantStatistics] = useState({ + averageTime: 0, + participantRate: 0, + solveRate: 0, + totalSubmit: 0, + }); const easyButtonRef = useRef(null); const hardButtonRef = useRef(null); const socket = getQuizSocket(); - const [tick, setTick] = useState({ currentTime: 0, elapsedTime: 0, remainingTime: 0 }); + + const totalReactions = reactionStats.easy + reactionStats.hard; + const easyPercentage = totalReactions ? (reactionStats.easy / totalReactions) * 100 : 50; + const handleSelectAnswer = (idx: number) => { setSelectedAnswer((prev) => { if (prev.includes(idx)) { @@ -38,7 +59,6 @@ export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizB pinCode: pinCode, submitTime: tick.elapsedTime, }); - console.log(selectedAnswer); setHasSubmitted(true); }; @@ -65,27 +85,23 @@ export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizB setReactionStats(data); }, []); + const handleParticipantStatistics = (response: StatisticsData) => { + setParticipantStatistics(response); + }; + useEffect(() => { socket.on('emoji', handleReactionUpdate); + socket.on('participant statistics', handleParticipantStatistics); - socket.on('timer tick', (response) => { - setTick(response); - }); - - socket.on('participant statistics', (response) => { - console.log('participant statistics', response); - }); - - socket.on('time end', (response) => { - console.log('time end', response); - }); return () => { socket.off('emoji', handleReactionUpdate); + socket.off('participant statistics', handleParticipantStatistics); }; }, []); return ( <> +
@@ -154,6 +170,8 @@ export default function QuizBox({ reactionStats, setReactionStats, quiz }: QuizB
+ + {} ); } From 340df119db930a150d4d0e217f08e2e2479e56b9 Mon Sep 17 00:00:00 2001 From: byeong Date: Sat, 23 Nov 2024 20:09:50 +0900 Subject: [PATCH 18/18] =?UTF-8?q?feat:=20tick=20props=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/pages/quiz-session/ui/QuizHeader.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/client/src/pages/quiz-session/ui/QuizHeader.tsx b/packages/client/src/pages/quiz-session/ui/QuizHeader.tsx index 83849401..d90efa56 100644 --- a/packages/client/src/pages/quiz-session/ui/QuizHeader.tsx +++ b/packages/client/src/pages/quiz-session/ui/QuizHeader.tsx @@ -2,7 +2,11 @@ import { useEffect, useState } from 'react'; import { getQuizSocket } from '@/shared/utils/socket'; -export default function QuizHeader() { +interface QuizHeaderProps { + tick: { currentTime: number; elapsedTime: number; remainingTime: number }; +} + +export default function QuizHeader({ tick }: QuizHeaderProps) { const socket = getQuizSocket(); const [submitStatus, setSubmitStatus] = useState<{ count: number; total: number }>({ count: 0, @@ -27,7 +31,7 @@ export default function QuizHeader() {
{submitStatus.count} / {submitStatus.total}명 제출
-
남은 시간
+
{tick.remainingTime}초 남음
);