1- import { useMutation , useQueryClient } from '@tanstack/ react-query '
1+ import { useCallback , useState } from 'react'
22
3+ import {
4+ getActivityQueryData ,
5+ invalidateActivityQuery ,
6+ setActivityQueryData ,
7+ } from './use-activity-query'
38import { subscriptionQueryKeys } from './use-subscription-query'
49import { getApiClient } from '../utils/codebuff-api'
510import { logger } from '../utils/logger'
@@ -11,51 +16,49 @@ interface UpdatePreferenceParams {
1116}
1217
1318export function useUpdatePreference ( ) {
14- const queryClient = useQueryClient ( )
19+ const [ isPending , setIsPending ] = useState ( false )
1520
16- return useMutation ( {
17- mutationFn : async ( params : UpdatePreferenceParams ) => {
18- const client = getApiClient ( )
19- const response = await client . patch ( '/api/user/preferences' , {
20- body : params ,
21- includeCookie : true ,
22- } )
21+ const mutate = useCallback ( async ( params : UpdatePreferenceParams ) => {
22+ const queryKey = subscriptionQueryKeys . current ( )
2323
24- if ( ! response . ok ) {
25- throw new Error ( 'Failed to update preference' )
26- }
24+ // Snapshot the previous value for rollback
25+ const previousData = getActivityQueryData < SubscriptionResponse > ( queryKey )
2726
28- return params
29- } ,
30- onMutate : async ( newParams ) => {
31- // Cancel any outgoing refetches
32- await queryClient . cancelQueries ( { queryKey : subscriptionQueryKeys . current ( ) } )
27+ // Optimistically update to the new value
28+ if ( previousData && params . fallbackToALaCarte !== undefined ) {
29+ setActivityQueryData < SubscriptionResponse > ( queryKey , {
30+ ...previousData ,
31+ fallbackToALaCarte : params . fallbackToALaCarte ,
32+ } )
33+ }
3334
34- // Snapshot the previous value
35- const previousData = queryClient . getQueryData < SubscriptionResponse > (
36- subscriptionQueryKeys . current ( )
35+ setIsPending ( true )
36+
37+ try {
38+ const client = getApiClient ( )
39+ const response = await client . patch < { success : boolean ; error ?: string } > (
40+ '/api/user/preferences' ,
41+ params as Record < string , unknown > ,
42+ { includeCookie : true } ,
3743 )
3844
39- // Optimistically update to the new value
40- if ( previousData && newParams . fallbackToALaCarte !== undefined ) {
41- queryClient . setQueryData < SubscriptionResponse > (
42- subscriptionQueryKeys . current ( ) ,
43- { ...previousData , fallbackToALaCarte : newParams . fallbackToALaCarte }
44- )
45+ if ( ! response . ok ) {
46+ const errorMessage = response . error || 'Failed to update preference'
47+ throw new Error ( errorMessage )
4548 }
4649
47- return { previousData }
48- } ,
49- onError : ( err , _newParams , context ) => {
50+ // Invalidate to refetch fresh data from server
51+ invalidateActivityQuery ( queryKey )
52+ } catch ( err ) {
5053 // Rollback to previous value on error
51- if ( context ?. previousData ) {
52- queryClient . setQueryData ( subscriptionQueryKeys . current ( ) , context . previousData )
54+ if ( previousData ) {
55+ setActivityQueryData ( queryKey , previousData )
5356 }
5457 logger . error ( { err } , 'Failed to update preference' )
55- } ,
56- onSettled : ( ) => {
57- // Refetch after mutation
58- queryClient . invalidateQueries ( { queryKey : subscriptionQueryKeys . current ( ) } )
59- } ,
60- } )
58+ } finally {
59+ setIsPending ( false )
60+ }
61+ } , [ ] )
62+
63+ return { mutate , isPending }
6164}
0 commit comments