aboutsummaryrefslogblamecommitdiffstats
path: root/src/views/History/ChoreHistory.jsx
blob: 1db1f060c8a99dbb2ea1bfd1f22f1f5e3d75286f (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                                                            

         
         
       


            

                  








                                                         
                                                    
                                       







































































                                                                              


                                             

        


                                                                

        







                                                            

                                                                        














                                                                             

        



                               
                  
                               






































                                                                          
                                            

                   














                                                     
                                 
                                                                        

                               


                                                                             

                                  




                   
                                
                                            

                   
                                                                


                                                  







                                                      

               
              




                           
import { Checklist, EventBusy, Group, Timelapse } from '@mui/icons-material'
import {
  Avatar,
  Button,
  Chip,
  Container,
  Grid,
  List,
  ListItem,
  ListItemContent,
  Sheet,
  Typography,
} from '@mui/joy'
import moment from 'moment'
import React, { useEffect, useState } from 'react'
import { Link, useParams } from 'react-router-dom'
import { API_URL } from '../../Config'
import { GetAllCircleMembers } from '../../utils/Fetcher'
import { Fetch } from '../../utils/TokenManager'
import LoadingComponent from '../components/Loading'
import HistoryCard from './HistoryCard'

const ChoreHistory = () => {
  const [choreHistory, setChoresHistory] = useState([])
  const [userHistory, setUserHistory] = useState([])
  const [performers, setPerformers] = useState([])
  const [historyInfo, setHistoryInfo] = useState([])

  const [isLoading, setIsLoading] = useState(true) // Add loading state
  const { choreId } = useParams()

  useEffect(() => {
    setIsLoading(true) // Start loading

    Promise.all([
      Fetch(`${API_URL}/chores/${choreId}/history`).then(res => res.json()),
      GetAllCircleMembers().then(res => res.json()),
    ])
      .then(([historyData, usersData]) => {
        setChoresHistory(historyData.res)

        const newUserChoreHistory = {}
        historyData.res.forEach(choreHistory => {
          const userId = choreHistory.completedBy
          newUserChoreHistory[userId] = (newUserChoreHistory[userId] || 0) + 1
        })
        setUserHistory(newUserChoreHistory)

        setPerformers(usersData.res)
        updateHistoryInfo(historyData.res, newUserChoreHistory, usersData.res)
      })
      .catch(error => {
        console.error('Error fetching data:', error)
        // Handle errors, e.g., show an error message to the user
      })
      .finally(() => {
        setIsLoading(false) // Finish loading
      })
  }, [choreId])

  const updateHistoryInfo = (histories, userHistories, performers) => {
    // average delay for task completaion from due date:

    const averageDelay =
      histories.reduce((acc, chore) => {
        if (chore.dueDate) {
          // Only consider chores with a due date
          return acc + moment(chore.completedAt).diff(chore.dueDate, 'hours')
        }
        return acc
      }, 0) / histories.length
    const averageDelayMoment = moment.duration(averageDelay, 'hours')
    const maximumDelay = histories.reduce((acc, chore) => {
      if (chore.dueDate) {
        // Only consider chores with a due date
        const delay = moment(chore.completedAt).diff(chore.dueDate, 'hours')
        return delay > acc ? delay : acc
      }
      return acc
    }, 0)

    const maxDelayMoment = moment.duration(maximumDelay, 'hours')

    // find max value in userHistories:
    const userCompletedByMost = Object.keys(userHistories).reduce((a, b) =>
      userHistories[a] > userHistories[b] ? a : b,
    )
    const userCompletedByLeast = Object.keys(userHistories).reduce((a, b) =>
      userHistories[a] < userHistories[b] ? a : b,
    )

    const historyInfo = [
      {
        icon: <Checklist />,
        text: 'Total Completed',
        subtext: `${histories.length} times`,
      },
      {
        icon: <Timelapse />,
        text: 'Usually Within',
        subtext: moment.duration(averageDelayMoment).humanize(),
      },
      {
        icon: <Timelapse />,
        text: 'Maximum Delay',
        subtext: moment.duration(maxDelayMoment).humanize(),
      },
      {
        icon: <Avatar />,
        text: ' Completed Most',
        subtext: `${
          performers.find(p => p.userId === Number(userCompletedByMost))
            ?.displayName
        } `,
      },
      //  contributes:
      {
        icon: <Group />,
        text: 'Total Performers',
        subtext: `${Object.keys(userHistories).length} users`,
      },
      {
        icon: <Avatar />,
        text: 'Last Completed',
        subtext: `${
          performers.find(p => p.userId === Number(histories[0].completedBy))
            ?.displayName
        }`,
      },
    ]

    setHistoryInfo(historyInfo)
  }

  if (isLoading) {
    return <LoadingComponent />
  }
  if (!choreHistory.length) {
    return (
      <Container
        maxWidth='md'
        sx={{
          textAlign: 'center',
          display: 'flex',
          // make sure the content is centered vertically:
          alignItems: 'center',
          justifyContent: 'center',
          flexDirection: 'column',
          height: '50vh',
        }}
      >
        <EventBusy
          sx={{
            fontSize: '6rem',
            // color: 'text.disabled',
            mb: 1,
          }}
        />

        <Typography level='h3' gutterBottom>
          No History Yet
        </Typography>
        <Typography level='body1'>
          You haven't completed any tasks. Once you start finishing tasks,
          they'll show up here.
        </Typography>
        <Button variant='soft' sx={{ mt: 2 }}>
          <Link to='/my/chores'>Go back to chores</Link>
        </Button>
      </Container>
    )
  }

  return (
    <Container maxWidth='md'>
      <Typography level='title-md' mb={1.5}>
        Summary:
      </Typography>
      <Sheet
        // sx={{
        //   mb: 1,
        //   borderRadius: 'lg',
        //   p: 2,
        // }}
        sx={{ borderRadius: 'sm', p: 2 }}
        variant='outlined'
      >
        <Grid container spacing={1}>
          {historyInfo.map((info, index) => (
            <Grid item xs={4} key={index}>
              {/* divider between the list items: */}

              <ListItem key={index}>
                <ListItemContent>
                  <Typography level='body-xs' sx={{ fontWeight: 'md' }}>
                    {info.text}
                  </Typography>
                  <Chip color='primary' size='md' startDecorator={info.icon}>
                    {info.subtext ? info.subtext : '--'}
                  </Chip>
                </ListItemContent>
              </ListItem>
            </Grid>
          ))}
        </Grid>
      </Sheet>

      {/* User History Cards */}
      <Typography level='title-md' my={1.5}>
        History:
      </Typography>
      <Sheet sx={{ borderRadius: 'sm', p: 2, boxShadow: 'md' }}>
        {/* Chore History List (Updated Style) */}

        <List sx={{ p: 0 }}>
          {choreHistory.map((historyEntry, index) => (
            <HistoryCard
              historyEntry={historyEntry}
              performers={performers}
              allHistory={choreHistory}
              key={index}
              index={index}
            />
          ))}
        </List>
      </Sheet>
    </Container>
  )
}

export default ChoreHistory