├── .babelrc ├── .eslintrc.json ├── .github └── workflows │ ├── jekyll-gh-pages.yml │ └── linters.yml ├── .gitignore ├── .stylelintrc.json ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt └── src ├── App.css ├── App.js ├── components ├── Continents │ ├── ContinentDisplay.js │ ├── ContinentDisplay.module.css │ ├── ContinentImages.js │ ├── Continents.js │ ├── ContinentsAPI.js │ ├── SingleContinent.js │ └── SingleContinent.module.css ├── Countries │ ├── Countries.js │ ├── Country.js │ ├── countriesAPI.js │ └── country.css └── pages │ ├── Navbar.js │ ├── TopNav.js │ ├── navbar.css │ └── worldImages.png ├── index.css ├── index.js ├── redux ├── configureStore.js ├── continents │ ├── continentActions.js │ ├── getContinents.js │ └── reducerContinent.js └── countries │ ├── countriesAction.js │ ├── getCountries.js │ └── reducerCountries.js └── test ├── App.test.js ├── Continent.test.js ├── Navbar.test.js ├── __snapshots__ ├── App.test.js.snap ├── Continent.test.js.snap └── Navbar.test.js.snap └── reduxReducers.test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-react" 4 | ], 5 | "plugins": ["@babel/plugin-syntax-jsx"] 6 | } -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "parser": "@babel/eslint-parser", 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "ecmaVersion": 2018, 13 | "sourceType": "module" 14 | }, 15 | "extends": ["airbnb", "plugin:react/recommended", "plugin:react-hooks/recommended"], 16 | "plugins": ["react"], 17 | "rules": { 18 | "react/jsx-filename-extension": ["warn", { "extensions": [".js", ".jsx"] }], 19 | "react/react-in-jsx-scope": "off", 20 | "import/no-unresolved": "off", 21 | "no-shadow": "off" 22 | }, 23 | "overrides": [ 24 | { 25 | // feel free to replace with your preferred file pattern - eg. 'src/**/*Slice.js' or 'redux/**/*Slice.js' 26 | "files": ["src/**/*Slice.js"], 27 | // avoid state param assignment 28 | "rules": { "no-param-reassign": ["error", { "props": false }], 29 | "linebreak-style": ["error", "windows"] } 30 | } 31 | ], 32 | "ignorePatterns": [ 33 | "dist/", 34 | "build/" 35 | ] 36 | } -------------------------------------------------------------------------------- /.github/workflows/jekyll-gh-pages.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages 2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Build job 26 | build: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | - name: Setup Pages 32 | uses: actions/configure-pages@v3 33 | - name: Build with Jekyll 34 | uses: actions/jekyll-build-pages@v1 35 | with: 36 | source: ./ 37 | destination: ./_site 38 | - name: Upload artifact 39 | uses: actions/upload-pages-artifact@v2 40 | 41 | # Deployment job 42 | deploy: 43 | environment: 44 | name: github-pages 45 | url: ${{ steps.deployment.outputs.page_url }} 46 | runs-on: ubuntu-latest 47 | needs: build 48 | steps: 49 | - name: Deploy to GitHub Pages 50 | id: deployment 51 | uses: actions/deploy-pages@v2 52 | -------------------------------------------------------------------------------- /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | env: 6 | FORCE_COLOR: 1 7 | 8 | jobs: 9 | eslint: 10 | name: ESLint 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: "18.x" 17 | - name: Setup ESLint 18 | run: | 19 | npm install --save-dev eslint@7.x eslint-config-airbnb@18.x eslint-plugin-import@2.x eslint-plugin-jsx-a11y@6.x eslint-plugin-react@7.x eslint-plugin-react-hooks@4.x @babel/eslint-parser@7.x @babel/core@7.x @babel/plugin-syntax-jsx@7.x @babel/preset-env@7.x @babel/preset-react@7.x 20 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/react-redux/.eslintrc.json 21 | [ -f .babelrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/react-redux/.babelrc 22 | - name: ESLint Report 23 | run: npx eslint "**/*.{js,jsx}" 24 | stylelint: 25 | name: Stylelint 26 | runs-on: ubuntu-22.04 27 | steps: 28 | - uses: actions/checkout@v3 29 | - uses: actions/setup-node@v3 30 | with: 31 | node-version: "18.x" 32 | - name: Setup Stylelint 33 | run: | 34 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x 35 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/react-redux/.stylelintrc.json 36 | - name: Stylelint Report 37 | run: npx stylelint "**/*.{css,scss}" 38 | nodechecker: 39 | name: node_modules checker 40 | runs-on: ubuntu-22.04 41 | steps: 42 | - uses: actions/checkout@v3 43 | - name: Check node_modules existence 44 | run: | 45 | if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi 46 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"], 3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"], 4 | "rules": { 5 | "at-rule-no-unknown": [ 6 | true, 7 | { 8 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"] 9 | } 10 | ], 11 | "scss/at-rule-no-unknown": [ 12 | true, 13 | { 14 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"] 15 | } 16 | ], 17 | "csstree/validator": true 18 | }, 19 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"] 20 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "linebreak" 4 | ] 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 NOEL NOMGNE FOKA 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 7 |

Covid 19 metric

