58 Commits

Author SHA1 Message Date
daf2a4d5f1 Fix snooze/due using container UTC instead of client local time
Docker container datetime.now() returns UTC, but all stored datetimes
are naive local time from the browser. Both /due and /snooze now
accept client_now from the frontend, ensuring snooze computes from
the user's actual current time, not the container's clock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:12:31 +08:00
89b4bd4870 Replace snooze button group with clock icon dropdown
Single clock icon opens a dropdown with 5/10/15 min options instead
of three inline buttons. Shared SnoozeDropdown component used in
both AlertBanner and toast notifications.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:09:17 +08:00
b7251b72c7 Address remaining QA items: index, validation, accessibility, guard
- S1: Add composite index (is_active, is_dismissed, remind_at) for
  /due query performance with multi-user scaling
- W3: Snooze endpoint rejects dismissed/inactive reminders (409)
- W4: Custom field_validator on ReminderSnooze for clear error message
- S2: aria-label on all snooze/dismiss buttons in banner and toasts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 01:02:19 +08:00
5b1b9cc5b7 Fix QA issues: single AlertsProvider, null safety, snooze cleanup
- C1: Replaced duplicate useAlerts() calls with AlertsProvider context
  wrapping AppLayout — single hook instance, no double polling/toasts
- C2: Added null guard on remind_at in Active Reminders card format()
- W2: Clear snoozed_until when dismissing a reminder
- W5: Extracted getRelativeTime to shared lib/date-utils.ts
- S3: Replaced inline SVG with Lucide Bell component in toasts
- S4: Clear snoozed_until when remind_at is updated via PUT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:56:56 +08:00
5080e23256 Add real-time reminder alerts with snooze/dismiss
- Backend: GET /api/reminders/due endpoint, PATCH snooze endpoint,
  snoozed_until column + migration
- Frontend: useAlerts hook polls every 30s, fires Sonner toasts on
  non-dashboard pages (max 3 + summary), renders AlertBanner on
  dashboard below stats row
- Dashboard Active Reminders card filters out items shown in banner

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:15:56 +08:00
5b056cf674 Add calendar redesign frontend with multi-calendar UI
- Custom toolbar replacing FullCalendar defaults (nav, today, view switcher)
- Calendar sidebar with visibility toggles, color dots, add/edit support
- CalendarForm dialog for creating/editing calendars with color swatches
- EventForm updated to use calendar dropdown instead of color picker
- CSS overrides: accent-tinted today highlight, now indicator, rounded event pills
- Types updated for Calendar interface and mixed id types

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:14:06 +08:00
1d21caaa62 Dashboard personalization: preferred name, colored dots, smart briefing
- Add preferred_name column to settings model/schema with migration
- Settings page gets Profile card with name input (saves on blur/enter)
- Dashboard greeting now shows "Good evening, Kyle." when name is set
- WeekTimeline dots use event's actual color when available
- New DayBriefing component shows time-of-day-aware contextual summary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 07:37:43 +08:00
1f6519635f Initial commit 2026-02-15 16:13:41 +08:00