summaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-20 15:37:08 +0200
committerArmand Philippot <git@armandphilippot.com>2022-05-20 15:37:08 +0200
commitf4c7ab4e306d2f04324853e67032d370abd65d0c (patch)
tree2c7d1ad467d6c52bc134202f0d33f7524f9056fa /src/components
parentbbd63400f94b43fde04449e0c71d14763d893e6a (diff)
chore: handle blog pagination when JS is disabled
Diffstat (limited to 'src/components')
-rw-r--r--src/components/molecules/nav/pagination.module.scss2
-rw-r--r--src/components/molecules/nav/pagination.tsx10
-rw-r--r--src/components/organisms/layout/posts-list.tsx95
3 files changed, 74 insertions, 33 deletions
diff --git a/src/components/molecules/nav/pagination.module.scss b/src/components/molecules/nav/pagination.module.scss
index a8cef47..56c5bfc 100644
--- a/src/components/molecules/nav/pagination.module.scss
+++ b/src/components/molecules/nav/pagination.module.scss
@@ -13,7 +13,7 @@
&--pages {
column-gap: var(--spacing-2xs);
- margin-top: var(--spacing-sm);
+ margin-bottom: var(--spacing-sm);
}
}
diff --git a/src/components/molecules/nav/pagination.tsx b/src/components/molecules/nav/pagination.tsx
index 38f6841..934b50a 100644
--- a/src/components/molecules/nav/pagination.tsx
+++ b/src/components/molecules/nav/pagination.tsx
@@ -44,12 +44,12 @@ const Pagination: FC<PaginationProps> = ({
className = '',
current,
perPage,
- siblings = 1,
+ siblings = 2,
total,
...props
}) => {
const intl = useIntl();
- const totalPages = Math.ceil(total / perPage);
+ const totalPages = Math.round(total / perPage);
const hasPreviousPage = current > 1;
const previousPageName = intl.formatMessage(
{
@@ -205,14 +205,14 @@ const Pagination: FC<PaginationProps> = ({
return (
<nav className={`${styles.wrapper} ${className}`} {...props}>
+ <ul className={`${styles.list} ${styles['list--pages']}`}>
+ {getPages(current, totalPages)}
+ </ul>
<ul className={styles.list}>
{hasPreviousPage &&
getItem('previous', previousPageName, previousPageUrl)}
{hasNextPage && getItem('next', nextPageName, nextPageUrl)}
</ul>
- <ul className={`${styles.list} ${styles['list--pages']}`}>
- {getPages(current, totalPages)}
- </ul>
</nav>
);
};
diff --git a/src/components/organisms/layout/posts-list.tsx b/src/components/organisms/layout/posts-list.tsx
index 9dfe254..50192dd 100644
--- a/src/components/organisms/layout/posts-list.tsx
+++ b/src/components/organisms/layout/posts-list.tsx
@@ -2,6 +2,11 @@ import Button from '@components/atoms/buttons/button';
import Heading, { type HeadingLevel } from '@components/atoms/headings/heading';
import ProgressBar from '@components/atoms/loaders/progress-bar';
import Spinner from '@components/atoms/loaders/spinner';
+import Pagination, {
+ PaginationProps,
+} from '@components/molecules/nav/pagination';
+import useIsMounted from '@utils/hooks/use-is-mounted';
+import useSettings from '@utils/hooks/use-settings';
import { FC, Fragment, useRef } from 'react';
import { useIntl } from 'react-intl';
import styles from './posts-list.module.scss';
@@ -18,7 +23,7 @@ export type YearCollection = {
[key: string]: Post[];
};
-export type PostsListProps = {
+export type PostsListProps = Pick<PaginationProps, 'baseUrl' | 'siblings'> & {
/**
* True to display the posts by year. Default: false.
*/
@@ -32,6 +37,10 @@ export type PostsListProps = {
*/
loadMore?: () => void;
/**
+ * The current page number. Default: 1.
+ */
+ pageNumber?: number;
+ /**
* The posts data.
*/
posts: Post[];
@@ -74,16 +83,22 @@ const sortPostsByYear = (data: Post[]): YearCollection => {
* Render a list of post summaries.
*/
const PostsList: FC<PostsListProps> = ({
+ baseUrl,
byYear = false,
isLoading = false,
loadMore,
+ pageNumber = 1,
posts,
showLoadMoreBtn = false,
+ siblings,
titleLevel,
total,
}) => {
const intl = useIntl();
+ const listRef = useRef<HTMLOListElement>(null);
const lastPostRef = useRef<HTMLSpanElement>(null);
+ const isMounted = useIsMounted(listRef);
+ const { blog } = useSettings();
/**
* Retrieve the list of posts.
@@ -99,7 +114,7 @@ const PostsList: FC<PostsListProps> = ({
const lastPostId = allPosts[allPosts.length - 1].id;
return (
- <ol className={styles.list}>
+ <ol className={styles.list} ref={listRef}>
{allPosts.map(({ id, ...post }) => (
<Fragment key={id}>
<li className={styles.item}>
@@ -168,34 +183,60 @@ const PostsList: FC<PostsListProps> = ({
loadMore && loadMore();
};
- return posts.length === 0 ? (
- <p>
- {intl.formatMessage({
- defaultMessage: 'No results found.',
- description: 'PostsList: no results',
- id: 'vK7Sxv',
- })}
- </p>
- ) : (
+ const getProgressBar = () => {
+ return (
+ <>
+ <ProgressBar
+ min={1}
+ max={total}
+ current={posts.length}
+ info={progressInfo}
+ />
+ {showLoadMoreBtn && (
+ <Button
+ kind="tertiary"
+ onClick={loadMorePosts}
+ disabled={isLoading}
+ className={styles.btn}
+ >
+ {loadMoreBody}
+ </Button>
+ )}
+ </>
+ );
+ };
+
+ const getPagination = () => {
+ return posts.length <= blog.postsPerPage ? (
+ <Pagination
+ baseUrl={baseUrl}
+ current={pageNumber}
+ perPage={blog.postsPerPage}
+ siblings={siblings}
+ total={total}
+ />
+ ) : (
+ <></>
+ );
+ };
+
+ if (posts.length === 0) {
+ return (
+ <p>
+ {intl.formatMessage({
+ defaultMessage: 'No results found.',
+ description: 'PostsList: no results',
+ id: 'vK7Sxv',
+ })}
+ </p>
+ );
+ }
+
+ return (
<>
{getPosts()}
{isLoading && <Spinner />}
- <ProgressBar
- min={1}
- max={total}
- current={posts.length}
- info={progressInfo}
- />
- {showLoadMoreBtn && (
- <Button
- kind="tertiary"
- onClick={loadMorePosts}
- disabled={isLoading}
- className={styles.btn}
- >
- {loadMoreBody}
- </Button>
- )}
+ {isMounted ? getProgressBar() : getPagination()}
</>
);
};