8 | 9 |
10 | 11 | # 📗 Table of Contents 12 | 13 | - [📗 Table of Contents](#-table-of-contents) 14 | - [📖 Covid 19 metric ](#-covid-19-metric-) 15 | - [🛠 Built With ](#-built-with-) 16 | - [Tech Stack ](#tech-stack-) 17 | - [Key Features ](#key-features-) 18 | - [💻 Getting Started ](#-getting-started-) 19 | - [Prerequisites](#prerequisites) 20 | - [Setup](#setup) 21 | - [Install](#install) 22 | - [Usage](#usage) 23 | - [Run tests](#run-tests) 24 | - [Deployment](#deployment) 25 | - [👥 Authors ](#-authors-) 26 | - [🔭 Future Features ](#-future-features-) 27 | - [🤝 Contributing ](#-contributing-) 28 | - [⭐️ Show your support ](#️-show-your-support-) 29 | - [🙏 Acknowledgments ](#-acknowledgments-) 30 | - [📝 License ](#-license-) 31 | 32 | # 📖 Covid 19 metric 33 | 34 | The COVID-19 pandemic, also known as the coronavirus pandemic, is a global pandemic of coronavirus disease 2019 (COVID-19) caused by severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2). The novel virus was first identified from an outbreak in Wuhan, China, in December 2019. 35 | ## 🛠 Built With 36 | - React 37 | - Redux 38 | - JAVASCRIPT 39 | - JSX 40 | -ES6 41 | 42 | ### Tech Stack 43 | 44 |
45 | Client 46 | 51 |
52 | 53 | ### Key Features 54 | 55 | - **Responsive Design** 56 | - **dynamic** 57 | - **Code Quality** 58 | 59 |

(back to top)

60 | 61 | ## 💻 Getting Started 62 | 63 | 64 | 65 | ### Prerequisites 66 | 67 | In order to run this project you need: 68 | 69 | - You need to have NodeJS installed 70 | - A Web Browser (Google Chrome, Firefox, etc) 71 | - A Code Editor (Notepad++, VSCode, etc) 72 | 73 | ### Setup 74 | 75 | Clone this repository to your desired folder: 76 | 77 | ```sh 78 | git clone your link repo https://github.com/noelfoka/react-capstone-project.git 79 | 80 | cd your folder name 81 | ``` 82 | 83 | ### Install 84 | 85 | Install this project with: 86 | 87 | ```sh 88 | npm install 89 | ``` 90 | 91 | ### Usage 92 | 93 | To run the project, execute the following command: 94 | 95 | ```sh 96 | npm start 97 | ``` 98 | 99 | ### Run tests 100 | 101 | To run tests, run the following command: 102 | 103 | npx hint . 104 | 105 | ### Deployment 106 | 107 | [Live Demo](https://64f821ff5a5747438394413e--calm-truffle-8ad364.netlify.app/) 108 | 109 |

(back to top)

110 | 111 | ## 👥 Authors 112 | 113 | 👤 **Noel Foka ** 114 | 115 | - GitHub: [@noelfoka](https://github.com/noelfoka) 116 | - Twitter: [@twitterhandle](https://twitter.com/noelnomgne) 117 | - LinkedIn: [@LinkedIn](https://www.linkedin.com/noelfoka/) 118 | 119 |

(back to top)

120 | 121 | ## 🔭 Future Features 122 | 123 | - [ ] **deploy** 124 | - [ ] **record video** 125 | 126 |

(back to top)

127 | 128 | ## 🤝 Contributing 129 | 130 | Contributions, issues, and feature requests are welcome! 131 | 132 | Feel free to check the [issues page](../../issues/). 133 | 134 |

(back to top)

135 | 136 | ## ⭐️ Show your support 137 | 138 | If you like this project give me a star. 139 | 140 |

(back to top)

141 | 142 | ## 🙏 Acknowledgments 143 | 144 | - [Nelson Sakwa](https://www.behance.net/sakwadesignstudio) - for the original design 145 | - [Covid-19 API](https://covid19api.com/) - for displaying the covid-19 data 146 | - [Flags API](https://countryflagsapi.com/). - for displaying the flags 147 | - Hat tip to [Microverse](https://www.microverse.org/)) and all the staff 148 | - Thanks to My coding Partners 149 | - Thanks to My Morning-session-group and Standup-team Partners and 150 | - Thanks to Code Reviewers 151 | 152 |

(back to top)

153 | 154 | ## 📝 License 155 | 156 | This project is [MIT](./LICENSE) licensed. 157 | 158 | 159 |

(back to top)

