├── .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 | You need to enable JavaScript to run this app.
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 |
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 | { navigate(`/${continent}`); }}
18 | type="button"
19 | >
20 |
21 |
22 |
23 |
24 |
25 |
{continent}
26 |
{` Active Cases : ${cases}`}
27 |
28 |
29 |
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 |
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 |
15 | {location.pathname === '/' && (
16 | <>
17 |
18 | GLOBAL PANDEMIC
19 |
20 | WORLD COVID STATS
21 | >
22 | )}
23 |
24 | {location.pathname !== '/' && (
25 | <>
26 | navigate(-1)} />
27 |
28 | {continent}
29 |
30 | {`${continent} COVID Cases`}
31 | >
32 | )}
33 |
34 |
35 |
36 |
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 |
11 |
12 |
13 | GLOBAL PANDEMIC
14 |
15 |
16 |
19 | WORLD COVID STATS
20 |
21 |
31 |
35 |
36 |
46 |
50 |
51 |
52 |
71 |
74 |
75 | CONTINENTS STATS
76 |
77 |
81 |
82 |
85 |
86 | ,
87 | "container":
88 |
91 |
92 |
93 | GLOBAL PANDEMIC
94 |
95 |
96 |
99 | WORLD COVID STATS
100 |
101 |
111 |
115 |
116 |
126 |
130 |
131 |
132 |
151 |
154 |
155 | CONTINENTS STATS
156 |
157 |
161 |
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 |
11 |
12 | CONTINENTS STATS
13 |
14 |
18 |
19 |
22 |
23 | ,
24 | "container":
25 |
28 |
29 | CONTINENTS STATS
30 |
31 |
35 |
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 |
11 |
12 |
13 | GLOBAL PANDEMIC
14 |
15 |
16 |
19 | WORLD COVID STATS
20 |
21 |
31 |
35 |
36 |
46 |
50 |
51 |
52 |
53 | ,
54 | "container":
55 |
58 |
59 |
60 | GLOBAL PANDEMIC
61 |
62 |
63 |
66 | WORLD COVID STATS
67 |
68 |
78 |
82 |
83 |
93 |
97 |
98 |
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 |
--------------------------------------------------------------------------------