Files
examjam-frontend/context/TimerContext.tsx
2025-08-31 17:45:08 +06:00

89 lines
2.1 KiB
TypeScript

"use client";
import React, {
createContext,
useContext,
useState,
useEffect,
useRef,
} from "react";
interface TimerContextType {
timeRemaining: number;
resetTimer: (duration: number) => void;
stopTimer: () => void;
setInitialTime: (duration: number) => void;
}
const TimerContext = createContext<TimerContextType | undefined>(undefined);
export const TimerProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [timeRemaining, setTimeRemaining] = useState<number>(0);
const timerRef = useRef<NodeJS.Timeout | null>(null);
// Effect: run interval whenever timeRemaining is set > 0
useEffect(() => {
if (timeRemaining > 0 && !timerRef.current) {
timerRef.current = setInterval(() => {
setTimeRemaining((prev) => {
if (prev <= 1) {
clearInterval(timerRef.current!);
timerRef.current = null;
return 0;
}
return prev - 1;
});
}, 1000);
}
return () => {
if (timerRef.current && timeRemaining <= 0) {
clearInterval(timerRef.current);
timerRef.current = null;
}
};
}, [timeRemaining]); // 👈 depend on timeRemaining
const resetTimer = (duration: number) => {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
setTimeRemaining(duration);
};
const stopTimer = () => {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
setTimeRemaining(0);
};
const setInitialTime = (duration: number) => {
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
setTimeRemaining(duration);
};
return (
<TimerContext.Provider
value={{ timeRemaining, resetTimer, stopTimer, setInitialTime }}
>
{children}
</TimerContext.Provider>
);
};
export const useTimer = (): TimerContextType => {
const context = useContext(TimerContext);
if (!context) {
throw new Error("useTimer must be used within a TimerProvider");
}
return context;
};