Updated the Exercise count for the Interactive Speaking as well
This commit is contained in:
@@ -11,7 +11,16 @@ const ReactMediaRecorder = dynamic(() => import("react-media-recorder").then((mo
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export default function InteractiveSpeaking({id, title, text, type, prompts, onNext, onBack}: InteractiveSpeakingExercise & CommonProps) {
|
||||
export default function InteractiveSpeaking({
|
||||
id,
|
||||
title,
|
||||
text,
|
||||
type,
|
||||
prompts,
|
||||
updateIndex,
|
||||
onNext,
|
||||
onBack,
|
||||
}: InteractiveSpeakingExercise & CommonProps) {
|
||||
const [recordingDuration, setRecordingDuration] = useState(0);
|
||||
const [isRecording, setIsRecording] = useState(false);
|
||||
const [mediaBlob, setMediaBlob] = useState<string>();
|
||||
@@ -20,6 +29,10 @@ export default function InteractiveSpeaking({id, title, text, type, prompts, onN
|
||||
|
||||
const hasExamEnded = useExamStore((state) => state.hasExamEnded);
|
||||
|
||||
useEffect(() => {
|
||||
if (updateIndex) updateIndex(promptIndex);
|
||||
}, [promptIndex, updateIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasExamEnded) {
|
||||
onNext({
|
||||
|
||||
@@ -57,6 +57,14 @@ export const renderExercise = (
|
||||
case "speaking":
|
||||
return <Speaking key={exercise.id} {...(exercise as SpeakingExercise)} onNext={onNext} onBack={onBack} />;
|
||||
case "interactiveSpeaking":
|
||||
return <InteractiveSpeaking key={exercise.id} {...(exercise as InteractiveSpeakingExercise)} onNext={onNext} onBack={onBack} />;
|
||||
return (
|
||||
<InteractiveSpeaking
|
||||
key={exercise.id}
|
||||
{...(exercise as InteractiveSpeakingExercise)}
|
||||
updateIndex={updateIndex}
|
||||
onNext={onNext}
|
||||
onBack={onBack}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function Level({exam, showSolutions = false, onFinish}: Props) {
|
||||
<div className="flex flex-col h-full w-full gap-8 items-center">
|
||||
<ModuleTitle
|
||||
minTimer={exam.minTimer}
|
||||
exerciseIndex={exerciseIndex + (exerciseIndex === -1 ? 0 : 1) + questionIndex + currentQuestionIndex}
|
||||
exerciseIndex={exerciseIndex + 1 + questionIndex + currentQuestionIndex}
|
||||
module="level"
|
||||
totalExercises={countExercises(exam.exercises)}
|
||||
disableTimer={showSolutions}
|
||||
|
||||
@@ -20,14 +20,21 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function Speaking({exam, showSolutions = false, onFinish}: Props) {
|
||||
const [questionIndex, setQuestionIndex] = useState(0);
|
||||
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
||||
const [exerciseIndex, setExerciseIndex] = useState(0);
|
||||
const [userSolutions, setUserSolutions] = useState<UserSolution[]>(exam.exercises.map((x) => defaultUserSolutions(x, exam)));
|
||||
const [hasExamEnded, setHasExamEnded] = useExamStore((state) => [state.hasExamEnded, state.setHasExamEnded]);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentQuestionIndex(0);
|
||||
}, [questionIndex]);
|
||||
|
||||
const nextExercise = (solution?: UserSolution) => {
|
||||
if (solution) {
|
||||
setUserSolutions((prev) => [...prev.filter((x) => x.exercise !== solution.exercise), solution]);
|
||||
}
|
||||
setQuestionIndex((prev) => prev + currentQuestionIndex);
|
||||
|
||||
if (exerciseIndex + 1 < exam.exercises.length) {
|
||||
setExerciseIndex((prev) => prev + 1);
|
||||
@@ -71,7 +78,7 @@ export default function Speaking({exam, showSolutions = false, onFinish}: Props)
|
||||
<ModuleTitle
|
||||
label={convertCamelCaseToReadable(exam.exercises[exerciseIndex].type)}
|
||||
minTimer={exam.minTimer}
|
||||
exerciseIndex={exerciseIndex + 1}
|
||||
exerciseIndex={exerciseIndex + 1 + questionIndex + currentQuestionIndex}
|
||||
module="speaking"
|
||||
totalExercises={countExercises(exam.exercises)}
|
||||
disableTimer={showSolutions}
|
||||
@@ -79,11 +86,11 @@ export default function Speaking({exam, showSolutions = false, onFinish}: Props)
|
||||
{exerciseIndex > -1 &&
|
||||
exerciseIndex < exam.exercises.length &&
|
||||
!showSolutions &&
|
||||
renderExercise(getExercise(), nextExercise, previousExercise)}
|
||||
renderExercise(getExercise(), nextExercise, previousExercise, setCurrentQuestionIndex)}
|
||||
{exerciseIndex > -1 &&
|
||||
exerciseIndex < exam.exercises.length &&
|
||||
showSolutions &&
|
||||
renderSolution(exam.exercises[exerciseIndex], nextExercise, previousExercise)}
|
||||
renderSolution(exam.exercises[exerciseIndex], nextExercise, previousExercise, setCurrentQuestionIndex)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -259,15 +259,6 @@ export default function ExamPage({page}: Props) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{capitalize(page).toString()} | EnCoach</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<ToastContainer />
|
||||
{user && (
|
||||
<Layout
|
||||
|
||||
@@ -4,6 +4,7 @@ import {withIronSessionSsr} from "iron-session/next";
|
||||
import {sessionOptions} from "@/lib/session";
|
||||
import {shouldRedirectHome} from "@/utils/navigation.disabled";
|
||||
import ExamPage from "./(exam)/ExamPage";
|
||||
import Head from "next/head";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
const user = req.session.user;
|
||||
@@ -36,5 +37,18 @@ export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
}, sessionOptions);
|
||||
|
||||
export default function Page() {
|
||||
return <ExamPage page="exams" />;
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Exams | EnCoach</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<ExamPage page="exams" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import {withIronSessionSsr} from "iron-session/next";
|
||||
import {sessionOptions} from "@/lib/session";
|
||||
import {shouldRedirectHome} from "@/utils/navigation.disabled";
|
||||
import ExamPage from "./(exam)/ExamPage";
|
||||
import Head from "next/head";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
const user = req.session.user;
|
||||
@@ -36,5 +37,18 @@ export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
}, sessionOptions);
|
||||
|
||||
export default function Page() {
|
||||
return <ExamPage page="exercises" />;
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Exercises | EnCoach</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<ExamPage page="exercises" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user