-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-capstone-project", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@fortawesome/free-solid-svg-icons": "^6.4.2", 7 | "@fortawesome/react-fontawesome": "^0.2.0", 8 | "@reduxjs/toolkit": "^1.9.5", 9 | "@testing-library/jest-dom": "^5.17.0", 10 | "@testing-library/react": "^13.4.0", 11 | "@testing-library/user-event": "^13.5.0", 12 | "prop-types": "^15.8.1", 13 | "react": "^18.2.0", 14 | "react-bootstrap": "^2.8.0", 15 | "react-dom": "^18.2.0", 16 | "react-redux": "^8.1.2", 17 | "react-router-bootstrap": "^0.26.2", 18 | "react-router-dom": "^6.15.0", 19 | "react-scripts": "5.0.1", 20 | "redux": "^4.2.1", 21 | "redux-logger": "^3.0.6", 22 | "redux-thunk": "^2.4.2", 23 | "web-vitals": "^2.1.4" 24 | }, 25 | "scripts": { 26 | "start": "react-scripts start", 27 | "build": "react-scripts build", 28 | "test": "react-scripts test", 29 | "eject": "react-scripts eject" 30 | }, 31 | "eslintConfig": { 32 | "extends": [ 33 | "react-app", 34 | "react-app/jest" 35 | ] 36 | }, 37 | "browserslist": { 38 | "production": [ 39 | ">0.2%", 40 | "not dead", 41 | "not op_mini all" 42 | ], 43 | "development": [ 44 | "last 1 chrome version", 45 | "last 1 firefox version", 46 | "last 1 safari version" 47 | ] 48 | }, 49 | "devDependencies": { 50 | "@babel/core": "^7.22.15", 51 | "@babel/eslint-parser": "^7.22.15", 52 | "@babel/plugin-syntax-jsx": "^7.22.5", 53 | "@babel/preset-react": "^7.22.15", 54 | "eslint": "^7.32.0", 55 | "eslint-config-airbnb": "^18.2.1", 56 | "eslint-plugin-import": "^2.28.1", 57 | "eslint-plugin-jsx-a11y": "^6.7.1", 58 | "eslint-plugin-react": "^7.33.2", 59 | "eslint-plugin-react-hooks": "^4.6.0", 60 | "redux-mock-store": "^1.5.4", 61 | "stylelint": "^13.13.1", 62 | "stylelint-config-standard": "^21.0.0", 63 | "stylelint-csstree-validator": "^1.9.0", 64 | "stylelint-scss": "^3.21.0" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noelfoka/react-capstone-project/946f378ba8e2ceedaba13648c640aec12c7a7f8c/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noelfoka/react-capstone-project/946f378ba8e2ceedaba13648c640aec12c7a7f8c/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noelfoka/react-capstone-project/946f378ba8e2ceedaba13648c640aec12c7a7f8c/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: #fff; 25 | } 26 | 27 | @keyframes App-logo-spin { 28 | from { 29 | transform: rotate(0deg); 30 | } 31 | 32 | to { 33 | transform: rotate(360deg); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Route, Routes } from 'react-router-dom'; 2 | import './App.css'; 3 | import ContinentDisplay from './components/Continents/ContinentDisplay'; 4 | import Continents from './components/Continents/Continents'; 5 | import Countries from './components/Countries/Countries'; 6 | import Navbar from './components/pages/Navbar'; 7 | import TopNav from './components/pages/TopNav'; 8 | 9 | function App() { 10 | return ( 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | )} 23 | /> 24 | 28 | 29 | 30 | 31 | )} 32 | /> 33 | 34 | 35 | ); 36 | } 37 | 38 | export default App; 39 | -------------------------------------------------------------------------------- /src/components/Continents/ContinentDisplay.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { useDispatch, useSelector } from 'react-redux'; 3 | import { useParams } from 'react-router-dom'; 4 | import ContinentImages from './ContinentImages'; 5 | import { getContinent } from '../../redux/continents/getContinents'; 6 | import styles from './ContinentDisplay.module.css'; 7 | 8 | const ContinentDisplay = () => { 9 | const { continentName } = useParams(); 10 | const dispatch = useDispatch(); 11 | 12 | useEffect(() => { 13 | dispatch(getContinent(continentName)); 14 | }, []); 15 | 16 | const { cases, continent } = useSelector((state) => state.continentReducer); 17 | 18 | return ( 19 |
20 |
21 | continentImage 22 |
23 |

{continent}

24 |

{`TOTAL STATS: ${cases}`}

25 |
26 |
27 |
{`STATISTICS : ${continent?.toUpperCase()}`}
28 |
29 | ); 30 | }; 31 | 32 | export default ContinentDisplay; 33 | -------------------------------------------------------------------------------- /src/components/Continents/ContinentDisplay.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | display: flex; 3 | justify-content: space-around; 4 | color: #fff; 5 | background-color: #e14984; 6 | height: 200px; 7 | } 8 | 9 | .image { 10 | width: 100px; 11 | } 12 | 13 | .stats { 14 | font-size: large; 15 | color: rgb(255, 255, 255); 16 | padding-left: 10px; 17 | background-color: #ce5885; 18 | } 19 | -------------------------------------------------------------------------------- /src/components/Continents/ContinentImages.js: -------------------------------------------------------------------------------- 1 | const ContinentImages = { 2 | 'North America': 3 | 'https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/968afb90-ac92-44de-a6d9-bbd220b7fa64/dbjftku-ea7e50b6-880b-4384-bac8-f2887927100d.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzk2OGFmYjkwLWFjOTItNDRkZS1hNmQ5LWJiZDIyMGI3ZmE2NFwvZGJqZnRrdS1lYTdlNTBiNi04ODBiLTQzODQtYmFjOC1mMjg4NzkyNzEwMGQucG5nIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.hAbGE-0_k5QYHIfGcG9IyNbYcXd5gx1uXGnj-FFIJHU', 4 | Asia: 'https://www.wecinternational.org/admin/resources/asia-home.png', 5 | 'South America': 6 | 'https://www.orchidproject.org/wp-content/uploads/2019/03/saoutl.png', 7 | Europe: 8 | 'https://www.pngkit.com/png/full/390-3903931_created-with-raphal-europe-map-white-png.png', 9 | Africa: 10 | 'https://www.pngplay.com/wp-content/uploads/6/Africa-White-Map-Transparent-Background.png', 11 | 'Australia-Oceania': 12 | 'https://www.pngkit.com/png/full/76-765568_bp-oil-spill-in-great-australian-bight-would.png', 13 | }; 14 | 15 | export default ContinentImages; 16 | -------------------------------------------------------------------------------- /src/components/Continents/Continents.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { useDispatch, useSelector } from 'react-redux'; 3 | import { getContinents } from '../../redux/continents/getContinents'; 4 | import SingleContinent from './SingleContinent'; 5 | import styles from './SingleContinent.module.css'; 6 | 7 | const Continents = () => { 8 | const [search, setSearch] = useState([]); 9 | const dispatch = useDispatch(); 10 | 11 | useEffect(() => { 12 | dispatch(getContinents()); 13 | }, []); 14 | 15 | const continents = useSelector((state) => state.continentsReducer); 16 | 17 | useEffect(() => { 18 | setSearch(continents); 19 | }, [continents]); 20 | 21 | const SearchContinent = (event) => { 22 | setSearch( 23 | continents.filter((search) => search.continent.toLowerCase().includes(event.target.value)), 24 | ); 25 | }; 26 | 27 | return ( 28 | <> 29 |
30 |

