{SCROLLING_TEXTS.map((text, index) => ( diff --git a/src/pages/Main/TestMake/TestMake.tsx b/src/pages/Main/TestMake/TestMake.tsx index b9e1603..281fd23 100644 --- a/src/pages/Main/TestMake/TestMake.tsx +++ b/src/pages/Main/TestMake/TestMake.tsx @@ -34,7 +34,7 @@ const TestMake = () => { }; const handleTestStartBtnClick = () => { - if (lectureId.length < 0 && questionCount > 0 && questionTypes.length > 0) { + if (lectureId.length > 0 && questionCount > 0 && questionTypes.length > 0) { navigate('/test'); } else { alert('스크립트와 문제 유형, 문제 개수를 모두 선택해주세요.'); diff --git a/src/pages/Test/Test.tsx b/src/pages/Test/Test.tsx index e7e93c2..cddaba3 100644 --- a/src/pages/Test/Test.tsx +++ b/src/pages/Test/Test.tsx @@ -1,17 +1,25 @@ import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import TestHeader from '../../components/organisms/headers/TestHeader/TestHeader'; import MultipleChoice from '../../components/molecules/questions/MultipleChoice/MultipleChoice'; import OXChoice from '../../components/molecules/questions/OXChoice/OXChoice'; import ShortAnswer from '../../components/molecules/questions/ShortAnswer/ShortAnswer'; +import Loading from '../../assets/images/LoadingCircle.gif'; import useTestModalStore from '../../store/useTestModalStore'; import useTestSettingsStore from '../../store/useTestSettingsStore'; import { generateProblem } from '../../apis/test'; import styles from './Test.module.scss'; const Test = () => { + const navigate = useNavigate(); + const [userAnswers, setUserAnswers] = useState<(string | number)[]>([]); + const [showResults, setShowResults] = useState(false); + + const { updateTestData, clearTestData } = useTestModalStore(); const { lectureId, scheduleElementId, questionCount, questionTypes } = useTestSettingsStore(); + const inputData = { lectureId: lectureId, subject: scheduleElementId, @@ -19,22 +27,12 @@ const Test = () => { problem_types: questionTypes.join(','), }; - const { data } = useQuery({ + const { data, isFetching } = useQuery({ queryKey: ['problem', lectureId], queryFn: () => generateProblem(inputData), retry: false, }); - const [userAnswers, setUserAnswers] = useState<(string | number)[]>([]); - - useEffect(() => { - setUserAnswers(Array(data?.length).fill('')); - }, [data]); - - const [showResults, setShowResults] = useState(false); - - const { updateTestData, clearTestData } = useTestModalStore(); - const handleAnswerChange = (index: number, answer: string | number) => { const newAnswers = [...userAnswers]; newAnswers[index] = answer; @@ -48,7 +46,22 @@ const Test = () => { }; useEffect(() => { - updateTestData({ totalNum: data?.length }); + if (!data?.success) { + alert('문제 생성을 실패했습니다. 다시 시도해주세요.'); + navigate('/home/test-make'); + } + }, [data]); + + useEffect(() => { + if (data != null && data.object != null) { + setUserAnswers(Array(data.object.length).fill('')); + } + }, [data]); + + useEffect(() => { + if (data != null && data.object != null) { + updateTestData({ totalNum: data.object.length }); + } return () => clearTestData(); }, [data]); @@ -56,41 +69,43 @@ const Test = () => { - {data?.map((question, index) => ( - - Q{index + 1} - {question.direction} - {question.type === 'MultipleChoice' && ( - handleAnswerChange(index, answer)} - showResult={showResults} - /> - )} - {question.type === 'ShortAnswer' && ( - handleAnswerChange(index, answer)} - showResult={showResults} - /> - )} - {question.type === 'OXChoice' && ( - handleAnswerChange(index, answer)} - showResult={showResults} - /> - )} - - ))} + {isFetching && } + {data != null && + data.object != null && + data.object.map((question, index) => ( + + Q{index + 1} + {question.direction} + {question.type === 'MultipleChoice' && ( + handleAnswerChange(index, answer)} + showResult={showResults} + /> + )} + {question.type === 'ShortAnswer' && ( + handleAnswerChange(index, answer)} + showResult={showResults} + /> + )} + {question.type === 'OXChoice' && ( + handleAnswerChange(index, answer)} + showResult={showResults} + /> + )} + + ))} - {} ); }; diff --git a/src/store/useRecordModalStore.ts b/src/store/useRecordModalStore.ts index 31c9762..b4ca674 100644 --- a/src/store/useRecordModalStore.ts +++ b/src/store/useRecordModalStore.ts @@ -4,6 +4,12 @@ import { generateRecordingTitle } from '../utils/dateFormatters'; interface IRecordData { title: string; tag: string; + scheduleId: number | null; +} + +export interface ITagItem { + name: string; + scheduleId: number | null; } interface IRecordModalState { @@ -18,6 +24,7 @@ interface IRecordModalState { const initialRecordData = { title: generateRecordingTitle(), tag: '', + scheduleId: null, }; const useRecordModalStore = create((set) => ({ diff --git a/src/store/useTestModalStore.ts b/src/store/useTestModalStore.ts index 5e11a15..70bd07b 100644 --- a/src/store/useTestModalStore.ts +++ b/src/store/useTestModalStore.ts @@ -1,7 +1,6 @@ import create from 'zustand'; interface ITestData { - time: number; completeNum: number; totalNum: number; } @@ -16,7 +15,6 @@ interface ITestModalState { } const initialTestData = { - time: 0, completeNum: 0, totalNum: 0, }; diff --git a/src/utils/schedule.ts b/src/utils/schedule.ts index f2876d3..f5e7fb7 100644 --- a/src/utils/schedule.ts +++ b/src/utils/schedule.ts @@ -1,20 +1,12 @@ import { - ColorKey, + daysEnNumMap, DayOfWeek, - daysObject, + daysKorEnMap, LectureInfo, + IScheduleElement, + IAddScheduleElement, } from '../constants/schedule'; -const DAYMAP: Record = { - SUN: 0, - MON: 1, - TUE: 2, - WED: 3, - THU: 4, - FRI: 5, - SAT: 6, -}; - export const getScheduleStyle = ( dayOfWeek: DayOfWeek, startTime: string, @@ -27,7 +19,7 @@ export const getScheduleStyle = ( // return 값 const top = (startHour + startMinute - 9) * 80 + 60; const height = (endHour + endMinute - startHour - startMinute) * 80; - const left = `calc((100% - 120px) * ${DAYMAP[dayOfWeek]} / 7)`; + const left = `calc((100% - 120px) * ${daysEnNumMap[dayOfWeek]} / 7)`; return { '--schedule-left': left, @@ -91,7 +83,7 @@ export const getIsAddScheduleFormValid = ({ // 요일 한글 -> 대문자 영어 변환 const getDayOfWeek = (day: string) => { - return daysObject[day as keyof typeof daysObject] || day; + return daysKorEnMap[day as keyof typeof daysKorEnMap] || day; }; // 시간 ISO 변환 @@ -103,15 +95,6 @@ const getFormattedTime = (hour: string, minute: string) => { return `${dateString}T${timeString}`; }; -export interface IScheduleElementDTO { - name: string; - location: string; - dayOfWeek: string; - startTime: string; - endTime: string; - color: ColorKey; -} - export const transformToScheduleElementDTO = (lectureData: LectureInfo) => { const transformedData = { name: lectureData.title, @@ -123,3 +106,34 @@ export const transformToScheduleElementDTO = (lectureData: LectureInfo) => { }; return transformedData; }; + +export const hasNewElementConflict = ( + newElement: IAddScheduleElement, + oldElements: IScheduleElement[], +): boolean => { + for (const oldElement of oldElements) { + if (newElement.dayOfWeek === oldElement.dayOfWeek) { + const startNewHour = Number(newElement.startTime.slice(11, 13)); + const startNewMinute = Number(newElement.startTime.slice(14, 16)) / 60; + const endNewHour = Number(newElement.endTime.slice(11, 13)); + const endNewMinute = Number(newElement.endTime.slice(14, 16)) / 60; + const startNewTime = startNewHour + startNewMinute; + const endNewTime = endNewHour + endNewMinute; + + const startOldHour = Number(oldElement.startTime.slice(11, 13)); + const startOldMinute = Number(oldElement.startTime.slice(14, 16)) / 60; + const endOldHour = Number(oldElement.endTime.slice(11, 13)); + const endOldMinute = Number(oldElement.endTime.slice(14, 16)) / 60; + const startOldTime = startOldHour + startOldMinute; + const endOldTime = endOldHour + endOldMinute; + if ( + (startNewTime < endOldTime && endNewTime > startOldTime) || + (startOldTime < endNewTime && endOldTime > startNewTime) || + (startNewTime === startOldTime && endNewTime === endOldTime) + ) { + return true; + } + } + } + return false; +};
- {data?.map((question, index) => ( - - Q{index + 1} - {question.direction} - {question.type === 'MultipleChoice' && ( - handleAnswerChange(index, answer)} - showResult={showResults} - /> - )} - {question.type === 'ShortAnswer' && ( - handleAnswerChange(index, answer)} - showResult={showResults} - /> - )} - {question.type === 'OXChoice' && ( - handleAnswerChange(index, answer)} - showResult={showResults} - /> - )} - - ))} + {isFetching && } + {data != null && + data.object != null && + data.object.map((question, index) => ( + + Q{index + 1} + {question.direction} + {question.type === 'MultipleChoice' && ( + handleAnswerChange(index, answer)} + showResult={showResults} + /> + )} + {question.type === 'ShortAnswer' && ( + handleAnswerChange(index, answer)} + showResult={showResults} + /> + )} + {question.type === 'OXChoice' && ( + handleAnswerChange(index, answer)} + showResult={showResults} + /> + )} + + ))}