Improve MarkChoreComplete, allow complete in past ,etc

This commit is contained in:
Mo Tarbin 2024-07-07 00:25:11 -04:00
parent df83cc8948
commit e039b732a8
3 changed files with 228 additions and 92 deletions

View file

@ -3,14 +3,19 @@ import {
CancelScheduleSend,
Check,
Checklist,
Note,
PeopleAlt,
Person,
} from '@mui/icons-material'
import {
Box,
Button,
Checkbox,
Container,
Divider,
FormControl,
Grid,
Input,
ListItem,
ListItemContent,
ListItemDecorator,
@ -21,7 +26,7 @@ import {
} from '@mui/joy'
import moment from 'moment'
import { useEffect, useState } from 'react'
import { useParams, useSearchParams } from 'react-router-dom'
import { useNavigate, useParams, useSearchParams } from 'react-router-dom'
import {
GetAllUsers,
GetChoreDetailById,
@ -43,14 +48,16 @@ const ChoreView = () => {
const [performers, setPerformers] = useState([])
const [infoCards, setInfoCards] = useState([])
const { choreId } = useParams()
const [note, setNote] = useState(null)
// query param `complete=true`
const Navigate = useNavigate()
const [searchParams] = useSearchParams()
const [isPendingCompletion, setIsPendingCompletion] = useState(false)
const [timeoutId, setTimeoutId] = useState(null)
const [secondsLeftToCancel, setSecondsLeftToCancel] = useState(null)
const [completedDate, setCompletedDate] = useState(null)
useEffect(() => {
Promise.all([
GetChoreDetailById(choreId).then(resp => {
@ -82,7 +89,7 @@ const ChoreView = () => {
{
icon: <CalendarMonth />,
text: 'Due Date',
subtext: moment(chore.dueDate).format('MM/DD/YYYY hh:mm A'),
subtext: moment(chore.nextDueDate).format('MM/DD/YYYY hh:mm A'),
},
{
icon: <PeopleAlt />,
@ -119,12 +126,21 @@ const ChoreView = () => {
subtext: chore.lastCompletedDate
? `${
chore.lastCompletedDate &&
moment(chore.lastCompletedDate).format('MM/DD/YYYY hh:mm A')
}(${
performers.find(p => p.id === chore.lastCompletedBy)?.displayName
})`
moment(chore.lastCompletedDate).fromNow()
// moment(chore.lastCompletedDate).format('MM/DD/YYYY hh:mm A'))
}(
${
performers.find(p => p.id === chore.lastCompletedBy)
?.displayName
}
)`
: 'Never',
},
{
icon: <Note />,
text: 'Recent Note',
subtext: chore.notes || '--',
},
]
setInfoCards(cards)
}
@ -143,10 +159,11 @@ const ChoreView = () => {
}, 1000)
const id = setTimeout(() => {
MarkChoreComplete(choreId)
MarkChoreComplete(choreId, note, completedDate)
.then(resp => {
if (resp.ok) {
return resp.json().then(data => {
setNote(null)
setChore(data.res)
})
}
@ -174,75 +191,130 @@ const ChoreView = () => {
}
return (
<Container maxWidth='sm'>
<Sheet
variant='plain'
sx={{
borderRadius: 'sm',
p: 2,
boxShadow: 'md',
minHeight: '90vh',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
}}
>
<Box>
<Typography
level='h4'
textAlign={'center'}
sx={{
mt: 2,
mb: 4,
}}
>
{chore.name}
</Typography>
<Grid container spacing={1}>
{infoCards.map((info, index) => (
<Grid key={index} item xs={12} sm={6}>
<Sheet
sx={{ mb: 1, borderRadius: 'md', p: 1, boxShadow: 'sm' }}
>
<ListItem>
<ListItemDecorator>
<IconCard>{info.icon}</IconCard>
</ListItemDecorator>
<ListItemContent>
<Typography level='body1' sx={{ fontWeight: 'md' }}>
{info.text}
</Typography>
<Typography level='body1' color='text.tertiary'>
{info.subtext ? info.subtext : '--'}
</Typography>
</ListItemContent>
</ListItem>
</Sheet>
</Grid>
))}
</Grid>
</Box>
<Box
<Container
maxWidth='sm'
sx={{
display: 'flex',
flexDirection: 'column',
// space between :
justifyContent: 'space-between',
}}
>
<Box>
<Typography
level='h3'
textAlign={'center'}
sx={{
mt: 6,
mt: 2,
mb: 4,
}}
>
<Button
fullWidth
size='lg'
sx={{
height: 50,
mb: 2,
{chore.name}
</Typography>
<Grid container spacing={1}>
{infoCards.map((info, index) => (
<Grid key={index} item xs={12} sm={6}>
<Sheet sx={{ mb: 1, borderRadius: 'md', p: 1, boxShadow: 'sm' }}>
<ListItem>
<ListItemDecorator>
<IconCard>{info.icon}</IconCard>
</ListItemDecorator>
<ListItemContent>
<Typography level='body1' sx={{ fontWeight: 'md' }}>
{info.text}
</Typography>
<Typography level='body1' color='text.tertiary'>
{info.subtext ? info.subtext : '--'}
</Typography>
</ListItemContent>
</ListItem>
</Sheet>
</Grid>
))}
</Grid>
</Box>
<Divider
sx={{
my: 2,
}}
/>
<Box>
<Typography level='title-md'>Additional Notes</Typography>
<Input
fullWidth
multiline
label='Additional Notes'
placeholder='note or information about the task'
value={note || ''}
onChange={e => {
if (e.target.value.trim() === '') {
setNote(null)
return
}
setNote(e.target.value)
}}
size='md'
sx={{
my: 1,
}}
/>
<FormControl size='sm' sx={{ width: 400 }}>
<Checkbox
defaultChecked={completedDate !== null}
checked={completedDate !== null}
value={completedDate !== null}
onChange={e => {
if (e.target.checked) {
setCompletedDate(
moment(new Date()).format('YYYY-MM-DDTHH:00:00'),
)
} else {
setCompletedDate(null)
}
}}
onClick={handleTaskCompletion}
disabled={isPendingCompletion}
color={isPendingCompletion ? 'danger' : 'success'}
startDecorator={<Check />}
>
<Box>Mark as done</Box>
</Button>
{/* <Button
overlay
sx={{
my: 1,
}}
label={<Typography level='body2'>Set completion date</Typography>}
/>
</FormControl>
{completedDate !== null && (
<Input
sx={{ mt: 1, mb: 1.5, width: 300 }}
type='datetime-local'
value={completedDate}
onChange={e => {
setCompletedDate(e.target.value)
}}
/>
)}
{completedDate === null && (
// placeholder for the completion date with margin:
<Box
sx={{
height: 56,
}}
/>
)}
<Button
fullWidth
size='lg'
sx={{
height: 50,
mb: 2,
}}
onClick={handleTaskCompletion}
disabled={isPendingCompletion}
color={isPendingCompletion ? 'danger' : 'success'}
startDecorator={<Check />}
>
<Box>Mark as done</Box>
</Button>
{/* <Button
sx={{
borderRadius: '32px',
mt: 1,
@ -258,8 +330,8 @@ const ChoreView = () => {
>
<Box>Mark as {isPendingCompletion ? 'completed' : 'done'}</Box>
</Button> */}
</Box>
</Sheet>
</Box>
<Snackbar
open={isPendingCompletion}
endDecorator={