generated from muhtadeetaron/nextjs-template
94 lines
3.0 KiB
TypeScript
94 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect, useCallback } from "react";
|
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
import Header from "@/components/Header";
|
|
import QuestionItem from "@/components/QuestionItem";
|
|
import BackgroundWrapper from "@/components/BackgroundWrapper";
|
|
import { useExamStore } from "@/stores/examStore";
|
|
import { useTimerStore } from "@/stores/timerStore";
|
|
|
|
export default function ExamPage() {
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
const test_id = searchParams.get("test_id") || "";
|
|
const type = searchParams.get("type") || "";
|
|
|
|
const { test, answers, startExam, setAnswer, submitExam, cancelExam } =
|
|
useExamStore();
|
|
const { resetTimer, stopTimer } = useTimerStore();
|
|
|
|
// Start exam + timer automatically
|
|
useEffect(() => {
|
|
if (type && test_id) {
|
|
startExam(type, test_id).then((fetchedTest) => {
|
|
if (fetchedTest?.metadata.time_limit_minutes) {
|
|
resetTimer(fetchedTest.metadata.time_limit_minutes * 60, () => {
|
|
// Timer ended → auto-submit exam
|
|
submitExam(type);
|
|
router.push(`/categories/${type}s`);
|
|
alert("Time's up! Your exam has been submitted.");
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}, [type, test_id, startExam, resetTimer, submitExam, router]);
|
|
|
|
const showExitDialog = useCallback(() => {
|
|
if (window.confirm("Are you sure you want to quit the exam?")) {
|
|
stopTimer();
|
|
cancelExam();
|
|
router.push(`/categories/${type}s`);
|
|
}
|
|
}, [stopTimer, cancelExam, router, type]);
|
|
|
|
if (!test) {
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
|
<div className="flex flex-col items-center justify-center">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-900 mb-4"></div>
|
|
<p className="text-lg font-medium text-gray-900">Loading exam...</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const handleSubmitExam = (type: string) => {
|
|
submitExam(type);
|
|
router.push(`/categories/${type}s`);
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50">
|
|
{/* Header with live timer */}
|
|
<Header />
|
|
|
|
{/* Questions */}
|
|
<BackgroundWrapper>
|
|
<div className="container mx-auto px-6 py-8 mb-20">
|
|
{test.questions.map((q, idx) => (
|
|
<div id={`question-${idx}`} key={q.question_id}>
|
|
<QuestionItem
|
|
question={q}
|
|
index={idx}
|
|
selectedAnswer={answers[idx]}
|
|
onSelect={(answer) => setAnswer(idx, answer)}
|
|
/>
|
|
</div>
|
|
))}
|
|
|
|
{/* Bottom submit bar */}
|
|
<div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 flex">
|
|
<button
|
|
onClick={() => handleSubmitExam(type)}
|
|
className="flex-1 bg-blue-900 text-white p-6 font-bold text-lg hover:bg-blue-800 transition-colors"
|
|
>
|
|
Submit
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</BackgroundWrapper>
|
|
</div>
|
|
);
|
|
}
|