'use client' import { useState, useMemo, useCallback } from 'react' import { Calendar } from '@/components/ui/calendar' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import CompletionCountBadge from '@/components/CompletionCountBadge' import { Button } from '@/components/ui/button' import { Check, Circle, CircleCheck } from 'lucide-react' import { d2s, getNow, t2d, getCompletedHabitsForDate, isHabitDue, getISODate, getCompletionsForToday, getCompletionsForDate } from '@/lib/utils' import { useAtom } from 'jotai' import { useHabits } from '@/hooks/useHabits' import { habitsAtom, settingsAtom, completedHabitsMapAtom, hasTasksAtom } from '@/lib/atoms' import { DateTime } from 'luxon' import Linkify from './linkify' import { Habit } from '@/lib/types' export default function HabitCalendar() { const { completePastHabit } = useHabits() const handleCompletePastHabit = useCallback(async (habit: Habit, date: DateTime) => { try { await completePastHabit(habit, date) } catch (error) { console.error('Error completing past habit:', error) } }, [completePastHabit]) const [settings] = useAtom(settingsAtom) const [selectedDateTime, setSelectedDateTime] = useState(getNow({ timezone: settings.system.timezone })) const selectedDate = selectedDateTime.toFormat("yyyy-MM-dd") const [habitsData] = useAtom(habitsAtom) const [hasTasks] = useAtom(hasTasksAtom) const habits = habitsData.habits const [completedHabitsMap] = useAtom(completedHabitsMapAtom) // Get completed dates for calendar modifiers const completedDates = useMemo(() => { return new Set(Array.from(completedHabitsMap.keys()).map(date => getISODate({ dateTime: DateTime.fromISO(date), timezone: settings.system.timezone }) )) }, [completedHabitsMap, settings.system.timezone]) return (

Habit Calendar

Calendar e && setSelectedDateTime(DateTime.fromJSDate(e))} weekStartsOn={settings.system.weekStartDay} className="rounded-md border" modifiers={{ completed: (date) => completedDates.has( getISODate({ dateTime: DateTime.fromJSDate(date), timezone: settings.system.timezone })! ) }} modifiersClassNames={{ completed: 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300 font-medium rounded-md', }} /> {selectedDateTime ? ( <>{d2s({ dateTime: selectedDateTime, timezone: settings.system.timezone, format: DateTime.DATE_MED_WITH_WEEKDAY })} ) : ( 'Select a date' )} {selectedDateTime && (
{hasTasks && (

Tasks

    {habits .filter(habit => habit.isTask && isHabitDue({ habit, timezone: settings.system.timezone, date: selectedDateTime })) .map((habit) => { const completions = getCompletionsForDate({ habit, date: selectedDateTime, timezone: settings.system.timezone }) const isCompleted = completions >= (habit.targetCompletions || 1) return (
  • {habit.name}
    {habit.targetCompletions && ( {completions}/{habit.targetCompletions} )}
  • ) })}
)}

Habits

    {habits .filter(habit => !habit.isTask && isHabitDue({ habit, timezone: settings.system.timezone, date: selectedDateTime })) .map((habit) => { const completions = getCompletionsForDate({ habit, date: selectedDateTime, timezone: settings.system.timezone }) const isCompleted = completions >= (habit.targetCompletions || 1) return (
  • {habit.name}
    {habit.targetCompletions && ( {completions}/{habit.targetCompletions} )}
  • ) })}
)}
) }