From 78c8ff8a2d36bf1a162a9d6b8eac1a86cf97f373 Mon Sep 17 00:00:00 2001 From: Wanda Gusdya Date: Thu, 5 Jan 2023 18:51:00 +0700 Subject: [PATCH] update --- src/components/DetailModal.css | 48 ++++++++++ src/components/DetailModal.js | 137 +++++++++++++++++++++++++++ src/components/ForecastContent.css | 7 ++ src/components/ForecastContent.js | 38 ++++++++ src/components/WeatherCard.css | 3 +- src/components/WeatherCard.js | 67 ++++++------- src/components/WeatherCardContent.js | 47 +++++++++ 7 files changed, 309 insertions(+), 38 deletions(-) create mode 100644 src/components/DetailModal.css create mode 100644 src/components/DetailModal.js create mode 100644 src/components/ForecastContent.css create mode 100644 src/components/ForecastContent.js create mode 100644 src/components/WeatherCardContent.js diff --git a/src/components/DetailModal.css b/src/components/DetailModal.css new file mode 100644 index 0000000..9eccfad --- /dev/null +++ b/src/components/DetailModal.css @@ -0,0 +1,48 @@ +.modal { + display: block; /* Shown by default */ + position: fixed; /* Stay in place */ + z-index: 1; /* Sit on top */ + left: 0; + top: 0; + width: 100%; /* Full width */ + height: 100%; /* Full height */ + overflow: auto; /* Enable scroll if needed */ + background-color: rgb(0,0,0); /* Fallback color */ + background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ +} + +/* Modal Content/Box */ +.modal-content { + background-color: #fefefe; + margin: 15% auto; /* 15% from the top and centered */ + padding: 20px; + border: 1px solid #888; + width: 50%; /* Could be more or less, depending on screen size */ +} + +/* The Close Button */ +.close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.close:hover, +.close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +.detail-weather-image { + height: 256px; + width: 256px; + display: block; + margin-left: auto; + margin-right: auto; +} + +.label { + padding-right: 10px; +} \ No newline at end of file diff --git a/src/components/DetailModal.js b/src/components/DetailModal.js new file mode 100644 index 0000000..13d6744 --- /dev/null +++ b/src/components/DetailModal.js @@ -0,0 +1,137 @@ +import './DetailModal.css' +import moment from "moment"; + +function DetailModal(props) { + + const weather = props.weather + let url = `http://localhost:3001/images/${weather.summary.replaceAll(' ', '_')}.png` + let formattedDate = moment(weather.date).format("DD/MM/YYYY HH:mm:ss") + let temperature = Math.round((weather.temperature + Number.EPSILON) * 100) / 100 + let apparentTemperature = Math.round((weather.apparentTemperature + Number.EPSILON) * 100) / 100 + + return ( +
+ +
+ × +
+
+ {weather.summary} +
+
+ +
+
+ Device ID +
+
+ {weather.deviceId} +
+
+ +
+
+ Date +
+
+ {formattedDate} +
+
+ +
+
+ Summary +
+
+ {weather.summary} +
+
+ +
+
+ Precip. Type +
+
+ {weather.precipType} +
+
+ +
+
+ Temperature +
+
+ {temperature}℃ +
+
+ +
+
+ Apparent Temperature +
+
+ {apparentTemperature}℃ +
+
+ +
+
+ Humidity +
+
+ {weather.humidity} +
+
+ +
+
+ Wind Bearing +
+
+ {weather.windBearing} +
+
+ +
+
+ Visibility +
+
+ {weather.visibility} +
+
+ +
+
+ Loud Cover +
+
+ {weather.loudCover} +
+
+ +
+
+ Pressure +
+
+ {weather.pressure} +
+
+ +
+
+ Daily Summary +
+
+ {weather.dailySummary} +
+
+ +
+ +
+ ) +} + +export default DetailModal \ No newline at end of file diff --git a/src/components/ForecastContent.css b/src/components/ForecastContent.css new file mode 100644 index 0000000..66fcd7c --- /dev/null +++ b/src/components/ForecastContent.css @@ -0,0 +1,7 @@ +.forecast-text { + font-size: 8px; +} + +.forecast-image { + width:100% +} \ No newline at end of file diff --git a/src/components/ForecastContent.js b/src/components/ForecastContent.js new file mode 100644 index 0000000..7a3fc12 --- /dev/null +++ b/src/components/ForecastContent.js @@ -0,0 +1,38 @@ +import moment from "moment"; +import './ForecastContent.css'; + +function ForecastContent(props) { + + let image; + let header; + let summary; + let date; + let time; + if (props.forecast != null) { + const forecast = props.forecast + + let url = `http://localhost:3001/images/${forecast.summary.replaceAll(' ', '_')}.png` + image = {forecast.summary} + let temperature = Math.round((forecast.temperature + Number.EPSILON) * 100) / 100 + header =

{temperature}℃

+ summary =

{forecast.summary}

+ let formattedDate = moment(forecast.date).format("DD/MM") + date =

{formattedDate}

+ let formattedTime = moment(forecast.date).format("HH:mm") + time =

{formattedTime}

+ } + + return ( +
+ {image} +
+ {header} + {summary} + {date} + {time} +
+
+ ) +} + +export default ForecastContent \ No newline at end of file diff --git a/src/components/WeatherCard.css b/src/components/WeatherCard.css index 3b6e450..5761cfa 100644 --- a/src/components/WeatherCard.css +++ b/src/components/WeatherCard.css @@ -1,5 +1,6 @@ .weather-image { - width:100% + width:100%; + cursor: pointer; } .weather-card { diff --git a/src/components/WeatherCard.js b/src/components/WeatherCard.js index 33a759f..83455af 100644 --- a/src/components/WeatherCard.js +++ b/src/components/WeatherCard.js @@ -1,6 +1,7 @@ import React from 'react'; import './WeatherCard.css'; -import moment from 'moment'; +import WeatherCardContent from "./WeatherCardContent"; +import ForecastContent from "./ForecastContent"; class WeatherCard extends React.Component { constructor(props) { @@ -8,7 +9,8 @@ class WeatherCard extends React.Component { this.state = { error: null, isLoaded: false, - weather: null, + weathers: [], + forecasts: [], device: props.device }; } @@ -19,7 +21,27 @@ class WeatherCard extends React.Component { (result) => { this.setState({ isLoaded: true, - weather: result + weathers: result + }); + }, + // Note: it's important to handle errors here + // instead of a catch() block so that we don't swallow + // exceptions from actual bugs in components. + (error) => { + this.setState({ + isLoaded: true, + error + }); + } + ) + + fetch(`http://localhost:3001/api/v1/weather/forecast/${this.state.device}`) + .then(res => res.json()) + .then( + (result) => { + this.setState({ + isLoaded: true, + forecasts: result }); }, // Note: it's important to handle errors here @@ -36,43 +58,14 @@ class WeatherCard extends React.Component { render() { - let device; - let image; - let header; - let summary; - let date; - if (this.state.weather != null) { - device =

Device {this.state.weather.deviceId}

- let url = `http://localhost:3001/images/${this.state.weather.summary.replaceAll(' ', '_')}.png` - image = {this.state.weather.summary} - let temperature = Math.round((this.state.weather.temperature + Number.EPSILON) * 100) / 100 - header =

{temperature}℃

- summary =

{this.state.weather.summary}

- let formattedDate = moment(this.state.weather.date).format("DD/MM/YYYY HH:mm:ss") - date =

{formattedDate}

- } + const weather = this.state.weathers?.map((weather) => ) + const forecasts = this.state.forecasts?.map((forecast) => ) + return (
- {device} - {image} -
- {header} - {summary} - {date} -
+ {weather} -
- A -
-
- A -
-
- A -
-
- A -
+ {forecasts}
) } diff --git a/src/components/WeatherCardContent.js b/src/components/WeatherCardContent.js new file mode 100644 index 0000000..20c606b --- /dev/null +++ b/src/components/WeatherCardContent.js @@ -0,0 +1,47 @@ +import moment from "moment/moment"; +import DetailModal from "./DetailModal"; +import {useState} from "react"; + +function WeatherCardContent(props) { + const [modalVisible, setModalVisible] = useState(props.modalVisible) + function handleClick(e) { + e.preventDefault(); + setModalVisible(!modalVisible) + } + + let device; + let image; + let header; + let summary; + let date; + let modal; + if (props.weather != null) { + const weather = props.weather + device =

Device {weather.deviceId}

+ let url = `http://localhost:3001/images/${weather.summary.replaceAll(' ', '_')}.png` + image = {weather.summary} + let temperature = Math.round((weather.temperature + Number.EPSILON) * 100) / 100 + header =

{temperature}℃

+ summary =

{weather.summary}

+ let formattedDate = moment(weather.date).format("DD/MM/YYYY HH:mm:ss") + date =

{formattedDate}

+ if (modalVisible) { + modal = + } + } + + return ( +
+ {device} + {image} +
+ {header} + {summary} + {date} +
+ {modal} +
+ ) +} + +export default WeatherCardContent \ No newline at end of file