Fixed bugs + translated components
This commit is contained in:
parent
930da37d64
commit
0df66815c8
|
@ -51,7 +51,7 @@ interface Props {
|
|||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
const ScanSet = ({
|
||||
export const ScanSet = ({
|
||||
openLightBox,
|
||||
scanSet,
|
||||
id,
|
||||
|
@ -138,7 +138,9 @@ const ScanSet = ({
|
|||
/>
|
||||
)}
|
||||
|
||||
<LanguageSwitcher {...languageSwitcherProps} />
|
||||
{languageSwitcherProps.locales.size > 1 && (
|
||||
<LanguageSwitcher {...languageSwitcherProps} />
|
||||
)}
|
||||
|
||||
<div className="grid place-content-center place-items-center">
|
||||
<p className="font-headers font-bold">{langui.status}:</p>
|
||||
|
@ -242,40 +244,3 @@ const ScanSet = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
interface TranslatedProps extends Omit<Props, "title"> {
|
||||
translations: {
|
||||
title: string;
|
||||
language: string;
|
||||
}[];
|
||||
fallbackTitle: TranslatedProps["translations"][number]["title"];
|
||||
languages: AppStaticProps["languages"];
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedScanSet = ({
|
||||
fallbackTitle,
|
||||
translations = [{ title: fallbackTitle, language: "default" }],
|
||||
languages,
|
||||
...otherProps
|
||||
}: TranslatedProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: useCallback(
|
||||
(item: TranslatedProps["translations"][number]) => item.language,
|
||||
[]
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<ScanSet
|
||||
title={selectedTranslation?.title ?? fallbackTitle}
|
||||
languages={languages}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { useRouter } from "next/router";
|
||||
import { MouseEventHandler, useCallback, useMemo } from "react";
|
||||
import { MouseEventHandler, useMemo } from "react";
|
||||
import { Ico, Icon } from "components/Ico";
|
||||
import { ToolTip } from "components/ToolTip";
|
||||
import { cJoin, cIf } from "helpers/className";
|
||||
import { isDefinedAndNotEmpty } from "helpers/others";
|
||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
|
@ -90,45 +88,3 @@ export const NavOption = ({
|
|||
</ToolTip>
|
||||
);
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
interface TranslatedProps extends Omit<Props, "subtitle" | "title"> {
|
||||
translations: {
|
||||
title: string | null | undefined;
|
||||
subtitle?: string | null | undefined;
|
||||
language: string;
|
||||
}[];
|
||||
fallbackTitle: TranslatedProps["translations"][number]["title"];
|
||||
fallbackSubtitle: TranslatedProps["translations"][number]["subtitle"];
|
||||
languages: AppStaticProps["languages"];
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedNavOption = ({
|
||||
fallbackTitle,
|
||||
fallbackSubtitle,
|
||||
translations = [
|
||||
{ title: fallbackTitle, subtitle: fallbackSubtitle, language: "default" },
|
||||
],
|
||||
languages,
|
||||
...otherProps
|
||||
}: TranslatedProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: useCallback(
|
||||
(item: TranslatedProps["translations"][number]) => item.language,
|
||||
[]
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<NavOption
|
||||
title={selectedTranslation?.title ?? fallbackTitle}
|
||||
subtitle={selectedTranslation?.subtitle ?? fallbackSubtitle}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Link from "next/link";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { Chip } from "./Chip";
|
||||
import { Ico, Icon } from "./Ico";
|
||||
import { Img } from "./Img";
|
||||
|
@ -16,10 +16,9 @@ import {
|
|||
prettyDuration,
|
||||
prettyPrice,
|
||||
prettyShortenNumber,
|
||||
prettySlug,
|
||||
} from "helpers/formatters";
|
||||
import { ImageQuality } from "helpers/img";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
import { useMediaHoverable } from "hooks/useMediaQuery";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
|
@ -78,6 +77,7 @@ export const PreviewCard = ({
|
|||
infoAppend,
|
||||
}: Props): JSX.Element => {
|
||||
const { currency } = useAppLayout();
|
||||
const isHoverable = useMediaHoverable();
|
||||
|
||||
const metadataJSX = useMemo(
|
||||
() => (
|
||||
|
@ -247,7 +247,7 @@ export const PreviewCard = ({
|
|||
className={cJoin(
|
||||
"z-20 grid gap-2 p-4 transition-opacity linearbg-obi",
|
||||
cIf(
|
||||
!keepInfoVisible,
|
||||
!keepInfoVisible && isHoverable,
|
||||
`-inset-x-0.5 bottom-2 opacity-0 [border-radius:10%_10%_10%_10%_/_1%_1%_3%_3%]
|
||||
group-hover:opacity-100 hoverable:absolute hoverable:drop-shadow-shade-lg
|
||||
notHoverable:rounded-b-md notHoverable:opacity-100`,
|
||||
|
@ -291,46 +291,3 @@ export const PreviewCard = ({
|
|||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
interface TranslatedProps
|
||||
extends Omit<Props, "description" | "pre_title" | "subtitle" | "title"> {
|
||||
translations: {
|
||||
pre_title?: string | null | undefined;
|
||||
title: string | null | undefined;
|
||||
subtitle?: string | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
language: string | undefined;
|
||||
}[];
|
||||
slug: string;
|
||||
languages: AppStaticProps["languages"];
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedPreviewCard = ({
|
||||
slug,
|
||||
translations = [{ title: slug, language: "default" }],
|
||||
languages,
|
||||
...otherProps
|
||||
}: TranslatedProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: useCallback(
|
||||
(item: TranslatedProps["translations"][number]) => item.language,
|
||||
[]
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<PreviewCard
|
||||
pre_title={selectedTranslation?.pre_title}
|
||||
title={selectedTranslation?.title ?? prettySlug(slug)}
|
||||
subtitle={selectedTranslation?.subtitle}
|
||||
description={selectedTranslation?.description}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
import Link from "next/link";
|
||||
import { useCallback } from "react";
|
||||
import { Chip } from "./Chip";
|
||||
import { Img } from "./Img";
|
||||
import { UploadImageFragment } from "graphql/generated";
|
||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||
import { prettySlug } from "helpers/formatters";
|
||||
import { ImageQuality } from "helpers/img";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
|
@ -26,7 +22,7 @@ interface Props {
|
|||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
const PreviewLine = ({
|
||||
export const PreviewLine = ({
|
||||
href,
|
||||
thumbnail,
|
||||
pre_title,
|
||||
|
@ -76,45 +72,3 @@ const PreviewLine = ({
|
|||
</div>
|
||||
</Link>
|
||||
);
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
interface TranslatedProps
|
||||
extends Omit<Props, "pre_title" | "subtitle" | "title"> {
|
||||
translations: {
|
||||
pre_title?: string | null | undefined;
|
||||
title: string | null | undefined;
|
||||
subtitle?: string | null | undefined;
|
||||
language: string | undefined;
|
||||
}[];
|
||||
|
||||
slug: string;
|
||||
languages: AppStaticProps["languages"];
|
||||
}
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedPreviewLine = ({
|
||||
slug,
|
||||
translations = [{ title: slug, language: "default" }],
|
||||
languages,
|
||||
...otherProps
|
||||
}: TranslatedProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: useCallback(
|
||||
(item: TranslatedProps["translations"][number]) => item.language,
|
||||
[]
|
||||
),
|
||||
});
|
||||
|
||||
return (
|
||||
<PreviewLine
|
||||
pre_title={selectedTranslation?.pre_title}
|
||||
title={selectedTranslation?.title ?? prettySlug(slug)}
|
||||
subtitle={selectedTranslation?.subtitle}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ export const RecorderChip = ({ recorder, langui }: Props): JSX.Element => (
|
|||
{filterHasAttributes(recorder.languages.data, [
|
||||
"attributes",
|
||||
] as const).map((language) => (
|
||||
<Fragment key={language.attributes.code}>
|
||||
<Fragment key={language.__typename}>
|
||||
<Chip text={language.attributes.code.toUpperCase()} />
|
||||
</Fragment>
|
||||
))}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
import { PreviewCard } from "./PreviewCard";
|
||||
import { PreviewLine } from "./PreviewLine";
|
||||
import { ScanSet } from "./Library/ScanSet";
|
||||
import { NavOption } from "./PanelComponents/NavOption";
|
||||
import { AppStaticProps } from "graphql/getAppStaticProps";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
|
||||
type TranslatedProps<P, K extends keyof P> = Omit<P, K> & {
|
||||
translations: (Pick<P, K> & { language: string })[];
|
||||
fallback: Pick<P, K>;
|
||||
languages: AppStaticProps["languages"];
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
type TranslatedPreviewCardProps = TranslatedProps<
|
||||
Parameters<typeof PreviewCard>[0],
|
||||
"description" | "pre_title" | "subtitle" | "title"
|
||||
>;
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedPreviewCard = ({
|
||||
translations,
|
||||
languages,
|
||||
fallback,
|
||||
...otherProps
|
||||
}: TranslatedPreviewCardProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: (item) => item.language,
|
||||
});
|
||||
|
||||
return (
|
||||
<PreviewCard
|
||||
pre_title={selectedTranslation?.pre_title ?? fallback.pre_title}
|
||||
title={selectedTranslation?.title ?? fallback.title}
|
||||
subtitle={selectedTranslation?.subtitle ?? fallback.subtitle}
|
||||
description={selectedTranslation?.description ?? fallback.description}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
type TranslatedPreviewLineProps = TranslatedProps<
|
||||
Parameters<typeof PreviewLine>[0],
|
||||
"pre_title" | "subtitle" | "title"
|
||||
>;
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedPreviewLine = ({
|
||||
translations,
|
||||
languages,
|
||||
fallback,
|
||||
...otherProps
|
||||
}: TranslatedPreviewLineProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: (item) => item.language,
|
||||
});
|
||||
|
||||
return (
|
||||
<PreviewLine
|
||||
pre_title={selectedTranslation?.pre_title ?? fallback.pre_title}
|
||||
title={selectedTranslation?.title ?? fallback.title}
|
||||
subtitle={selectedTranslation?.subtitle ?? fallback.subtitle}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
type TranslatedScanSetProps = TranslatedProps<
|
||||
Parameters<typeof ScanSet>[0],
|
||||
"title"
|
||||
>;
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedScanSet = ({
|
||||
translations,
|
||||
languages,
|
||||
fallback,
|
||||
...otherProps
|
||||
}: TranslatedScanSetProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: (item) => item.language,
|
||||
});
|
||||
|
||||
return (
|
||||
<ScanSet
|
||||
title={selectedTranslation?.title ?? fallback.title}
|
||||
languages={languages}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
type TranslatedNavOptionProps = TranslatedProps<
|
||||
Parameters<typeof NavOption>[0],
|
||||
"subtitle" | "title"
|
||||
>;
|
||||
|
||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
|
||||
export const TranslatedNavOption = ({
|
||||
translations,
|
||||
languages,
|
||||
fallback,
|
||||
...otherProps
|
||||
}: TranslatedNavOptionProps): JSX.Element => {
|
||||
const [selectedTranslation] = useSmartLanguage({
|
||||
items: translations,
|
||||
languages: languages,
|
||||
languageExtractor: (item) => item.language,
|
||||
});
|
||||
|
||||
return (
|
||||
<NavOption
|
||||
title={selectedTranslation?.title ?? fallback.title}
|
||||
subtitle={selectedTranslation?.subtitle ?? fallback.subtitle}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -75,22 +75,27 @@ export const filterHasAttributes = <T, P extends PathDot<T>>(
|
|||
t: T[] | null | undefined,
|
||||
paths: readonly P[]
|
||||
): SelectiveNonNullable<T, typeof paths[number]>[] =>
|
||||
isUndefined(t)
|
||||
? []
|
||||
: (t.filter((item) =>
|
||||
isDefined(t)
|
||||
? (t.filter((item) =>
|
||||
hasAttributes(item, paths)
|
||||
) as unknown as SelectiveNonNullable<T, typeof paths[number]>[]);
|
||||
) as unknown as SelectiveNonNullable<T, typeof paths[number]>[])
|
||||
: [];
|
||||
|
||||
const hasAttributes = <T>(item: T, paths: readonly PathDot<T>[]): boolean => {
|
||||
const hasAttributes = <T>(item: T, paths: readonly PathDot<T>[]): boolean =>
|
||||
isDefined(item) && paths.every((path) => hasAttribute(item, path));
|
||||
|
||||
const hasAttribute = <T>(item: T, path: string): boolean => {
|
||||
if (isDefined(item)) {
|
||||
return paths.every((path) => {
|
||||
const attributeToCheck = (path as string).split(".")[0];
|
||||
return (
|
||||
isDefined(attributeToCheck) &&
|
||||
Object.keys(item).includes(attributeToCheck) &&
|
||||
isDefined(item[attributeToCheck as keyof T])
|
||||
);
|
||||
});
|
||||
const [head, ...rest] = path.split(".");
|
||||
if (Object.keys(item).includes(head)) {
|
||||
const attribute = head as keyof T;
|
||||
if (isDefined(item[attribute])) {
|
||||
if (rest.length > 0) {
|
||||
return hasAttribute(item[attribute], rest.join("."));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
import { ContentPanel } from "components/Panels/ContentPanel";
|
||||
import { SubPanel } from "components/Panels/SubPanel";
|
||||
import { PreviewCard } from "components/PreviewCard";
|
||||
import { TranslatedPreviewLine } from "components/PreviewLine";
|
||||
import { RecorderChip } from "components/RecorderChip";
|
||||
import { ThumbnailHeader } from "components/ThumbnailHeader";
|
||||
import { ToolTip } from "components/ToolTip";
|
||||
|
@ -27,7 +26,6 @@ import {
|
|||
} from "helpers/formatters";
|
||||
import { isUntangibleGroupItem } from "helpers/libraryItem";
|
||||
import {
|
||||
filterDefined,
|
||||
filterHasAttributes,
|
||||
getStatusDescription,
|
||||
isDefinedAndNotEmpty,
|
||||
|
@ -36,6 +34,7 @@ import { ContentWithTranslations } from "helpers/types";
|
|||
import { useMediaMobile } from "hooks/useMediaQuery";
|
||||
import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
|
||||
import { useSmartLanguage } from "hooks/useSmartLanguage";
|
||||
import { TranslatedPreviewLine } from "components/Translated";
|
||||
|
||||
/*
|
||||
* ╭────────╮
|
||||
|
@ -344,15 +343,18 @@ const Content = ({
|
|||
</h2>
|
||||
<TranslatedPreviewLine
|
||||
href={`/contents/${previousContent.attributes.slug}`}
|
||||
translations={filterDefined(
|
||||
previousContent.attributes.translations
|
||||
translations={filterHasAttributes(
|
||||
previousContent.attributes.translations,
|
||||
["language.data.attributes.code"] as const
|
||||
).map((translation) => ({
|
||||
pre_title: translation.pre_title,
|
||||
title: translation.title,
|
||||
subtitle: translation.subtitle,
|
||||
language: translation.language?.data?.attributes?.code,
|
||||
language: translation.language.data.attributes.code,
|
||||
}))}
|
||||
slug={previousContent.attributes.slug}
|
||||
fallback={{
|
||||
title: prettySlug(previousContent.attributes.slug),
|
||||
}}
|
||||
languages={languages}
|
||||
thumbnail={
|
||||
previousContent.attributes.thumbnail?.data?.attributes
|
||||
|
@ -397,15 +399,16 @@ const Content = ({
|
|||
</h2>
|
||||
<TranslatedPreviewLine
|
||||
href={`/contents/${nextContent.attributes.slug}`}
|
||||
translations={filterDefined(
|
||||
nextContent.attributes.translations
|
||||
translations={filterHasAttributes(
|
||||
nextContent.attributes.translations,
|
||||
["language.data.attributes.code"] as const
|
||||
).map((translation) => ({
|
||||
pre_title: translation.pre_title,
|
||||
title: translation.title,
|
||||
subtitle: translation.subtitle,
|
||||
language: translation.language?.data?.attributes?.code,
|
||||
language: translation.language.data.attributes.code,
|
||||
}))}
|
||||
slug={nextContent.attributes.slug}
|
||||
fallback={{ title: nextContent.attributes.slug }}
|
||||
languages={languages}
|
||||
thumbnail={nextContent.attributes.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio="3/2"
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
ContentPanelWidthSizes,
|
||||
} from "components/Panels/ContentPanel";
|
||||
import { SubPanel } from "components/Panels/SubPanel";
|
||||
import { TranslatedPreviewCard } from "components/PreviewCard";
|
||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||
import { getReadySdk } from "graphql/sdk";
|
||||
import { prettyinlineTitle, prettySlug } from "helpers/formatters";
|
||||
|
@ -24,6 +23,7 @@ import { SmartList } from "components/SmartList";
|
|||
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
|
||||
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||
import { useBoolean } from "hooks/useBoolean";
|
||||
import { TranslatedPreviewCard } from "components/Translated";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
|
@ -223,49 +223,41 @@ const Contents = ({
|
|||
items={filterHasAttributes(contents, ["attributes", "id"] as const)}
|
||||
getItemId={(item) => item.id}
|
||||
renderItem={({ item }) => (
|
||||
<>
|
||||
{item.attributes.translations && (
|
||||
<TranslatedPreviewCard
|
||||
href={`/contents/${item.attributes.slug}`}
|
||||
translations={item.attributes.translations.map(
|
||||
(translation) => ({
|
||||
pre_title: translation?.pre_title,
|
||||
title: translation?.title,
|
||||
subtitle: translation?.subtitle,
|
||||
language: translation?.language?.data?.attributes?.code,
|
||||
})
|
||||
)}
|
||||
slug={item.attributes.slug}
|
||||
languages={languages}
|
||||
thumbnail={item.attributes.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio="3/2"
|
||||
thumbnailForceAspectRatio
|
||||
stackNumber={
|
||||
effectiveCombineRelatedContent &&
|
||||
item.attributes.group?.data?.attributes?.combine === true
|
||||
? item.attributes.group.data.attributes.contents?.data
|
||||
.length
|
||||
: 0
|
||||
}
|
||||
topChips={
|
||||
item.attributes.type?.data?.attributes
|
||||
? [
|
||||
item.attributes.type.data.attributes.titles?.[0]
|
||||
? item.attributes.type.data.attributes.titles[0]
|
||||
?.title
|
||||
: prettySlug(
|
||||
item.attributes.type.data.attributes.slug
|
||||
),
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={item.attributes.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
)}
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
/>
|
||||
<TranslatedPreviewCard
|
||||
href={`/contents/${item.attributes.slug}`}
|
||||
translations={filterHasAttributes(item.attributes.translations, [
|
||||
"language.data.attributes.code",
|
||||
] as const).map((translation) => ({
|
||||
pre_title: translation.pre_title,
|
||||
title: translation.title,
|
||||
subtitle: translation.subtitle,
|
||||
language: translation.language.data.attributes.code,
|
||||
}))}
|
||||
fallback={{ title: prettySlug(item.attributes.slug) }}
|
||||
languages={languages}
|
||||
thumbnail={item.attributes.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio="3/2"
|
||||
thumbnailForceAspectRatio
|
||||
stackNumber={
|
||||
effectiveCombineRelatedContent &&
|
||||
item.attributes.group?.data?.attributes?.combine === true
|
||||
? item.attributes.group.data.attributes.contents?.data.length
|
||||
: 0
|
||||
}
|
||||
topChips={
|
||||
item.attributes.type?.data?.attributes
|
||||
? [
|
||||
item.attributes.type.data.attributes.titles?.[0]
|
||||
? item.attributes.type.data.attributes.titles[0]?.title
|
||||
: prettySlug(item.attributes.type.data.attributes.slug),
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
bottomChips={item.attributes.categories?.data.map(
|
||||
(category) => category.attributes?.short ?? ""
|
||||
)}
|
||||
</>
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
/>
|
||||
)}
|
||||
renderWhenEmpty={() => (
|
||||
<ContentPlaceholder
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { GetStaticPaths, GetStaticPathsResult, GetStaticProps } from "next";
|
||||
import { Fragment, useMemo } from "react";
|
||||
import { AppLayout } from "components/AppLayout";
|
||||
import { TranslatedScanSet } from "components/Library/ScanSet";
|
||||
import { ScanSetCover } from "components/Library/ScanSetCover";
|
||||
import { TranslatedNavOption } from "components/PanelComponents/NavOption";
|
||||
import {
|
||||
ReturnButton,
|
||||
ReturnButtonType,
|
||||
|
@ -31,6 +29,7 @@ import { isUntangibleGroupItem } from "helpers/libraryItem";
|
|||
import { PreviewCardCTAs } from "components/Library/PreviewCardCTAs";
|
||||
import { PreviewCard } from "components/PreviewCard";
|
||||
import { HorizontalLine } from "components/HorizontalLine";
|
||||
import { TranslatedNavOption, TranslatedScanSet } from "components/Translated";
|
||||
|
||||
/*
|
||||
* ╭────────╮
|
||||
|
@ -69,34 +68,36 @@ const LibrarySlug = ({
|
|||
displayOn={ReturnButtonType.Desktop}
|
||||
/>
|
||||
|
||||
<div className="mobile:w-[80%]">
|
||||
<PreviewCard
|
||||
href={`/library/${item.slug}`}
|
||||
title={item.title}
|
||||
subtitle={item.subtitle}
|
||||
thumbnail={item.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio="21/29.7"
|
||||
thumbnailRounded={false}
|
||||
topChips={
|
||||
item.metadata && item.metadata.length > 0 && item.metadata[0]
|
||||
? [prettyItemSubType(item.metadata[0])]
|
||||
: []
|
||||
}
|
||||
bottomChips={filterHasAttributes(item.categories?.data, [
|
||||
"attributes",
|
||||
] as const).map((category) => category.attributes.short)}
|
||||
metadata={{
|
||||
currencies: currencies,
|
||||
release_date: item.release_date,
|
||||
price: item.price,
|
||||
position: "Bottom",
|
||||
}}
|
||||
infoAppend={
|
||||
!isUntangibleGroupItem(item.metadata?.[0]) && (
|
||||
<PreviewCardCTAs id={itemId} langui={langui} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<div className="grid place-items-center">
|
||||
<div className="mobile:w-[80%]">
|
||||
<PreviewCard
|
||||
href={`/library/${item.slug}`}
|
||||
title={item.title}
|
||||
subtitle={item.subtitle}
|
||||
thumbnail={item.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio="21/29.7"
|
||||
thumbnailRounded={false}
|
||||
topChips={
|
||||
item.metadata && item.metadata.length > 0 && item.metadata[0]
|
||||
? [prettyItemSubType(item.metadata[0])]
|
||||
: []
|
||||
}
|
||||
bottomChips={filterHasAttributes(item.categories?.data, [
|
||||
"attributes",
|
||||
] as const).map((category) => category.attributes.short)}
|
||||
metadata={{
|
||||
currencies: currencies,
|
||||
release_date: item.release_date,
|
||||
price: item.price,
|
||||
position: "Bottom",
|
||||
}}
|
||||
infoAppend={
|
||||
!isUntangibleGroupItem(item.metadata?.[0]) && (
|
||||
<PreviewCardCTAs id={itemId} langui={langui} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<HorizontalLine />
|
||||
|
@ -132,18 +133,16 @@ const LibrarySlug = ({
|
|||
`${content.attributes.range[0].ending_page}`
|
||||
: undefined,
|
||||
}))}
|
||||
fallbackTitle={prettySlug(
|
||||
content.attributes.slug,
|
||||
item.slug
|
||||
)}
|
||||
fallbackSubtitle={
|
||||
content.attributes.range[0]?.__typename ===
|
||||
"ComponentRangePageRange"
|
||||
? `${content.attributes.range[0].starting_page}` +
|
||||
`→` +
|
||||
`${content.attributes.range[0].ending_page}`
|
||||
: undefined
|
||||
}
|
||||
fallback={{
|
||||
title: prettySlug(content.attributes.slug, item.slug),
|
||||
subtitle:
|
||||
content.attributes.range[0]?.__typename ===
|
||||
"ComponentRangePageRange"
|
||||
? `${content.attributes.range[0].starting_page}` +
|
||||
`→` +
|
||||
`${content.attributes.range[0].ending_page}`
|
||||
: undefined,
|
||||
}}
|
||||
border
|
||||
languages={languages}
|
||||
/>
|
||||
|
@ -210,7 +209,9 @@ const LibrarySlug = ({
|
|||
translation.subtitle
|
||||
),
|
||||
}))}
|
||||
fallbackTitle={prettySlug(content.attributes.slug, item.slug)}
|
||||
fallback={{
|
||||
title: prettySlug(content.attributes.slug, item.slug),
|
||||
}}
|
||||
languages={languages}
|
||||
langui={langui}
|
||||
content={content.attributes.content}
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
ContentPanelWidthSizes,
|
||||
} from "components/Panels/ContentPanel";
|
||||
import { SubPanel } from "components/Panels/SubPanel";
|
||||
import { TranslatedPreviewCard } from "components/PreviewCard";
|
||||
import { GetPostsPreviewQuery } from "graphql/generated";
|
||||
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
||||
import { getReadySdk } from "graphql/sdk";
|
||||
|
@ -18,9 +17,10 @@ import { WithLabel } from "components/Inputs/WithLabel";
|
|||
import { TextInput } from "components/Inputs/TextInput";
|
||||
import { Button } from "components/Inputs/Button";
|
||||
import { useMediaHoverable } from "hooks/useMediaQuery";
|
||||
import { filterDefined, filterHasAttributes } from "helpers/others";
|
||||
import { filterHasAttributes } from "helpers/others";
|
||||
import { SmartList } from "components/SmartList";
|
||||
import { useBoolean } from "hooks/useBoolean";
|
||||
import { TranslatedPreviewCard } from "components/Translated";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
|
@ -113,15 +113,15 @@ const News = ({
|
|||
renderItem={({ item: post }) => (
|
||||
<TranslatedPreviewCard
|
||||
href={`/news/${post.attributes.slug}`}
|
||||
translations={filterDefined(post.attributes.translations).map(
|
||||
(translation) => ({
|
||||
language: translation.language?.data?.attributes?.code,
|
||||
title: translation.title,
|
||||
description: translation.excerpt,
|
||||
})
|
||||
)}
|
||||
translations={filterHasAttributes(post.attributes.translations, [
|
||||
"language.data.attributes.code",
|
||||
] as const).map((translation) => ({
|
||||
language: translation.language.data.attributes.code,
|
||||
title: translation.title,
|
||||
description: translation.excerpt,
|
||||
}))}
|
||||
fallback={{ title: prettySlug(post.attributes.slug) }}
|
||||
languages={languages}
|
||||
slug={post.attributes.slug}
|
||||
thumbnail={post.attributes.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio="3/2"
|
||||
thumbnailForceAspectRatio
|
||||
|
|
|
@ -12,20 +12,20 @@ import {
|
|||
ContentPanel,
|
||||
ContentPanelWidthSizes,
|
||||
} from "components/Panels/ContentPanel";
|
||||
import { TranslatedPreviewCard } from "components/PreviewCard";
|
||||
import { HorizontalLine } from "components/HorizontalLine";
|
||||
import { Button } from "components/Inputs/Button";
|
||||
import { Switch } from "components/Inputs/Switch";
|
||||
import { TextInput } from "components/Inputs/TextInput";
|
||||
import { WithLabel } from "components/Inputs/WithLabel";
|
||||
import { useMediaHoverable } from "hooks/useMediaQuery";
|
||||
import { filterDefined, filterHasAttributes, isDefined } from "helpers/others";
|
||||
import { filterDefined, filterHasAttributes } from "helpers/others";
|
||||
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
|
||||
import { SmartList } from "components/SmartList";
|
||||
import { Select } from "components/Inputs/Select";
|
||||
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||
import { prettySlug } from "helpers/formatters";
|
||||
import { useBoolean } from "hooks/useBoolean";
|
||||
import { TranslatedPreviewCard } from "components/Translated";
|
||||
|
||||
/*
|
||||
* ╭─────────────╮
|
||||
|
@ -169,44 +169,40 @@ const Wiki = ({
|
|||
items={filterHasAttributes(pages, ["id", "attributes"] as const)}
|
||||
getItemId={(item) => item.id}
|
||||
renderItem={({ item }) => (
|
||||
<>
|
||||
{isDefined(item.attributes.translations) && (
|
||||
<TranslatedPreviewCard
|
||||
href={`/wiki/${item.attributes.slug}`}
|
||||
translations={item.attributes.translations.map(
|
||||
(translation) => ({
|
||||
title: translation?.title,
|
||||
subtitle:
|
||||
translation?.aliases && translation.aliases.length > 0
|
||||
? translation.aliases
|
||||
.map((alias) => alias?.alias)
|
||||
.join("・")
|
||||
: undefined,
|
||||
description: translation?.summary,
|
||||
language: translation?.language?.data?.attributes?.code,
|
||||
})
|
||||
)}
|
||||
thumbnail={item.attributes.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio={"4/3"}
|
||||
thumbnailRounded
|
||||
thumbnailForceAspectRatio
|
||||
languages={languages}
|
||||
slug={item.attributes.slug}
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
topChips={filterHasAttributes(item.attributes.tags?.data, [
|
||||
"attributes",
|
||||
] as const).map(
|
||||
(tag) =>
|
||||
tag.attributes.titles?.[0]?.title ??
|
||||
prettySlug(tag.attributes.slug)
|
||||
)}
|
||||
bottomChips={filterHasAttributes(
|
||||
item.attributes.categories?.data,
|
||||
["attributes"] as const
|
||||
).map((category) => category.attributes.short)}
|
||||
/>
|
||||
<TranslatedPreviewCard
|
||||
href={`/wiki/${item.attributes.slug}`}
|
||||
translations={filterHasAttributes(item.attributes.translations, [
|
||||
"language.data.attributes.code",
|
||||
] as const).map((translation) => ({
|
||||
title: translation.title,
|
||||
subtitle:
|
||||
translation.aliases && translation.aliases.length > 0
|
||||
? translation.aliases
|
||||
.map((alias) => alias?.alias)
|
||||
.join("・")
|
||||
: undefined,
|
||||
description: translation.summary,
|
||||
language: translation.language.data.attributes.code,
|
||||
}))}
|
||||
fallback={{ title: prettySlug(item.attributes.slug) }}
|
||||
thumbnail={item.attributes.thumbnail?.data?.attributes}
|
||||
thumbnailAspectRatio={"4/3"}
|
||||
thumbnailRounded
|
||||
thumbnailForceAspectRatio
|
||||
languages={languages}
|
||||
keepInfoVisible={keepInfoVisible}
|
||||
topChips={filterHasAttributes(item.attributes.tags?.data, [
|
||||
"attributes",
|
||||
] as const).map(
|
||||
(tag) =>
|
||||
tag.attributes.titles?.[0]?.title ??
|
||||
prettySlug(tag.attributes.slug)
|
||||
)}
|
||||
</>
|
||||
bottomChips={filterHasAttributes(
|
||||
item.attributes.categories?.data,
|
||||
["attributes"] as const
|
||||
).map((category) => category.attributes.short)}
|
||||
/>
|
||||
)}
|
||||
renderWhenEmpty={() => (
|
||||
<ContentPlaceholder
|
||||
|
|
Loading…
Reference in New Issue