├── src
├── assets
│ └── bg.jpg
├── sounds
│ ├── play.mp3
│ ├── wait.mp3
│ ├── wrong.mp3
│ └── correct.mp3
├── index.js
├── components
│ ├── Timer.jsx
│ ├── Start.jsx
│ └── Trivia.jsx
├── App.css
└── App.jsx
├── .gitignore
├── package.json
├── README.md
└── public
└── index.html
/src/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlanBinu007/React-quiz/HEAD/src/assets/bg.jpg
--------------------------------------------------------------------------------
/src/sounds/play.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlanBinu007/React-quiz/HEAD/src/sounds/play.mp3
--------------------------------------------------------------------------------
/src/sounds/wait.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlanBinu007/React-quiz/HEAD/src/sounds/wait.mp3
--------------------------------------------------------------------------------
/src/sounds/wrong.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlanBinu007/React-quiz/HEAD/src/sounds/wrong.mp3
--------------------------------------------------------------------------------
/src/sounds/correct.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlanBinu007/React-quiz/HEAD/src/sounds/correct.mp3
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(
6 |
7 |
8 | ,
9 | document.getElementById('root')
10 | );
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/src/components/Timer.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | export default function Timer({ setTimeOut, questionNumber }) {
4 | const [timer, setTimer] = useState(30);
5 |
6 | useEffect(() => {
7 | if (timer === 0) return setTimeOut(true);
8 | const interval = setInterval(() => {
9 | setTimer((prev) => prev - 1);
10 | }, 1000);
11 | return () => clearInterval(interval);
12 | }, [timer, setTimeOut]);
13 |
14 | useEffect(() => {
15 | setTimer(30);
16 | }, [questionNumber]);
17 | return timer;
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/Start.jsx:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 |
3 | export default function Start({ setUsername }) {
4 | const inputRef = useRef();
5 |
6 | const handleClick = () => {
7 | inputRef.current.value && setUsername(inputRef.current.value);
8 | };
9 |
10 | return (
11 |
12 |
17 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "milionaire",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.11.4",
7 | "@testing-library/react": "^11.1.0",
8 | "@testing-library/user-event": "^12.1.10",
9 | "react": "^17.0.2",
10 | "react-dom": "^17.0.2",
11 | "react-scripts": "4.0.3",
12 | "use-sound": "^3.0.0",
13 | "web-vitals": "^1.0.1"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": [
23 | "react-app",
24 | "react-app/jest"
25 | ]
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Cone the repo
6 |
7 | `git clone https://github.com/AlanBinu007/React-quiz`
8 |
9 | In the project directory, you can run:
10 |
11 | ### `yarn start`
12 |
13 | Runs the app in the development mode.\
14 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
15 |
16 | The page will reload if you make edits.\
17 | You will also see any lint errors in the console.
18 |
19 | ### `yarn test`
20 |
21 | Launches the test runner in the interactive watch mode.\
22 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
23 |
24 | ### `yarn build`
25 |
26 | Builds the app for production to the `build` folder.\
27 | It correctly bundles React in production mode and optimizes the build for the best performance.
28 |
29 | The build is minified and the filenames include the hashes.\
30 | Your app is ready to be deployed!
31 |
32 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
33 |
--------------------------------------------------------------------------------
/src/components/Trivia.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import useSound from "use-sound";
3 | import play from "../sounds/play.mp3";
4 | import correct from "../sounds/correct.mp3";
5 | import wrong from "../sounds/wrong.mp3";
6 |
7 | export default function Trivia({
8 | data,
9 | questionNumber,
10 | setQuestionNumber,
11 | setTimeOut,
12 | }) {
13 | const [question, setQuestion] = useState(null);
14 | const [selectedAnswer, setSelectedAnswer] = useState(null);
15 | const [className, setClassName] = useState("answer");
16 | const [letsPlay] = useSound(play);
17 | const [correctAnswer] = useSound(correct);
18 | const [wrongAnswer] = useSound(wrong);
19 |
20 | useEffect(() => {
21 | letsPlay();
22 | }, [letsPlay]);
23 |
24 | useEffect(() => {
25 | setQuestion(data[questionNumber - 1]);
26 | }, [data, questionNumber]);
27 |
28 | const delay = (duration, callback) => {
29 | setTimeout(() => {
30 | callback();
31 | }, duration);
32 | };
33 |
34 | const handleClick = (a) => {
35 | setSelectedAnswer(a);
36 | setClassName("answer active");
37 | delay(3000, () => {
38 | setClassName(a.correct ? "answer correct" : "answer wrong");
39 | });
40 | // setTimeout(() => {
41 | // setClassName(a.correct ? "answer correct" : "answer wrong");
42 | // }, 3000);
43 |
44 | // setTimeout(() => {
45 | delay(5000, () => {
46 | if (a.correct) {
47 | correctAnswer();
48 | delay(1000, () => {
49 | setQuestionNumber((prev) => prev + 1);
50 | setSelectedAnswer(null);
51 | });
52 | // setTimeout(() => {
53 | // setQuestionNumber((prev) => prev + 1);
54 | // setSelectedAnswer(null);
55 | // }, 1000);
56 | } else {
57 | wrongAnswer();
58 | delay(1000, () => {
59 | setTimeOut(true);
60 | });
61 | // setTimeout(() => {
62 | // setTimeOut(true);
63 | // }, 1000);
64 | }
65 | // }, 5000);
66 | })
67 | };
68 | return (
69 |
70 |
{question?.question}
71 |
72 | {question?.answers.map((a) => (
73 |
!selectedAnswer && handleClick(a)}
76 | >
77 | {a.text}
78 |
79 | ))}
80 |
81 |
82 | );
83 | }
84 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
14 |
20 | React Quiz
21 |
22 |
23 |
24 |
25 |
26 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .app {
2 | height: 100vh;
3 | display: flex;
4 | color: white;
5 | background-color: #020230;
6 | }
7 |
8 | .main {
9 | width: 75%;
10 | background: linear-gradient(to bottom, rgba(0, 0, 0, 0), #020230),
11 | url("https://i.ytimg.com/vi/yQbJRGs0fy8/maxresdefault.jpg") center;
12 | display: flex;
13 | flex-direction: column;
14 | }
15 |
16 | .pyramid {
17 | width: 25%;
18 | background-color: #020230;
19 | display: flex;
20 | align-items: center;
21 | justify-content: center;
22 | }
23 |
24 | .moneyList {
25 | padding: 20px;
26 | list-style: none;
27 | width: 100%;
28 | }
29 |
30 | .moneyListItem {
31 | display: flex;
32 | align-items: center;
33 | padding: 5px;
34 | border-radius: 5px;
35 | }
36 |
37 | .moneyListItem.active {
38 | background-color: teal;
39 | }
40 |
41 | .moneyListItemNumber {
42 | width: 30%;
43 | font-size: 18px;
44 | font-weight: 100;
45 | }
46 |
47 | .moneyListItemAmount {
48 | font-size: 20px;
49 | font-weight: 300;
50 | }
51 |
52 | .top {
53 | height: 50%;
54 | position: relative;
55 | }
56 |
57 | .timer {
58 | width: 70px;
59 | height: 70px;
60 | border-radius: 50%;
61 | border: 5px solid white;
62 | display: flex;
63 | align-items: center;
64 | justify-content: center;
65 | position: absolute;
66 | bottom: 10px;
67 | left: 80px;
68 | font-size: 30px;
69 | font-weight: 700;
70 | }
71 |
72 | .bottom {
73 | height: 50%;
74 | }
75 |
76 | .trivia {
77 | height: 100%;
78 | display: flex;
79 | flex-direction: column;
80 | align-items: center;
81 | justify-content: space-around;
82 | }
83 |
84 | .question {
85 | width: 80%;
86 | background: linear-gradient(#100241, black);
87 | text-align: center;
88 | padding: 20px;
89 | border-radius: 10px;
90 | border: 2px solid white;
91 | font-size: 20px;
92 | }
93 |
94 | .answers {
95 | width: 100%;
96 | display: flex;
97 | justify-content: center;
98 | flex-wrap: wrap;
99 | }
100 |
101 | .answer {
102 | width: 40%;
103 | padding: 10px;
104 | margin: 0 10px 20px 10px;
105 | text-align: center;
106 | background: linear-gradient(#0e0124, #22074d);
107 | border: 1px solid white;
108 | border-radius: 15px;
109 | font-weight: 300;
110 | font-size: 20px;
111 | cursor: pointer;
112 | }
113 |
114 | .answer:hover,
115 | .answer.active {
116 | background: mediumblue;
117 | }
118 |
119 | .answer.correct {
120 | animation: correct 3s ease forwards;
121 | }
122 |
123 | @keyframes correct {
124 | 0%,
125 | 22%,
126 | 42% {
127 | background: mediumblue;
128 | }
129 | 20%,
130 | 40%,
131 | 60% {
132 | background: linear-gradient(#0e0124, #22074d);
133 | }
134 | 62%,
135 | 100% {
136 | background: green;
137 | }
138 | }
139 |
140 | .answer.wrong {
141 | animation: wrong 3s ease forwards;
142 | }
143 |
144 | @keyframes wrong {
145 | 0%,
146 | 22%,
147 | 42% {
148 | background: mediumblue;
149 | }
150 | 20%,
151 | 40%,
152 | 60% {
153 | background: linear-gradient(#0e0124, #22074d);
154 | }
155 | 62%,
156 | 100% {
157 | background: crimson;
158 | }
159 | }
160 |
161 | .endText {
162 | position: relative;
163 | top: 0;
164 | bottom: 0;
165 | left: 0;
166 | right: 0;
167 | margin: auto;
168 | }
169 |
170 | .start {
171 | width: 250px;
172 | height: 100px;
173 | display: flex;
174 | flex-direction: column;
175 | align-items: center;
176 | justify-content: space-around;
177 | position: relative;
178 | top: 0;
179 | bottom: 0;
180 | left: 0;
181 | right: 0;
182 | margin: auto;
183 | }
184 |
185 | .startInput {
186 | width: 100%;
187 | height: 30px;
188 | border: none;
189 | border-radius: 5px;
190 | text-align: center;
191 | font-size: 18px;
192 | }
193 |
194 | .startInput:focus {
195 | outline: none;
196 | }
197 |
198 | .startButton {
199 | width: 100%;
200 | height: 30px;
201 | border: none;
202 | border-radius: 5px;
203 | cursor: pointer;
204 | font-size: 18px;
205 | font-weight: 500;
206 | }
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import { useEffect, useMemo, useState } from "react";
3 | import Start from "./components/Start";
4 | import Timer from "./components/Timer";
5 | import Trivia from "./components/Trivia";
6 |
7 | function App() {
8 | const [username, setUsername] = useState(null);
9 | const [timeOut, setTimeOut] = useState(false);
10 | const [questionNumber, setQuestionNumber] = useState(1);
11 | const [earned, setEarned] = useState("$ 0");
12 |
13 | const data = [
14 | {
15 | id: 1,
16 | question: "Rolex is a company that specializes in what type of product?",
17 | answers: [
18 | {
19 | text: "Phone",
20 | correct: false,
21 | },
22 | {
23 | text: "Watches",
24 | correct: true,
25 | },
26 | {
27 | text: "Food",
28 | correct: false,
29 | },
30 | {
31 | text: "Cosmetic",
32 | correct: false,
33 | },
34 | ],
35 | },
36 | {
37 | id: 2,
38 | question: "When did the website `Facebook` launch?",
39 | answers: [
40 | {
41 | text: "2004",
42 | correct: true,
43 | },
44 | {
45 | text: "2005",
46 | correct: false,
47 | },
48 | {
49 | text: "2006",
50 | correct: false,
51 | },
52 | {
53 | text: "2007",
54 | correct: false,
55 | },
56 | ],
57 | },
58 | {
59 | id: 3,
60 | question: "Who played the character of harry potter in movie?",
61 | answers: [
62 | {
63 | text: "Johnny Deep",
64 | correct: false,
65 | },
66 | {
67 | text: "Leonardo Di Caprio",
68 | correct: false,
69 | },
70 | {
71 | text: "Denzel Washington",
72 | correct: false,
73 | },
74 | {
75 | text: "Daniel Red Cliff",
76 | correct: true,
77 | },
78 | ],
79 | },
80 | ];
81 |
82 | const moneyPyramid = useMemo(
83 | () =>
84 | [
85 | { id: 1, amount: "$ 100" },
86 | { id: 2, amount: "$ 200" },
87 | { id: 3, amount: "$ 300" },
88 | { id: 4, amount: "$ 500" },
89 | { id: 5, amount: "$ 1.000" },
90 | { id: 6, amount: "$ 2.000" },
91 | { id: 7, amount: "$ 4.000" },
92 | { id: 8, amount: "$ 8.000" },
93 | { id: 9, amount: "$ 16.000" },
94 | { id: 10, amount: "$ 32.000" },
95 | { id: 11, amount: "$ 64.000" },
96 | { id: 12, amount: "$ 125.000" },
97 | { id: 13, amount: "$ 250.000" },
98 | { id: 14, amount: "$ 500.000" },
99 | { id: 15, amount: "$ 1.000.000" },
100 | ].reverse(),
101 | []
102 | );
103 |
104 | useEffect(() => {
105 | questionNumber > 1 &&
106 | setEarned(moneyPyramid.find((m) => m.id === questionNumber - 1).amount);
107 | }, [questionNumber, moneyPyramid]);
108 |
109 | return (
110 |
111 | {!username ? (
112 |
113 | ) : (
114 | <>
115 |
116 | {timeOut ? (
117 |
You earned: {earned}
118 | ) : (
119 | <>
120 |
128 |
129 |
135 |
136 | >
137 | )}
138 |
139 |
140 |
141 | {moneyPyramid.map((m) => (
142 | -
149 | {m.id}
150 | {m.amount}
151 |
152 | ))}
153 |
154 |
155 | >
156 | )}
157 |
158 | );
159 | }
160 |
161 | export default App;
162 |
--------------------------------------------------------------------------------