import { GetStaticProps, GetStaticPaths, GetStaticPathsResult } from "next"; import { useCallback } from "react"; import { getReadySdk } from "graphql/sdk"; import { isDefined, filterHasAttributes } from "helpers/asserts"; import { ChronicleWithTranslations } from "types/types"; import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { useSmartLanguage } from "hooks/useSmartLanguage"; import { ContentPanel } from "components/Containers/ContentPanel"; import { Markdawn } from "components/Markdown/Markdawn"; import { SubPanel } from "components/Containers/SubPanel"; import { ThumbnailHeader } from "components/ThumbnailHeader"; import { HorizontalLine } from "components/HorizontalLine"; import { GetChroniclesChaptersQuery } from "graphql/generated"; import { prettyInlineTitle, prettySlug } from "helpers/formatters"; import { ReturnButton } from "components/PanelComponents/ReturnButton"; import { getOpenGraph } from "helpers/openGraph"; import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales"; import { getDescription } from "helpers/description"; import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList"; import { useScrollTopOnChange } from "hooks/useScrollTopOnChange"; import { Ids } from "types/ids"; import { useFormat } from "hooks/useFormat"; import { getFormat } from "helpers/i18n"; import { ElementsSeparator } from "helpers/component"; import { ChroniclesLists } from "components/Chronicles/ChroniclesLists"; /* * ╭────────╮ * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── */ interface Props extends AppLayoutRequired { chronicle: ChronicleWithTranslations; chapters: NonNullable["data"]; } const Chronicle = ({ chronicle, chapters, ...otherProps }: Props): JSX.Element => { const { format } = useFormat(); useScrollTopOnChange(Ids.ContentPanel, [chronicle.slug]); const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] = useSmartLanguage({ items: chronicle.translations, languageExtractor: useCallback( (item: ChronicleWithTranslations["translations"][number]) => item?.language?.data?.attributes?.code, [] ), }); const primaryContent = chronicle.contents ? filterHasAttributes(chronicle.contents.data, ["attributes.translations"])[0]?.attributes : undefined; const [selectedContentTranslation, ContentLanguageSwitcher, ContentLanguageSwitcherProps] = useSmartLanguage({ items: primaryContent?.translations ?? [], languageExtractor: useCallback( ( item: NonNullable< NonNullable< NonNullable["data"][number]["attributes"] >["translations"] >[number] ) => item?.language?.data?.attributes?.code, [] ), }); const subPanel = ( ); const contentPanel = ( {isDefined(selectedTranslation) ? ( <>

{selectedTranslation.title}

{languageSwitcherProps.locales.size > 1 && ( )} {isDefined(selectedTranslation.body) && } ) : ( <> {selectedContentTranslation && ( {[ 1 ? ( ) : undefined } categories={primaryContent?.categories} type={primaryContent?.type} description={selectedContentTranslation.description} thumbnail={primaryContent?.thumbnail?.data?.attributes} />, selectedContentTranslation.text_set?.text && ( ), ]} )} )}
); return ( ); }; export default Chronicle; /* * ╭──────────────────────╮ * ───────────────────────────────────╯ NEXT DATA FETCHING ╰────────────────────────────────────── */ export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); const { format } = getFormat(context.locale); const slug = context.params && isDefined(context.params.slug) ? context.params.slug.toString() : ""; const chronicle = await sdk.getChronicle({ language_code: context.locale ?? "en", slug: slug, }); const chronicles = await sdk.getChroniclesChapters(); if ( !chronicle.chronicles?.data[0]?.attributes?.translations || !chronicles.chroniclesChapters?.data ) return { notFound: true }; const { title, description } = (() => { if (context.locale && context.locales) { if (chronicle.chronicles.data[0].attributes.contents?.data[0]?.attributes?.translations) { const selectedContentTranslation = staticSmartLanguage({ items: chronicle.chronicles.data[0].attributes.contents.data[0].attributes.translations, languageExtractor: (item) => item.language?.data?.attributes?.code, preferredLanguages: getDefaultPreferredLanguages(context.locale, context.locales), }); if (selectedContentTranslation) { return { title: prettyInlineTitle( selectedContentTranslation.pre_title, selectedContentTranslation.title, selectedContentTranslation.subtitle ), description: getDescription(selectedContentTranslation.description, { [format("type", { count: Infinity })]: [ chronicle.chronicles.data[0].attributes.contents.data[0].attributes.type?.data ?.attributes?.titles?.[0]?.title, ], [format("category", { count: Infinity })]: filterHasAttributes( chronicle.chronicles.data[0].attributes.contents.data[0].attributes.categories ?.data, ["attributes"] ).map((category) => category.attributes.short), }), }; } } else { const selectedTranslation = staticSmartLanguage({ items: chronicle.chronicles.data[0].attributes.translations, languageExtractor: (item) => item.language?.data?.attributes?.code, preferredLanguages: getDefaultPreferredLanguages(context.locale, context.locales), }); if (selectedTranslation) { return { title: selectedTranslation.title, description: selectedTranslation.summary, }; } } } return { title: prettySlug(chronicle.chronicles.data[0].attributes.slug), description: undefined, }; })(); const thumbnail = chronicle.chronicles.data[0].attributes.translations.length === 0 ? chronicle.chronicles.data[0].attributes.contents?.data[0]?.attributes?.thumbnail?.data ?.attributes : undefined; const props: Props = { chronicle: chronicle.chronicles.data[0].attributes as ChronicleWithTranslations, chapters: chronicles.chroniclesChapters.data, openGraph: getOpenGraph(format, title, description, thumbnail), }; return { props: props, }; }; // ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ export const getStaticPaths: GetStaticPaths = async (context) => { const sdk = getReadySdk(); const contents = await sdk.getChroniclesSlugs(); const paths: GetStaticPathsResult["paths"] = []; filterHasAttributes(contents.chronicles?.data, ["attributes"]).map((wikiPage) => { context.locales?.map((local) => paths.push({ params: { slug: wikiPage.attributes.slug }, locale: local, }) ); }); return { paths, fallback: "blocking", }; };