import {
CheckCircle,
EventNote,
Notes,
Person,
Redo,
Refresh,
Timelapse,
Toll,
WatchLater,
} from '@mui/icons-material'
import {
Avatar,
Box,
Chip,
Divider,
IconButton,
List,
ListItem,
ListItemContent,
ListItemDecorator,
Sheet,
Typography,
} from '@mui/joy'
import moment from 'moment'
import { useChores, useChoresHistory } from '../../queries/ChoreQueries'
import { useCircleMembers } from '../../queries/UserQueries'
import { resolvePhotoURL } from '../../utils/Helpers'
const ActivityItem = ({ activity, members }) => {
// Find the member who completed the activity
const completedByMember = members?.find(
member => member.userId === activity.completedBy,
)
const getTimeDisplay = dateToDisplay => {
const now = moment()
const completed = moment(dateToDisplay)
const diffInHours = now.diff(completed, 'hours')
const diffInDays = now.diff(completed, 'days')
if (diffInHours < 1) {
return 'Just now'
} else if (diffInHours < 24) {
return `${diffInHours}h ago`
} else if (diffInDays < 7) {
return `${diffInDays}d ago`
} else {
return completed.format('MMM DD')
}
}
const getStatusInfo = activity => {
if (activity.status === 0) {
return {
color: 'primary',
text: 'Started',
icon: ,
}
}
if (!activity.status === 1) {
return {
color: 'neutral',
text: 'Completed',
icon: ,
}
} else if (activity.status === 2) {
// skipped
return {
color: 'warning',
text: 'Skipped',
icon: ,
}
}
const wasOnTime = moment(activity.performedAt).isSameOrBefore(
moment(activity.dueDate),
)
if (wasOnTime) {
return {
color: 'success',
text: 'Done',
icon: ,
}
} else {
return {
color: 'primary',
text: 'Late',
icon: ,
}
}
}
return (
{completedByMember?.displayName?.charAt(0) ||
completedByMember?.name?.charAt(0) || }
{/* Activity header */}
{activity.choreName}
{getTimeDisplay(
activity.performedAt ||
activity.updatedAt ||
activity.createdAt,
)}
{/* Who completed it */}
{/* Status chip */}
{getStatusInfo(activity).text}
by{' '}
{completedByMember?.displayName ||
completedByMember?.name ||
'Unknown'}
{/* Points chip */}
{activity.points && activity.points > 0 && (
}
>
{activity.points} pts
)}
{/* Status, Points, and Notes */}
{/* Notes */}
{activity.notes && (
{activity.notes}
)}
)
}
const groupActivitiesByDate = activities => {
const groups = {}
activities.forEach(activity => {
const date = moment(
activity.performedAt || activity.updatedAt || activity.createdAt,
).format('YYYY-MM-DD')
if (!groups[date]) {
groups[date] = []
}
groups[date].push(activity)
})
return groups
}
const ActivitiesCard = ({ title = 'Recent Activities' }) => {
// Use hooks to fetch data
const {
data: choresData,
isLoading: isChoresLoading,
refetch: refetchChores,
} = useChores(true) // Include archived chores
const {
data: choreHistory,
isLoading: isChoresHistoryLoading,
refetch: refetchHistory,
} = useChoresHistory(10, true) // Limit to 10 items, include members
const {
data: circleMembersData,
isLoading: isCircleMembersLoading,
refetch: refetchMembers,
} = useCircleMembers()
// Extract data from responses
const chores = choresData?.res || []
const members = circleMembersData?.res || []
// Refresh function to refetch all data
const handleRefresh = async () => {
await Promise.all([refetchChores(), refetchHistory(), refetchMembers()])
}
// Show loading state
if (isChoresLoading || isChoresHistoryLoading || isCircleMembersLoading) {
return (
{title}
Loading activities...
)
}
// Enrich history with chore names
const enrichedHistory =
choreHistory?.map(history => {
const chore = chores?.find(c => c.id === history.choreId)
return {
...history,
choreName: chore?.name || 'Unknown Chore',
}
}) || []
// Sort by completion date (most recent first)
const sortedHistory = enrichedHistory
.sort(
(a, b) =>
moment(b.performedAt || b.updatedAt).valueOf() -
moment(a.performedAt || a.updatedAt).valueOf(),
)
.slice(0, 10) // Show only latest 10 activities
const groupedActivities = groupActivitiesByDate(sortedHistory)
if (!sortedHistory.length) {
return (
{title}
No recent activities
)
}
return (
{/* Header */}
{title}
{sortedHistory.length}
{/* Scrollable activity list */}
{Object.entries(groupedActivities).map(([date, activities]) => {
const isToday = moment(date).isSame(moment(), 'day')
const isYesterday = moment(date).isSame(
moment().subtract(1, 'day'),
'day',
)
let dateLabel
if (isToday) {
dateLabel = 'Today'
} else if (isYesterday) {
dateLabel = 'Yesterday'
} else {
dateLabel = moment(date).format('MMM DD')
}
return (
{/* Date separator */}
{dateLabel}
{/* Activities for this date */}
{activities.map(activity => (
))}
)
})}
)
}
export default ActivitiesCard