diff --git a/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx b/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx new file mode 100644 index 00000000..3ed0ffff --- /dev/null +++ b/apps/timo-web/app/[locale]/(main)/statistics/_components/StatisticsCalendar.tsx @@ -0,0 +1,120 @@ +import { + StatisticsClockEmptyIcon, + StatisticsClockFilledIcon, + StatisticsClockLightIcon, + StatisticsClockOutlineIcon, +} from "@repo/timo-design-system/icons"; +import { cn } from "@repo/timo-design-system/utils"; + +import type { StatisticsCalendarResponse } from "@/app/[locale]/(main)/statistics/_types/statistics"; + +import { + formatStatisticsCalendarDate, + formatStatisticsMonth, +} from "@/app/[locale]/(main)/statistics/_utils/format-statistics-date"; +import { + formatDateKey, + getCalendarDates, + getFirstDayOffset, +} from "@/app/[locale]/(main)/statistics/_utils/statistics-calendar"; + +type CalendarIconStatus = "disabled" | "empty" | "outline" | "light" | "filled"; + +const DisabledClockIcon = () => ( +
+); + +const STATUS_ICON = { + disabled: DisabledClockIcon, + empty: StatisticsClockEmptyIcon, + outline: StatisticsClockOutlineIcon, + light: StatisticsClockLightIcon, + filled: StatisticsClockFilledIcon, +}; + +const getIconStatus = (completionRate: number | null): CalendarIconStatus => { + if (completionRate === null) return "disabled"; + if (completionRate === 0) return "empty"; + if (completionRate < 50) return "outline"; + if (completionRate < 100) return "light"; + return "filled"; +}; + +const WEEKDAYS = [ + { label: "M", ariaLabel: "Monday" }, + { label: "T", ariaLabel: "Tuesday" }, + { label: "W", ariaLabel: "Wednesday" }, + { label: "T", ariaLabel: "Thursday" }, + { label: "F", ariaLabel: "Friday" }, + { label: "S", ariaLabel: "Saturday" }, + { label: "S", ariaLabel: "Sunday" }, +]; + +interface StatisticsCalendarProps { + currentMonth: Date; + calendarData: StatisticsCalendarResponse; +} + +export const StatisticsCalendar = ({ + currentMonth, + calendarData, +}: StatisticsCalendarProps) => { + const today = new Date(calendarData.today); + const calendarDates = getCalendarDates(currentMonth); + const firstDayOffset = getFirstDayOffset(currentMonth); + const completionRateByDate = new Map( + calendarData.days.map(({ date, completionRate }) => [date, completionRate]), + ); + const todayLabel = formatStatisticsCalendarDate(today); + + return ( ++ {todayLabel} +
+