1- import React , { useEffect , useState } from "react" ;
1+ import React , { useEffect , useState , useRef } from "react" ;
22import "../../styles/pages/games/Gk_quiz.css" ;
33
44const ALL_QUESTIONS = [
@@ -24,6 +24,8 @@ const ALL_QUESTIONS = [
2424 { q : "Which is the hardest natural substance?" , options : [ "Gold" , "Iron" , "Diamond" , "Silver" ] , ans : 2 }
2525] ;
2626
27+ const QUESTION_TIME = 15 ; // seconds
28+
2729function shuffleArray ( arr ) {
2830 const copy = [ ...arr ] ;
2931 for ( let i = copy . length - 1 ; i > 0 ; i -- ) {
@@ -41,11 +43,48 @@ export default function GKQuiz() {
4143 const [ answered , setAnswered ] = useState ( false ) ;
4244 const [ chosenIndex , setChosenIndex ] = useState ( null ) ;
4345 const [ showResult , setShowResult ] = useState ( false ) ;
46+ const [ timeLeft , setTimeLeft ] = useState ( QUESTION_TIME ) ;
47+
48+ // to clear interval when question changes or component unmounts
49+ const timerRef = useRef ( null ) ;
4450
4551 useEffect ( ( ) => {
4652 startQuiz ( ) ;
4753 } , [ ] ) ;
4854
55+ // start timer whenever question changes
56+ useEffect ( ( ) => {
57+ if ( questions . length === 0 ) return ;
58+ startTimer ( ) ;
59+ return ( ) => {
60+ clearInterval ( timerRef . current ) ;
61+ } ;
62+ } , [ current , questions ] ) ;
63+
64+ function startTimer ( ) {
65+ clearInterval ( timerRef . current ) ;
66+ setTimeLeft ( QUESTION_TIME ) ;
67+ timerRef . current = setInterval ( ( ) => {
68+ setTimeLeft ( ( prev ) => {
69+ if ( prev <= 1 ) {
70+ clearInterval ( timerRef . current ) ;
71+ if ( ! answered ) {
72+ handleTimeUp ( ) ;
73+ }
74+ return 0 ;
75+ }
76+ return prev - 1 ;
77+ } ) ;
78+ } , 1000 ) ;
79+ }
80+
81+ function handleTimeUp ( ) {
82+ const qObj = questions [ current ] ;
83+ setAnswered ( true ) ;
84+ setChosenIndex ( null ) ;
85+ setWrong ( ( w ) => w + 1 ) ;
86+ }
87+
4988 function startQuiz ( ) {
5089 const shuffled = shuffleArray ( ALL_QUESTIONS ) . slice ( 0 , 5 ) ;
5190 setQuestions ( shuffled ) ;
@@ -55,20 +94,23 @@ export default function GKQuiz() {
5594 setAnswered ( false ) ;
5695 setChosenIndex ( null ) ;
5796 setShowResult ( false ) ;
97+ setTimeLeft ( QUESTION_TIME ) ;
5898 }
5999
60100 function handleOptionClick ( index ) {
61101 if ( answered ) return ;
62102 const qObj = questions [ current ] ;
63103 setChosenIndex ( index ) ;
64104 setAnswered ( true ) ;
105+ clearInterval ( timerRef . current ) ;
65106 if ( index === qObj . ans ) setCorrect ( ( c ) => c + 1 ) ;
66107 else setWrong ( ( w ) => w + 1 ) ;
67108 }
68109
69110 function handleNext ( ) {
70111 if ( current === questions . length - 1 ) {
71112 setShowResult ( true ) ;
113+ clearInterval ( timerRef . current ) ;
72114 return ;
73115 }
74116 setCurrent ( ( c ) => c + 1 ) ;
@@ -101,6 +143,7 @@ export default function GKQuiz() {
101143 }
102144
103145 const qObj = questions [ current ] ;
146+ const pct = Math . round ( ( timeLeft / QUESTION_TIME ) * 100 ) ;
104147
105148 return (
106149 < div className = "gk-quiz-wrapper" >
@@ -110,7 +153,13 @@ export default function GKQuiz() {
110153 < p className = "gk-quiz-subtitle" > Answer the questions and check instantly</ p >
111154 </ div >
112155 < div className = "gk-quiz-body" >
113- < p className = "gk-quiz-progress" > Question { current + 1 } of { questions . length } </ p >
156+ < div className = "gk-top-row" >
157+ < p className = "gk-quiz-progress" > Question { current + 1 } of { questions . length } </ p >
158+ < div className = { `gk-timer ${ timeLeft <= 5 ? "low" : "" } ` } >
159+ < div className = "gk-timer-bar" style = { { width : pct + "%" } } > </ div >
160+ < span className = "gk-timer-text" > { timeLeft } s</ span >
161+ </ div >
162+ </ div >
114163 < h3 className = "gk-quiz-question" > { qObj . q } </ h3 >
115164 < div className = "gk-quiz-options" >
116165 { qObj . options . map ( ( opt , idx ) => {
@@ -137,7 +186,7 @@ export default function GKQuiz() {
137186 < div className = "gk-quiz-feedback" >
138187 { chosenIndex === qObj . ans
139188 ? < > ✅ Correct! The right answer is: { qObj . options [ qObj . ans ] } </ >
140- : < > ❌ Wrong ! The correct answer is: { qObj . options [ qObj . ans ] } </ > }
189+ : < > ❌ Time up / wrong ! The correct answer is: { qObj . options [ qObj . ans ] } </ > }
141190 </ div >
142191 ) }
143192 { answered && (
0 commit comments