Skip to content

Commit 633cc35

Browse files
committed
feat: add answers validation
1 parent d2abde3 commit 633cc35

File tree

3 files changed

+135
-54
lines changed

3 files changed

+135
-54
lines changed

components/mdx/Quiz.tsx

Lines changed: 110 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,86 @@ interface Quiz {
3232
]
3333
}
3434

35+
interface Answers {
36+
[index: string]: number
37+
}
38+
3539
const Quiz: FC<QuizProps> = (props: QuizProps) => {
3640
const quiz: Quiz = require(`../../utils/quizzes/${props.quiz}.json`)
3741
const [showQuiz, setShowQuiz] = useState(false)
38-
const [currenQuestionIndex, setCurrentQuestionIndex] = useState(0)
42+
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0)
43+
const [answers, setAnswers] = useState<Answers>({})
44+
45+
const nextQuestion = () => {
46+
setCurrentQuestionIndex(currentQuestionIndex + 1)
47+
}
48+
49+
const previousQuestion = () => {
50+
setCurrentQuestionIndex(currentQuestionIndex - 1)
51+
}
52+
53+
const previousButtonVisibility = () => {
54+
return currentQuestionIndex == 0 ? 'hidden' : 'visible'
55+
}
56+
57+
const nextButtonVisibility = () => {
58+
return currentQuestionIndex + 1 == quiz.questions.length
59+
? 'hidden'
60+
: 'visible'
61+
}
62+
63+
const selectAnswer = (answerIndex: number) => {
64+
let newAnswers: Answers = { ...answers }
65+
newAnswers[currentQuestionIndex.toString()] = answerIndex
66+
setAnswers(newAnswers)
67+
}
68+
69+
const getQuestionBackground = (optionIndex: number) => {
70+
if (answers[currentQuestionIndex] == optionIndex) {
71+
return 'yellow.600'
72+
}
73+
return 'gray.600'
74+
}
75+
76+
const submit = () => {
77+
if (quiz.questions.length != Object.keys(answers).length) {
78+
return alert('You must answer all the questions!')
79+
}
80+
81+
let hasWrongAnswers = false
82+
83+
quiz.questions.forEach((q, index) => {
84+
if (!q.options[answers[index]].correct) {
85+
hasWrongAnswers = true
86+
}
87+
})
88+
89+
if (hasWrongAnswers) {
90+
return alert('Test not passed :(')
91+
}
92+
93+
return alert('Test passed :D')
94+
}
95+
96+
const cancelQuiz = () => {
97+
setAnswers({})
98+
setShowQuiz(false)
99+
setCurrentQuestionIndex(0)
100+
}
39101

