diff --git a/package.json b/package.json index 2de35684..ef580cc0 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "react-player": "^2.12.0", "react-string-replace": "^1.1.0", "react-toastify": "^9.1.2", + "react-xarrows": "^2.0.2", "swr": "^2.1.3", "typescript": "4.9.5", "uuid": "^9.0.0", diff --git a/src/components/Exercises/MatchSentences.tsx b/src/components/Exercises/MatchSentences.tsx index 8220af51..fca9da97 100644 --- a/src/components/Exercises/MatchSentences.tsx +++ b/src/components/Exercises/MatchSentences.tsx @@ -7,6 +7,7 @@ import {Fragment, useState} from "react"; import LineTo from "react-lineto"; import {CommonProps} from "."; import Button from "../Low/Button"; +import Xarrow from "react-xarrows"; export default function MatchSentences({id, options, type, prompt, sentences, userSolutions, onNext, onBack}: MatchSentencesExercise & CommonProps) { const [selectedQuestion, setSelectedQuestion] = useState(); @@ -32,8 +33,8 @@ export default function MatchSentences({id, options, type, prompt, sentences, us return ( <> -
- +
+ {prompt.split("\\n").map((line, index) => ( {line} @@ -41,55 +42,44 @@ export default function MatchSentences({id, options, type, prompt, sentences, us ))} -
-
+
+
{sentences.map(({sentence, id, color}) => ( -
setSelectedQuestion((prev) => (prev === id ? undefined : id))}> - - {id}. {sentence}{" "} - -
+
+ {sentence} +
))}
-
+
{options.map(({sentence, id}) => ( -
selectOption(id)}> -
x.option === id) - ? { - border: `2px solid ${getSentenceColor(answers.find((x) => x.option === id)!.question)}`, - } - : {} - } - className={clsx("border-2 border-green-500 bg-transparent w-4 h-4 rounded-full", id)} - /> - - {id}. {sentence}{" "} - +
+ + {sentence}
))}
{answers.map((solution, index) => ( -
- x.id === solution.question)!.color} - borderWidth={5} - /> -
+ ))}
diff --git a/src/components/Medium/ModuleTitle.tsx b/src/components/Medium/ModuleTitle.tsx index e36a32f3..68c8f384 100644 --- a/src/components/Medium/ModuleTitle.tsx +++ b/src/components/Medium/ModuleTitle.tsx @@ -7,12 +7,13 @@ import ProgressBar from "../Low/ProgressBar"; interface Props { minTimer: number; module: Module; + label?: string; exerciseIndex: number; totalExercises: number; disableTimer?: boolean; } -export default function ModuleTitle({minTimer, module, exerciseIndex, totalExercises, disableTimer = false}: Props) { +export default function ModuleTitle({minTimer, module, label, exerciseIndex, totalExercises, disableTimer = false}: Props) { const [timer, setTimer] = useState(minTimer * 60); useEffect(() => { @@ -55,7 +56,9 @@ export default function ModuleTitle({minTimer, module, exerciseIndex, totalExerc
{moduleIcon[module]}
- {moduleLabels[module]} exam + + {moduleLabels[module]} exam {label && `- ${label}`} + Question {exerciseIndex}/{totalExercises} diff --git a/src/components/Solutions/FillBlanks.tsx b/src/components/Solutions/FillBlanks.tsx index 2a792820..7cd8fe4f 100644 --- a/src/components/Solutions/FillBlanks.tsx +++ b/src/components/Solutions/FillBlanks.tsx @@ -82,6 +82,17 @@ export default function FillBlanksSolutions({prompt, solutions, text, userSoluti

))} +
+
+
= Correct +
+
+
= Unanswered +
+
+
= Wrong +
+
diff --git a/src/components/Solutions/MatchSentences.tsx b/src/components/Solutions/MatchSentences.tsx index f37a8265..9a1daf00 100644 --- a/src/components/Solutions/MatchSentences.tsx +++ b/src/components/Solutions/MatchSentences.tsx @@ -7,12 +7,13 @@ import {mdiArrowLeft, mdiArrowRight} from "@mdi/js"; import Icon from "@mdi/react"; import {Fragment} from "react"; import Button from "../Low/Button"; +import Xarrow from "react-xarrows"; export default function MatchSentencesSolutions({options, prompt, sentences, userSolutions, onNext, onBack}: MatchSentencesExercise & CommonProps) { return ( <> -
- +
+ {prompt.split("\\n").map((line, index) => ( {line} @@ -20,48 +21,67 @@ export default function MatchSentencesSolutions({options, prompt, sentences, use ))} - -
-
- {sentences.map(({sentence, id, color, solution}) => ( -
x.question === id)?.option === solution ? "text-green-500" : "text-red-500", - )}> - - {id}. {sentence}{" "} - -
+
+
+ {sentences.map(({sentence, id, solution}) => ( +
+ {sentence} +
))}
-
+
{options.map(({sentence, id}) => (
-
x.solution === id) - ? { - border: `2px solid ${sentences.find((x) => x.solution === id)!.color}`, - } - : {} - } - className={clsx("border-2 border-green-500 bg-transparent w-4 h-4 rounded-full", id)} - /> - - {id}. {sentence}{" "} - + + {sentence}
))}
{sentences.map((sentence, index) => ( -
- -
+ x.question === sentence.id) + ? "#0696ff" + : userSolutions.find((x) => x.question === sentence.id)?.option === sentence.solution + ? "#307912" + : "#FF6000" + } + showHead={false} + /> ))}
+
+
+
= Correct +
+
+
= Unanswered +
+
+
= Wrong +
+
diff --git a/src/components/Solutions/MultipleChoice.tsx b/src/components/Solutions/MultipleChoice.tsx index ab37f062..afa3aac3 100644 --- a/src/components/Solutions/MultipleChoice.tsx +++ b/src/components/Solutions/MultipleChoice.tsx @@ -75,14 +75,27 @@ export default function MultipleChoice({prompt, questions, userSolutions, onNext return ( <> -
- {prompt} - {questionIndex < questions.length && ( - questions[questionIndex].id === x.question)?.option} - /> - )} +
+
+ {prompt} + {questionIndex < questions.length && ( + questions[questionIndex].id === x.question)?.option} + /> + )} +
+
+
+
= Correct +
+
+
= Unanswered +
+
+
= Wrong +
+
diff --git a/src/components/Solutions/WriteBlanks.tsx b/src/components/Solutions/WriteBlanks.tsx index fb1bc890..41f4ef84 100644 --- a/src/components/Solutions/WriteBlanks.tsx +++ b/src/components/Solutions/WriteBlanks.tsx @@ -110,6 +110,17 @@ export default function WriteBlanksSolutions({

))} +
+
+
= Correct +
+
+
= Unanswered +
+
+
= Wrong +
+
diff --git a/src/exams/Reading.tsx b/src/exams/Reading.tsx index 0fc9b4f0..8a04616b 100644 --- a/src/exams/Reading.tsx +++ b/src/exams/Reading.tsx @@ -4,6 +4,7 @@ import Icon from "@mdi/react"; import {mdiArrowRight, mdiNotebook} from "@mdi/js"; import clsx from "clsx"; import {infoButtonStyle} from "@/constants/buttonStyles"; +import {convertCamelCaseToReadable} from "@/utils/string"; import {Dialog, Transition} from "@headlessui/react"; import {renderExercise} from "@/components/Exercises"; import {renderSolution} from "@/components/Solutions"; @@ -148,6 +149,7 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props) module="reading" totalExercises={exam.exercises.length} disableTimer={showSolutions} + label={exerciseIndex === -1 ? undefined : convertCamelCaseToReadable(exam.exercises[exerciseIndex].type)} /> {exerciseIndex === -1 && renderText()} {exerciseIndex > -1 && diff --git a/yarn.lock b/yarn.lock index 6d8c1b37..2ff5c405 100644 --- a/yarn.lock +++ b/yarn.lock @@ -873,7 +873,7 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== -"@types/prop-types@*": +"@types/prop-types@*", "@types/prop-types@^15.7.3": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== @@ -3178,6 +3178,15 @@ react-transition-group@^4.4.1: loose-envify "^1.4.0" prop-types "^15.6.2" +react-xarrows@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/react-xarrows/-/react-xarrows-2.0.2.tgz#7555687612339eaefd4ed55fc5c63f2302726d9c" + integrity sha512-tDlAqaxHNmy0vegW/6NdhoWyXJq1LANX/WUAlHyzoHe9BwFVnJPPDghmDjYeVr7XWFmBrVTUrHsrW7GKYI6HtQ== + dependencies: + "@types/prop-types" "^15.7.3" + lodash "^4.17.21" + prop-types "^15.7.2" + react@17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"