From dab72bb270ee2ee47a0b472d5e9e240cba7cbf0f Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 13 May 2022 15:39:55 +0200 Subject: chore: handle blog pagination --- src/components/organisms/layout/posts-list.tsx | 73 +++++++++++++++++++++----- 1 file changed, 60 insertions(+), 13 deletions(-) (limited to 'src/components/organisms/layout/posts-list.tsx') diff --git a/src/components/organisms/layout/posts-list.tsx b/src/components/organisms/layout/posts-list.tsx index daf4491..4d77d20 100644 --- a/src/components/organisms/layout/posts-list.tsx +++ b/src/components/organisms/layout/posts-list.tsx @@ -1,10 +1,11 @@ +import Button from '@components/atoms/buttons/button'; import Heading, { type HeadingLevel } from '@components/atoms/headings/heading'; -import { FC } from 'react'; +import ProgressBar from '@components/atoms/loaders/progress-bar'; +import Spinner from '@components/atoms/loaders/spinner'; +import { FC, Fragment, useRef } from 'react'; import { useIntl } from 'react-intl'; -import Summary, { type SummaryProps } from './summary'; import styles from './posts-list.module.scss'; -import ProgressBar from '@components/atoms/loaders/progress-bar'; -import Button from '@components/atoms/buttons/button'; +import Summary, { type SummaryProps } from './summary'; export type Post = SummaryProps & { /** @@ -22,10 +23,22 @@ export type PostsListProps = { * True to display the posts by year. Default: false. */ byYear?: boolean; + /** + * Determine if the data is loading. + */ + isLoading?: boolean; + /** + * Load more button handler. + */ + loadMore?: () => void; /** * The posts data. */ posts: Post[]; + /** + * Determine if the load more button should be visible. + */ + showLoadMoreBtn?: boolean; /** * The posts heading level (hn). */ @@ -62,29 +75,42 @@ const sortPostsByYear = (data: Post[]): YearCollection => { */ const PostsList: FC = ({ byYear = false, + isLoading = false, + loadMore, posts, + showLoadMoreBtn = false, titleLevel, total, }) => { const intl = useIntl(); + const lastPostRef = useRef(null); /** * Retrieve the list of posts. * - * @param {Posts[]} data - A collection fo posts. + * @param {Posts[]} allPosts - A collection fo posts. * @param {HeadingLevel} [headingLevel] - The posts heading level (hn). * @returns {JSX.Element} The list of posts. */ const getList = ( - data: Post[], + allPosts: Post[], headingLevel: HeadingLevel = 2 ): JSX.Element => { + const lastPostId = allPosts[allPosts.length - 1].id; + return (
    - {data.map(({ id, ...post }) => ( -
  1. - -
  2. + {allPosts.map(({ id, ...post }) => ( + +
  3. + +
  4. + {id === lastPostId && ( +
  5. + +
  6. + )} +
    ))}
); @@ -93,7 +119,7 @@ const PostsList: FC = ({ /** * Retrieve the list of posts. * - * @returns {JSX.Element | JSX.Element[]} - The posts list. + * @returns {JSX.Element | JSX.Element[]} The posts list. */ const getPosts = (): JSX.Element | JSX.Element[] => { if (!byYear) return getList(posts); @@ -123,12 +149,23 @@ const PostsList: FC = ({ { articlesCount: posts.length, total: total } ); - const loadMore = intl.formatMessage({ + const loadMoreBody = intl.formatMessage({ defaultMessage: 'Load more articles?', id: 'uaqd5F', description: 'PostsList: load more button', }); + /** + * Load more posts handler. + */ + const loadMorePosts = () => { + if (lastPostRef.current) { + lastPostRef.current.focus(); + } + + loadMore && loadMore(); + }; + return posts.length === 0 ? (

{intl.formatMessage({ @@ -140,13 +177,23 @@ const PostsList: FC = ({ ) : ( <> {getPosts()} + {isLoading && } - + {showLoadMoreBtn && ( + + )} ); }; -- cgit v1.2.3