Support for multiple previous/follow-up contents

This commit is contained in:
DrMint 2023-05-03 04:31:34 +02:00
parent e1e107078e
commit b9d10f4670
15 changed files with 454 additions and 361 deletions

View File

@ -118,8 +118,8 @@
"primary_language": "Primary language", "primary_language": "Primary language",
"secondary_language": "Secondary languages", "secondary_language": "Secondary languages",
"combine_related_contents": "Combine related contents", "combine_related_contents": "Combine related contents",
"previous_content": "Previous content", "previous_content": "{ count, plural, =0 {No previous content} one {Previous content} other {Previous contents} }",
"followup_content": "Follow-up content", "followup_content": "{ count, plural, =0 {No follow-up content} one {Follow-up content} other {Follow-up contents} }",
"videos": "Videos", "videos": "Videos",
"view_on": "View on", "view_on": "View on",
"channel": "Channel", "channel": "Channel",
@ -184,7 +184,8 @@
"weapon": "{ count, plural, =0 {No weapons} one {Weapon} other {Weapons} }", "weapon": "{ count, plural, =0 {No weapons} one {Weapon} other {Weapons} }",
"weapons_description": "A list of all the weapons across all of the games. All distinguished weapons come with an “account.” Its a document with various details like how the weapon was forged and how its been used in the past.", "weapons_description": "A list of all the weapons across all of the games. All distinguished weapons come with an “account.” Its a document with various details like how the weapon was forged and how its been used in the past.",
"level_x": "Level {x}", "level_x": "Level {x}",
"story_x": "Story {x}" "story_x": "Story {x}",
"player_name_tooltip": "Certain in-game texts use the player's name as part of the dialogue/narration. If you want to see your name in the transcript found on this website, feel free to enter your player's name here. If left empty, '(player)' will be used instead."
} }
}, },
{ {
@ -367,10 +368,11 @@
"subitem_of_x": "Sous-item de {x}", "subitem_of_x": "Sous-item de {x}",
"variant_of_x": "Variante de {x}", "variant_of_x": "Variante de {x}",
"dark_mode_extension_warning": "Ce site web propose un thème clair et un thème sombre. Si vous utilisez une extension de navigateur qui simule un thème sombre, veillez à la désactiver pour une expérience optimale.", "dark_mode_extension_warning": "Ce site web propose un thème clair et un thème sombre. Si vous utilisez une extension de navigateur qui simule un thème sombre, veillez à la désactiver pour une expérience optimale.",
"weapon": null, "weapon": "{ count, plural, =0 {Pas d'arme} one {Arme} other {Armes} }",
"weapons_description": null, "weapons_description": "Une liste de toutes les armes présentes dans tous les jeux. Toutes les armes distinguées sont accompagnées d'un \"compte\". Il s'agit d'un document contenant divers détails tels que la façon dont l'arme a été forgée et comment elle a été utilisée dans le passé.",
"level_x": null, "level_x": "Niveau {x}",
"story_x": null "story_x": "Histoire {x}",
"player_name_tooltip": "Certains textes dans les jeux utilisent le nom du joueur dans les dialogue/la narration. Si vous voulez voir votre nom dans les transcriptions se trouvant sur ce site web, n'hésitez pas à entrer votre nom de joueur ici. S'il n'est pas renseigné, '(player)' sera utilisé à la place."
} }
}, },
{ {
@ -556,7 +558,8 @@
"weapon": null, "weapon": null,
"weapons_description": null, "weapons_description": null,
"level_x": null, "level_x": null,
"story_x": null "story_x": null,
"player_name_tooltip": null
} }
}, },
{ {
@ -742,7 +745,8 @@
"weapon": null, "weapon": null,
"weapons_description": null, "weapons_description": null,
"level_x": null, "level_x": null,
"story_x": null "story_x": null,
"player_name_tooltip": null
} }
}, },
{ {
@ -928,7 +932,8 @@
"weapon": null, "weapon": null,
"weapons_description": null, "weapons_description": null,
"level_x": null, "level_x": null,
"story_x": null "story_x": null,
"player_name_tooltip": null
} }
} }
] ]

View File

