Skip to content

Commit 036d970

Browse files
committedJan 20, 2024
feat: add quiz-builder.jsx solution
1 parent 04d8498 commit 036d970

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
 

‎solutions/quiz-builder.jsx

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React, { useState, useMemo } from "react"
2+
import { createRoot } from "react-dom/client"
3+
4+
const style = {
5+
container: {
6+
padding: "20px",
7+
border: "1px solid #E0E0E0",
8+
borderRadius: "15px",
9+
width: "max-content",
10+
marginBottom: "40px",
11+
},
12+
question: {
13+
fontWeight: "bold",
14+
marginBottom: "10px",
15+
},
16+
options: {
17+
marginBottom: "5px",
18+
},
19+
button: {
20+
marginTop: "10px",
21+
padding: "10px 15px",
22+
border: "none",
23+
backgroundColor: "#007BFF",
24+
color: "#FFF",
25+
fontSize: "14px",
26+
borderRadius: "5px",
27+
cursor: "pointer",
28+
},
29+
feedback: {
30+
marginTop: "10px",
31+
fontSize: "14px",
32+
},
33+
}
34+
35+
const QuizOption = ({ option, index, answer, setAnswer }) => {
36+
const onChange = ({ target: { value } }) => setAnswer(value)
37+
return (
38+
<>
39+
<input
40+
type="radio"
41+
onChange={onChange}
42+
checked={option === answer}
43+
name="answers"
44+
value={option}
45+
id={`option${index}`}
46+
/>
47+
<label htmlFor={option}>{option}</label>
48+
</>
49+
)
50+
}
51+
52+
function QuizApp() {
53+
// do not modify the questions or answers below
54+
const questions = useMemo(
55+
() => [
56+
{
57+
question: "What is the capital of France?",
58+
options: ["London", "Paris", "Berlin", "Madrid"],
59+
correct: "Paris",
60+
},
61+
{
62+
question: "What is the capital of Germany?",
63+
options: ["Berlin", "Munich", "Frankfurt", "Hamburg"],
64+
correct: "Berlin",
65+
},
66+
],
67+
[]
68+
)
69+
70+
const questionsTotal = useMemo(() => questions.length, [questions])
71+
72+
const [questionsIndex, setQuestionsIndex] = useState(0)
73+
const [score, setScore] = useState(0)
74+
const [feedback, setFeedback] = useState(null)
75+
const [answer, setAnswer] = useState(null)
76+
const [completedQuiz, setCompletedQuiz] = useState(false)
77+
78+
const submit = () => {
79+
if (answer === questions[questionsIndex].correct) {
80+
setScore(score + 1)
81+
setFeedback("Correct!")
82+
} else {
83+
setFeedback("Incorrect!")
84+
}
85+
86+
if (questionsIndex === questionsTotal - 1) {
87+
setCompletedQuiz(true)
88+
} else {
89+
setQuestionsIndex(questionsIndex + 1)
90+
setAnswer(null)
91+
}
92+
}
93+
94+
return (
95+
<div style={style.container}>
96+
<div id="question" style={style.question}>
97+
{`${questions[questionsIndex].question}`}
98+
</div>
99+
<div style={style.options}>
100+
{questions[questionsIndex].options.map((option, index) => (
101+
<QuizOption
102+
key={`option-${index}`}
103+
option={option}
104+
index={index}
105+
answer={answer}
106+
setAnswer={setAnswer}
107+
/>
108+
))}
109+
</div>
110+
<button
111+
disabled={completedQuiz}
112+
style={style.button}
113+
id="submitBtn"
114+
onClick={submit}
115+
>
116+
Submit
117+
</button>
118+
<div id="feedback" style={style.feedback}>
119+
{questionsIndex !== 0 && !completedQuiz && `${feedback}`}
120+
</div>
121+
<div id="score" style={style.feedback}>
122+
{completedQuiz &&
123+
`Quiz complete! You scored ${score} out of ${questions.length}!`}
124+
</div>
125+
</div>
126+
)
127+
}
128+
129+
const root = createRoot(document.getElementById("root"))
130+
root.render(<QuizApp />)

0 commit comments

Comments
 (0)