import { Habit } from '@/lib/types' import { useAtom } from 'jotai' import { settingsAtom, pomodoroAtom, browserSettingsAtom } from '@/lib/atoms' import { getTodayInTimezone, isSameDate, t2d, d2t, getNow, parseNaturalLanguageRRule, parseRRule, d2s } from '@/lib/utils' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Coins, Edit, Trash2, Check, Undo2, MoreVertical, Timer, Archive, ArchiveRestore } from 'lucide-react' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { useEffect, useState } from 'react' import { useHabits } from '@/hooks/useHabits' import { INITIAL_RECURRENCE_RULE } from '@/lib/constants' import { DateTime } from 'luxon' interface HabitItemProps { habit: Habit onEdit: () => void onDelete: () => void } export default function HabitItem({ habit, onEdit, onDelete }: HabitItemProps) { const { completeHabit, undoComplete, archiveHabit, unarchiveHabit } = useHabits() const [settings] = useAtom(settingsAtom) const [_, setPomo] = useAtom(pomodoroAtom) const completionsToday = habit.completions?.filter(completion => isSameDate(t2d({ timestamp: completion, timezone: settings.system.timezone }), t2d({ timestamp: d2t({ dateTime: getNow({ timezone: settings.system.timezone }) }), timezone: settings.system.timezone })) ).length || 0 const target = habit.targetCompletions || 1 const isCompletedToday = completionsToday >= target const [isHighlighted, setIsHighlighted] = useState(false) const [browserSettings] = useAtom(browserSettingsAtom) const isTasksView = browserSettings.viewType === 'tasks' const isRecurRule = !isTasksView useEffect(() => { const params = new URLSearchParams(window.location.search) const highlightId = params.get('highlight') if (highlightId === habit.id) { setIsHighlighted(true) // Scroll the element into view after a short delay to ensure rendering setTimeout(() => { const element = document.getElementById(`habit-${habit.id}`) if (element) { element.scrollIntoView({ behavior: 'smooth', block: 'center' }) } }, 100) // Remove highlight after animation const timer = setTimeout(() => setIsHighlighted(false), 2000) return () => clearTimeout(timer) } }, [habit.id]) return ( {habit.name} {habit.description && ( {habit.description} )}

When: {isRecurRule ? parseRRule(habit.frequency || INITIAL_RECURRENCE_RULE).toText() : d2s({ dateTime: t2d({ timestamp: habit.frequency, timezone: settings.system.timezone }), timezone: settings.system.timezone, format: DateTime.DATE_MED_WITH_WEEKDAY })}

{habit.coinReward} coins per completion
{completionsToday > 0 && !habit.archived && ( )}
{!habit.archived && ( )} {!habit.archived && ( { setPomo((prev) => ({ ...prev, show: true, selectedHabitId: habit.id })) }}> Start Pomodoro )} {!habit.archived && ( archiveHabit(habit.id)}> Archive )} {habit.archived && ( unarchiveHabit(habit.id)}> Unarchive )} Edit Delete
) }