@ -16,6 +16,7 @@ import { useFormat } from "hooks/useFormat";
import { useAtomGetter, useAtomSetter } from "helpers/atoms"; import { useAtomGetter, useAtomSetter } from "helpers/atoms";
import { atoms } from "contexts/atoms"; import { atoms } from "contexts/atoms";
import { ElementsSeparator } from "helpers/component"; import { ElementsSeparator } from "helpers/component";
import { HorizontalLine } from "components/HorizontalLine";
/* /*
* *
@ -129,6 +130,7 @@ export const PostPage = ({
)} )}
{displayThumbnailHeader ? ( {displayThumbnailHeader ? (
<>
<ThumbnailHeader <ThumbnailHeader
thumbnail={thumbnail} thumbnail={thumbnail}
title={title} title={title}
@ -140,6 +142,8 @@ export const PostPage = ({
) : undefined ) : undefined
} }
/> />
<HorizontalLine />
</>
) : ( ) : (
<> <>
{displayLanguageSwitcher && ( {displayLanguageSwitcher && (

View File

@ -1,103 +0,0 @@
import { useCallback } from "react";
import { Chip } from "./Chip";
import { Img } from "./Img";
import { UpPressable } from "./Containers/UpPressable";
import { UploadImageFragment } from "graphql/generated";
import { ImageQuality } from "helpers/img";
import { TranslatedProps } from "types/TranslatedProps";
import { useSmartLanguage } from "hooks/useSmartLanguage";
import { cIf, cJoin } from "helpers/className";
import { isDefined } from "helpers/asserts";
/*
*
* COMPONENT
*/
interface Props {
thumbnail?: UploadImageFragment | string | null | undefined;
href: string;
pre_title?: string | null | undefined;
title: string | null | undefined;
subtitle?: string | null | undefined;
topChips?: string[];
bottomChips?: string[];
disabled?: boolean;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export const PreviewLine = ({
href,
thumbnail,
pre_title,
title,
subtitle,
topChips,
disabled,
bottomChips,
}: Props): JSX.Element => (
<UpPressable href={href} disabled={disabled}>
<div
className={cJoin(
"grid w-full grid-flow-col place-items-center gap-4",
cIf(disabled, "pointer-events-none touch-none select-none")
)}>
{thumbnail && (
<div className="h-full w-full">
<Img className="h-full object-cover" src={thumbnail} quality={ImageQuality.Medium} />
</div>
)}
<div className={cJoin("grid gap-2 py-4", cIf(isDefined(thumbnail), "pr-3", "px-6"))}>
{topChips && topChips.length > 0 && (
<div
className="grid grid-flow-col place-content-start gap-1 overflow-scroll
scrollbar-none">
{topChips.map((text, index) => (
<Chip key={index} text={text} />
))}
</div>
)}
<div className="my-1 flex flex-col">
{pre_title && <p className="mb-1 leading-none">{pre_title}</p>}
{title && <p className="font-headers text-lg font-bold leading-none">{title}</p>}
{subtitle && <p className="leading-none">{subtitle}</p>}
</div>
{bottomChips && bottomChips.length > 0 && (
<div
className="grid grid-flow-col place-content-start gap-1 overflow-scroll
scrollbar-none">
{bottomChips.map((text, index) => (
<Chip key={index} className="text-sm" text={text} />
))}
</div>
)}
</div>
</div>
</UpPressable>
);
/*
*
* TRANSLATED VARIANT
*/
export const TranslatedPreviewLine = ({
translations,
fallback,
...otherProps
}: TranslatedProps<Props, "pre_title" | "subtitle" | "title">): JSX.Element => {
const [selectedTranslation] = useSmartLanguage({
items: translations,
languageExtractor: useCallback((item: { language: string }): string => item.language, []),
});
return (
<PreviewLine
pre_title={selectedTranslation?.pre_title ?? fallback.pre_title}
title={selectedTranslation?.title ?? fallback.title}
subtitle={selectedTranslation?.subtitle ?? fallback.subtitle}
{...otherProps}
/>
);
};

View File

@ -27,7 +27,7 @@ interface Props {
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"] NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
>["categories"]; >["categories"];
thumbnail?: UploadImageFragment | null | undefined; thumbnail?: UploadImageFragment | null | undefined;
className?: string;
languageSwitcher?: JSX.Element; languageSwitcher?: JSX.Element;
} }
@ -42,13 +42,14 @@ export const ThumbnailHeader = ({
categories, categories,
description, description,
languageSwitcher, languageSwitcher,
className,
}: Props): JSX.Element => { }: Props): JSX.Element => {
const { format } = useFormat(); const { format } = useFormat();
const { showLightBox } = useAtomGetter(atoms.lightBox); const { showLightBox } = useAtomGetter(atoms.lightBox);
return ( return (
<> <div className={className}>
<div className="mb-12 grid place-items-center gap-12"> <div className={"mb-12 grid place-items-center gap-12"}>
<div className="drop-shadow-lg shadow-shade"> <div className="drop-shadow-lg shadow-shade">
{thumbnail ? ( {thumbnail ? (
<Img <Img
@ -97,6 +98,6 @@ export const ThumbnailHeader = ({
{languageSwitcher} {languageSwitcher}
</div> </div>
{description && <InsetBox className="mt-8">{<Markdawn text={description} />}</InsetBox>} {description && <InsetBox className="mt-8">{<Markdawn text={description} />}</InsetBox>}
</> </div>
); );
}; };

View File

@ -0,0 +1,40 @@
fragment relatedContentPreview on Content {
slug
translations(pagination: { limit: -1 }) {
pre_title
title
subtitle
language {
data {
attributes {
code
}
}
}
}
categories(pagination: { limit: -1 }) {
data {
id
attributes {
short
}
}
}
type {
data {
attributes {
slug
titles(filters: { language: { code: { eq: $language_code } } }) {
title
}
}
}
}
thumbnail {
data {
attributes {
...uploadImage
}
}
}
}

View File

@ -113,8 +113,8 @@ export interface ICUParams {
primary_language: never; primary_language: never;
secondary_language: never; secondary_language: never;
combine_related_contents: never; combine_related_contents: never;
previous_content: never; previous_content: { count: number };
followup_content: never; followup_content: { count: number };
videos: never; videos: never;
view_on: never; view_on: never;
channel: never; channel: never;

View File

@ -208,51 +208,20 @@ query getContentText($slug: String, $language_code: String) {
} }
title title
} }
sequence }
contents(pagination: { limit: -1 }) { }
}
previous_contents(pagination: { limit: -1 }) {
data { data {
attributes { attributes {
slug ...relatedContentPreview
translations(pagination: { limit: -1 }) { }
pre_title }
title }
subtitle next_contents(pagination: { limit: -1 }) {
language {
data { data {
attributes { attributes {
code ...relatedContentPreview
}
}
}
}
categories(pagination: { limit: -1 }) {
data {
id
attributes {
short
}
}
}
type {
data {
attributes {
slug
titles(filters: { language: { code: { eq: $language_code } } }) {
title
}
}
}
}
thumbnail {
data {
attributes {
...uploadImage
}
}
}
}
}
}
} }
} }
} }

View File

