1
- import React , { useState , useEffect , useRef , useCallback } from 'react' ;
1
+ import React , { useState , useEffect , useRef } from 'react' ;
2
2
import { useLocation , useNavigate } from 'react-router-dom' ;
3
3
import {
4
4
Container ,
@@ -56,63 +56,61 @@ function QuizPage() {
56
56
} ) ;
57
57
} , [ quizID , username , navigate ] ) ;
58
58
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
+ }
76
75
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 } ,
93
85
} ) ;
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
+ } ;
97
94
98
- const moveToNextQuestion = useCallback ( ( ) => {
95
+ const moveToNextQuestion = ( ) => {
99
96
if ( quizData && currentQuestionIndex < quizData . Questions . length - 1 ) {
100
97
setCurrentQuestionIndex ( ( prevIndex ) => prevIndex + 1 ) ;
101
98
}
102
- } , [ quizData , currentQuestionIndex ] ) ;
99
+ } ;
103
100
104
101
const handleSkip = ( ) => {
105
102
const timeTaken =
106
103
quizData && quizData . EnableTimer ? quizData . TimerSeconds - timeLeft : 0 ;
107
104
108
- setAnswers ( ( prevAnswers ) => ( {
109
- ...prevAnswers ,
105
+ const updatedAnswers = {
106
+ ...answers ,
110
107
[ currentQuestionIndex ] : {
111
108
Answer : '' ,
112
109
TimeTaken : timeTaken ,
113
110
Skipped : true ,
114
111
} ,
115
- } ) ) ;
112
+ } ;
113
+ setAnswers ( updatedAnswers ) ;
116
114
117
115
if ( quizData && quizData . EnableTimer && timerRef . current ) {
118
116
clearInterval ( timerRef . current ) ;
@@ -122,7 +120,7 @@ function QuizPage() {
122
120
moveToNextQuestion ( ) ;
123
121
} else {
124
122
if ( ! hasSubmittedRef . current ) {
125
- handleSubmit ( ) ;
123
+ handleSubmit ( false , updatedAnswers ) ;
126
124
}
127
125
}
128
126
} ;
@@ -138,21 +136,26 @@ function QuizPage() {
138
136
139
137
const handleTimeUp = ( ) => {
140
138
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
+ }
154
155
}
155
- }
156
+
157
+ return updatedAnswers ;
158
+ } ) ;
156
159
} ;
157
160
158
161
timerRef . current = setInterval ( ( ) => {
@@ -168,20 +171,21 @@ function QuizPage() {
168
171
169
172
return ( ) => clearInterval ( timerRef . current ) ;
170
173
}
171
- } , [ currentQuestionIndex , quizData , moveToNextQuestion , handleSubmit ] ) ;
174
+ } , [ currentQuestionIndex , quizData ] ) ;
172
175
173
176
const handleOptionChange = ( e ) => {
174
177
const selectedOption = e . target . value ;
175
178
const timeTaken =
176
179
quizData && quizData . EnableTimer ? quizData . TimerSeconds - timeLeft : 0 ;
177
180
178
- setAnswers ( ( prevAnswers ) => ( {
179
- ...prevAnswers ,
181
+ const updatedAnswers = {
182
+ ...answers ,
180
183
[ currentQuestionIndex ] : {
181
184
Answer : selectedOption ,
182
185
TimeTaken : timeTaken ,
183
186
} ,
184
- } ) ) ;
187
+ } ;
188
+ setAnswers ( updatedAnswers ) ;
185
189
186
190
if ( quizData && quizData . EnableTimer && timerRef . current ) {
187
191
clearInterval ( timerRef . current ) ;
@@ -190,8 +194,11 @@ function QuizPage() {
190
194
if ( currentQuestionIndex < quizData . Questions . length - 1 ) {
191
195
moveToNextQuestion ( ) ;
192
196
} 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 ( ) ;
195
202
}
196
203
}
197
204
} ;
@@ -216,7 +223,11 @@ function QuizPage() {
216
223
217
224
return (
218
225
< 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
+ >
220
231
{ /* Skip Button at Top Right */ }
221
232
{ ! isSubmitting && (
222
233
< IconButton
@@ -287,18 +298,19 @@ function QuizPage() {
287
298
) ) }
288
299
</ RadioGroup >
289
300
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
+ ) }
302
314
303
315
{ isSubmitting && (
304
316
< Box sx = { { textAlign : 'center' , marginTop : 4 } } >
0 commit comments