124 Commits

Author SHA1 Message Date
7d4089762e Fix upcoming widget row alignment with consistent priority column
The priority badge was conditionally rendered, causing rows without
priority to have fewer flex children and shifting the date/type columns.
Now always renders a fixed-width priority slot (invisible when empty).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:36:35 +08:00
e74d4cf7c6 Align date/time column in upcoming widget
Give the date column a fixed width (7rem) and right-align it so
entries with different date formats (date-only vs datetime) line up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:26:47 +08:00
7c02b4f824 Remove unused label variable in weather location dropdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:20:37 +08:00
4b5649758a Address code review findings for weather coordinates feature
- CRIT-1: Add lat/lon validation ([-90,90] and [-180,180]) in Pydantic schema
- WARN-1: Replace deprecated get_event_loop() with get_running_loop()
- SUG-1: Add GeoSearchResult response model to /search endpoint
- SUG-2: Dashboard weather query enables on coordinates too, not just city
- SUG-3: Clean up debounce timer on component unmount
- SUG-4: Fix geocoding URL from HTTP to HTTPS
- SUG-5: Add fallback display when weather_city is null but coords exist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:17:41 +08:00
1545da48e5 Add coordinate-based weather lookup with location search
Replace plain-text city input with geocoding search that resolves
lat/lon coordinates for accurate OpenWeatherMap queries. Users can
now search, see multiple results with state/country detail, and
select the exact location.

- Add GET /api/weather/search endpoint (OWM Geocoding API)
- Add weather_lat/weather_lon columns to settings model + migration
- Use lat/lon for weather API calls when available, fall back to city name
- Replace settings text input with debounced search + dropdown selector
- Show selected location as chip with clear button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:11:02 +08:00
c2c4446ea6 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 <noreply@anthropic.com>
2026-02-21 11:54:52 +08:00
fa7b50233e Compact stat cards: ~50% shorter, recede as informational strip
- Padding: p-4 → px-3 py-2
- Number: text-3xl → text-xl
- Icons: p-2 h-5 w-5 → p-1.5 h-4 w-4
- Label/number gap: space-y-2 → space-y-0.5
- Weather: description + city inline with temp on one line
- Grid gap tightened from gap-3 to gap-2.5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:48:54 +08:00
bdae07fb7d Compact dashboard: single-line rows, multi-star, weather city
- UpcomingWidget: single-line rows with icon/title/date/type/priority
- CalendarWidget: whitespace-nowrap time ranges, no wrapping
- TodoWidget: compact dot + title + date + badge on one line
- Active Reminders: single-line with dot indicator
- CountdownWidget: supports array of starred events
- StatsWidget: shows city name in weather card
- Dashboard API: returns starred_events array (up to 5) instead of single

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:28:39 +08:00
374e07708f Fix QA review issues: route path, blocking I/O, API key leak, cache
- CRIT-1: Change weather route from /weather to / (was doubling prefix)
- CRIT-2: Use run_in_executor for urllib calls + parallel fetch
- WARN-1: Invalidate weather cache when city changes
- WARN-2: Sanitize error messages to prevent API key leakage
- SUG-2: Only enable weather query when city is configured
- SUG-4: Remove duplicate Bell import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:36:06 +08:00
ca8b654471 Dashboard Phase 2: weather widget, starred events, quick add, thinner events
- Add weather router with OpenWeatherMap integration and 1-hour cache
- Add is_starred column to calendar events with countdown widget
- Add weather_city setting with Settings page input
- Replace people/locations stats with open todos count + weather card
- Add quick-add dropdown (event/todo/reminder) to dashboard header
- Make CalendarWidget events single-line thin rows
- Add rain warnings to smart briefing when chance > 40%
- Invalidate dashboard/upcoming queries on form mutations
- Migration 004: is_starred + weather_city columns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:15:43 +08:00
10546de751 Fix TS error: preferred_name can be null from API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 07:59:23 +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
e9b3c90b0d Remove unused formatISO import from WeekTimeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:40:38 +08:00
d99506c9e4 UI overhaul Stage 1: Dashboard redesign with refined dark luxury aesthetic
- Add Sora + DM Sans Google Fonts with heading/body font system
- New CSS variables for elevated surfaces, transitions, custom scrollbars
- Tailwind config: fade-in/slide-up animations, card-elevated color, font families
- Card component: hover glow, accent border on hover, smooth transitions
- New WeekTimeline component: 7-day horizontal strip with event dot indicators
- Dashboard: contextual time-of-day greeting, week timeline, redesigned 5-col layout
- Stats widget: accent-tinted gradients, icon glow backgrounds, uppercase labels
- Upcoming widget: colored left-border type indicators, unified timeline feed
- Calendar/Todo widgets: refined spacing, hover states, colored accent bars
- Sidebar: accent bar active state (border-l-2), backdrop-blur mobile overlay

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:35:01 +08:00
c5adc316ef resolved event create bug 2026-02-19 20:44:14 +08:00
d5080f59af fixed day view visual bug 2026-02-19 20:38:11 +08:00
a352a50b63 resolved click & drag bug 2026-02-19 20:24:41 +08:00
27c65ce40d Fix Round 2 code review findings: type safety, security, and correctness
Backend:
- Add Literal types for status/priority fields (project_task, todo, project schemas)
- Add AccentColor Literal validation to prevent CSS injection (settings schema)
- Add PIN max-length (72 char bcrypt limit) validation
- Fix event date filtering to use correct range overlap logic
- Add revocation check to auth_status endpoint for consistency
- Config: env-aware SECRET_KEY fail-fast, configurable COOKIE_SECURE