@ -3,7 +3,6 @@ query getContentsFolder($slug: String, $language_code: String) {
data { data {
attributes { attributes {
slug slug
sequence
titles(pagination: { limit: -1 }) { titles(pagination: { limit: -1 }) {
id id
language { language {

View File

@ -34,11 +34,13 @@ export const ConditionalWrapper = <T, U>({
interface ElementsSeparatorProps { interface ElementsSeparatorProps {
children: React.ReactNode[]; children: React.ReactNode[];
separator?: React.ReactNode; separator?: React.ReactNode;
className?: string;
} }
export const ElementsSeparator = ({ export const ElementsSeparator = ({
children, children,
separator = <HorizontalLine />, className,
separator = <HorizontalLine className={className} />,
}: ElementsSeparatorProps): JSX.Element => ( }: ElementsSeparatorProps): JSX.Element => (
<>{insertInBetweenArray(children.filter(Boolean), separator)}</> <>{insertInBetweenArray(children.filter(Boolean), separator)}</>
); );

View File

@ -72,6 +72,8 @@ interface StrapiContent extends StrapiEvent {
slug: string; slug: string;
folder?: StrapiRelationalFieldEntry; folder?: StrapiRelationalFieldEntry;
ranged_contents: StrapiRelationalFieldEntry[]; ranged_contents: StrapiRelationalFieldEntry[];
next_contents: StrapiRelationalFieldEntry[];
previous_contents: StrapiRelationalFieldEntry[];
}; };
} }
@ -235,6 +237,9 @@ const Revalidate = async (
} }
} }
body.entry.previous_contents.forEach(({ slug }) => paths.push(`/contents/${slug}`));
body.entry.next_contents.forEach(({ slug }) => paths.push(`/contents/${slug}`));
await Promise.all( await Promise.all(
body.entry.ranged_contents.map(async ({ id }) => { body.entry.ranged_contents.map(async ({ id }) => {
const rangedContent = await sdk.revalidationGetRangedContent({ const rangedContent = await sdk.revalidationGetRangedContent({

View File

@ -16,7 +16,6 @@ import { ReturnButton } from "components/PanelComponents/ReturnButton";
import { getOpenGraph } from "helpers/openGraph"; import { getOpenGraph } from "helpers/openGraph";
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales"; import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
import { getDescription } from "helpers/description"; import { getDescription } from "helpers/description";
import { TranslatedChroniclesList } from "components/Chronicles/ChroniclesList";
import { useScrollTopOnChange } from "hooks/useScrollTopOnChange"; import { useScrollTopOnChange } from "hooks/useScrollTopOnChange";
import { Ids } from "types/ids"; import { Ids } from "types/ids";
import { useFormat } from "hooks/useFormat"; import { useFormat } from "hooks/useFormat";

View File

@ -1,14 +1,14 @@
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next"; import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
import { Fragment, useCallback } from "react"; import { Fragment, useCallback, useState } from "react";
import naturalCompare from "string-natural-compare"; import Collapsible from "react-collapsible";
import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Chip } from "components/Chip"; import { Chip } from "components/Chip";
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs"; import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
import { getTocFromMarkdawn, Markdawn, TableOfContents } from "components/Markdown/Markdawn"; import { getTocFromMarkdawn, Markdawn, TableOfContents } from "components/Markdown/Markdawn";
import { TranslatedReturnButton } from "components/PanelComponents/ReturnButton"; import { TranslatedReturnButton } from "components/PanelComponents/ReturnButton";
import { ContentPanel } from "components/Containers/ContentPanel"; import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { SubPanel } from "components/Containers/SubPanel"; import { SubPanel } from "components/Containers/SubPanel";
import { PreviewCard } from "components/PreviewCard"; import { PreviewCard, TranslatedPreviewCard } from "components/PreviewCard";
import { RecorderChip } from "components/RecorderChip"; import { RecorderChip } from "components/RecorderChip";
import { ThumbnailHeader } from "components/ThumbnailHeader"; import { ThumbnailHeader } from "components/ThumbnailHeader";
import { ToolTip } from "components/ToolTip"; import { ToolTip } from "components/ToolTip";
@ -27,14 +27,15 @@ import { useSmartLanguage } from "hooks/useSmartLanguage";
import { getOpenGraph } from "helpers/openGraph"; import { getOpenGraph } from "helpers/openGraph";
import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales"; import { getDefaultPreferredLanguages, staticSmartLanguage } from "helpers/locales";
import { getDescription } from "helpers/description"; import { getDescription } from "helpers/description";
import { TranslatedPreviewLine } from "components/PreviewLine"; import { cIf, cJoin } from "helpers/className";
import { cIf } from "helpers/className";
import { Ids } from "types/ids"; import { Ids } from "types/ids";
import { atoms } from "contexts/atoms"; import { atoms } from "contexts/atoms";
import { useAtomGetter, useAtomSetter } from "helpers/atoms"; import { useAtomGetter, useAtomSetter } from "helpers/atoms";
import { useFormat } from "hooks/useFormat"; import { useFormat } from "hooks/useFormat";
import { getFormat } from "helpers/i18n"; import { getFormat } from "helpers/i18n";
import { ElementsSeparator } from "helpers/component"; import { ElementsSeparator } from "helpers/component";
import { RelatedContentPreviewFragment } from "graphql/generated";
import { Button } from "components/Inputs/Button";
/* /*
* *
@ -46,7 +47,6 @@ interface Props extends AppLayoutRequired {
} }
const Content = ({ content, ...otherProps }: Props): JSX.Element => { const Content = ({ content, ...otherProps }: Props): JSX.Element => {
const isContentPanelAtLeast2xl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeast2xl);
const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened); const setSubPanelOpened = useAtomSetter(atoms.layout.subPanelOpened);
const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout); const is1ColumnLayout = useAtomGetter(atoms.containerQueries.is1ColumnLayout);
@ -64,15 +64,6 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
useScrollTopOnChange(Ids.ContentPanel, [selectedTranslation]); useScrollTopOnChange(Ids.ContentPanel, [selectedTranslation]);
const previousContent =
content.folder?.data?.attributes?.contents && content.folder.data.attributes.sequence
? getPreviousContent(content.folder.data.attributes.contents.data, content.slug)
: undefined;
const nextContent =
content.folder?.data?.attributes?.contents && content.folder.data.attributes.sequence
? getNextContent(content.folder.data.attributes.contents.data, content.slug)
: undefined;
const returnButtonProps = { const returnButtonProps = {
href: content.folder?.data?.attributes href: content.folder?.data?.attributes
? `/contents/folder/${content.folder.data.attributes.slug}` ? `/contents/folder/${content.folder.data.attributes.slug}`
@ -255,7 +246,7 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
); );
const contentPanel = ( const contentPanel = (
<ContentPanel> <ContentPanel width={ContentPanelWidthSizes.Full}>
<TranslatedReturnButton <TranslatedReturnButton
{...returnButtonProps} {...returnButtonProps}
displayOnlyOn="1ColumnLayout" displayOnlyOn="1ColumnLayout"
@ -263,10 +254,11 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
/> />
<div className="grid place-items-center"> <div className="grid place-items-center">
<ElementsSeparator> <ElementsSeparator className="max-w-2xl">
{[ {[
<ThumbnailHeader <ThumbnailHeader
key="thumbnailHeader" key="thumbnailHeader"
className="max-w-2xl"
thumbnail={content.thumbnail?.data?.attributes} thumbnail={content.thumbnail?.data?.attributes}
pre_title={selectedTranslation?.pre_title} pre_title={selectedTranslation?.pre_title}
title={selectedTranslation?.title} title={selectedTranslation?.title}
@ -281,80 +273,27 @@ const Content = ({ content, ...otherProps }: Props): JSX.Element => {
} }
/>, />,
previousContent?.attributes && ( content.previous_contents?.data && content.previous_contents.data.length > 0 && (
<> <RelatedContentsSection
<h2 className="mb-4 text-center text-2xl">{format("previous_content")}</h2> title={format("previous_content", { count: content.previous_contents.data.length })}
<TranslatedPreviewLine contents={filterHasAttributes(content.previous_contents.data, ["attributes"]).map(
href={`/contents/${previousContent.attributes.slug}`} ({ attributes }) => attributes
translations={filterHasAttributes(previousContent.attributes.translations, [ )}
"language.data.attributes.code", isInitiallyOpened={false}
]).map((translation) => ({
pre_title: translation.pre_title,
title: translation.title,
subtitle: translation.subtitle,
language: translation.language.data.attributes.code,
}))}
fallback={{
title: prettySlug(previousContent.attributes.slug),
}}
thumbnail={previousContent.attributes.thumbnail?.data?.attributes}
topChips={
isContentPanelAtLeast2xl && previousContent.attributes.type?.data?.attributes
? [
previousContent.attributes.type.data.attributes.titles?.[0]
? previousContent.attributes.type.data.attributes.titles[0]?.title
: prettySlug(previousContent.attributes.type.data.attributes.slug),
]
: undefined
}
bottomChips={
isContentPanelAtLeast2xl
? previousContent.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)
: undefined
}
/> />
</>
), ),
selectedTranslation?.text_set?.text && ( selectedTranslation?.text_set?.text && (
<Markdawn text={selectedTranslation.text_set.text} /> <Markdawn className="max-w-2xl" text={selectedTranslation.text_set.text} />
), ),
nextContent?.attributes && ( content.next_contents?.data && content.next_contents.data.length > 0 && (
<> <RelatedContentsSection
<h2 className="mb-4 text-center text-2xl">{format("followup_content")}</h2> title={format("followup_content", { count: content.next_contents.data.length })}
<TranslatedPreviewLine contents={filterHasAttributes(content.next_contents.data, ["attributes"]).map(
href={`/contents/${nextContent.attributes.slug}`} ({ attributes }) => attributes
translations={filterHasAttributes(nextContent.attributes.translations, [ )}
"language.data.attributes.code",
]).map((translation) => ({
pre_title: translation.pre_title,
title: translation.title,
subtitle: translation.subtitle,
language: translation.language.data.attributes.code,
}))}
fallback={{ title: nextContent.attributes.slug }}
thumbnail={nextContent.attributes.thumbnail?.data?.attributes}
topChips={
isContentPanelAtLeast2xl && nextContent.attributes.type?.data?.attributes
? [
nextContent.attributes.type.data.attributes.titles?.[0]
? nextContent.attributes.type.data.attributes.titles[0]?.title
: prettySlug(nextContent.attributes.type.data.attributes.slug),
]
: undefined
}
bottomChips={
isContentPanelAtLeast2xl
? nextContent.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)
: undefined
}
/> />
</>
), ),
]} ]}
</ElementsSeparator> </ElementsSeparator>
@ -418,12 +357,6 @@ export const getStaticProps: GetStaticProps = async (context) => {
const thumbnail = content.contents.data[0].attributes.thumbnail?.data?.attributes; const thumbnail = content.contents.data[0].attributes.thumbnail?.data?.attributes;
if (content.contents.data[0].attributes.folder?.data?.attributes?.sequence === false) {
content.contents.data[0].attributes.folder.data.attributes.contents?.data.sort((a, b) =>
a.attributes && b.attributes ? naturalCompare(a.attributes.slug, b.attributes.slug) : 0
);
}
const props: Props = { const props: Props = {
content: content.contents.data[0].attributes as ContentWithTranslations, content: content.contents.data[0].attributes as ContentWithTranslations,
openGraph: getOpenGraph(format, title, description, thumbnail), openGraph: getOpenGraph(format, title, description, thumbnail),
@ -454,34 +387,83 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
}; };
/* /*
* *
* PRIVATE METHODS * PRIVATE COMPONENTS
*/ */
type FolderContents = NonNullable< interface RelatedContentsSectionProps {
NonNullable< title: string;
NonNullable<NonNullable<ContentWithTranslations["folder"]>["data"]>["attributes"] contents: RelatedContentPreviewFragment[];
>["contents"] isInitiallyOpened?: boolean;
>["data"]; }
const getPreviousContent = (contents: FolderContents, currentSlug: string) => { const RelatedContentsSection = ({
for (let index = 0; index < contents.length; index++) { title,
const content = contents[index]; contents,
if (content?.attributes?.slug === currentSlug && index > 0) { isInitiallyOpened = true,
return contents[index - 1]; }: RelatedContentsSectionProps) => {
const [isOpened, setOpened] = useState(isInitiallyOpened);
return (
<Collapsible
open={isOpened}
onClosing={() => setOpened(false)}
onOpening={() => setOpened(true)}
trigger={
<div className="flex place-content-center place-items-center gap-4">
<h2 className="text-center text-2xl">{title}</h2>
<Button icon={isOpened ? "expand_less" : "expand_more"} active={isOpened} size="small" />
</div>
} }
} contentInnerClassName={cJoin(
return undefined; cIf(contents.length > 1, "px-4 py-10", "px-4 py-6"),
"flex w-full flex-wrap place-content-center items-start gap-x-6 gap-y-8"
)}
easing="ease-in-out"
transitionTime={400}
lazyRender
contentHiddenWhenClosed>
{contents.map((relatedContent) => (
<RelatedContentPreview key={relatedContent.slug} {...relatedContent} />
))}
</Collapsible>
);
}; };
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ const RelatedContentPreview = ({
slug,
translations,
thumbnail,
categories,
type,
}: RelatedContentPreviewFragment) => {
const isContentPanelAtLeastXl = useAtomGetter(atoms.containerQueries.isContentPanelAtLeastXl);
const getNextContent = (contents: FolderContents, currentSlug: string) => { return (
for (let index = 0; index < contents.length; index++) { <TranslatedPreviewCard
const content = contents[index]; href={`/contents/${slug}`}
if (content?.attributes?.slug === currentSlug && index < contents.length - 1) { className={cIf(isContentPanelAtLeastXl, "max-w-xs")}
return contents[index + 1]; translations={filterHasAttributes(translations, ["language.data.attributes.code"]).map(
(translation) => ({
pre_title: translation.pre_title,
title: translation.title,
subtitle: translation.subtitle,
language: translation.language.data.attributes.code,
})
)}
fallback={{ title: slug }}
thumbnail={thumbnail?.data?.attributes}
topChips={
type?.data?.attributes
? [
type.data.attributes.titles?.[0]
? type.data.attributes.titles[0]?.title
: prettySlug(type.data.attributes.slug),
]
: undefined
} }
} bottomChips={categories?.data.map((category) => category.attributes?.short ?? "")}
return undefined; keepInfoVisible
/>
);
}; };

View File

@ -1,5 +1,4 @@
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next"; import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
import naturalCompare from "string-natural-compare";
import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel"; import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
import { getOpenGraph } from "helpers/openGraph"; import { getOpenGraph } from "helpers/openGraph";
@ -218,16 +217,6 @@ export const getStaticProps: GetStaticProps = async (context) => {
const folder = contentsFolder.contentsFolders.data[0].attributes; const folder = contentsFolder.contentsFolders.data[0].attributes;
folder.subfolders?.data.sort((a, b) =>
a.attributes && b.attributes ? naturalCompare(a.attributes.slug, b.attributes.slug) : 0
);
if (!folder.sequence) {
folder.contents?.data.sort((a, b) =>
a.attributes && b.attributes ? naturalCompare(a.attributes.slug, b.attributes.slug) : 0
);
}
const title = (() => { const title = (() => {
if (slug === "root") { if (slug === "root") {
return format("contents"); return format("contents");

View File

@ -14,7 +14,6 @@ import { WithLabel } from "components/Inputs/WithLabel";
import { NavOption } from "components/PanelComponents/NavOption"; import { NavOption } from "components/PanelComponents/NavOption";
import { ButtonGroup } from "components/Inputs/ButtonGroup"; import { ButtonGroup } from "components/Inputs/ButtonGroup";
import { PreviewCard } from "components/PreviewCard"; import { PreviewCard } from "components/PreviewCard";
import { PreviewLine } from "components/PreviewLine";
import { ChroniclePreview } from "components/Chronicles/ChroniclePreview"; import { ChroniclePreview } from "components/Chronicles/ChroniclePreview";
import { PreviewFolder } from "components/Contents/PreviewFolder"; import { PreviewFolder } from "components/Contents/PreviewFolder";
import { getFormat } from "helpers/i18n"; import { getFormat } from "helpers/i18n";
@ -805,57 +804,6 @@ const DesignSystem = (props: Props): JSX.Element => {
/> />
</div> </div>
<HorizontalLine />
<h3 className="-mt-6 mb-2 text-xl">Preview Line</h3>
<div className="grid grid-cols-[repeat(2,auto)] place-items-center gap-4">
<PreviewLine
href="#"
pre_title="Breaking News"
title="Accord's Library is live"
subtitle="I know, big deal, this is subtitle"
/>
<PreviewLine
href="#"
pre_title="Breaking News"
title="Accord's Library is live"
subtitle="I know, big deal, this is subtitle"
thumbnail={"/default_og.jpg"}
/>
<PreviewLine
href="#"
pre_title="Breaking News"
title="Accord's Library is live"
subtitle="I know, big deal, this is subtitle"
thumbnail={"/default_og.jpg"}
topChips={["Top chip 1", "Chip 2", "Chip 3", "Chip 4"]}
/>
<PreviewLine
href="#"
pre_title="Breaking News"
title="This one has everything"
subtitle="I know, big deal, this is subtitle"
thumbnail={"/default_og.jpg"}
topChips={["Top chip 1", "Chip 2", "Chip 3", "Chip 4"]}
bottomChips={["Bottom chip 1", "Chip 2", "Chip 3", "Chip 4"]}
/>
<PreviewLine
href="#"
title="Just a title"
thumbnail={"/default_og.jpg"}
topChips={["Top chip 1", "Chip 2", "Chip 3", "Chip 4"]}
bottomChips={["Bottom chip 1", "Chip 2", "Chip 3", "Chip 4"]}
/>
<PreviewLine
href="#"
title="Disabled"
thumbnail={"/default_og.jpg"}
topChips={["Top chip 1", "Chip 2", "Chip 3", "Chip 4"]}
bottomChips={["Bottom chip 1", "Chip 2", "Chip 3", "Chip 4"]}
disabled
/>
</div>
<HorizontalLine /> <HorizontalLine />
<h3 className="-mt-6 mb-2 text-xl">Folder Card</h3> <h3 className="-mt-6 mb-2 text-xl">Folder Card</h3>

View File

@ -1497,6 +1497,54 @@ export type ComponentTranslationsPostsInput = {
translators?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; translators?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
}; };
export type ComponentTranslationsReinCostumes = {
__typename?: "ComponentTranslationsReinCostumes";
description: Scalars["String"];
id: Scalars["ID"];
language?: Maybe<LanguageEntityResponse>;
name: Scalars["String"];
};
export type ComponentTranslationsReinCostumesFiltersInput = {
and?: InputMaybe<Array<InputMaybe<ComponentTranslationsReinCostumesFiltersInput>>>;
description?: InputMaybe<StringFilterInput>;
language?: InputMaybe<LanguageFiltersInput>;
name?: InputMaybe<StringFilterInput>;
not?: InputMaybe<ComponentTranslationsReinCostumesFiltersInput>;
or?: InputMaybe<Array<InputMaybe<ComponentTranslationsReinCostumesFiltersInput>>>;
};
export type ComponentTranslationsReinCostumesInput = {
description?: InputMaybe<Scalars["String"]>;
id?: InputMaybe<Scalars["ID"]>;
language?: InputMaybe<Scalars["ID"]>;
name?: InputMaybe<Scalars["String"]>;
};
export type ComponentTranslationsReinEmblems = {
__typename?: "ComponentTranslationsReinEmblems";
description: Scalars["String"];
id: Scalars["ID"];
language?: Maybe<LanguageEntityResponse>;
name: Scalars["String"];
};
export type ComponentTranslationsReinEmblemsFiltersInput = {
and?: InputMaybe<Array<InputMaybe<ComponentTranslationsReinEmblemsFiltersInput>>>;
description?: InputMaybe<StringFilterInput>;
language?: InputMaybe<LanguageFiltersInput>;
name?: InputMaybe<StringFilterInput>;
not?: InputMaybe<ComponentTranslationsReinEmblemsFiltersInput>;
or?: InputMaybe<Array<InputMaybe<ComponentTranslationsReinEmblemsFiltersInput>>>;
};
export type ComponentTranslationsReinEmblemsInput = {
description?: InputMaybe<Scalars["String"]>;
id?: InputMaybe<Scalars["ID"]>;
language?: InputMaybe<Scalars["ID"]>;
name?: InputMaybe<Scalars["String"]>;
};
export type ComponentTranslationsScanSet = { export type ComponentTranslationsScanSet = {
__typename?: "ComponentTranslationsScanSet"; __typename?: "ComponentTranslationsScanSet";
credits: ComponentBasicsCredits; credits: ComponentBasicsCredits;
@ -1840,6 +1888,8 @@ export type Content = {
chronicles?: Maybe<ChronicleRelationResponseCollection>; chronicles?: Maybe<ChronicleRelationResponseCollection>;
createdAt?: Maybe<Scalars["DateTime"]>; createdAt?: Maybe<Scalars["DateTime"]>;
folder?: Maybe<ContentsFolderEntityResponse>; folder?: Maybe<ContentsFolderEntityResponse>;
next_contents?: Maybe<ContentRelationResponseCollection>;
previous_contents?: Maybe<ContentRelationResponseCollection>;
ranged_contents?: Maybe<RangedContentRelationResponseCollection>; ranged_contents?: Maybe<RangedContentRelationResponseCollection>;
slug: Scalars["String"]; slug: Scalars["String"];
thumbnail?: Maybe<UploadFileEntityResponse>; thumbnail?: Maybe<UploadFileEntityResponse>;
@ -1860,6 +1910,18 @@ export type ContentChroniclesArgs = {
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>; sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
}; };
export type ContentNext_ContentsArgs = {
filters?: InputMaybe<ContentFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type ContentPrevious_ContentsArgs = {
filters?: InputMaybe<ContentFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type ContentRanged_ContentsArgs = { export type ContentRanged_ContentsArgs = {
filters?: InputMaybe<RangedContentFiltersInput>; filters?: InputMaybe<RangedContentFiltersInput>;
pagination?: InputMaybe<PaginationArg>; pagination?: InputMaybe<PaginationArg>;
@ -1896,8 +1958,10 @@ export type ContentFiltersInput = {
createdAt?: InputMaybe<DateTimeFilterInput>; createdAt?: InputMaybe<DateTimeFilterInput>;
folder?: InputMaybe<ContentsFolderFiltersInput>; folder?: InputMaybe<ContentsFolderFiltersInput>;
id?: InputMaybe<IdFilterInput>; id?: InputMaybe<IdFilterInput>;
next_contents?: InputMaybe<ContentFiltersInput>;
not?: InputMaybe<ContentFiltersInput>; not?: InputMaybe<ContentFiltersInput>;
or?: InputMaybe<Array<InputMaybe<ContentFiltersInput>>>; or?: InputMaybe<Array<InputMaybe<ContentFiltersInput>>>;
previous_contents?: InputMaybe<ContentFiltersInput>;
ranged_contents?: InputMaybe<RangedContentFiltersInput>; ranged_contents?: InputMaybe<RangedContentFiltersInput>;
slug?: InputMaybe<StringFilterInput>; slug?: InputMaybe<StringFilterInput>;
translations?: InputMaybe<ComponentTranslationsTitleFiltersInput>; translations?: InputMaybe<ComponentTranslationsTitleFiltersInput>;
@ -1909,6 +1973,8 @@ export type ContentInput = {
categories?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; categories?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
chronicles?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; chronicles?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
folder?: InputMaybe<Scalars["ID"]>; folder?: InputMaybe<Scalars["ID"]>;
next_contents?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
previous_contents?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
ranged_contents?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; ranged_contents?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
slug?: InputMaybe<Scalars["String"]>; slug?: InputMaybe<Scalars["String"]>;
thumbnail?: InputMaybe<Scalars["ID"]>; thumbnail?: InputMaybe<Scalars["ID"]>;
@ -1973,7 +2039,6 @@ export type ContentsFolder = {
contents?: Maybe<ContentRelationResponseCollection>; contents?: Maybe<ContentRelationResponseCollection>;
createdAt?: Maybe<Scalars["DateTime"]>; createdAt?: Maybe<Scalars["DateTime"]>;
parent_folder?: Maybe<ContentsFolderEntityResponse>; parent_folder?: Maybe<ContentsFolderEntityResponse>;
sequence: Scalars["Boolean"];
slug: Scalars["String"]; slug: Scalars["String"];
subfolders?: Maybe<ContentsFolderRelationResponseCollection>; subfolders?: Maybe<ContentsFolderRelationResponseCollection>;
titles: Array<Maybe<ComponentTranslationsSimpleTitle>>; titles: Array<Maybe<ComponentTranslationsSimpleTitle>>;
@ -2023,7 +2088,6 @@ export type ContentsFolderFiltersInput = {
not?: InputMaybe<ContentsFolderFiltersInput>; not?: InputMaybe<ContentsFolderFiltersInput>;
or?: InputMaybe<Array<InputMaybe<ContentsFolderFiltersInput>>>; or?: InputMaybe<Array<InputMaybe<ContentsFolderFiltersInput>>>;
parent_folder?: InputMaybe<ContentsFolderFiltersInput>; parent_folder?: InputMaybe<ContentsFolderFiltersInput>;
sequence?: InputMaybe<BooleanFilterInput>;
slug?: InputMaybe<StringFilterInput>; slug?: InputMaybe<StringFilterInput>;
subfolders?: InputMaybe<ContentsFolderFiltersInput>; subfolders?: InputMaybe<ContentsFolderFiltersInput>;
titles?: InputMaybe<ComponentTranslationsSimpleTitleFiltersInput>; titles?: InputMaybe<ComponentTranslationsSimpleTitleFiltersInput>;
@ -2033,7 +2097,6 @@ export type ContentsFolderFiltersInput = {
export type ContentsFolderInput = { export type ContentsFolderInput = {
contents?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; contents?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
parent_folder?: InputMaybe<Scalars["ID"]>; parent_folder?: InputMaybe<Scalars["ID"]>;
sequence?: InputMaybe<Scalars["Boolean"]>;
slug?: InputMaybe<Scalars["String"]>; slug?: InputMaybe<Scalars["String"]>;
subfolders?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>; subfolders?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
titles?: InputMaybe<Array<InputMaybe<ComponentTranslationsSimpleTitleInput>>>; titles?: InputMaybe<Array<InputMaybe<ComponentTranslationsSimpleTitleInput>>>;
@ -2409,6 +2472,8 @@ export type GenericMorph =
| ComponentTranslationsLibraryContent | ComponentTranslationsLibraryContent
| ComponentTranslationsLibraryItems | ComponentTranslationsLibraryItems
| ComponentTranslationsPosts | ComponentTranslationsPosts
| ComponentTranslationsReinCostumes
| ComponentTranslationsReinEmblems
| ComponentTranslationsScanSet | ComponentTranslationsScanSet
| ComponentTranslationsSimpleTitle | ComponentTranslationsSimpleTitle
| ComponentTranslationsTextSet | ComponentTranslationsTextSet
@ -2439,6 +2504,8 @@ export type GenericMorph =
| Post | Post
| RangedContent | RangedContent
| Recorder | Recorder
| ReinCostume
| ReinEmblem
| Source | Source
| TextualSubtype | TextualSubtype
| UploadFile | UploadFile
@ -3009,6 +3076,8 @@ export type Mutation = {
createPost?: Maybe<PostEntityResponse>; createPost?: Maybe<PostEntityResponse>;
createRangedContent?: Maybe<RangedContentEntityResponse>; createRangedContent?: Maybe<RangedContentEntityResponse>;
createRecorder?: Maybe<RecorderEntityResponse>; createRecorder?: Maybe<RecorderEntityResponse>;
createReinCostume?: Maybe<ReinCostumeEntityResponse>;
createReinEmblem?: Maybe<ReinEmblemEntityResponse>;
createSource?: Maybe<SourceEntityResponse>; createSource?: Maybe<SourceEntityResponse>;
createTextualSubtype?: Maybe<TextualSubtypeEntityResponse>; createTextualSubtype?: Maybe<TextualSubtypeEntityResponse>;
createUploadFile?: Maybe<UploadFileEntityResponse>; createUploadFile?: Maybe<UploadFileEntityResponse>;
@ -3044,6 +3113,8 @@ export type Mutation = {
deletePost?: Maybe<PostEntityResponse>; deletePost?: Maybe<PostEntityResponse>;
deleteRangedContent?: Maybe<RangedContentEntityResponse>; deleteRangedContent?: Maybe<RangedContentEntityResponse>;
deleteRecorder?: Maybe<RecorderEntityResponse>; deleteRecorder?: Maybe<RecorderEntityResponse>;
deleteReinCostume?: Maybe<ReinCostumeEntityResponse>;
deleteReinEmblem?: Maybe<ReinEmblemEntityResponse>;
deleteSource?: Maybe<SourceEntityResponse>; deleteSource?: Maybe<SourceEntityResponse>;
deleteTextualSubtype?: Maybe<TextualSubtypeEntityResponse>; deleteTextualSubtype?: Maybe<TextualSubtypeEntityResponse>;
deleteUploadFile?: Maybe<UploadFileEntityResponse>; deleteUploadFile?: Maybe<UploadFileEntityResponse>;
@ -3082,6 +3153,8 @@ export type Mutation = {
updatePost?: Maybe<PostEntityResponse>; updatePost?: Maybe<PostEntityResponse>;
updateRangedContent?: Maybe<RangedContentEntityResponse>; updateRangedContent?: Maybe<RangedContentEntityResponse>;
updateRecorder?: Maybe<RecorderEntityResponse>; updateRecorder?: Maybe<RecorderEntityResponse>;
updateReinCostume?: Maybe<ReinCostumeEntityResponse>;
updateReinEmblem?: Maybe<ReinEmblemEntityResponse>;
updateSource?: Maybe<SourceEntityResponse>; updateSource?: Maybe<SourceEntityResponse>;
updateTextualSubtype?: Maybe<TextualSubtypeEntityResponse>; updateTextualSubtype?: Maybe<TextualSubtypeEntityResponse>;
updateUploadFile?: Maybe<UploadFileEntityResponse>; updateUploadFile?: Maybe<UploadFileEntityResponse>;
@ -3183,6 +3256,14 @@ export type MutationCreateRecorderArgs = {
data: RecorderInput; data: RecorderInput;
}; };
export type MutationCreateReinCostumeArgs = {
data: ReinCostumeInput;
};
export type MutationCreateReinEmblemArgs = {
data: ReinEmblemInput;
};
export type MutationCreateSourceArgs = { export type MutationCreateSourceArgs = {
data: SourceInput; data: SourceInput;
}; };
@ -3323,6 +3404,14 @@ export type MutationDeleteRecorderArgs = {
id: Scalars["ID"]; id: Scalars["ID"];
}; };
export type MutationDeleteReinCostumeArgs = {
id: Scalars["ID"];
};
export type MutationDeleteReinEmblemArgs = {
id: Scalars["ID"];
};
export type MutationDeleteSourceArgs = { export type MutationDeleteSourceArgs = {
id: Scalars["ID"]; id: Scalars["ID"];
}; };
@ -3500,6 +3589,16 @@ export type MutationUpdateRecorderArgs = {
id: Scalars["ID"]; id: Scalars["ID"];
}; };
export type MutationUpdateReinCostumeArgs = {
data: ReinCostumeInput;
id: Scalars["ID"];
};
export type MutationUpdateReinEmblemArgs = {
data: ReinEmblemInput;
id: Scalars["ID"];
};
export type MutationUpdateSourceArgs = { export type MutationUpdateSourceArgs = {
data: SourceInput; data: SourceInput;
id: Scalars["ID"]; id: Scalars["ID"];
@ -3710,6 +3809,10 @@ export type Query = {
rangedContents?: Maybe<RangedContentEntityResponseCollection>; rangedContents?: Maybe<RangedContentEntityResponseCollection>;
recorder?: Maybe<RecorderEntityResponse>; recorder?: Maybe<RecorderEntityResponse>;
recorders?: Maybe<RecorderEntityResponseCollection>; recorders?: Maybe<RecorderEntityResponseCollection>;
reinCostume?: Maybe<ReinCostumeEntityResponse>;
reinCostumes?: Maybe<ReinCostumeEntityResponseCollection>;
reinEmblem?: Maybe<ReinEmblemEntityResponse>;
reinEmblems?: Maybe<ReinEmblemEntityResponseCollection>;
source?: Maybe<SourceEntityResponse>; source?: Maybe<SourceEntityResponse>;
sources?: Maybe<SourceEntityResponseCollection>; sources?: Maybe<SourceEntityResponseCollection>;
textualSubtype?: Maybe<TextualSubtypeEntityResponse>; textualSubtype?: Maybe<TextualSubtypeEntityResponse>;
@ -3950,6 +4053,26 @@ export type QueryRecordersArgs = {
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>; sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
}; };
export type QueryReinCostumeArgs = {
id?: InputMaybe<Scalars["ID"]>;
};
export type QueryReinCostumesArgs = {
filters?: InputMaybe<ReinCostumeFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type QueryReinEmblemArgs = {
id?: InputMaybe<Scalars["ID"]>;
};
export type QueryReinEmblemsArgs = {
filters?: InputMaybe<ReinEmblemFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type QuerySourceArgs = { export type QuerySourceArgs = {
id?: InputMaybe<Scalars["ID"]>; id?: InputMaybe<Scalars["ID"]>;
}; };
@ -4228,6 +4351,121 @@ export type RecorderRelationResponseCollection = {
data: Array<RecorderEntity>; data: Array<RecorderEntity>;
}; };
export type ReinCostume = {
__typename?: "ReinCostume";
createdAt?: Maybe<Scalars["DateTime"]>;
emblem?: Maybe<ReinEmblemEntityResponse>;
slug: Scalars["String"];
sprite?: Maybe<UploadFileEntityResponse>;
thumbnail?: Maybe<UploadFileEntityResponse>;
translations?: Maybe<Array<Maybe<ComponentTranslationsReinCostumes>>>;
updatedAt?: Maybe<Scalars["DateTime"]>;
};
export type ReinCostumeTranslationsArgs = {
filters?: InputMaybe<ComponentTranslationsReinCostumesFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type ReinCostumeEntity = {
__typename?: "ReinCostumeEntity";
attributes?: Maybe<ReinCostume>;
id?: Maybe<Scalars["ID"]>;
};
export type ReinCostumeEntityResponse = {
__typename?: "ReinCostumeEntityResponse";
data?: Maybe<ReinCostumeEntity>;
};
export type ReinCostumeEntityResponseCollection = {
__typename?: "ReinCostumeEntityResponseCollection";
data: Array<ReinCostumeEntity>;
meta: ResponseCollectionMeta;
};
export type ReinCostumeFiltersInput = {
and?: InputMaybe<Array<InputMaybe<ReinCostumeFiltersInput>>>;
createdAt?: InputMaybe<DateTimeFilterInput>;
emblem?: InputMaybe<ReinEmblemFiltersInput>;
id?: InputMaybe<IdFilterInput>;
not?: InputMaybe<ReinCostumeFiltersInput>;
or?: InputMaybe<Array<InputMaybe<ReinCostumeFiltersInput>>>;
slug?: InputMaybe<StringFilterInput>;
translations?: InputMaybe<ComponentTranslationsReinCostumesFiltersInput>;
updatedAt?: InputMaybe<DateTimeFilterInput>;
};
export type ReinCostumeInput = {
emblem?: InputMaybe<Scalars["ID"]>;
slug?: InputMaybe<Scalars["String"]>;
sprite?: InputMaybe<Scalars["ID"]>;
thumbnail?: InputMaybe<Scalars["ID"]>;
translations?: InputMaybe<Array<InputMaybe<ComponentTranslationsReinCostumesInput>>>;
};
export type ReinCostumeRelationResponseCollection = {
__typename?: "ReinCostumeRelationResponseCollection";
data: Array<ReinCostumeEntity>;
};
export type ReinEmblem = {
__typename?: "ReinEmblem";
costumes?: Maybe<ReinCostumeRelationResponseCollection>;
createdAt?: Maybe<Scalars["DateTime"]>;
slug: Scalars["String"];
translations?: Maybe<Array<Maybe<ComponentTranslationsReinEmblems>>>;
updatedAt?: Maybe<Scalars["DateTime"]>;
};
export type ReinEmblemCostumesArgs = {
filters?: InputMaybe<ReinCostumeFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type ReinEmblemTranslationsArgs = {
filters?: InputMaybe<ComponentTranslationsReinEmblemsFiltersInput>;
pagination?: InputMaybe<PaginationArg>;
sort?: InputMaybe<Array<InputMaybe<Scalars["String"]>>>;
};
export type ReinEmblemEntity = {
__typename?: "ReinEmblemEntity";
attributes?: Maybe<ReinEmblem>;
id?: Maybe<Scalars["ID"]>;
};
export type ReinEmblemEntityResponse = {
__typename?: "ReinEmblemEntityResponse";
data?: Maybe<ReinEmblemEntity>;
};
export type ReinEmblemEntityResponseCollection = {
__typename?: "ReinEmblemEntityResponseCollection";
data: Array<ReinEmblemEntity>;
meta: ResponseCollectionMeta;
};
export type ReinEmblemFiltersInput = {
and?: InputMaybe<Array<InputMaybe<ReinEmblemFiltersInput>>>;
costumes?: InputMaybe<ReinCostumeFiltersInput>;
createdAt?: InputMaybe<DateTimeFilterInput>;
id?: InputMaybe<IdFilterInput>;
not?: InputMaybe<ReinEmblemFiltersInput>;
or?: InputMaybe<Array<InputMaybe<ReinEmblemFiltersInput>>>;
slug?: InputMaybe<StringFilterInput>;
translations?: InputMaybe<ComponentTranslationsReinEmblemsFiltersInput>;
updatedAt?: InputMaybe<DateTimeFilterInput>;
};
export type ReinEmblemInput = {
costumes?: InputMaybe<Array<InputMaybe<Scalars["ID"]>>>;
slug?: InputMaybe<Scalars["String"]>;
translations?: InputMaybe<Array<InputMaybe<ComponentTranslationsReinEmblemsInput>>>;
};
export type ResponseCollectionMeta = { export type ResponseCollectionMeta = {
__typename?: "ResponseCollectionMeta"; __typename?: "ResponseCollectionMeta";
pagination: Pagination; pagination: Pagination;
@ -5031,6 +5269,7 @@ export type WebsiteInterface = {
least_popular?: Maybe<Scalars["String"]>; least_popular?: Maybe<Scalars["String"]>;
left_to_right?: Maybe<Scalars["String"]>; left_to_right?: Maybe<Scalars["String"]>;
legality?: Maybe<Scalars["String"]>; legality?: Maybe<Scalars["String"]>;
level_x?: Maybe<Scalars["String"]>;
library?: Maybe<Scalars["String"]>; library?: Maybe<Scalars["String"]>;
library_description?: Maybe<Scalars["String"]>; library_description?: Maybe<Scalars["String"]>;
library_short_description?: Maybe<Scalars["String"]>; library_short_description?: Maybe<Scalars["String"]>;
@ -5065,6 +5304,7 @@ export type WebsiteInterface = {
paper_texture?: Maybe<Scalars["String"]>; paper_texture?: Maybe<Scalars["String"]>;
paperback?: Maybe<Scalars["String"]>; paperback?: Maybe<Scalars["String"]>;
player_name?: Maybe<Scalars["String"]>; player_name?: Maybe<Scalars["String"]>;
player_name_tooltip?: Maybe<Scalars["String"]>;
previous_content?: Maybe<Scalars["String"]>; previous_content?: Maybe<Scalars["String"]>;
price?: Maybe<Scalars["String"]>; price?: Maybe<Scalars["String"]>;
primary_language?: Maybe<Scalars["String"]>; primary_language?: Maybe<Scalars["String"]>;
@ -5111,6 +5351,7 @@ export type WebsiteInterface = {
status_draft?: Maybe<Scalars["String"]>; status_draft?: Maybe<Scalars["String"]>;
status_incomplete?: Maybe<Scalars["String"]>; status_incomplete?: Maybe<Scalars["String"]>;
status_review?: Maybe<Scalars["String"]>; status_review?: Maybe<Scalars["String"]>;
story_x?: Maybe<Scalars["String"]>;
subitem?: Maybe<Scalars["String"]>; subitem?: Maybe<Scalars["String"]>;
subitem_of_x?: Maybe<Scalars["String"]>; subitem_of_x?: Maybe<Scalars["String"]>;
subscribers?: Maybe<Scalars["String"]>; subscribers?: Maybe<Scalars["String"]>;
@ -5139,6 +5380,8 @@ export type WebsiteInterface = {
view_scans?: Maybe<Scalars["String"]>; view_scans?: Maybe<Scalars["String"]>;
want_it?: Maybe<Scalars["String"]>; want_it?: Maybe<Scalars["String"]>;
watch_content?: Maybe<Scalars["String"]>; watch_content?: Maybe<Scalars["String"]>;
weapon?: Maybe<Scalars["String"]>;
weapons_description?: Maybe<Scalars["String"]>;
width?: Maybe<Scalars["String"]>; width?: Maybe<Scalars["String"]>;
wiki?: Maybe<Scalars["String"]>; wiki?: Maybe<Scalars["String"]>;
wiki_description?: Maybe<Scalars["String"]>; wiki_description?: Maybe<Scalars["String"]>;
@ -5233,6 +5476,7 @@ export type WebsiteInterfaceFiltersInput = {
least_popular?: InputMaybe<StringFilterInput>; least_popular?: InputMaybe<StringFilterInput>;
left_to_right?: InputMaybe<StringFilterInput>; left_to_right?: InputMaybe<StringFilterInput>;
legality?: InputMaybe<StringFilterInput>; legality?: InputMaybe<StringFilterInput>;
level_x?: InputMaybe<StringFilterInput>;
library?: InputMaybe<StringFilterInput>; library?: InputMaybe<StringFilterInput>;
library_description?: InputMaybe<StringFilterInput>; library_description?: InputMaybe<StringFilterInput>;
library_short_description?: InputMaybe<StringFilterInput>; library_short_description?: InputMaybe<StringFilterInput>;
@ -5269,6 +5513,7 @@ export type WebsiteInterfaceFiltersInput = {
paper_texture?: InputMaybe<StringFilterInput>; paper_texture?: InputMaybe<StringFilterInput>;
paperback?: InputMaybe<StringFilterInput>; paperback?: InputMaybe<StringFilterInput>;
player_name?: InputMaybe<StringFilterInput>; player_name?: InputMaybe<StringFilterInput>;
player_name_tooltip?: InputMaybe<StringFilterInput>;
previous_content?: InputMaybe<StringFilterInput>; previous_content?: InputMaybe<StringFilterInput>;
price?: InputMaybe<StringFilterInput>; price?: InputMaybe<StringFilterInput>;
primary_language?: InputMaybe<StringFilterInput>; primary_language?: InputMaybe<StringFilterInput>;
@ -5315,6 +5560,7 @@ export type WebsiteInterfaceFiltersInput = {
status_draft?: InputMaybe<StringFilterInput>; status_draft?: InputMaybe<StringFilterInput>;
status_incomplete?: InputMaybe<StringFilterInput>; status_incomplete?: InputMaybe<StringFilterInput>;
status_review?: InputMaybe<StringFilterInput>; status_review?: InputMaybe<StringFilterInput>;
story_x?: InputMaybe<StringFilterInput>;
subitem?: InputMaybe<StringFilterInput>; subitem?: InputMaybe<StringFilterInput>;
subitem_of_x?: InputMaybe<StringFilterInput>; subitem_of_x?: InputMaybe<StringFilterInput>;
subscribers?: InputMaybe<StringFilterInput>; subscribers?: InputMaybe<StringFilterInput>;
@ -5343,6 +5589,8 @@ export type WebsiteInterfaceFiltersInput = {
view_scans?: InputMaybe<StringFilterInput>; view_scans?: InputMaybe<StringFilterInput>;
want_it?: InputMaybe<StringFilterInput>; want_it?: InputMaybe<StringFilterInput>;
watch_content?: InputMaybe<StringFilterInput>; watch_content?: InputMaybe<StringFilterInput>;
weapon?: InputMaybe<StringFilterInput>;
weapons_description?: InputMaybe<StringFilterInput>;
width?: InputMaybe<StringFilterInput>; width?: InputMaybe<StringFilterInput>;
wiki?: InputMaybe<StringFilterInput>; wiki?: InputMaybe<StringFilterInput>;
wiki_description?: InputMaybe<StringFilterInput>; wiki_description?: InputMaybe<StringFilterInput>;
@ -5417,6 +5665,7 @@ export type WebsiteInterfaceInput = {
least_popular?: InputMaybe<Scalars["String"]>; least_popular?: InputMaybe<Scalars["String"]>;
left_to_right?: InputMaybe<Scalars["String"]>; left_to_right?: InputMaybe<Scalars["String"]>;
legality?: InputMaybe<Scalars["String"]>; legality?: InputMaybe<Scalars["String"]>;
level_x?: InputMaybe<Scalars["String"]>;
library?: InputMaybe<Scalars["String"]>; library?: InputMaybe<Scalars["String"]>;
library_description?: InputMaybe<Scalars["String"]>; library_description?: InputMaybe<Scalars["String"]>;
library_short_description?: InputMaybe<Scalars["String"]>; library_short_description?: InputMaybe<Scalars["String"]>;
@ -5451,6 +5700,7 @@ export type WebsiteInterfaceInput = {
paper_texture?: InputMaybe<Scalars["String"]>; paper_texture?: InputMaybe<Scalars["String"]>;
paperback?: InputMaybe<Scalars["String"]>; paperback?: InputMaybe<Scalars["String"]>;
player_name?: InputMaybe<Scalars["String"]>; player_name?: InputMaybe<Scalars["String"]>;
player_name_tooltip?: InputMaybe<Scalars["String"]>;
previous_content?: InputMaybe<Scalars["String"]>; previous_content?: InputMaybe<Scalars["String"]>;
price?: InputMaybe<Scalars["String"]>; price?: InputMaybe<Scalars["String"]>;
primary_language?: InputMaybe<Scalars["String"]>; primary_language?: InputMaybe<Scalars["String"]>;
@ -5497,6 +5747,7 @@ export type WebsiteInterfaceInput = {
status_draft?: InputMaybe<Scalars["String"]>; status_draft?: InputMaybe<Scalars["String"]>;
status_incomplete?: InputMaybe<Scalars["String"]>; status_incomplete?: InputMaybe<Scalars["String"]>;
status_review?: InputMaybe<Scalars["String"]>; status_review?: InputMaybe<Scalars["String"]>;
story_x?: InputMaybe<Scalars["String"]>;
subitem?: InputMaybe<Scalars["String"]>; subitem?: InputMaybe<Scalars["String"]>;
subitem_of_x?: InputMaybe<Scalars["String"]>; subitem_of_x?: InputMaybe<Scalars["String"]>;
subscribers?: InputMaybe<Scalars["String"]>; subscribers?: InputMaybe<Scalars["String"]>;
@ -5524,6 +5775,8 @@ export type WebsiteInterfaceInput = {
view_scans?: InputMaybe<Scalars["String"]>; view_scans?: InputMaybe<Scalars["String"]>;
want_it?: InputMaybe<Scalars["String"]>; want_it?: InputMaybe<Scalars["String"]>;
watch_content?: InputMaybe<Scalars["String"]>; watch_content?: InputMaybe<Scalars["String"]>;
weapon?: InputMaybe<Scalars["String"]>;
weapons_description?: InputMaybe<Scalars["String"]>;
width?: InputMaybe<Scalars["String"]>; width?: InputMaybe<Scalars["String"]>;
wiki?: InputMaybe<Scalars["String"]>; wiki?: InputMaybe<Scalars["String"]>;
wiki_description?: InputMaybe<Scalars["String"]>; wiki_description?: InputMaybe<Scalars["String"]>;