From 5e54da8271c7fac5062f0aca9b10e7370fd4bae2 Mon Sep 17 00:00:00 2001 From: Mo Tarbin Date: Mon, 1 Jul 2024 22:12:19 -0400 Subject: Update button re-enable timeout to 3 seconds, update thing history --- src/views/Things/ThingsHistory.jsx | 164 ++++++++++++++++++++++++++++++++++++- src/views/Things/ThingsView.jsx | 87 ++++++++++++++++---- 2 files changed, 233 insertions(+), 18 deletions(-) (limited to 'src/views/Things') diff --git a/src/views/Things/ThingsHistory.jsx b/src/views/Things/ThingsHistory.jsx index 39f0e30..4b32b0e 100644 --- a/src/views/Things/ThingsHistory.jsx +++ b/src/views/Things/ThingsHistory.jsx @@ -1,11 +1,171 @@ -import { Container, Typography } from '@mui/joy' +import { EventBusy } from '@mui/icons-material' +import { + Box, + Button, + Chip, + Container, + List, + ListDivider, + ListItem, + ListItemContent, + Typography, +} from '@mui/joy' +import moment from 'moment' +import { useEffect, useState } from 'react' +import { Link, useParams } from 'react-router-dom' +import { GetThingHistory } from '../../utils/Fetcher' const ThingsHistory = () => { + const { id } = useParams() + const [thingsHistory, setThingsHistory] = useState([]) + const [noMoreHistory, setNoMoreHistory] = useState(false) + const [errLoading, setErrLoading] = useState(false) + useEffect(() => { + GetThingHistory(id, 0, 10).then(resp => { + if (resp.ok) { + resp.json().then(data => { + setThingsHistory(data.res) + if (data.res.length < 10) { + setNoMoreHistory(true) + } + }) + } else { + setErrLoading(true) + } + }) + }, []) + + const handleLoadMore = () => { + GetThingHistory(id, thingsHistory.length).then(resp => { + if (resp.ok) { + resp.json().then(data => { + setThingsHistory([...thingsHistory, ...data.res]) + if (data.res.length < 10) { + setNoMoreHistory(true) + } + }) + } + }) + } + + const formatTimeDifference = (startDate, endDate) => { + const diffInMinutes = moment(startDate).diff(endDate, 'minutes') + let timeValue = diffInMinutes + let unit = 'minute' + + if (diffInMinutes >= 60) { + const diffInHours = moment(startDate).diff(endDate, 'hours') + timeValue = diffInHours + unit = 'hour' + + if (diffInHours >= 24) { + const diffInDays = moment(startDate).diff(endDate, 'days') + timeValue = diffInDays + unit = 'day' + } + } + + return `${timeValue} ${unit}${timeValue !== 1 ? 's' : ''}` + } + if (errLoading || !thingsHistory) { + return ( + + + + + No history found + + + It's look like there is no history for this thing yet. + + + + ) + } + return ( - Summary: + History: + + {thingsHistory.map((history, index) => ( + <> + + + + + {moment(history.updatedAt).format( + 'ddd MM/DD/yyyy HH:mm:ss', + )} + + {history.state === '1' ? 'Active' : 'Inactive'} + + + + {index < thingsHistory.length - 1 && ( + <> + + {/* time between two completion: */} + {index < thingsHistory.length - 1 && + thingsHistory[index + 1].createdAt && ( + + {formatTimeDifference( + history.createdAt, + thingsHistory[index + 1].createdAt, + )}{' '} + before + + )} + + + )} + + ))} + + {/* Load more Button */} + + + ) } diff --git a/src/views/Things/ThingsView.jsx b/src/views/Things/ThingsView.jsx index deb2df5..8b2beb6 100644 --- a/src/views/Things/ThingsView.jsx +++ b/src/views/Things/ThingsView.jsx @@ -12,12 +12,15 @@ import { Box, Card, Chip, + CircularProgress, Container, Grid, IconButton, + Snackbar, Typography, } from '@mui/joy' import { useEffect, useState } from 'react' +import { useNavigate } from 'react-router-dom' import { CreateThing, DeleteThing, @@ -27,13 +30,14 @@ import { } from '../../utils/Fetcher' import ConfirmationModal from '../Modals/Inputs/ConfirmationModal' import CreateThingModal from '../Modals/Inputs/CreateThingModal' - const ThingCard = ({ thing, onEditClick, onStateChangeRequest, onDeleteClick, }) => { + const [isDisabled, setIsDisabled] = useState(false) + const Navigate = useNavigate() const getThingIcon = type => { if (type === 'text') { return @@ -49,6 +53,15 @@ const ThingCard = ({ return } } + + const handleRequestChange = thing => { + setIsDisabled(true) + onStateChangeRequest(thing) + setTimeout(() => { + setIsDisabled(false) + }, 2000) + } + return ( { + Navigate(`/things/${thing?.id}`) + }} > {thing?.name} @@ -91,21 +107,39 @@ const ThingCard = ({ {/* */} - { - onStateChangeRequest(thing) - }} - sx={{ - borderRadius: '50%', - width: 50, - height: 50, - zIndex: 1, - }} - > - {getThingIcon(thing?.type)} - +
+ { + handleRequestChange(thing) + }} + sx={{ + borderRadius: '50%', + width: 50, + minWidth: 50, + height: 50, + zIndex: 1, + }} + disabled={isDisabled} + > + {getThingIcon(thing?.type)} + + {isDisabled && ( + + )} +
{ const [isShowCreateThingModal, setIsShowCreateThingModal] = useState(false) const [createModalThing, setCreateModalThing] = useState(null) const [confirmModelConfig, setConfirmModelConfig] = useState({}) + + const [isSnackbarOpen, setIsSnackbarOpen] = useState(false) + const [snackBarMessage, setSnackBarMessage] = useState('') + useEffect(() => { // fetch things GetThings().then(result => { @@ -184,6 +222,8 @@ const ThingsView = () => { } }) }) + setSnackBarMessage('Thing saved successfully') + setIsSnackbarOpen(true) } const handleEditClick = thing => { setCreateModalThing(thing) @@ -240,6 +280,8 @@ const ThingsView = () => { }) }) } + setSnackBarMessage('Thing state updated successfully') + setIsSnackbarOpen(true) } return ( @@ -317,6 +359,19 @@ const ThingsView = () => { )}
+ { + setIsSnackbarOpen(false) + }} + autoHideDuration={3000} + variant='soft' + color='success' + size='lg' + invertedColors + > + {snackBarMessage} + ) } -- cgit