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 (
+
+
+
+
×
+
+
+

+
+
+
+
+
+ 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 =
+ 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 =
- 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 =
+ 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