import { useState } from 'react'; import { format, isPast, endOfDay } from 'date-fns'; import { useNavigate } from 'react-router-dom'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { CheckCircle2, Check } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { cn } from '@/lib/utils'; import api from '@/lib/api'; interface DashboardTodo { id: number; title: string; due_date: string; priority: string; category?: string; } interface TodoWidgetProps { todos: DashboardTodo[]; } const priorityColors: Record = { low: 'bg-green-500/10 text-green-400 border-green-500/20', medium: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20', high: 'bg-red-500/10 text-red-400 border-red-500/20', }; const dotColors: Record = { high: 'bg-red-400', medium: 'bg-yellow-400', low: 'bg-green-400', }; export default function TodoWidget({ todos }: TodoWidgetProps) { const navigate = useNavigate(); const queryClient = useQueryClient(); const [hoveredId, setHoveredId] = useState(null); const toggleTodo = useMutation({ mutationFn: (id: number) => api.patch(`/todos/${id}/toggle`), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['dashboard'] }); queryClient.invalidateQueries({ queryKey: ['upcoming'] }); toast.success('Todo completed'); }, onError: () => toast.error('Failed to complete todo'), }); const hasOverdue = todos.some((t) => isPast(endOfDay(new Date(t.due_date)))); return (
Upcoming Todos
{todos.length === 0 ? (

Your slate is clean

) : (
{todos.slice(0, 5).map((todo) => { const isOverdue = isPast(endOfDay(new Date(todo.due_date))); const isHovered = hoveredId === todo.id; return (
navigate('/todos', { state: { todoId: todo.id } })} onMouseEnter={() => setHoveredId(todo.id)} onMouseLeave={() => setHoveredId(null)} className="flex items-center gap-2 py-1.5 px-2 rounded-md hover:bg-card-elevated transition-colors duration-150 cursor-pointer" >
{todo.title}
{format(new Date(todo.due_date), 'MMM d')} {isOverdue && ' overdue'} {todo.priority}
{isHovered && (
)}
); })}
)} ); }