From fe2252ced2bb895e26179640553b5a6c02957d54 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 13 May 2022 22:41:39 +0200 Subject: chore: add Topic pages --- src/pages/sujet/[slug].tsx | 244 +++++++++++++++++++++++++++++++++++ src/services/graphql/topics.query.ts | 7 + src/services/graphql/topics.ts | 135 ++++++++++++++++++- 3 files changed, 380 insertions(+), 6 deletions(-) create mode 100644 src/pages/sujet/[slug].tsx (limited to 'src') diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx new file mode 100644 index 0000000..22fb531 --- /dev/null +++ b/src/pages/sujet/[slug].tsx @@ -0,0 +1,244 @@ +import Heading from '@components/atoms/headings/heading'; +import { type BreadcrumbItem } from '@components/molecules/nav/breadcrumb'; +import PostsList, { type Post } from '@components/organisms/layout/posts-list'; +import LinksListWidget from '@components/organisms/widgets/links-list-widget'; +import PageLayout, { + type PageLayoutProps, +} from '@components/templates/page/page-layout'; +import { + getAllTopicsSlugs, + getTopicBySlug, + getTopicsPreview, + getTotalTopics, +} from '@services/graphql/topics'; +import { type Article, type PageLink, type Topic } from '@ts/types/app'; +import { loadTranslation, type Messages } from '@utils/helpers/i18n'; +import { + getLinksListItems, + getPageLinkFromRawData, + getPostMeta, +} from '@utils/helpers/pages'; +import useSettings from '@utils/hooks/use-settings'; +import { GetStaticPaths, GetStaticProps, NextPage } from 'next'; +import Head from 'next/head'; +import { useRouter } from 'next/router'; +import Script from 'next/script'; +import { ParsedUrlQuery } from 'querystring'; +import { useIntl } from 'react-intl'; +import { Article as ArticleSchema, Graph, WebPage } from 'schema-dts'; + +export type TopicPageProps = { + currentTopic: Topic; + topics: PageLink[]; + translation: Messages; +}; + +const TopicPage: NextPage = ({ currentTopic, topics }) => { + const { content, intro, meta, slug, title } = currentTopic; + const { articles, dates, seo, thematics } = meta; + const intl = useIntl(); + const homeLabel = intl.formatMessage({ + defaultMessage: 'Home', + description: 'Breadcrumb: home label', + id: 'j5k9Fe', + }); + const blogLabel = intl.formatMessage({ + defaultMessage: 'Blog', + description: 'Breadcrumb: blog label', + id: 'Es52wh', + }); + const breadcrumb: BreadcrumbItem[] = [ + { id: 'home', name: homeLabel, url: '/' }, + { id: 'blog', name: blogLabel, url: '/blog' }, + { id: 'topic', name: title, url: `/sujet/${slug}` }, + ]; + + const headerMeta: PageLayoutProps['headerMeta'] = { + publication: { date: dates.publication }, + update: dates.update ? { date: dates.update } : undefined, + }; + + const { website } = useSettings(); + const { asPath } = useRouter(); + const pageUrl = `${website.url}${asPath}`; + const pagePublicationDate = new Date(dates.publication); + const pageUpdateDate = dates.update ? new Date(dates.update) : undefined; + + const webpageSchema: WebPage = { + '@id': `${pageUrl}`, + '@type': 'WebPage', + breadcrumb: { '@id': `${website.url}/#breadcrumb` }, + name: seo.title, + description: seo.description, + inLanguage: website.locales.default, + reviewedBy: { '@id': `${website.url}/#branding` }, + url: `${website.url}`, + }; + + const articleSchema: ArticleSchema = { + '@id': `${website.url}/#topic`, + '@type': 'Article', + name: title, + description: intro, + author: { '@id': `${website.url}/#branding` }, + copyrightYear: pagePublicationDate.getFullYear(), + creator: { '@id': `${website.url}/#branding` }, + dateCreated: pagePublicationDate.toISOString(), + dateModified: pageUpdateDate && pageUpdateDate.toISOString(), + datePublished: pagePublicationDate.toISOString(), + editor: { '@id': `${website.url}/#branding` }, + headline: title, + inLanguage: website.locales.default, + isPartOf: { '@id': `${website.url}/blog` }, + license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr', + mainEntityOfPage: { '@id': `${pageUrl}` }, + subjectOf: { '@id': `${website.url}/blog` }, + }; + + const schemaJsonLd: Graph = { + '@context': 'https://schema.org', + '@graph': [webpageSchema, articleSchema], + }; + + const getPosts = (array: Article[]): Post[] => { + return array.map((article) => { + const { + intro: articleIntro, + meta: articleMeta, + slug: articleSlug, + ...remainingData + } = article; + + const { cover, ...remainingMeta } = articleMeta; + + return { + cover, + excerpt: articleIntro, + meta: getPostMeta(remainingMeta), + url: `/article/${articleSlug}`, + ...remainingData, + }; + }); + }; + + const topicsListTitle = intl.formatMessage({ + defaultMessage: 'Other topics', + description: 'TopicPage: other topics list widget title', + id: 'JpC3JH', + }); + + const thematicsListTitle = intl.formatMessage({ + defaultMessage: 'Related thematics', + description: 'TopicPage: related thematics list widget title', + id: '/sRqPT', + }); + + return ( + <> + + {seo.title} + + + + + + +