├── src ├── images │ └── map.jpg ├── __test__ │ ├── __snapshots__ │ │ ├── Home.test.js.snap │ │ ├── Details.test.js.snap │ │ ├── NavBar.test.js.snap │ │ └── App.test.js.snap │ ├── NavBar.test.js │ ├── App.test.js │ ├── Home.test.js │ └── Details.test.js ├── redux │ ├── rootReducer.js │ ├── store.js │ └── actions │ │ ├── AllCountries.js │ │ └── AllInfo.js ├── index.js ├── components │ ├── SearchBar.js │ ├── NavBar.js │ ├── Home.js │ └── Details.js ├── App.js └── styles │ ├── App.css │ ├── NavBar.css │ ├── Details.css │ ├── SearchBar.css │ └── Home.css ├── .babelrc ├── .gitignore ├── .stylelintrc.json ├── .eslintrc.json ├── .github └── workflows │ └── linters.yml ├── public └── index.html ├── package.json └── README.md /src/images/map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reem-lab/covid-tracker/HEAD/src/images/map.jpg -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-react" 4 | ], 5 | "plugins": ["@babel/plugin-syntax-jsx"] 6 | } -------------------------------------------------------------------------------- /src/__test__/__snapshots__/Home.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test the Countries list renders correctly 1`] = ` 4 |
7 | No Counrties Information Found ❗❕ 8 |
9 | `; 10 | -------------------------------------------------------------------------------- /src/__test__/__snapshots__/Details.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test the Countries list renders correctly 1`] = ` 4 |
7 | No Counrties Information and Details Found ❗❕ 8 |
9 | `; 10 | -------------------------------------------------------------------------------- /src/redux/rootReducer.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import CountriesReducer from './actions/AllCountries'; 3 | import RegionsReducer from './actions/AllInfo'; 4 | 5 | const rootReducer = combineReducers({ 6 | CountriesReducer, 7 | RegionsReducer, 8 | }); 9 | 10 | export default rootReducer; 11 | -------------------------------------------------------------------------------- /src/redux/store.js: -------------------------------------------------------------------------------- 1 | import { applyMiddleware, createStore } from 'redux'; 2 | import logger from 'redux-logger'; 3 | import thunk from 'redux-thunk'; 4 | import rootReducer from './rootReducer'; 5 | 6 | const store = createStore( 7 | rootReducer, 8 | applyMiddleware(logger, thunk), 9 | ); 10 | 11 | export default store; 12 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Provider } from 'react-redux'; 4 | import App from './App'; 5 | import store from './redux/store'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | 12 | , 13 | document.getElementById('root'), 14 | ); 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"], 3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"], 4 | "rules": { 5 | "at-rule-no-unknown": null, 6 | "scss/at-rule-no-unknown": true, 7 | "csstree/validator": true 8 | }, 9 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"] 10 | } -------------------------------------------------------------------------------- /src/__test__/NavBar.test.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter as Router } from 'react-router-dom'; 2 | import renderer from 'react-test-renderer'; 3 | import NavBar from '../components/NavBar'; 4 | 5 | it('renders correctly', () => { 6 | const tree = renderer 7 | .create( 8 | 9 | 10 | , 11 | ) 12 | .toJSON(); 13 | expect(tree).toMatchSnapshot(); 14 | }); 15 | -------------------------------------------------------------------------------- /src/components/SearchBar.js: -------------------------------------------------------------------------------- 1 | import '../styles/SearchBar.css'; 2 | import img from '../images/map.jpg'; 3 | 4 | const SearchBar = () => ( 5 |
6 |
7 | map-world 8 |
9 |

All new Confrimed Cases

