Compare commits
1 Commits
main
...
rein-costu
Author | SHA1 | Date |
---|---|---|
DrMint | 5adae32429 |
|
@ -0,0 +1,27 @@
|
||||||
|
fragment reinCostume on ReinCostume {
|
||||||
|
slug
|
||||||
|
sprite {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
...uploadImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translations {
|
||||||
|
id
|
||||||
|
language {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name
|
||||||
|
description
|
||||||
|
}
|
||||||
|
emblem {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
query getReinCostumes {
|
||||||
|
reinCostumes(pagination: { limit: -1 }) {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
sprite {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
...uploadImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
translations {
|
||||||
|
id
|
||||||
|
language {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name
|
||||||
|
description
|
||||||
|
}
|
||||||
|
emblem {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
query getReinCostumesWithoutEmblem {
|
||||||
|
reinCostumes(filters: { emblem: { id: { null: true } } }, pagination: { limit: -1 }) {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
attributes {
|
||||||
|
...reinCostume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
query getReinEmblem($slug: String) {
|
||||||
|
reinEmblems(filters: { slug: { eq: $slug } }) {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
translations {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
language {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
costumes {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
attributes {
|
||||||
|
...reinCostume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
query getReinEmblems {
|
||||||
|
reinEmblems(pagination: { limit: -1 }) {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
translations {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
language {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
query getReinEmblemsSlugs {
|
||||||
|
reinEmblems(pagination: { limit: -1 }) {
|
||||||
|
data {
|
||||||
|
id
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -167,6 +167,13 @@ const Wiki = (props: Props): JSX.Element => {
|
||||||
onClick={closeSubPanel}
|
onClick={closeSubPanel}
|
||||||
border
|
border
|
||||||
/>
|
/>
|
||||||
|
<NavOption
|
||||||
|
title={"Re[in]carnation"}
|
||||||
|
subtitle={format("costume", { count: Infinity })}
|
||||||
|
url="/wiki/rein/costumes"
|
||||||
|
onClick={closeSubPanel}
|
||||||
|
border
|
||||||
|
/>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
import { GetStaticProps } from "next";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import Markdown from "markdown-to-jsx";
|
||||||
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
|
import { getFormat } from "helpers/i18n";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
import { ReinCostume, ReinEmblemCostume } from "types/types";
|
||||||
|
import { getReadySdk } from "graphql/sdk";
|
||||||
|
import { filterHasAttributes, isDefinedAndNotEmpty, isUndefined } from "helpers/asserts";
|
||||||
|
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
|
||||||
|
import { TranslatedProps } from "types/TranslatedProps";
|
||||||
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
|
import { prettySlug } from "helpers/formatters";
|
||||||
|
import { ElementsSeparator } from "helpers/component";
|
||||||
|
import { SubPanel } from "components/Containers/SubPanel";
|
||||||
|
import { ReturnButton } from "components/PanelComponents/ReturnButton";
|
||||||
|
import { useFormat } from "hooks/useFormat";
|
||||||
|
import { PanelHeader } from "components/PanelComponents/PanelHeader";
|
||||||
|
import { TranslatedNavOption } from "components/PanelComponents/NavOption";
|
||||||
|
import { Img } from "components/Img";
|
||||||
|
import { TranslatedPreviewCard } from "components/PreviewCard";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ╭────────╮
|
||||||
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface Props extends AppLayoutRequired {
|
||||||
|
emblems: ReinEmblemCostume[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReincarnationCostumes = ({ emblems, ...otherProps }: Props): JSX.Element => {
|
||||||
|
const { format } = useFormat();
|
||||||
|
|
||||||
|
const subPanel = (
|
||||||
|
<SubPanel>
|
||||||
|
<ElementsSeparator>
|
||||||
|
{[
|
||||||
|
<>
|
||||||
|
<ReturnButton
|
||||||
|
href="/wiki"
|
||||||
|
title={format("wiki")}
|
||||||
|
displayOnlyOn="3ColumnsLayout"
|
||||||
|
className="mb-10"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PanelHeader
|
||||||
|
icon="accessibility_new"
|
||||||
|
title={format("costume", { count: Infinity })}
|
||||||
|
description={format("costume_description")}
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
|
||||||
|
<>
|
||||||
|
{emblems.map((emblem) => (
|
||||||
|
<TranslatedNavOption
|
||||||
|
key={emblem.id}
|
||||||
|
translations={filterHasAttributes(emblem.attributes.translations, [
|
||||||
|
"language.data.attributes.code",
|
||||||
|
] as const).map((translation) => ({
|
||||||
|
language: translation.language.data.attributes.code,
|
||||||
|
title: translation.name,
|
||||||
|
}))}
|
||||||
|
fallback={{ title: prettySlug(emblem.attributes.slug) }}
|
||||||
|
url={`#${emblem.attributes.slug}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>,
|
||||||
|
]}
|
||||||
|
</ElementsSeparator>
|
||||||
|
</SubPanel>
|
||||||
|
);
|
||||||
|
|
||||||
|
const contentPanel = (
|
||||||
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
<div className="grid gap-12">
|
||||||
|
<ElementsSeparator>
|
||||||
|
{emblems.map((emblem) => (
|
||||||
|
<TranslatedEmblemCostume
|
||||||
|
key={emblem.id}
|
||||||
|
translations={filterHasAttributes(emblem.attributes.translations, [
|
||||||
|
"language.data.attributes.code",
|
||||||
|
] as const).map((translation) => ({
|
||||||
|
language: translation.language.data.attributes.code,
|
||||||
|
title: translation.name,
|
||||||
|
description: translation.description,
|
||||||
|
}))}
|
||||||
|
fallback={{ title: prettySlug(emblem.attributes.slug) }}
|
||||||
|
slug={emblem.attributes.slug}
|
||||||
|
costumes={emblem.attributes.costumes}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ElementsSeparator>
|
||||||
|
</div>
|
||||||
|
</ContentPanel>
|
||||||
|
);
|
||||||
|
|
||||||
|
return <AppLayout subPanel={subPanel} contentPanel={contentPanel} {...otherProps} />;
|
||||||
|
};
|
||||||
|
export default ReincarnationCostumes;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ╭──────────────────────╮
|
||||||
|
* ───────────────────────────────────╯ NEXT DATA FETCHING ╰──────────────────────────────────────
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const sdk = getReadySdk();
|
||||||
|
const { format } = getFormat(context.locale);
|
||||||
|
|
||||||
|
const emblems = (await sdk.getReinEmblems()).reinEmblems?.data;
|
||||||
|
const costumes = (await sdk.getReinCostumes()).reinCostumes?.data;
|
||||||
|
|
||||||
|
if (isUndefined(emblems) || isUndefined(costumes)) {
|
||||||
|
return { notFound: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const processedEmblems: ReinEmblemCostume[] = [];
|
||||||
|
|
||||||
|
filterHasAttributes(emblems, ["id", "attributes"] as const).forEach(({ id, attributes }) => {
|
||||||
|
const costumesOfCurrentEmblem = costumes.filter(
|
||||||
|
(costume) => costume.attributes?.emblem?.data?.id === id
|
||||||
|
);
|
||||||
|
const emblemCostume: ReinEmblemCostume = {
|
||||||
|
id,
|
||||||
|
attributes: { ...attributes, costumes: costumesOfCurrentEmblem },
|
||||||
|
};
|
||||||
|
processedEmblems.push(emblemCostume);
|
||||||
|
});
|
||||||
|
|
||||||
|
const costumesWithoutEmblem = costumes.filter((costume) =>
|
||||||
|
isUndefined(costume.attributes?.emblem?.data)
|
||||||
|
);
|
||||||
|
|
||||||
|
processedEmblems.push({
|
||||||
|
id: "others",
|
||||||
|
attributes: { slug: "others", costumes: costumesWithoutEmblem },
|
||||||
|
});
|
||||||
|
|
||||||
|
const props: Props = {
|
||||||
|
emblems: processedEmblems,
|
||||||
|
openGraph: getOpenGraph(format, format("costume", { count: Infinity })),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
props: props,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ╭──────────────────────╮
|
||||||
|
* ───────────────────────────────────╯ PRIVATE COMPONENTS ╰──────────────────────────────────────
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface EmblemCostumeProps {
|
||||||
|
slug: string;
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
costumes: ReinCostume[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const EmblemCostume = ({ slug, title, description, costumes }: EmblemCostumeProps): JSX.Element => (
|
||||||
|
<div>
|
||||||
|
<h2 id={slug} className="text-2xl">
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
{isDefinedAndNotEmpty(description) && <Markdown>{description}</Markdown>}
|
||||||
|
<div className="grid grid-cols-[repeat(auto-fill,_minmax(12rem,1fr))] items-end gap-x-6 gap-y-8">
|
||||||
|
{costumes.map((costume) => (
|
||||||
|
<TranslatedPreviewCard
|
||||||
|
key={costume.id}
|
||||||
|
translations={filterHasAttributes(costume.attributes?.translations, [
|
||||||
|
"language.data.attributes.code",
|
||||||
|
] as const).map((translation) => ({
|
||||||
|
language: translation.language.data.attributes.code,
|
||||||
|
title: translation.name,
|
||||||
|
}))}
|
||||||
|
thumbnail={costume.attributes?.sprite?.data?.attributes}
|
||||||
|
keepInfoVisible
|
||||||
|
thumbnailAspectRatio="1/1"
|
||||||
|
thumbnailForceAspectRatio
|
||||||
|
thumbnailFitMethod="contain"
|
||||||
|
fallback={{ title: prettySlug(costume.attributes?.slug) }}
|
||||||
|
href="#"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const TranslatedEmblemCostume = ({
|
||||||
|
translations,
|
||||||
|
fallback,
|
||||||
|
...otherProps
|
||||||
|
}: TranslatedProps<EmblemCostumeProps, "description" | "title">): JSX.Element => {
|
||||||
|
const [selectedTranslation] = useSmartLanguage({
|
||||||
|
items: translations,
|
||||||
|
languageExtractor: useCallback((item: { language: string }): string => item.language, []),
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<EmblemCostume
|
||||||
|
title={selectedTranslation?.title ?? fallback.title}
|
||||||
|
description={selectedTranslation?.description ?? fallback.description}
|
||||||
|
{...otherProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,148 @@
|
||||||
|
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||||
|
import Markdown from "markdown-to-jsx";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import { getReadySdk } from "graphql/sdk";
|
||||||
|
import { filterHasAttributes, isDefined, isDefinedAndNotEmpty, isUndefined } from "helpers/asserts";
|
||||||
|
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
|
||||||
|
import { useFormat } from "hooks/useFormat";
|
||||||
|
import { GetReinEmblemQuery, ReinCostumeFragment } from "graphql/generated";
|
||||||
|
import { ContentPanel, ContentPanelWidthSizes } from "components/Containers/ContentPanel";
|
||||||
|
import { Img } from "components/Img";
|
||||||
|
import { TranslatedProps } from "types/TranslatedProps";
|
||||||
|
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||||
|
import { prettySlug } from "helpers/formatters";
|
||||||
|
import { getFormat } from "helpers/i18n";
|
||||||
|
import { getOpenGraph } from "helpers/openGraph";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ╭────────╮
|
||||||
|
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface Props extends AppLayoutRequired {
|
||||||
|
emblem: NonNullable<
|
||||||
|
NonNullable<NonNullable<GetReinEmblemQuery["reinEmblems"]>["data"][number]>["attributes"]
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReinEmblem = ({ emblem, ...otherProps }: Props): JSX.Element => {
|
||||||
|
const { format } = useFormat();
|
||||||
|
|
||||||
|
const contentPanel = (
|
||||||
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
|
<div>
|
||||||
|
<TranslatedEmblemCostume
|
||||||
|
translations={filterHasAttributes(emblem.translations, [
|
||||||
|
"language.data.attributes.code",
|
||||||
|
] as const).map((translation) => ({
|
||||||
|
language: translation.language.data.attributes.code,
|
||||||
|
title: translation.name,
|
||||||
|
description: translation.description,
|
||||||
|
}))}
|
||||||
|
fallback={{ title: prettySlug(emblem.slug) }}
|
||||||
|
slug={emblem.slug}
|
||||||
|
costumes={filterHasAttributes(emblem.costumes?.data, ["attributes"] as const).map(
|
||||||
|
(costume) => costume.attributes
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ContentPanel>
|
||||||
|
);
|
||||||
|
|
||||||
|
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
|
||||||
|
};
|
||||||
|
export default ReinEmblem;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ╭──────────────────────╮
|
||||||
|
* ───────────────────────────────────╯ NEXT DATA FETCHING ╰──────────────────────────────────────
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = async (context) => {
|
||||||
|
const sdk = getReadySdk();
|
||||||
|
const { format } = getFormat(context.locale);
|
||||||
|
|
||||||
|
const slug =
|
||||||
|
context.params && isDefined(context.params.slug) ? context.params.slug.toString() : "";
|
||||||
|
const emblem = (await sdk.getReinEmblem({ slug })).reinEmblems?.data?.[0]?.attributes;
|
||||||
|
|
||||||
|
if (isUndefined(emblem)) {
|
||||||
|
return { notFound: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const props: Props = {
|
||||||
|
emblem,
|
||||||
|
openGraph: getOpenGraph(format, format("costume", { count: Infinity })),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
props: props,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
|
export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
|
const sdk = getReadySdk();
|
||||||
|
const contents = await sdk.getReinEmblemsSlugs();
|
||||||
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
|
filterHasAttributes(contents.reinEmblems?.data, ["attributes"] as const).map((emblem) => {
|
||||||
|
context.locales?.map((local) =>
|
||||||
|
paths.push({
|
||||||
|
params: { slug: emblem.attributes.slug },
|
||||||
|
locale: local,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
paths,
|
||||||
|
fallback: "blocking",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ╭──────────────────────╮
|
||||||
|
* ───────────────────────────────────╯ PRIVATE COMPONENTS ╰──────────────────────────────────────
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface EmblemCostumeProps {
|
||||||
|
slug: string;
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
costumes: ReinCostumeFragment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const EmblemCostume = ({ slug, title, description, costumes }: EmblemCostumeProps): JSX.Element => (
|
||||||
|
<div>
|
||||||
|
<h2 id={slug} className="text-2xl">
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
{isDefinedAndNotEmpty(description) && <Markdown>{description}</Markdown>}
|
||||||
|
<div className="grid grid-cols-[repeat(auto-fill,_minmax(12rem,1fr))] items-start gap-x-6 gap-y-8">
|
||||||
|
{costumes.map((costume) => (
|
||||||
|
<div key={costume.slug}>
|
||||||
|
{costume.sprite?.data?.attributes && <Img src={costume.sprite.data.attributes} />}
|
||||||
|
<h3 className="text-xl">{costume.translations?.[0]?.name}</h3>
|
||||||
|
<Markdown>{costume.translations?.[0]?.description ?? ""}</Markdown>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const TranslatedEmblemCostume = ({
|
||||||
|
translations,
|
||||||
|
fallback,
|
||||||
|
...otherProps
|
||||||
|
}: TranslatedProps<EmblemCostumeProps, "description" | "title">): JSX.Element => {
|
||||||
|
const [selectedTranslation] = useSmartLanguage({
|
||||||
|
items: translations,
|
||||||
|
languageExtractor: useCallback((item: { language: string }): string => item.language, []),
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<EmblemCostume
|
||||||
|
title={selectedTranslation?.title ?? fallback.title}
|
||||||
|
description={selectedTranslation?.description ?? fallback.description}
|
||||||
|
{...otherProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -2,6 +2,8 @@ import {
|
||||||
GetChronicleQuery,
|
GetChronicleQuery,
|
||||||
GetContentTextQuery,
|
GetContentTextQuery,
|
||||||
GetPostQuery,
|
GetPostQuery,
|
||||||
|
GetReinCostumesQuery,
|
||||||
|
GetReinEmblemsQuery,
|
||||||
GetWeaponQuery,
|
GetWeaponQuery,
|
||||||
GetWikiPageQuery,
|
GetWikiPageQuery,
|
||||||
} from "graphql/generated";
|
} from "graphql/generated";
|
||||||
|
@ -68,6 +70,17 @@ export type WeaponGroupPreview = NonNullable<
|
||||||
|
|
||||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
|
type ReinEmblem = NonNullable<GetReinEmblemsQuery["reinEmblems"]>["data"][number];
|
||||||
|
|
||||||
|
export type ReinCostume = NonNullable<GetReinCostumesQuery["reinCostumes"]>["data"][number];
|
||||||
|
|
||||||
|
export type ReinEmblemCostume = {
|
||||||
|
id: ReinEmblem["id"];
|
||||||
|
attributes: NonNullable<ReinEmblem["attributes"]> & { costumes: ReinCostume[] };
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
export enum LibraryItemUserStatus {
|
export enum LibraryItemUserStatus {
|
||||||
None = 0,
|
None = 0,
|
||||||
Want = 1,
|
Want = 1,
|
||||||
|
|
Loading…
Reference in New Issue