From 56878f647ea0f1066fa3e222d7aa0d83057f496d Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 13 Nov 2023 17:45:59 +0100 Subject: refactor(components): rewrite PostsList component * remove NoResults component and move logic to Search page * add a usePostsList hook * remove Pagination from PostsList (it is only used if javascript is disabled and not on every posts list) * replace `byYear` prop with `sortByYear` * replace `loadMore` prop with `onLoadMore` * remove `showLoadMoreBtn` (we can use `loadMore` prop instead to determine if we need to display the button) * replace `titleLevel` prop with `headingLvl` * add `firstNewResult` prop to handle focus on the new results when loading more article (we should not focus a useless span but the item directly) --- src/pages/recherche/index.tsx | 69 +++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 15 deletions(-) (limited to 'src/pages/recherche') diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx index a0e5057..effd087 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -3,6 +3,7 @@ import type { GetStaticProps } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; import Script from 'next/script'; +import { useCallback } from 'react'; import { useIntl } from 'react-intl'; import { getLayout, @@ -13,6 +14,8 @@ import { PageLayout, PostsList, Spinner, + SearchForm, + type SearchFormSubmit, } from '../../components'; import { getArticles, @@ -22,9 +25,9 @@ import { getTotalThematics, getTotalTopics, } from '../../services/graphql'; +import styles from '../../styles/pages/blog.module.scss'; import type { NextPageWithLayout, - RawArticle, RawThematicPreview, RawTopicPreview, } from '../../types'; @@ -33,7 +36,6 @@ import { getBlogSchema, getLinksListItems, getPageLinkFromRawData, - getPostsList, getSchemaJson, getWebPageSchema, } from '../../utils/helpers'; @@ -41,7 +43,7 @@ import { loadTranslation, type Messages } from '../../utils/helpers/server'; import { useBreadcrumb, useDataFromAPI, - usePagination, + usePostsList, useSettings, } from '../../utils/hooks'; @@ -59,7 +61,7 @@ const SearchPage: NextPageWithLayout = ({ topicsList, }) => { const intl = useIntl(); - const { asPath, query } = useRouter(); + const { asPath, query, push: routerPush } = useRouter(); const title = query.s ? intl.formatMessage( { @@ -116,14 +118,15 @@ const SearchPage: NextPageWithLayout = ({ const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); const { - data, error, + firstNewResultIndex, isLoading, isLoadingMore, isRefreshing, hasNextPage, loadMore, - } = usePagination({ + posts, + } = usePostsList({ fallback: [], fetcher: getArticles, perPage: blog.postsPerPage, @@ -167,13 +170,33 @@ const SearchPage: NextPageWithLayout = ({ description: 'SearchPage: topics list widget title', id: 'N804XO', }); - const postsListBaseUrl = `${ROUTES.SEARCH}/page/`; const loadingResults = intl.formatMessage({ defaultMessage: 'Loading the search results...', description: 'SearchPage: loading search results message', id: 'EeCqAE', }); + const searchSubmitHandler: SearchFormSubmit = useCallback( + ({ query: searchQuery }) => { + if (!searchQuery) + return { + messages: { + error: intl.formatMessage({ + defaultMessage: 'Query must be longer than one character.', + description: 'NoResults: invalid query message', + id: 'VkfO7t', + }), + }, + validator: (value) => value.query.length > 1, + }; + + routerPush({ pathname: ROUTES.SEARCH, query: { s: searchQuery } }); + + return undefined; + }, + [intl, routerPush] + ); + return ( <> @@ -227,18 +250,34 @@ const SearchPage: NextPageWithLayout = ({ />, ]} > - {data && data.length > 0 ? ( + {posts ? null : {loadingResults}} + {posts?.length ? ( ) : ( - {loadingResults} + <> +

+ {intl.formatMessage({ + defaultMessage: 'No results found.', + description: 'SearchPage: no results', + id: 'YV//MH', + })} +

+

+ {intl.formatMessage({ + defaultMessage: 'Would you like to try a new search?', + description: 'SearchPage: try a new search message', + id: 'vtDLzG', + })} +

+ + )} {error ? (