Frontend:
- Add withCredentials to axios for cross-origin cookie support
- Replace .toISOString() with local date formatter in DashboardPage
- Replace `as any` casts with proper indexed type access in forms
- Nginx: add CSP, Referrer-Policy headers; remove deprecated X-XSS-Protection
- Nginx: duplicate security headers in static asset location block

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 15:18:49 +08:00
1aaa2b3a74 Fix code review findings: security hardening and frontend fixes
Backend:
- Add rate limiting to login (5 attempts / 5 min window)
- Add secure flag to session cookies with helper function
- Add PIN min-length validation via Pydantic field_validator
- Fix naive datetime usage in todos.py (datetime.now() not UTC)
- Disable SQLAlchemy echo in production
- Remove auto-commit from get_db to prevent double commits
- Add lower bound filter to upcoming events query
- Add SECRET_KEY default warning on startup
- Remove create_all from lifespan (Alembic handles migrations)

Frontend:
- Fix ReminderForm remind_at slice for datetime-local input
- Add window.confirm() dialogs on all destructive actions
- Redirect authenticated users away from login screen
- Replace error: any with getErrorMessage helper in LockScreen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 07:49:21 +08:00
ccfbf6df96 Add subtasks feature to project tasks
Backend:
- Add self-referencing parent_task_id FK on project_tasks with CASCADE delete
- Add Alembic migration 002 for parent_task_id column + index
- Update schemas with parent_task_id in create, nested subtasks in response
- Chain selectinload for subtasks on all project queries
- Validate parent must be top-level task (single nesting level only)

Frontend:
- Add parent_task_id and subtasks[] to ProjectTask type
- ProjectDetail: expand/collapse chevrons, subtask progress bars, inline
  subtask rendering with accent left border, add/edit/delete subtask buttons
- TaskForm: accept parentTaskId prop, include in create payload, context-aware
  dialog title (New Task vs New Subtask)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 01:31:46 +08:00
a1b2067faa Fix Sonner toaster blocking button clicks on login screen
Sonner's toaster container has z-index: 999999999 with no pointer-events: none,
creating an invisible overlay that intercepts clicks. Set pointer-events: none on
the container and pointer-events: auto on individual toasts so buttons underneath
remain clickable while toasts stay interactive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 20:58:30 +08:00
cea1c36d92 Fix logout, category filter, dialog width, and mark all tests complete
- Add logout button to sidebar with destructive hover styling
- Fix case-sensitive todo category filter with .toLowerCase()
- Widen dialog popups from max-w-lg to max-w-xl with mobile margin
- Update CLAUDE.md with commit-and-push instruction
- Update progress.md: all CRUD tests verified, all outstanding items resolved

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 20:46:18 +08:00
e6387065ad updated name from lifemanager to umbra, 2026-02-15 20:21:55 +08:00
1f6519635f Initial commit 2026-02-15 16:13:41 +08:00