import { useState, useMemo } from 'react'; import { Plus, CheckSquare, CheckCircle2, AlertCircle, Search, ChevronDown } from 'lucide-react'; import { useQuery } from '@tanstack/react-query'; import api from '@/lib/api'; import type { Todo } from '@/types'; import { isTodoOverdue } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent } from '@/components/ui/card'; import { Checkbox } from '@/components/ui/checkbox'; import { Label } from '@/components/ui/label'; import { ListSkeleton } from '@/components/ui/skeleton'; import TodoList from './TodoList'; import TodoForm from './TodoForm'; const priorityFilters = [ { value: '', label: 'All' }, { value: 'none', label: 'None' }, { value: 'low', label: 'Low' }, { value: 'medium', label: 'Medium' }, { value: 'high', label: 'High' }, ] as const; export default function TodosPage() { const [showForm, setShowForm] = useState(false); const [editingTodo, setEditingTodo] = useState(null); const [filters, setFilters] = useState({ priority: '', category: '', showCompleted: true, search: '', }); const { data: todos = [], isLoading } = useQuery({ queryKey: ['todos'], queryFn: async () => { const { data } = await api.get('/todos'); return data; }, }); const categories = useMemo(() => { const cats = new Set(); todos.forEach((t) => { if (t.category) cats.add(t.category); }); return Array.from(cats).sort(); }, [todos]); const filteredTodos = useMemo( () => todos.filter((todo) => { if (filters.priority && todo.priority !== filters.priority) return false; if (filters.category && todo.category?.toLowerCase() !== filters.category.toLowerCase()) return false; if (!filters.showCompleted && todo.completed) return false; if (filters.search && !todo.title.toLowerCase().includes(filters.search.toLowerCase())) return false; return true; }), [todos, filters] ); const totalCount = filteredTodos.filter((t) => !t.completed).length; const completedCount = filteredTodos.filter((t) => t.completed).length; const overdueCount = filteredTodos.filter((t) => isTodoOverdue(t.due_date, t.completed)).length; const handleEdit = (todo: Todo) => { setEditingTodo(todo); setShowForm(true); }; const handleCloseForm = () => { setShowForm(false); setEditingTodo(null); }; return (
{/* Header */}

Todos

{priorityFilters.map((pf) => ( ))}
setFilters({ ...filters, search: e.target.value })} className="w-52 h-8 pl-8 text-sm" />
setFilters({ ...filters, showCompleted: (e.target as HTMLInputElement).checked }) } />
{/* Summary stats */} {!isLoading && todos.length > 0 && (

Open

{totalCount}

Completed

{completedCount}

Overdue

{overdueCount}

)} {isLoading ? ( ) : ( setShowForm(true)} /> )}
{showForm && }
); }