Skip to content

[FE-06] Implement optimistic updates with rollback for all admin CRUD mutations #274

Description

@Leothosine

Problem

MenuClient.tsx, GalleryClient.tsx, and ContactsClient.tsx all call queryClient.invalidateQueries() in mutation onSuccess handlers. This triggers a full server refetch on every toggle, delete, and status change. The user sees the whole table flash and reload. There is no rollback if a mutation fails.

Proposed Solution

  1. Add onMutate callbacks that call queryClient.setQueryData() to immediately apply the expected change to the cache
  2. Store the previous cache snapshot in onMutate context
  3. In onError, call queryClient.setQueryData(previousSnapshot) to revert the change
  4. Show per-row loading spinners (not table-level skeletons) during pending mutations using isPending and the item's id
  5. Show a toast on mutation error with the server's error message

Acceptance Criteria

  • Toggling a menu item's active state updates the UI instantly - no table refetch or flicker
  • If the API call fails, the toggle reverts automatically and a toast shows the error
  • Deleting a gallery image removes it from the list immediately and restores it on failure
  • Updating a contact status changes the badge instantly
  • Per-row spinner appears only on the affected row, not the whole table

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions