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
- Add
onMutate callbacks that call queryClient.setQueryData() to immediately apply the expected change to the cache
- Store the previous cache snapshot in
onMutate context
- In
onError, call queryClient.setQueryData(previousSnapshot) to revert the change
- Show per-row loading spinners (not table-level skeletons) during pending mutations using
isPending and the item's id
- Show a toast on mutation error with the server's error message
Acceptance Criteria
Problem
MenuClient.tsx,GalleryClient.tsx, andContactsClient.tsxall callqueryClient.invalidateQueries()in mutationonSuccesshandlers. 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
onMutatecallbacks that callqueryClient.setQueryData()to immediately apply the expected change to the cacheonMutatecontextonError, callqueryClient.setQueryData(previousSnapshot)to revert the changeisPendingand the item'sidAcceptance Criteria