diff --git a/README.md b/README.md index d1f22b80..69a19543 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ # Redux quiz group project -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +The assignment was to to build a quiz game using Redux. A multiple-choice quiz, with our own questions and a bunch of possible answers to present to the users. +This was a group project made by [Jonas](https://github.com/jonsjak), [Johanna](https://github.com/JohLeo), [Vera](https://github.com/Vera-Sjunnesson) & [Sammy](https://github.com/sammyolsson) ## The problem -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +We used Figma as a project planner, to list tasks and sketch design. +Regarding coding we went with the pair-programming approach with mobile first in mind. +We focused on the functionality of the components first and then styled the quiz with styled components. ## View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +https://cute-pasca-d39626.netlify.app/ diff --git a/package-lock.json b/package-lock.json index 8bd1eecb..52f58cce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,9 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.2", - "react-scripts": "^5.0.1" + "react-scripts": "^5.0.1", + "styled-components": "^5.3.9", + "styled-components.macro": "^1.0.0" }, "devDependencies": { "react-scripts": "5.0.1" @@ -132,7 +134,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -2156,6 +2157,29 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "dependencies": { + "@emotion/memoize": "^0.8.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "node_modules/@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -3721,8 +3745,7 @@ "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "node_modules/@types/prettier": { "version": "2.6.4", @@ -4868,7 +4891,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -4927,6 +4949,26 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.1.tgz", + "integrity": "sha512-c8lJlszObVQPguHkI+akXv8+Jgb9Ccujx0EetL7oIvwU100LxO6XAGe45qry37wUL40a5U9f23SYrivro2XKhA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.21", + "picomatch": "^2.3.0" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" + }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -5264,6 +5306,14 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5699,7 +5749,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -5751,6 +5800,14 @@ "postcss": "^8.4" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz", @@ -5959,6 +6016,16 @@ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", "dev": true }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -6619,7 +6686,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -8968,8 +9034,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.4", @@ -11588,8 +11653,7 @@ "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema": { "version": "0.4.0", @@ -11724,8 +11788,7 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/loader-runner": { "version": "4.3.0", @@ -11767,8 +11830,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -12503,7 +12565,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -14012,8 +14073,7 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -15342,6 +15402,11 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -15751,6 +15816,61 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-components": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.9.tgz", + "integrity": "sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/styled-components.macro": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/styled-components.macro/-/styled-components.macro-1.0.0.tgz", + "integrity": "sha512-MrGQOP3VhXk3iwJIEM/Qx55u5TZ9x3H5fOyVMH+oLqf3b8nbozsMY1eYghPChwOALh99qrDGpaEXzhhOU583jg==", + "dependencies": { + "babel-plugin-styled-components": "^1.8.0" + }, + "peerDependencies": { + "babel-plugin-macros": ">=2", + "styled-components": ">=2" + } + }, + "node_modules/styled-components.macro/node_modules/babel-plugin-styled-components": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz", + "integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-module-imports": "^7.15.4", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, "node_modules/stylehacks": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", @@ -17479,7 +17599,6 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, "engines": { "node": ">= 6" } @@ -17604,7 +17723,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, "requires": { "@babel/types": "^7.18.6" } @@ -18936,6 +19054,29 @@ "dev": true, "requires": {} }, + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -20105,8 +20246,7 @@ "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prettier": { "version": "2.6.4", @@ -20976,7 +21116,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dev": true, "requires": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", @@ -21020,6 +21159,23 @@ "@babel/helper-define-polyfill-provider": "^0.3.2" } }, + "babel-plugin-styled-components": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.1.tgz", + "integrity": "sha512-c8lJlszObVQPguHkI+akXv8+Jgb9Ccujx0EetL7oIvwU100LxO6XAGe45qry37wUL40a5U9f23SYrivro2XKhA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.21", + "picomatch": "^2.3.0" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" + }, "babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -21288,6 +21444,11 @@ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "dev": true }, + "camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" + }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -21626,7 +21787,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -21660,6 +21820,11 @@ "postcss-selector-parser": "^6.0.9" } }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" + }, "css-declaration-sorter": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz", @@ -21790,6 +21955,16 @@ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", "dev": true }, + "css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -22290,7 +22465,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -24008,8 +24182,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.4", @@ -25940,8 +26113,7 @@ "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema": { "version": "0.4.0", @@ -26044,8 +26216,7 @@ "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "loader-runner": { "version": "4.3.0", @@ -26075,8 +26246,7 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.debounce": { "version": "4.0.8", @@ -26624,7 +26794,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -27550,8 +27719,7 @@ "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "prelude-ls": { "version": "1.2.1", @@ -28546,6 +28714,11 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -28860,6 +29033,44 @@ "dev": true, "requires": {} }, + "styled-components": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.9.tgz", + "integrity": "sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + } + }, + "styled-components.macro": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/styled-components.macro/-/styled-components.macro-1.0.0.tgz", + "integrity": "sha512-MrGQOP3VhXk3iwJIEM/Qx55u5TZ9x3H5fOyVMH+oLqf3b8nbozsMY1eYghPChwOALh99qrDGpaEXzhhOU583jg==", + "requires": { + "babel-plugin-styled-components": "^1.8.0" + }, + "dependencies": { + "babel-plugin-styled-components": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz", + "integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-module-imports": "^7.15.4", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + } + } + } + }, "stylehacks": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", @@ -30208,8 +30419,7 @@ "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yargs": { "version": "16.2.0", diff --git a/package.json b/package.json index 58da74eb..4f4eb4b0 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.2", - "react-scripts": "^5.0.1" + "react-scripts": "^5.0.1", + "styled-components": "^5.3.9", + "styled-components.macro": "^1.0.0" }, "scripts": { "start": "react-scripts start", diff --git a/src/App.js b/src/App.js index 690bd373..19395c96 100644 --- a/src/App.js +++ b/src/App.js @@ -2,9 +2,9 @@ import React from 'react'; import { Provider } from 'react-redux'; import { combineReducers, configureStore } from '@reduxjs/toolkit'; import { quiz } from 'reducers/quiz'; - import { CurrentQuestion } from 'components/CurrentQuestion'; +/* combineReducers lets us add many reducers to the state */ const reducer = combineReducers({ quiz: quiz.reducer }); diff --git a/src/components/Accordion.js b/src/components/Accordion.js new file mode 100644 index 00000000..f7c90de8 --- /dev/null +++ b/src/components/Accordion.js @@ -0,0 +1,45 @@ +import React, { useState } from 'react'; +import { useSelector } from 'react-redux'; +import { StyledAccordion, StyledButton, AccordionH5, AnswersContainer } from './Style/GlobalStyle'; + +export const Accordion = () => { + const questions = useSelector((store) => store.quiz.questions); + const answers = useSelector((store) => store.quiz.answers); + const [activeAccordion, setActiveAccordion] = useState(null); + + const handleAccordionClick = (index) => { + /* Checks the index of the clicked button against activeAccordion + and alter it's class */ + setActiveAccordion(index === activeAccordion ? null : index); + }; + + return ( + + {questions.map((question, index) => ( +
+ handleAccordionClick(index)}> + {question.questionText} + + + {activeAccordion === index && ( + +

+ Your answer: + {answers[index].answer} +

+

+ Correct answer: + {question.options[question.correctAnswerIndex]} +

+
+ )} +
+ ))} +
+ ); +}; diff --git a/src/components/AnswerOptions.js b/src/components/AnswerOptions.js new file mode 100644 index 00000000..74c66341 --- /dev/null +++ b/src/components/AnswerOptions.js @@ -0,0 +1,89 @@ +import React, { useState } from 'react' +import { useSelector, useDispatch } from 'react-redux' +import { quiz } from 'reducers/quiz' +import { StyledButton } from './Style/GlobalStyle'; + +export const AnswerOptions = () => { + const question = useSelector((state) => state.quiz.questions[state.quiz.currentQuestionIndex]) + const dispatch = useDispatch() + const [answerColor, setAnswerColor] = useState('pink'); + const [showSelectedColor, setShowSelectedColor] = useState(false); + const [selectedIndex, setSelectedIndex] = useState(); + const [disabled, setDisabled] = useState(false); + const [showCorrectColor, setShowCorrectColor] = useState(); + const [correctIndex, setCorrectIndex] = useState(); + const [correctColor, setCorrectColor] = useState(); + + if (!question) { + return

Oh no! I could not find the current question!

+ } + + const handleOptionClick = (option, index) => { + dispatch(quiz.actions.submitAnswer({ questionId: question.id, answerIndex: index })) + setSelectedIndex(index); + setCorrectIndex(question.correctAnswerIndex); + setDisabled(true) + + setShowSelectedColor(true); + if (index === question.correctAnswerIndex) { + setAnswerColor('olivedrab'); + setShowCorrectColor(false); + setCorrectColor('olivedrab'); + } else { + setAnswerColor('orangered'); + setShowCorrectColor(true); + setCorrectColor('olivedrab'); + } + + setTimeout(() => { + setSelectedIndex(100) + dispatch(quiz.actions.goToNextQuestion()) + setShowSelectedColor(false); + setAnswerColor('#D1E64B') + setShowCorrectColor(false); + setCorrectColor(''); + setDisabled(false) + }, 1000) + } + + const handleMouseEnter = (e) => { + e.target.style.boxShadow = '0px 0px 0px 0.5em #F36B2B'; + } + + const handleMouseLeave = (e) => { + e.target.style.boxShadow = '0px 0px 0px 0.5em #D1E64B'; + } + + const getOptionColor = (index) => { + if (showSelectedColor && index === selectedIndex) { + return answerColor; + } else if (showCorrectColor && index === correctIndex) { + return correctColor; + } else { + return '#D1E64B'; + } + }; + + return ( + <> + {question.options.map((option, index) => ( +
+ handleOptionClick(option, index)}> + {option} + +
+ ))} + + ) +} \ No newline at end of file diff --git a/src/components/CurrentQuestion.js b/src/components/CurrentQuestion.js index 36ee2224..3e6afc5e 100644 --- a/src/components/CurrentQuestion.js +++ b/src/components/CurrentQuestion.js @@ -1,16 +1,35 @@ import React from 'react' import { useSelector } from 'react-redux' +import { Starter } from 'components/Starter'; +import Summary from './Summary' +import Progressbar from './Progressbar' +import RestartBtn from './RestartBtn' +import { AnswerOptions } from './AnswerOptions'; +import { OptionContainer, BackgroundStarter, InnerContainer } from './Style/GlobalStyle'; export const CurrentQuestion = () => { const question = useSelector((state) => state.quiz.questions[state.quiz.currentQuestionIndex]) + const isQuizOver = useSelector((store) => store.quiz.quizOver) + const quizStarted = useSelector((store) => store.quiz.quizStarted) if (!question) { return

Oh no! I could not find the current question!

} return ( -
-

Question: {question.questionText}

-
+ + {!quizStarted && } + {!isQuizOver && quizStarted && ( + +

{question.questionText}

+ + + + + +
)} + {isQuizOver && ( + )} + ) -} +} \ No newline at end of file diff --git a/src/components/Progressbar.js b/src/components/Progressbar.js new file mode 100644 index 00000000..656ca9aa --- /dev/null +++ b/src/components/Progressbar.js @@ -0,0 +1,70 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import styled from 'styled-components'; + +const ProgressContainer = styled.div` + width: 30vw; + height: 10px; + border-radius: 50px; + position: relative; + overflow: hidden; + display: flex; + margin-top: 5px; + justify-content: space-between; + align-items: center; + border: 0.5px solid black; + + } +`; + +const ProgressStatus = styled.div` + width: ${(props) => props.width}; + background: linear-gradient( + 90deg, + var(--yellow) 0%, + var(--orange) 100% + ); + transition: width 1s ease-in-out; + height: 100%; + position: absolute; + top: 0; +`; +const Amount = styled.label` + color: black; + text-align: center; + font-size: 1.25vw; + font-weight: bold; + line-height: 2vw; + white-space: wrap; + letter-spacing: 0.1vw; + +` + +const Wrapper = styled.div` +display: flex; +align-items: center; +justify-content: center; +flex-direction: column; +padding: 3em; +padding-bottom: 2em; +` + +const ProgressBar = () => { + const question = useSelector((state) => state.quiz.questions[state.quiz.currentQuestionIndex]) + const amountOfQuestions = useSelector((state) => state.quiz.questions.length); + const percentCompleted = `${useSelector( + (store) => (store.quiz.currentQuestionIndex * 100) / store.quiz.questions.length + )}%`; + return ( + + THIS IS QUESTION NO   + {question.id} / {amountOfQuestions} + + + + + + + ) +} +export default ProgressBar; \ No newline at end of file diff --git a/src/components/RestartBtn.js b/src/components/RestartBtn.js new file mode 100644 index 00000000..c785f238 --- /dev/null +++ b/src/components/RestartBtn.js @@ -0,0 +1,23 @@ +import React from 'react' +import { useDispatch } from 'react-redux' +import { quiz } from 'reducers/quiz' +import { StyledButton } from './Style/GlobalStyle' + +const RestartBtn = () => { + const dispatch = useDispatch() + const onRestart = () => { + dispatch(quiz.actions.restart()) + } + + return ( +
+ + RESTART + +
+ ) +} + +export default RestartBtn; \ No newline at end of file diff --git a/src/components/Starter.js b/src/components/Starter.js new file mode 100644 index 00000000..eec6043c --- /dev/null +++ b/src/components/Starter.js @@ -0,0 +1,34 @@ +/* eslint-disable max-len */ +import React from 'react' +import { useDispatch } from 'react-redux' +import { startQuiz } from 'reducers/quiz' +import { StartContainer, StyledButton } from './Style/GlobalStyle' + +export const Starter = () => { + const dispatch = useDispatch() + + const handleStartQuiz = () => { + dispatch(startQuiz()) + } + + return ( + +

+ Welcome to the Zombie Quiz Game! +

+

+ In this game, you will be tested on your knowledge of everything zombie-related.
+ Do you think you have what it takes to make it through the apocalypse?
+ Put your knowledge to the test and find out!
+ Are you ready to survive the zombie apocalypse?
+ + Let's find out! +

+ + START ZOMBIE QUIZ + +
+ ) +} \ No newline at end of file diff --git a/src/components/Style/GlobalStyle.js b/src/components/Style/GlobalStyle.js new file mode 100644 index 00000000..8723dcb6 --- /dev/null +++ b/src/components/Style/GlobalStyle.js @@ -0,0 +1,212 @@ +import styled, { createGlobalStyle, css } from 'styled-components'; +import backgroundimg from 'images/startimg.jpg'; + +const GlobalStyles = createGlobalStyle` +*, +body { + margin: 0; + padding: 0; +} +` + +export const BackgroundStarter = styled.div` + background-image: url(${backgroundimg}); + display: flex; + background-repeat: no-repeat; + background-size: cover; + position: absolute; + width: 100vw; + height: 100vh; +` + +export const StartContainer = styled.section` + align-items: center; + justify-content: center; + background-color: var(--yellow); + display: flex; + flex-direction: column; + gap: 10px; + height: 75%; + width: 75%; + border-radius: 25px; + margin: auto; + top: 10%; + padding: 20px 20px; + + h1 { + font-size: 1.4rem; + text-align: center; + text-transform: uppercase; + padding: 10px 4px; + margin: 0; + } + + p { + font-size: 0.9rem; + line-height: 125%; + padding: 0 20px; + text-align: center; + } + + @media (min-width: 767px) { + + h1 { + font-size: 2.5rem; + padding: 0 20px; + } + + p { + font-size: 1rem; + line-height: 125%; + padding: 0 70px 0 70px; + } + } + + @media (min-width: 1024px) { + background-color: var(--yellowtrans); + + h1 { + font-size: 4.4rem; + padding: 0 20px; + } + + p { + font-size: 1.4rem; + line-height: 125%; + padding: 0 70px 0 70px; + } +} +` + +export const OptionContainer = styled.div` + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-rows: repeat(2,1fr); + width: 100%; + gap: 25px; + justify-content: center; + margin: auto; + + @media (min-width: 768px) and (max-width: 1023px) { + width: 400px; + gap: 30px; + } + + @media (min-width: 1023px) { + width: 600px; + gap: 30px; + } +` + +export const InnerContainer = styled.section` + background-color: var(--eggpink); + border-radius: 25px; + top: 10%; + height: 80%; + width: 75%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + margin: auto; + padding: 20px 20px; + + @media (min-width: 768px) and (max-width: 1023px) { + padding: 20px 50px; + } + + @media (min-width: 1023px) { + height: 75%; + padding: 20px 50px; + } +` + +export const SummaryContainer = styled.div` + height: 400px; + overflow: scroll; + ` +export const StyledButton = styled.button` + + background-color: #F36B2B; + color: black; + font-size: 1.25vw; + letter-spacing: 0.5vw; + font-weight: bold; + padding: 10px 30px; + border-radius: 10px; + top: 20px; + outline: none; + border: none; + cursor: pointer; + + :hover { + background-color: #D1E64B; + } + + ${(props) => props.optionbutton && css` + letter-spacing: 0.1vw; + width: 100%; + height: 70px; + display: flex; + justify-content: center; + align-items: center; + font-size: 16px; + padding: 10px; + border none; + background: #D1E64B; + -ms-hyphens: auto; + -moz-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; + + word-break: break-all; + word-break: break-word; + overflow-wrap: break-word; + -webkit-box-shadow: 0px 0px 0px 0.5em #D1E64B; + -moz-box-shadow: 0px 0px 0px 0.5em #D1E64B; + box-shadow: 0px 0px 0px 0.5em #D1E64B; + `} + + ${(props) => props.accordian && css` + letter-spacing: 0.1vw; + outline: none; + border: none; + background: #d1e64bce; + width: 100%; + + :hover { + background-color: #D1E64B; + } + + `} +` + +export const AccordionH5 = styled.h5` + font-weight: 900; + font-size: 16px; + padding: 0; + margin: 12px; + font-family: 'Syne Mono', monospace; + } +` + +export const StyledAccordion = styled.div` + overflow-y: scroll; + margin-top: 30px; + display: flex; + flex-direction: column; + align-items: stretch; + gap: 10px; + width: 100%; + } +` + +export const AnswersContainer = styled.div` + background: #D1E64B; + padding: 10px 20px; + border-radius: 10px; + } +` +/* Add styling for active/inactive accordion and hovering? */ + +export default GlobalStyles; \ No newline at end of file diff --git a/src/components/Summary.js b/src/components/Summary.js new file mode 100644 index 00000000..0f49dec1 --- /dev/null +++ b/src/components/Summary.js @@ -0,0 +1,22 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import RestartBtn from './RestartBtn'; +import { InnerContainer } from './Style/GlobalStyle'; +import { Accordion } from './Accordion'; + +const Summary = () => { + const answers = useSelector((store) => store.quiz.answers); + const correctAnswers = answers.filter((item) => item.isCorrect) + + return ( + + {correctAnswers.length > 5 ? (

