import { useAuth } from '@/contexts/AuthContext'; import { commonQueryOptions, createDetailQueryHook, createListQueryHook, useInvalidatingMutation, } from '@/lib/api-hooks'; import { createQueryKeyFactory } from '@/lib/query-keys'; import type { CreateOrganizationRequest } from '@/schemas/backend/organization'; import { getOrganizationById, getOrganizations } from '@/services/organization-service'; import { createOrganization, deleteOrganization, getUserOrganizations, updateOrganization, } from '@/services/organizations-api'; import { useQuery } from '@tanstack/react-query'; /** * Query key factory for organizations * Uses reusable factory to reduce duplication * Version 2: Fixed JSON array serialization in backend */ const baseKeys = createQueryKeyFactory('organizations'); export const organizationKeys = { ...baseKeys, // Override methods to include version for cache invalidation lists: () => [...baseKeys.lists(), 'v2'] as const, list: (filters?: Record) => [...baseKeys.list(filters), 'v2'] as const, details: () => [...baseKeys.details(), 'v2'] as const, detail: (id: string) => [...baseKeys.detail(id), 'v2'] as const, user: () => [...baseKeys.all, 'user', 'v2'] as const, }; /** * Hook to fetch all organizations * Uses generic factory for consistent behavior */ export const useOrganizations = createListQueryHook(organizationKeys.lists(), getOrganizations); /** * Hook to fetch a single organization by ID * Uses generic factory for consistent behavior */ export const useOrganization = createDetailQueryHook( (id) => organizationKeys.detail(id!), (id) => getOrganizationById(id) ); /** * Hook to create a new organization * Uses reusable mutation utility for consistent invalidation */ export function useCreateOrganization() { return useInvalidatingMutation({ mutationFn: (request: CreateOrganizationRequest) => createOrganization(request), invalidateKeys: [organizationKeys.lists()], }); } /** * Hook to delete an organization * Uses reusable mutation utility for consistent invalidation */ export function useDeleteOrganization() { return useInvalidatingMutation({ mutationFn: (id: string) => deleteOrganization(id), invalidateKeys: [organizationKeys.lists(), organizationKeys.user()], }); } /** * Hook to update an organization * Accepts payload: { id: string, data: Partial } */ export function useUpdateOrganization() { return useInvalidatingMutation({ mutationFn: (payload: { id: string; data: Partial }) => updateOrganization(payload.id, payload.data), // Invalidate lists and details caches so both listings and detail pages refresh invalidateKeys: [organizationKeys.lists(), organizationKeys.details()], }); } /** * Hook to fetch organizations for the current user * Only enabled when user is authenticated to avoid 401 errors */ export function useUserOrganizations() { const { isAuthenticated, isLoading } = useAuth(); console.log('[useUserOrganizations] isAuthenticated:', isAuthenticated, 'isLoading:', isLoading); return useQuery({ queryKey: organizationKeys.user(), queryFn: getUserOrganizations, enabled: isAuthenticated && !isLoading, staleTime: commonQueryOptions.standardStaleTime, placeholderData: () => [] as ReturnType extends Promise ? T : never, }); }