10 |
11 |
12 |
13 | ); 14 | 15 | export default SearchBar; 16 | -------------------------------------------------------------------------------- /src/__test__/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | import { cleanup } from '@testing-library/react'; 4 | import { Provider } from 'react-redux'; 5 | import store from '../redux/store'; 6 | import App from '../App'; 7 | 8 | afterEach(() => cleanup()); 9 | 10 | it('App Renders Correctly', () => { 11 | const tree = renderer.create( 12 | 13 | 14 | , 15 | ).toJSON(); 16 | expect(tree).toMatchSnapshot(); 17 | }); 18 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; 2 | import Details from './components/Details'; 3 | import Home from './components/Home'; 4 | import NavBar from './components/NavBar'; 5 | import './styles/App.css'; 6 | 7 | function App() { 8 | return ( 9 |
10 | 11 | 12 | 13 | } /> 14 | } /> 15 | 16 | 17 |
18 | ); 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /src/styles/App.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | border: none; 5 | outline: none; 6 | box-shadow: none; 7 | border-radius: 0; 8 | font-family: Roboto, Helvetica, sans-serif; 9 | font-weight: inherit; 10 | box-sizing: border-box; 11 | flex-shrink: 0; 12 | } 13 | 14 | *, 15 | body, 16 | body * { 17 | outline: none; 18 | box-sizing: border-box; 19 | font-family: "Lato", sans-serif; 20 | } 21 | 22 | body { 23 | box-sizing: border-box; 24 | margin: 0 auto; 25 | overflow-x: hidden; 26 | } 27 | 28 | @media screen and (max-width: 768px) { 29 | body { 30 | width: 350px; 31 | height: auto; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/__test__/Home.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { Provider } from 'react-redux'; 3 | import { render, screen } from '@testing-library/react'; 4 | import Home from '../components/Home'; 5 | import store from '../redux/store'; 6 | 7 | describe('Test the Countries list', () => { 8 | it('renders correctly', () => { 9 | const rocket = [ 10 | { 11 | country: 'Afghanstan', 12 | cases: 222, 13 | }, 14 | ]; 15 | 16 | const { container } = render( 17 | 18 | 19 | , 20 | ); 21 | const message = screen.getByText('No Counrties Information Found ❗❕'); 22 | expect(message).toMatchSnapshot(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.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"], 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 | "ignorePatterns": [ 24 | "dist/", 25 | "build/" 26 | ] 27 | } -------------------------------------------------------------------------------- /src/__test__/Details.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { Provider } from 'react-redux'; 3 | import { render, screen } from '@testing-library/react'; 4 | import Details from '../components/Details'; 5 | import store from '../redux/store'; 6 | 7 | describe('Test the Countries list', () => { 8 | it('renders correctly', () => { 9 | const rocket = [ 10 | { 11 | country: 'Afghanstan', 12 | cases: 222, 13 | }, 14 | ]; 15 | 16 | const { container } = render( 17 | 18 |
19 | , 20 | ); 21 | const message = screen.getByText('No Counrties Information and Details Found ❗❕'); 22 | expect(message).toMatchSnapshot(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/components/NavBar.js: -------------------------------------------------------------------------------- 1 | import { IoIosArrowBack } from 'react-icons/io'; 2 | import { FiSettings } from 'react-icons/fi'; 3 | import { FaMicrophone } from 'react-icons/fa'; 4 | import { Link } from 'react-router-dom'; 5 | import '../styles/NavBar.css'; 6 | 7 | const NavBar = () => ( 8 | <> 9 | 22 | 23 | ); 24 | 25 | export default NavBar; 26 | -------------------------------------------------------------------------------- /src/styles/NavBar.css: -------------------------------------------------------------------------------- 1 | .nav-bar { 2 | height: 70px; 3 | display: flex; 4 | justify-content: space-between; 5 | background-color: #4369b2; 6 | align-items: baseline; 7 | } 8 | 9 | .right-nav, 10 | .left-nav { 11 | width: 120px; 12 | display: flex; 13 | justify-content: space-evenly; 14 | margin-top: 15px; 15 | align-items: baseline; 16 | } 17 | 18 | .middle-nav { 19 | font-size: 23px; 20 | color: #fff; 21 | } 22 | 23 | .iconA, 24 | .iconS, 25 | .iconM { 26 | color: #fff; 27 | width: 50px; 28 | height: 25px; 29 | cursor: pointer; 30 | } 31 | 32 | @media screen and (max-width: 768px) { 33 | .iconA, 34 | .iconS, 35 | .iconM { 36 | width: 15px; 37 | height: 20px; 38 | } 39 | 40 | .middle-nav { 41 | font-size: 20px; 42 | } 43 | 44 | .left-nav, 45 | .right-nav { 46 | align-items: flex-start; 47 | width: 60px; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/styles/Details.css: -------------------------------------------------------------------------------- 1 | 2 | .info { 3 | display: flex; 4 | background-color: #35548b; 5 | color: #fff; 6 | justify-content: space-between; 7 | align-items: baseline; 8 | padding: 15px; 9 | font-size: 20px; 10 | height: 80px; 11 | } 12 | 13 | .info:nth-child(2n) { 14 | background-color: #5485e1; 15 | } 16 | 17 | .cases-number { 18 | display: flex; 19 | gap: 20px; 20 | } 21 | 22 | .header { 23 | display: flex; 24 | justify-content: space-between; 25 | background-color: #5485e1; 26 | padding: 15px; 27 | color: #fff; 28 | height: 110px; 29 | } 30 | 31 | .arrow { 32 | cursor: pointer; 33 | color: #fff; 34 | } 35 | 36 | .naCases { 37 | display: flex; 38 | flex-direction: column; 39 | gap: 10px; 40 | } 41 | 42 | @media screen and (max-width: 768px) { 43 | .cases-number { 44 | gap: 4px; 45 | } 46 | 47 | .info { 48 | font-size: 18px; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/redux/actions/AllCountries.js: -------------------------------------------------------------------------------- 1 | export const LOAD_COUNTRIES = 'LOAD_COUNTRIES'; 2 | 3 | export const loadCountries = (payload) => ({ 4 | type: LOAD_COUNTRIES, 5 | payload, 6 | }); 7 | 8 | const fetchData = async () => { 9 | const response = await fetch('https://disease.sh/v3/covid-19/countries/'); 10 | const data = await response.json(); 11 | return data; 12 | }; 13 | 14 | export const displayCountries = () => async (dispatch) => { 15 | const countriesArr = await fetchData(); 16 | 17 | const CountriesTemp = countriesArr.map((ele) => ({ 18 | // eslint-disable-next-line no-underscore-dangle 19 | id: ele.countryInfo._id, 20 | country: ele.country, 21 | cases: ele.cases, 22 | image: ele.countryInfo.flag, 23 | })); 24 | dispatch(loadCountries(CountriesTemp)); 25 | }; 26 | 27 | const initialState = []; 28 | 29 | const CountriesReducer = (state = initialState, action) => { 30 | switch (action.type) { 31 | case LOAD_COUNTRIES: 32 | return action.payload; 33 | 34 | default: 35 | return state; 36 | } 37 | }; 38 | 39 | export default CountriesReducer; 40 | -------------------------------------------------------------------------------- /src/redux/actions/AllInfo.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-underscore-dangle */ 2 | export const LOAD_REGIONS = ' LOAD_REGIONS'; 3 | export const LOAD_NAME = ' LOAD_NAME'; 4 | 5 | export const loadRegions = (payload) => ({ 6 | type: LOAD_REGIONS, 7 | payload, 8 | }); 9 | 10 | export const loadName = (name) => ({ 11 | type: LOAD_NAME, 12 | name, 13 | }); 14 | 15 | const fetchData = async () => { 16 | const response = await fetch('https://disease.sh/v3/covid-19/countries/'); 17 | const data = await response.json(); 18 | return data; 19 | }; 20 | 21 | export const displayInformations = () => async (dispatch) => { 22 | const regionsArr = await fetchData(); 23 | 24 | const RegionssTemp = regionsArr.map((ele) => ({ 25 | country: ele.country, 26 | cases: ele.cases, 27 | id: ele.countryInfo._id, 28 | todayCases: ele.todayCases, 29 | deaths: ele.deaths, 30 | recovered: ele.recovered, 31 | continent: ele.continent, 32 | tests: ele.tests, 33 | todayDeaths: ele.todayDeaths, 34 | todayRecovered: ele.todayRecovered, 35 | })); 36 | dispatch(loadRegions(RegionssTemp)); 37 | }; 38 | 39 | const initialState = []; 40 | 41 | const RegionsReducer = (state = initialState, action) => { 42 | switch (action.type) { 43 | case LOAD_REGIONS: 44 | return action.payload; 45 | 46 | case LOAD_NAME: 47 | return action.name; 48 | 49 | default: 50 | return state; 51 | } 52 | }; 53 | 54 | export default RegionsReducer; 55 | -------------------------------------------------------------------------------- /src/styles/SearchBar.css: -------------------------------------------------------------------------------- 1 | .img-map { 2 | width: 600px; 3 | height: auto; 4 | margin: 12px; 5 | border-radius: 30px; 6 | } 7 | 8 | .first-section { 9 | display: flex; 10 | align-items: center; 11 | gap: 40px; 12 | } 13 | 14 | .all-cases { 15 | background-color: #5485e1; 16 | } 17 | 18 | .info { 19 | color: #fff; 20 | } 21 | 22 | .search { 23 | background-color: #35548b; 24 | display: flex; 25 | flex-direction: column; 26 | align-items: center; 27 | padding-bottom: 25px; 28 | } 29 | 30 | .inputs { 31 | display: flex; 32 | } 33 | 34 | .search-icon { 35 | color: #fff; 36 | width: 40px; 37 | height: 20px; 38 | } 39 | 40 | h2 { 41 | color: #fff; 42 | margin: 10px; 43 | } 44 | 45 | .input-search { 46 | width: 400px; 47 | height: 30px; 48 | border-radius: 9px; 49 | } 50 | 51 | .btn { 52 | width: 70px; 53 | height: 30px; 54 | margin-left: 5px; 55 | border-radius: 9px; 56 | cursor: pointer; 57 | } 58 | 59 | @media screen and (max-width: 768px) { 60 | .first-section { 61 | display: flex; 62 | flex-direction: column; 63 | gap: 0; 64 | } 65 | 66 | .img-map { 67 | width: 250px; 68 | height: auto; 69 | } 70 | 71 | .confimred-cases { 72 | font-size: 15px; 73 | } 74 | 75 | .input-search { 76 | width: 250px; 77 | height: 30px; 78 | } 79 | 80 | .h2Search { 81 | font-size: 22px; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/styles/Home.css: -------------------------------------------------------------------------------- 1 | .all-countries { 2 | display: -ms-grid; 3 | display: grid; 4 | grid-template-columns: repeat(5, 1fr); 5 | grid-template-rows: repeat(6, 1fr); 6 | gap: 5px; 7 | border: 5px solid #fff; 8 | } 9 | 10 | .country-card { 11 | background-color: #35548b; 12 | color: #fff; 13 | cursor: pointer; 14 | } 15 | 16 | .country-card:nth-child(2n) { 17 | background-color: #5485e1; 18 | } 19 | 20 | .icons { 21 | display: flex; 22 | align-items: flex-start; 23 | gap: 160px; 24 | margin: 5px; 25 | color: #fff; 26 | } 27 | 28 | .virsus-icon { 29 | width: 70px; 30 | height: 60px; 31 | } 32 | 33 | .arrow { 34 | width: 20px; 35 | height: 20px; 36 | } 37 | 38 | .Cname { 39 | display: flex; 40 | flex-direction: column; 41 | align-items: flex-end; 42 | margin: 7px; 43 | } 44 | 45 | .number { 46 | color: #fff; 47 | } 48 | 49 | @media screen and (max-width: 768px) { 50 | .all-countries { 51 | display: -ms-grid; 52 | display: grid; 53 | grid-template-columns: repeat(2, 1fr); 54 | grid-template-rows: repeat(2, 1fr); 55 | gap: 0; 56 | border: 1px solid #5485e1; 57 | } 58 | 59 | .icons { 60 | display: flex; 61 | align-items: flex-start; 62 | gap: 45px; 63 | color: #fff; 64 | } 65 | 66 | .country-card { 67 | color: #fff; 68 | cursor: pointer; 69 | background-color: #5485e1; 70 | border: 0.5px solid #1c4894; 71 | } 72 | 73 | .country-card:nth-child(3n+1) { 74 | background-color: #35548b; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /.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-18.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: "12.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 . 24 | stylelint: 25 | name: Stylelint 26 | runs-on: ubuntu-18.04 27 | steps: 28 | - uses: actions/checkout@v2 29 | - uses: actions/setup-node@v1 30 | with: 31 | node-version: "12.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}" -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "covid-tracker", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.2", 7 | "@testing-library/react": "^12.1.3", 8 | "@testing-library/user-event": "^13.5.0", 9 | "jest": "^27.5.1", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-icons": "^4.3.1", 13 | "react-redux": "^7.2.6", 14 | "react-router-dom": "^6.2.2", 15 | "react-scripts": "5.0.0", 16 | "react-test-renderer": "^17.0.2", 17 | "redux": "^4.1.2", 18 | "redux-logger": "^3.0.6", 19 | "redux-thunk": "^2.4.1", 20 | "web-vitals": "^2.1.4" 21 | }, 22 | "scripts": { 23 | "start": "react-scripts start", 24 | "build": "react-scripts build", 25 | "test": "react-scripts test", 26 | "eject": "react-scripts eject", 27 | "lint": "npx eslint .", 28 | "lintf": "npx eslint --fix .", 29 | "style": "npx stylelint \"**/*.{css,scss}\"", 30 | "stylef": "npx stylelint --fix \"**/*.{css,scss}\"", 31 | "format": "prettier --write \"src/**/*.{js, jsx}\"", 32 | "predeploy": "npm run build", 33 | "deploy": "gh-pages -d build" 34 | }, 35 | "eslintConfig": { 36 | "extends": [ 37 | "react-app", 38 | "react-app/jest" 39 | ] 40 | }, 41 | "browserslist": { 42 | "production": [ 43 | ">0.2%", 44 | "not dead", 45 | "not op_mini all" 46 | ], 47 | "development": [ 48 | "last 1 chrome version", 49 | "last 1 firefox version", 50 | "last 1 safari version" 51 | ] 52 | }, 53 | "devDependencies": { 54 | "@babel/core": "^7.17.5", 55 | "@babel/eslint-parser": "^7.17.0", 56 | "@babel/plugin-syntax-jsx": "^7.16.7", 57 | "@babel/preset-react": "^7.16.7", 58 | "eslint": "^7.32.0", 59 | "eslint-config-airbnb": "^18.2.1", 60 | "eslint-plugin-import": "^2.25.4", 61 | "eslint-plugin-jsx-a11y": "^6.5.1", 62 | "eslint-plugin-react": "^7.29.3", 63 | "eslint-plugin-react-hooks": "^4.3.0", 64 | "stylelint": "^13.13.1", 65 | "stylelint-config-standard": "^21.0.0", 66 | "stylelint-csstree-validator": "^1.9.0", 67 | "stylelint-scss": "^3.21.0" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/components/Home.js: -------------------------------------------------------------------------------- 1 | import { NavLink } from 'react-router-dom'; 2 | import { RiVirusLine } from 'react-icons/ri'; 3 | import { BsArrowRightCircle } from 'react-icons/bs'; 4 | import { VscSearch } from 'react-icons/vsc'; 5 | import { useEffect, useState } from 'react'; 6 | import { useSelector, useDispatch } from 'react-redux'; 7 | import SearchBar from './SearchBar'; 8 | import { displayCountries } from '../redux/actions/AllCountries'; 9 | import '../styles/Home.css'; 10 | 11 | const Home = () => { 12 | const [location, setLocation] = useState(''); 13 | const countries = useSelector((state) => state.CountriesReducer); 14 | const filtered = countries.filter((item) => item.country.toLowerCase() 15 | .includes(location.toLowerCase())); 16 | 17 | const dispatch = useDispatch(); 18 | 19 | useEffect(() => { 20 | if (countries.length === 0) { 21 | dispatch(displayCountries()); 22 | } 23 | }, []); 24 | 25 | return ( 26 |
27 | 28 |
29 |

30 | Search by Country 31 | 32 |

33 | { setLocation(e.target.value); }} 38 | /> 39 |
40 |
41 | { !filtered.length ? ( 42 |
No Counrties Information Found ❗❕
43 | ) : ( 44 | filtered.map((country1) => ( 45 |
46 | 47 |
48 | 49 | 50 |
51 |
52 |

{country1.country}

53 | {country1.cases} 54 |
55 |
56 |
57 | )))} 58 |
59 |
60 | ); 61 | }; 62 | 63 | export default Home; 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![](https://img.shields.io/static/v1?label=BY&message=Reemoz&color=pink) 3 | 4 | 5 | 6 | # Covid19-Tracker 🦠 7 | 8 | > This is my react capstone project. The project is talking about covid cases in all countries in the world and also displays all the information details to each country with all covid cases or recovered cases. 9 | 10 | 11 | ## Video Demo 📽 12 | 13 | https://user-images.githubusercontent.com/58553711/157734548-45e097f2-d841-4a84-8d98-c00a3094a6c2.mp4 14 | 15 | 16 | 17 | ## Deploy Demo 🚀 18 | 19 | [![Netlify Status](https://api.netlify.com/api/v1/badges/cc500adb-5279-4240-9ff1-26be38ac6130/deploy-status)](https://covid19-tracker9.netlify.app/) 20 | 21 | ## Video Description by me 22 | 23 | [see my video from here](https://www.loom.com/share/abd3e97140784135bbc8ddbf2906bb86) 24 | 25 | 26 | 27 | # Getting Started with Create React App 28 | 29 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 30 | 31 | 32 | 33 | ## Available Scripts 34 | 35 | In the project directory, you can run: 36 | 37 | ### `npm install` 38 | 39 | ### `npm start` 40 | 41 | 42 | 43 | ## Built With 44 | 45 | - Languages: _**HTML, CSS, JavaScript, Reactjs, Redux**_ 46 | - Frameworks: _**N/A**_ 47 | - Technologies used: _**GIT, GITHUB, LINTERS**_ 48 | 49 | ## Additional tools 50 | - Google fonts 51 | - Webpack 52 | - React Icons 53 | - linters 54 | - Gitflow 55 | - Redux 56 | - Test by jest 57 | 58 | 59 | ## Authors 60 | 61 | 62 | 63 | 👤 **Reem** 64 | 65 | Platform | Badge | 66 | --- | --- | 67 | **GitHub** | [@Reem-lab](https://github.com/Reem-lab) 68 | **Twitter** | [Rem79940127](https://twitter.com/Rem79940127) 69 | **LinkdIn** | [reem-janina](https://www.linkedin.com/in/reem-janina-ab74ab21a/) 70 | 71 | 72 | ## 🤝 Contributing 73 | 74 | Contributions, issues, and feature requests are welcome! 75 | 76 | Feel free to check the [issues page](https://github.com/MrRamoun/WEBDEV/issues). 77 | 78 | ## Show your support 79 | 80 | Give a ⭐️ if you like this project! 81 | 82 | ## Acknowledgments 83 | 84 | - Original design idea by [Nelson Sakwa on Behance](https://www.behance.net/sakwadesignstudio) 85 | - Hat tip to anyone whose code was used 86 | - Inspiration 87 | - etc 88 | 89 | ## 📝 License 90 | 91 | This project is [MIT](/LICENSE) licensed. 92 | -------------------------------------------------------------------------------- /src/__test__/__snapshots__/NavBar.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`renders correctly 1`] = ` 4 | 95 | `; 96 | -------------------------------------------------------------------------------- /src/components/Details.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-underscore-dangle */ 2 | import { BsArrowRightCircle } from 'react-icons/bs'; 3 | import { FaVirus } from 'react-icons/fa'; 4 | import { useSelector, useDispatch } from 'react-redux'; 5 | import { Link, useParams } from 'react-router-dom'; 6 | import { useEffect } from 'react'; 7 | import { displayInformations } from '../redux/actions/AllInfo'; 8 | import '../styles/Details.css'; 9 | 10 | const Details = () => { 11 | const params = useParams(); 12 | const countriesInfo = useSelector((state) => state.RegionsReducer); 13 | const filtered = countriesInfo.filter((item) => item.country === params.country); 14 | const dispatch = useDispatch(); 15 | 16 | useEffect(() => { 17 | if (countriesInfo.length === 0) { 18 | dispatch(displayInformations()); 19 | } 20 | }, []); 21 | 22 | return ( 23 |
24 | { !filtered.length ? ( 25 |
No Counrties Information and Details Found ❗❕
26 | ) : (filtered.map((info) => ( 27 |
28 |
29 | 30 |
31 |

32 | {info.country} 33 | {' '} 34 |

35 | {info.cases} 36 |
37 |
38 |
39 |
40 |

Today cases in the country

41 |
42 | {info.todayCases} 43 | 44 |
45 |
46 |
47 |

General deaths

48 |
49 | {info.deaths} 50 | 51 |
52 |
53 |
54 |

Total Recovered

55 |
56 | {info.recovered} 57 | 58 |
59 |
60 |
61 |

Continent name

62 |
63 | {info.continent} 64 | 65 |
66 |
67 |
68 |

Total tests that made

69 |
70 | {info.tests} 71 | 72 |
73 |
74 |
75 |

Today deaths

76 |
77 | {info.todayDeaths} 78 | 79 |
80 |
81 |
82 |

Today Recovered

83 |
84 | {info.todayRecovered} 85 | 86 |
87 |
88 |
89 |
90 | )))} 91 |
92 | ); 93 | }; 94 | 95 | export default Details; 96 | -------------------------------------------------------------------------------- /src/__test__/__snapshots__/App.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`App Renders Correctly 1`] = ` 4 |
7 | 98 |
101 |
104 |
107 | map-world 112 |
115 |

118 | All new Confrimed Cases 119 |

120 |
121 |
122 |
123 |
126 |

129 | Search by Country 130 | 145 | 148 | 149 |

150 | 156 |
157 |
160 |
163 | No Counrties Information Found ❗❕ 164 |
165 |
166 |
167 |
168 | `; 169 | --------------------------------------------------------------------------------