Merge branch 'fe/fixLiveQuiz' into 'frontend'
[Front-End] 퀴즈 API 변경사항 반영 See merge request s11-webmobile1-sub2/S11P12A701!86
This commit is contained in:
commit
4035fbb250
@ -69,7 +69,7 @@ export default function ChatRoom({ isTeacher, ...props }) {
|
||||
<>
|
||||
<div
|
||||
{...props}
|
||||
className={`lk-chat ${wsChat.quizSetId ? styles.none : ''}`}
|
||||
className={`lk-chat ${wsChat.quizSetInfo ? styles.none : ''}`}
|
||||
>
|
||||
<header className={styles.header}>
|
||||
<h2 className={styles.title}>채팅</h2>
|
||||
@ -131,15 +131,16 @@ export default function ChatRoom({ isTeacher, ...props }) {
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{wsChat.quizSetId && (
|
||||
{wsChat.quizSetInfo && (
|
||||
<div className="lk-chat">
|
||||
<header className={styles.header}>
|
||||
<h2 className={styles.title}>퀴즈</h2>
|
||||
</header>
|
||||
<Suspense fallback={<></>}>
|
||||
<QuizSet
|
||||
quizSetId={wsChat.quizSetId}
|
||||
finish={() => wsChat.setQuizSetId(null)}
|
||||
quizSetId={wsChat.quizSetInfo[0]}
|
||||
reportSetId={wsChat.quizSetInfo[1]}
|
||||
finish={() => wsChat.setQuizSetInfo(null)}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
22
frontend/src/components/Countdown/Countdown.jsx
Normal file
22
frontend/src/components/Countdown/Countdown.jsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export default function Countdown({ seconds }) {
|
||||
// eslint-disable-next-line no-undef
|
||||
const [remainedTime, setRemainedTime] = useState(seconds);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setRemainedTime((prev) => {
|
||||
if (prev === 0) {
|
||||
clearInterval(interval);
|
||||
return 0;
|
||||
}
|
||||
return prev - 1;
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [remainedTime]);
|
||||
|
||||
return <span>{remainedTime}</span>;
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-width: 1360px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
import styles from './QuizSet.module.css';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import Quiz from '../Quiz/Quiz';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import LoadingIndicator from '../LoadingIndicator.jsx/LoadingIndicator';
|
||||
import instance from '../../utils/axios/instance';
|
||||
import { API_URL } from '../../constants';
|
||||
import { useStudentQuizsetDetail } from '../../hooks/api/useStudentQuizsetDetail';
|
||||
import Countdown from '../Countdown/Countdown';
|
||||
|
||||
export default function QuizSet({ quizSetId, finish }) {
|
||||
const { roomId } = useParams();
|
||||
export default function QuizSet({ quizSetId, reportSetId, finish }) {
|
||||
const [step, setStep] = useState(null);
|
||||
const { data } = useStudentQuizsetDetail(quizSetId);
|
||||
const quizSetData = data?.data;
|
||||
@ -20,9 +19,9 @@ export default function QuizSet({ quizSetId, finish }) {
|
||||
const requestData = {
|
||||
answer: data,
|
||||
};
|
||||
instance.post(`${API_URL}/report/submit/${roomId}/quizset/${quizSetId}`, requestData).catch(() => {});
|
||||
instance.post(`${API_URL}/report/submit/${reportSetId}/quizset/${quizSetId}`, requestData).catch(() => {});
|
||||
},
|
||||
[quizSetId, roomId]
|
||||
[quizSetId, reportSetId]
|
||||
);
|
||||
const QuizComponents = [
|
||||
...quizList.map((quiz, index) => (
|
||||
@ -39,7 +38,10 @@ export default function QuizSet({ quizSetId, finish }) {
|
||||
key={Infinity}
|
||||
className={styles.message}
|
||||
>
|
||||
퀴즈 종료
|
||||
<div>
|
||||
<div>퀴즈 종료!</div>
|
||||
<div className={styles.subMsg}>답안을 전송하고 있어요</div>
|
||||
</div>
|
||||
</div>,
|
||||
];
|
||||
|
||||
@ -80,7 +82,9 @@ export default function QuizSet({ quizSetId, finish }) {
|
||||
<>
|
||||
{step === null ? (
|
||||
<div className={styles.message}>
|
||||
<span>10초 후 퀴즈를 시작합니다.</span>
|
||||
<span>
|
||||
<Countdown seconds={10} />초 후 퀴즈를 시작합니다.
|
||||
</span>
|
||||
<LoadingIndicator />
|
||||
</div>
|
||||
) : (
|
||||
|
@ -17,6 +17,7 @@
|
||||
gap: 32px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
@ -42,3 +43,22 @@
|
||||
transform-origin: left center;
|
||||
animation: progress 10s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% {
|
||||
rotate: -2.5deg;
|
||||
}
|
||||
100% {
|
||||
rotate: 2.5deg;
|
||||
}
|
||||
}
|
||||
|
||||
.subMsg {
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #ccc;
|
||||
animation: shake 1s ease-in-out alternate-reverse infinite;
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ import { chatClient } from '../../utils/chat/chatClient';
|
||||
import useBoundStore from '../../store';
|
||||
import { useQuizsets } from '../api/useQuizsets';
|
||||
|
||||
const USER_ID = crypto.getRandomValues(new Uint32Array(1))[0];
|
||||
|
||||
export default function useChatRoom(roomId) {
|
||||
const client = chatClient;
|
||||
const [messages, setMessages] = useState([]);
|
||||
@ -13,13 +11,12 @@ export default function useChatRoom(roomId) {
|
||||
const chatListRef = useRef(null);
|
||||
const { data: quizSetData } = useQuizsets();
|
||||
const quizSets = quizSetData?.data ?? [];
|
||||
const [quizSetId, setQuizSetId] = useState(null);
|
||||
const [quizSetInfo, setQuizSetInfo] = useState(null);
|
||||
|
||||
const startQuiz = (quizSetId) => {
|
||||
chatClient.publish({
|
||||
destination: `/pub/chat.quiz.${roomId}`,
|
||||
body: JSON.stringify({
|
||||
userId: USER_ID,
|
||||
quizSetId,
|
||||
}),
|
||||
});
|
||||
@ -36,7 +33,6 @@ export default function useChatRoom(roomId) {
|
||||
chatClient.publish({
|
||||
destination: `/pub/chat.message.${roomId}`,
|
||||
body: JSON.stringify({
|
||||
userId: USER_ID,
|
||||
name: userName,
|
||||
content: text,
|
||||
}),
|
||||
@ -48,13 +44,13 @@ export default function useChatRoom(roomId) {
|
||||
client.onConnect = () => {
|
||||
client.subscribe(`/exchange/chat.exchange/*.room.${roomId}`, (response) => {
|
||||
const data = JSON.parse(response.body);
|
||||
const { content: message, name, quizSetId } = data;
|
||||
const { content: message, name, quizSetId, reportSetId } = data;
|
||||
|
||||
if (quizSetId !== undefined) {
|
||||
setQuizSetId(quizSetId);
|
||||
setQuizSetInfo([quizSetId, reportSetId]);
|
||||
return;
|
||||
}
|
||||
setMessages((prev) => [...prev, { id: prev.length, text: message, isMine: USER_ID === data.userId, name }]);
|
||||
setMessages((prev) => [...prev, { id: prev.length, text: message, name }]);
|
||||
});
|
||||
};
|
||||
client.activate();
|
||||
@ -77,7 +73,7 @@ export default function useChatRoom(roomId) {
|
||||
chatListRef,
|
||||
startQuiz,
|
||||
quizSets,
|
||||
quizSetId,
|
||||
setQuizSetId,
|
||||
quizSetInfo,
|
||||
setQuizSetInfo,
|
||||
};
|
||||
}
|
||||
|
@ -167,7 +167,6 @@ body {
|
||||
sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-width: 1360px;
|
||||
}
|
||||
|
||||
a {
|
||||
|
Loading…
Reference in New Issue
Block a user