10 Commits

Author SHA1 Message Date
b401fd9392 Phase 6: Real-time sync, drag-drop guards, security fix, invite bug fix, UI polish
- Event polling (5s refetchInterval) so collaborators see changes without refresh
- Lock status polling in EventDetailPanel view mode — proactive lock banner
- Per-event editable flag blocks drag on read-only shared events
- Read-only permission guard in handleEventDrop/handleEventResize
- M-01 security fix: block non-owners from moving events off shared calendars (403)
- Fix invite response type (backend returns list, not wrapper object)
- Remove is_shared from CalendarCreate/CalendarUpdate input schemas
- New PermissionToggle segmented control (Eye/Pencil/Shield icons)
- CalendarMemberRow restructured into spacious two-line card layout
- CalendarForm dialog widened (sm:max-w-2xl), polished invite card with accent border
- SharedCalendarSettings dialog widened (sm:max-w-lg)
- CalendarMemberList max-height increased (max-h-48 → max-h-72)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 16:46:15 +08:00
f45b7a2115 Fix 4 reported bugs from Phase 4 testing
1. Invite auto-sends at read_only: now stages connection with permission
   selector (Read Only / Create Modify / Full Access) before sending
2. Shared calendars missing from event create dropdown: members with
   create_modify+ permission now see shared calendars in calendar picker
3. Shared calendar category not showing for owner: owner's shared calendars
   now appear under SHARED CALENDARS section with "Owner" badge
4. Event creation not updating calendar: handlePanelClose now invalidates
   calendar-events query to ensure FullCalendar refreshes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 06:23:45 +08:00
e5690625eb Fix member removal bug + QA fixes + shared calendar sidebar styling
Bug fix:
- CalendarMemberRow: add type="button" to remove button (was submitting parent form)

QA fixes:
- EventDetailPanel: use axios.isAxiosError() instead of duck-typing for lock errors
- EventDetailPanel: only call onSaved on create (edits return to view mode, not close)
- CalendarForm: remove 4 redundant membersQuery.refetch() calls (mutations already invalidate)
- useEventLock: remove unused lockHeld ref from return, fix stale eventId in onSuccess
- EventLockBanner: guard against invalid date parse

UI:
- SharedCalendarSection: add purple Ghost icon next to "SHARED CALENDARS" header

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 06:07:55 +08:00
eedfaaf859 Phase 4: Event locking + permission gating for shared calendars
- useEventLock hook with auto-release on unmount/event change
- EventLockBanner component for locked event display
- EventDetailPanel: lock acquire on edit, release on save/cancel, permission-gated edit/delete buttons
- CalendarPage: permission map from owned+shared calendars, per-event editable gating

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 05:24:43 +08:00
6cd648f3a8 Replace native date/time inputs with DatePicker across calendar and todo forms
- EventForm + EventDetailPanel: native <Input type=date|datetime-local> → DatePicker with dynamic mode via all_day toggle
- TodoForm + TodoDetailPanel: merge date + time into single datetime DatePicker, remove separate time input, move recurrence select into 2-col grid beside date picker

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 16:43:14 +08:00
a128005ae5 Fix create-mode crash in detail panels (null entity access)
The desktop detail panels are pre-mounted (always in DOM, hidden with w-0).
useState(isCreating) only captures the initial value on mount (false), so
when isCreating later becomes true via props, isEditing stays false. The
view-mode branch then runs with a null entity, crashing on property access.

Fix: use (isEditing || isCreating) for all conditionals that gate between
edit/create form and view mode, ensuring the form always renders when
isCreating is true regardless of isEditing state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 09:57:19 +08:00
f07ce02576 Fix crash when creating new todo/reminder/event (null.priority)
All three DetailPanel components initialized isEditing=false even
when isCreating=true. The useEffect that flips it to true runs AFTER
the first render, so the view-mode branch executes with todo=null,
crashing on null.priority. Initialize isEditing from isCreating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 08:35:31 +08:00
87a7a4ae32 Reformat detail panel view modes to 2-column grid layout
Match TaskDetailPanel gold standard: short fields use grid grid-cols-2
with icon+label headers, full-width fields (description) below the grid.
All grid slots render with "—" fallback to keep alignment consistent.

- Todo: Priority, Category, Due Date, Recurrence in grid
- Reminder: Status, Recurrence, Remind At, Snoozed Until in grid
- Calendar: Calendar, Starred, Start, End, Location, Recurrence in grid
- Task: Add "Updated X ago" footer (was missing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:52:15 +08:00
8945295e2a Replace Sheet overlays with inline detail panels across all pages
- Calendar: move view selector left, inline EventDetailPanel with view/edit/create
  modes, fix resize on panel close, remove all Sheet/Dialog usage
- Todos: add TodoDetailPanel with inline view/edit/create, replace CategoryFilterBar
  with shared component (drag-and-drop categories), 55/45 split layout
- Reminders: add ReminderDetailPanel with inline view/edit/create, 55/45 split layout
- Dashboard: all widget items now deep-link to destination page AND open the
  relevant item's detail panel (events, todos, reminders)
- Fix TS errors: unused imports, undefined→null coalescing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:43:06 +08:00
898ecc407a Stage 7: final polish — transitions, navigation, calendar panel
- Add animate-fade-in page transitions to all pages
- Persist sidebar collapsed state in localStorage
- Add two-click logout confirmation using useConfirmAction
- Restructure Todos header: replace <select> with pill filters, move search right
- Move Reminders search right-aligned with spacer
- Add event search dropdown + Create Event button to Calendar toolbar
- Add search input to Projects header with name/description filtering
- Fix CategoryFilterBar search focus ring clipping with ring-inset
- Create EventDetailPanel: read-only event view with copyable fields,
  recurrence display, edit/delete actions, location name resolution
- Refactor CalendarPage to 55/45 split-panel layout matching People/Locations
- Add mobile overlay panel for calendar event details
- Add navigation state handler for CalendarPage (date/view from dashboard)
- Add navigation state handler for ProjectsPage (status filter from dashboard)
- Make all dashboard widgets navigable: stat cards → pages, week timeline
  days → calendar day view, upcoming items → source pages, countdown items
  → calendar, today's events/todos/reminders → respective pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:08:08 +08:00