CONTINENTS STATS

31 | 32 |
33 |
34 | {search?.map((continent) => ( 35 | 36 | ))} 37 |
38 | 39 | ); 40 | }; 41 | 42 | export default Continents; 43 | -------------------------------------------------------------------------------- /src/components/Continents/ContinentsAPI.js: -------------------------------------------------------------------------------- 1 | export const ContinentsAPI = async () => { 2 | const data = await fetch('https://corona.lmao.ninja/v2/continents') 3 | .then((response) => response.json()); 4 | 5 | return data; 6 | }; 7 | 8 | export const ContinentNameAPI = async (continentName) => { 9 | const data = await fetch(`https://corona.lmao.ninja/v2/continents/${continentName}`) 10 | .then((response) => response.json()); 11 | 12 | return data; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/Continents/SingleContinent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { useNavigate } from 'react-router-dom'; 4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 5 | import { faArrowAltCircleRight } from '@fortawesome/free-solid-svg-icons'; 6 | import styles from './SingleContinent.module.css'; 7 | import ContinentImages from './ContinentImages'; 8 | 9 | /* eslint-disable react/prop-types */ 10 | const SingleContinent = ({ continentData }) => { 11 | const navigate = useNavigate(); 12 | const { cases, continent } = continentData; 13 | 14 | return ( 15 | 30 | ); 31 | }; 32 | 33 | SingleContinent.protoTypes = { 34 | continentData: PropTypes.shape({ 35 | cases: PropTypes.number.isRequired, 36 | continent: PropTypes.string.isRequired, 37 | }).isRequired, 38 | }; 39 | 40 | export default SingleContinent; 41 | -------------------------------------------------------------------------------- /src/components/Continents/SingleContinent.module.css: -------------------------------------------------------------------------------- 1 | .continent { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: center; 5 | color: #fff; 6 | width: 50%; 7 | cursor: pointer; 8 | border: solid 0.1px #fff; 9 | background-color: #e14984; 10 | padding-top: 5px; 11 | } 12 | 13 | .continent:hover { 14 | background-color: #ac4164; 15 | } 16 | 17 | .container { 18 | display: flex; 19 | justify-content: space-around; 20 | align-items: center; 21 | padding: 5px; 22 | } 23 | 24 | .icon { 25 | display: block; 26 | color: rgb(255, 255, 255); 27 | margin-left: auto; 28 | } 29 | 30 | .search { 31 | display: flex; 32 | justify-content: space-around; 33 | align-items: center; 34 | gap: 10px; 35 | font-size: large; 36 | color: #fff; 37 | background-color: #cc5381; 38 | padding: 0 10px; 39 | } 40 | 41 | .search input { 42 | width: 50%; 43 | max-width: 200px; 44 | border: 0; 45 | outline: none; 46 | padding: 8px; 47 | } 48 | 49 | .searchbody { 50 | display: flex; 51 | flex-wrap: wrap; 52 | } 53 | 54 | .contImage { 55 | width: 70%; 56 | height: 100%; 57 | } 58 | -------------------------------------------------------------------------------- /src/components/Countries/Countries.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { useDispatch, useSelector } from 'react-redux'; 3 | import getCountries from '../../redux/countries/getCountries'; 4 | import Country from './Country'; 5 | 6 | const Countries = () => { 7 | const { countries } = useSelector((state) => state.continentReducer); 8 | const countriesString = countries?.toString(); 9 | 10 | const dispatch = useDispatch(); 11 | useEffect(() => { 12 | if (countriesString) { 13 | dispatch(getCountries(countriesString)); 14 | } 15 | }, [countriesString]); 16 | 17 | const countriesData = useSelector((state) => state.countriesReducer); 18 | 19 | return ( 20 |
21 | {countriesData.map((country) => ( 22 | 23 | ))} 24 |
25 | ); 26 | }; 27 | 28 | export default Countries; 29 | -------------------------------------------------------------------------------- /src/components/Countries/Country.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 4 | import { faArrowCircleRight } from '@fortawesome/free-solid-svg-icons'; 5 | import './country.css'; 6 | 7 | const Country = ({ countryDate }) => { 8 | const { country, cases, flag } = countryDate; 9 | 10 | return ( 11 |
12 | flagImage 13 |

{country}

14 |

{cases}

15 | 16 |
17 | ); 18 | }; 19 | 20 | Country.propTypes = { 21 | countryDate: PropTypes.shape({ 22 | cases: PropTypes.number.isRequired, 23 | country: PropTypes.string.isRequired, 24 | flag: PropTypes.string.isRequired, 25 | }).isRequired, 26 | }; 27 | 28 | export default Country; 29 | -------------------------------------------------------------------------------- /src/components/Countries/countriesAPI.js: -------------------------------------------------------------------------------- 1 | const CountriesAPINames = async (countriesNames) => { 2 | const data = await fetch(`https://corona.lmao.ninja/v2/countries/${countriesNames}`) 3 | .then((response) => response.json()); 4 | 5 | return data; 6 | }; 7 | 8 | export default CountriesAPINames; 9 | -------------------------------------------------------------------------------- /src/components/Countries/country.css: -------------------------------------------------------------------------------- 1 | .countryContainer { 2 | display: flex; 3 | align-items: center; 4 | gap: 10px; 5 | color: #fff; 6 | height: 50px; 7 | padding: 0 10px; 8 | } 9 | 10 | .countryContainer:nth-child(odd) { background-color: #c54c74; } 11 | .countryContainer:nth-child(even) { background-color: #aa4574; } 12 | 13 | .flag-image { 14 | width: 40px; 15 | height: 50%; 16 | } 17 | 18 | .cases { 19 | margin-left: auto; 20 | } 21 | 22 | .icon { 23 | color: #fff; 24 | } 25 | -------------------------------------------------------------------------------- /src/components/pages/Navbar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useLocation, useNavigate } from 'react-router-dom'; 3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 4 | import { faMicrophoneAlt, faUserCog, faArrowLeft } from '@fortawesome/free-solid-svg-icons'; 5 | import { useSelector } from 'react-redux'; 6 | import './navbar.css'; 7 | 8 | function Navbar() { 9 | const navigate = useNavigate(); 10 | const location = useLocation(); 11 | const { continent } = useSelector((state) => state.continentReducer); 12 | 13 | return ( 14 | 37 | ); 38 | } 39 | 40 | export default Navbar; 41 | -------------------------------------------------------------------------------- /src/components/pages/TopNav.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import WorldImage from './worldImages.png'; 4 | import classes from './navbar.css'; 5 | 6 | const TopNav = () => { 7 | const continents = useSelector((state) => state.continentsReducer); 8 | const [totalCases, setTotalCases] = useState(0); 9 | 10 | useEffect(() => { 11 | const totalNumber = continents?.reduce((prev, curr) => prev + curr.cases, 0); 12 | setTotalCases(totalNumber); 13 | }, [continents]); 14 | 15 | return ( 16 |
17 |
18 | 19 |
20 |

World Cases

21 |

{`STATS: ${totalCases}`}

22 |
23 |
24 |
25 | ); 26 | }; 27 | 28 | export default TopNav; 29 | -------------------------------------------------------------------------------- /src/components/pages/navbar.css: -------------------------------------------------------------------------------- 1 | .header { 2 | display: flex; 3 | justify-content: space-around; 4 | align-items: center; 5 | color: rgb(255, 255, 255); 6 | background-color: #e14984; 7 | } 8 | 9 | .image { 10 | width: 150px; 11 | height: 50%; 12 | } 13 | 14 | .nav { 15 | display: flex; 16 | align-items: baseline; 17 | background-color: #cf5383; 18 | text-align: center; 19 | color: rgb(255, 255, 255); 20 | padding: 0 10px; 21 | gap: 10px; 22 | } 23 | 24 | .stats { 25 | flex-grow: 1; 26 | } 27 | -------------------------------------------------------------------------------- /src/components/pages/worldImages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noelfoka/react-capstone-project/946f378ba8e2ceedaba13648c640aec12c7a7f8c/src/components/pages/worldImages.png -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: Lato, sans-serif; 4 | -webkit-font-smoothing: antialiased; 5 | -moz-osx-font-smoothing: grayscale; 6 | min-height: 100vh; 7 | background-color: #e14984; 8 | } 9 | 10 | code { 11 | font-family: 'Courier New', monospace; 12 | } 13 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { Provider } from 'react-redux'; 4 | import './index.css'; 5 | import App from './App'; 6 | import store from './redux/configureStore'; 7 | 8 | const root = ReactDOM.createRoot(document.getElementById('root')); 9 | root.render( 10 | 11 | 12 | 13 | 14 | , 15 | ); 16 | -------------------------------------------------------------------------------- /src/redux/configureStore.js: -------------------------------------------------------------------------------- 1 | import { legacy_createStore as createStore, applyMiddleware, combineReducers } from 'redux'; 2 | import thunk from 'redux-thunk'; 3 | import logger from 'redux-logger'; 4 | import { continentsReducer, continentReducer } from './continents/reducerContinent'; 5 | import countriesReducer from './countries/reducerCountries'; 6 | 7 | const reducer = combineReducers({ 8 | continentsReducer, 9 | continentReducer, 10 | countriesReducer, 11 | }); 12 | 13 | const store = createStore(reducer, applyMiddleware(thunk, logger)); 14 | 15 | export default store; 16 | -------------------------------------------------------------------------------- /src/redux/continents/continentActions.js: -------------------------------------------------------------------------------- 1 | export const GET_CONTINENTS = 'GET_CONTINENTS'; 2 | export const GET_CONTINENT = 'GET_CONTINENT'; 3 | 4 | export const ContinentsAction = (payload) => ({ 5 | type: GET_CONTINENTS, 6 | payload, 7 | }); 8 | 9 | export const ContinentAction = (payload) => ({ 10 | type: GET_CONTINENT, 11 | payload, 12 | }); 13 | -------------------------------------------------------------------------------- /src/redux/continents/getContinents.js: -------------------------------------------------------------------------------- 1 | import { ContinentsAPI, ContinentNameAPI } from '../../components/Continents/ContinentsAPI'; 2 | import { ContinentsAction, ContinentAction } from './continentActions'; 3 | 4 | export const getContinents = () => async (dispatch) => { 5 | const continents = await ContinentsAPI(); 6 | const objectContinents = []; 7 | 8 | continents.forEach((continent) => { 9 | objectContinents.push({ 10 | cases: continent.cases, 11 | continent: continent.continent, 12 | countries: continent.countries, 13 | }); 14 | }); 15 | 16 | dispatch(ContinentsAction(objectContinents)); 17 | }; 18 | 19 | export const getContinent = (continentName) => async (dispatch) => { 20 | const continent = await ContinentNameAPI(continentName); 21 | const objectContinent = { 22 | cases: continent.cases, 23 | continent: continent.continent, 24 | countries: continent.countries, 25 | }; 26 | 27 | dispatch(ContinentAction(objectContinent)); 28 | }; 29 | -------------------------------------------------------------------------------- /src/redux/continents/reducerContinent.js: -------------------------------------------------------------------------------- 1 | import { GET_CONTINENT, GET_CONTINENTS } from './continentActions'; 2 | 3 | export const continentsReducer = (state = [], action) => { 4 | switch (action.type) { 5 | case GET_CONTINENTS: 6 | return action.payload; 7 | default: 8 | return state; 9 | } 10 | }; 11 | 12 | export const continentReducer = (state = {}, action) => { 13 | switch (action.type) { 14 | case GET_CONTINENT: 15 | return action.payload; 16 | default: 17 | return state; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /src/redux/countries/countriesAction.js: -------------------------------------------------------------------------------- 1 | export const GET_COUNTRIES = 'GET_COUNTRIES'; 2 | 3 | export const CountriesAction = (payload) => ({ 4 | type: GET_COUNTRIES, 5 | payload, 6 | }); 7 | -------------------------------------------------------------------------------- /src/redux/countries/getCountries.js: -------------------------------------------------------------------------------- 1 | import CountriesAPINames from '../../components/Countries/countriesAPI'; 2 | import { CountriesAction } from './countriesAction'; 3 | 4 | const getCountries = (countriesNames) => async (dispatch) => { 5 | const countries = await CountriesAPINames(countriesNames); 6 | 7 | const objectCountries = []; 8 | countries.forEach((country) => { 9 | objectCountries.push({ 10 | country: country.country, 11 | cases: country.cases, 12 | flag: country.countryInfo.flag, 13 | }); 14 | }); 15 | 16 | dispatch(CountriesAction(objectCountries)); 17 | }; 18 | 19 | export default getCountries; 20 | -------------------------------------------------------------------------------- /src/redux/countries/reducerCountries.js: -------------------------------------------------------------------------------- 1 | import { GET_COUNTRIES } from './countriesAction'; 2 | 3 | const countriesReducer = (state = [], action) => { 4 | switch (action.type) { 5 | case GET_COUNTRIES: 6 | return action.payload; 7 | default: 8 | return state; 9 | } 10 | }; 11 | 12 | export default countriesReducer; 13 | -------------------------------------------------------------------------------- /src/test/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import { Provider } from 'react-redux'; 3 | import '@testing-library/jest-dom'; 4 | import logger from 'redux-logger'; 5 | import configureStore from 'redux-mock-store'; 6 | import thunk from 'redux-thunk'; 7 | import App from '../App'; 8 | 9 | const middlewares = [logger, thunk]; 10 | const mockStore = configureStore(middlewares); 11 | 12 | it('should render App Component', () => { 13 | const initialState = { 14 | cases: 567465, 15 | continent: 'Europe', 16 | countries: ['Germany', 'Netherlands'], 17 | }; 18 | const store = mockStore({ continentReducer: initialState }); 19 | render( 20 | 21 | 22 | , 23 | ); 24 | const textElement = screen.getByText(/Global Pandemic/i); 25 | expect(textElement).toBeInTheDocument(); 26 | }); 27 | 28 | test('Should Render App Component', () => { 29 | const initialState = { 30 | cases: 758746, 31 | continent: 'North America', 32 | countries: ['USA', 'Canada'], 33 | }; 34 | const store = mockStore({ continentReducer: initialState }); 35 | const tree = render( 36 | 37 | 38 | , 39 | ); 40 | expect(tree).toMatchSnapshot(); 41 | }); 42 | -------------------------------------------------------------------------------- /src/test/Continent.test.js: -------------------------------------------------------------------------------- 1 | import { render } from '@testing-library/react'; 2 | import { Provider } from 'react-redux'; 3 | import '@testing-library/jest-dom'; 4 | import { BrowserRouter as Router } from 'react-router-dom'; 5 | import configureStore from 'redux-mock-store'; 6 | import thunk from 'redux-thunk'; 7 | import Continents from '../components/Continents/Continents'; 8 | 9 | const applyMiddleware = [thunk]; 10 | const mockStore = configureStore(applyMiddleware); 11 | const continentsAction = () => ({ type: 'GET_CONTINENTS' }); 12 | 13 | function getContinents() { 14 | return (dispatch) => Promise.resolve(dispatch(continentsAction())); 15 | } 16 | 17 | test('should render mock Continent', () => { 18 | const store = mockStore(); 19 | store.dispatch(getContinents()) 20 | .then(() => { 21 | const actions = store.getActions(); 22 | expect(actions[0]).toEqual(continentsAction()); 23 | }); 24 | }); 25 | 26 | test('Should render mock Continent(Africa)', () => { 27 | const initialState = [{ cases: 23415, continent: 'Africa', countries: ['Ghana', 'Algeria'] }]; 28 | const store = mockStore(initialState); 29 | 30 | const tree = render( 31 | 32 | 33 | 34 | 35 | , 36 | ); 37 | expect(tree).toMatchSnapshot(); 38 | }); 39 | -------------------------------------------------------------------------------- /src/test/Navbar.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import { Provider } from 'react-redux'; 3 | import '@testing-library/jest-dom'; 4 | import { BrowserRouter as Router } from 'react-router-dom'; 5 | import store from '../redux/configureStore'; 6 | import Navbar from '../components/pages/Navbar'; 7 | 8 | it('should render Navbar Items', () => { 9 | render( 10 | 11 | 12 | 13 | 14 | , 15 | ); 16 | const Navlinks = screen.getByText(/COVID/i); 17 | expect(Navlinks).toBeInTheDocument(); 18 | }); 19 | 20 | it('should render Navbar Item', () => { 21 | const tree = render( 22 | 23 | 24 | 25 | 26 | , 27 | ); 28 | expect(tree).toMatchSnapshot(); 29 | }); 30 | -------------------------------------------------------------------------------- /src/test/__snapshots__/App.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Should Render App Component 1`] = ` 4 | Object { 5 | "asFragment": [Function], 6 | "baseElement": 7 |
8 | 52 |
53 |
56 | 61 |
62 |

63 | World Cases 64 |

65 |

66 | STATS: undefined 67 |

68 |
69 |
70 |
71 | 82 |
85 |
86 | , 87 | "container":
88 | 132 |
133 |
136 | 141 |
142 |

143 | World Cases 144 |

145 |

146 | STATS: undefined 147 |

148 |
149 |
150 |
151 | 162 |
165 |
, 166 | "debug": [Function], 167 | "findAllByAltText": [Function], 168 | "findAllByDisplayValue": [Function], 169 | "findAllByLabelText": [Function], 170 | "findAllByPlaceholderText": [Function], 171 | "findAllByRole": [Function], 172 | "findAllByTestId": [Function], 173 | "findAllByText": [Function], 174 | "findAllByTitle": [Function], 175 | "findByAltText": [Function], 176 | "findByDisplayValue": [Function], 177 | "findByLabelText": [Function], 178 | "findByPlaceholderText": [Function], 179 | "findByRole": [Function], 180 | "findByTestId": [Function], 181 | "findByText": [Function], 182 | "findByTitle": [Function], 183 | "getAllByAltText": [Function], 184 | "getAllByDisplayValue": [Function], 185 | "getAllByLabelText": [Function], 186 | "getAllByPlaceholderText": [Function], 187 | "getAllByRole": [Function], 188 | "getAllByTestId": [Function], 189 | "getAllByText": [Function], 190 | "getAllByTitle": [Function], 191 | "getByAltText": [Function], 192 | "getByDisplayValue": [Function], 193 | "getByLabelText": [Function], 194 | "getByPlaceholderText": [Function], 195 | "getByRole": [Function], 196 | "getByTestId": [Function], 197 | "getByText": [Function], 198 | "getByTitle": [Function], 199 | "queryAllByAltText": [Function], 200 | "queryAllByDisplayValue": [Function], 201 | "queryAllByLabelText": [Function], 202 | "queryAllByPlaceholderText": [Function], 203 | "queryAllByRole": [Function], 204 | "queryAllByTestId": [Function], 205 | "queryAllByText": [Function], 206 | "queryAllByTitle": [Function], 207 | "queryByAltText": [Function], 208 | "queryByDisplayValue": [Function], 209 | "queryByLabelText": [Function], 210 | "queryByPlaceholderText": [Function], 211 | "queryByRole": [Function], 212 | "queryByTestId": [Function], 213 | "queryByText": [Function], 214 | "queryByTitle": [Function], 215 | "rerender": [Function], 216 | "unmount": [Function], 217 | } 218 | `; 219 | -------------------------------------------------------------------------------- /src/test/__snapshots__/Continent.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Should render mock Continent(Africa) 1`] = ` 4 | Object { 5 | "asFragment": [Function], 6 | "baseElement": 7 |
8 | 19 |
22 |
23 | , 24 | "container":
25 | 36 |
39 |
, 40 | "debug": [Function], 41 | "findAllByAltText": [Function], 42 | "findAllByDisplayValue": [Function], 43 | "findAllByLabelText": [Function], 44 | "findAllByPlaceholderText": [Function], 45 | "findAllByRole": [Function], 46 | "findAllByTestId": [Function], 47 | "findAllByText": [Function], 48 | "findAllByTitle": [Function], 49 | "findByAltText": [Function], 50 | "findByDisplayValue": [Function], 51 | "findByLabelText": [Function], 52 | "findByPlaceholderText": [Function], 53 | "findByRole": [Function], 54 | "findByTestId": [Function], 55 | "findByText": [Function], 56 | "findByTitle": [Function], 57 | "getAllByAltText": [Function], 58 | "getAllByDisplayValue": [Function], 59 | "getAllByLabelText": [Function], 60 | "getAllByPlaceholderText": [Function], 61 | "getAllByRole": [Function], 62 | "getAllByTestId": [Function], 63 | "getAllByText": [Function], 64 | "getAllByTitle": [Function], 65 | "getByAltText": [Function], 66 | "getByDisplayValue": [Function], 67 | "getByLabelText": [Function], 68 | "getByPlaceholderText": [Function], 69 | "getByRole": [Function], 70 | "getByTestId": [Function], 71 | "getByText": [Function], 72 | "getByTitle": [Function], 73 | "queryAllByAltText": [Function], 74 | "queryAllByDisplayValue": [Function], 75 | "queryAllByLabelText": [Function], 76 | "queryAllByPlaceholderText": [Function], 77 | "queryAllByRole": [Function], 78 | "queryAllByTestId": [Function], 79 | "queryAllByText": [Function], 80 | "queryAllByTitle": [Function], 81 | "queryByAltText": [Function], 82 | "queryByDisplayValue": [Function], 83 | "queryByLabelText": [Function], 84 | "queryByPlaceholderText": [Function], 85 | "queryByRole": [Function], 86 | "queryByTestId": [Function], 87 | "queryByText": [Function], 88 | "queryByTitle": [Function], 89 | "rerender": [Function], 90 | "unmount": [Function], 91 | } 92 | `; 93 | -------------------------------------------------------------------------------- /src/test/__snapshots__/Navbar.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`should render Navbar Item 1`] = ` 4 | Object { 5 | "asFragment": [Function], 6 | "baseElement": 7 |
8 | 52 |
53 | , 54 | "container":
55 | 99 |
, 100 | "debug": [Function], 101 | "findAllByAltText": [Function], 102 | "findAllByDisplayValue": [Function], 103 | "findAllByLabelText": [Function], 104 | "findAllByPlaceholderText": [Function], 105 | "findAllByRole": [Function], 106 | "findAllByTestId": [Function], 107 | "findAllByText": [Function], 108 | "findAllByTitle": [Function], 109 | "findByAltText": [Function], 110 | "findByDisplayValue": [Function], 111 | "findByLabelText": [Function], 112 | "findByPlaceholderText": [Function], 113 | "findByRole": [Function], 114 | "findByTestId": [Function], 115 | "findByText": [Function], 116 | "findByTitle": [Function], 117 | "getAllByAltText": [Function], 118 | "getAllByDisplayValue": [Function], 119 | "getAllByLabelText": [Function], 120 | "getAllByPlaceholderText": [Function], 121 | "getAllByRole": [Function], 122 | "getAllByTestId": [Function], 123 | "getAllByText": [Function], 124 | "getAllByTitle": [Function], 125 | "getByAltText": [Function], 126 | "getByDisplayValue": [Function], 127 | "getByLabelText": [Function], 128 | "getByPlaceholderText": [Function], 129 | "getByRole": [Function], 130 | "getByTestId": [Function], 131 | "getByText": [Function], 132 | "getByTitle": [Function], 133 | "queryAllByAltText": [Function], 134 | "queryAllByDisplayValue": [Function], 135 | "queryAllByLabelText": [Function], 136 | "queryAllByPlaceholderText": [Function], 137 | "queryAllByRole": [Function], 138 | "queryAllByTestId": [Function], 139 | "queryAllByText": [Function], 140 | "queryAllByTitle": [Function], 141 | "queryByAltText": [Function], 142 | "queryByDisplayValue": [Function], 143 | "queryByLabelText": [Function], 144 | "queryByPlaceholderText": [Function], 145 | "queryByRole": [Function], 146 | "queryByTestId": [Function], 147 | "queryByText": [Function], 148 | "queryByTitle": [Function], 149 | "rerender": [Function], 150 | "unmount": [Function], 151 | } 152 | `; 153 | -------------------------------------------------------------------------------- /src/test/reduxReducers.test.js: -------------------------------------------------------------------------------- 1 | import countriesReducer from '../redux/countries/reducerCountries'; 2 | import { continentsReducer, continentReducer } from '../redux/continents/reducerContinent'; 3 | import { GET_CONTINENT, GET_CONTINENTS } from '../redux/continents/continentActions'; 4 | import { GET_COUNTRIES } from '../redux/countries/countriesAction'; 5 | 6 | describe('should render redux reducers', () => { 7 | it('continentsReducer', () => { 8 | expect(continentsReducer([], { type: GET_CONTINENTS, payload: [1, 2, 3] })).toEqual([1, 2, 3]); 9 | }); 10 | 11 | it('continentReducer', () => { 12 | expect(continentReducer({}, { type: GET_CONTINENT, payload: { dat: 1 } })).toEqual({ dat: 1 }); 13 | }); 14 | 15 | it('countriesReducer', () => { 16 | expect(countriesReducer([], { type: GET_COUNTRIES, payload: [1, 2, 3] })).toEqual([1, 2, 3]); 17 | }); 18 | }); 19 | --------------------------------------------------------------------------------