Files
examjam-frontend/context/ExamContext.tsx
shafin-r b112a8fdac fix(api): fix api logic for exam screen
needs more work for the timercontext
2025-08-31 02:20:55 +06:00

101 lines
2.7 KiB
TypeScript

"use client";
import React, { createContext, useContext, useState } from "react";
import { Test, Answer } from "@/types/exam";
import { API_URL } from "@/lib/auth";
import { getToken } from "@/lib/auth";
interface ExamContextType {
test: Test | null;
answers: Answer[];
startExam: (testType: string, testId: string) => Promise<void>;
setAnswer: (questionIndex: number, answer: Answer) => void;
submitExam: () => Promise<void>;
cancelExam: () => void;
}
const ExamContext = createContext<ExamContextType | undefined>(undefined);
export const ExamProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [test, setTest] = useState<Test | null>(null);
const [answers, setAnswers] = useState<Answer[]>([]);
// start exam
const startExam = async (testType: string, testId: string) => {
try {
const token = await getToken(); // if needed
const res = await fetch(`${API_URL}/tests/${testType}/${testId}`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) throw new Error(`Failed to fetch test: ${res.status}`);
const data: Test = await res.json();
setTest(data);
setAnswers(Array(data.questions.length).fill(null));
} catch (err) {
console.error("startExam error:", err);
}
};
// update answer
const setAnswer = (questionIndex: number, answer: Answer) => {
setAnswers((prev) => {
const updated = [...prev];
updated[questionIndex] = answer;
return updated;
});
};
// submit exam
const submitExam = async () => {
if (!test) return;
const token = await getToken();
try {
const { type, test_id, attempt_id } = test.metadata;
const res = await fetch(
`${API_URL}/tests/${type}/${test_id}/${attempt_id}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
authorization: `Bearer ${token}`,
},
body: JSON.stringify({ answers }),
}
);
if (!res.ok) throw new Error("Failed to submit exam");
// clear
setTest(null);
setAnswers([]);
} catch (err) {
console.error("Failed to submit exam. Reason:", err);
}
};
// cancel exam
const cancelExam = () => {
setTest(null);
setAnswers([]);
};
return (
<ExamContext.Provider
value={{ test, answers, startExam, setAnswer, submitExam, cancelExam }}
>
{children}
</ExamContext.Provider>
);
};
export const useExam = (): ExamContextType => {
const ctx = useContext(ExamContext);
if (!ctx) throw new Error("useExam must be used inside ExamProvider");
return ctx;
};