* feat(companion): add optimistic updates to EditAvailabilityNameScreen
- Refactor useUpdateSchedule hook with optimistic updates
- Update EditAvailabilityNameScreen to use mutation hook instead of direct API call
- Update EditAvailabilityNameScreen.ios.tsx with same pattern
- Cache is updated immediately on save, then synced with server
- On error, cache is rolled back to previous state
* fix(companion): fix cache update for schedule list when detail cache is empty
- Update list cache in onMutate even when detail cache doesn't exist
- Remove onSettled invalidation that was causing issues with staleTime: Infinity
- Add fallback invalidation in onSuccess when list cache doesn't exist
* fix(companion): fix AvailabilityDetailScreen not reflecting cache updates
The previous optimistic updates implementation in EditAvailabilityNameScreen
correctly updated the React Query cache, but AvailabilityDetailScreen was
still using direct CalComAPIService.getScheduleById() calls with local
useState, completely bypassing the cache.
The disconnect:
- EditAvailabilityNameScreen → useUpdateSchedule → Updates React Query Cache ✓
- AvailabilityDetailScreen → CalComAPIService.getScheduleById → Local state ✗
This meant when a user saved changes to a schedule's name/timezone, the
cache was updated but the detail screen (and subsequently the list screen)
never saw those updates because they weren't reading from the cache.
Changes:
- Refactor AvailabilityDetailScreen.tsx to use useScheduleById hook
- Refactor AvailabilityDetailScreen.ios.tsx to use useScheduleById hook
- Replace direct API calls with React Query for cache synchronization
- Add RefreshControl for pull-to-refresh support
- Use mutation hooks (useSetScheduleAsDefault, useDeleteSchedule) for actions
- Derive availability/overrides data using useMemo from query result
Now when EditAvailabilityNameScreen updates the cache, AvailabilityDetailScreen
automatically reflects those changes because both read from the same cache.
* feat(companion): refactor EditAvailabilityOverrideScreen to use mutation hook
- Replace direct CalComAPIService.updateSchedule calls with useUpdateSchedule hook
- Remove local isSaving state, use isPending from mutation hook instead
- Cache is now updated automatically via the mutation hook's optimistic updates
- Consistent pattern with EditAvailabilityNameScreen refactoring
* feat(companion): refactor EditAvailabilityDayScreen to use mutation hook
- Replace direct CalComAPIService.updateSchedule calls with useUpdateSchedule hook
- Remove local isSaving state, use isPending from mutation hook instead
- Cache is now updated automatically via the mutation hook's optimistic updates
- Consistent pattern with EditAvailabilityNameScreen and EditAvailabilityOverrideScreen
* fix(companion): refactor edit-availability-hours routes to use useScheduleById hook
The working hours page (page 2 in the flow) was showing stale data because
it used direct CalComAPIService.getScheduleById() calls with local useState,
bypassing the React Query cache.
The disconnect:
- EditAvailabilityDayScreen → useUpdateSchedule → Updates React Query Cache ✓
- edit-availability-hours route → CalComAPIService.getScheduleById → Local state ✗
This meant when a user saved changes to a day's availability, the cache was
updated but the working hours page never saw those updates because it wasn't
reading from the cache.
Changes:
- Refactor edit-availability-hours.tsx to use useScheduleById hook
- Refactor edit-availability-hours.ios.tsx to use useScheduleById hook
- Replace direct API calls with React Query for cache synchronization
- Now all 3 pages in the flow read from the same cache
* fix(companion): make Date Overrides section clickable when empty
Previously, when there were no date overrides, the Date Overrides section
was just a plain View without any press handler, making it impossible for
users to navigate to the edit override page to add new overrides.
This follows the same pattern as other sections (Weekly Schedule, Timezone)
which are always clickable regardless of their content state.
Changes:
- Wrap the 'No Overrides' section in AppPressable with navigation handler
- Add chevron-forward icon to indicate it's tappable
- Apply fix to both AvailabilityDetailScreen.tsx and .ios.tsx
* fix(companion): use useEffect instead of useMemo for side effects
- Change useMemo to useEffect for onActionsReady callback (side effect)
- Move error handling (showErrorAlert, router.back) to useEffect
- Keep early return for error state after useEffect hooks
Fixes Cubic AI review feedback (confidence 9/10)
* feat(companion): add optimistic updates to EventTypeDetail screen
- Enhance useUpdateEventType hook with full optimistic update support
- Add onMutate callback to update cache immediately
- Add onSuccess callback to sync with server response
- Add onError callback to rollback on failure
- Update both eventTypes.detail(id) and eventTypes.lists() caches
- Refactor handleSave in event-type-detail.tsx
- Replace direct CalComAPIService.updateEventType() with useUpdateEventType hook
- Replace direct CalComAPIService.createEventType() with useCreateEventType hook
- Remove manual fetchEventTypeData() call after save (cache updates automatically)
- Replace local saving state with mutation hooks' isPending states
- Refactor handleDelete in event-type-detail.tsx
- Replace direct CalComAPIService.deleteEventType() with useDeleteEventType hook
This ensures the event types list updates immediately after save/delete
without requiring manual refresh.