diff --git a/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/FillInTheBlanks.tsx b/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/FillInTheBlanks.tsx index 09fa9f787..7d8d3e779 100644 --- a/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/FillInTheBlanks.tsx +++ b/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/FillInTheBlanks.tsx @@ -1,85 +1,21 @@ -import { useState } from "react"; - import Viewer from "~/components/RichText/Viever"; import { Card } from "~/components/ui/card"; -import { FillInTheTextBlanks } from "~/modules/Courses/Lesson/Question/FillInTheBlanks/FillInTheTextBlanks"; -import { TextBlank } from "~/modules/Courses/Lesson/Question/FillInTheBlanks/TextBlank"; -import { handleCompletionForMediaLesson } from "~/utils/handleCompletionForMediaLesson"; -import type { QuizQuestion } from "~/modules/Courses/Lesson/Question/types"; +import { FillInTheTextBlanks } from "./FillInTheTextBlanks"; +import { TextBlank } from "./TextBlank"; -type Answer = { - id: string; - optionText: string; - displayOrder: number | null; - isStudentAnswer?: boolean | null; - isCorrect?: boolean | null; - studentAnswerText?: string | null; -}; +import type { QuizQuestion } from "../types"; type FillInTheBlanksProps = { question: QuizQuestion; - isQuizSubmitted?: boolean; - lessonItemId: string; isCompleted: boolean; }; -type Word = { - index: number | null; - value: string | null; -}; - -export const FillInTheBlanks = ({ - question, - isQuizSubmitted, - isCompleted, -}: FillInTheBlanksProps) => { - const [_words, setWords] = useState( - question.options!.map(({ displayOrder, studentAnswer }) => ({ - index: displayOrder, - value: studentAnswer, - })), - ); - - if (!question.description || !question.options?.length) return null; - +export const FillInTheBlanks = ({ question, isCompleted }: FillInTheBlanksProps) => { const solutionExplanation = "solutionExplanation" in question ? (question.solutionExplanation as string) : null; - const maxAnswersAmount = question.description?.match(/\[word]/g)?.length ?? 0; - const handleWordUpdate = (prevWords: Word[], index: number, value: string) => { - const trimmedValue = value.trim(); - const existingWordIndex = prevWords.findIndex((word) => word.index === index); - - let updatedWords = prevWords; - - if (trimmedValue === "") { - updatedWords = - existingWordIndex !== -1 ? prevWords.filter((word) => word.index !== index) : prevWords; - } else if (existingWordIndex !== -1) { - updatedWords = [...prevWords]; - updatedWords[existingWordIndex] = { index, value: trimmedValue }; - } else if (prevWords.length < maxAnswersAmount) { - updatedWords = [...prevWords, { index, value: trimmedValue }]; - } - - const sortedWords = updatedWords.sort((a, b) => a.index - b.index); - - if (sortedWords.length > 0 && sortedWords.length <= maxAnswersAmount) { - if ( - handleCompletionForMediaLesson(isCompleted, true) && - sortedWords.length === maxAnswersAmount - ) { - // TODO: handle completion - } - } - - return updatedWords; - }; - - const handleOnBlur = (value: string, index: number) => { - setWords((prev) => handleWordUpdate(prev, index, value)); - }; + if (!question.description) return null; return ( @@ -90,15 +26,15 @@ export const FillInTheBlanks = ({ replacement={(index) => { return ( ); }} /> - {!!solutionExplanation && !question.passQuestion && ( + {isCompleted && !!solutionExplanation && question.passQuestion && (
Correct sentence: diff --git a/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/TextBlank.tsx b/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/TextBlank.tsx index b8211d3b0..a618601df 100644 --- a/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/TextBlank.tsx +++ b/apps/web/app/modules/Courses/Lesson/Question/FillInTheBlanks/TextBlank.tsx @@ -1,34 +1,33 @@ import { useEffect, useRef } from "react"; +import { useFormContext } from "react-hook-form"; import { cn } from "~/lib/utils"; +import type { QuizQuestionOption } from "../types"; +import type { TQuestionsForm } from "~/modules/Courses/Lesson/types"; + type TextBlankProps = { index: number; - studentAnswer?: { - id: string; - optionText: string; - displayOrder: number | null; - isStudentAnswer?: boolean | null; - isCorrect?: boolean | null; - studentAnswerText?: string | null; - }; - handleOnBlur: (value: string, index: number) => void; + studentAnswer?: QuizQuestionOption; isQuizSubmitted?: boolean; + questionId: string; }; export const TextBlank = ({ index, studentAnswer, - handleOnBlur, isQuizSubmitted, + questionId, }: TextBlankProps) => { + const { register } = useFormContext(); const inputRef = useRef(null); + const formFieldId = `${index + 1}`; useEffect(() => { if (!inputRef?.current) return; if (isQuizSubmitted) { - inputRef.current.value = studentAnswer?.studentAnswerText ?? ""; + inputRef.current.value = studentAnswer?.studentAnswer ?? ""; } else { inputRef.current.value = ""; } @@ -51,18 +50,11 @@ export const TextBlank = ({ return ( { - const value = e.target.value; - - handleOnBlur(value, index); - }, - })} + {...register(`fillInTheBlanksText.${questionId}.${formFieldId}`)} /> ); }; diff --git a/apps/web/app/modules/Courses/Lesson/Question/Question.tsx b/apps/web/app/modules/Courses/Lesson/Question/Question.tsx index 2aa90f235..6c96822e6 100644 --- a/apps/web/app/modules/Courses/Lesson/Question/Question.tsx +++ b/apps/web/app/modules/Courses/Lesson/Question/Question.tsx @@ -69,14 +69,7 @@ export const Question = ({ isSubmitted, question, isCompleted }: QuestionProps) return ; case isTextFillInTheBlanks: - return ( - - ); + return ; case isDraggableFillInTheBlanks: return ( @@ -94,6 +87,7 @@ export const Question = ({ isSubmitted, question, isCompleted }: QuestionProps) updateLessonItemCompletion={() => {}} /> ); + case isSingleQuestion: return ; diff --git a/apps/web/app/modules/Courses/Lesson/Quiz.tsx b/apps/web/app/modules/Courses/Lesson/Quiz.tsx index ef1d224af..87caf561a 100644 --- a/apps/web/app/modules/Courses/Lesson/Quiz.tsx +++ b/apps/web/app/modules/Courses/Lesson/Quiz.tsx @@ -1,4 +1,4 @@ -import { useParams } from "@remix-run/react"; +import { useNavigate, useParams } from "@remix-run/react"; import { FormProvider, useForm } from "react-hook-form"; import { useSubmitQuiz } from "~/api/mutations"; @@ -95,6 +95,25 @@ function transformData(input: TQuestionsForm) { } } + for (const questionId in input.fillInTheBlanksText) { + const answers = input.fillInTheBlanksText[questionId]; + const answerArray = []; + + for (const [key, value] of Object.entries(answers)) { + if (answers[key]) { + answerArray.push({ + value, + }); + } + } + if (answerArray.length > 0) { + result.push({ + questionId: questionId, + answer: answerArray, + }); + } + } + for (const questionId in input.photoQuestionMultipleChoice) { const answers = input.photoQuestionMultipleChoice[questionId]; const answerArray = []; @@ -140,7 +159,8 @@ function transformData(input: TQuestionsForm) { } export const Quiz = ({ lesson }: QuizProps) => { - const { lessonId = "" } = useParams(); + const { lessonId = "", courseId = "" } = useParams(); + const navigate = useNavigate(); const questions = lesson.quizDetails?.questions; @@ -151,7 +171,7 @@ export const Quiz = ({ lesson }: QuizProps) => { const submitQuiz = useSubmitQuiz({ handleOnSuccess: () => { - // TODO: Add logic to handle success + navigate(`/course/${courseId}/lesson/${lesson.nextLessonId}`); }, }); diff --git a/apps/web/app/modules/Courses/Lesson/types.ts b/apps/web/app/modules/Courses/Lesson/types.ts index 392636214..1fb5f599a 100644 --- a/apps/web/app/modules/Courses/Lesson/types.ts +++ b/apps/web/app/modules/Courses/Lesson/types.ts @@ -26,4 +26,9 @@ export type TQuestionsForm = { [key: string]: string | null; }; }; + fillInTheBlanksText: { + [key: string]: { + [key: string]: string | null; + }; + }; }; diff --git a/apps/web/app/modules/Courses/Lesson/utils.ts b/apps/web/app/modules/Courses/Lesson/utils.ts index 2f9aea5d6..c6524edee 100644 --- a/apps/web/app/modules/Courses/Lesson/utils.ts +++ b/apps/web/app/modules/Courses/Lesson/utils.ts @@ -70,6 +70,12 @@ const prepareAnswers = (questions: Questions, mode: "options" | "open"): Record< ); } + if (question.type === "fill_in_the_blanks_text") { + result[question.id ?? ""] = question?.options?.map(({ studentAnswer }, index) => { + return { [`${index + 1}`]: studentAnswer ?? null }; + }); + } + if (mode === "options") { result[question.id ?? ""] = question?.options?.reduce( (optionMap, option) => {