관리 메뉴

Dev Blog

Initial Set up & Covid19 API_20210428 _Day1 본문

Projects/Covid19 Tracker

Initial Set up & Covid19 API_20210428 _Day1

Nomad Kim 2021. 4. 29. 00:17

Framework

[ADD]Make Category function and Data table

- Make Coronavirus/Recovered/Deaths Info Boxes

- Get data from disease.sh(API) and Structure through Material UI

 

Covid19 API(Fetch Data)

import React, { useState, useEffect } from 'react'
import './App.css';
import {
  MenuItem,
  FormControl,
  Select,
  Card,
  CardContent
} from "@material-ui/core"
import InfoBox from './Infobox'
import Map from './Map'

function App() {
  //모든 국가의 { 국가명, 국가코드 } 데이터를 카테고리 목록에서 사용
  const [countries, setContries] = useState([]);
  //선택된 국가의 국가코드 를 fetch 에 사용 
  const [country, setCountry] = useState("worldwide");
  //선택된 국가의 모든 데이터 
  const [countryInfo, setCountryInfo] = useState({});  
  
  //default 데이터로 전세계 코로나 상황 데이터를 저장 및 사용 
  useEffect(()=>{
    fetch('https://disease.sh/v3/covid-19/all')
    .then(res => res.json())
    .then(data => {
      setCountryInfo(data);
    })
  },[])
  //전세계 국가명 및 국가코드 데이터로 카테고리 생성(국가코드를 value 값으로 이용)
  useEffect(() => {
    const getCountriesData = async () => {
      await fetch("https://disease.sh/v3/covid-19/countries")
      .then(res => res.json())
      .then((data) =>{
        const countries = data.map((country)=> (
          {
            name:country.country,
            value: country.countryInfo.iso2
          }
        ))
        setContries(countries);
      })
    }
    getCountriesData();
  }, [])
  //선택된 국가의 국가코드를 이용하여 코로나 데이터 fetch 
  const onCountryChange = async (e) => {
    const countryCode = e.target.value
    setCountry(countryCode);

    const url = countryCode === "worldwide" ? 'https://disease.sh/v3/covid-19/all' : `https://disease.sh/v3/covid-19/countries/${countryCode}`

    await fetch(url)
    .then(res => res.json())
    .then(data => {
      setCountry(countryCode)
      setCountryInfo(data);
    })
    //https://disease.sh/v3/covid-19/all
    //https://disease.sh/v3/covid-19/countries/[COUNTRY_CODE]
  }
  return (
    <div className="app">
      <div className="app__left">
        <div className="app__header">
          <h1>Let's build a COVID 19 TRACKER!</h1>
          <FormControl className="app__dropdown">
            <Select value={country} variant="outlined" onChange={onCountryChange}>
              <MenuItem value="worldwide">Worldwide</MenuItem>
              {/* Loop through all the countries and show a drop down */}
              {countries.map((country) => (
                <MenuItem value={country.value}>{country.name}</MenuItem>
              ))}
            </Select>
          </FormControl>
        </div>
        <div className="app__stats">
          <InfoBox title="Coronavirus" cases={countryInfo.todayCases} total={countryInfo.cases}/>
          <InfoBox title="Recovered" cases={countryInfo.todayRecovered} total={countryInfo.recovered}/>
          <InfoBox title="Deaths" cases={countryInfo.todayDeaths} total={countryInfo.deaths}/>
        </div>
        <Map/>
      </div>
      <Card className="app__right">
        <CardContent>
          <h3>Live Cases by Country</h3>
          <h3>Worldwide new cases</h3>
        </CardContent>
           {/* Table */}
           {/* Graph */}
      </Card>
    </div>
  );
}

export default App;

Source from: disease.sh/docs/

 

카테고리에 따른 API 요청 후 Infobox 에 렌더링

onChange => setCountryInfo => Infobox

          <FormControl className="app__dropdown">
            <Select value={country} variant="outlined" onChange={onCountryChange}>
              <MenuItem value="worldwide">Worldwide</MenuItem>
              {/* Loop through all the countries and show a drop down */}
              {countries.map((country) => (
                <MenuItem value={country.value}>{country.name}</MenuItem>
              ))}
            </Select>
          </FormControl>
  const onCountryChange = async (e) => {
    const countryCode = e.target.value
    setCountry(countryCode);

    const url = countryCode === "worldwide" ? 'https://disease.sh/v3/covid-19/all' : `https://disease.sh/v3/covid-19/countries/${countryCode}`

    await fetch(url)
    .then(res => res.json())
    .then(data => {
      setCountry(countryCode)
      setCountryInfo(data);
      if(countryCode === 'worldwide'){
        setMapCenter({ lat: 37, lng: 127.5});
        setMapZoom(3);
      } else {
        setMapCenter([data.countryInfo.lat, data.countryInfo.long]);
        setMapZoom(5);
      }
    })
    //https://disease.sh/v3/covid-19/all
    //https://disease.sh/v3/covid-19/countries/[COUNTRY_CODE]
  }
return (
  <InfoBox 
     isRed
     active={casesType === 'cases'}
     onClick={e => setCasesType('cases')}
     title="Coronavirus" 
     cases={prettyPrintStat(countryInfo.todayCases)} 
     total={prettyPrintStat(countryInfo.cases)}
   />
)
//util.js
export const prettyPrintStat = (stat) => (
  stat ? `+${numeral(stat).format("0,0a")}`: "+0"
)
import React from 'react'
import { Card, CardContent, Typography } from "@material-ui/core"
import './InfoBox.css'

function Infobox({ title, cases, total, active, isRed, ...props }) { //...props passes onClick event
  // console.log(active, isRed)
  return (
    <Card onClick={props.onClick} className={`infoBox ${active && 'infoBox--selected'} ${isRed && 'infoBox--red'}`}>
      <CardContent>
        <Typography className="infoBox__title" color="textSecondary">
          {title}
        </Typography>
        <h2 className={`infoBox__cases ${!isRed && "infoBox__cases--green"}`}>{cases}</h2>
        <Typography className="infoBox__total" color="textSecondary">{total} Total</Typography>
      </CardContent>
    </Card>
  )
}

export default Infobox

Material UI

매우 편리한 라이브러리. 카테고리 버튼을 클릭했을 때 애니메이션까지 적용되어 있다. 더 사용해 봐야겠다.

 

Data source from disease.sh/

'Projects > Covid19 Tracker' 카테고리의 다른 글

Completed Map_20210430_Day3  (0) 2021.05.01
Category/Data table/Basic Map_20210429_Day2  (0) 2021.04.30
Comments