diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-01-25 11:47:59 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-01-25 11:49:56 +0100 |
| commit | 71942c86311a9d1ddf4ae486d811f8393786e855 (patch) | |
| tree | 4e14e1f1ff083dabbb483ba2f12874666c1d6ced /src | |
| parent | 82702fbe2d0607e7ca8a02c878b2e79a21664b7c (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.scss | 28 | ||||
| -rw-r--r-- | src/components/PaginationCursor/PaginationCursor.tsx | 30 | ||||
| -rw-r--r-- | src/pages/blog/index.tsx | 31 | ||||
| -rw-r--r-- | src/pages/recherche/index.tsx | 31 |
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"> |
