├── .gitignore ├── README.md ├── package.json ├── pages └── index.js ├── utils └── useStats.js └── components ├── Stats.js └── CountrySelector.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .next/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rona 🦠 2 | Code along with React + Next + Hooks API 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rona", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "next" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "next": "^9.3.0", 13 | "normalize.css": "^8.0.1", 14 | "react": "^16.13.0", 15 | "react-dom": "^16.13.0", 16 | "styled-components": "^5.0.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | import useStats from '../utils/useStats'; 3 | import Stats from '../components/Stats'; 4 | import CountrySelector from '../components/CountrySelector'; 5 | 6 | const GlobalStyle = createGlobalStyle` 7 | html { 8 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 9 | } 10 | `; 11 | 12 | export default function IndexPage() { 13 | return ( 14 |
15 | 16 | 17 | 18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /utils/useStats.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | export default function useStats(url) { 4 | const [stats, setStats] = useState(); 5 | const [loading, setLoading] = useState(true); 6 | const [error, setError] = useState(); 7 | useEffect(() => { 8 | console.log('Mounting or updating'); 9 | async function fetchData() { 10 | setLoading(true); 11 | setError(); 12 | console.log('Fetching Data'); 13 | const data = await fetch(url) 14 | .then(res => res.json()) 15 | .catch(err => { 16 | setError(err); 17 | }); 18 | setStats(data); 19 | setLoading(false); 20 | } 21 | fetchData(); 22 | }, [url]); 23 | return { 24 | stats, 25 | loading, 26 | error, 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /components/Stats.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import useStats from '../utils/useStats'; 3 | 4 | const StatGrid = styled.div` 5 | display: grid; 6 | grid-template-columns: repeat(3, 1fr); 7 | grid-gap: 1rem; 8 | `; 9 | const StatBlock = styled.div` 10 | background: #f2f2f2; 11 | font-size: 2rem; 12 | padding: 2rem; 13 | border-radius: 2rem; 14 | display: grid; 15 | align-items: center; 16 | justify-items: center; 17 | text-align: center; 18 | `; 19 | 20 | export default function Stats({ url }) { 21 | const { stats, loading, error } = useStats(url); 22 | console.log(stats, loading, error); 23 | if (loading) return

Loading...

; 24 | if (error) return

Error...

; 25 | return ( 26 | 27 | 28 |

Confirmed:

29 | {stats.confirmed.value} 30 |
31 | 32 |

Deaths:

33 | {stats.deaths.value} 34 |
35 | 36 |

Recovered:

37 | {stats.recovered.value} 38 |
39 |
40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /components/CountrySelector.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import useStats from '../utils/useStats'; 3 | import Stats from './Stats'; 4 | 5 | export default function CountrySelector() { 6 | const { stats: countries, loading, error } = useStats( 7 | 'https://covid19.mathdro.id/api/countries' 8 | ); 9 | const [selectedCountry, setSelectedCountry] = useState('USA'); 10 | if (loading) return

Loading...

; 11 | if (loading) return

Loading...

; 12 | if (error) return

Error...

; 13 | 14 | return ( 15 |
16 |

Currently Showing {selectedCountry}

17 | 32 | 35 |
36 | ); 37 | } 38 | --------------------------------------------------------------------------------