All files / web/src/hooks usePlayerSessionPreferences.ts

100% Statements 81/81
93.75% Branches 15/16
100% Functions 9/9
100% Lines 81/81

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 821x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 3x 3x 3x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 3x 3x 3x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 1x 1x 1x 1x 1x 8x 8x 8x 8x 4x 8x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 8x 1x 1x 1x 1x 8x 4x 3x 3x 4x 8x 8x  
'use client'
 
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import type { PlayerSessionPreferencesConfig } from '@/db/schema/player-session-preferences'
import { api } from '@/lib/queryClient'
import { sessionPreferencesKeys } from '@/lib/queryKeys'
 
interface SessionPreferencesResponse {
  preferences: PlayerSessionPreferencesConfig | null
}
 
async function fetchSessionPreferences(
  playerId: string
): Promise<PlayerSessionPreferencesConfig | null> {
  const res = await api(`curriculum/${playerId}/session-preferences`)
  if (!res.ok) throw new Error('Failed to fetch session preferences')
  const data: SessionPreferencesResponse = await res.json()
  return data.preferences
}
 
async function saveSessionPreferences(
  playerId: string,
  preferences: PlayerSessionPreferencesConfig
): Promise<PlayerSessionPreferencesConfig> {
  const res = await api(`curriculum/${playerId}/session-preferences`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ preferences }),
  })
  if (!res.ok) throw new Error('Failed to save session preferences')
  const data: SessionPreferencesResponse = await res.json()
  return data.preferences!
}
 
/**
 * Hook: Fetch persisted session preferences for a student
 */
export function usePlayerSessionPreferences(playerId: string | null) {
  return useQuery({
    queryKey: sessionPreferencesKeys.detail(playerId ?? 'anonymous'),
    queryFn: () => fetchSessionPreferences(playerId as string),
    enabled: Boolean(playerId),
    // Preferences don't change often — keep stale longer
    staleTime: 1000 * 60 * 30,
  })
}
 
/**
 * Hook: Save session preferences with optimistic update
 */
export function useSavePlayerSessionPreferences(playerId: string) {
  const queryClient = useQueryClient()
 
  return useMutation({
    mutationFn: (preferences: PlayerSessionPreferencesConfig) =>
      saveSessionPreferences(playerId, preferences),
    onMutate: async (preferences) => {
      await queryClient.cancelQueries({
        queryKey: sessionPreferencesKeys.detail(playerId),
      })
 
      const previous = queryClient.getQueryData<PlayerSessionPreferencesConfig | null>(
        sessionPreferencesKeys.detail(playerId)
      )
 
      queryClient.setQueryData(sessionPreferencesKeys.detail(playerId), preferences)
 
      return { previous }
    },
    onError: (_err, _prefs, context) => {
      if (context?.previous !== undefined) {
        queryClient.setQueryData(sessionPreferencesKeys.detail(playerId), context.previous)
      }
    },
    onSettled: (savedPreferences) => {
      if (savedPreferences) {
        queryClient.setQueryData(sessionPreferencesKeys.detail(playerId), savedPreferences)
      }
    },
  })
}