diff --git a/src/orgs/components/org-list/use-org-list-query.ts b/src/orgs/components/org-list/use-org-list-query.ts new file mode 100644 index 00000000..8eb2312a --- /dev/null +++ b/src/orgs/components/org-list/use-org-list-query.ts @@ -0,0 +1,46 @@ +import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query'; + +import { QUERY_STALETIME } from '@/shared/core/constants'; +import { MW_URL, PAGE_SIZE } from '@/shared/core/envs'; +import { createUrlWithSearchParams } from '@/shared/utils/create-url-with-search-params'; +import { mwGET } from '@/shared/utils/mw-get'; + +import { OrgQueryKeys, orgQueryKeys } from '@/orgs/core/query-keys'; +import { OrgListQueryPage, orgListQueryPageSchema } from '@/orgs/core/schemas'; +import { useFiltersContext } from '@/filters/providers/filters-provider/context'; + +const getOrgList = async ( + page: number, + searchParams: string | Record, +) => { + const url = createUrlWithSearchParams( + `${MW_URL}/organizations/list?page=${page}&limit=${PAGE_SIZE}`, + searchParams, + ); + + return mwGET({ + url, + label: 'getOrgList', + responseSchema: orgListQueryPageSchema, + options: { next: { revalidate: 60 * 60 } }, + }); +}; + +export const useOrgListQuery = () => { + const { filterParamsString } = useFiltersContext(); + + return useInfiniteQuery< + OrgListQueryPage, + Error, + InfiniteData, + ReturnType, + number + >({ + queryKey: orgQueryKeys.list(filterParamsString), + queryFn: async ({ pageParam }) => getOrgList(pageParam, filterParamsString), + initialPageParam: 1, + getNextPageParam: ({ page, data }) => + page > 0 && data.length > 0 ? page + 1 : undefined, + staleTime: QUERY_STALETIME.DEFAULT, + }); +}; diff --git a/src/orgs/core/query-keys.ts b/src/orgs/core/query-keys.ts new file mode 100644 index 00000000..3b14b9fb --- /dev/null +++ b/src/orgs/core/query-keys.ts @@ -0,0 +1,14 @@ +export const orgQueryKeys = { + all: ['orgs'] as const, + details: (orgId: string) => [...orgQueryKeys.all, 'details', orgId] as const, + list: (params: string | Record) => { + const searchParams = + typeof params === 'string' + ? params + : new URLSearchParams(params).toString(); + + return [...orgQueryKeys.all, 'list', searchParams] as const; + }, +}; + +export type OrgQueryKeys = typeof orgQueryKeys; diff --git a/src/shared/utils/create-url-with-search-params.ts b/src/shared/utils/create-url-with-search-params.ts new file mode 100644 index 00000000..75855b69 --- /dev/null +++ b/src/shared/utils/create-url-with-search-params.ts @@ -0,0 +1,21 @@ +export const createUrlWithSearchParams = ( + url: string, + searchParams: string | Record, +): string => { + if (typeof searchParams === 'string') { + if (!searchParams) return url; + const separator = url.includes('?') ? '&' : '?'; + return `${url}${separator}${searchParams}`; + } + + const urlObject = new URL(url); + const paramsEntries = Object.entries(searchParams); + + if (paramsEntries.length > 0) { + paramsEntries.forEach(([key, value]) => + urlObject.searchParams.set(key, value), + ); + } + + return urlObject.toString(); +};