2024-07-16 19:37:18 -04:00
|
|
|
import { CalendarViewDay, Check, Timelapse } from '@mui/icons-material'
|
2024-07-09 17:39:16 -04:00
|
|
|
import {
|
|
|
|
Avatar,
|
|
|
|
Box,
|
|
|
|
Chip,
|
|
|
|
ListDivider,
|
|
|
|
ListItem,
|
|
|
|
ListItemContent,
|
|
|
|
ListItemDecorator,
|
|
|
|
Typography,
|
|
|
|
} from '@mui/joy'
|
|
|
|
import moment from 'moment'
|
|
|
|
|
2024-07-20 03:40:41 -04:00
|
|
|
const HistoryCard = ({
|
|
|
|
allHistory,
|
|
|
|
performers,
|
|
|
|
historyEntry,
|
|
|
|
index,
|
|
|
|
onClick,
|
|
|
|
}) => {
|
2024-07-09 17:39:16 -04:00
|
|
|
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' : ''}`
|
|
|
|
}
|
2024-07-16 19:37:18 -04:00
|
|
|
|
|
|
|
const getCompletedChip = historyEntry => {
|
|
|
|
var text = 'No Due Date'
|
|
|
|
var color = 'info'
|
|
|
|
var icon = <CalendarViewDay />
|
|
|
|
// if completed few hours +-6 hours
|
|
|
|
if (
|
|
|
|
historyEntry.dueDate &&
|
|
|
|
historyEntry.completedAt > historyEntry.dueDate - 1000 * 60 * 60 * 6 &&
|
|
|
|
historyEntry.completedAt < historyEntry.dueDate + 1000 * 60 * 60 * 6
|
|
|
|
) {
|
|
|
|
text = 'On Time'
|
|
|
|
color = 'success'
|
|
|
|
icon = <Check />
|
|
|
|
} else if (
|
|
|
|
historyEntry.dueDate &&
|
|
|
|
historyEntry.completedAt < historyEntry.dueDate
|
|
|
|
) {
|
|
|
|
text = 'On Time'
|
|
|
|
color = 'success'
|
|
|
|
icon = <Check />
|
|
|
|
}
|
|
|
|
|
|
|
|
// if completed after due date then it's late
|
|
|
|
else if (
|
|
|
|
historyEntry.dueDate &&
|
|
|
|
historyEntry.completedAt > historyEntry.dueDate
|
|
|
|
) {
|
|
|
|
text = 'Late'
|
|
|
|
color = 'warning'
|
|
|
|
icon = <Timelapse />
|
|
|
|
} else {
|
|
|
|
text = 'No Due Date'
|
2024-07-20 03:40:41 -04:00
|
|
|
color = 'neutral'
|
2024-07-16 19:37:18 -04:00
|
|
|
icon = <CalendarViewDay />
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Chip startDecorator={icon} color={color}>
|
|
|
|
{text}
|
|
|
|
</Chip>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-07-09 17:39:16 -04:00
|
|
|
return (
|
|
|
|
<>
|
2024-07-20 03:40:41 -04:00
|
|
|
<ListItem sx={{ gap: 1.5, alignItems: 'flex-start' }} onClick={onClick}>
|
2024-07-09 17:39:16 -04:00
|
|
|
{' '}
|
|
|
|
{/* 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' }}>
|
2024-07-20 03:40:41 -04:00
|
|
|
{historyEntry.completedAt
|
|
|
|
? moment(historyEntry.completedAt).format(
|
|
|
|
'ddd MM/DD/yyyy HH:mm',
|
|
|
|
)
|
|
|
|
: 'Skipped'}
|
2024-07-09 17:39:16 -04:00
|
|
|
</Typography>
|
2024-07-16 19:37:18 -04:00
|
|
|
{getCompletedChip(historyEntry)}
|
2024-07-09 17:39:16 -04:00
|
|
|
</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
|