Congratulations! You survived the Zombie apocalypse!

) + : (

Oh no! You got infected! Better luck next time

)} +

Your score is {correctAnswers.length}/{answers.length}

+ + +
+ ) +} + +export default Summary; \ No newline at end of file diff --git a/src/images/startimg.jpg b/src/images/startimg.jpg new file mode 100644 index 00000000..0b2f9f39 Binary files /dev/null and b/src/images/startimg.jpg differ diff --git a/src/index.css b/src/index.css index 4a1df4db..3b8df589 100644 --- a/src/index.css +++ b/src/index.css @@ -1,10 +1,21 @@ +@import url('https://fonts.googleapis.com/css2?family=Syne+Mono&display=swap'); + +:root { + --orange: #F36B2B; + --yellow: #D1E64B; + --text: #141414; + --yellowtrans: #d1e64b94; + --eggpink: #c09393cb; + --color: #e45fbc; + } + + body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; + font-family: 'Syne Mono', monospace; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + color: var(--text); } code { diff --git a/src/reducers/quiz.js b/src/reducers/quiz.js index a38bbf68..2e0e184d 100644 --- a/src/reducers/quiz.js +++ b/src/reducers/quiz.js @@ -1,23 +1,40 @@ +/* eslint-disable max-len */ import { createSlice } from '@reduxjs/toolkit' -// Change these to your own questions! const questions = [ - { id: 1, questionText: 'Who set the Olympic record for the 100m dash in 2012?', options: ['Usain Bolt', 'Justin Gatlin', 'Tyson Gay', 'Asafa Powell'], correctAnswerIndex: 0 }, - { id: 2, questionText: 'When was Michael Phelps last named male World Swimmer of the Year?', options: ['2012', '2014', '2016', '2018'], correctAnswerIndex: 2 } + { id: 1, questionText: 'Which of the following is not a common way to kill a zombie?', options: ['Shooting it in the head', 'Decapitating it', 'Stabbing it in the heart', 'Poisoning it'], correctAnswerIndex: 3 }, + { id: 2, questionText: 'What is the most common way for someone to become a zombie?', options: ['Being bitten by a zombie', 'Eating contaminated food', 'Being exposed to radiation', 'Contracting a virus'], correctAnswerIndex: 0 }, + { id: 3, questionText: 'Which of the following is not a type of zombie?', options: ['Runner', 'Walker', 'Crawler', 'Jumper'], correctAnswerIndex: 3 }, + { id: 4, questionText: 'What is the best way to survive a zombie apocalypse?', options: ['Stay in one place and wait for rescue', 'Gather supplies and weapons', 'Join a group of survivors', 'Run as fast as you can'], correctAnswerIndex: 1 }, + { id: 5, questionText: 'What is the best weapon to use against zombies?', options: ['Baseball bat', 'Knife', 'Flamethrower', 'Bow and arrow'], correctAnswerIndex: 2 }, + { id: 6, questionText: 'What should you do if you encounter a zombie horde?', options: ['Stand your ground and fight', 'Run as fast as you can', 'Hide and wait for them to pass', 'Play dead and hope they dont notice you'], correctAnswerIndex: 1 }, + { id: 7, questionText: 'Which of the following is not a common symptom of zombification?', options: ['Pale skin', 'Bloodshot eyes', 'Rapid heartbeat', 'Drooling'], correctAnswerIndex: 2 }, + { id: 8, questionText: 'What is the best way to defend yourself against a zombie attack?', options: ['Use a shield', 'Wear heavy armor', 'Stay agile and avoid getting cornered', 'Use a distraction to escape'], correctAnswerIndex: 2 }, + { id: 9, questionText: 'Which of the following is not a popular zombie movie or TV show?', options: ['The Walking Dead', 'Zombieland', 'Shaun of the Dead', 'The Vampire Diaries'], correctAnswerIndex: 3 }, + { id: 10, questionText: 'What is the best way to stop a zombie outbreak?', options: ['Develop a vaccine', 'Quarantine infected individuals', 'Kill all zombies', 'Escape to another planet'], correctAnswerIndex: 1 } ] const initialState = { questions, answers: [], currentQuestionIndex: 0, - quizOver: false + quizOver: false, + quizStarted: false } +export const startQuiz = () => ({ + type: 'quiz/startQuiz' +}); + export const quiz = createSlice({ name: 'quiz', initialState, reducers: { + startQuiz: (state) => { + state.quizStarted = true; + }, + /** * Use this action when a user selects an answer to the question. * The answer will be stored in the `quiz.answers` state with the @@ -79,6 +96,5 @@ export const quiz = createSlice({ restart: () => { return initialState } - } })