import { Badge } from '@/components/ui/badge'; import { Card, CardContent } from '@/components/ui/card'; import { router } from '@inertiajs/react'; import { AlertTriangle, Clock } from 'lucide-react'; import { useEffect, useState } from 'react'; interface Props { endTime: string; onTimeUp?: () => void; attempt: ExamAttempt; questionIndex: number; } const TimerComponent = ({ endTime, onTimeUp, attempt, questionIndex }: Props) => { const [timeLeft, setTimeLeft] = useState(0); const [isWarning, setIsWarning] = useState(false); useEffect(() => { const calculateTimeLeft = () => { if (!endTime) { return 0; } const end = new Date(endTime).getTime(); if (Number.isNaN(end)) { return 0; } const now = new Date().getTime(); const difference = end - now; return Math.max(0, Math.floor(difference / 1000)); }; setTimeLeft(calculateTimeLeft()); const interval = setInterval(() => { const remaining = calculateTimeLeft(); setTimeLeft(remaining); // Warning at 5 minutes if (remaining <= 300 && remaining > 0) { setIsWarning(true); } // Auto-submit when time is up if (remaining === 0) { clearInterval(interval); if (onTimeUp) { onTimeUp(); } else { router.post(route('exam-attempts.submit', attempt.id)); } } }, 1000); return () => clearInterval(interval); }, [endTime, attempt.id, onTimeUp]); const formatTime = (seconds: number) => { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; }; return (
{isWarning ? : } Time Remaining
{formatTime(timeLeft)}

Question {questionIndex + 1} of {attempt.exam.questions.length}

{isWarning && (

Less than 5 minutes remaining! The exam will auto-submit when time runs out.

)}
); }; export default TimerComponent;