1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-07-19 03:29:37 +02:00

WeatherWidget temp unit. WeatherSettings update on change

This commit is contained in:
unknown 2021-06-07 12:17:10 +02:00
parent 08c769b630
commit d2e6ebae4f
8 changed files with 68 additions and 24 deletions

View file

@ -1,7 +1,7 @@
import { useState, ChangeEvent, useEffect, FormEvent } from 'react'; import { useState, ChangeEvent, useEffect, FormEvent } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import axios from 'axios'; import axios from 'axios';
import { ApiResponse, Config, NewNotification } from '../../../interfaces'; import { ApiResponse, Config, NewNotification, Weather } from '../../../interfaces';
import InputGroup from '../../UI/Forms/InputGroup/InputGroup'; import InputGroup from '../../UI/Forms/InputGroup/InputGroup';
import Button from '../../UI/Buttons/Button/Button'; import Button from '../../UI/Buttons/Button/Button';
@ -65,13 +65,31 @@ const WeatherSettings = (props: ComponentProps): JSX.Element => {
e.preventDefault(); e.preventDefault();
axios.put<ApiResponse<{}>>('/api/config', formData) axios.put<ApiResponse<{}>>('/api/config', formData)
.then(data => { .then(() => {
props.createNotification({ props.createNotification({
title: 'Success', title: 'Success',
message: 'Settings updated' message: 'Settings updated'
}) })
// Update weather with new settings
axios.get<ApiResponse<Weather>>('/api/weather/update')
.then(() => {
props.createNotification({
title: 'Success',
message: 'Weather updated'
})
})
.catch((err) => {
props.createNotification({
title: 'Error',
message: err.response.data.error
})
});
}) })
.catch(err => console.log(err)); .catch(err => console.log(err));
// set localStorage
localStorage.setItem('isCelsius', JSON.stringify(formData.isCelsius === 1))
} }
return ( return (

View file

@ -1,5 +1,5 @@
import { useState, useEffect, Fragment } from 'react'; import { useState, useEffect, Fragment } from 'react';
import { Weather, ApiResponse } from '../../../interfaces'; import { Weather, ApiResponse, Config } from '../../../interfaces';
import axios from 'axios'; import axios from 'axios';
import WeatherIcon from '../../UI/Icons/WeatherIcon/WeatherIcon'; import WeatherIcon from '../../UI/Icons/WeatherIcon/WeatherIcon';
@ -12,6 +12,7 @@ const WeatherWidget = (): JSX.Element => {
tempC: 0, tempC: 0,
tempF: 0, tempF: 0,
isDay: 1, isDay: 1,
cloud: 0,
conditionText: '', conditionText: '',
conditionCode: 1000, conditionCode: 1000,
id: -1, id: -1,
@ -19,9 +20,11 @@ const WeatherWidget = (): JSX.Element => {
updatedAt: new Date() updatedAt: new Date()
}); });
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isCelsius, setIsCelsius] = useState(true);
// Initial request to get data // Initial request to get data
useEffect(() => { useEffect(() => {
// get weather
axios.get<ApiResponse<Weather[]>>('/api/weather') axios.get<ApiResponse<Weather[]>>('/api/weather')
.then(data => { .then(data => {
const weatherData = data.data.data[0]; const weatherData = data.data.data[0];
@ -31,20 +34,24 @@ const WeatherWidget = (): JSX.Element => {
setIsLoading(false); setIsLoading(false);
}) })
.catch(err => console.log(err)); .catch(err => console.log(err));
// get config
if (!localStorage.isCelsius) {
axios.get<ApiResponse<Config>>('/api/config/isCelsius')
.then((data) => {
setIsCelsius(parseInt(data.data.data.value) === 1);
localStorage.setItem('isCelsius', JSON.stringify(isCelsius));
})
.catch((err) => console.log(err));
} else {
setIsCelsius(JSON.parse(localStorage.isCelsius));
}
}, []); }, []);
// Open socket for data updates // Open socket for data updates
useEffect(() => { useEffect(() => {
const webSocketClient = new WebSocket('ws://localhost:5005'); const webSocketClient = new WebSocket('ws://localhost:5005');
webSocketClient.onopen = () => {
console.log('WebSocket opened');
}
webSocketClient.onclose = () => {
console.log('WebSocket closed')
}
webSocketClient.onmessage = (e) => { webSocketClient.onmessage = (e) => {
const data = JSON.parse(e.data); const data = JSON.parse(e.data);
setWeather({ setWeather({
@ -69,8 +76,11 @@ const WeatherWidget = (): JSX.Element => {
/> />
</div> </div>
<div className={classes.WeatherDetails}> <div className={classes.WeatherDetails}>
<span>{weather.tempC}°C</span> {isCelsius
<span>{weather.conditionCode}</span> ? <span>{weather.tempC}°C</span>
: <span>{weather.tempF}°F</span>
}
<span>{weather.cloud}%</span>
</div> </div>
</Fragment>) </Fragment>)
) )

View file

@ -5,6 +5,7 @@ export interface Weather extends Model {
tempC: number; tempC: number;
tempF: number; tempF: number;
isDay: number; isDay: number;
cloud: number;
conditionText: string; conditionText: string;
conditionCode: number; conditionCode: number;
} }

View file

@ -1,9 +1,10 @@
const asyncWrapper = require('../middleware/asyncWrapper'); const asyncWrapper = require('../middleware/asyncWrapper');
const ErrorResponse = require('../utils/ErrorResponse'); const ErrorResponse = require('../utils/ErrorResponse');
const Weather = require('../models/Weather'); const Weather = require('../models/Weather');
const getExternalWeather = require('../utils/getExternalWeather');
// @desc Get latest weather status // @desc Get latest weather status
// @route POST /api/weather // @route GET /api/weather
// @access Public // @access Public
exports.getWeather = asyncWrapper(async (req, res, next) => { exports.getWeather = asyncWrapper(async (req, res, next) => {
const weather = await Weather.findAll({ const weather = await Weather.findAll({
@ -16,3 +17,15 @@ exports.getWeather = asyncWrapper(async (req, res, next) => {
data: weather data: weather
}) })
}) })
// @desc Update weather
// @route GET /api/weather/update
// @access Public
exports.updateWeather = asyncWrapper(async (req, res, next) => {
const weather = await getExternalWeather();
res.status(200).json({
success: true,
data: weather
})
})

View file

@ -6,6 +6,7 @@ const Weather = sequelize.define('Weather', {
tempC: DataTypes.FLOAT, tempC: DataTypes.FLOAT,
tempF: DataTypes.FLOAT, tempF: DataTypes.FLOAT,
isDay: DataTypes.INTEGER, isDay: DataTypes.INTEGER,
cloud: DataTypes.INTEGER,
conditionText: DataTypes.TEXT, conditionText: DataTypes.TEXT,
conditionCode: DataTypes.INTEGER conditionCode: DataTypes.INTEGER
}, { }, {

View file

@ -11,7 +11,7 @@ const {
} = require('../controllers/config'); } = require('../controllers/config');
router router
.route('') .route('/')
.post(createPair) .post(createPair)
.get(getAllPairs) .get(getAllPairs)
.put(updateValues); .put(updateValues);

View file

@ -2,11 +2,16 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const { const {
getWeather getWeather, updateWeather
} = require('../controllers/weather'); } = require('../controllers/weather');
router router
.route('') .route('/')
.get(getWeather); .get(getWeather);
router
.route('/update')
.get(updateWeather);
module.exports = router; module.exports = router;

View file

@ -12,22 +12,17 @@ const getExternalWeather = async () => {
const long = config.find(pair => pair.key === 'long'); const long = config.find(pair => pair.key === 'long');
if (!secret) { if (!secret) {
console.log('API key was not found. Weather updated failed'); throw new Error('API key was not found. Weather updated failed');
return;
} }
if (!lat || !long) { if (!lat || !long) {
console.log('Location was not found. Weather updated failed'); throw new Error('Location was not found. Weather updated failed');
return;
} }
// Fetch data from external API // Fetch data from external API
try { try {
const res = await axios.get(`http://api.weatherapi.com/v1/current.json?key=${secret.value}&q=${lat.value},${long.value}`); const res = await axios.get(`http://api.weatherapi.com/v1/current.json?key=${secret.value}&q=${lat.value},${long.value}`);
// For dev
// console.log(res.data);
// Save weather data // Save weather data
const cursor = res.data.current; const cursor = res.data.current;
const weatherData = await Weather.create({ const weatherData = await Weather.create({
@ -35,6 +30,7 @@ const getExternalWeather = async () => {
tempC: cursor.temp_c, tempC: cursor.temp_c,
tempF: cursor.temp_f, tempF: cursor.temp_f,
isDay: cursor.is_day, isDay: cursor.is_day,
cloud: cursor.cloud,
conditionText: cursor.condition.text, conditionText: cursor.condition.text,
conditionCode: cursor.condition.code conditionCode: cursor.condition.code
}); });