import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '@/components/ui/dropdown-menu' import { useHabits } from '@/hooks/useHabits' import { browserSettingsAtom, settingsAtom, usersAtom } from '@/lib/atoms' import { useHelpers } from '@/lib/client-helpers' import { Habit, User } from '@/lib/types' import { convertMachineReadableFrequencyToHumanReadable, getCompletionsForToday, isTaskOverdue } from '@/lib/utils' import { useAtom } from 'jotai' import { Check, Coins, Edit, MoreVertical, Pin, Undo2 } from 'lucide-react'; // Removed unused icons import { useEffect, useState } from 'react' import { HabitContextMenuItems } from './HabitContextMenuItems' import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar' interface HabitItemProps { habit: Habit onEdit: () => void onDelete: () => void } const renderUserAvatars = (habit: Habit, currentUser: User | null, usersData: { users: User[] }) => { if (!habit.userIds || habit.userIds.length <= 1) return null; return (
{habit.userIds?.filter((u) => u !== currentUser?.id).map(userId => { const user = usersData.users.find(u => u.id === userId) if (!user) return null return ( {user.username[0]} ) })}
); }; export default function HabitItem({ habit, onEdit, onDelete }: HabitItemProps) { const { completeHabit, undoComplete, archiveHabit, unarchiveHabit, saveHabit } = useHabits() const [settings] = useAtom(settingsAtom) const completionsToday = getCompletionsForToday({ habit, timezone: settings.system.timezone }) const target = habit.targetCompletions || 1 const isCompletedToday = completionsToday >= target const [isHighlighted, setIsHighlighted] = useState(false) const [usersData] = useAtom(usersAtom) const { currentUser, hasPermission } = useHelpers() const canWrite = hasPermission('habit', 'write') const canInteract = hasPermission('habit', 'interact') 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.pinned && ( )} {habit.name}
{isTaskOverdue(habit, settings.system.timezone) && ( Overdue )}
{renderUserAvatars(habit, currentUser as User, usersData)}
{habit.description && ( {habit.description} )}

When: {convertMachineReadableFrequencyToHumanReadable({ frequency: habit.frequency, isRecurRule, timezone: settings.system.timezone })}

{habit.coinReward} coins per completion
{completionsToday > 0 && !habit.archived && ( )}
{!habit.archived && ( )}
) }