OpenGraph support
This commit is contained in:
parent
74b77431a9
commit
7832b71f5c
|
@ -19,13 +19,13 @@ import {
|
||||||
isUndefined,
|
isUndefined,
|
||||||
iterateMap,
|
iterateMap,
|
||||||
} from "helpers/others";
|
} from "helpers/others";
|
||||||
import { getOgImage, ImageQuality } from "helpers/img";
|
import { prettyLanguage } from "helpers/formatters";
|
||||||
import { prettyLanguage, prettySlug } from "helpers/formatters";
|
|
||||||
import { cIf, cJoin } from "helpers/className";
|
import { cIf, cJoin } from "helpers/className";
|
||||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { UploadImageFragment } from "graphql/generated";
|
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
|
import { OpenGraph } from "helpers/openGraph";
|
||||||
|
import { getDefaultPreferredLanguages } from "helpers/locales";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -33,21 +33,20 @@ import { Button } from "components/Inputs/Button";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SENSIBILITY_SWIPE = 1.1;
|
const SENSIBILITY_SWIPE = 1.1;
|
||||||
const TITLE_PREFIX = "Accord’s Library";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
* ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
|
* ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
export interface AppLayoutRequired {
|
||||||
|
openGraph: OpenGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
subPanel?: React.ReactNode;
|
subPanel?: React.ReactNode;
|
||||||
subPanelIcon?: Icon;
|
subPanelIcon?: Icon;
|
||||||
contentPanel?: React.ReactNode;
|
contentPanel?: React.ReactNode;
|
||||||
title?: string;
|
|
||||||
navTitle: string | null | undefined;
|
|
||||||
thumbnail?: UploadImageFragment;
|
|
||||||
description?: string;
|
|
||||||
contentPanelScroolbar?: boolean;
|
contentPanelScroolbar?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,10 +58,7 @@ export const AppLayout = ({
|
||||||
languages,
|
languages,
|
||||||
subPanel,
|
subPanel,
|
||||||
contentPanel,
|
contentPanel,
|
||||||
thumbnail,
|
openGraph,
|
||||||
title,
|
|
||||||
navTitle,
|
|
||||||
description,
|
|
||||||
subPanelIcon = Icon.Tune,
|
subPanelIcon = Icon.Tune,
|
||||||
contentPanelScroolbar = true,
|
contentPanelScroolbar = true,
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
|
@ -136,33 +132,6 @@ export const AppLayout = ({
|
||||||
[contentPanel, subPanel]
|
[contentPanel, subPanel]
|
||||||
);
|
);
|
||||||
|
|
||||||
const metaImage = useMemo(
|
|
||||||
() =>
|
|
||||||
thumbnail
|
|
||||||
? getOgImage(ImageQuality.Og, thumbnail)
|
|
||||||
: {
|
|
||||||
image: "/default_og.jpg",
|
|
||||||
width: 1200,
|
|
||||||
height: 630,
|
|
||||||
alt: "Accord's Library Logo",
|
|
||||||
},
|
|
||||||
[thumbnail]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { ogTitle, metaTitle } = useMemo(() => {
|
|
||||||
const resultTitle =
|
|
||||||
title ?? navTitle ?? prettySlug(router.asPath.split("/").pop());
|
|
||||||
return {
|
|
||||||
ogTitle: resultTitle,
|
|
||||||
metaTitle: `${TITLE_PREFIX} - ${resultTitle}`,
|
|
||||||
};
|
|
||||||
}, [navTitle, router.asPath, title]);
|
|
||||||
|
|
||||||
const metaDescription = useMemo(
|
|
||||||
() => description ?? langui.default_description ?? "",
|
|
||||||
[description, langui.default_description]
|
|
||||||
);
|
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
document.getElementsByTagName("html")[0].style.fontSize = `${
|
document.getElementsByTagName("html")[0].style.fontSize = `${
|
||||||
(fontSize ?? 1) * 100
|
(fontSize ?? 1) * 100
|
||||||
|
@ -191,25 +160,13 @@ export const AppLayout = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (preferredLanguages) {
|
if (preferredLanguages) {
|
||||||
if (preferredLanguages.length === 0) {
|
if (preferredLanguages.length === 0) {
|
||||||
let defaultPreferredLanguages: string[] = [];
|
|
||||||
if (isDefinedAndNotEmpty(router.locale) && router.locales) {
|
if (isDefinedAndNotEmpty(router.locale) && router.locales) {
|
||||||
if (router.locale === "en") {
|
setPreferredLanguages(
|
||||||
defaultPreferredLanguages = [router.locale];
|
getDefaultPreferredLanguages(router.locale, router.locales)
|
||||||
router.locales.map((locale) => {
|
);
|
||||||
if (locale !== router.locale)
|
|
||||||
defaultPreferredLanguages.push(locale);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
defaultPreferredLanguages = [router.locale, "en"];
|
|
||||||
router.locales.map((locale) => {
|
|
||||||
if (locale !== router.locale && locale !== "en")
|
|
||||||
defaultPreferredLanguages.push(locale);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
setPreferredLanguages(defaultPreferredLanguages);
|
|
||||||
} else if (router.locale !== preferredLanguages[0]) {
|
} else if (router.locale !== preferredLanguages[0]) {
|
||||||
router.push(router.asPath, router.asPath, {
|
router.replace(router.asPath, router.asPath, {
|
||||||
locale: preferredLanguages[0],
|
locale: preferredLanguages[0],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -251,27 +208,36 @@ export const AppLayout = ({
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{metaTitle}</title>
|
<title>{openGraph.title}</title>
|
||||||
<meta name="description" content={metaDescription} />
|
<meta name="description" content={openGraph.description} />
|
||||||
|
|
||||||
<meta name="twitter:title" content={metaTitle}></meta>
|
<meta name="twitter:title" content={openGraph.title}></meta>
|
||||||
<meta name="twitter:description" content={metaDescription}></meta>
|
<meta
|
||||||
|
name="twitter:description"
|
||||||
|
content={openGraph.description}
|
||||||
|
></meta>
|
||||||
<meta name="twitter:card" content="summary_large_image"></meta>
|
<meta name="twitter:card" content="summary_large_image"></meta>
|
||||||
<meta name="twitter:image" content={metaImage.image}></meta>
|
<meta name="twitter:image" content={openGraph.thumbnail.image}></meta>
|
||||||
|
|
||||||
<meta property="og:title" content={metaTitle} />
|
<meta property="og:title" content={openGraph.title} />
|
||||||
<meta property="og:description" content={metaDescription} />
|
<meta property="og:description" content={openGraph.description} />
|
||||||
<meta property="og:image" content={metaImage.image}></meta>
|
<meta property="og:image" content={openGraph.thumbnail.image}></meta>
|
||||||
<meta property="og:image:secure_url" content={metaImage.image}></meta>
|
<meta
|
||||||
|
property="og:image:secure_url"
|
||||||
|
content={openGraph.thumbnail.image}
|
||||||
|
></meta>
|
||||||
<meta
|
<meta
|
||||||
property="og:image:width"
|
property="og:image:width"
|
||||||
content={metaImage.width.toString()}
|
content={openGraph.thumbnail.width.toString()}
|
||||||
></meta>
|
></meta>
|
||||||
<meta
|
<meta
|
||||||
property="og:image:height"
|
property="og:image:height"
|
||||||
content={metaImage.height.toString()}
|
content={openGraph.thumbnail.height.toString()}
|
||||||
|
></meta>
|
||||||
|
<meta
|
||||||
|
property="og:image:alt"
|
||||||
|
content={openGraph.thumbnail.alt}
|
||||||
></meta>
|
></meta>
|
||||||
<meta property="og:image:alt" content={metaImage.alt}></meta>
|
|
||||||
<meta property="og:image:type" content="image/jpeg"></meta>
|
<meta property="og:image:type" content="image/jpeg"></meta>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
|
@ -370,13 +336,13 @@ export const AppLayout = ({
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
"overflow-hidden text-center font-headers font-black",
|
"overflow-hidden text-center font-headers font-black",
|
||||||
cIf(
|
cIf(
|
||||||
ogTitle && ogTitle.length > 30,
|
openGraph.title.length > 30,
|
||||||
"max-h-14 text-xl",
|
"max-h-14 text-xl",
|
||||||
"max-h-16 text-2xl"
|
"max-h-16 text-2xl"
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{ogTitle}
|
{openGraph.title}
|
||||||
</p>
|
</p>
|
||||||
{isDefined(subPanel) && !turnSubIntoContent && (
|
{isDefined(subPanel) && !turnSubIntoContent && (
|
||||||
<Ico
|
<Ico
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback, useMemo } from "react";
|
||||||
import { AppLayout } from "./AppLayout";
|
import { AppLayout, AppLayoutRequired } from "./AppLayout";
|
||||||
import { Chip } from "./Chip";
|
import { Chip } from "./Chip";
|
||||||
import { HorizontalLine } from "./HorizontalLine";
|
import { HorizontalLine } from "./HorizontalLine";
|
||||||
import { Markdawn, TableOfContents } from "./Markdown/Markdawn";
|
import { Markdawn, TableOfContents } from "./Markdown/Markdawn";
|
||||||
|
@ -13,7 +13,6 @@ import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { PostWithTranslations } from "helpers/types";
|
import { PostWithTranslations } from "helpers/types";
|
||||||
import { filterHasAttributes, getStatusDescription } from "helpers/others";
|
import { filterHasAttributes, getStatusDescription } from "helpers/others";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { getDescription } from "helpers/description";
|
|
||||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -21,7 +20,7 @@ import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||||
* ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
|
* ───────────────────────────────────────╯ COMPONENT ╰───────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props {
|
interface Props extends AppLayoutRequired {
|
||||||
post: PostWithTranslations;
|
post: PostWithTranslations;
|
||||||
langui: AppStaticProps["langui"];
|
langui: AppStaticProps["langui"];
|
||||||
languages: AppStaticProps["languages"];
|
languages: AppStaticProps["languages"];
|
||||||
|
@ -52,7 +51,7 @@ export const PostPage = ({
|
||||||
appendBody,
|
appendBody,
|
||||||
prependBody,
|
prependBody,
|
||||||
displayTitle = true,
|
displayTitle = true,
|
||||||
currencies,
|
...otherProps
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] =
|
const [selectedTranslation, LanguageSwitcher, languageSwitcherProps] =
|
||||||
useSmartLanguage({
|
useSmartLanguage({
|
||||||
|
@ -221,16 +220,9 @@ export const PostPage = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={title}
|
{...otherProps}
|
||||||
description={getDescription({
|
|
||||||
langui: langui,
|
|
||||||
description: selectedTranslation?.excerpt,
|
|
||||||
categories: post.categories,
|
|
||||||
})}
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
thumbnail={thumbnail ?? undefined}
|
|
||||||
currencies={currencies}
|
|
||||||
languages={languages}
|
languages={languages}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
import { Chip } from "./Chip";
|
import { Chip } from "./Chip";
|
||||||
import { Ico, Icon } from "./Ico";
|
import { Ico, Icon } from "./Ico";
|
||||||
import { Img } from "./Img";
|
import { Img } from "./Img";
|
||||||
|
@ -41,7 +42,8 @@ interface Props {
|
||||||
stackNumber?: number;
|
stackNumber?: number;
|
||||||
metadata?: {
|
metadata?: {
|
||||||
currencies?: AppStaticProps["currencies"];
|
currencies?: AppStaticProps["currencies"];
|
||||||
release_date?: DatePickerFragment | null;
|
releaseDate?: DatePickerFragment | null;
|
||||||
|
releaseDateFormat?: Intl.DateTimeFormatOptions["dateStyle"];
|
||||||
price?: PricePickerFragment | null;
|
price?: PricePickerFragment | null;
|
||||||
views?: number;
|
views?: number;
|
||||||
author?: string;
|
author?: string;
|
||||||
|
@ -78,19 +80,20 @@ export const PreviewCard = ({
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { currency } = useAppLayout();
|
const { currency } = useAppLayout();
|
||||||
const isHoverable = useMediaHoverable();
|
const isHoverable = useMediaHoverable();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const metadataJSX = useMemo(
|
const metadataJSX = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<>
|
<>
|
||||||
{metadata && (metadata.release_date || metadata.price) && (
|
{metadata && (metadata.releaseDate || metadata.price) && (
|
||||||
<div className="flex w-full flex-row flex-wrap gap-x-3">
|
<div className="flex w-full flex-row flex-wrap gap-x-3">
|
||||||
{metadata.release_date && (
|
{metadata.releaseDate && (
|
||||||
<p className="text-sm mobile:text-xs">
|
<p className="text-sm mobile:text-xs">
|
||||||
<Ico
|
<Ico
|
||||||
icon={Icon.Event}
|
icon={Icon.Event}
|
||||||
className="mr-1 translate-y-[.15em] !text-base"
|
className="mr-1 translate-y-[.15em] !text-base"
|
||||||
/>
|
/>
|
||||||
{prettyDate(metadata.release_date)}
|
{prettyDate(metadata.releaseDate, router.locale)}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{metadata.price && metadata.currencies && (
|
{metadata.price && metadata.currencies && (
|
||||||
|
@ -124,7 +127,7 @@ export const PreviewCard = ({
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
[currency, metadata]
|
[currency, metadata, router.locale]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -278,7 +281,7 @@ export const PreviewCard = ({
|
||||||
{bottomChips && bottomChips.length > 0 && (
|
{bottomChips && bottomChips.length > 0 && (
|
||||||
<div
|
<div
|
||||||
className="grid grid-flow-col place-content-start gap-1 overflow-x-scroll
|
className="grid grid-flow-col place-content-start gap-1 overflow-x-scroll
|
||||||
[scrollbar-width:none] webkit-scrollbar:w-0"
|
[scrollbar-width:none] webkit-scrollbar:h-0"
|
||||||
>
|
>
|
||||||
{bottomChips.map((text, index) => (
|
{bottomChips.map((text, index) => (
|
||||||
<Chip key={index} className="text-sm" text={text} />
|
<Chip key={index} className="text-sm" text={text} />
|
||||||
|
|
|
@ -2,9 +2,18 @@ import { GetStaticProps } from "next";
|
||||||
import { AppStaticProps, getAppStaticProps } from "./getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "./getAppStaticProps";
|
||||||
import { getReadySdk } from "./sdk";
|
import { getReadySdk } from "./sdk";
|
||||||
import { PostWithTranslations } from "helpers/types";
|
import { PostWithTranslations } from "helpers/types";
|
||||||
|
import { OpenGraph, getOpenGraph } from "helpers/openGraph";
|
||||||
|
import { prettyDate, prettySlug } from "helpers/formatters";
|
||||||
|
import {
|
||||||
|
getDefaultPreferredLanguages,
|
||||||
|
staticSmartLanguage,
|
||||||
|
} from "helpers/locales";
|
||||||
|
import { filterHasAttributes, isDefined } from "helpers/others";
|
||||||
|
import { getDescription } from "helpers/description";
|
||||||
|
|
||||||
export interface PostStaticProps extends AppStaticProps {
|
export interface PostStaticProps extends AppStaticProps {
|
||||||
post: PostWithTranslations;
|
post: PostWithTranslations;
|
||||||
|
openGraph: OpenGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getPostStaticProps =
|
export const getPostStaticProps =
|
||||||
|
@ -15,10 +24,48 @@ export const getPostStaticProps =
|
||||||
slug: slug,
|
slug: slug,
|
||||||
language_code: context.locale ?? "en",
|
language_code: context.locale ?? "en",
|
||||||
});
|
});
|
||||||
if (post.posts?.data[0]?.attributes?.translations) {
|
if (
|
||||||
|
post.posts?.data &&
|
||||||
|
post.posts.data.length > 0 &&
|
||||||
|
post.posts.data[0].attributes?.translations &&
|
||||||
|
isDefined(context.locale) &&
|
||||||
|
isDefined(context.locales)
|
||||||
|
) {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
|
const selectedTranslation = staticSmartLanguage({
|
||||||
|
items: post.posts.data[0].attributes.translations,
|
||||||
|
languageExtractor: (item) => item.language?.data?.attributes?.code,
|
||||||
|
preferredLanguages: getDefaultPreferredLanguages(
|
||||||
|
context.locale,
|
||||||
|
context.locales
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const title = selectedTranslation?.title ?? prettySlug(slug);
|
||||||
|
|
||||||
|
const description = getDescription(selectedTranslation?.excerpt, {
|
||||||
|
[appStaticProps.langui.release_date ?? "Release date"]: [
|
||||||
|
prettyDate(post.posts.data[0].attributes.date, context.locale),
|
||||||
|
],
|
||||||
|
[appStaticProps.langui.categories ?? "Categories"]: filterHasAttributes(
|
||||||
|
post.posts.data[0].attributes.categories?.data,
|
||||||
|
["attributes"] as const
|
||||||
|
).map((category) => category.attributes.short),
|
||||||
|
});
|
||||||
|
|
||||||
|
const thumbnail =
|
||||||
|
selectedTranslation?.thumbnail?.data?.attributes ??
|
||||||
|
post.posts.data[0].attributes.thumbnail?.data?.attributes;
|
||||||
|
|
||||||
const props: PostStaticProps = {
|
const props: PostStaticProps = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
post: post.posts.data[0].attributes as PostWithTranslations,
|
post: post.posts.data[0].attributes as PostWithTranslations,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
thumbnail
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -20,19 +20,12 @@ query getWikiPage($slug: String, $language_code: String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tags(pagination: { limit: -1 }) {
|
tags {
|
||||||
data {
|
data {
|
||||||
id
|
id
|
||||||
attributes {
|
attributes {
|
||||||
slug
|
slug
|
||||||
titles(filters: { language: { code: { eq: $language_code } } }) {
|
titles(filters: { language: { code: { eq: $language_code } } }) {
|
||||||
language {
|
|
||||||
data {
|
|
||||||
attributes {
|
|
||||||
code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
import { isUndefined } from "./others";
|
||||||
import { DatePickerFragment } from "graphql/generated";
|
import { DatePickerFragment } from "graphql/generated";
|
||||||
|
|
||||||
export const compareDate = (
|
export const compareDate = (
|
||||||
a: DatePickerFragment,
|
a: DatePickerFragment | null | undefined,
|
||||||
b: DatePickerFragment
|
b: DatePickerFragment | null | undefined
|
||||||
): number => {
|
): number => {
|
||||||
|
if (isUndefined(a) || isUndefined(b)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const dateA = (a.year ?? 99999) * 365 + (a.month ?? 12) * 31 + (a.day ?? 31);
|
const dateA = (a.year ?? 99999) * 365 + (a.month ?? 12) * 31 + (a.day ?? 31);
|
||||||
const dateB = (b.year ?? 99999) * 365 + (b.month ?? 12) * 31 + (b.day ?? 31);
|
const dateB = (b.year ?? 99999) * 365 + (b.month ?? 12) * 31 + (b.day ?? 31);
|
||||||
return dateA - dateB;
|
return dateA - dateB;
|
||||||
|
|
|
@ -1,52 +1,28 @@
|
||||||
import { prettySlug } from "./formatters";
|
import { isDefined, isDefinedAndNotEmpty } from "./others";
|
||||||
import { isDefined } from "./others";
|
|
||||||
import { Content } from "./types";
|
|
||||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
|
||||||
|
|
||||||
interface Description {
|
export const getDescription = (
|
||||||
langui: AppStaticProps["langui"];
|
description: string | null | undefined,
|
||||||
description?: string | null | undefined;
|
chipsGroups?: Record<string, (string | undefined)[]>
|
||||||
type?: Content["type"];
|
): string => {
|
||||||
categories?: Content["categories"];
|
let result = "";
|
||||||
}
|
|
||||||
|
|
||||||
export const getDescription = ({
|
if (isDefinedAndNotEmpty(description)) {
|
||||||
langui,
|
result += prettyMarkdown(description);
|
||||||
description: text,
|
if (isDefined(chipsGroups)) {
|
||||||
type,
|
result += "\n\n";
|
||||||
categories,
|
}
|
||||||
}: Description): string => {
|
|
||||||
let description = "";
|
|
||||||
|
|
||||||
// TEXT
|
|
||||||
if (text) {
|
|
||||||
description += prettyMarkdown(text);
|
|
||||||
description += "\n\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TYPE
|
for (const key in chipsGroups) {
|
||||||
if (type?.data) {
|
if (Object.hasOwn(chipsGroups, key)) {
|
||||||
description += `${langui.type}: `;
|
const chipsGroup = chipsGroups[key];
|
||||||
|
if (chipsGroup.length > 0) {
|
||||||
description += `(${
|
result += `${key}: ${prettyChip(chipsGroup)}\n`;
|
||||||
type.data.attributes?.titles?.[0]?.title ??
|
}
|
||||||
prettySlug(type.data.attributes?.slug)
|
}
|
||||||
})`;
|
|
||||||
|
|
||||||
description += "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CATEGORIES
|
return result;
|
||||||
if (categories?.data && categories.data.length > 0) {
|
|
||||||
description += `${langui.categories}: `;
|
|
||||||
description += prettyChip(
|
|
||||||
categories.data.map((category) => category.attributes?.short)
|
|
||||||
);
|
|
||||||
|
|
||||||
description += "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return description;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const prettyMarkdown = (markdown: string): string =>
|
const prettyMarkdown = (markdown: string): string =>
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
import { AppStaticProps } from "../graphql/getAppStaticProps";
|
import { AppStaticProps } from "../graphql/getAppStaticProps";
|
||||||
import { convertPrice } from "./numbers";
|
import { convertPrice } from "./numbers";
|
||||||
import { isDefinedAndNotEmpty } from "./others";
|
import { isDefinedAndNotEmpty, isUndefined } from "./others";
|
||||||
import { DatePickerFragment, PricePickerFragment } from "graphql/generated";
|
import { DatePickerFragment, PricePickerFragment } from "graphql/generated";
|
||||||
|
|
||||||
export const prettyDate = (datePicker: DatePickerFragment): string => {
|
export const prettyDate = (
|
||||||
let result = "";
|
datePicker: DatePickerFragment,
|
||||||
if (datePicker.year) result += datePicker.year.toString();
|
locale = "en",
|
||||||
if (datePicker.month)
|
dateStyle: Intl.DateTimeFormatOptions["dateStyle"] = "medium"
|
||||||
result += `/${datePicker.month.toString().padStart(2, "0")}`;
|
): string =>
|
||||||
if (datePicker.day)
|
new Date(
|
||||||
result += `/${datePicker.day.toString().padStart(2, "0")}`;
|
datePicker.year ?? 0,
|
||||||
return result;
|
datePicker.month ?? 0,
|
||||||
};
|
datePicker.day ?? 1
|
||||||
|
).toLocaleString(locale, { dateStyle });
|
||||||
|
|
||||||
export const prettyPrice = (
|
export const prettyPrice = (
|
||||||
pricePicker: PricePickerFragment,
|
pricePicker: PricePickerFragment,
|
||||||
|
@ -19,19 +20,23 @@ export const prettyPrice = (
|
||||||
targetCurrencyCode?: string
|
targetCurrencyCode?: string
|
||||||
): string => {
|
): string => {
|
||||||
if (!targetCurrencyCode) return "";
|
if (!targetCurrencyCode) return "";
|
||||||
let result = "";
|
if (isUndefined(pricePicker.amount)) return "";
|
||||||
currencies.map((currency) => {
|
|
||||||
if (currency.attributes?.code === targetCurrencyCode) {
|
const targetCurrency = currencies.find(
|
||||||
const amountInTargetCurrency = convertPrice(pricePicker, currency);
|
(currency) => currency.attributes?.code === targetCurrencyCode
|
||||||
result =
|
);
|
||||||
currency.attributes.symbol +
|
|
||||||
amountInTargetCurrency.toLocaleString(undefined, {
|
if (targetCurrency?.attributes) {
|
||||||
minimumFractionDigits: currency.attributes.display_decimals ? 2 : 0,
|
const amountInTargetCurrency = convertPrice(pricePicker, targetCurrency);
|
||||||
maximumFractionDigits: currency.attributes.display_decimals ? 2 : 0,
|
return amountInTargetCurrency.toLocaleString("en", {
|
||||||
|
style: "currency",
|
||||||
|
currency: targetCurrency.attributes.code,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return pricePicker.amount.toLocaleString("en", {
|
||||||
|
style: "currency",
|
||||||
|
currency: pricePicker.currency?.data?.attributes?.code,
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prettySlug = (slug?: string, parentSlug?: string): string => {
|
export const prettySlug = (slug?: string, parentSlug?: string): string => {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { UploadImageFragment } from "graphql/generated";
|
|
||||||
|
|
||||||
export enum ImageQuality {
|
export enum ImageQuality {
|
||||||
Small = "small",
|
Small = "small",
|
||||||
Medium = "medium",
|
Medium = "medium",
|
||||||
|
@ -7,7 +5,7 @@ export enum ImageQuality {
|
||||||
Og = "og",
|
Og = "og",
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OgImage {
|
export interface OgImage {
|
||||||
image: string;
|
image: string;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
@ -65,20 +63,3 @@ export const getImgSizesByQuality = (
|
||||||
return { width: 0, height: 0 };
|
return { width: 0, height: 0 };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOgImage = (
|
|
||||||
quality: ImageQuality,
|
|
||||||
image: UploadImageFragment
|
|
||||||
): OgImage => {
|
|
||||||
const imgSize = getImgSizesByQuality(
|
|
||||||
image.width ?? 0,
|
|
||||||
image.height ?? 0,
|
|
||||||
quality
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
image: getAssetURL(image.url, quality),
|
|
||||||
width: imgSize.width,
|
|
||||||
height: imgSize.height,
|
|
||||||
alt: image.alternativeText ?? "",
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { isDefined } from "./others";
|
||||||
|
|
||||||
|
export const getDefaultPreferredLanguages = (
|
||||||
|
routerLocal: string,
|
||||||
|
locales: string[]
|
||||||
|
): string[] => {
|
||||||
|
let defaultPreferredLanguages: string[] = [];
|
||||||
|
if (routerLocal === "en") {
|
||||||
|
defaultPreferredLanguages = [routerLocal];
|
||||||
|
locales.map((locale) => {
|
||||||
|
if (locale !== routerLocal) defaultPreferredLanguages.push(locale);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
defaultPreferredLanguages = [routerLocal, "en"];
|
||||||
|
locales.map((locale) => {
|
||||||
|
if (locale !== routerLocal && locale !== "en")
|
||||||
|
defaultPreferredLanguages.push(locale);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return defaultPreferredLanguages;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPreferredLanguage = (
|
||||||
|
preferredLanguages: (string | undefined)[],
|
||||||
|
availableLanguages: Map<string, number>
|
||||||
|
): number | undefined => {
|
||||||
|
for (const locale of preferredLanguages) {
|
||||||
|
if (isDefined(locale) && availableLanguages.has(locale)) {
|
||||||
|
return availableLanguages.get(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface StaticSmartLanguageProps<T> {
|
||||||
|
items: T[];
|
||||||
|
preferredLanguages: string[];
|
||||||
|
languageExtractor: (item: NonNullable<T>) => string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const staticSmartLanguage = <T>({
|
||||||
|
languageExtractor,
|
||||||
|
preferredLanguages,
|
||||||
|
items,
|
||||||
|
}: StaticSmartLanguageProps<T>): T | undefined => {
|
||||||
|
for (const language of preferredLanguages) {
|
||||||
|
for (const item of items) {
|
||||||
|
if (isDefined(item) && languageExtractor(item) === language) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
|
@ -0,0 +1,51 @@
|
||||||
|
import {
|
||||||
|
OgImage,
|
||||||
|
getImgSizesByQuality,
|
||||||
|
ImageQuality,
|
||||||
|
getAssetURL,
|
||||||
|
} from "./img";
|
||||||
|
import { isDefinedAndNotEmpty } from "./others";
|
||||||
|
import { UploadImageFragment } from "graphql/generated";
|
||||||
|
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
|
||||||
|
const DEFAULT_OG_THUMBNAIL = {
|
||||||
|
image: `${process.env.NEXT_PUBLIC_URL_SELF}/default_og.jpg`,
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
alt: "Accord's Library Logo",
|
||||||
|
};
|
||||||
|
|
||||||
|
const TITLE_PREFIX = "Accord’s Library";
|
||||||
|
|
||||||
|
export interface OpenGraph {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
thumbnail: OgImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getOpenGraph = (
|
||||||
|
langui: AppStaticProps["langui"],
|
||||||
|
title: string,
|
||||||
|
description?: string | null | undefined,
|
||||||
|
thumbnail?: UploadImageFragment | null | undefined
|
||||||
|
): OpenGraph => ({
|
||||||
|
title: `${TITLE_PREFIX}${isDefinedAndNotEmpty(title) && ` - ${title}`}`,
|
||||||
|
description: isDefinedAndNotEmpty(description)
|
||||||
|
? description
|
||||||
|
: langui.default_description ?? "",
|
||||||
|
thumbnail: thumbnail ? getOgImage(thumbnail) : DEFAULT_OG_THUMBNAIL,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getOgImage = (image: UploadImageFragment): OgImage => {
|
||||||
|
const imgSize = getImgSizesByQuality(
|
||||||
|
image.width ?? 0,
|
||||||
|
image.height ?? 0,
|
||||||
|
ImageQuality.Og
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
image: getAssetURL(image.url, ImageQuality.Og),
|
||||||
|
width: imgSize.width,
|
||||||
|
height: imgSize.height,
|
||||||
|
alt: image.alternativeText ?? "",
|
||||||
|
};
|
||||||
|
};
|
|
@ -17,7 +17,7 @@ export interface PostWithTranslations extends Omit<Post, "translations"> {
|
||||||
|
|
||||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
export type Content = NonNullable<
|
type Content = NonNullable<
|
||||||
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
|
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { LanguageSwitcher } from "components/Inputs/LanguageSwitcher";
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { filterDefined, isDefined } from "helpers/others";
|
import { filterDefined, isDefined } from "helpers/others";
|
||||||
|
import { getPreferredLanguage } from "helpers/locales";
|
||||||
|
|
||||||
interface Props<T> {
|
interface Props<T> {
|
||||||
items: T[];
|
items: T[];
|
||||||
|
@ -12,18 +13,6 @@ interface Props<T> {
|
||||||
transform?: (item: NonNullable<T>) => NonNullable<T>;
|
transform?: (item: NonNullable<T>) => NonNullable<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPreferredLanguage = (
|
|
||||||
preferredLanguages: (string | undefined)[],
|
|
||||||
availableLanguages: Map<string, number>
|
|
||||||
): number | undefined => {
|
|
||||||
for (const locale of preferredLanguages) {
|
|
||||||
if (isDefined(locale) && availableLanguages.has(locale)) {
|
|
||||||
return availableLanguages.get(locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useSmartLanguage = <T>({
|
export const useSmartLanguage = <T>({
|
||||||
items,
|
items,
|
||||||
languageExtractor,
|
languageExtractor,
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import {
|
import {
|
||||||
ReturnButton,
|
ReturnButton,
|
||||||
ReturnButtonType,
|
ReturnButtonType,
|
||||||
} from "components/PanelComponents/ReturnButton";
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import { ContentPanel } from "components/Panels/ContentPanel";
|
import { ContentPanel } from "components/Panels/ContentPanel";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
|
|
||||||
const FourOhFour = ({ langui, ...otherProps }: Props): JSX.Element => (
|
const FourOhFour = ({
|
||||||
|
langui,
|
||||||
|
openGraph,
|
||||||
|
...otherProps
|
||||||
|
}: Props): JSX.Element => (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle="404"
|
|
||||||
contentPanel={
|
contentPanel={
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<h1>404 - {langui.page_not_found}</h1>
|
<h1>{openGraph.title}</h1>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/"
|
href="/"
|
||||||
title="Home"
|
title="Home"
|
||||||
|
@ -28,6 +32,7 @@ const FourOhFour = ({ langui, ...otherProps }: Props): JSX.Element => (
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
}
|
}
|
||||||
|
openGraph={openGraph}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
/>
|
/>
|
||||||
|
@ -40,8 +45,13 @@ export default FourOhFour;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
`404 - ${appStaticProps.langui.page_not_found}`
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import {
|
import {
|
||||||
ReturnButton,
|
ReturnButton,
|
||||||
ReturnButtonType,
|
ReturnButtonType,
|
||||||
} from "components/PanelComponents/ReturnButton";
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import { ContentPanel } from "components/Panels/ContentPanel";
|
import { ContentPanel } from "components/Panels/ContentPanel";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
|
|
||||||
const FiveHundred = ({ langui, ...otherProps }: Props): JSX.Element => (
|
const FiveHundred = ({
|
||||||
|
langui,
|
||||||
|
openGraph,
|
||||||
|
...otherProps
|
||||||
|
}: Props): JSX.Element => (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle="500"
|
|
||||||
contentPanel={
|
contentPanel={
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<h1>500 - Internal Server Error</h1>
|
<h1>{openGraph.title}</h1>
|
||||||
<ReturnButton
|
<ReturnButton
|
||||||
href="/"
|
href="/"
|
||||||
title="Home"
|
title="Home"
|
||||||
|
@ -28,6 +32,7 @@ const FiveHundred = ({ langui, ...otherProps }: Props): JSX.Element => (
|
||||||
/>
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
}
|
}
|
||||||
|
openGraph={openGraph}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
/>
|
/>
|
||||||
|
@ -40,8 +45,13 @@ export default FiveHundred;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
"500 - Internal Server Error"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -9,19 +9,11 @@ import {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const AccordsHandbook = ({
|
const AccordsHandbook = (props: PostStaticProps): JSX.Element => (
|
||||||
post,
|
|
||||||
langui,
|
|
||||||
languages,
|
|
||||||
currencies,
|
|
||||||
}: PostStaticProps): JSX.Element => (
|
|
||||||
<PostPage
|
<PostPage
|
||||||
currencies={currencies}
|
{...props}
|
||||||
languages={languages}
|
|
||||||
langui={langui}
|
|
||||||
post={post}
|
|
||||||
returnHref="/about-us/"
|
returnHref="/about-us/"
|
||||||
returnTitle={langui.about_us}
|
returnTitle={props.langui.about_us}
|
||||||
displayToc
|
displayToc
|
||||||
displayLanguageSwitcher
|
displayLanguageSwitcher
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -15,12 +15,7 @@ import { RequestMailProps, ResponseMailProps } from "pages/api/mail";
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const AboutUs = ({
|
const AboutUs = ({ langui, ...otherProps }: PostStaticProps): JSX.Element => {
|
||||||
post,
|
|
||||||
langui,
|
|
||||||
languages,
|
|
||||||
currencies,
|
|
||||||
}: PostStaticProps): JSX.Element => {
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [formResponse, setFormResponse] = useState("");
|
const [formResponse, setFormResponse] = useState("");
|
||||||
const [formState, setFormState] = useState<"completed" | "ongoing" | "stale">(
|
const [formState, setFormState] = useState<"completed" | "ongoing" | "stale">(
|
||||||
|
@ -177,10 +172,8 @@ const AboutUs = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostPage
|
<PostPage
|
||||||
currencies={currencies}
|
{...otherProps}
|
||||||
languages={languages}
|
|
||||||
langui={langui}
|
langui={langui}
|
||||||
post={post}
|
|
||||||
returnHref="/about-us/"
|
returnHref="/about-us/"
|
||||||
returnTitle={langui.about_us}
|
returnTitle={langui.about_us}
|
||||||
displayToc
|
displayToc
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
import { NavOption } from "components/PanelComponents/NavOption";
|
import { NavOption } from "components/PanelComponents/NavOption";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Panels/SubPanel";
|
import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
|
|
||||||
const AboutUs = ({ langui, ...otherProps }: Props): JSX.Element => (
|
const AboutUs = ({ langui, ...otherProps }: Props): JSX.Element => (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.about_us}
|
|
||||||
subPanel={
|
subPanel={
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
|
@ -49,8 +49,13 @@ export default AboutUs;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.about_us ?? "About us"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -9,19 +9,11 @@ import {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Legality = ({
|
const Legality = (props: PostStaticProps): JSX.Element => (
|
||||||
post,
|
|
||||||
langui,
|
|
||||||
languages,
|
|
||||||
currencies,
|
|
||||||
}: PostStaticProps): JSX.Element => (
|
|
||||||
<PostPage
|
<PostPage
|
||||||
currencies={currencies}
|
{...props}
|
||||||
languages={languages}
|
|
||||||
langui={langui}
|
|
||||||
post={post}
|
|
||||||
returnHref="/about-us/"
|
returnHref="/about-us/"
|
||||||
returnTitle={langui.about_us}
|
returnTitle={props.langui.about_us}
|
||||||
displayToc
|
displayToc
|
||||||
displayLanguageSwitcher
|
displayLanguageSwitcher
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -9,19 +9,11 @@ import {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const SharingPolicy = ({
|
const SharingPolicy = (props: PostStaticProps): JSX.Element => (
|
||||||
post,
|
|
||||||
langui,
|
|
||||||
languages,
|
|
||||||
currencies,
|
|
||||||
}: PostStaticProps): JSX.Element => (
|
|
||||||
<PostPage
|
<PostPage
|
||||||
currencies={currencies}
|
{...props}
|
||||||
languages={languages}
|
|
||||||
langui={langui}
|
|
||||||
post={post}
|
|
||||||
returnHref="/about-us/"
|
returnHref="/about-us/"
|
||||||
returnTitle={langui.about_us}
|
returnTitle={props.langui.about_us}
|
||||||
displayToc
|
displayToc
|
||||||
displayLanguageSwitcher
|
displayLanguageSwitcher
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { NavOption } from "components/PanelComponents/NavOption";
|
import { NavOption } from "components/PanelComponents/NavOption";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Panels/SubPanel";
|
import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
|
|
||||||
const Archives = ({ langui, ...otherProps }: Props): JSX.Element => {
|
const Archives = ({ langui, ...otherProps }: Props): JSX.Element => {
|
||||||
const subPanel = useMemo(
|
const subPanel = useMemo(
|
||||||
|
@ -28,14 +29,7 @@ const Archives = ({ langui, ...otherProps }: Props): JSX.Element => {
|
||||||
),
|
),
|
||||||
[langui]
|
[langui]
|
||||||
);
|
);
|
||||||
return (
|
return <AppLayout subPanel={subPanel} langui={langui} {...otherProps} />;
|
||||||
<AppLayout
|
|
||||||
navTitle={langui.archives}
|
|
||||||
subPanel={subPanel}
|
|
||||||
langui={langui}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export default Archives;
|
export default Archives;
|
||||||
|
|
||||||
|
@ -45,8 +39,13 @@ export default Archives;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.archives ?? "Archives"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { Fragment, useMemo } from "react";
|
import { Fragment, useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import {
|
import {
|
||||||
|
@ -22,13 +22,14 @@ import { useMediaHoverable } from "hooks/useMediaQuery";
|
||||||
import { WithLabel } from "components/Inputs/WithLabel";
|
import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
import { filterHasAttributes, isDefined } from "helpers/others";
|
import { filterHasAttributes, isDefined } from "helpers/others";
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
channel: NonNullable<
|
channel: NonNullable<
|
||||||
GetVideoChannelQuery["videoChannels"]
|
GetVideoChannelQuery["videoChannels"]
|
||||||
>["data"][number]["attributes"];
|
>["data"][number]["attributes"];
|
||||||
|
@ -91,7 +92,7 @@ const Channel = ({ langui, channel, ...otherProps }: Props): JSX.Element => {
|
||||||
thumbnailAspectRatio="16/9"
|
thumbnailAspectRatio="16/9"
|
||||||
keepInfoVisible={keepInfoVisible}
|
keepInfoVisible={keepInfoVisible}
|
||||||
metadata={{
|
metadata={{
|
||||||
release_date: video.attributes.published_date,
|
releaseDate: video.attributes.published_date,
|
||||||
views: video.attributes.views,
|
views: video.attributes.views,
|
||||||
author: channel?.title,
|
author: channel?.title,
|
||||||
position: "Top",
|
position: "Top",
|
||||||
|
@ -116,7 +117,6 @@ const Channel = ({ langui, channel, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.archives}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
@ -140,9 +140,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
: "",
|
: "",
|
||||||
});
|
});
|
||||||
if (!channel.videoChannels?.data[0].attributes) return { notFound: true };
|
if (!channel.videoChannels?.data[0].attributes) return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
channel: channel.videoChannels.data[0].attributes,
|
channel: channel.videoChannels.data[0].attributes,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
channel.videoChannels.data[0].attributes.title
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { SmartList } from "components/SmartList";
|
import { SmartList } from "components/SmartList";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
|
@ -20,11 +20,12 @@ import { PreviewCard } from "components/PreviewCard";
|
||||||
import { GetVideosPreviewQuery } from "graphql/generated";
|
import { GetVideosPreviewQuery } from "graphql/generated";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { prettyDate } from "helpers/formatters";
|
|
||||||
import { filterHasAttributes } from "helpers/others";
|
import { filterHasAttributes } from "helpers/others";
|
||||||
import { getVideoThumbnailURL } from "helpers/videos";
|
import { getVideoThumbnailURL } from "helpers/videos";
|
||||||
import { useMediaHoverable } from "hooks/useMediaQuery";
|
import { useMediaHoverable } from "hooks/useMediaQuery";
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import { compareDate } from "helpers/date";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -40,7 +41,7 @@ const DEFAULT_FILTERS_STATE = {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
videos: NonNullable<GetVideosPreviewQuery["videos"]>["data"];
|
videos: NonNullable<GetVideosPreviewQuery["videos"]>["data"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ const Videos = ({ langui, videos, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
className="mb-6 w-full"
|
||||||
placeholder={langui.search_title ?? undefined}
|
placeholder={langui.search_title ?? "Search title..."}
|
||||||
value={searchName}
|
value={searchName}
|
||||||
onChange={setSearchName}
|
onChange={setSearchName}
|
||||||
/>
|
/>
|
||||||
|
@ -107,7 +108,7 @@ const Videos = ({ langui, videos, ...otherProps }: Props): JSX.Element => {
|
||||||
thumbnailForceAspectRatio
|
thumbnailForceAspectRatio
|
||||||
keepInfoVisible={keepInfoVisible}
|
keepInfoVisible={keepInfoVisible}
|
||||||
metadata={{
|
metadata={{
|
||||||
release_date: item.attributes.published_date,
|
releaseDate: item.attributes.published_date,
|
||||||
views: item.attributes.views,
|
views: item.attributes.views,
|
||||||
author: item.attributes.channel?.data?.attributes?.title,
|
author: item.attributes.channel?.data?.attributes?.title,
|
||||||
position: "Top",
|
position: "Top",
|
||||||
|
@ -132,7 +133,6 @@ const Videos = ({ langui, videos, ...otherProps }: Props): JSX.Element => {
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.archives}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
@ -152,19 +152,18 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
const videos = await sdk.getVideosPreview();
|
const videos = await sdk.getVideosPreview();
|
||||||
if (!videos.videos) return { notFound: true };
|
if (!videos.videos) return { notFound: true };
|
||||||
videos.videos.data
|
videos.videos.data
|
||||||
.sort((a, b) => {
|
.sort((a, b) =>
|
||||||
const dateA = a.attributes?.published_date
|
compareDate(a.attributes?.published_date, b.attributes?.published_date)
|
||||||
? prettyDate(a.attributes.published_date)
|
)
|
||||||
: "9999";
|
|
||||||
const dateB = b.attributes?.published_date
|
|
||||||
? prettyDate(b.attributes.published_date)
|
|
||||||
: "9999";
|
|
||||||
return dateA.localeCompare(dateB);
|
|
||||||
})
|
|
||||||
.reverse();
|
.reverse();
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
videos: videos.videos.data,
|
videos: videos.videos.data,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.videos ?? "Videos"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { useRouter } from "next/router";
|
||||||
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { Ico, Icon } from "components/Ico";
|
import { Ico, Icon } from "components/Ico";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
|
@ -23,13 +24,14 @@ import { prettyDate, prettyShortenNumber } from "helpers/formatters";
|
||||||
import { filterHasAttributes, isDefined } from "helpers/others";
|
import { filterHasAttributes, isDefined } from "helpers/others";
|
||||||
import { getVideoFile } from "helpers/videos";
|
import { getVideoFile } from "helpers/videos";
|
||||||
import { useMediaMobile } from "hooks/useMediaQuery";
|
import { useMediaMobile } from "hooks/useMediaQuery";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
video: NonNullable<
|
video: NonNullable<
|
||||||
NonNullable<GetVideoQuery["videos"]>["data"][number]["attributes"]
|
NonNullable<GetVideoQuery["videos"]>["data"][number]["attributes"]
|
||||||
>;
|
>;
|
||||||
|
@ -38,6 +40,8 @@ interface Props extends AppStaticProps {
|
||||||
const Video = ({ langui, video, ...otherProps }: Props): JSX.Element => {
|
const Video = ({ langui, video, ...otherProps }: Props): JSX.Element => {
|
||||||
const isMobile = useMediaMobile();
|
const isMobile = useMediaMobile();
|
||||||
const { setSubPanelOpen } = useAppLayout();
|
const { setSubPanelOpen } = useAppLayout();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const subPanel = useMemo(
|
const subPanel = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
|
@ -118,7 +122,7 @@ const Video = ({ langui, video, ...otherProps }: Props): JSX.Element => {
|
||||||
icon={Icon.Event}
|
icon={Icon.Event}
|
||||||
className="mr-1 translate-y-[.15em] !text-base"
|
className="mr-1 translate-y-[.15em] !text-base"
|
||||||
/>
|
/>
|
||||||
{prettyDate(video.published_date)}
|
{prettyDate(video.published_date, router.locale)}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<Ico
|
<Ico
|
||||||
|
@ -184,6 +188,7 @@ const Video = ({ langui, video, ...otherProps }: Props): JSX.Element => {
|
||||||
[
|
[
|
||||||
isMobile,
|
isMobile,
|
||||||
langui,
|
langui,
|
||||||
|
router.locale,
|
||||||
video.channel?.data?.attributes,
|
video.channel?.data?.attributes,
|
||||||
video.description,
|
video.description,
|
||||||
video.gone,
|
video.gone,
|
||||||
|
@ -198,7 +203,6 @@ const Video = ({ langui, video, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.archives}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
@ -222,9 +226,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
: "",
|
: "",
|
||||||
});
|
});
|
||||||
if (!videos.videos?.data[0]?.attributes) return { notFound: true };
|
if (!videos.videos?.data[0]?.attributes) return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
video: videos.videos.data[0].attributes,
|
video: videos.videos.data[0].attributes,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
videos.videos.data[0].attributes.title
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { isDefined, filterHasAttributes } from "helpers/others";
|
import { isDefined, filterHasAttributes } from "helpers/others";
|
||||||
import { ChronicleWithTranslations } from "helpers/types";
|
import { ChronicleWithTranslations } from "helpers/types";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { ContentPanel } from "components/Panels/ContentPanel";
|
import { ContentPanel } from "components/Panels/ContentPanel";
|
||||||
import { Markdawn } from "components/Markdown/Markdawn";
|
import { Markdawn } from "components/Markdown/Markdawn";
|
||||||
|
@ -12,20 +12,26 @@ import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { ThumbnailHeader } from "components/ThumbnailHeader";
|
import { ThumbnailHeader } from "components/ThumbnailHeader";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { GetChroniclesChaptersQuery } from "graphql/generated";
|
import { GetChroniclesChaptersQuery } from "graphql/generated";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettyInlineTitle, prettySlug } from "helpers/formatters";
|
||||||
import {
|
import {
|
||||||
ReturnButton,
|
ReturnButton,
|
||||||
ReturnButtonType,
|
ReturnButtonType,
|
||||||
} from "components/PanelComponents/ReturnButton";
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import { TranslatedChroniclesList } from "components/Translated";
|
import { TranslatedChroniclesList } from "components/Translated";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import {
|
||||||
|
getDefaultPreferredLanguages,
|
||||||
|
staticSmartLanguage,
|
||||||
|
} from "helpers/locales";
|
||||||
|
import { getDescription } from "helpers/description";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
chronicle: ChronicleWithTranslations;
|
chronicle: ChronicleWithTranslations;
|
||||||
chapters: NonNullable<
|
chapters: NonNullable<
|
||||||
GetChroniclesChaptersQuery["chroniclesChapters"]
|
GetChroniclesChaptersQuery["chroniclesChapters"]
|
||||||
|
@ -191,7 +197,6 @@ const Chronicle = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.chronicles}
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
@ -220,15 +225,92 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
});
|
});
|
||||||
const chronicles = await sdk.getChroniclesChapters();
|
const chronicles = await sdk.getChroniclesChapters();
|
||||||
if (
|
if (
|
||||||
!chronicle.chronicles?.data[0].attributes?.translations ||
|
!chronicle.chronicles?.data[0]?.attributes?.translations ||
|
||||||
!chronicles.chroniclesChapters?.data
|
!chronicles.chroniclesChapters?.data
|
||||||
)
|
)
|
||||||
return { notFound: true };
|
return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
|
|
||||||
|
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,
|
||||||
|
{
|
||||||
|
[appStaticProps.langui.type ?? "Type"]: [
|
||||||
|
chronicle.chronicles.data[0].attributes.contents.data[0]
|
||||||
|
.attributes.type?.data?.attributes?.titles?.[0]?.title,
|
||||||
|
],
|
||||||
|
[appStaticProps.langui.categories ?? "Categories"]:
|
||||||
|
filterHasAttributes(
|
||||||
|
chronicle.chronicles.data[0].attributes.contents.data[0]
|
||||||
|
.attributes.categories?.data,
|
||||||
|
["attributes"] as const
|
||||||
|
).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 = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
chronicle: chronicle.chronicles.data[0]
|
chronicle: chronicle.chronicles.data[0]
|
||||||
.attributes as ChronicleWithTranslations,
|
.attributes as ChronicleWithTranslations,
|
||||||
chapters: chronicles.chroniclesChapters.data,
|
chapters: chronicles.chroniclesChapters.data,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
thumbnail
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Panels/SubPanel";
|
import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
@ -10,13 +10,14 @@ import { GetChroniclesChaptersQuery } from "graphql/generated";
|
||||||
import { filterHasAttributes } from "helpers/others";
|
import { filterHasAttributes } from "helpers/others";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { TranslatedChroniclesList } from "components/Translated";
|
import { TranslatedChroniclesList } from "components/Translated";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
chapters: NonNullable<
|
chapters: NonNullable<
|
||||||
GetChroniclesChaptersQuery["chroniclesChapters"]
|
GetChroniclesChaptersQuery["chroniclesChapters"]
|
||||||
>["data"];
|
>["data"];
|
||||||
|
@ -58,14 +59,7 @@ const Chronicles = ({
|
||||||
[chapters, langui]
|
[chapters, langui]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return <AppLayout subPanel={subPanel} langui={langui} {...otherProps} />;
|
||||||
<AppLayout
|
|
||||||
navTitle={langui.chronicles}
|
|
||||||
subPanel={subPanel}
|
|
||||||
langui={langui}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export default Chronicles;
|
export default Chronicles;
|
||||||
|
|
||||||
|
@ -78,9 +72,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const chronicles = await sdk.getChroniclesChapters();
|
const chronicles = await sdk.getChroniclesChapters();
|
||||||
if (!chronicles.chroniclesChapters?.data) return { notFound: true };
|
if (!chronicles.chroniclesChapters?.data) return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
chapters: chronicles.chroniclesChapters.data,
|
chapters: chronicles.chroniclesChapters.data,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.chronicles ?? "Chronicles"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback, useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
|
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
|
||||||
|
@ -17,7 +17,6 @@ import { ThumbnailHeader } from "components/ThumbnailHeader";
|
||||||
import { ToolTip } from "components/ToolTip";
|
import { ToolTip } from "components/ToolTip";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { getDescription } from "helpers/description";
|
|
||||||
import {
|
import {
|
||||||
prettyInlineTitle,
|
prettyInlineTitle,
|
||||||
prettyLanguage,
|
prettyLanguage,
|
||||||
|
@ -35,13 +34,19 @@ import { useMediaMobile } from "hooks/useMediaQuery";
|
||||||
import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
||||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { TranslatedPreviewLine } from "components/Translated";
|
import { TranslatedPreviewLine } from "components/Translated";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import {
|
||||||
|
getDefaultPreferredLanguages,
|
||||||
|
staticSmartLanguage,
|
||||||
|
} from "helpers/locales";
|
||||||
|
import { getDescription } from "helpers/description";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
content: ContentWithTranslations;
|
content: ContentWithTranslations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +265,7 @@ const Content = ({
|
||||||
).map((category) => category.attributes.short)}
|
).map((category) => category.attributes.short)}
|
||||||
metadata={{
|
metadata={{
|
||||||
currencies: currencies,
|
currencies: currencies,
|
||||||
release_date: libraryItem.attributes.release_date,
|
releaseDate: libraryItem.attributes.release_date,
|
||||||
price: libraryItem.attributes.price,
|
price: libraryItem.attributes.price,
|
||||||
position: "Bottom",
|
position: "Bottom",
|
||||||
}}
|
}}
|
||||||
|
@ -457,22 +462,6 @@ const Content = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={
|
|
||||||
selectedTranslation
|
|
||||||
? prettyInlineTitle(
|
|
||||||
selectedTranslation.pre_title,
|
|
||||||
selectedTranslation.title,
|
|
||||||
selectedTranslation.subtitle
|
|
||||||
)
|
|
||||||
: prettySlug(content.slug)
|
|
||||||
}
|
|
||||||
description={getDescription({
|
|
||||||
langui: langui,
|
|
||||||
description: selectedTranslation?.description,
|
|
||||||
type: content.type,
|
|
||||||
categories: content.categories,
|
|
||||||
})}
|
|
||||||
thumbnail={content.thumbnail?.data?.attributes ?? undefined}
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
currencies={currencies}
|
currencies={currencies}
|
||||||
|
@ -500,9 +489,57 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
if (!content.contents?.data[0]?.attributes?.translations) {
|
if (!content.contents?.data[0]?.attributes?.translations) {
|
||||||
return { notFound: true };
|
return { notFound: true };
|
||||||
}
|
}
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
|
|
||||||
|
const { title, description } = (() => {
|
||||||
|
if (context.locale && context.locales) {
|
||||||
|
const selectedTranslation = staticSmartLanguage({
|
||||||
|
items: content.contents.data[0].attributes.translations,
|
||||||
|
languageExtractor: (item) => item.language?.data?.attributes?.code,
|
||||||
|
preferredLanguages: getDefaultPreferredLanguages(
|
||||||
|
context.locale,
|
||||||
|
context.locales
|
||||||
|
),
|
||||||
|
});
|
||||||
|
if (selectedTranslation) {
|
||||||
|
return {
|
||||||
|
title: prettyInlineTitle(
|
||||||
|
selectedTranslation.pre_title,
|
||||||
|
selectedTranslation.title,
|
||||||
|
selectedTranslation.subtitle
|
||||||
|
),
|
||||||
|
description: getDescription(selectedTranslation.description, {
|
||||||
|
[appStaticProps.langui.type ?? "Type"]: [
|
||||||
|
content.contents.data[0].attributes.type?.data?.attributes
|
||||||
|
?.titles?.[0]?.title,
|
||||||
|
],
|
||||||
|
[appStaticProps.langui.categories ?? "Categories"]:
|
||||||
|
filterHasAttributes(
|
||||||
|
content.contents.data[0].attributes.categories?.data,
|
||||||
|
["attributes"] as const
|
||||||
|
).map((category) => category.attributes.short),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
title: prettySlug(content.contents.data[0].attributes.slug),
|
||||||
|
description: undefined,
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
const thumbnail =
|
||||||
|
content.contents.data[0].attributes.thumbnail?.data?.attributes;
|
||||||
|
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
content: content.contents.data[0].attributes as ContentWithTranslations,
|
content: content.contents.data[0].attributes as ContentWithTranslations,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
thumbnail
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useState, useMemo, useCallback } from "react";
|
import { useState, useMemo, useCallback } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Select } from "components/Inputs/Select";
|
import { Select } from "components/Inputs/Select";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
|
@ -23,6 +23,7 @@ import { SmartList } from "components/SmartList";
|
||||||
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
import { TranslatedPreviewCard } from "components/Translated";
|
import { TranslatedPreviewCard } from "components/Translated";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -41,7 +42,7 @@ const DEFAULT_FILTERS_STATE = {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
contents: NonNullable<GetContentsQuery["contents"]>["data"];
|
contents: NonNullable<GetContentsQuery["contents"]>["data"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +165,7 @@ const Contents = ({
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
className="mb-6 w-full"
|
||||||
placeholder={langui.search_title ?? undefined}
|
placeholder={langui.search_title ?? "Search..."}
|
||||||
value={searchName}
|
value={searchName}
|
||||||
onChange={setSearchName}
|
onChange={setSearchName}
|
||||||
/>
|
/>
|
||||||
|
@ -174,7 +175,7 @@ const Contents = ({
|
||||||
input={
|
input={
|
||||||
<Select
|
<Select
|
||||||
className="w-full"
|
className="w-full"
|
||||||
options={[langui.category ?? "", langui.type ?? ""]}
|
options={[langui.category ?? "Category", langui.type ?? "Type"]}
|
||||||
value={groupingMethod}
|
value={groupingMethod}
|
||||||
onChange={setGroupingMethod}
|
onChange={setGroupingMethod}
|
||||||
allowEmpty
|
allowEmpty
|
||||||
|
@ -317,7 +318,6 @@ const Contents = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.contents}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanelIcon={Icon.Search}
|
subPanelIcon={Icon.Search}
|
||||||
|
@ -346,9 +346,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
return titleA.localeCompare(titleB);
|
return titleA.localeCompare(titleB);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
contents: contents.contents.data,
|
contents: contents.contents.data,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.contents ?? "Contents"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import {
|
import {
|
||||||
|
@ -13,13 +13,14 @@ import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { filterDefined, filterHasAttributes } from "helpers/others";
|
import { filterDefined, filterHasAttributes } from "helpers/others";
|
||||||
import { Report, Severity } from "helpers/types/Report";
|
import { Report, Severity } from "helpers/types/Report";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
contents: DevGetContentsQuery;
|
contents: DevGetContentsQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,13 +88,7 @@ const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
[testReport.lines, testReport.title]
|
[testReport.lines, testReport.title]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
||||||
<AppLayout
|
|
||||||
navTitle={"Checkup"}
|
|
||||||
contentPanel={contentPanel}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export default CheckupContents;
|
export default CheckupContents;
|
||||||
|
|
||||||
|
@ -105,9 +100,11 @@ export default CheckupContents;
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const contents = await sdk.devGetContents();
|
const contents = await sdk.devGetContents();
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
contents: contents,
|
contents: contents,
|
||||||
|
openGraph: getOpenGraph(appStaticProps.langui, "Checkup Contents"),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import {
|
import {
|
||||||
|
@ -15,13 +15,14 @@ import {
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { Report, Severity } from "helpers/types/Report";
|
import { Report, Severity } from "helpers/types/Report";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
libraryItems: DevGetLibraryItemsQuery;
|
libraryItems: DevGetLibraryItemsQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,13 +93,7 @@ const CheckupLibraryItems = ({
|
||||||
[testReport.lines, testReport.title]
|
[testReport.lines, testReport.title]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
||||||
<AppLayout
|
|
||||||
navTitle={"Checkup"}
|
|
||||||
contentPanel={contentPanel}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
export default CheckupLibraryItems;
|
export default CheckupLibraryItems;
|
||||||
|
|
||||||
|
@ -110,9 +105,11 @@ export default CheckupLibraryItems;
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const libraryItems = await sdk.devGetLibraryItems();
|
const libraryItems = await sdk.devGetLibraryItems();
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
libraryItems: libraryItems,
|
libraryItems: libraryItems,
|
||||||
|
openGraph: getOpenGraph(appStaticProps.langui, "Checkup Library Items"),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useMemo, useRef, useState } from "react";
|
||||||
import TurndownService from "turndown";
|
import TurndownService from "turndown";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import { Markdawn, TableOfContents } from "components/Markdown/Markdawn";
|
import { Markdawn, TableOfContents } from "components/Markdown/Markdawn";
|
||||||
import {
|
import {
|
||||||
|
@ -12,13 +12,14 @@ import { Popup } from "components/Popup";
|
||||||
import { ToolTip } from "components/ToolTip";
|
import { ToolTip } from "components/ToolTip";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
|
|
||||||
const Editor = ({ langui, ...otherProps }: Props): JSX.Element => {
|
const Editor = ({ langui, ...otherProps }: Props): JSX.Element => {
|
||||||
const handleInput = useCallback((text: string) => {
|
const handleInput = useCallback((text: string) => {
|
||||||
|
@ -465,12 +466,7 @@ const Editor = ({ langui, ...otherProps }: Props): JSX.Element => {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout contentPanel={contentPanel} langui={langui} {...otherProps} />
|
||||||
navTitle="Markdawn Editor"
|
|
||||||
contentPanel={contentPanel}
|
|
||||||
langui={langui}
|
|
||||||
{...otherProps}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default Editor;
|
export default Editor;
|
||||||
|
@ -481,8 +477,10 @@ export default Editor;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(appStaticProps.langui, "Markdawn Editor"),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useMemo, useRef, useState } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
import { ButtonGroup } from "components/Inputs/ButtonGroup";
|
import { ButtonGroup } from "components/Inputs/ButtonGroup";
|
||||||
import {
|
import {
|
||||||
|
@ -9,6 +9,7 @@ import {
|
||||||
} from "components/Panels/ContentPanel";
|
} from "components/Panels/ContentPanel";
|
||||||
import { ToolTip } from "components/ToolTip";
|
import { ToolTip } from "components/ToolTip";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -22,7 +23,7 @@ const SIZE_MULTIPLIER = 1000;
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
|
|
||||||
const replaceSelection = (
|
const replaceSelection = (
|
||||||
text: string,
|
text: string,
|
||||||
|
@ -566,7 +567,6 @@ const Transcript = (props: Props): JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle="Transcript"
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
{...props}
|
{...props}
|
||||||
contentPanelScroolbar={false}
|
contentPanelScroolbar={false}
|
||||||
|
@ -581,8 +581,13 @@ export default Transcript;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
"Japanese Transcription Tool"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -9,17 +9,9 @@ import {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Home = ({
|
const Home = (props: PostStaticProps): JSX.Element => (
|
||||||
post,
|
|
||||||
langui,
|
|
||||||
languages,
|
|
||||||
currencies,
|
|
||||||
}: PostStaticProps): JSX.Element => (
|
|
||||||
<PostPage
|
<PostPage
|
||||||
currencies={currencies}
|
{...props}
|
||||||
languages={languages}
|
|
||||||
langui={langui}
|
|
||||||
post={post}
|
|
||||||
prependBody={
|
prependBody={
|
||||||
<div className="grid w-full place-content-center place-items-center gap-5 text-center">
|
<div className="grid w-full place-content-center place-items-center gap-5 text-center">
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Fragment, useCallback, useMemo } from "react";
|
import { Fragment, useCallback, useMemo } from "react";
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { useRouter } from "next/router";
|
||||||
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { Img } from "components/Img";
|
import { Img } from "components/Img";
|
||||||
import { Button } from "components/Inputs/Button";
|
import { Button } from "components/Inputs/Button";
|
||||||
|
@ -52,15 +53,16 @@ import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
import { Ico, Icon } from "components/Ico";
|
import { Ico, Icon } from "components/Ico";
|
||||||
import { cJoin, cIf } from "helpers/className";
|
import { cJoin, cIf } from "helpers/className";
|
||||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { getDescription } from "helpers/description";
|
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import { getDescription } from "helpers/description";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
item: NonNullable<
|
item: NonNullable<
|
||||||
NonNullable<
|
NonNullable<
|
||||||
GetLibraryItemQuery["libraryItems"]
|
GetLibraryItemQuery["libraryItems"]
|
||||||
|
@ -81,6 +83,7 @@ const LibrarySlug = ({
|
||||||
}: Props): JSX.Element => {
|
}: Props): JSX.Element => {
|
||||||
const { currency } = useAppLayout();
|
const { currency } = useAppLayout();
|
||||||
const hoverable = useMediaHoverable();
|
const hoverable = useMediaHoverable();
|
||||||
|
const router = useRouter();
|
||||||
const [openLightBox, LightBox] = useLightBox();
|
const [openLightBox, LightBox] = useLightBox();
|
||||||
const { state: keepInfoVisible, toggleState: toggleKeepInfoVisible } =
|
const { state: keepInfoVisible, toggleState: toggleKeepInfoVisible } =
|
||||||
useBoolean(false);
|
useBoolean(false);
|
||||||
|
@ -300,7 +303,7 @@ const LibrarySlug = ({
|
||||||
{item.release_date && (
|
{item.release_date && (
|
||||||
<div className="grid place-content-start place-items-center">
|
<div className="grid place-content-start place-items-center">
|
||||||
<h3 className="text-xl">{langui.release_date}</h3>
|
<h3 className="text-xl">{langui.release_date}</h3>
|
||||||
<p>{prettyDate(item.release_date)}</p>
|
<p>{prettyDate(item.release_date, router.locale)}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -483,7 +486,7 @@ const LibrarySlug = ({
|
||||||
)}
|
)}
|
||||||
metadata={{
|
metadata={{
|
||||||
currencies: currencies,
|
currencies: currencies,
|
||||||
release_date: subitem.attributes.release_date,
|
releaseDate: subitem.attributes.release_date,
|
||||||
price: subitem.attributes.price,
|
price: subitem.attributes.price,
|
||||||
position: "Bottom",
|
position: "Bottom",
|
||||||
}}
|
}}
|
||||||
|
@ -569,8 +572,23 @@ const LibrarySlug = ({
|
||||||
[
|
[
|
||||||
LightBox,
|
LightBox,
|
||||||
langui,
|
langui,
|
||||||
item,
|
item.thumbnail?.data?.attributes,
|
||||||
|
item.subitem_of?.data,
|
||||||
|
item.title,
|
||||||
|
item.subtitle,
|
||||||
|
item.metadata,
|
||||||
|
item.descriptions,
|
||||||
|
item.urls,
|
||||||
|
item.gallery,
|
||||||
|
item.release_date,
|
||||||
|
item.price,
|
||||||
|
item.categories,
|
||||||
|
item.size,
|
||||||
|
item.subitems,
|
||||||
|
item.contents,
|
||||||
|
item.slug,
|
||||||
itemId,
|
itemId,
|
||||||
|
router.locale,
|
||||||
currencies,
|
currencies,
|
||||||
currency,
|
currency,
|
||||||
isVariantSet,
|
isVariantSet,
|
||||||
|
@ -585,14 +603,8 @@ const LibrarySlug = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={prettyInlineTitle("", item.title, item.subtitle)}
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
thumbnail={item.thumbnail?.data?.attributes ?? undefined}
|
|
||||||
description={getDescription({
|
|
||||||
langui,
|
|
||||||
description: item.descriptions?.[0]?.description,
|
|
||||||
})}
|
|
||||||
currencies={currencies}
|
currencies={currencies}
|
||||||
languages={languages}
|
languages={languages}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
@ -618,10 +630,42 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
});
|
});
|
||||||
if (!item.libraryItems?.data[0]?.attributes) return { notFound: true };
|
if (!item.libraryItems?.data[0]?.attributes) return { notFound: true };
|
||||||
sortRangedContent(item.libraryItems.data[0].attributes.contents);
|
sortRangedContent(item.libraryItems.data[0].attributes.contents);
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
|
|
||||||
|
const { title, thumbnail } = item.libraryItems.data[0].attributes;
|
||||||
|
|
||||||
|
const description = getDescription(
|
||||||
|
item.libraryItems.data[0].attributes.descriptions?.[0]?.description,
|
||||||
|
{
|
||||||
|
[appStaticProps.langui.categories ?? "Categories"]: filterHasAttributes(
|
||||||
|
item.libraryItems.data[0].attributes.categories?.data,
|
||||||
|
["attributes.short"]
|
||||||
|
).map((category) => category.attributes.short),
|
||||||
|
[appStaticProps.langui.type ?? "Type"]: item.libraryItems.data[0]
|
||||||
|
.attributes.metadata?.[0]
|
||||||
|
? [prettyItemSubType(item.libraryItems.data[0].attributes.metadata[0])]
|
||||||
|
: [],
|
||||||
|
[appStaticProps.langui.release_date ?? "Release date"]: [
|
||||||
|
item.libraryItems.data[0].attributes.release_date
|
||||||
|
? prettyDate(
|
||||||
|
item.libraryItems.data[0].attributes.release_date,
|
||||||
|
context.locale
|
||||||
|
)
|
||||||
|
: undefined,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
item: item.libraryItems.data[0].attributes,
|
item: item.libraryItems.data[0].attributes,
|
||||||
itemId: item.libraryItems.data[0].id,
|
itemId: item.libraryItems.data[0].id,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
thumbnail?.data?.attributes
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { Fragment, useMemo } from "react";
|
import { Fragment, useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { ScanSetCover } from "components/Library/ScanSetCover";
|
import { ScanSetCover } from "components/Library/ScanSetCover";
|
||||||
import {
|
import {
|
||||||
ReturnButton,
|
ReturnButton,
|
||||||
|
@ -30,13 +30,14 @@ import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
|
||||||
import { PreviewCard } from "components/PreviewCard";
|
import { PreviewCard } from "components/PreviewCard";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { TranslatedNavOption, TranslatedScanSet } from "components/Translated";
|
import { TranslatedNavOption, TranslatedScanSet } from "components/Translated";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
item: NonNullable<
|
item: NonNullable<
|
||||||
NonNullable<
|
NonNullable<
|
||||||
GetLibraryItemScansQuery["libraryItems"]
|
GetLibraryItemScansQuery["libraryItems"]
|
||||||
|
@ -87,7 +88,7 @@ const LibrarySlug = ({
|
||||||
] as const).map((category) => category.attributes.short)}
|
] as const).map((category) => category.attributes.short)}
|
||||||
metadata={{
|
metadata={{
|
||||||
currencies: currencies,
|
currencies: currencies,
|
||||||
release_date: item.release_date,
|
releaseDate: item.release_date,
|
||||||
price: item.price,
|
price: item.price,
|
||||||
position: "Bottom",
|
position: "Bottom",
|
||||||
}}
|
}}
|
||||||
|
@ -232,10 +233,8 @@ const LibrarySlug = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={prettyInlineTitle("", item.title, item.subtitle)}
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
thumbnail={item.thumbnail?.data?.attributes ?? undefined}
|
|
||||||
languages={languages}
|
languages={languages}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
currencies={currencies}
|
currencies={currencies}
|
||||||
|
@ -262,10 +261,17 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
if (!item.libraryItems?.data[0]?.attributes || !item.libraryItems.data[0]?.id)
|
if (!item.libraryItems?.data[0]?.attributes || !item.libraryItems.data[0]?.id)
|
||||||
return { notFound: true };
|
return { notFound: true };
|
||||||
sortRangedContent(item.libraryItems.data[0].attributes.contents);
|
sortRangedContent(item.libraryItems.data[0].attributes.contents);
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
item: item.libraryItems.data[0].attributes,
|
item: item.libraryItems.data[0].attributes,
|
||||||
itemId: item.libraryItems.data[0].id,
|
itemId: item.libraryItems.data[0].id,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
item.libraryItems.data[0].attributes.title,
|
||||||
|
undefined,
|
||||||
|
item.libraryItems.data[0].attributes.thumbnail?.data?.attributes
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useState, useMemo, useCallback } from "react";
|
import { useState, useMemo, useCallback } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Select } from "components/Inputs/Select";
|
import { Select } from "components/Inputs/Select";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
|
@ -12,11 +12,7 @@ import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { GetLibraryItemsPreviewQuery } from "graphql/generated";
|
import { GetLibraryItemsPreviewQuery } from "graphql/generated";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import {
|
import { prettyInlineTitle, prettyItemSubType } from "helpers/formatters";
|
||||||
prettyDate,
|
|
||||||
prettyInlineTitle,
|
|
||||||
prettyItemSubType,
|
|
||||||
} from "helpers/formatters";
|
|
||||||
import { LibraryItemUserStatus } from "helpers/types";
|
import { LibraryItemUserStatus } from "helpers/types";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
import { WithLabel } from "components/Inputs/WithLabel";
|
import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
|
@ -33,6 +29,8 @@ import { convertPrice } from "helpers/numbers";
|
||||||
import { SmartList } from "components/SmartList";
|
import { SmartList } from "components/SmartList";
|
||||||
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import { compareDate } from "helpers/date";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -55,7 +53,7 @@ const DEFAULT_FILTERS_STATE = {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
items: NonNullable<GetLibraryItemsPreviewQuery["libraryItems"]>["data"];
|
items: NonNullable<GetLibraryItemsPreviewQuery["libraryItems"]>["data"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +172,10 @@ const Library = ({
|
||||||
return priceA - priceB;
|
return priceA - priceB;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
const dateA = a.attributes.release_date
|
return compareDate(
|
||||||
? prettyDate(a.attributes.release_date)
|
a.attributes.release_date,
|
||||||
: "9999";
|
b.attributes.release_date
|
||||||
const dateB = b.attributes.release_date
|
);
|
||||||
? prettyDate(b.attributes.release_date)
|
|
||||||
: "9999";
|
|
||||||
return dateA.localeCompare(dateB);
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -268,7 +263,7 @@ const Library = ({
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
className="mb-6 w-full"
|
||||||
placeholder={langui.search_title ?? undefined}
|
placeholder={langui.search_title ?? "Search..."}
|
||||||
value={searchName}
|
value={searchName}
|
||||||
onChange={setSearchName}
|
onChange={setSearchName}
|
||||||
/>
|
/>
|
||||||
|
@ -433,7 +428,7 @@ const Library = ({
|
||||||
)}
|
)}
|
||||||
metadata={{
|
metadata={{
|
||||||
currencies: currencies,
|
currencies: currencies,
|
||||||
release_date: item.attributes.release_date,
|
releaseDate: item.attributes.release_date,
|
||||||
price: item.attributes.price,
|
price: item.attributes.price,
|
||||||
position: "Bottom",
|
position: "Bottom",
|
||||||
}}
|
}}
|
||||||
|
@ -474,7 +469,6 @@ const Library = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.library}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanelIcon={Icon.Search}
|
subPanelIcon={Icon.Search}
|
||||||
|
@ -497,9 +491,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
language_code: context.locale ?? "en",
|
language_code: context.locale ?? "en",
|
||||||
});
|
});
|
||||||
if (!items.libraryItems?.data) return { notFound: true };
|
if (!items.libraryItems?.data) return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
items: items.libraryItems.data,
|
items: items.libraryItems.data,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.library ?? "Library"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Panels/SubPanel";
|
import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {}
|
interface Props extends AppStaticProps, AppLayoutRequired {}
|
||||||
const Merch = ({ langui, ...otherProps }: Props): JSX.Element => (
|
const Merch = ({ langui, ...otherProps }: Props): JSX.Element => (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.merch}
|
|
||||||
subPanel={
|
subPanel={
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<PanelHeader
|
<PanelHeader
|
||||||
|
@ -35,8 +35,13 @@ export default Merch;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const getStaticProps: GetStaticProps = async (context) => {
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.merch ?? "Merch"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Switch } from "components/Inputs/Switch";
|
import { Switch } from "components/Inputs/Switch";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import {
|
import {
|
||||||
|
@ -11,7 +11,7 @@ import { SubPanel } from "components/Panels/SubPanel";
|
||||||
import { GetPostsPreviewQuery } from "graphql/generated";
|
import { GetPostsPreviewQuery } from "graphql/generated";
|
||||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { prettyDate, prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
import { WithLabel } from "components/Inputs/WithLabel";
|
import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
import { TextInput } from "components/Inputs/TextInput";
|
import { TextInput } from "components/Inputs/TextInput";
|
||||||
|
@ -21,6 +21,8 @@ import { filterHasAttributes } from "helpers/others";
|
||||||
import { SmartList } from "components/SmartList";
|
import { SmartList } from "components/SmartList";
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
import { TranslatedPreviewCard } from "components/Translated";
|
import { TranslatedPreviewCard } from "components/Translated";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import { compareDate } from "helpers/date";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -37,7 +39,7 @@ const DEFAULT_FILTERS_STATE = {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
posts: NonNullable<GetPostsPreviewQuery["posts"]>["data"];
|
posts: NonNullable<GetPostsPreviewQuery["posts"]>["data"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ const News = ({ langui, posts, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
className="mb-6 w-full"
|
||||||
placeholder={langui.search_title ?? undefined}
|
placeholder={langui.search_title ?? "Search..."}
|
||||||
value={searchName}
|
value={searchName}
|
||||||
onChange={setSearchName}
|
onChange={setSearchName}
|
||||||
/>
|
/>
|
||||||
|
@ -124,7 +126,8 @@ const News = ({ langui, posts, ...otherProps }: Props): JSX.Element => {
|
||||||
)}
|
)}
|
||||||
keepInfoVisible={keepInfoVisible}
|
keepInfoVisible={keepInfoVisible}
|
||||||
metadata={{
|
metadata={{
|
||||||
release_date: post.attributes.date,
|
releaseDate: post.attributes.date,
|
||||||
|
releaseDateFormat: "long",
|
||||||
position: "Top",
|
position: "Top",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -144,7 +147,6 @@ const News = ({ langui, posts, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.news}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanelIcon={Icon.Search}
|
subPanelIcon={Icon.Search}
|
||||||
|
@ -164,9 +166,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const posts = await sdk.getPostsPreview();
|
const posts = await sdk.getPostsPreview();
|
||||||
if (!posts.posts) return { notFound: true };
|
if (!posts.posts) return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
posts: sortPosts(posts.posts.data),
|
posts: sortPosts(posts.posts.data),
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.news ?? "News"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
@ -180,9 +187,5 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
|
||||||
const sortPosts = (posts: Props["posts"]): Props["posts"] =>
|
const sortPosts = (posts: Props["posts"]): Props["posts"] =>
|
||||||
posts
|
posts
|
||||||
.sort((a, b) => {
|
.sort((a, b) => compareDate(a.attributes?.date, b.attributes?.date))
|
||||||
const dateA = a.attributes?.date ? prettyDate(a.attributes.date) : "9999";
|
|
||||||
const dateB = b.attributes?.date ? prettyDate(b.attributes.date) : "9999";
|
|
||||||
return dateA.localeCompare(dateB);
|
|
||||||
})
|
|
||||||
.reverse();
|
.reverse();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { Chip } from "components/Chip";
|
import { Chip } from "components/Chip";
|
||||||
import { HorizontalLine } from "components/HorizontalLine";
|
import { HorizontalLine } from "components/HorizontalLine";
|
||||||
import { Img } from "components/Img";
|
import { Img } from "components/Img";
|
||||||
|
@ -26,13 +26,19 @@ import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { useLightBox } from "hooks/useLightBox";
|
import { useLightBox } from "hooks/useLightBox";
|
||||||
import { getAssetURL, ImageQuality } from "helpers/img";
|
import { getAssetURL, ImageQuality } from "helpers/img";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import {
|
||||||
|
getDefaultPreferredLanguages,
|
||||||
|
staticSmartLanguage,
|
||||||
|
} from "helpers/locales";
|
||||||
|
import { getDescription } from "helpers/description";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
page: WikiPageWithTranslations;
|
page: WikiPageWithTranslations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +223,6 @@ const WikiPage = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.news}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
languages={languages}
|
languages={languages}
|
||||||
|
@ -245,9 +250,58 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
});
|
});
|
||||||
if (!page.wikiPages?.data[0].attributes?.translations)
|
if (!page.wikiPages?.data[0].attributes?.translations)
|
||||||
return { notFound: true };
|
return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
|
|
||||||
|
const { title, description } = (() => {
|
||||||
|
const chipsGroups = {
|
||||||
|
[appStaticProps.langui.tags ?? "Tags"]: filterHasAttributes(
|
||||||
|
page.wikiPages.data[0].attributes.tags?.data,
|
||||||
|
["attributes"] as const
|
||||||
|
).map(
|
||||||
|
(tag) =>
|
||||||
|
tag.attributes.titles?.[0]?.title ?? prettySlug(tag.attributes.slug)
|
||||||
|
),
|
||||||
|
[appStaticProps.langui.categories ?? "Categories"]: filterHasAttributes(
|
||||||
|
page.wikiPages.data[0].attributes.categories?.data,
|
||||||
|
["attributes"] as const
|
||||||
|
).map((category) => category.attributes.short),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (context.locale && context.locales) {
|
||||||
|
const selectedTranslation = staticSmartLanguage({
|
||||||
|
items: page.wikiPages.data[0].attributes.translations,
|
||||||
|
languageExtractor: (item) => item.language?.data?.attributes?.code,
|
||||||
|
preferredLanguages: getDefaultPreferredLanguages(
|
||||||
|
context.locale,
|
||||||
|
context.locales
|
||||||
|
),
|
||||||
|
});
|
||||||
|
if (selectedTranslation) {
|
||||||
|
return {
|
||||||
|
title: selectedTranslation.title,
|
||||||
|
description: getDescription(selectedTranslation.summary, chipsGroups),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: prettySlug(page.wikiPages.data[0].attributes.slug),
|
||||||
|
description: getDescription(undefined, chipsGroups),
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
const thumbnail =
|
||||||
|
page.wikiPages.data[0].attributes.thumbnail?.data?.attributes;
|
||||||
|
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
page: page.wikiPages.data[0].attributes as WikiPageWithTranslations,
|
page: page.wikiPages.data[0].attributes as WikiPageWithTranslations,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
thumbnail
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { Fragment, useMemo } from "react";
|
import { Fragment, useMemo } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { InsetBox } from "components/InsetBox";
|
import { InsetBox } from "components/InsetBox";
|
||||||
import { NavOption } from "components/PanelComponents/NavOption";
|
import { NavOption } from "components/PanelComponents/NavOption";
|
||||||
import {
|
import {
|
||||||
|
@ -15,13 +15,14 @@ import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||||
import { getReadySdk } from "graphql/sdk";
|
import { getReadySdk } from "graphql/sdk";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { filterHasAttributes, isDefined } from "helpers/others";
|
import { filterHasAttributes, isDefined } from "helpers/others";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭────────╮
|
* ╭────────╮
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
chronologyItems: NonNullable<
|
chronologyItems: NonNullable<
|
||||||
GetChronologyItemsQuery["chronologyItems"]
|
GetChronologyItemsQuery["chronologyItems"]
|
||||||
>["data"];
|
>["data"];
|
||||||
|
@ -145,7 +146,6 @@ const Chronology = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.chronology}
|
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
@ -166,10 +166,15 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
const chronologyEras = await sdk.getEras();
|
const chronologyEras = await sdk.getEras();
|
||||||
if (!chronologyItems.chronologyItems || !chronologyEras.chronologyEras)
|
if (!chronologyItems.chronologyItems || !chronologyEras.chronologyEras)
|
||||||
return { notFound: true };
|
return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
chronologyItems: chronologyItems.chronologyItems.data,
|
chronologyItems: chronologyItems.chronologyItems.data,
|
||||||
chronologyEras: chronologyEras.chronologyEras.data,
|
chronologyEras: chronologyEras.chronologyEras.data,
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.chronology ?? "Chronology"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useMemo, useState } from "react";
|
||||||
import { AppLayout } from "components/AppLayout";
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
import { NavOption } from "components/PanelComponents/NavOption";
|
import { NavOption } from "components/PanelComponents/NavOption";
|
||||||
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
import { SubPanel } from "components/Panels/SubPanel";
|
import { SubPanel } from "components/Panels/SubPanel";
|
||||||
|
@ -25,6 +25,7 @@ import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||||
import { prettySlug } from "helpers/formatters";
|
import { prettySlug } from "helpers/formatters";
|
||||||
import { useBoolean } from "hooks/useBoolean";
|
import { useBoolean } from "hooks/useBoolean";
|
||||||
import { TranslatedPreviewCard } from "components/Translated";
|
import { TranslatedPreviewCard } from "components/Translated";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -42,7 +43,7 @@ const DEFAULT_FILTERS_STATE = {
|
||||||
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Props extends AppStaticProps {
|
interface Props extends AppStaticProps, AppLayoutRequired {
|
||||||
pages: NonNullable<GetWikiPagesPreviewsQuery["wikiPages"]>["data"];
|
pages: NonNullable<GetWikiPagesPreviewsQuery["wikiPages"]>["data"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ const Wiki = ({ langui, pages, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
className="mb-6 w-full"
|
className="mb-6 w-full"
|
||||||
placeholder={langui.search_title ?? undefined}
|
placeholder={langui.search_title ?? "Search..."}
|
||||||
value={searchName}
|
value={searchName}
|
||||||
onChange={setSearchName}
|
onChange={setSearchName}
|
||||||
/>
|
/>
|
||||||
|
@ -84,7 +85,7 @@ const Wiki = ({ langui, pages, ...otherProps }: Props): JSX.Element => {
|
||||||
input={
|
input={
|
||||||
<Select
|
<Select
|
||||||
className="w-full"
|
className="w-full"
|
||||||
options={[langui.category ?? ""]}
|
options={[langui.category ?? "Category"]}
|
||||||
value={groupingMethod}
|
value={groupingMethod}
|
||||||
onChange={setGroupingMethod}
|
onChange={setGroupingMethod}
|
||||||
allowEmpty
|
allowEmpty
|
||||||
|
@ -219,7 +220,6 @@ const Wiki = ({ langui, pages, ...otherProps }: Props): JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppLayout
|
<AppLayout
|
||||||
navTitle={langui.wiki}
|
|
||||||
subPanel={subPanel}
|
subPanel={subPanel}
|
||||||
contentPanel={contentPanel}
|
contentPanel={contentPanel}
|
||||||
subPanelIcon={Icon.Search}
|
subPanelIcon={Icon.Search}
|
||||||
|
@ -241,9 +241,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
language_code: context.locale ?? "en",
|
language_code: context.locale ?? "en",
|
||||||
});
|
});
|
||||||
if (!pages.wikiPages?.data) return { notFound: true };
|
if (!pages.wikiPages?.data) return { notFound: true };
|
||||||
|
const appStaticProps = await getAppStaticProps(context);
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
...(await getAppStaticProps(context)),
|
...appStaticProps,
|
||||||
pages: sortPages(pages.wikiPages.data),
|
pages: sortPages(pages.wikiPages.data),
|
||||||
|
openGraph: getOpenGraph(
|
||||||
|
appStaticProps.langui,
|
||||||
|
appStaticProps.langui.wiki ?? "Wiki"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
props: props,
|
props: props,
|
||||||
|
|
Loading…
Reference in New Issue