Skip to content

Commit

Permalink
feat: 학습하기 api연결을 위한 구조 개선 (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
gominzip committed Aug 25, 2024
1 parent cf79ec5 commit 9f8ddb1
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 136 deletions.
2 changes: 1 addition & 1 deletion src/apis/learning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const getQuizAndAnswer = async (languageTaleId: number) => {
const access = LocalStorage.getItem("access");
const authAxios = getAuthAxios(access);
const response = await authAxios.get(`${baseURL}/quiz/${languageTaleId}`);
return response.data;
return response.data.data;
} catch (error) {
throw error;
}
Expand Down
8 changes: 4 additions & 4 deletions src/components/common/selectOption/SelectOptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ const SelectOptionList = (props: SelectListProps) => {
}
};

const handleSelect = (value: string | number | null) => {
props.setter(value);
const handleSelect = (text: string | number | null) => {
props.setter(text);
};

return (
<S.SelectOptionContainer width={props.width}>
{props.selectList.map((element) => (
{props.selectList.map((element, id) => (
<SelectBtn
key={element.text}
key={id}
text={element.text}
colorName={getColorName(element.state)}
imgURL={getImgURL(element.state)}
Expand Down
55 changes: 27 additions & 28 deletions src/components/learn/ChoiceQuiz.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
import SelectOptionList from "@components/common/selectOption/SelectOptionList";
import * as S from "./learn.styled";
import { useState } from "react";
import { useEffect, useState } from "react";
import { ChoiceQuizProps } from "@type/learning";

const dummy = [
{ text: "사랑", value: true },
{ text: "엄마", value: false },
{ text: "우정", value: false },
{ text: "추억", value: false },
{ text: "행복", value: false },
];

const ChoiceQuiz = ({ setter, currentStep }: ChoiceQuizProps) => {
const ChoiceQuiz = ({
setter,
data,
isQuizGraded,
}: ChoiceQuizProps) => {
const [select, setSelect] = useState<string | number | null>(null);

useEffect(() => {
setter(null);
setSelect(null);
}, [data]);

const handleOptionChange = (text: string | number | null) => {
setSelect(text as string);
setter(text);
console.log(select);
};

return (
<S.Container>
<S.Title>Love는 무슨 뜻인가요?</S.Title>
<S.Title>{data.question}</S.Title>
<S.SubContainer>
<SelectOptionList
selectList={dummy.map((option) => ({
text: option.text,
value: option.text,
state:
currentStep === 2
? option.text === select
? option.text === "사랑"
? "correct"
: "wrong"
: option.text === "사랑"
? "correct"
: "default"
: option.text === select
? "selected"
: "default",
selectList={data.choiceList.map((option, id) => ({
text: option.sunji,
value: id + 1,
state: isQuizGraded
? id + 1 === select
? option.isCorrect === 1
? "wrong"
: "correct"
: option.isCorrect === 0
? "correct"
: "default"
: id + 1 === select
? "selected"
: "default",
}))}
setter={currentStep === 1 ? handleOptionChange : () => {}}
setter={handleOptionChange}
/>
</S.SubContainer>
</S.Container>
Expand Down
25 changes: 17 additions & 8 deletions src/components/learn/EssayQuiz.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import * as S from "./learn.styled";
import SelectBtn from "@components/common/selectOption/SelectBtn";
import { EssayQuizProps } from "@type/learning";

const EssayQuiz = ({ setter, currentStep, answer }: EssayQuizProps) => {
const EssayQuiz = ({
setter,
data,
isQuizGraded,
}: EssayQuizProps) => {
const [inputValue, setInputValue] = useState<string>("");

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
Expand All @@ -12,11 +16,16 @@ const EssayQuiz = ({ setter, currentStep, answer }: EssayQuizProps) => {
setter(trimmedValue);
};

useEffect(() => {
setter(null);
setInputValue("");
}, [data]);

return (
<S.Container>
<S.Title>Love는 무슨 뜻인가요?</S.Title>
<S.Title>{data.question}</S.Title>
<S.SubContainer>
{currentStep !== 4 ? (
{!isQuizGraded ? (
<S.Input
type="text"
value={inputValue}
Expand All @@ -28,13 +37,13 @@ const EssayQuiz = ({ setter, currentStep, answer }: EssayQuizProps) => {
<>
<SelectBtn
text={inputValue}
colorName={inputValue === answer ? "green" : "red"}
imgURL={inputValue === answer ? "/correct.png" : "/wrong.png"}
colorName={inputValue === "답" ? "green" : "red"}
imgURL={inputValue === "답" ? "/correct.png" : "/wrong.png"}
onClick={() => {}}
/>
{inputValue !== answer && (
{inputValue !== "답" && (
<SelectBtn
text={answer}
text={"답"}
colorName="green"
imgURL="/correct.png"
onClick={() => {}}
Expand Down
29 changes: 13 additions & 16 deletions src/components/learn/SentenceQuiz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const shuffleArray = (array: Array<{ order: number; word: string }>) => {
return shuffled;
};

const SentenceQuiz = ({ setter, currentStep, quizData }: SentenceQuizProps) => {
const SentenceQuiz = ({ setter, data, isQuizGraded }: SentenceQuizProps) => {
const [selectedWords, setSelectedWords] = useState<
Array<{ order: number; word: string }>
>([]);
Expand All @@ -20,8 +20,9 @@ const SentenceQuiz = ({ setter, currentStep, quizData }: SentenceQuizProps) => {
>([]);

useEffect(() => {
setShuffledWords(shuffleArray(quizData.sequenceList));
}, []);
setSelectedWords([]);
setShuffledWords(shuffleArray(data.sequenceList));
}, [data]);

const handleWordClick = (wordObj: { order: number; word: string }) => {
setSelectedWords((prev) => {
Expand All @@ -35,9 +36,9 @@ const SentenceQuiz = ({ setter, currentStep, quizData }: SentenceQuizProps) => {
};

const isCorrectOrder = () => {
if (selectedWords.length !== quizData.sequenceList.length) return false;
if (selectedWords.length !== data.sequenceList.length) return false;
return selectedWords.every(
(wordObj, index) => wordObj.order === quizData.sequenceList[index].order
(wordObj, index) => wordObj.order === data.sequenceList[index].order
);
};

Expand All @@ -49,9 +50,7 @@ const SentenceQuiz = ({ setter, currentStep, quizData }: SentenceQuizProps) => {
return (
<S.WordButton
key={wordObj.order}
onClick={
currentStep !== 6 ? () => handleWordClick(wordObj) : () => {}
}
onClick={!isQuizGraded ? () => handleWordClick(wordObj) : () => {}}
$isSelected={!!isSelected}
>
{wordObj.word}
Expand All @@ -61,7 +60,7 @@ const SentenceQuiz = ({ setter, currentStep, quizData }: SentenceQuizProps) => {
};

useEffect(() => {
if (selectedWords.length === quizData.sequenceList.length) {
if (selectedWords.length === data.sequenceList.length) {
const completedSentence = selectedWords
.map((wordObj) => wordObj.word)
.join(" ");
Expand All @@ -74,28 +73,26 @@ const SentenceQuiz = ({ setter, currentStep, quizData }: SentenceQuizProps) => {
return (
<S.Container>
<S.Title>
{currentStep !== 6
{!isQuizGraded
? "문장을 배열해볼까요?"
: isCorrectOrder()
? "정답입니다!"
: "오답입니다"}
</S.Title>
<S.SubContainer>
<S.SubTitle>{quizData.question}</S.SubTitle>
<S.SubTitle>{data.question}</S.SubTitle>
<S.SelectedSentence
$isPlaceholder={selectedWords.length === 0}
$state={
currentStep !== 6 ? "gray" : isCorrectOrder() ? "green" : "red"
}
$state={!isQuizGraded ? "gray" : isCorrectOrder() ? "green" : "red"}
>
{selectedWords.length === 0
? "단어를 선택해주세요"
: selectedWords.map((wordObj) => wordObj.word).join(" ")}
</S.SelectedSentence>
{currentStep === 6 && !isCorrectOrder() && (
{isQuizGraded && !isCorrectOrder() && (
<S.ResultSentence $isCorrect={isCorrectOrder()}>
{"정답: " +
quizData.sequenceList.map((wordObj) => wordObj.word).join(" ")}
data.sequenceList.map((wordObj) => wordObj.word).join(" ")}
</S.ResultSentence>
)}
</S.SubContainer>
Expand Down
123 changes: 88 additions & 35 deletions src/components/learn/TaleLearn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,113 @@ import FinishScreen from "@components/common/FinishScreen";
import NextBtn from "@components/common/NextBtn";
import ProgressBar from "@components/common/progressBar/ProgressBar";
import useLearning from "@hooks/useLearning";
import LearnTaleKeys from "./LearnTaleKeys";
import ChoiceQuiz from "./ChoiceQuiz";
import EssayQuiz from "./EssayQuiz";
import SentenceQuiz from "./SentenceQuiz";
import { Wrapper } from "./learn.styled";
import {
EssayQuestions,
MultipleChoices,
QuizData,
SentenceArrangements,
} from "@type/learning";
import { QUIZ_STAGES, QuizType } from "@utils/constants/QuizStage";

interface TaleLearnProps {
quizData?: QuizData;
}

const TaleLearn = ({ quizData }: TaleLearnProps) => {
if (!quizData) {
return;
}

const totalSteps = quizData.totalSteps;

const TaleLearn = () => {
const {
setChoice,
choice,
setSentence,
essay,
setEssay,
currentStep,
isLastStep,
isNextBtnActive,
handleNextStep,
} = useLearning();
getCurrentQuizType,
isQuizGraded,
} = useLearning(quizData);

const progressPercentage = (currentStep / (totalSteps - 1)) * 100;

const progressPercentage =
currentStep ===0
? 5
: (currentStep)*16.7
const getCurrentQuiz = () => {
if (
currentStep <
QUIZ_STAGES[QuizType.MultipleChoice].end(quizData.multipleChoices.length)
) {
return quizData.multipleChoices[currentStep];
} else if (
currentStep <
QUIZ_STAGES[QuizType.Essay].end(
quizData.multipleChoices.length,
quizData.essayQuestions.length
)
) {
return quizData.essayQuestions[
currentStep - quizData.multipleChoices.length
];
} else {
return quizData.sentenceArrangements[
currentStep -
QUIZ_STAGES[QuizType.Essay].end(
quizData.multipleChoices.length,
quizData.essayQuestions.length
)
];
}
};

const isMultipleChoice = (quiz: any): quiz is MultipleChoices =>
"choiceList" in quiz;
const isEssayQuestion = (quiz: any): quiz is EssayQuestions =>
"answer" in quiz;
const isSentenceArrangement = (quiz: any): quiz is SentenceArrangements =>
"sequenceList" in quiz;

const currentQuiz = getCurrentQuiz();
const currentQuizType = getCurrentQuizType(currentStep);

return (
<>
{currentStep < 7 ? (
{currentStep < totalSteps ? (
<Wrapper>
<ProgressBar percentage={progressPercentage} />
{currentStep === 0 && <LearnTaleKeys />}
{(currentStep === 1 || currentStep === 2) && (
<ChoiceQuiz setter={setChoice} currentStep={currentStep} />
)}
{(currentStep === 3 || currentStep === 4) && choice && (
<EssayQuiz
setter={setEssay}
currentStep={currentStep}
answer="사랑"
/>
)}
{(currentStep === 5 || currentStep === 6) && choice && essay && (
<SentenceQuiz
setter={setSentence}
currentStep={currentStep}
quizData={{
question: "그들은 함께 왕국의 귀환을 축하했다.",
sequenceList: [
{ word: "Together,", order: 1 },
{ word: "they celebrated", order: 2 },
{ word: "the return", order: 3 },
{ word: "of their kingdom.", order: 4 },
],
}}
/>
{/* {currentStep === 0 && <LearnTaleKeys />} */}
{currentQuiz && currentQuiz.question && (
<>
{currentQuizType === QuizType.MultipleChoice &&
isMultipleChoice(currentQuiz) && (
<ChoiceQuiz
setter={setChoice}
data={currentQuiz}
isQuizGraded={isQuizGraded}
/>
)}
{currentQuizType === QuizType.Essay &&
isEssayQuestion(currentQuiz) && (
<EssayQuiz
setter={setEssay}
data={currentQuiz}
isQuizGraded={isQuizGraded}
/>
)}
{currentQuizType === QuizType.SentenceArrangement &&
isSentenceArrangement(currentQuiz) && (
<SentenceQuiz
setter={setSentence}
data={currentQuiz}
isQuizGraded={isQuizGraded}
/>
)}
</>
)}
<NextBtn
isActive={isNextBtnActive}
Expand Down
Loading

0 comments on commit 9f8ddb1

Please sign in to comment.