1+ "use client" ;
2+
3+ import { useState } from "react" ;
4+ import Card from "../ui/Card" ;
5+ import Button from "../ui/Button" ;
6+ import ProgressBar from "../ui/Progressbar" ;
7+ import Timer from "../ui/Timer" ;
8+ import QuestionNavigation from "../ui/QuestionNavigation" ;
9+ import { Flag , ChevronRight } from "lucide-react" ;
10+
11+ export default function Retentiaquiz ( ) {
12+
13+ const totalQuestions = 50 ;
14+
15+ const [ showSubmitModal , setShowSubmitModal ] = useState ( false ) ;
16+ const [ currentQuestion , setCurrentQuestion ] = useState ( 1 ) ;
17+ const [ answers , setAnswers ] = useState < Record < number , string | null > > ( { } ) ;
18+ const [ confirmedAnswers , setConfirmedAnswers ] = useState < Record < number , boolean > > ( { } ) ;
19+ const [ markedReview , setMarkedReview ] = useState < Record < number , boolean > > ( { } ) ;
20+ const [ skipped , setSkipped ] = useState < Record < number , boolean > > ( { } ) ;
21+
22+ const answeredCount = Object . keys ( confirmedAnswers ) . length ;
23+
24+ const options = [
25+ { id : "A" , text : "Solar power" } ,
26+ { id : "B" , text : "Wind Power" } ,
27+ { id : "C" , text : "Natural Gas" } ,
28+ { id : "D" , text : "Hydroelectric Power" } ,
29+ ] ;
30+
31+ const confirmSubmit = ( ) => {
32+ setShowSubmitModal ( false ) ;
33+
34+ console . log ( "Quiz submitted successfully" ) ;
35+
36+ } ;
37+
38+ const handleOptionClick = ( optionId : string ) => {
39+
40+ setAnswers ( ( prev ) => {
41+
42+ const current = prev [ currentQuestion ] ;
43+
44+ return {
45+ ...prev ,
46+ [ currentQuestion ] : current === optionId ? null : optionId ,
47+ } ;
48+
49+ } ) ;
50+
51+ setSkipped ( ( prev ) => {
52+ const updated = { ...prev } ;
53+ delete updated [ currentQuestion ] ;
54+ return updated ;
55+ } ) ;
56+
57+ } ;
58+
59+ const handleNext = ( ) => {
60+
61+ if ( answers [ currentQuestion ] ) {
62+
63+ setConfirmedAnswers ( ( prev ) => ( {
64+ ...prev ,
65+ [ currentQuestion ] : true ,
66+ } ) ) ;
67+
68+ setSkipped ( ( prev ) => {
69+ const updated = { ...prev } ;
70+ delete updated [ currentQuestion ] ;
71+ return updated ;
72+ } ) ;
73+
74+ } else {
75+
76+ setSkipped ( ( prev ) => ( {
77+ ...prev ,
78+ [ currentQuestion ] : true ,
79+ } ) ) ;
80+
81+ setConfirmedAnswers ( ( prev ) => {
82+ const updated = { ...prev } ;
83+ delete updated [ currentQuestion ] ;
84+ return updated ;
85+ } ) ;
86+
87+ }
88+
89+ if ( currentQuestion < totalQuestions ) {
90+ setCurrentQuestion ( ( prev ) => prev + 1 ) ;
91+ }
92+
93+ } ;
94+
95+ const toggleReview = ( ) => {
96+
97+ setMarkedReview ( ( prev ) => ( {
98+ ...prev ,
99+ [ currentQuestion ] : ! prev [ currentQuestion ] ,
100+ } ) ) ;
101+
102+ setSkipped ( ( prev ) => {
103+ const updated = { ...prev } ;
104+ delete updated [ currentQuestion ] ;
105+ return updated ;
106+ } ) ;
107+
108+ } ;
109+ const handleSubmit = ( ) => {
110+ setShowSubmitModal ( true ) ;
111+ } ;
112+
113+ return (
114+
115+ < main className = "min-h-screen flex flex-col justify-center bg-background py-10
116+ px-4 sm:px-10 md:px-20 lg:px-80" >
117+
118+ < div className = "grid grid-cols-3 items-center mt-3 gap-4" >
119+
120+ < div > </ div >
121+
122+ < div className = "flex justify-center" >
123+ < Timer totalQuestions = { totalQuestions } />
124+ </ div >
125+
126+ < div className = "flex justify-center sm:justify-end" >
127+ < Button
128+ variant = "default"
129+ className = "bg-answered px-6 py-2 text-white"
130+ onClick = { handleSubmit }
131+ >
132+ Submit
133+ </ Button >
134+ </ div >
135+
136+ </ div >
137+
138+ < div className = "mb-10 mt-10" >
139+ < ProgressBar
140+ answered = { answeredCount }
141+ total = { totalQuestions }
142+ />
143+ </ div >
144+
145+ < QuestionNavigation
146+ currentQuestion = { currentQuestion }
147+ totalQuestions = { totalQuestions }
148+ onQuestionChange = { setCurrentQuestion }
149+ confirmedAnswers = { confirmedAnswers }
150+ markedReview = { markedReview }
151+ skipped = { skipped }
152+ />
153+
154+ < Card
155+ variant = "primary"
156+ className = "w-full max-h-212.5 px-4 sm:px-6 md:px-10"
157+ >
158+
159+ < Card
160+ variant = "secondary"
161+ className = "w-full mb-15 flex items-center justify-center"
162+ >
163+ < p className = "text-xl sm:text-2xl md:text-3xl font-bold leading-relaxed p-6 sm:p-10 md:p-15 text-center" >
164+ Which of the following energy sources cannot be
165+ replenished naturally on a human timescale?
166+ </ p >
167+ </ Card >
168+
169+ < div className = "space-y-5 text-lg sm:text-xl" >
170+
171+ { options . map ( ( option ) => {
172+
173+ const isSelected = answers [ currentQuestion ] === option . id ;
174+ const isAnswered = confirmedAnswers [ currentQuestion ] ;
175+
176+ let colorClass = "" ;
177+
178+ if ( isAnswered && isSelected ) colorClass = "border-secondary " ;
179+ else if ( isSelected ) colorClass = "border-secondary" ;
180+
181+ return (
182+
183+ < Button
184+ key = { option . id }
185+ variant = "opt_btn"
186+ onClick = { ( ) => handleOptionClick ( option . id ) }
187+ className = { `${ colorClass } ` }
188+ >
189+
190+ < div className = "flex items-center justify-center w-8 h-8 rounded-full bg-white text-black font-semibold" >
191+ { option . id }
192+ </ div >
193+
194+ < span className = "flex-1 text-left" >
195+ { option . text }
196+ </ span >
197+
198+ </ Button >
199+
200+ ) ;
201+ } ) }
202+
203+ </ div >
204+
205+ </ Card >
206+
207+ < div className = "flex flex-col sm:flex-row justify-end items-center gap-5 mt-20 mb-5" >
208+
209+ < Button
210+ variant = "default"
211+ onClick = { toggleReview }
212+ className = "bg-purple-600 text-white px-6 py-2 flex items-center gap-2 w-full sm:w-auto justify-center"
213+ >
214+ < Flag size = { 18 } />
215+ Mark For Review
216+ </ Button >
217+
218+ < Button
219+ variant = "default"
220+ onClick = { handleNext }
221+ className = "bg-secondary px-6 py-2 flex text-white items-center gap-2 w-full sm:w-auto justify-center"
222+ >
223+ Next Question
224+ < ChevronRight size = { 18 } />
225+ </ Button >
226+
227+ </ div >
228+ { showSubmitModal && (
229+ < div className = "fixed inset-0 bg-background flex items-center justify-center z-50" >
230+ < Card variant = "primary" className = "p-8 max-w-md w-full text-center" >
231+
232+ < h2 className = "text-xl font-bold mb-4" >
233+ Submit Quiz?
234+ </ h2 >
235+
236+ < p className = "text-text mb-6" >
237+ Are you sure you want to submit the quiz?
238+ </ p >
239+
240+ < div className = "flex justify-center gap-4" >
241+
242+ < Button
243+ variant = "default"
244+ onClick = { ( ) => setShowSubmitModal ( false ) }
245+ >
246+ Cancel
247+ </ Button >
248+
249+ < Button
250+ variant = "default"
251+ className = "bg-answered text-text"
252+ onClick = { confirmSubmit }
253+ >
254+ Submit
255+ </ Button >
256+
257+ </ div >
258+
259+ </ Card >
260+ </ div >
261+ ) }
262+
263+ </ main >
264+ ) ;
265+ }
0 commit comments