-
Notifications
You must be signed in to change notification settings - Fork 19
7주차 고다경 과제구현 #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
7주차 고다경 과제구현 #5
Changes from 1 commit
feb8233
fd7839c
b7bccc4
cf70f58
1db73ad
84a963f
4d8521f
81a3e31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,23 @@ | ||
| import React from "react"; | ||
| import { | ||
| CurrentWeatherWrapper, | ||
| Temperature, | ||
| WeatherCode, | ||
| } from "./styles/StyledComponents"; | ||
| import { getWeatherDescription } from "../utils/weather"; | ||
| import { CurrentWeatherWrapper, Temperature, WeatherCode } from "./styles/StyledComponents"; | ||
| import { getWeatherDescription, formatCurrentData } from "../utils/weather"; | ||
| import { DEGREE_CELSIUS, LOADING } from "../constants/uiConstants"; | ||
|
|
||
| const CurrentWeather = ({ weatherData, isLoading }) => { | ||
| const currentData = formatCurrentData(weatherData); | ||
|
|
||
| if (isLoading) { | ||
| return <div>채워주세요</div>; | ||
| return <div>{LOADING}</div>; | ||
| } | ||
|
|
||
| return <div>채워주세요</div>; | ||
| return ( | ||
| <CurrentWeatherWrapper> | ||
| <Temperature> | ||
| {currentData.temperature} | ||
| {DEGREE_CELSIUS} | ||
| </Temperature> | ||
| <WeatherCode>{getWeatherDescription(currentData.weatherCode)}</WeatherCode> | ||
| </CurrentWeatherWrapper> | ||
| ); | ||
| }; | ||
|
|
||
| export default CurrentWeather; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,24 @@ | ||
| import React from "react"; | ||
| import { DailyForecastWrapper, DailyItem } from "./styles/StyledComponents"; | ||
| import { getWeatherDescription, formatDailyData } from "../utils/weather"; | ||
| import { DEGREE_CELSIUS } from "../constants/uiConstants"; | ||
|
|
||
| const DailyForecast = ({ weatherData }) => { | ||
| const dailyData = formatDailyData(weatherData); | ||
|
|
||
| return <div>채워주세요</div>; | ||
| return ( | ||
| <DailyForecastWrapper> | ||
| {dailyData.map((data) => ( | ||
| <DailyItem key={data.timeString}> | ||
| <div>{data.date}</div> | ||
| <div>{getWeatherDescription(data.weatherCode)}</div> | ||
| <div> | ||
| {data.temperature} | ||
| {DEGREE_CELSIUS} | ||
| </div> | ||
| </DailyItem> | ||
| ))} | ||
| </DailyForecastWrapper> | ||
| ); | ||
| }; | ||
|
|
||
| export default DailyForecast; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,27 @@ | ||
| import React from "react"; | ||
| import { HourlyForecastWrapper, HourlyItem } from "./styles/StyledComponents"; | ||
| import { getWeatherDescription, formatHourlyData } from "../utils/weather"; | ||
| import { DEGREE_CELSIUS, HOUR_SUFFIX } from "../constants/uiConstants"; | ||
|
|
||
| const HourlyForecast = ({ weatherData }) => { | ||
| const hourlyData = formatHourlyData(weatherData); | ||
|
|
||
| return <div>채워주세요</div>; | ||
| return ( | ||
| <HourlyForecastWrapper> | ||
| {hourlyData.map((data) => ( | ||
| <div key={data.timeString}> | ||
| <HourlyItem> | ||
| {data.hour} | ||
| {HOUR_SUFFIX} | ||
| </HourlyItem> | ||
| <HourlyItem> | ||
| {data.temperature} | ||
| {DEGREE_CELSIUS} | ||
| </HourlyItem> | ||
| <HourlyItem>{getWeatherDescription(data.weatherCode)}</HourlyItem> | ||
| </div> | ||
| ))} | ||
| </HourlyForecastWrapper> | ||
| ); | ||
| }; | ||
|
|
||
| export default HourlyForecast; |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| // Units | ||
| export const DEGREE_CELSIUS = "°C"; | ||
| export const HOUR_SUFFIX = "시"; | ||
|
|
||
| // Message | ||
| export const LOADING = "Loading..."; |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 데이터 검증 로직 좋습니다 😁 |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,23 @@ | ||||||
| export const isToDay = (dateInData, currentDate) => { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| return ( | ||||||
| dateInData.getFullYear() === currentDate.getFullYear() && | ||||||
| dateInData.getMonth() === currentDate.getMonth() && | ||||||
| dateInData.getDate() === currentDate.getDate() | ||||||
| ); | ||||||
| }; | ||||||
|
|
||||||
| export const isWithin12Hours = (dateInData, currentDate) => { | ||||||
| const diff = (dateInData - currentDate) / (1000 * 60 * 60); | ||||||
| return diff >= 0 && diff <= 12; | ||||||
| }; | ||||||
|
|
||||||
| export const isInCurrentTime = (dateInData) => { | ||||||
| const now = new Date(); | ||||||
|
|
||||||
| return ( | ||||||
| dateInData.getFullYear() === now.getFullYear() && | ||||||
| dateInData.getMonth() === now.getMonth() && | ||||||
| dateInData.getDate() === now.getDate() && | ||||||
| dateInData.getHours() === now.getHours() | ||||||
| ); | ||||||
| }; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전체적으로 안에 포매팅 기능을 하는 부분들이 많은데, 이를 별도의 util 함수로 분리하면 좋겠습니다!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fetch로 시작하는 함수들로 변경하여 최대한 데이터 원본 형태로 불러오도록 수정했습니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| import { isToDay, isWithin12Hours, isInCurrentTime } from "./validators"; | ||
| import { getWeekdayName } from "./weeks"; | ||
|
|
||
| export const getWeatherDescription = (code) => { | ||
| const weatherCodes = { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기도 constants.js로 분리하면 어떨까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. constants로 분리 후, 아래와 같이 변경했습니다! |
||
| 0: "맑음", | ||
|
|
@@ -19,14 +22,59 @@ export const getWeatherDescription = (code) => { | |
| return weatherCodes[code] || "알 수 없음"; | ||
| }; | ||
|
|
||
| export const formatCurrentData = (weatherData) => { | ||
| if (!weatherData) return; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 만약 문제가 발생해서 return했다면 console에 log라도 찍어주면 개발할 때 빠르게 어느 부분에서 문제가 생겼는지 확인할 수 있을 것 같아요!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다음과 같이 작성했습니다! |
||
|
|
||
| const index = weatherData.hourly.time.findIndex((time) => isInCurrentTime(new Date(time))); | ||
| const date = new Date(weatherData.hourly.time[index]); | ||
|
|
||
| return { | ||
| time: date.toISOString(), | ||
| temperature: Math.floor(weatherData.hourly.temperature_2m[index]), | ||
| weatherCode: weatherData.hourly.weather_code[index], | ||
| }; | ||
| }; | ||
|
|
||
| export const formatHourlyData = (weatherData) => { | ||
| if (!weatherData) return []; | ||
| // 밑에 코드 채워주세요 | ||
| return []; | ||
| const currentDate = new Date(); | ||
| const result = []; | ||
|
|
||
| weatherData.hourly.time.forEach((time, index) => { | ||
| const hourlyDate = new Date(time); | ||
|
|
||
| if ( | ||
| isToDay(hourlyDate, currentDate) && | ||
| isWithin12Hours(hourlyDate, currentDate) && | ||
| result.length < 12 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이것도 validate 로직이니까 따로 분리하면 좋을 것 같네요!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 기존에 result였던 배열명도 collectedForecasts로 변경하고 validators 안에 분리했습니다! |
||
| ) { | ||
| result.push({ | ||
| timeString: hourlyDate.toISOString(), | ||
| hour: hourlyDate.getHours(), | ||
| temperature: Math.floor(weatherData.hourly.temperature_2m[index]), | ||
| weatherCode: weatherData.hourly.weather_code[index], | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 포매팅 함수도 분리해 봅시다!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| }); | ||
| } | ||
| }); | ||
|
|
||
| return result; | ||
| }; | ||
|
|
||
| export const formatDailyData = (weatherData) => { | ||
| if (!weatherData) return []; | ||
| // 밑에 코드 채워주세요 | ||
| return []; | ||
|
|
||
| const result = weatherData.daily.time.map((time, index) => { | ||
| const dailyDate = new Date(time); | ||
|
|
||
| return { | ||
| timeString: dailyDate.toISOString(), | ||
| date: `${dailyDate.getMonth() + 1}월 ${dailyDate.getDate()}일 (${getWeekdayName( | ||
| dailyDate.getDay() | ||
| )})`, | ||
| temperature: Math.floor(weatherData.daily.temperature_2m_max[index]), | ||
| weatherCode: weatherData.daily.weather_code[index], | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 포매팅!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| }; | ||
| }); | ||
|
|
||
| return result; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| export const getWeekdayName = (dayIndex) => { | ||
| const weeksCodes = { | ||
| 0: "일", | ||
| 1: "월", | ||
| 2: "화", | ||
| 3: "수", | ||
| 4: "목", | ||
| 5: "금", | ||
| 6: "토", | ||
| }; | ||
|
|
||
| return weeksCodes[dayIndex]; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading 대신 스피너나 간단한 스켈레톤 UI를 추가해보는 것도 좋을 것 같아요!
https://blog.makerjun.com/2f7a9818-df45-4eab-9768-b79d61b4d0ec
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
찾아보니 스피너 라이브러리가 있어서 사용해보았습니다!
참고자료
https://www.davidhu.io/react-spinners/
https://choijying21.tistory.com/entry/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A1%9C%EB%94%A9%ED%99%94%EB%A9%B4-%EC%8A%A4%ED%94%BC%EB%84%88-%EB%A7%8C%EB%93%9C%EB%8A%94-%EC%97%AC%EB%9F%AC%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95gif-React-spinners