import AlertTriangle from 'lucide-react/dist/esm/icons/alert-triangle' import Maximize from 'lucide-react/dist/esm/icons/maximize' import Spinner from '../components/shared/Spinner' import Calculator from '../components/test/Calculator' import QuestionView from '../components/test/QuestionView' import TestHeader from '../components/test/TestHeader' import TestSidebar from '../components/test/TestSidebar' import TimerDisplay from '../components/test/TimerDisplay' import useTestEngine from '../hooks/useTestEngine' import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' function LoadingScreen() { return (
) } function InstructionScreen({ accepted, beginTest, navigate, setAccepted, starting, test, }) { return (
General Instructions

{test?.title}

{[ ['Duration', `${test?.duration_minutes || 0} min`], ['Questions', test?.question_count || 0], ['Marks', test?.total_marks || 0], ].map(([label, value]) => (

{label}

{value}

))}

The test opens in fullscreen mode after you click Begin Test.

Leaving fullscreen or switching tabs may be counted as a violation.

The timer starts only after the attempt is created.

) } function EmptyQuestionsScreen({ navigate }) { return (

No Questions Available

This test does not have any questions to display.

) } function FullscreenWarning({ endTimeMs, fsViolations, handleTimerExpire, setShowConfirm, setShowFsWarning, }) { return (

You exited fullscreen!

The timer is still running.

Violation {fsViolations}/3

3 violations = test auto-submitted

) } function ConfirmSubmitModal({ answered, doSubmit, marked, notAnswered, questions, setShowConfirm, submitting, }) { return (

Submit Test?

{[ ['Total Questions', questions.length, 'theme-text'], ['Answered', answered, 'text-[var(--success-text)]'], ['Not Answered', notAnswered, 'text-[var(--danger-text)]'], ['Marked', marked.size, 'text-[var(--marked-text)]'], ].map(([label, val, colorClass]) => (
{label} {val}
))}

This cannot be undone. Your answers will be evaluated.

) } export default function TestEngine() { const engine = useTestEngine() const { accepted, answered, answers, attemptNumber, beginTest, clearResponse, commitNAT, current, currentQuestion, doSubmit, endTimeMs, fsViolations, handleTimerExpire, loading, markAndNext, marked, maxAttempts, natInput, navigate, notAnswered, questions, saveAndNext, setAccepted, setCurrent, setMCQ, setNatInput, setShowCalc, setShowConfirm, setShowFsWarning, setShowPalette, showCalc, showConfirm, showFsWarning, showPalette, started, starting, subjects, submitting, test, toggleMSQ, totalViolations, visited, } = engine if (loading) return if (!started) { return ( ) } if (!currentQuestion) return const sidebar = ( { setCurrent(index) setShowPalette(false) }} onSubmitClick={() => setShowConfirm(true)} questions={questions} submitting={submitting} subjects={subjects} visited={visited} /> ) return (
{showFsWarning && ( )} setShowConfirm(true)} questions={questions} setCurrent={setCurrent} setShowCalc={setShowCalc} showCalc={showCalc} subjects={subjects} submitting={submitting} test={test} totalViolations={totalViolations} />
{sidebar}
Question Palette {sidebar}
{showCalc && setShowCalc(false)} />} {showConfirm && ( )}
) }