diff options
Diffstat (limited to 'src/utils/hooks/use-articles-list/use-articles-list.ts')
| -rw-r--r-- | src/utils/hooks/use-articles-list/use-articles-list.ts | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/utils/hooks/use-articles-list/use-articles-list.ts b/src/utils/hooks/use-articles-list/use-articles-list.ts new file mode 100644 index 0000000..8a52702 --- /dev/null +++ b/src/utils/hooks/use-articles-list/use-articles-list.ts @@ -0,0 +1,86 @@ +import { useCallback, useState } from 'react'; +import { + convertPostPreviewToArticlePreview, + fetchPostsList, +} from '../../../services/graphql'; +import type { + ArticlePreview, + GraphQLConnection, + GraphQLEdge, + Maybe, + WPPostPreview, +} from '../../../types'; +import { + type UsePaginationConfig, + usePagination, + type UsePaginationReturn, +} from '../use-pagination'; + +export type useArticlesListReturn = Omit< + UsePaginationReturn<WPPostPreview>, + 'data' +> & { + /** + * The articles list. + */ + articles: Maybe<GraphQLConnection<ArticlePreview>[]>; + /** + * The index of the first new result when loading more posts. + */ + firstNewResultIndex: Maybe<number>; +}; + +export const useArticlesList = ( + config: Omit<UsePaginationConfig<WPPostPreview>, 'fetcher'> +): useArticlesListReturn => { + const { + data, + error, + hasNextPage, + isEmpty, + isError, + isLoading, + isLoadingMore, + isRefreshing, + isValidating, + loadMore, + size, + } = usePagination({ ...config, fetcher: fetchPostsList }); + const [firstNewResultIndex, setFirstNewResultIndex] = + useState<Maybe<number>>(undefined); + + const handleLoadMore = useCallback(async () => { + setFirstNewResultIndex(size * config.perPage + 1); + + await loadMore(); + }, [config.perPage, loadMore, size]); + + const articles: Maybe<GraphQLConnection<ArticlePreview>[]> = data?.map( + ({ edges, pageInfo }): GraphQLConnection<ArticlePreview> => { + return { + edges: edges.map((edge): GraphQLEdge<ArticlePreview> => { + return { + cursor: edge.cursor, + node: convertPostPreviewToArticlePreview(edge.node), + }; + }), + pageInfo, + }; + } + ); + + return { + articles, + error, + firstNewResultIndex, + hasNextPage, + isEmpty, + isError, + isLoading, + isLoadingMore, + isRefreshing, + isValidating, + loadMore: handleLoadMore, + size, + }; +}; |
