summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-01-25 11:47:59 +0100
committerArmand Philippot <git@armandphilippot.com>2022-01-25 11:49:56 +0100
commit71942c86311a9d1ddf4ae486d811f8393786e855 (patch)
tree4e14e1f1ff083dabbb483ba2f12874666c1d6ced /src
parent82702fbe2d0607e7ca8a02c878b2e79a21664b7c (diff)
chore: display a progress bar before load more button
Since I'm using cursor pagination, users cannot know if there is a lot of posts available. With this cursor, they can verify the progression.
Diffstat (limited to 'src')
-rw-r--r--src/components/PaginationCursor/PaginationCursor.module.scss28
-rw-r--r--src/components/PaginationCursor/PaginationCursor.tsx30
-rw-r--r--src/pages/blog/index.tsx31
-rw-r--r--src/pages/recherche/index.tsx31
4 files changed, 110 insertions, 10 deletions
diff --git a/src/components/PaginationCursor/PaginationCursor.module.scss b/src/components/PaginationCursor/PaginationCursor.module.scss
new file mode 100644
index 0000000..35484ea
--- /dev/null
+++ b/src/components/PaginationCursor/PaginationCursor.module.scss
@@ -0,0 +1,28 @@
+@use "@styles/abstracts/functions" as fun;
+
+.wrapper {
+ margin: var(--spacing-sm) auto var(--spacing-md);
+ width: max-content;
+
+ .bar[value] {
+ display: block;
+ width: 30ch;
+ height: fun.convert-px(13);
+ appearance: none;
+ background: var(--color-bg-tertiary);
+ border: fun.convert-px(1) solid var(--color-primary-darker);
+ border-radius: 1em;
+ box-shadow: inset 0 0 fun.convert-px(4) fun.convert-px(1)
+ var(--color-shadow-light);
+
+ &::-webkit-progress-value {
+ background-color: var(--color-primary-dark);
+ border-radius: 1em;
+ }
+
+ &::-moz-progress-bar {
+ background-color: var(--color-primary-dark);
+ border-radius: 1em;
+ }
+ }
+}
diff --git a/src/components/PaginationCursor/PaginationCursor.tsx b/src/components/PaginationCursor/PaginationCursor.tsx
new file mode 100644
index 0000000..bcbb555
--- /dev/null
+++ b/src/components/PaginationCursor/PaginationCursor.tsx
@@ -0,0 +1,30 @@
+import { plural, t } from '@lingui/macro';
+import styles from './PaginationCursor.module.scss';
+
+const PaginationCursor = ({
+ current,
+ total,
+}: {
+ current: number;
+ total: number;
+}) => {
+ return (
+ <div className={styles.wrapper}>
+ <progress
+ className={styles.bar}
+ max={total}
+ value={current}
+ aria-valuemin={0}
+ aria-valuemax={total}
+ aria-label={t`Number of articles loaded out of the total available.`}
+ title={plural(current, {
+ zero: `# articles out of a total of ${total}`,
+ one: `# article out of a total of ${total}`,
+ other: `# articles out of a total of ${total}`,
+ })}
+ ></progress>
+ </div>
+ );
+};
+
+export default PaginationCursor;
diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx
index bd27c75..e0d1485 100644
--- a/src/pages/blog/index.tsx
+++ b/src/pages/blog/index.tsx
@@ -19,6 +19,7 @@ import { useEffect, useRef, useState } from 'react';
import Spinner from '@components/Spinner/Spinner';
import { Blog as BlogSchema, Graph, WebPage } from 'schema-dts';
import { useRouter } from 'next/router';
+import PaginationCursor from '@components/PaginationCursor/PaginationCursor';
const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => {
const lastPostRef = useRef<HTMLSpanElement>(null);
@@ -46,6 +47,20 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => {
if (data) setTotalPostsCount(data[0].pageInfo.total);
}, [data]);
+ const [loadedPostsCount, setLoadedPostsCount] = useState<number>(
+ config.postsPerPage
+ );
+
+ useEffect(() => {
+ if (data && data.length > 0) {
+ const newCount =
+ config.postsPerPage +
+ data[0].pageInfo.total -
+ data[data.length - 1].pageInfo.total;
+ setLoadedPostsCount(newCount);
+ }
+ }, [data]);
+
const isLoadingInitialData = !data && !error;
const isLoadingMore: boolean =
isLoadingInitialData ||
@@ -122,11 +137,17 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => {
<div className={styles.body}>
{getPostsList()}
{hasNextPage && (
- <Button
- isDisabled={isLoadingMore}
- clickHandler={loadMorePosts}
- position="center"
- >{t`Load more?`}</Button>
+ <>
+ <PaginationCursor
+ current={loadedPostsCount}
+ total={totalPostsCount}
+ />
+ <Button
+ isDisabled={isLoadingMore}
+ clickHandler={loadMorePosts}
+ position="center"
+ >{t`Load more?`}</Button>
+ </>
)}
</div>
<Sidebar position="right" title={t`Filter by`}>
diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx
index 771bd3b..f497ca3 100644
--- a/src/pages/recherche/index.tsx
+++ b/src/pages/recherche/index.tsx
@@ -17,6 +17,7 @@ import Sidebar from '@components/Sidebar/Sidebar';
import { ThematicsList, TopicsList } from '@components/Widgets';
import styles from '@styles/pages/Page.module.scss';
import Spinner from '@components/Spinner/Spinner';
+import PaginationCursor from '@components/PaginationCursor/PaginationCursor';
const Search: NextPageWithLayout = () => {
const [query, setQuery] = useState('');
@@ -53,6 +54,20 @@ const Search: NextPageWithLayout = () => {
if (data) setTotalPostsCount(data[0].pageInfo.total);
}, [data]);
+ const [loadedPostsCount, setLoadedPostsCount] = useState<number>(
+ config.postsPerPage
+ );
+
+ useEffect(() => {
+ if (data && data.length > 0) {
+ const newCount =
+ config.postsPerPage +
+ data[0].pageInfo.total -
+ data[data.length - 1].pageInfo.total;
+ setLoadedPostsCount(newCount);
+ }
+ }, [data]);
+
const isLoadingInitialData = !data && !error;
const isLoadingMore: boolean =
isLoadingInitialData ||
@@ -104,11 +119,17 @@ const Search: NextPageWithLayout = () => {
<div className={styles.body}>
{getPostsList()}
{hasNextPage && (
- <Button
- isDisabled={isLoadingMore}
- clickHandler={loadMorePosts}
- position="center"
- >{t`Load more?`}</Button>
+ <>
+ <PaginationCursor
+ current={loadedPostsCount}
+ total={totalPostsCount}
+ />
+ <Button
+ isDisabled={isLoadingMore}
+ clickHandler={loadMorePosts}
+ position="center"
+ >{t`Load more?`}</Button>
+ </>
)}
</div>
<Sidebar position="right">