/* eslint-disable max-statements */ import type { GetStaticProps } from 'next'; import Head from 'next/head'; import Script from 'next/script'; import { useCallback } from 'react'; import { useIntl } from 'react-intl'; import { getLayout, Heading, LinksWidget, Notice, PostsList, Pagination, type RenderPaginationLink, type RenderPaginationItemAriaLabel, Page, PageHeader, PageBody, PageSidebar, Spinner, } from '../../components'; import { convertWPThematicPreviewToPageLink, convertWPTopicPreviewToPageLink, fetchPostsList, fetchThematicsCount, fetchThematicsList, fetchTopicsCount, fetchTopicsList, } from '../../services/graphql'; import styles from '../../styles/pages/blog.module.scss'; import type { GraphQLConnection, NextPageWithLayout, WPPostPreview, WPThematicPreview, WPTopicPreview, } from '../../types'; import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getBlogSchema, getLinksItemData, getPostsWithUrl, getSchemaJson, getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; import { useArticlesList, useBreadcrumb, useThematicsList, useTopicsList, } from '../../utils/hooks'; const renderPaginationLink: RenderPaginationLink = (pageNum) => `${ROUTES.BLOG}/page/${pageNum}`; type BlogPageProps = { data: { posts: GraphQLConnection; thematics: GraphQLConnection; topics: GraphQLConnection; }; translation: Messages; }; /** * Blog index page. */ const BlogPage: NextPageWithLayout = ({ data }) => { const intl = useIntl(); const { articles, error, firstNewResultIndex, isLoading, isLoadingMore, isRefreshing, hasNextPage, loadMore, } = useArticlesList({ fallback: [data.posts], perPage: CONFIG.postsPerPage, }); const { isLoading: areThematicsLoading, thematics } = useThematicsList({ fallback: data.thematics, input: { first: data.thematics.pageInfo.total }, }); const { isLoading: areTopicsLoading, topics } = useTopicsList({ fallback: data.topics, input: { first: data.topics.pageInfo.total }, }); const messages = { loading: { thematicsList: intl.formatMessage({ defaultMessage: 'Thematics are loading...', description: 'BlogPage: loading thematics message', id: 'y37FuH', }), topicsList: intl.formatMessage({ defaultMessage: 'Topics are loading...', description: 'BlogPage: loading topics message', id: 'OsclKU', }), }, pageTitle: intl.formatMessage({ defaultMessage: 'Blog', description: 'BlogPage: page title', id: '7TbbIk', }), pagination: { noJS: intl.formatMessage({ defaultMessage: "You can't load more articles without Javascript, please use the pagination instead.", description: 'BlogPage: pagination no script message', id: 'ZMES/E', }), title: intl.formatMessage({ defaultMessage: 'Pagination', description: 'BlogPage: pagination accessible name', id: 'AXe1Iz', }), }, seo: { metaDesc: intl.formatMessage( { defaultMessage: "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.", description: 'BlogPage: SEO - Meta description', id: '18h/t0', }, { websiteName: CONFIG.name } ), title: intl.formatMessage( { defaultMessage: 'Blog: development, open source - {websiteName}', description: 'BlogPage: SEO - Page title', id: '+Y+tLK', }, { websiteName: CONFIG.name } ), }, widgets: { thematicsListTitle: intl.formatMessage({ defaultMessage: 'Thematics', description: 'BlogPage: thematics list widget title', id: 'HriY57', }), topicsListTitle: intl.formatMessage({ defaultMessage: 'Topics', description: 'BlogPage: topics list widget title', id: '2D9tB5', }), }, }; const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ title: messages.pageTitle, url: ROUTES.BLOG, }); const webpageSchema = getWebPageSchema({ description: messages.seo.metaDesc, locale: CONFIG.locales.defaultLocale, slug: ROUTES.BLOG, title: messages.pageTitle, }); const blogSchema = getBlogSchema({ isSinglePage: false, locale: CONFIG.locales.defaultLocale, slug: ROUTES.BLOG, }); const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); const renderPaginationLabel: RenderPaginationItemAriaLabel = useCallback( ({ kind, pageNumber: number, isCurrentPage }) => { switch (kind) { case 'backward': return intl.formatMessage( { defaultMessage: 'Go to previous page, page {number}', description: 'BlogPage: previous page label', id: 'faO6BQ', }, { number } ); case 'forward': return intl.formatMessage( { defaultMessage: 'Go to next page, page {number}', description: 'BlogPage: next page label', id: 'oq3BzP', }, { number } ); case 'number': default: return isCurrentPage ? intl.formatMessage( { defaultMessage: 'Current page, page {number}', description: 'BlogPage: current page label', id: 'JL6G22', }, { number } ) : intl.formatMessage( { defaultMessage: 'Go to page {number}', description: 'BlogPage: page number label', id: 'IVczxR', }, { number } ); } }, [intl] ); const pageUrl = `${CONFIG.url}${ROUTES.BLOG}`; return ( {messages.seo.title} {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} {/*eslint-disable-next-line react/jsx-no-literals -- Content allowed */}