import {
Bar,
BarChart,
CartesianGrid,
ResponsiveContainer,
XAxis,
YAxis,
} from 'recharts'
import { CreditCard, Toll } from '@mui/icons-material'
import {
Avatar,
Box,
Button,
Card,
Chip,
Container,
Option,
Select,
Tab,
TabList,
Tabs,
Typography,
} from '@mui/joy'
import { useContext, useEffect, useState } from 'react'
import { UserContext } from '../../contexts/UserContext.js'
import LoadingComponent from '../components/Loading.jsx'
import { useChoresHistory } from '../../queries/ChoreQueries.jsx'
import { useCircleMembers } from '../../queries/UserQueries.jsx'
import { RedeemPoints } from '../../utils/Fetcher.jsx'
import { resolvePhotoURL } from '../../utils/Helpers.jsx'
import RedeemPointsModal from '../Modals/RedeemPointsModal'
const UserPoints = () => {
const [tabValue, setTabValue] = useState(7)
const [isRedeemModalOpen, setIsRedeemModalOpen] = useState(false)
const {
data: circleMembersData,
isLoading: isCircleMembersLoading,
handleRefetch: handleCircleMembersRefetch,
} = useCircleMembers()
const {
data: choresHistoryData,
isLoading: isChoresHistoryLoading,
handleLimitChange: handleChoresHistoryLimitChange,
} = useChoresHistory(7)
const { userProfile } = useContext(UserContext)
const [selectedUser, setSelectedUser] = useState(userProfile?.id)
const [circleUsers, setCircleUsers] = useState([])
const [selectedHistory, setSelectedHistory] = useState([])
const [userPointsBarChartData, setUserPointsBarChartData] = useState([])
const [choresHistory, setChoresHistory] = useState([])
useEffect(() => {
if (circleMembersData && choresHistoryData && userProfile) {
setCircleUsers(circleMembersData.res)
setSelectedHistory(generateWeeklySummary(choresHistory, userProfile?.id))
}
}, [circleMembersData, choresHistoryData])
useEffect(() => {
if (choresHistoryData) {
var history
if (tabValue === 7) {
history = generateWeeklySummary(choresHistoryData, selectedUser)
} else if (tabValue === 30) {
history = generateMonthSummary(choresHistoryData, selectedUser)
} else if (tabValue === 6 * 30) {
history = generateMonthlySummary(choresHistoryData, selectedUser)
} else {
history = generateYearlySummary(choresHistoryData, selectedUser)
}
setSelectedHistory(history)
}
}, [selectedUser, choresHistoryData])
useEffect(() => {
setSelectedUser(userProfile?.id)
}, [userProfile])
const generateUserPointsHistory = history => {
const userPoints = {}
for (let i = 0; i < history.length; i++) {
const chore = history[i]
if (!userPoints[chore.completedBy]) {
userPoints[chore.completedBy] = chore.points ? chore.points : 0
} else {
userPoints[chore.completedBy] += chore.points ? chore.points : 0
}
}
return userPoints
}
const generateWeeklySummary = (history, userId) => {
const daysAggregated = []
for (let i = 6; i > -1; i--) {
const currentDate = new Date()
currentDate.setDate(currentDate.getDate() - i)
daysAggregated.push({
label: currentDate.toLocaleString('en-US', { weekday: 'short' }),
points: 0,
tasks: 0,
})
}
history.forEach(chore => {
const dayName = new Date(chore.completedAt).toLocaleString('en-US', {
weekday: 'short',
})
const dayIndex = daysAggregated.findIndex(dayData => {
if (userId)
return dayData.label === dayName && chore.completedBy === userId
return dayData.label === dayName
})
if (dayIndex !== -1) {
if (chore.points) daysAggregated[dayIndex].points += chore.points
daysAggregated[dayIndex].tasks += 1
}
})
return daysAggregated
}
const generateMonthSummary = (history, userId) => {
const daysAggregated = []
for (let i = 29; i > -1; i--) {
const currentDate = new Date()
currentDate.setDate(currentDate.getDate() - i)
daysAggregated.push({
label: currentDate.toLocaleString('en-US', { day: 'numeric' }),
points: 0,
tasks: 0,
})
}
history.forEach(chore => {
const dayName = new Date(chore.completedAt).toLocaleString('en-US', {
day: 'numeric',
})
const dayIndex = daysAggregated.findIndex(dayData => {
if (userId)
return dayData.label === dayName && chore.completedBy === userId
return dayData.label === dayName
})
if (dayIndex !== -1) {
if (chore.points) daysAggregated[dayIndex].points += chore.points
daysAggregated[dayIndex].tasks += 1
}
})
return daysAggregated
}
const generateMonthlySummary = (history, userId) => {
const monthlyAggregated = []
for (let i = 5; i > -1; i--) {
const currentMonth = new Date()
currentMonth.setMonth(currentMonth.getMonth() - i)
monthlyAggregated.push({
label: currentMonth.toLocaleString('en-US', { month: 'short' }),
points: 0,
tasks: 0,
})
}
history.forEach(chore => {
const monthName = new Date(chore.completedAt).toLocaleString('en-US', {
month: 'short',
})
const monthIndex = monthlyAggregated.findIndex(monthData => {
if (userId)
return monthData.label === monthName && chore.completedBy === userId
return monthData.label === monthName
})
if (monthIndex !== -1) {
if (chore.points) monthlyAggregated[monthIndex].points += chore.points
monthlyAggregated[monthIndex].tasks += 1
}
})
return monthlyAggregated
}
const generateYearlySummary = (history, userId) => {
const yearlyAggregated = []
for (let i = 11; i > -1; i--) {
const currentYear = new Date()
currentYear.setFullYear(currentYear.getFullYear() - i)
yearlyAggregated.push({
label: currentYear.toLocaleString('en-US', { year: 'numeric' }),
points: 0,
tasks: 0,
})
}
history.forEach(chore => {
const yearName = new Date(chore.completedAt).toLocaleString('en-US', {
year: 'numeric',
})
const yearIndex = yearlyAggregated.findIndex(yearData => {
if (userId)
return yearData.label === yearName && chore.completedBy === userId
return yearData.label === yearName
})
if (yearIndex !== -1) {
if (chore.points) yearlyAggregated[yearIndex].points += chore.points
yearlyAggregated[yearIndex].tasks += 1
}
})
return yearlyAggregated
}
if (isChoresHistoryLoading || isCircleMembersLoading || !userProfile) {
return
}
return (
Points Overview
{circleUsers.find(user => user.userId === userProfile.id)?.role ===
'admin' && (
}
onClick={() => {
setIsRedeemModalOpen(true)
}}
>
Redeem Points
)}
{[
{
title: 'Total',
value: circleMembersData.res.find(
user => user.userId === selectedUser,
)?.points,
color: 'primary',
},
{
title: 'Available',
value: (function () {
const user = circleMembersData.res.find(
user => user.userId === selectedUser,
)
if (!user) return 0
return user.points - user.pointsRedeemed
})(),
color: 'success',
},
{
title: 'Redeemed',
value: circleMembersData.res.find(
user => user.userId === selectedUser,
)?.pointsRedeemed,
color: 'warning',
},
].map(card => (
{card.title}
{card.value}
))}
Points History
{
setTabValue(tabValue)
handleChoresHistoryLimitChange(tabValue)
}}
defaultValue={tabValue}
sx={{
py: 0.5,
borderRadius: 16,
maxWidth: 400,
mb: 1,
}}
>
{[
{ label: '7 Days', value: 7 },
// { label: '3 Month', value: 30 },
{ label: '6 Months', value: 6 * 30 },
{ label: 'All Time', value: 24 * 30 },
].map((tab, index) => (
{tab.label}
))}
{[
{
title: 'Points',
value: selectedHistory.reduce((acc, cur) => acc + cur.points, 0),
color: 'success',
},
{
title: 'Tasks',
value: selectedHistory.reduce((acc, cur) => acc + cur.tasks, 0),
color: 'primary',
},
].map(card => (
{card.title}
{card.value}
))}
{/* Bar Chart for points overtime : */}
{/* Rounded top corners, blue fill, set bar width */}
{/* Add a slightly darker top section to the 'Jul' bar */}
{
setIsRedeemModalOpen(false)
},
isOpen: isRedeemModalOpen,
available: circleUsers.find(user => user.userId === selectedUser)
?.points,
user: circleUsers.find(user => user.userId === selectedUser),
onSave: ({ userId, points }) => {
RedeemPoints(userId, points, userProfile.circleID)
.then(res => {
setIsRedeemModalOpen(false)
handleCircleMembersRefetch()
})
.catch(err => {
console.log(err)
})
},
}}
/>
)
}
export default UserPoints