40102
return (
41103
<>
42-
{!showQuiz && (
43-
<Button
44-
colorScheme="yellow"
45-
backgroundColor="yellow.600"
46-
display="flex"
47-
margin="auto"
48-
onClick={() => setShowQuiz(true)}
49-
>
50-
Take quiz
51-
</Button>
52-
)}
53-
54-
<Modal
55-
closeOnOverlayClick={false}
56-
isOpen={showQuiz}
57-
onClose={() => setShowQuiz(false)}
104+
<Button
105+
colorScheme="yellow"
106+
backgroundColor="yellow.600"
107+
display="flex"
108+
margin="auto"
109+
onClick={() => setShowQuiz(true)}
58110
>
111+
Take quiz
112+
</Button>
113+
114+
<Modal closeOnOverlayClick={false} isOpen={showQuiz} onClose={cancelQuiz}>
59115
<ModalOverlay />
60116
<ModalContent>
61117
<ModalHeader>{quiz.title}</ModalHeader>
@@ -68,47 +124,46 @@ const Quiz: FC<QuizProps> = (props: QuizProps) => {
68124
borderRadius="md"
69125
>
70126
<Text fontWeight="bold" w="100%">
71-
{quiz.questions[currenQuestionIndex].question}
127+
{quiz.questions[currentQuestionIndex].question}
72128
</Text>
73-
<Box
74-
w="100%"
75-
borderRadius="md"
76-
background="gray.600"
77-
padding="3"
78-
cursor="pointer"
79-
>
80-
Transactions
81-
</Box>
82-
<Box
83-
w="100%"
84-
borderRadius="md"
85-
background="yellow.600"
86-
padding="3"
87-
cursor="pointer"
88-
>
89-
Smart Contracts
90-
</Box>
91-
<Box
92-
w="100%"
93-
borderRadius="md"
94-
background="gray.600"
95-
padding="3"
96-
cursor="pointer"
97-
>
98-
Just user wallets have an address
99-
</Box>
129+
{quiz.questions[currentQuestionIndex].options.map((o, index) => {
130+
return (
131+
<Box
132+
w="100%"
133+
borderRadius="md"
134+
background={getQuestionBackground(index)}
135+
padding="3"
136+
cursor="pointer"
137+
onClick={() => selectAnswer(index)}
138+
key={index}
139+
>
140+
{o.answer}
141+
</Box>
142+
)
143+
})}
100144
<Box
101145
display="flex"
102146
justifyContent="space-between"
103147
w="100%"
104148
alignItems="center"
105149
>
106-
<Text w="100%">{`Question ${currenQuestionIndex + 1}/${
150+
<Text w="100%">{`Question ${currentQuestionIndex + 1}/${
107151
quiz.questions.length
108152
}`}</Text>
109153
<Box w="100%" display="flex">
110-
<Button mx="2">{'< Previous'}</Button>
111-
<Button>{'Next >'}</Button>
154+
<Button
155+
mx="2"
156+
visibility={previousButtonVisibility()}
157+
onClick={previousQuestion}
158+
>
159+
{'< Previous'}
160+
</Button>
161+
<Button
162+
visibility={nextButtonVisibility()}
163+
onClick={nextQuestion}
164+
>
165+
{'Next >'}
166+
</Button>
112167
</Box>
113168
</Box>
114169
</VStack>
@@ -119,11 +174,16 @@ const Quiz: FC<QuizProps> = (props: QuizProps) => {
119174
mx="1"
120175
colorScheme="red"
121176
backgroundColor="red.600"
122-
onClick={() => setShowQuiz(false)}
177+
onClick={cancelQuiz}
123178
>
124179
Cancel
125180
</Button>
126-
<Button mx="1" colorScheme="green" backgroundColor="green.400">
181+
<Button
182+
mx="1"
183+
colorScheme="green"
184+
backgroundColor="green.400"
185+
onClick={submit}
186+
>
127187
Submit
128188
</Button>
129189
</ModalFooter>

pages/lessons/projects/1.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ icons: ['solidity', 'remix']
66

77
# Lesson 1: Intro to Smart Contract Development
88

9-
<Quiz quiz="lesson-1" />
10-
119
## What are we building?
1210

1311
### Where are we going with it? Web what? Smart contract?
@@ -727,5 +725,7 @@ Can a view function modify the state of the blockchain?
727725

728726
What can we use a smart contract for?
729727

728+
<Quiz quiz="lesson-1" />
729+
730730
**Now, go to the community in Discord to share your new Open Sourcerer
731731
powers**......and find the answers too!!!

utils/quizzes/lesson-1.json

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,38 @@
22
"title": "Quiz: Lesson 1",
33
"questions": [
44
{
5-
"question": "Apart from a user wallet, what else uses a blockchain (Ethereum) address?",
5+
"question": "Apart from a user wallet, what else uses a blockchain (Ethereum) address?",
66
"options": [
77
{
88
"answer": "Transactions"
99
},
1010
{
1111
"answer": "Smart contracts",
1212
"correct": true
13+
}
14+
]
15+
},
16+
{
17+
"question": "What is the use of the pragma solidity statement in our smart contract?",
18+
"options": [
19+
{
20+
"answer": "Defines that the file has Solidity code"
21+
},
22+
{
23+
"answer": "Defines the Solidity version for the compiler",
24+
"correct": true
25+
}
26+
]
27+
},
28+
{
29+
"question": "What can we use a smart contract for?",
30+
"options": [
31+
{
32+
"answer": "Store or transfer value",
33+
"correct": true
1334
},
1435
{
15-
"answer": "Just user wallets have an address"
36+
"answer": "Make a breakfast"
1637
}
1738
]
1839
}

0 commit comments

Comments
 (0)