{"version":3,"file":"users.mjs","sources":["../../../src/lib/queries/users.ts"],"sourcesContent":["/**\n * @file Users Query Factories\n * @description Query factories for user-related API calls using standardized apiClient\n */\n\nimport {\n  useQuery,\n  useSuspenseQuery,\n  useMutation,\n  useQueryClient,\n  type UseQueryOptions,\n  type UseSuspenseQueryOptions,\n  type UseMutationOptions,\n} from '@tanstack/react-query';\nimport { queryKeys } from './queryClient';\nimport { TIMING } from '@/config';\nimport { apiClient, type ApiError } from '@/lib/api';\n\n/**\n * User role type\n */\nexport type UserRole = 'admin' | 'manager' | 'user' | 'viewer';\n\n/**\n * User status type\n */\nexport type UserStatus = 'active' | 'inactive' | 'pending' | 'suspended';\n\n/**\n * User entity type\n */\nexport interface User {\n  id: string;\n  email: string;\n  firstName: string;\n  lastName: string;\n  displayName: string;\n  avatar?: string;\n  role: UserRole;\n  status: UserStatus;\n  createdAt: string;\n  updatedAt: string;\n  lastLoginAt?: string;\n}\n\n/**\n * User list filters\n */\nexport interface UserFilters {\n  search?: string;\n  role?: UserRole;\n  status?: UserStatus;\n  page?: number;\n  pageSize?: number;\n  sortBy?: keyof User;\n  sortOrder?: 'asc' | 'desc';\n  [key: string]: unknown;\n}\n\n/**\n * Paginated users response\n */\nexport interface UsersResponse {\n  users: User[];\n  total: number;\n  page: number;\n  pageSize: number;\n  totalPages: number;\n}\n\n/**\n * Create user payload\n */\nexport interface CreateUserPayload {\n  email: string;\n  firstName: string;\n  lastName: string;\n  role: UserRole;\n  password?: string;\n  sendInvite?: boolean;\n}\n\n/**\n * Update user payload\n */\nexport interface UpdateUserPayload {\n  firstName?: string;\n  lastName?: string;\n  role?: UserRole;\n  status?: UserStatus;\n  avatar?: string;\n}\n\n/**\n * Fetch users list using apiClient\n * @throws {ApiError} When the request fails\n */\nasync function fetchUsers(filters?: UserFilters): Promise<UsersResponse> {\n  const params: Record<string, string | number | boolean | undefined> = {};\n  if (filters) {\n    Object.entries(filters).forEach(([key, value]) => {\n      if (value !== undefined) {\n        params[key] = value as string | number | boolean;\n      }\n    });\n  }\n\n  const response = await apiClient.get<UsersResponse>('/api/users', { params });\n  return response.data;\n}\n\n/**\n * Fetch single user by ID using apiClient\n * @throws {ApiError} When the request fails\n */\nasync function fetchUserById(id: string): Promise<User> {\n  const response = await apiClient.get<User>(`/api/users/${id}`);\n  return response.data;\n}\n\n/**\n * Fetch current user profile using apiClient\n * @throws {ApiError} When the request fails\n */\nasync function fetchUserProfile(): Promise<User> {\n  const response = await apiClient.get<User>('/api/users/profile');\n  return response.data;\n}\n\n/**\n * Create a new user using apiClient\n * @throws {ApiError} When the request fails\n */\nasync function createUser(payload: CreateUserPayload): Promise<User> {\n  const response = await apiClient.post<User>('/api/users', payload);\n  return response.data;\n}\n\n/**\n * Update an existing user using apiClient\n * @throws {ApiError} When the request fails\n */\nasync function updateUser(id: string, payload: UpdateUserPayload): Promise<User> {\n  const response = await apiClient.patch<User>(`/api/users/${id}`, payload);\n  return response.data;\n}\n\n/**\n * Delete a user using apiClient\n * @throws {ApiError} When the request fails\n */\nasync function deleteUser(id: string): Promise<void> {\n  await apiClient.delete(`/api/users/${id}`);\n}\n\n/**\n * Query options for users list\n */\nexport function usersListQueryOptions(filters?: UserFilters): UseQueryOptions<UsersResponse> {\n  return {\n    queryKey: queryKeys.users.list(filters),\n    queryFn: async () => fetchUsers(filters),\n    staleTime: TIMING.QUERY.STALE.SHORT, // ~1 minute (close to 2 min)\n    meta: {\n      errorMessage: 'Failed to load users',\n    },\n  };\n}\n\n/**\n * Query options for single user\n */\nexport function userDetailQueryOptions(id: string): UseQueryOptions<User> {\n  return {\n    queryKey: queryKeys.users.detail(id),\n    queryFn: async () => fetchUserById(id),\n    staleTime: TIMING.QUERY.STALE.MEDIUM, // 5 minutes\n    enabled: !!id,\n    meta: {\n      errorMessage: 'Failed to load user details',\n    },\n  };\n}\n/**\n * Query options for user profile\n */\nexport function userProfileQueryOptions(): UseQueryOptions<User> {\n  return {\n    queryKey: queryKeys.users.profile(),\n    queryFn: fetchUserProfile,\n    staleTime: TIMING.QUERY.STALE.LONG, // 10 minutes\n    meta: {\n      errorMessage: 'Failed to load user profile',\n    },\n  };\n}\n\n/**\n * Suspense query options for users list\n */\nexport function usersListSuspenseQueryOptions(\n  filters?: UserFilters\n): UseSuspenseQueryOptions<UsersResponse> {\n  return {\n    queryKey: queryKeys.users.list(filters),\n    queryFn: async () => fetchUsers(filters),\n    staleTime: TIMING.QUERY.STALE.SHORT, // ~1 minute\n  };\n}\n\n/**\n * Suspense query options for single user\n */\nexport function userDetailSuspenseQueryOptions(id: string): UseSuspenseQueryOptions<User> {\n  return {\n    queryKey: queryKeys.users.detail(id),\n    queryFn: async () => fetchUserById(id),\n    staleTime: TIMING.QUERY.STALE.MEDIUM, // 5 minutes\n  };\n}\n\n/**\n * Suspense query options for user profile\n */\nexport function userProfileSuspenseQueryOptions(): UseSuspenseQueryOptions<User> {\n  return {\n    queryKey: queryKeys.users.profile(),\n    queryFn: fetchUserProfile,\n    staleTime: TIMING.QUERY.STALE.LONG, // 10 minutes\n  };\n}\n\n/**\n * Hook to fetch users list with Suspense\n */\nexport function useUsersSuspense(\n  filters?: UserFilters\n): ReturnType<typeof useSuspenseQuery<UsersResponse>> {\n  return useSuspenseQuery(usersListSuspenseQueryOptions(filters));\n}\n\n/**\n * Hook to fetch users list\n */\nexport function useUsers(filters?: UserFilters): ReturnType<typeof useQuery<UsersResponse>> {\n  return useQuery(usersListQueryOptions(filters));\n}\n\n/**\n * Hook to fetch current user profile with Suspense\n */\nexport function useUserProfileSuspense(): ReturnType<typeof useSuspenseQuery<User>> {\n  return useSuspenseQuery(userProfileSuspenseQueryOptions());\n}\n\n/**\n * Hook to fetch single user with Suspense\n */\nexport function useUserSuspense(id: string): ReturnType<typeof useSuspenseQuery<User>> {\n  return useSuspenseQuery(userDetailSuspenseQueryOptions(id));\n}\n\n/**\n * Hook to fetch single user\n */\nexport function useUser(id: string): ReturnType<typeof useQuery<User>> {\n  return useQuery(userDetailQueryOptions(id));\n}\n\n/**\n * Hook to fetch current user profile\n */\nexport function useUserProfile(): ReturnType<typeof useQuery<User>> {\n  return useQuery(userProfileQueryOptions());\n}\n\n/**\n * Hook to create a user\n * @throws {ApiError} When the request fails\n */\nexport function useCreateUser(\n  options?: UseMutationOptions<User, ApiError, CreateUserPayload>\n): ReturnType<typeof useMutation<User, ApiError, CreateUserPayload>> {\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: createUser,\n    onSuccess: () => {\n      void queryClient.invalidateQueries({ queryKey: queryKeys.users.all });\n    },\n    ...options,\n  });\n}\n\n/**\n * Hook to update a user\n * @throws {ApiError} When the request fails\n */\nexport function useUpdateUser(\n  options?: UseMutationOptions<User, ApiError, { id: string; payload: UpdateUserPayload }>\n): ReturnType<typeof useMutation<User, ApiError, { id: string; payload: UpdateUserPayload }>> {\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: async ({ id, payload }) => updateUser(id, payload),\n    onSuccess: (updatedUser) => {\n      queryClient.setQueryData(queryKeys.users.detail(updatedUser.id), updatedUser);\n      void queryClient.invalidateQueries({ queryKey: queryKeys.users.list() });\n    },\n    ...options,\n  });\n}\n\n/**\n * Hook to delete a user\n * @throws {ApiError} When the request fails\n */\nexport function useDeleteUser(\n  options?: UseMutationOptions<void, ApiError, string>\n): ReturnType<typeof useMutation<void, ApiError, string>> {\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: deleteUser,\n    onSuccess: (_, id) => {\n      queryClient.removeQueries({ queryKey: queryKeys.users.detail(id) });\n      void queryClient.invalidateQueries({ queryKey: queryKeys.users.list() });\n    },\n    ...options,\n  });\n}\n"],"names":["fetchUsers","filters","params","key","value","apiClient","fetchUserById","id","fetchUserProfile","createUser","payload","updateUser","deleteUser","usersListQueryOptions","queryKeys","TIMING","userDetailQueryOptions","userProfileQueryOptions","usersListSuspenseQueryOptions","userDetailSuspenseQueryOptions","userProfileSuspenseQueryOptions","useUsersSuspense","useSuspenseQuery","useUsers","useQuery","useUserProfileSuspense","useUserSuspense","useUser","useUserProfile","useCreateUser","options","queryClient","useQueryClient","useMutation","useUpdateUser","updatedUser","useDeleteUser","_"],"mappings":"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"}