"use client"; import { useRouter } from "next/navigation"; import { useExam, useExamResults } from "@/context/ExamContext"; import { useEffect, useState, useRef } from "react"; import React from "react"; import { ArrowLeft } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import Image from "next/image"; import SlidingGallery from "@/components/SlidingGallery"; interface Question { correctAnswer: string; id: number; question: string; options: Record; solution?: string; } interface QuestionItemProps { question: Question; selectedAnswer: string | undefined; } const QuestionItem = ({ question, selectedAnswer }: QuestionItemProps) => (

{question.id}. {question.question}

{!selectedAnswer ? ( Skipped ) : selectedAnswer.answer === question.correctAnswer ? ( Correct ) : ( Incorrect )}
{Object.entries(question.options).map(([key, value]) => { const isCorrect = key === question.correctAnswer; const isSelected = key === selectedAnswer?.answer; let optionStyle = "px-2 py-1 flex items-center rounded-full border font-medium text-sm"; if (isCorrect) { optionStyle += " bg-green-600 text-white border-green-600"; } if (isSelected && !isCorrect) { optionStyle += " bg-red-600 text-white border-red-600"; } if (!isCorrect && !isSelected) { optionStyle += " border-gray-300 text-gray-700"; } return (
{key.toUpperCase()} {value}
); })}

Solution:

{question.solution}

); export default function ResultsPage() { // All hooks at the top - no conditional calls const router = useRouter(); const { clearExam, isExamCompleted, getApiResponse } = useExam(); // Add a ref to track if we're in cleanup mode const isCleaningUp = useRef(false); // Conditionally call useExamResults based on cleanup state const examResults = !isCleaningUp.current ? useExamResults() : null; // State to control component behavior const [componentState, setComponentState] = useState< "loading" | "redirecting" | "ready" >("loading"); // Single useEffect to handle all initialization logic useEffect(() => { let mounted = true; const initializeComponent = async () => { // Allow time for all hooks to initialize await new Promise((resolve) => setTimeout(resolve, 50)); if (!mounted) return; // Check if exam is completed if (!isExamCompleted()) { setComponentState("redirecting"); // Small delay before redirect to prevent hook order issues setTimeout(() => { if (mounted) { router.push("/unit"); } }, 100); return; } // Check if we have exam results if (!examResults || !examResults.answers) { // Keep loading state return; } // Everything is ready setComponentState("ready"); }; initializeComponent(); return () => { mounted = false; }; }, [isExamCompleted, router, examResults]); // Always render loading screen for non-ready states if (componentState !== "ready") { const loadingText = componentState === "redirecting" ? "Redirecting..." : "Loading..."; return (

{loadingText}

); } // At this point, we know examResults exists and component is ready const apiResponse = getApiResponse(); const handleBackToHome = () => { // Set cleanup flag to prevent useExamResults from running isCleaningUp.current = true; clearExam(); setTimeout(() => { router.push("/unit"); }, 400); }; const timeTaken = examResults?.endTime && examResults?.startTime ? Math.round( (examResults.endTime.getTime() - examResults.startTime.getTime()) / 1000 / 60 ) : 0; const resultViews = [ { id: 1, content: (
Accuracy Rate:
accuracy

{examResults ? ( (examResults.score / examResults.totalQuestions) * 100 ).toFixed(1) : "0"} %

), }, { id: 2, content: (
Error Rate:
accuracy

{examResults ? ( ((examResults.totalQuestions - examResults.score) / examResults.totalQuestions) * 100 ).toFixed(1) : "0"} %

), }, { id: 3, content: (
Attempt Rate:
accuracy

{examResults ? ( (examResults.answers.length / examResults.totalQuestions) * 100 ).toFixed(1) : "0"} %

), }, ]; return (

{!examResults?.score || examResults?.score < 30 ? "Try harder!" : examResults?.score < 70 ? "Getting Better" : "You did great!"}

{/* Score Display */} {apiResponse && (

Solutions

{apiResponse.questions?.map((question) => ( ))}
)}
); }