From c2c4446ea6181ea2f1ea9393fc953a4b8dbfab91 Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Sat, 21 Feb 2026 11:54:52 +0800 Subject: [PATCH] Fix upcoming widget showing past items (yesterday's events, overdue todos) - Add lower-bound date filter (>= today) for todos and reminders in /upcoming endpoint - Accept client_date param for timezone-correct filtering - Pass client_date from frontend to /upcoming API call Co-Authored-By: Claude Opus 4.6 --- backend/app/routers/dashboard.py | 11 +++++++---- frontend/src/components/dashboard/DashboardPage.tsx | 4 +++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/backend/app/routers/dashboard.py b/backend/app/routers/dashboard.py index 10470b9..937dd82 100644 --- a/backend/app/routers/dashboard.py +++ b/backend/app/routers/dashboard.py @@ -130,25 +130,27 @@ async def get_dashboard( @router.get("/upcoming") async def get_upcoming( days: int = Query(default=7, ge=1, le=90), + client_date: Optional[date] = Query(None), db: AsyncSession = Depends(get_db), current_user: Settings = Depends(get_current_session) ): """Get unified list of upcoming items (todos, events, reminders) sorted by date.""" - today = date.today() + today = client_date or date.today() cutoff_date = today + timedelta(days=days) cutoff_datetime = datetime.combine(cutoff_date, datetime.max.time()) + today_start = datetime.combine(today, datetime.min.time()) - # Get upcoming todos with due dates + # Get upcoming todos with due dates (today onward only) todos_query = select(Todo).where( Todo.completed == False, Todo.due_date.isnot(None), + Todo.due_date >= today, Todo.due_date <= cutoff_date ) todos_result = await db.execute(todos_query) todos = todos_result.scalars().all() # Get upcoming events (from today onward) - today_start = datetime.combine(today, datetime.min.time()) events_query = select(CalendarEvent).where( CalendarEvent.start_datetime >= today_start, CalendarEvent.start_datetime <= cutoff_datetime, @@ -156,10 +158,11 @@ async def get_upcoming( events_result = await db.execute(events_query) events = events_result.scalars().all() - # Get upcoming reminders + # Get upcoming reminders (today onward only) reminders_query = select(Reminder).where( Reminder.is_active == True, Reminder.is_dismissed == False, + Reminder.remind_at >= today_start, Reminder.remind_at <= cutoff_datetime ) reminders_result = await db.execute(reminders_query) diff --git a/frontend/src/components/dashboard/DashboardPage.tsx b/frontend/src/components/dashboard/DashboardPage.tsx index c38eda3..05e378f 100644 --- a/frontend/src/components/dashboard/DashboardPage.tsx +++ b/frontend/src/components/dashboard/DashboardPage.tsx @@ -59,7 +59,9 @@ export default function DashboardPage() { queryKey: ['upcoming', settings?.upcoming_days], queryFn: async () => { const days = settings?.upcoming_days || 7; - const { data } = await api.get(`/upcoming?days=${days}`); + const now = new Date(); + const clientDate = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`; + const { data } = await api.get(`/upcoming?days=${days}&client_date=${clientDate}`); return data; }, });