Skip to content

Commit f2018e1

Browse files
committed
Updates
1 parent 920a97f commit f2018e1

2 files changed

Lines changed: 295 additions & 0 deletions

File tree

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ Frontend project implementations.
1010
| 2 | Age Calculator App | [Webpage](https://jc-progjava.github.io/FrontendMentor/age-calculator-app/), [Source](https://github.com/JC-ProgJava/FrontendMentor/tree/master/docs/age-calculator-app/) |
1111
| 3 🟨 | Space Tourism | [Webpage](https://jc-progjava.github.io/FrontendMentor/space-tourism/), [Source](https://github.com/JC-ProgJava/FrontendMentor/tree/master/docs/space-tourism/) |
1212
| 3 | Room Homepage | [Webpage](https://jc-progjava.github.io/FrontendMentor/room-homepage/), [Source](https://github.com/JC-ProgJava/FrontendMentor/tree/master/docs/room-homepage/) |
13+
| 3 | Frontend Quiz App | [Webpage](https://jc-progjava.github.io/FrontendMentor/age-calculator-app/), [Source](https://github.com/JC-ProgJava/FrontendMentor/tree/master/docs/frontend-quiz-app/) |
1314

docs/frontend-quiz-app/index.html

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Quiz App</title>
6+
<style>
7+
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap");
8+
9+
:root {
10+
--dark-blue: rgb(52, 62, 79);
11+
--lighter-blue: rgb(63, 76, 101);
12+
--foreground-white: rgb(248, 248, 248);
13+
--grey: rgb(200, 200, 200);
14+
--accent: #81a1c1;
15+
}
16+
17+
body {
18+
font-family: "Montserrat", sans-serif;
19+
background-color: var(--dark-blue);
20+
color: var(--foreground-white);
21+
}
22+
23+
.card-display {
24+
padding: 20px 40px;
25+
display: flex;
26+
gap: 30px;
27+
28+
@media screen and (max-width: 500px) {
29+
flex-direction: column;
30+
}
31+
32+
@media screen and (min-width: 500px) {
33+
flex-direction: row;
34+
.question-display {
35+
width: 50%;
36+
}
37+
38+
.answer-display {
39+
width: 50%;
40+
}
41+
}
42+
43+
.question-display {
44+
h1 {
45+
color: var(--foreground-white);
46+
}
47+
48+
p {
49+
color: var(--grey);
50+
}
51+
}
52+
53+
.answer-display {
54+
display: flex;
55+
flex-direction: column;
56+
gap: 15px;
57+
58+
.answer-options-container {
59+
display: flex;
60+
flex-direction: column;
61+
gap: 10px;
62+
63+
.answer-option {
64+
padding: 15px 20px;
65+
background-color: var(--lighter-blue);
66+
font-size: 15pt;
67+
border-radius: 10px;
68+
display: flex;
69+
flex-direction: row;
70+
gap: 15px;
71+
line-height: 1.5;
72+
transition: border 300ms;
73+
border: 2px solid var(--lighter-blue);
74+
75+
.answer-option-name {
76+
width: 30px;
77+
height: 30px;
78+
display: flex;
79+
justify-content: center;
80+
border-radius: 5px;
81+
color: var(--lighter-blue);
82+
background-color: #d8dee9;
83+
}
84+
85+
.answer-option-content {
86+
display: inline-block;
87+
}
88+
}
89+
90+
.answer-option:hover {
91+
border: 2px solid #81a1c1;
92+
cursor: pointer;
93+
}
94+
95+
.answer-option.active {
96+
border: 2px solid var(--foreground-white);
97+
}
98+
}
99+
100+
.submit-option {
101+
font-family: "Montserrat", sans-serif;
102+
font-weight: 700;
103+
border-radius: 10px;
104+
display: block;
105+
width: 100%;
106+
padding: 10px 20px;
107+
border: 0;
108+
background-color: var(--accent);
109+
color: var(--foreground-white);
110+
transition: background-color 0.5s;
111+
}
112+
113+
.submit-option:hover {
114+
cursor: pointer;
115+
background-color: #5e81ac;
116+
}
117+
}
118+
}
119+
120+
.final-screen {
121+
padding: 40px;
122+
display: none;
123+
gap: 15px;
124+
flex-direction: column;
125+
126+
.final-display-text {
127+
h2:nth-of-type(1) {
128+
font-weight: 300;
129+
}
130+
131+
h2:nth-of-type(2) {
132+
font-weight: 700;
133+
}
134+
}
135+
136+
.final-display-score {
137+
padding: 20px 40px;
138+
display: flex;
139+
flex-direction: column;
140+
gap: 10px;
141+
text-align: center;
142+
background-color: var(--lighter-blue);
143+
border-radius: 10px;
144+
145+
.score {
146+
font-weight: 800;
147+
font-size: 30pt;
148+
color: var(--foreground-white);
149+
}
150+
151+
.total {
152+
font-weight: 500;
153+
font-size: 12pt;
154+
color: var(--grey);
155+
}
156+
}
157+
}
158+
</style>
159+
160+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.15/dist/katex.min.css" crossorigin="anonymous">
161+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.15/dist/katex.min.js" crossorigin="anonymous"></script>
162+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.15/dist/contrib/auto-render.min.js"
163+
crossorigin="anonymous"></script>
164+
</head>
165+
<body>
166+
<div class="card-display">
167+
<div class="question-display">
168+
<h2>Math Quiz</h2>
169+
<p>Select an option to get started</p>
170+
<h1></h1>
171+
</div>
172+
<div class="answer-display">
173+
<template>
174+
<div class="answer-option">
175+
<div class="answer-option-name">
176+
<span></span>
177+
</div>
178+
<div class="answer-option-content"></div>
179+
</div>
180+
</template>
181+
<div class="answer-options-container">
182+
<div class="answer-option">
183+
<div class="answer-option-name"><span>A</span></div>
184+
<div class="answer-option-content">Arithmetic</div>
185+
</div>
186+
</div>
187+
<button class="submit-option">Submit</button>
188+
</div>
189+
</div>
190+
<div class="final-screen">
191+
<div class="final-display-text">
192+
<h2>Quiz completed</h2>
193+
<h2>You scored...</h2>
194+
</div>
195+
<div class="final-display-score">
196+
<div class="score"></div>
197+
<div class="total"></div>
198+
</div>
199+
</div>
200+
201+
</body>
202+
<script>
203+
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
204+
let questions = [
205+
{
206+
question: "1 + 3 = ?",
207+
correct_answer: "4",
208+
options: ["4", "7", "1", "0"]
209+
},
210+
{
211+
question: "3 - 2 = ?",
212+
correct_answer: "1",
213+
options: ["9", "1", "4", "7"]
214+
},
215+
{
216+
question: "\\\(5 * 2 = ?\\\)",
217+
correct_answer: "10",
218+
options: ["17", "32", "10", "5"]
219+
}
220+
];
221+
222+
let startQuiz = false;
223+
let correctCount = 0;
224+
let qNumber = 1;
225+
226+
setupListeners();
227+
228+
document.querySelector(".submit-option").addEventListener("click", () => {
229+
if (document.querySelector(".answer-option.active")) {
230+
if (!startQuiz) {
231+
startQuiz = true;
232+
showQuestion(qNumber);
233+
} else {
234+
// check answer, show next question
235+
if (document.querySelector(".answer-option.active .answer-option-content").innerText === questions[qNumber - 1].correct_answer) {
236+
correctCount++;
237+
}
238+
qNumber++;
239+
240+
if (qNumber <= questions.length) {
241+
showQuestion(qNumber);
242+
} else {
243+
// Finished quiz
244+
console.log(correctCount + " / " + questions.length + " correct.")
245+
showFinishScreen(correctCount, questions.length);
246+
}
247+
}
248+
}
249+
});
250+
251+
function showQuestion(qNumber) {
252+
document.querySelector(".question-display p").innerText = `Question ${qNumber} of ${questions.length}`;
253+
document.querySelector(".question-display h1").innerText = questions[qNumber - 1].question;
254+
255+
document.querySelectorAll(".answer-options-container > .answer-option").forEach(element => element.remove())
256+
for (let i = 0; i < questions[qNumber - 1].options.length; i++) {
257+
let node = document.querySelector(".answer-display template").content.cloneNode(true);
258+
node.querySelector(".answer-option-name span").innerText = alphabet.charAt(i);
259+
node.querySelector(".answer-option-content").innerText = questions[qNumber - 1].options[i];
260+
document.querySelector(".answer-options-container").appendChild(node);
261+
}
262+
263+
setupListeners();
264+
renderMathInElement(document.body);
265+
}
266+
267+
function showFinishScreen(correctCount, questionCount) {
268+
document.querySelector(".card-display").style.display = "none";
269+
document.querySelector(".final-screen").style.display = "flex";
270+
document.querySelector(".final-display-score .score").innerText = correctCount;
271+
document.querySelector(".final-display-score .total").innerText = ` out of ${questionCount}`;
272+
}
273+
274+
function setupListeners() {
275+
document.querySelectorAll(".answer-option").forEach(element => {
276+
element.addEventListener("click", () => {
277+
if (element.classList.contains("active")) {
278+
element.classList.remove("active");
279+
} else {
280+
select([...document.querySelectorAll(".answer-option")].indexOf(element));
281+
}
282+
});
283+
});
284+
}
285+
286+
function select(index) {
287+
let elements = document.querySelectorAll(".answer-option");
288+
for (let i = 0; i < elements.length; i++) {
289+
elements[i].classList.remove("active");
290+
}
291+
elements[index].classList.add("active");
292+
}
293+
</script>
294+
</html>

0 commit comments

Comments
 (0)