Update bookmark. Changes to CSS. Changes to WeatherJob

This commit is contained in:
unknown 2021-06-01 14:54:47 +02:00
parent 519b6d0746
commit 96aa1f7d69
11 changed files with 165 additions and 36 deletions

View file

@ -17,7 +17,7 @@ interface ComponentProps {
addCategory: (formData: NewCategory) => void;
addBookmark: (formData: NewBookmark) => void;
updateCategory: (id: number, formData: NewCategory) => void;
updateBookmark: (id: number, formData: NewBookmark) => void;
updateBookmark: (id: number, formData: NewBookmark, categoryWasChanged: boolean) => void;
createNotification: (notification: NewNotification) => void;
}
@ -90,7 +90,7 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => {
setCategoryName({ name: '' });
} else if (props.contentType === ContentType.bookmark && props.bookmark) {
// Update bookmark
props.updateBookmark(props.bookmark.id, formData);
props.updateBookmark(props.bookmark.id, formData, props.bookmark.categoryId !== formData.categoryId);
setFormData({
name: '',
url: '',

View file

@ -1,9 +1,11 @@
import { useState, ChangeEvent, Fragment, useEffect, FormEvent } from 'react';
import { useState, ChangeEvent, useEffect, FormEvent } from 'react';
import { connect } from 'react-redux';
import axios from 'axios';
import { ApiResponse, Config } from '../../../interfaces';
import { ApiResponse, Config, NewNotification } from '../../../interfaces';
import InputGroup from '../../UI/Forms/InputGroup/InputGroup';
import Button from '../../UI/Buttons/Button/Button';
import { createNotification } from '../../../store/actions';
interface FormState {
WEATHER_API_KEY: string;
@ -12,7 +14,11 @@ interface FormState {
isCelsius: number;
}
const WeatherSettings = (): JSX.Element => {
interface ComponentProps {
createNotification: (notification: NewNotification) => void;
}
const WeatherSettings = (props: ComponentProps): JSX.Element => {
const [formData, setFormData] = useState<FormState>({
WEATHER_API_KEY: '',
lat: 0,
@ -59,7 +65,12 @@ const WeatherSettings = (): JSX.Element => {
e.preventDefault();
axios.put<ApiResponse<{}>>('/api/config', formData)
.then(data => console.log(data.data.success))
.then(data => {
props.createNotification({
title: 'Success',
message: 'Settings updated'
})
})
.catch(err => console.log(err));
}
@ -131,4 +142,4 @@ const WeatherSettings = (): JSX.Element => {
)
}
export default WeatherSettings;
export default connect(null, { createNotification })(WeatherSettings);

View file

@ -1,8 +1,16 @@
.Container {
width: 100%;
padding: 20px;
margin: 0 auto;
}
/* .Container {
width: 60%;
margin: 0 auto;
padding: 20px;
padding-top: 20px;
} */
/* 320px 480px: Mobile devices.
481px 768px: iPads, Tablets.
769px 1024px: Small screens, laptops.
@ -11,7 +19,8 @@
@media (min-width: 769px) {
.Container {
padding: 25px 40px;
/* padding: 25px 40px; */
width: 90%;
}
}

View file

@ -1,5 +1,6 @@
.WeatherWidget {
display: flex;
visibility: hidden;
}
.WeatherDetails {
@ -20,3 +21,9 @@
.WeatherDetails span:last-child {
padding-top: 5px;
}
@media (min-width: 600px) {
.WeatherWidget {
visibility: visible;
}
}

View file

@ -14,38 +14,65 @@ const WeatherWidget = (): JSX.Element => {
isDay: 1,
conditionText: '',
conditionCode: 1000,
id: 0,
id: -1,
createdAt: new Date(),
updatedAt: new Date()
});
const [isLoading, setIsLoading] = useState(true);
// Initial request to get data
useEffect(() => {
axios.get<ApiResponse<Weather[]>>('/api/weather')
.then(data => {
setWeather(data.data.data[0]);
const weatherData = data.data.data[0];
if (weatherData) {
setWeather(weatherData);
}
setIsLoading(false);
})
.catch(err => console.log(err));
}, []);
// Open socket for data updates
useEffect(() => {
const webSocketClient = new WebSocket('ws://localhost:5005');
webSocketClient.onopen = () => {
console.log('WebSocket opened');
}
webSocketClient.onclose = () => {
console.log('WebSocket closed')
}
webSocketClient.onmessage = (e) => {
const data = JSON.parse(e.data);
setWeather({
...weather,
...data
})
}
return () => webSocketClient.close();
}, []);
return (
<div className={classes.WeatherWidget}>
{isLoading
? 'loading'
: (
<Fragment>
<div className={classes.WeatherIcon}>
<WeatherIcon
weatherStatusCode={weather.conditionCode}
isDay={weather.isDay}
/>
</div>
<div className={classes.WeatherDetails}>
<span>{weather.tempC}°C</span>
<span>{weather.conditionCode}</span>
</div>
</Fragment>
: (weather.id > 0 &&
(<Fragment>
<div className={classes.WeatherIcon}>
<WeatherIcon
weatherStatusCode={weather.conditionCode}
isDay={weather.isDay}
/>
</div>
<div className={classes.WeatherDetails}>
<span>{weather.tempC}°C</span>
<span>{weather.conditionCode}</span>
</div>
</Fragment>)
)
}
</div>

View file

@ -2,7 +2,7 @@
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
/* user-select: none; */
}
body {

View file

@ -218,10 +218,13 @@ export const deleteBookmark = (bookmarkId: number, categoryId: number) => async
*/
export interface UpdateBookmarkAction {
type: ActionTypes.updateBookmark,
payload: Bookmark
payload: {
bookmark: Bookmark,
categoryWasChanged: boolean
}
}
export const updateBookmark = (bookmarkId: number, formData: NewBookmark) => async (dispatch: Dispatch) => {
export const updateBookmark = (bookmarkId: number, formData: NewBookmark, categoryWasChanged: boolean) => async (dispatch: Dispatch) => {
try {
const res = await axios.put<ApiResponse<Bookmark>>(`/api/bookmarks/${bookmarkId}`, formData);
@ -235,7 +238,10 @@ export const updateBookmark = (bookmarkId: number, formData: NewBookmark) => asy
dispatch<UpdateBookmarkAction>({
type: ActionTypes.updateBookmark,
payload: res.data.data
payload: {
bookmark: res.data.data,
categoryWasChanged
}
})
} catch (err) {
console.log(err);

View file

@ -107,8 +107,38 @@ const deleteBookmark = (state: State, action: Action): State => {
}
const updateBookmark = (state: State, action: Action): State => {
const { bookmark, categoryWasChanged } = action.payload;
const tmpCategories = [...state.categories];
let categoryIndex = state.categories.findIndex((category: Category) => category.id === bookmark.categoryId);
let bookmarkIndex = state.categories[categoryIndex].bookmarks.findIndex((bookmark: Bookmark) => bookmark.id === bookmark.id);
// if (categoryWasChanged) {
// const categoryInUpdate = tmpCategories.find((category: Category) => category.id === bookmark.categoryId);
// if (categoryInUpdate) {
// categoryInUpdate.bookmarks = categoryInUpdate.bookmarks.filter((_bookmark: Bookmark) => _bookmark.id === bookmark.id);
// }
// console.log(categoryInUpdate);
// }
return {
...state
...state,
categories: [
...state.categories.slice(0, categoryIndex),
{
...state.categories[categoryIndex],
bookmarks: [
...state.categories[categoryIndex].bookmarks.slice(0, bookmarkIndex),
{
...bookmark
},
...state.categories[categoryIndex].bookmarks.slice(bookmarkIndex + 1)
]
},
...state.categories.slice(categoryIndex + 1)
]
}
}

40
utils/Logger.js Normal file
View file

@ -0,0 +1,40 @@
const fs = require('fs');
class Logger {
constructor() {
this.logFileHandler();
}
logFileHandler() {
if (!fs.existsSync('./flame.log')) {
fs.writeFileSync('./flame.log', '');
} else {
console.log('file exists');
}
}
writeLog(logMsg, logType) {
}
generateLog(logMsg, logType) {
const now = new Date();
const date = `${this.parseNumber(now.getDate())}-${this.parseNumber(now.getMonth() + 1)}-${now.getFullYear()}`;
const time = `${this.parseNumber(now.getHours())}:${this.parseNumber(now.getMinutes())}:${this.parseNumber(now.getSeconds())}.${now.getMilliseconds()}`;
const log = `[${date} ${time}]: ${logType} ${logMsg}`;
return log;
// const timestamp = new Date().toISOString();
}
parseNumber(number) {
if (number > 9) {
return number;
} else {
return `0${number}`;
}
}
}
// console.log(logger.generateLog('testMsg', 'INFO'));
module.exports = new Logger();

View file

@ -30,7 +30,7 @@ const getExternalWeather = async () => {
// Save weather data
const cursor = res.data.current;
await Weather.create({
const weatherData = await Weather.create({
externalLastUpdate: cursor.last_updated,
tempC: cursor.temp_c,
tempF: cursor.temp_f,
@ -38,10 +38,9 @@ const getExternalWeather = async () => {
conditionText: cursor.condition.text,
conditionCode: cursor.condition.code
});
return weatherData;
} catch (err) {
console.log(err);
console.log('External API request failed');
return;
throw new Error('External API request failed');
}
}

View file

@ -4,10 +4,10 @@ const Sockets = require('../Sockets');
const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async () => {
try {
await getExternalWeather();
const weatherData = await getExternalWeather();
console.log('weather updated');
Sockets.getSocket('weather').socket.send('weather updated');
Sockets.getSocket('weather').socket.send(JSON.stringify(weatherData));
} catch (err) {
console.log(err);
console.log(err.message);
}
})