All files / web/src/hooks useAbacusSettings.ts

34.83% Statements 31/89
100% Branches 0/0
0% Functions 0/5
34.83% Lines 31/89

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 901x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x             1x 1x 1x 1x                         1x 1x 1x 1x 1x           1x 1x 1x 1x 1x                                                                        
'use client'
 
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import type { AbacusSettings } from '@/db/schema/abacus-settings'
import { api } from '@/lib/queryClient'
 
/**
 * Query key factory for abacus settings
 */
export const abacusSettingsKeys = {
  all: ['abacus-settings'] as const,
  detail: () => [...abacusSettingsKeys.all, 'detail'] as const,
}
 
/**
 * Fetch abacus display settings
 */
async function fetchAbacusSettings(): Promise<AbacusSettings> {
  const res = await api('abacus-settings')
  if (!res.ok) throw new Error('Failed to fetch abacus settings')
  const data = await res.json()
  return data.settings
}
 
/**
 * Update abacus display settings
 */
async function updateAbacusSettings(
  updates: Partial<Omit<AbacusSettings, 'userId'>>
): Promise<AbacusSettings> {
  const res = await api('abacus-settings', {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(updates),
  })
  if (!res.ok) throw new Error('Failed to update abacus settings')
  const data = await res.json()
  return data.settings
}
 
/**
 * Hook: Fetch abacus display settings
 */
export function useAbacusSettings() {
  return useQuery({
    queryKey: abacusSettingsKeys.detail(),
    queryFn: fetchAbacusSettings,
  })
}
 
/**
 * Hook: Update abacus display settings
 */
export function useUpdateAbacusSettings() {
  const queryClient = useQueryClient()

  return useMutation({
    mutationFn: updateAbacusSettings,
    onMutate: async (updates) => {
      // Cancel outgoing refetches
      await queryClient.cancelQueries({
        queryKey: abacusSettingsKeys.detail(),
      })

      // Snapshot previous value
      const previousSettings = queryClient.getQueryData<AbacusSettings>(abacusSettingsKeys.detail())

      // Optimistically update
      if (previousSettings) {
        const optimisticSettings = { ...previousSettings, ...updates }
        queryClient.setQueryData<AbacusSettings>(abacusSettingsKeys.detail(), optimisticSettings)
      }

      return { previousSettings }
    },
    onError: (_err, _updates, context) => {
      // Rollback on error
      if (context?.previousSettings) {
        queryClient.setQueryData(abacusSettingsKeys.detail(), context.previousSettings)
      }
    },
    onSettled: (updatedSettings) => {
      // Update with server data on success
      if (updatedSettings) {
        queryClient.setQueryData(abacusSettingsKeys.detail(), updatedSettings)
      }
    },
  })
}