개선된 코로나 현황 사이트 CoronaTracerMk2 - 8

먼저 카드들을 스타일링 해보자 이전 코드들 중 InfoBox내에 CardContent에 대해 className을 잘못 지정해 주었는데

function InfoBox({ title, cases, total }) {
  return (
    <Card className="infoBox">
      <CardContent>
        {/*title*/}
        <Typography className="infoBox__title" color="textSecondary">
          {title}

CardContent가 아닌 Card에 className을 지정해주자.

.infoBox {
  flex: 1;
}

.infoBox:not(:last-child) {
  margin-right: 10px;
}

.infoBox__cases {
  color: #cc1034;
  font-weight: 600;
  font-size: 1.75rem;
  margin-bottom: 0.5rem;
}

.infoBox__total {
  color: #6c757d;
  font-weight: 700 !important;
  font-size: 0.8rem !important;
  margin-top: 15px !important;
}

디자인 css를 적용하면

이전보다 더 나아진 모습을 볼 수 있다.
하지만 아직 숫자들의 가독성이 떨어져보이므로 이를 해결할 함수를 utill에 만들자.

export const prettyPrintStat = (stat) =>
  stat ? `+${numeral(stat).format("0.0a")}` : "+0";

당일 증가치에 대한 함수이다. 증가치가 있으면 numeral과 format으로 값을 정리하고 값이 없다면 +0을 리턴한다.
이제 이 함수를 App.js의 InfoBox 내에 적용해보면

이전보다 가독성이 향상되었다.

다음으로 우측 테이블 내 데이터도 정리하자 Table.js에서도 numeral을 import하고

          <td>{country}</td>
          <td>
            <strong>{numeral(cases).format("0,0")}</strong>
          </td>
        </tr>

기존의 cases를 대체해준다.

훨씬 보기 편해졌다.
배경색으로 구분을 준 것도 그렇고 이런것 하나하나가 양질UX를 제공하는데 도움이 된다.

이제 InfoBox들을 클릭하면 해당 카드의 값에 해당하는 데이터들을 보여주도록 하자.
요것 또한 바뀔때마다 다시 렌더링 해줘야 하므로 useState를 사용한다.
App.js에 스테이트를 추가하고

  const [casesType, setCasesType] = useState("cases");

InfoBox에

          <InfoBox
            onClick={(e) => setCasesType("cases")}
            title="Coronavirus cases"
            cases={prettyPrintStat(countryInfo.todayCases)}
            total={prettyPrintStat(countryInfo.cases)}
          />

          <InfoBox
            onClick={(e) => setCasesType("recovered")}
            title="Recovered"
            cases={prettyPrintStat(countryInfo.todayRecovered)}
            total={prettyPrintStat(countryInfo.recovered)}
          />

          <InfoBox
            onClick={(e) => setCasesType("deaths")}
            title="Deaths"
            cases={prettyPrintStat(countryInfo.todayDeaths)}
            total={prettyPrintStat(countryInfo.deaths)}
          />
        </div>

각각의 setter함수를 onClick으로 추가한다.
그리고 InfoBox.js에서

function InfoBox({ title, cases, total, ...props }) {
  return (
    <Card onClick={props.onClick} className="infoBox">
      <CardContent>
        {/*title*/}

spread문법으로 prop을 넣어주고 onClick이벤트를 props에 대해 추가한다.
아직까지는 Card들을 클릭해도 아무 반응이 없다.
Map에 아무런 코드를 작성하지 않았기 때문인데

        </div>
        {/*Map*/}
        <Map casesType={casesType} countries={mapCountries} center={mapCenter} zoom={mapZoom} />
      </div>

App.js내의 Map에도 casesType을 추가해주자

각 Card의 casesType에 따라 Map에서 보여주는 casesType이 바뀐다.
이제 Map뿐만 아니라 LineGraph도 연동하자 앞의 Map과 유사하게

          {/*Graph*/}
          <h3>Worldwide new {casesType}</h3>
          <LineGraph casesType={casesType} />
        </CardContent>

casesType을 추가하면 된다 한가지 더해 그래프에 대한 h3태그도 바꿔주었다.

이제 사용자에게 어떤 Card의 data를 보여주고 있는지 알려주기 위해 스타일을 추가하자

          <InfoBox
            active={casesType === "cases"}
            onClick={(e) => setCasesType("cases")}
            title="Coronavirus cases"
            cases={prettyPrintStat(countryInfo.todayCases)}
            total={prettyPrintStat(countryInfo.cases)}
          />

          <InfoBox
            active={casesType === "recovered"}
            onClick={(e) => setCasesType("recovered")}
            title="Recovered"
            cases={prettyPrintStat(countryInfo.todayRecovered)}
            total={prettyPrintStat(countryInfo.recovered)}
          />

          <InfoBox
            active={casesType === "deaths"}
            onClick={(e) => setCasesType("deaths")}
            title="Deaths"
            cases={prettyPrintStat(countryInfo.todayDeaths)}
            total={prettyPrintStat(countryInfo.deaths)}
          />
        </div>

InfoBox에 선택한 casesType이 해당 InfoBox의 casesType과 동일하면 True를 반환하는 active를 만들고 InfoBox.js에도 active prop을 추가한다.


function InfoBox({ title, cases, active, total, ...props }) {
  return (
    <Card onClick={props.onClick} className="infoBox">

여기서 active상태가 되었을때만 className을 추가해주기 위해

    <Card
      onClick={props.onClick}
      className={`infoBox ${active && "infoBox--selected"}`}
    >
      <CardContent>

Card의 className을 바꿔주고

.infoBox--selected {
    border-top: 10px solid greenyellow;
}

css코드도 추가하자

선택한 Card의 윗부분이 잘 바뀐다. 하지만 Death의 색이 형광색인게 좀 어색하다.

          <InfoBox
            isRed
            active={casesType === "cases"}
            onClick={(e) => setCasesType("cases")}
            title="Coronavirus cases"
            cases={prettyPrintStat(countryInfo.todayCases)}
            total={prettyPrintStat(countryInfo.cases)}
          />

          <InfoBox
            active={casesType === "recovered"}
            onClick={(e) => setCasesType("recovered")}
            title="Recovered"
            cases={prettyPrintStat(countryInfo.todayRecovered)}
            total={prettyPrintStat(countryInfo.recovered)}
          />

          <InfoBox
            isRed
            active={casesType === "deaths"}
            onClick={(e) => setCasesType("deaths")}
            title="Deaths"
            cases={prettyPrintStat(countryInfo.todayDeaths)}
            total={prettyPrintStat(countryInfo.deaths)}
          />

다시 InfoBox에 빨간색으로 표시하고 싶은 부분에 isRed라는 코드를 추가하고


function InfoBox({ title, cases, isRed, active, total, ...props }) {
  return (
    <Card
      onClick={props.onClick}

이를 InfoBox의 prop으로 넣어준 뒤

    <Card
      onClick={props.onClick}
      className={`infoBox ${active && "infoBox--selected"} ${
        isRed && "infoBox--red"
      }`}
    >

className의 조건으로 isRed가 True면 infoBox--red라는 className을 추가하는 코드를 작성한다.
그리고 css파일에도 스타일을 작성하면

.infoBox--red {
    border-color: red;
}


확진자와 사망자에 대한 카드는 빨간색 테두리가 생긴다.
그리고 카드영역이 클릭이 가능한 부분이란것을 알려주기 위해 포인터를 바꾸고

.infoBox {
  flex: 1;
  cursor: pointer;
}

완치자의 글씨색이 빨간것도 좀 이상하니 바꿔주자

        {/*numberofcases*/}
        <h2 className={`infoBox__cases ${!isRed && "infoBox__cases--green"}`}>
          {cases}
        </h2>

글씨에 해당하는 h2태그의 className을 조건부로 바꿔주고

.infoBox__cases--green {
    color: lawngreen !important;
}

해당 css를 추가하면

글씨색도 바뀌었다.

나머지는 이제 기호에 맞게 스타일링 해주면 되겠다.

좋은 웹페이지 즐겨찾기