diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hooks/useWindowWidth.js | 19 | ||||
-rw-r--r-- | src/views/Chores/ChoreCard.jsx | 10 | ||||
-rw-r--r-- | src/views/History/ChoreHistory.jsx | 113 | ||||
-rw-r--r-- | src/views/History/HistoryCard.jsx | 120 |
4 files changed, 157 insertions, 105 deletions
diff --git a/src/hooks/useWindowWidth.js b/src/hooks/useWindowWidth.js new file mode 100644 index 0000000..92bf184 --- /dev/null +++ b/src/hooks/useWindowWidth.js @@ -0,0 +1,19 @@ +import { useEffect, useState } from 'react' +const useWindowWidth = () => { + const [windowWidth, setWindowWidth] = useState() + + useEffect(() => { + const handleResize = () => { + setWindowWidth(window.innerWidth) + } + + window.addEventListener('resize', handleResize) + + // Cleanup function to remove the event listener + return () => window.removeEventListener('resize', handleResize) + }, []) + + return windowWidth +} + +export default useWindowWidth diff --git a/src/views/Chores/ChoreCard.jsx b/src/views/Chores/ChoreCard.jsx index 5e54e6b..08a5406 100644 --- a/src/views/Chores/ChoreCard.jsx +++ b/src/views/Chores/ChoreCard.jsx @@ -45,7 +45,14 @@ import DateModal from '../Modals/Inputs/DateModal' import SelectModal from '../Modals/Inputs/SelectModal' import TextModal from '../Modals/Inputs/TextModal' import WriteNFCModal from '../Modals/Inputs/WriteNFCModal' -const ChoreCard = ({ chore, performers, onChoreUpdate, onChoreRemove, sx }) => { +const ChoreCard = ({ + chore, + performers, + onChoreUpdate, + onChoreRemove, + sx, + viewOnly, +}) => { const [activeUserId, setActiveUserId] = React.useState(0) const [isChangeDueDateModalOpen, setIsChangeDueDateModalOpen] = React.useState(false) @@ -367,6 +374,7 @@ const ChoreCard = ({ chore, performers, onChoreUpdate, onChoreRemove, sx }) => { </Chip> <Card + style={viewOnly ? { pointerEvents: 'none' } : {}} variant='plain' sx={{ ...sx, diff --git a/src/views/History/ChoreHistory.jsx b/src/views/History/ChoreHistory.jsx index 22ea6a9..b85e456 100644 --- a/src/views/History/ChoreHistory.jsx +++ b/src/views/History/ChoreHistory.jsx @@ -3,12 +3,10 @@ import { Avatar, Box, Button, - Chip, CircularProgress, Container, Grid, List, - ListDivider, ListItem, ListItemContent, ListItemDecorator, @@ -21,6 +19,7 @@ import { Link, useParams } from 'react-router-dom' import { API_URL } from '../../Config' import { GetAllCircleMembers } from '../../utils/Fetcher' import { Fetch } from '../../utils/TokenManager' +import HistoryCard from './HistoryCard' const ChoreHistory = () => { const [choreHistory, setChoresHistory] = useState([]) @@ -144,25 +143,6 @@ const ChoreHistory = () => { setHistoryInfo(historyInfo) } - function 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 (isLoading) { return <CircularProgress /> // Show loading indicator } @@ -251,89 +231,14 @@ const ChoreHistory = () => { {/* Chore History List (Updated Style) */} <List sx={{ p: 0 }}> - {choreHistory.map((chore, index) => ( - <> - <ListItem sx={{ gap: 1.5, alignItems: 'flex-start' }}> - {' '} - {/* Adjusted spacing and alignment */} - <ListItemDecorator> - <Avatar sx={{ mr: 1 }}> - {performers - .find(p => p.userId === chore.completedBy) - ?.displayName?.charAt(0) || '?'} - </Avatar> - </ListItemDecorator> - <ListItemContent sx={{ my: 0 }}> - {' '} - {/* Removed vertical margin */} - <Box - sx={{ - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - }} - > - <Typography level='body1' sx={{ fontWeight: 'md' }}> - {moment(chore.completedAt).format('ddd MM/DD/yyyy HH:mm')} - </Typography> - - <Chip> - {chore.dueDate && chore.completedAt > chore.dueDate - ? 'Late' - : 'On Time'} - </Chip> - </Box> - <Typography level='body2' color='text.tertiary'> - <Chip> - { - performers.find(p => p.userId === chore.completedBy) - ?.displayName - } - </Chip>{' '} - completed - {chore.completedBy !== chore.assignedTo && ( - <> - {', '} - assigned to{' '} - <Chip> - { - performers.find(p => p.userId === chore.assignedTo) - ?.displayName - } - </Chip> - </> - )} - </Typography> - {chore.dueDate && ( - <Typography level='body2' color='text.tertiary'> - Due: {moment(chore.dueDate).format('ddd MM/DD/yyyy')} - </Typography> - )} - {chore.notes && ( - <Typography level='body2' color='text.tertiary'> - Note: {chore.notes} - </Typography> - )} - </ListItemContent> - </ListItem> - {index < choreHistory.length - 1 && ( - <> - <ListDivider component='li'> - {/* time between two completion: */} - {index < choreHistory.length - 1 && - choreHistory[index + 1].completedAt && ( - <Typography level='body3' color='text.tertiary'> - {formatTimeDifference( - chore.completedAt, - choreHistory[index + 1].completedAt, - )}{' '} - before - </Typography> - )} - </ListDivider> - </> - )} - </> + {choreHistory.map((historyEntry, index) => ( + <HistoryCard + historyEntry={historyEntry} + performers={performers} + allHistory={choreHistory} + key={index} + index={index} + /> ))} </List> </Box> diff --git a/src/views/History/HistoryCard.jsx b/src/views/History/HistoryCard.jsx new file mode 100644 index 0000000..c606fbf --- /dev/null +++ b/src/views/History/HistoryCard.jsx @@ -0,0 +1,120 @@ +import { + Avatar, + Box, + Chip, + ListDivider, + ListItem, + ListItemContent, + ListItemDecorator, + Typography, +} from '@mui/joy' +import moment from 'moment' + +const HistoryCard = ({ allHistory, performers, historyEntry, index }) => { + function 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' : ''}` + } + return ( + <> + <ListItem sx={{ gap: 1.5, alignItems: 'flex-start' }}> + {' '} + {/* Adjusted spacing and alignment */} + <ListItemDecorator> + <Avatar sx={{ mr: 1 }}> + {performers + .find(p => p.userId === historyEntry.completedBy) + ?.displayName?.charAt(0) || '?'} + </Avatar> + </ListItemDecorator> + <ListItemContent sx={{ my: 0 }}> + {' '} + {/* Removed vertical margin */} + <Box + sx={{ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + }} + > + <Typography level='body1' sx={{ fontWeight: 'md' }}> + {moment(historyEntry.completedAt).format('ddd MM/DD/yyyy HH:mm')} + </Typography> + + <Chip> + {historyEntry.dueDate && + historyEntry.completedAt > historyEntry.dueDate + ? 'Late' + : 'On Time'} + </Chip> + </Box> + <Typography level='body2' color='text.tertiary'> + <Chip> + { + performers.find(p => p.userId === historyEntry.completedBy) + ?.displayName + } + </Chip>{' '} + completed + {historyEntry.completedBy !== historyEntry.assignedTo && ( + <> + {', '} + assigned to{' '} + <Chip> + { + performers.find(p => p.userId === historyEntry.assignedTo) + ?.displayName + } + </Chip> + </> + )} + </Typography> + {historyEntry.dueDate && ( + <Typography level='body2' color='text.tertiary'> + Due: {moment(historyEntry.dueDate).format('ddd MM/DD/yyyy')} + </Typography> + )} + {historyEntry.notes && ( + <Typography level='body2' color='text.tertiary'> + Note: {historyEntry.notes} + </Typography> + )} + </ListItemContent> + </ListItem> + {index < allHistory.length - 1 && ( + <> + <ListDivider component='li'> + {/* time between two completion: */} + {index < allHistory.length - 1 && + allHistory[index + 1].completedAt && ( + <Typography level='body3' color='text.tertiary'> + {formatTimeDifference( + historyEntry.completedAt, + allHistory[index + 1].completedAt, + )}{' '} + before + </Typography> + )} + </ListDivider> + </> + )} + </> + ) +} + +export default HistoryCard |