fix(ui): fix results screen

This commit is contained in:
shafin-r
2025-07-22 17:59:15 +06:00
parent 5245ab878d
commit 341a46e788
8 changed files with 450 additions and 323 deletions

View File

@ -7,6 +7,7 @@ import React, {
useEffect,
ReactNode,
} from "react";
import { useRouter } from "next/navigation";
import { Exam, ExamAnswer, ExamAttempt, ExamContextType } from "@/types/exam";
import { getFromStorage, removeFromStorage, setToStorage } from "@/lib/utils";
@ -21,6 +22,7 @@ const STORAGE_KEYS = {
export const ExamProvider: React.FC<{ children: ReactNode }> = ({
children,
}) => {
const router = useRouter();
const [currentExam, setCurrentExamState] = useState<Exam | null>(null);
const [currentAttempt, setCurrentAttemptState] = useState<ExamAttempt | null>(
null
@ -81,13 +83,14 @@ export const ExamProvider: React.FC<{ children: ReactNode }> = ({
const setCurrentExam = (exam: Exam) => {
setCurrentExamState(exam);
setCurrentAttemptState(null);
};
const startExam = () => {
if (!currentExam) {
throw new Error("No exam selected");
console.warn("No exam selected, redirecting to /unit");
router.push("/unit");
return;
}
const attempt: ExamAttempt = {
@ -103,7 +106,9 @@ export const ExamProvider: React.FC<{ children: ReactNode }> = ({
const setAnswer = (questionId: string, answer: any) => {
if (!currentAttempt) {
throw new Error("No exam attempt started");
console.warn("No exam attempt started, redirecting to /unit");
router.push("/unit");
return;
}
setCurrentAttemptState((prev) => {
@ -138,7 +143,9 @@ export const ExamProvider: React.FC<{ children: ReactNode }> = ({
const setApiResponse = (response: any) => {
if (!currentAttempt) {
throw new Error("No exam attempt started");
console.warn("No exam attempt started, redirecting to /unit");
router.push("/unit");
return;
}
setCurrentAttemptState((prev) => {
@ -150,9 +157,11 @@ export const ExamProvider: React.FC<{ children: ReactNode }> = ({
});
};
const submitExam = (): ExamAttempt => {
const submitExam = (): ExamAttempt | null => {
if (!currentAttempt) {
throw new Error("No exam attempt to submit");
console.warn("No exam attempt to submit, redirecting to /unit");
router.push("/unit");
return null;
}
// Calculate score (simple example - you can customize this)
@ -209,7 +218,7 @@ export const ExamProvider: React.FC<{ children: ReactNode }> = ({
const isExamStarted = () => !!currentExam && !!currentAttempt;
const isExamCompleted = (): boolean => {
if (!isHydrated) return false; // wait for hydration
if (!isHydrated) return false; // wait for hydration
return currentAttempt !== null && currentAttempt.endTime !== undefined;
};
@ -246,12 +255,18 @@ export const useExam = (): ExamContextType => {
return context;
};
// Hook for exam results (only when exam is completed)
export const useExamResults = (): ExamAttempt => {
const { currentAttempt, isExamCompleted } = useExam();
// Hook for exam results (only when exam is completed) - now returns null instead of throwing
export const useExamResults = (): ExamAttempt | null => {
const { currentAttempt, isExamCompleted, isHydrated } = useExam();
// Wait for hydration before making decisions
if (!isHydrated) {
return null;
}
// If no completed exam is found, return null (let component handle redirect)
if (!isExamCompleted() || !currentAttempt) {
throw new Error("No completed exam attempt found");
return null;
}
return currentAttempt;