1- import React , { useState , useEffect , useRef , useCallback } from 'react' ;
1+ import React , { useState , useEffect , useRef } from 'react' ;
22import { useLocation , useNavigate } from 'react-router-dom' ;
33import {
44 Container ,
@@ -56,63 +56,61 @@ function QuizPage() {
5656 } ) ;
5757 } , [ quizID , username , navigate ] ) ;
5858
59- const handleSubmit = useCallback (
60- ( timerExceeded = false ) => {
61- if ( hasSubmittedRef . current ) return ;
62- hasSubmittedRef . current = true ;
63-
64- setIsSubmitting ( true ) ;
65- const submissionData = {
66- Username : username ,
67- QuizID : quizID ,
68- Answers : answers ,
69- } ;
70- if ( email ) {
71- submissionData . Email = email ;
72- }
73- if ( timerExceeded ) {
74- submissionData . TimerExceeded = true ;
75- }
59+ const handleSubmit = ( timerExceeded = false , submissionAnswers = answers ) => {
60+ if ( hasSubmittedRef . current ) return ;
61+ hasSubmittedRef . current = true ;
62+
63+ setIsSubmitting ( true ) ;
64+ const submissionData = {
65+ Username : username ,
66+ QuizID : quizID ,
67+ Answers : submissionAnswers ,
68+ } ;
69+ if ( email ) {
70+ submissionData . Email = email ;
71+ }
72+ if ( timerExceeded ) {
73+ submissionData . TimerExceeded = true ;
74+ }
7675
77- fetch ( `${ process . env . REACT_APP_API_ENDPOINT } /submitquiz` , {
78- method : 'POST' ,
79- headers : { 'Content-Type' : 'application/json' } ,
80- body : JSON . stringify ( submissionData ) ,
81- } )
82- . then ( ( res ) => res . json ( ) )
83- . then ( ( data ) => {
84- navigate ( '/result' , {
85- state : { submissionID : data . SubmissionID , quizID } ,
86- } ) ;
87- } )
88- . catch ( ( err ) => {
89- console . error ( 'Error submitting quiz:' , err ) ;
90- alert ( 'Failed to submit quiz. Please try again.' ) ;
91- setIsSubmitting ( false ) ;
92- hasSubmittedRef . current = false ;
76+ fetch ( `${ process . env . REACT_APP_API_ENDPOINT } /submitquiz` , {
77+ method : 'POST' ,
78+ headers : { 'Content-Type' : 'application/json' } ,
79+ body : JSON . stringify ( submissionData ) ,
80+ } )
81+ . then ( ( res ) => res . json ( ) )
82+ . then ( ( data ) => {
83+ navigate ( '/result' , {
84+ state : { submissionID : data . SubmissionID , quizID } ,
9385 } ) ;
94- } ,
95- [ username , quizID , answers , email , navigate ]
96- ) ;
86+ } )
87+ . catch ( ( err ) => {
88+ console . error ( 'Error submitting quiz:' , err ) ;
89+ alert ( 'Failed to submit quiz. Please try again.' ) ;
90+ setIsSubmitting ( false ) ;
91+ hasSubmittedRef . current = false ;
92+ } ) ;
93+ } ;
9794
98- const moveToNextQuestion = useCallback ( ( ) => {
95+ const moveToNextQuestion = ( ) => {
9996 if ( quizData && currentQuestionIndex < quizData . Questions . length - 1 ) {
10097 setCurrentQuestionIndex ( ( prevIndex ) => prevIndex + 1 ) ;
10198 }
102- } , [ quizData , currentQuestionIndex ] ) ;
99+ } ;
103100
104101 const handleSkip = ( ) => {
105102 const timeTaken =
106103 quizData && quizData . EnableTimer ? quizData . TimerSeconds - timeLeft : 0 ;
107104
108- setAnswers ( ( prevAnswers ) => ( {
109- ...prevAnswers ,
105+ const updatedAnswers = {
106+ ...answers ,
110107 [ currentQuestionIndex ] : {
111108 Answer : '' ,
112109 TimeTaken : timeTaken ,
113110 Skipped : true ,
114111 } ,
115- } ) ) ;
112+ } ;
113+ setAnswers ( updatedAnswers ) ;
116114
117115 if ( quizData && quizData . EnableTimer && timerRef . current ) {
118116 clearInterval ( timerRef . current ) ;
@@ -122,7 +120,7 @@ function QuizPage() {
122120 moveToNextQuestion ( ) ;
123121 } else {
124122 if ( ! hasSubmittedRef . current ) {
125- handleSubmit ( ) ;
123+ handleSubmit ( false , updatedAnswers ) ;
126124 }
127125 }
128126 } ;
@@ -138,21 +136,26 @@ function QuizPage() {
138136
139137 const handleTimeUp = ( ) => {
140138 const timeTaken = quizData . TimerSeconds ;
141- setAnswers ( ( prevAnswers ) => ( {
142- ...prevAnswers ,
143- [ currentQuestionIndex ] : {
144- Answer : prevAnswers [ currentQuestionIndex ] ?. Answer || '' ,
145- TimeTaken : timeTaken ,
146- } ,
147- } ) ) ;
148-
149- if ( currentQuestionIndex < quizData . Questions . length - 1 ) {
150- moveToNextQuestion ( ) ;
151- } else {
152- if ( ! hasSubmittedRef . current ) {
153- handleSubmit ( true ) ;
139+
140+ setAnswers ( ( prevAnswers ) => {
141+ const updatedAnswers = {
142+ ...prevAnswers ,
143+ [ currentQuestionIndex ] : {
144+ Answer : prevAnswers [ currentQuestionIndex ] ?. Answer || '' ,
145+ TimeTaken : timeTaken ,
146+ } ,
147+ } ;
148+
149+ if ( currentQuestionIndex < quizData . Questions . length - 1 ) {
150+ moveToNextQuestion ( ) ;
151+ } else {
152+ if ( ! hasSubmittedRef . current ) {
153+ handleSubmit ( true , updatedAnswers ) ;
154+ }
154155 }
155- }
156+
157+ return updatedAnswers ;
158+ } ) ;
156159 } ;
157160
158161 timerRef . current = setInterval ( ( ) => {
@@ -168,20 +171,21 @@ function QuizPage() {
168171
169172 return ( ) => clearInterval ( timerRef . current ) ;
170173 }
171- } , [ currentQuestionIndex , quizData , moveToNextQuestion , handleSubmit ] ) ;
174+ } , [ currentQuestionIndex , quizData ] ) ;
172175
173176 const handleOptionChange = ( e ) => {
174177 const selectedOption = e . target . value ;
175178 const timeTaken =
176179 quizData && quizData . EnableTimer ? quizData . TimerSeconds - timeLeft : 0 ;
177180
178- setAnswers ( ( prevAnswers ) => ( {
179- ...prevAnswers ,
181+ const updatedAnswers = {
182+ ...answers ,
180183 [ currentQuestionIndex ] : {
181184 Answer : selectedOption ,
182185 TimeTaken : timeTaken ,
183186 } ,
184- } ) ) ;
187+ } ;
188+ setAnswers ( updatedAnswers ) ;
185189
186190 if ( quizData && quizData . EnableTimer && timerRef . current ) {
187191 clearInterval ( timerRef . current ) ;
@@ -190,8 +194,11 @@ function QuizPage() {
190194 if ( currentQuestionIndex < quizData . Questions . length - 1 ) {
191195 moveToNextQuestion ( ) ;
192196 } else {
193- if ( ! hasSubmittedRef . current ) {
194- handleSubmit ( ) ;
197+ // Do not auto-submit on the last question
198+ // Start the timer for the last question
199+ if ( quizData . EnableTimer ) {
200+ setTimeLeft ( quizData . TimerSeconds ) ;
201+ questionStartTimeRef . current = Date . now ( ) ;
195202 }
196203 }
197204 } ;
@@ -216,7 +223,11 @@ function QuizPage() {
216223
217224 return (
218225 < MainLayout >
219- < Container maxWidth = "sm" className = "main-quiz-container" sx = { { position : 'relative' } } >
226+ < Container
227+ maxWidth = "sm"
228+ className = "main-quiz-container"
229+ sx = { { position : 'relative' } }
230+ >
220231 { /* Skip Button at Top Right */ }
221232 { ! isSubmitting && (
222233 < IconButton
@@ -287,18 +298,19 @@ function QuizPage() {
287298 ) ) }
288299 </ RadioGroup >
289300
290- { ! isSubmitting && currentQuestionIndex === quizData . Questions . length - 1 && (
291- < Box sx = { { textAlign : 'center' , marginTop : 4 } } >
292- < Button
293- variant = "contained"
294- color = "primary"
295- onClick = { handleSubmit }
296- disabled = { isSubmitting || isTimeUp }
297- >
298- Submit Quiz
299- </ Button >
300- </ Box >
301- ) }
301+ { ! isSubmitting &&
302+ currentQuestionIndex === quizData . Questions . length - 1 && (
303+ < Box sx = { { textAlign : 'center' , marginTop : 4 } } >
304+ < Button
305+ variant = "contained"
306+ color = "primary"
307+ onClick = { ( ) => handleSubmit ( false , answers ) }
308+ disabled = { isSubmitting || isTimeUp }
309+ >
310+ Submit Quiz
311+ </ Button >
312+ </ Box >
313+ ) }
302314
303315 { isSubmitting && (
304316 < Box sx = { { textAlign : 'center' , marginTop : 4 } } >
0 commit comments