Exam Edit on ExamList

This commit is contained in:
Carlos-Mesquita
2024-11-27 02:01:50 +00:00
parent ca5977e78b
commit a2a513077f
13 changed files with 199 additions and 53 deletions

View File

@@ -24,6 +24,7 @@ import useExamTimer from "@/hooks/useExamTimer";
import ProgressButtons from "../components/ProgressButtons";
import useExamNavigation from "../Navigation/useExamNavigation";
import { calculateExerciseIndex } from "../utils/calculateExerciseIndex";
import { defaultExamUserSolutions } from "@/utils/exams";
const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, preview = false }) => {
@@ -55,7 +56,6 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
const { finalizeModule, timeIsUp } = flags;
const timer = useRef(exam.minTimer - timeSpentCurrentModule / 60);
const [isFirstTimeRender, setIsFirstTimeRender] = useState(partIndex === 0 && exerciseIndex == 0 && !showSolutions);
// In case client want to switch back
const textRenderDisabled = true;
@@ -92,12 +92,12 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
const {
nextExercise, previousExercise,
showPartDivider, setShowPartDivider,
seenParts, setSeenParts,
seenParts, setSeenParts, startNow
} = useExamNavigation(
{
exam, module: "level", showBlankModal: showQuestionsModal,
setShowBlankModal: setShowQuestionsModal, showSolutions,
preview, disableBetweenParts: true, modalBetweenParts: true ,modalKwargs
preview, disableBetweenParts: true, modalBetweenParts: true, modalKwargs
}
);
@@ -106,6 +106,13 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
setSolutionWasUpdated(true);
}, []);
useEffect(() => {
if (preview) {
setUserSolutions(defaultExamUserSolutions(exam));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const [contextWords, setContextWords] = useState<{ match: string, originalLine: string }[] | undefined>(undefined);
const [contextWordLines, setContextWordLines] = useState<number[] | undefined>(undefined);
const [totalLines, setTotalLines] = useState<number>(0);
@@ -351,17 +358,17 @@ const Level: React.FC<ExamProps<LevelExam>> = ({ exam, showSolutions = false, pr
</Modal>
<QuestionsModal isOpen={showQuestionsModal} {...questionModalKwargs} />
{
!(partIndex === 0 && questionIndex === 0 && (showPartDivider || isFirstTimeRender)) &&
(!showPartDivider && !startNow) &&
<Timer minTimer={exam.minTimer} disableTimer={showSolutions || preview} standalone={true} />
}
{(showPartDivider || isFirstTimeRender) ?
{(showPartDivider || startNow) ?
<PartDivider
module="level"
sectionLabel="Part"
defaultTitle="Placement Test"
section={exam.parts[partIndex]}
sectionIndex={partIndex}
onNext={() => { setShowPartDivider(false); setIsFirstTimeRender(false); setBgColor("bg-white"); setSeenParts(prev => new Set(prev).add(partIndex)); }}
onNext={() => { setShowPartDivider(false); setBgColor("bg-white"); setSeenParts(prev => new Set(prev).add(partIndex)); }}
/> : (
<>
{exam.parts.length > 1 && <SectionNavbar

View File

@@ -90,6 +90,7 @@ const Listening: React.FC<ExamProps<ListeningExam>> = ({ exam, showSolutions = f
: (!startNow && !showPartDivider && !isBetweenParts && !showSolutions) && renderExercise(e, exam.id, registerSolution, preview))}
</div>
)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [partIndex, startNow, showPartDivider, isBetweenParts, showSolutions]);
@@ -128,6 +129,7 @@ const Listening: React.FC<ExamProps<ListeningExam>> = ({ exam, showSolutions = f
timesListened={timesListened}
setShowTextModal={setShowTextModal}
setTimesListened={setTimesListened}
// eslint-disable-next-line react-hooks/exhaustive-deps
/>, [partIndex, assignment, timesListened, setShowTextModal, setTimesListened])
const memoizedInstructions = useMemo(()=>

View File

@@ -30,7 +30,22 @@ const PartDivider: React.FC<Props> = ({ sectionIndex, sectionLabel, section, mod
<div className={`w-12 h-12 bg-ielts-${module} flex items-center justify-center rounded-lg`}>{moduleIcon[module]}</div>
<p className="text-3xl">{section.intro ? `${sectionLabel} ${sectionIndex + 1}` : defaultTitle}</p>
</div>
{section.intro && section.intro.split('\\n\\n').map((x, index) => <p key={`line-${index}`} className="text-2xl text-clip" dangerouslySetInnerHTML={{ __html: x.replace('that is not correct', 'that is <span class="font-bold"><u>not correct</u></span>') }}></p>)}
{section.intro && section.intro
.replace(/\\n/g, '\n')
.split('\n')
.map((x, index) => (
<p
key={`line-${index}`}
className="text-2xl text-clip"
dangerouslySetInnerHTML={{
__html: x.replace(
'that is not correct',
'that is <span class="font-bold"><u>not correct</u></span>'
)
}}
></p>
))
}
<div className="flex items-center justify-center mt-4">
<button
onClick={() => onNext()}

View File

@@ -17,7 +17,6 @@ type PartExam = {
const answeredEveryQuestionInPart = (exam: PartExam, partIndex: number, userSolutions: UserSolution[]) => {
return exam.parts[partIndex].exercises.every((exercise) => {
const userSolution = userSolutions.find(x => x.exercise === exercise.id);
switch (exercise.type) {
case 'multipleChoice':
return userSolution?.solutions.length === exercise.questions!.length;