1
1
mirror of https://github.com/theoludwig/p61-project.git synced 2024-07-17 07:00:12 +02:00
p61-project/presentation/react/components/Stats/Stats.tsx

199 lines
6.5 KiB
TypeScript
Raw Normal View History

2024-04-12 13:43:49 +02:00
import { Card, Text } from "react-native-paper"
2024-04-12 15:27:11 +02:00
import CircularProgress from "react-native-circular-progress-indicator"
2024-05-20 15:35:49 +02:00
import { Agenda } from "react-native-calendars"
2024-05-21 23:35:04 +02:00
import type { SetStateAction } from "react"
import { useState, useEffect } from "react"
2024-04-12 13:43:49 +02:00
2024-05-20 23:56:21 +02:00
import { getNowDateUTC, getISODate } from "@/utils/dates"
2024-04-12 15:27:11 +02:00
import type { HabitsTracker } from "@/domain/entities/HabitsTracker"
2024-05-21 23:35:04 +02:00
import type { HabitHistory } from "@/domain/entities/HabitHistory"
2024-04-12 15:27:11 +02:00
export interface StatsProps {
habitsTracker: HabitsTracker
}
2024-05-21 23:35:04 +02:00
export const Stats: React.FC<StatsProps> = ({ habitsTracker }) => {
2024-05-20 23:56:21 +02:00
const today = getNowDateUTC()
2024-05-20 15:35:49 +02:00
const todayISO = getISODate(today)
const [selectedDate, setSelectedDate] = useState<Date>(today)
const selectedDateISO = getISODate(selectedDate)
2024-04-12 15:27:11 +02:00
const habitsHistory = habitsTracker.getAllHabitsHistory()
2024-04-12 13:43:49 +02:00
2024-05-21 23:35:04 +02:00
const [goalDays, setGoalDays] = useState(0)
const [totalGoalDays, setTotalGoalDays] = useState(0)
const [displayDaily, setDisplayDaily] = useState(true)
const [goalWeek, setGoalWeek] = useState(0)
const [totalGoalWeek, setTotalGoalWeek] = useState(0)
const [displayWeekly, setDisplayWeekly] = useState(true)
const [goalMonth, setGoalMonth] = useState(0)
const [totalGoalMonth, setTotalGoalMonth] = useState(0)
const [displayMonthly, setDisplayMonthly] = useState(true)
2024-05-20 15:35:49 +02:00
2024-05-21 23:35:04 +02:00
const updateStats = (date: Date): void => {
const dailyHabits = habitsHistory.filter((el) => {
return (
el.habit.goal.frequency === "daily" &&
el.habit.startDate.getFullYear() <= date.getFullYear() &&
el.habit.startDate.getMonth() <= date.getMonth() &&
el.habit.startDate.getDate() <= date.getDate()
)
})
const weeklyHabits = habitsHistory.filter((el) => {
return (
el.habit.goal.frequency === "weekly" &&
el.habit.startDate.getFullYear() <= date.getFullYear() &&
el.habit.startDate.getMonth() <= date.getMonth() &&
el.habit.startDate.getDate() <= date.getDate()
)
})
const monthlyHabits = habitsHistory.filter((el) => {
return (
el.habit.goal.frequency === "monthly" &&
el.habit.startDate.getFullYear() <= date.getFullYear() &&
el.habit.startDate.getMonth() <= date.getMonth() &&
el.habit.startDate.getDate() <= date.getDate()
)
})
2024-05-20 15:35:49 +02:00
2024-05-21 23:35:04 +02:00
const calculateGoals = (
habits: HabitHistory[],
setTotalGoals: {
(value: SetStateAction<number>): void
(value: SetStateAction<number>): void
(value: SetStateAction<number>): void
(arg0: any): void
},
setGoals: {
(value: SetStateAction<number>): void
(value: SetStateAction<number>): void
(value: SetStateAction<number>): void
(arg0: any): void
},
): void => {
setTotalGoals(habits.length)
const completedGoals = habits.filter((el) => {
return (
el.getProgressesByDate(date)[0]?.goalProgress.isCompleted() ?? false
)
}).length
setGoals(completedGoals)
2024-05-20 15:35:49 +02:00
}
2024-05-21 23:35:04 +02:00
if (dailyHabits.length === 0) {
setDisplayDaily(false)
} else {
setDisplayDaily(true)
calculateGoals(dailyHabits, setTotalGoalDays, setGoalDays)
}
if (weeklyHabits.length === 0) {
setDisplayWeekly(false)
} else {
setDisplayWeekly(true)
calculateGoals(weeklyHabits, setTotalGoalWeek, setGoalWeek)
}
2024-05-20 15:35:49 +02:00
2024-05-21 23:35:04 +02:00
if (monthlyHabits.length === 0) {
setDisplayMonthly(false)
} else {
setDisplayMonthly(true)
calculateGoals(monthlyHabits, setTotalGoalMonth, setGoalMonth)
2024-05-20 15:35:49 +02:00
}
}
2024-05-21 23:35:04 +02:00
useEffect(() => {
updateStats(selectedDate)
}, [selectedDate])
2024-05-20 15:35:49 +02:00
return (
<Agenda
firstDay={1}
showClosingKnob
onDayPress={(date) => {
2024-05-21 23:35:04 +02:00
return setSelectedDate(new Date(date.dateString))
2024-05-20 15:35:49 +02:00
}}
markedDates={{
[todayISO]: { marked: true, today: true },
}}
maxDate={todayISO}
selected={selectedDateISO}
renderList={() => {
return (
<>
2024-05-21 23:35:04 +02:00
<Card key="statsDay" mode="outlined">
<Card.Title title="Success Day" />
<Card.Content>
{displayDaily ? (
<>
<Text variant="bodyMedium">
{goalDays} but réussi dans la journée sur {totalGoalDays}
</Text>
<CircularProgress
value={(goalDays / totalGoalDays) * 100}
activeStrokeWidth={12}
progressValueColor={"#ecf0f1"}
circleBackgroundColor="black"
titleColor="white"
title="%"
/>
</>
) : (
<Text variant="bodyMedium">Aucun objectif quotidien</Text>
)}
</Card.Content>
</Card>
<Card key="statsWeek" mode="outlined">
<Card.Title title="Success Week" />
<Card.Content>
{displayWeekly ? (
<>
<Text variant="bodyMedium">
{goalWeek} but réussi dans la semaine sur {totalGoalWeek}
</Text>
<CircularProgress
value={(goalWeek / totalGoalWeek) * 100}
activeStrokeWidth={12}
progressValueColor={"#ecf0f1"}
circleBackgroundColor="black"
titleColor="white"
title="%"
/>
</>
) : (
<Text variant="bodyMedium">Aucun objectif hebdomadaire</Text>
)}
</Card.Content>
</Card>
<Card key="statsMonth" mode="outlined">
<Card.Title title="Success Month" />
<Card.Content>
{displayMonthly ? (
<>
<Text variant="bodyMedium">
{goalMonth} but réussi dans le mois sur {totalGoalMonth}
</Text>
<CircularProgress
value={(goalMonth / totalGoalMonth) * 100}
activeStrokeWidth={12}
progressValueColor={"#ecf0f1"}
circleBackgroundColor="black"
titleColor="white"
title="%"
/>
</>
) : (
<Text variant="bodyMedium">Aucun objectif mensuel</Text>
)}
</Card.Content>
</Card>
2024-05-20 15:35:49 +02:00
</>
)
}}
/>
2024-04-12 13:43:49 +02:00
)
}