From de3f3854588e3dcd160fb2ea973316025332a108 Mon Sep 17 00:00:00 2001
From: DrMint
Date: Sun, 10 Jul 2022 02:47:32 +0200
Subject: [PATCH] Improved the filterHasAttributes + Chip
---
src/components/AppLayout.tsx | 15 +-
src/components/Chip.tsx | 6 +-
src/components/Library/ScanSet.tsx | 98 +--
src/components/Library/ScanSetCover.tsx | 89 +--
src/components/PostPage.tsx | 7 +-
src/components/PreviewCard.tsx | 6 +-
src/components/PreviewLine.tsx | 6 +-
src/components/RecorderChip.tsx | 29 +-
src/components/SmartList.tsx | 12 +-
src/components/ThumbnailHeader.tsx | 19 +-
.../Chronology/ChronologyItemComponent.tsx | 4 +-
src/components/Wiki/DefinitionCard.tsx | 4 +-
src/helpers/formatters.ts | 14 +-
src/helpers/others.ts | 35 +-
src/helpers/types.ts | 12 +-
src/helpers/types/SelectiveNonNullable.ts | 47 ++
src/pages/archives/videos/c/[uid].tsx | 8 +-
src/pages/archives/videos/index.tsx | 2 +-
src/pages/archives/videos/v/[uid].tsx | 12 +-
src/pages/contents/[slug]/index.tsx | 138 +++--
src/pages/contents/index.tsx | 14 +-
src/pages/dev/checkup/contents.tsx | 581 +++++++++---------
src/pages/dev/checkup/libraryitems.tsx | 7 +-
src/pages/library/[slug]/index.tsx | 193 +++---
src/pages/library/[slug]/scans.tsx | 4 +-
src/pages/library/index.tsx | 31 +-
src/pages/news/[slug].tsx | 12 +-
src/pages/news/index.tsx | 2 +-
src/pages/wiki/[slug]/index.tsx | 70 ++-
src/pages/wiki/chronology.tsx | 34 +-
src/pages/wiki/index.tsx | 59 +-
31 files changed, 828 insertions(+), 742 deletions(-)
create mode 100644 src/helpers/types/SelectiveNonNullable.ts
diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx
index 1ff4041..4d133e0 100644
--- a/src/components/AppLayout.tsx
+++ b/src/components/AppLayout.tsx
@@ -188,14 +188,13 @@ export const AppLayout = ({
return memo;
}, [router.locale, router.locales]);
- const currencyOptions = useMemo(() => {
- const memo: string[] = [];
- filterHasAttributes(currencies).map((currentCurrency) => {
- if (isDefinedAndNotEmpty(currentCurrency.attributes.code))
- memo.push(currentCurrency.attributes.code);
- });
- return memo;
- }, [currencies]);
+ const currencyOptions = useMemo(
+ () =>
+ filterHasAttributes(currencies, ["attributes"] as const).map(
+ (currentCurrency) => currentCurrency.attributes.code
+ ),
+ [currencies]
+ );
const [currencySelect, setCurrencySelect] = useState(-1);
diff --git a/src/components/Chip.tsx b/src/components/Chip.tsx
index 9ab8bb9..0d8c701 100644
--- a/src/components/Chip.tsx
+++ b/src/components/Chip.tsx
@@ -7,12 +7,12 @@ import { cJoin } from "helpers/className";
interface Props {
className?: string;
- children: React.ReactNode;
+ text: string;
}
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
-export const Chip = ({ className, children }: Props): JSX.Element => (
+export const Chip = ({ className, text }: Props): JSX.Element => (
(
className
)}
>
- {children}
+ {text}
);
diff --git a/src/components/Library/ScanSet.tsx b/src/components/Library/ScanSet.tsx
index c7a3410..9b5dff7 100644
--- a/src/components/Library/ScanSet.tsx
+++ b/src/components/Library/ScanSet.tsx
@@ -103,7 +103,7 @@ export const ScanSet = ({
});
const pages = useMemo(
- () => selectedScan && filterHasAttributes(selectedScan.pages?.data),
+ () => filterHasAttributes(selectedScan?.pages?.data, ["attributes"]),
[selectedScan]
);
@@ -119,12 +119,15 @@ export const ScanSet = ({
{title}
-
- {selectedScan.language?.data?.attributes?.code ===
- selectedScan.source_language?.data?.attributes?.code
- ? "Scan"
- : "Scanlation"}
-
+ {/* TODO: Add Scan and Scanlation to langui */}
+
@@ -144,7 +147,7 @@ export const ScanSet = ({
content={getStatusDescription(selectedScan.status, langui)}
maxWidth={"20rem"}
>
- {selectedScan.status}
+
@@ -153,16 +156,17 @@ export const ScanSet = ({
{/* TODO: Add Scanner to langui */}
{"Scanners"}:
- {filterHasAttributes(selectedScan.scanners.data).map(
- (scanner) => (
-
-
-
- )
- )}
+ {filterHasAttributes(selectedScan.scanners.data, [
+ "id",
+ "attributes",
+ ] as const).map((scanner) => (
+
+
+
+ ))}
)}
@@ -172,16 +176,17 @@ export const ScanSet = ({
{/* TODO: Add Cleaners to langui */}
{"Cleaners"}:
- {filterHasAttributes(selectedScan.cleaners.data).map(
- (cleaner) => (
-
-
-
- )
- )}
+ {filterHasAttributes(selectedScan.cleaners.data, [
+ "id",
+ "attributes",
+ ] as const).map((cleaner) => (
+
+
+
+ ))}
)}
@@ -189,27 +194,28 @@ export const ScanSet = ({
{selectedScan.typesetters &&
selectedScan.typesetters.data.length > 0 && (
- {/* TODO: Add Cleaners to Typesetters */}
+ {/* TODO: Add typesetter to langui */}
{"Typesetters"}:
- {filterHasAttributes(selectedScan.typesetters.data).map(
- (typesetter) => (
-
-
-
- )
- )}
+ {filterHasAttributes(selectedScan.typesetters.data, [
+ "id",
+ "attributes",
+ ] as const).map((typesetter) => (
+
+
+
+ ))}
)}
{isDefinedAndNotEmpty(selectedScan.notes) && (
- {/* TODO: Add Notes to Typesetters */}
- {"Notes"}
+ {/* TODO: Add Notes to langui */}
+
)}
@@ -224,13 +230,9 @@ export const ScanSet = ({
className="cursor-pointer transition-transform
drop-shadow-shade-lg hover:scale-[1.02]"
onClick={() => {
- const images: string[] = [];
- pages.map((image) => {
- if (isDefinedAndNotEmpty(image.attributes.url))
- images.push(
- getAssetURL(image.attributes.url, ImageQuality.Large)
- );
- });
+ const images = pages.map((image) =>
+ getAssetURL(image.attributes.url, ImageQuality.Large)
+ );
openLightBox(images, index);
}}
>
diff --git a/src/components/Library/ScanSetCover.tsx b/src/components/Library/ScanSetCover.tsx
index dd9ba70..5229dbb 100644
--- a/src/components/Library/ScanSetCover.tsx
+++ b/src/components/Library/ScanSetCover.tsx
@@ -80,12 +80,15 @@ export const ScanSetCover = ({
{"Cover"}
-
- {selectedScan.language?.data?.attributes?.code ===
- selectedScan.source_language?.data?.attributes?.code
- ? "Scan"
- : "Scanlation"}
-
+ {/* TODO: Add Scan and Scanlation to langui */}
+
@@ -97,7 +100,7 @@ export const ScanSetCover = ({
content={getStatusDescription(selectedScan.status, langui)}
maxWidth={"20rem"}
>
- {selectedScan.status}
+
@@ -106,16 +109,17 @@ export const ScanSetCover = ({
{/* TODO: Add Scanner to langui */}
{"Scanners"}:
- {filterHasAttributes(selectedScan.scanners.data).map(
- (scanner) => (
-
-
-
- )
- )}
+ {filterHasAttributes(selectedScan.scanners.data, [
+ "id",
+ "attributes",
+ ] as const).map((scanner) => (
+
+
+
+ ))}
)}
@@ -125,16 +129,17 @@ export const ScanSetCover = ({
{/* TODO: Add Cleaners to langui */}
{"Cleaners"}:
- {filterHasAttributes(selectedScan.cleaners.data).map(
- (cleaner) => (
-
-
-
- )
- )}
+ {filterHasAttributes(selectedScan.cleaners.data, [
+ "id",
+ "attributes",
+ ] as const).map((cleaner) => (
+
+
+
+ ))}
)}
@@ -145,16 +150,17 @@ export const ScanSetCover = ({
{/* TODO: Add Cleaners to Typesetters */}
{"Typesetters"}:
- {filterHasAttributes(selectedScan.typesetters.data).map(
- (typesetter) => (
-
-
-
- )
- )}
+ {filterHasAttributes(selectedScan.typesetters.data, [
+ "id",
+ "attributes",
+ ] as const).map((typesetter) => (
+
+
+
+ ))}
)}
@@ -171,11 +177,10 @@ export const ScanSetCover = ({
className="cursor-pointer transition-transform
drop-shadow-shade-lg hover:scale-[1.02]"
onClick={() => {
- const imgs: string[] = [];
- coverImages.map((img) => {
- if (img.url)
- imgs.push(getAssetURL(img.url, ImageQuality.Large));
- });
+ const imgs = coverImages.map((img) =>
+ getAssetURL(img.url, ImageQuality.Large)
+ );
+
openLightBox(imgs, index);
}}
>
diff --git a/src/components/PostPage.tsx b/src/components/PostPage.tsx
index 6abe50a..870628a 100644
--- a/src/components/PostPage.tsx
+++ b/src/components/PostPage.tsx
@@ -104,7 +104,7 @@ export const PostPage = ({
)}
maxWidth={"20rem"}
>
- {selectedTranslation.status}
+
)}
@@ -113,7 +113,10 @@ export const PostPage = ({
{"Authors"}:
- {filterHasAttributes(post.authors.data).map((author) => (
+ {filterHasAttributes(post.authors.data, [
+ "id",
+ "attributes",
+ ] as const).map((author) => (
0 && (
{topChips.map((text, index) => (
- {text}
+
))}
)}
@@ -281,9 +281,7 @@ export const PreviewCard = ({
{bottomChips && bottomChips.length > 0 && (
{bottomChips.map((text, index) => (
-
- {text}
-
+
))}
)}
diff --git a/src/components/PreviewLine.tsx b/src/components/PreviewLine.tsx
index 399c0cb..e71e64e 100644
--- a/src/components/PreviewLine.tsx
+++ b/src/components/PreviewLine.tsx
@@ -52,7 +52,7 @@ const PreviewLine = ({
{topChips && topChips.length > 0 && (
{topChips.map((text, index) => (
- {text}
+
))}
)}
@@ -68,9 +68,7 @@ const PreviewLine = ({
{bottomChips && bottomChips.length > 0 && (
{bottomChips.map((text, index) => (
-
- {text}
-
+
))}
)}
diff --git a/src/components/RecorderChip.tsx b/src/components/RecorderChip.tsx
index 0da17e1..5d725f1 100644
--- a/src/components/RecorderChip.tsx
+++ b/src/components/RecorderChip.tsx
@@ -38,19 +38,19 @@ export const RecorderChip = ({ recorder, langui }: Props): JSX.Element => (
{recorder.languages?.data && recorder.languages.data.length > 0 && (
{langui.languages}:
- {filterHasAttributes(recorder.languages.data).map(
- (language) => (
-
- {language.attributes.code.toUpperCase()}
-
- )
- )}
+ {filterHasAttributes(recorder.languages.data, [
+ "attributes",
+ ] as const).map((language) => (
+
+
+
+ ))}
)}
{recorder.pronouns && (
{langui.pronouns}:
-
{recorder.pronouns}
+
)}
@@ -60,10 +60,13 @@ export const RecorderChip = ({ recorder, langui }: Props): JSX.Element => (
}
placement="top"
>
-
- {recorder.anonymize
- ? `Recorder#${recorder.anonymous_code}`
- : recorder.username}
-
+
);
diff --git a/src/components/SmartList.tsx b/src/components/SmartList.tsx
index 93b3adf..2905b15 100644
--- a/src/components/SmartList.tsx
+++ b/src/components/SmartList.tsx
@@ -146,11 +146,13 @@ export const SmartList =
({
first-of-type:pt-0"
>
{name}
- {`${groupItems.length} ${
- groupItems.length <= 1
- ? langui.result?.toLowerCase() ?? ""
- : langui.results?.toLowerCase() ?? ""
- }`}
+
)}
{langui.type}
-
- {type.data.attributes.titles &&
- type.data.attributes.titles.length > 0
- ? type.data.attributes.titles[0]?.title
- : prettySlug(type.data.attributes.slug)}
-
+
)}
@@ -94,8 +94,11 @@ export const ThumbnailHeader = ({
{langui.categories}
- {filterHasAttributes(categories.data).map((category) => (
- {category.attributes.name}
+ {filterHasAttributes(categories.data, [
+ "attributes",
+ "id",
+ ] as const).map((category) => (
+
))}
diff --git a/src/components/Wiki/Chronology/ChronologyItemComponent.tsx b/src/components/Wiki/Chronology/ChronologyItemComponent.tsx
index 7399ffc..97d665d 100644
--- a/src/components/Wiki/Chronology/ChronologyItemComponent.tsx
+++ b/src/components/Wiki/Chronology/ChronologyItemComponent.tsx
@@ -57,7 +57,7 @@ export const ChronologyItemComponent = ({
filterHasAttributes(item.attributes.events, [
"id",
"translations",
- ]).map((event) => (
+ ] as const).map((event) => (
{filterDefined(event.translations).map(
@@ -77,7 +77,7 @@ export const ChronologyItemComponent = ({
)}
maxWidth={"20rem"}
>
-
{translation.status}
+
)}
{translation.title ? (
diff --git a/src/components/Wiki/DefinitionCard.tsx b/src/components/Wiki/DefinitionCard.tsx
index 92912ec..75151d7 100644
--- a/src/components/Wiki/DefinitionCard.tsx
+++ b/src/components/Wiki/DefinitionCard.tsx
@@ -62,7 +62,7 @@ const DefinitionCard = ({
content={getStatusDescription(selectedTranslation.status, langui)}
maxWidth={"20rem"}
>
-
{selectedTranslation.status}
+
>
)}
@@ -72,7 +72,7 @@ const DefinitionCard = ({
{categories.map((category, categoryIndex) => (
- {category}
+
))}
>
diff --git a/src/helpers/formatters.ts b/src/helpers/formatters.ts
index bb9ee56..c0cae3c 100644
--- a/src/helpers/formatters.ts
+++ b/src/helpers/formatters.ts
@@ -60,20 +60,20 @@ export const prettyinlineTitle = (
export const prettyItemType = (
metadata: any,
langui: AppStaticProps["langui"]
-): string | null | undefined => {
+): string => {
switch (metadata.__typename) {
case "ComponentMetadataAudio":
- return langui.audio;
+ return langui.audio ?? "Audio";
case "ComponentMetadataBooks":
- return langui.textual;
+ return langui.textual ?? "Textual";
case "ComponentMetadataGame":
- return langui.game;
+ return langui.game ?? "Game";
case "ComponentMetadataVideo":
- return langui.video;
+ return langui.video ?? "Video";
case "ComponentMetadataGroup":
- return langui.group;
+ return langui.group ?? "Group";
case "ComponentMetadataOther":
- return langui.other;
+ return langui.other ?? "Other";
default:
return "";
}
diff --git a/src/helpers/others.ts b/src/helpers/others.ts
index a836541..b012fe8 100644
--- a/src/helpers/others.ts
+++ b/src/helpers/others.ts
@@ -1,5 +1,5 @@
import { AppStaticProps } from "../graphql/getAppStaticProps";
-import { SelectiveRequiredNonNullable } from "./types";
+import { PathDot, SelectiveNonNullable } from "./types/SelectiveNonNullable";
import {
Enum_Componentsetstextset_Status,
GetLibraryItemQuery,
@@ -71,21 +71,29 @@ export const filterDefined =
(t: T[] | null | undefined): NonNullable[] =>
? []
: (t.filter((item) => isDefined(item)) as NonNullable[]);
-export const filterHasAttributes = >(
+export const filterHasAttributes = >(
t: T[] | null | undefined,
- attributes?: P[]
-): SelectiveRequiredNonNullable, P>[] =>
+ paths: readonly P[]
+): SelectiveNonNullable[] =>
isUndefined(t)
? []
- : (t.filter((item) => {
- if (isDefined(item)) {
- const attributesToCheck = attributes ?? (Object.keys(item) as P[]);
- return attributesToCheck.every((attribute) =>
- isDefined(item[attribute])
- );
- }
- return false;
- }) as unknown as SelectiveRequiredNonNullable, P>[]);
+ : (t.filter((item) =>
+ hasAttributes(item, paths)
+ ) as unknown as SelectiveNonNullable[]);
+
+const hasAttributes = (item: T, paths: readonly PathDot[]): 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])
+ );
+ });
+ }
+ return false;
+};
export const iterateMap = (
map: Map,
@@ -95,7 +103,6 @@ export const iterateMap = (
const toList = [...map];
if (isDefined(sortingFunction)) {
toList.sort(sortingFunction);
- console.log(toList.sort(sortingFunction));
}
return toList.map(([key, value], index) => callbackfn(key, value, index));
};
diff --git a/src/helpers/types.ts b/src/helpers/types.ts
index 1a836b0..e164625 100644
--- a/src/helpers/types.ts
+++ b/src/helpers/types.ts
@@ -4,6 +4,8 @@ import {
GetWikiPageQuery,
} from "graphql/generated";
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
type Post = NonNullable<
NonNullable["data"][number]["attributes"]
>;
@@ -12,6 +14,8 @@ export interface PostWithTranslations extends Omit {
translations: NonNullable;
}
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
export type Content = NonNullable<
NonNullable["data"][number]["attributes"]
>;
@@ -20,6 +24,8 @@ export interface ContentWithTranslations extends Omit {
translations: NonNullable;
}
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
type WikiPage = NonNullable<
NonNullable["data"][number]["attributes"]
>;
@@ -29,13 +35,13 @@ export interface WikiPageWithTranslations
translations: NonNullable;
}
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
+
export type RequiredNonNullable = {
[P in keyof T]-?: NonNullable;
};
-export type SelectiveRequiredNonNullable = Omit & {
- [P in K]-?: NonNullable;
-};
+// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
export enum LibraryItemUserStatus {
None = 0,
diff --git a/src/helpers/types/SelectiveNonNullable.ts b/src/helpers/types/SelectiveNonNullable.ts
new file mode 100644
index 0000000..f1a4e6a
--- /dev/null
+++ b/src/helpers/types/SelectiveNonNullable.ts
@@ -0,0 +1,47 @@
+type JoinDot = `${K}${"" extends K
+ ? ""
+ : "."}${P}`;
+
+export type PathDot = T extends object
+ ? {
+ [K in keyof T]: K extends string
+ ? JoinDot | PathDot>
+ : never;
+ }[keyof T]
+ : Acc;
+
+type PathHead = T extends [infer head]
+ ? head
+ : T extends [infer head, ...infer rest]
+ ? head
+ : "";
+
+type PathRest = T extends [infer head, ...infer rest]
+ ? rest extends []
+ ? never
+ : rest
+ : never;
+
+type PathLast = T["length"] extends 1 ? true : false;
+
+type Recursive = PathHead extends keyof T
+ ? Omit> & {
+ [P in PathHead]-?: PathLast extends true
+ ? NonNullable
+ : Recursive, PathRest>;
+ }
+ : T;
+
+type Split<
+ Str,
+ Cache extends string[] = []
+> = Str extends `${infer Method}.${infer PathRest}`
+ ? Split
+ : Str extends `${infer PathLast}`
+ ? [...Cache, PathLast]
+ : never;
+
+export type SelectiveNonNullable> = Recursive<
+ NonNullable,
+ Split
+>;
diff --git a/src/pages/archives/videos/c/[uid].tsx b/src/pages/archives/videos/c/[uid].tsx
index c80a18e..5b27787 100644
--- a/src/pages/archives/videos/c/[uid].tsx
+++ b/src/pages/archives/videos/c/[uid].tsx
@@ -78,7 +78,9 @@ const Channel = ({ langui, channel, ...otherProps }: Props): JSX.Element => {
className="grid items-start gap-8 border-b-[3px] border-dotted pb-12 last-of-type:border-0
desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] mobile:grid-cols-2"
>
- {filterHasAttributes(channel?.videos?.data).map((video) => (
+ {filterHasAttributes(channel?.videos?.data, [
+ "attributes",
+ ] as const).map((video) => (
{
const channels = await sdk.getVideoChannelsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
if (channels.videoChannels?.data)
- filterHasAttributes(channels.videoChannels.data).map((channel) => {
+ filterHasAttributes(channels.videoChannels.data, [
+ "attributes",
+ ] as const).map((channel) => {
context.locales?.map((local) => {
paths.push({
params: { uid: channel.attributes.uid },
diff --git a/src/pages/archives/videos/index.tsx b/src/pages/archives/videos/index.tsx
index 0b5b3c3..e579446 100644
--- a/src/pages/archives/videos/index.tsx
+++ b/src/pages/archives/videos/index.tsx
@@ -92,7 +92,7 @@ const Videos = ({ langui, videos, ...otherProps }: Props): JSX.Element => {
() => (
item.id}
renderItem={({ item }) => (
<>
diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx
index 64d1458..e0a24df 100644
--- a/src/pages/archives/videos/v/[uid].tsx
+++ b/src/pages/archives/videos/v/[uid].tsx
@@ -238,11 +238,13 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
const videos = await sdk.getVideosSlugs();
const paths: GetStaticPathsResult["paths"] = [];
if (videos.videos?.data)
- filterHasAttributes(videos.videos.data).map((video) => {
- context.locales?.map((local) => {
- paths.push({ params: { uid: video.attributes.uid }, locale: local });
- });
- });
+ filterHasAttributes(videos.videos.data, ["attributes"] as const).map(
+ (video) => {
+ context.locales?.map((local) => {
+ paths.push({ params: { uid: video.attributes.uid }, locale: local });
+ });
+ }
+ );
return {
paths,
fallback: "blocking",
diff --git a/src/pages/contents/[slug]/index.tsx b/src/pages/contents/[slug]/index.tsx
index eb76544..bb943d3 100644
--- a/src/pages/contents/[slug]/index.tsx
+++ b/src/pages/contents/[slug]/index.tsx
@@ -114,13 +114,13 @@ const Content = ({
{langui.source_language}:
-
- {prettyLanguage(
+
+ />
)}
@@ -134,7 +134,7 @@ const Content = ({
)}
maxWidth={"20rem"}
>
- {selectedTranslation.text_set.status}
+
@@ -146,7 +146,8 @@ const Content = ({
{filterHasAttributes(
- selectedTranslation.text_set.transcribers.data
+ selectedTranslation.text_set.transcribers.data,
+ ["attributes", "id"] as const
).map((recorder) => (
{filterHasAttributes(
- selectedTranslation.text_set.translators.data
+ selectedTranslation.text_set.translators.data,
+ ["attributes", "id"] as const
).map((recorder) => (
{filterHasAttributes(
- selectedTranslation.text_set.proofreaders.data
+ selectedTranslation.text_set.proofreaders.data,
+ ["attributes", "id"] as const
).map((recorder) => (
- {content.ranged_contents.data.map((rangedContent) => {
+ {filterHasAttributes(content.ranged_contents.data, [
+ "attributes.library_item.data.attributes",
+ "attributes.library_item.data.id",
+ ] as const).map((rangedContent) => {
const libraryItem =
- rangedContent.attributes?.library_item?.data;
- if (libraryItem?.attributes && libraryItem.id) {
- return (
-
-
0 &&
- libraryItem.attributes.metadata[0]
- ? [
- prettyItemSubType(
- libraryItem.attributes.metadata[0]
- ),
- ]
- : []
- }
- bottomChips={libraryItem.attributes.categories?.data.map(
- (category) => category.attributes?.short ?? ""
- )}
- metadata={{
- currencies: currencies,
- release_date: libraryItem.attributes.release_date,
- price: libraryItem.attributes.price,
- position: "Bottom",
- }}
- infoAppend={
- !isUntangibleGroupItem(
- libraryItem.attributes.metadata?.[0]
- ) && (
-
- )
- }
- />
-
- );
- }
- return <>>;
+ rangedContent.attributes.library_item.data;
+ return (
+
+
0 &&
+ libraryItem.attributes.metadata[0]
+ ? [
+ prettyItemSubType(
+ libraryItem.attributes.metadata[0]
+ ),
+ ]
+ : []
+ }
+ bottomChips={filterHasAttributes(
+ libraryItem.attributes.categories?.data,
+ ["attributes"] as const
+ ).map((category) => category.attributes.short)}
+ metadata={{
+ currencies: currencies,
+ release_date: libraryItem.attributes.release_date,
+ price: libraryItem.attributes.price,
+ position: "Bottom",
+ }}
+ infoAppend={
+ !isUntangibleGroupItem(
+ libraryItem.attributes.metadata?.[0]
+ ) && (
+
+ )
+ }
+ />
+
+ );
})}
@@ -507,14 +511,16 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
const sdk = getReadySdk();
const contents = await sdk.getContentsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- filterHasAttributes(contents.contents?.data).map((item) => {
- context.locales?.map((local) => {
- paths.push({
- params: { slug: item.attributes.slug },
- locale: local,
+ filterHasAttributes(contents.contents?.data, ["attributes"] as const).map(
+ (item) => {
+ context.locales?.map((local) => {
+ paths.push({
+ params: { slug: item.attributes.slug },
+ locale: local,
+ });
});
- });
- });
+ }
+ );
return {
paths,
fallback: "blocking",
diff --git a/src/pages/contents/index.tsx b/src/pages/contents/index.tsx
index 817d53d..4f4b3fe 100644
--- a/src/pages/contents/index.tsx
+++ b/src/pages/contents/index.tsx
@@ -21,8 +21,8 @@ import { Icon } from "components/Ico";
import { filterDefined, filterHasAttributes } from "helpers/others";
import { GetContentsQuery } from "graphql/generated";
import { SmartList } from "components/SmartList";
-import { SelectiveRequiredNonNullable } from "helpers/types";
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
+import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
/*
* ╭─────────────╮
@@ -73,7 +73,7 @@ const Contents = ({
const groupingFunction = useCallback(
(
- item: SelectiveRequiredNonNullable<
+ item: SelectiveNonNullable<
NonNullable["data"][number],
"attributes" | "id"
>
@@ -81,7 +81,8 @@ const Contents = ({
switch (groupingMethod) {
case 0: {
const categories = filterHasAttributes(
- item.attributes.categories?.data
+ item.attributes.categories?.data,
+ ["attributes"] as const
);
if (categories.length > 0) {
return categories.map((category) => category.attributes.name);
@@ -106,10 +107,7 @@ const Contents = ({
const filteringFunction = useCallback(
(
- item: SelectiveRequiredNonNullable<
- Props["contents"][number],
- "attributes" | "id"
- >
+ item: SelectiveNonNullable
) => {
if (
effectiveCombineRelatedContent &&
@@ -217,7 +215,7 @@ const Contents = ({
() => (
item.id}
renderItem={({ item }) => (
<>
diff --git a/src/pages/dev/checkup/contents.tsx b/src/pages/dev/checkup/contents.tsx
index dafaeb0..b9a0667 100644
--- a/src/pages/dev/checkup/contents.tsx
+++ b/src/pages/dev/checkup/contents.tsx
@@ -60,7 +60,7 @@ const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
/>
{line.subitems.join(" -> ")}
{line.name}
- {line.type}
+
{
? "bg-[#fff344] !opacity-100"
: ""
}
- >
- {line.severity}
-
+ text={line.severity}
+ />
{line.description}
@@ -138,320 +137,322 @@ const testingContent = (contents: Props["contents"]): Report => {
lines: [],
};
- filterHasAttributes(contents.contents?.data).map((content) => {
- const backendUrl = `${process.env.NEXT_PUBLIC_URL_CMS}/admin/content-manager/collectionType/api::content.content/${content.id}`;
- const frontendUrl = `${process.env.NEXT_PUBLIC_URL_SELF}/contents/${content.attributes.slug}`;
+ filterHasAttributes(contents.contents?.data, ["attributes"] as const).map(
+ (content) => {
+ const backendUrl = `${process.env.NEXT_PUBLIC_URL_CMS}/admin/content-manager/collectionType/api::content.content/${content.id}`;
+ const frontendUrl = `${process.env.NEXT_PUBLIC_URL_SELF}/contents/${content.attributes.slug}`;
- if (content.attributes.categories?.data.length === 0) {
- report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Category",
- type: "Missing",
- severity: "Medium",
- description: "The Content has no Category.",
- recommandation: "Select a Category in relation with the Content",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
+ if (content.attributes.categories?.data.length === 0) {
+ report.lines.push({
+ subitems: [content.attributes.slug],
+ name: "No Category",
+ type: "Missing",
+ severity: "Medium",
+ description: "The Content has no Category.",
+ recommandation: "Select a Category in relation with the Content",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ }
- if (!content.attributes.type?.data?.id) {
- report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Category",
- type: "Missing",
- severity: "Medium",
- description: "The Content has no Type.",
- recommandation: 'If unsure, use the "Other" Type.',
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
+ if (!content.attributes.type?.data?.id) {
+ report.lines.push({
+ subitems: [content.attributes.slug],
+ name: "No Category",
+ type: "Missing",
+ severity: "Medium",
+ description: "The Content has no Type.",
+ recommandation: 'If unsure, use the "Other" Type.',
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ }
- if (content.attributes.ranged_contents?.data.length === 0) {
- report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Ranged Content",
- type: "Improvement",
- severity: "Low",
- description: "The Content has no Ranged Content.",
- recommandation:
- "If this Content is available in one or multiple Library Item(s), create a Range Content to connect the Content to its Library Item(s).",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
+ if (content.attributes.ranged_contents?.data.length === 0) {
+ report.lines.push({
+ subitems: [content.attributes.slug],
+ name: "No Ranged Content",
+ type: "Improvement",
+ severity: "Low",
+ description: "The Content has no Ranged Content.",
+ recommandation:
+ "If this Content is available in one or multiple Library Item(s), create a Range Content to connect the Content to its Library Item(s).",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ }
- if (!content.attributes.thumbnail?.data?.id) {
- report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Thumbnail",
- type: "Missing",
- severity: "High",
- description: "The Content has no Thumbnail.",
- recommandation: "",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
+ if (!content.attributes.thumbnail?.data?.id) {
+ report.lines.push({
+ subitems: [content.attributes.slug],
+ name: "No Thumbnail",
+ type: "Missing",
+ severity: "High",
+ description: "The Content has no Thumbnail.",
+ recommandation: "",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ }
- if (content.attributes.translations?.length === 0) {
- report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Titles",
- type: "Missing",
- severity: "High",
- description: "The Content has no Titles.",
- recommandation: "",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- } else {
- const titleLanguages: string[] = [];
+ if (content.attributes.translations?.length === 0) {
+ report.lines.push({
+ subitems: [content.attributes.slug],
+ name: "No Titles",
+ type: "Missing",
+ severity: "High",
+ description: "The Content has no Titles.",
+ recommandation: "",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ } else {
+ const titleLanguages: string[] = [];
- filterDefined(content.attributes.translations).map(
- (translation, titleIndex) => {
- if (translation.language?.data?.id) {
- if (translation.language.data.id in titleLanguages) {
+ filterDefined(content.attributes.translations).map(
+ (translation, titleIndex) => {
+ if (translation.language?.data?.id) {
+ if (translation.language.data.id in titleLanguages) {
+ report.lines.push({
+ subitems: [
+ content.attributes.slug,
+ `Title ${titleIndex.toString()}`,
+ ],
+ name: "Duplicate Language",
+ type: "Error",
+ severity: "High",
+ description: "",
+ recommandation: "",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ } else {
+ titleLanguages.push(translation.language.data.id);
+ }
+ } else {
report.lines.push({
subitems: [
content.attributes.slug,
`Title ${titleIndex.toString()}`,
],
- name: "Duplicate Language",
+ name: "No Language",
type: "Error",
- severity: "High",
+ severity: "Very High",
+ description: "",
+ recommandation: "",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ }
+ if (!translation.description) {
+ report.lines.push({
+ subitems: [
+ content.attributes.slug,
+ `Title ${titleIndex.toString()}`,
+ ],
+ name: "No Description",
+ type: "Missing",
+ severity: "Medium",
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
- } else {
- titleLanguages.push(translation.language.data.id);
}
- } else {
- report.lines.push({
- subitems: [
- content.attributes.slug,
- `Title ${titleIndex.toString()}`,
- ],
- name: "No Language",
- type: "Error",
- severity: "Very High",
- description: "",
- recommandation: "",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
- if (!translation.description) {
- report.lines.push({
- subitems: [
- content.attributes.slug,
- `Title ${titleIndex.toString()}`,
- ],
- name: "No Description",
- type: "Missing",
- severity: "Medium",
- description: "",
- recommandation: "",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
- if (translation.text_set) {
+ if (translation.text_set) {
+ report.lines.push({
+ subitems: [content.attributes.slug],
+ name: "No Text Set",
+ type: "Missing",
+ severity: "Medium",
+ description: "The Content has no Text Set.",
+ recommandation: "",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ } else {
+ /*
+ *const textSetLanguages: string[] = [];
+ *if (content.attributes && textSet) {
+ * if (textSet.language?.data?.id) {
+ * if (textSet.language.data.id in textSetLanguages) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "Duplicate Language",
+ * type: "Error",
+ * severity: "High",
+ * description: "",
+ * recommandation: "",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * } else {
+ * textSetLanguages.push(textSet.language.data.id);
+ * }
+ * } else {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "No Language",
+ * type: "Error",
+ * severity: "Very High",
+ * description: "",
+ * recommandation: "",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ *
+ * if (!textSet.source_language?.data?.id) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "No Source Language",
+ * type: "Error",
+ * severity: "High",
+ * description: "",
+ * recommandation: "",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ *
+ * if (textSet.status !== Enum_Componentsetstextset_Status.Done) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "Not Done Status",
+ * type: "Improvement",
+ * severity: "Low",
+ * description: "",
+ * recommandation: "",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ *
+ * if (!textSet.text || textSet.text.length < 10) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "No Text",
+ * type: "Missing",
+ * severity: "Medium",
+ * description: "",
+ * recommandation: "",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ *
+ * if (
+ * textSet.source_language?.data?.id ===
+ * textSet.language?.data?.id
+ * ) {
+ * if (textSet.transcribers?.data.length === 0) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "No Transcribers",
+ * type: "Missing",
+ * severity: "High",
+ * description:
+ * "The Content is a Transcription but doesn't credit any Transcribers.",
+ * recommandation: "Add the appropriate Transcribers.",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ * if (
+ * textSet.translators?.data &&
+ * textSet.translators.data.length > 0
+ * ) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "Credited Translators",
+ * type: "Error",
+ * severity: "High",
+ * description:
+ * "The Content is a Transcription but credits one or more Translators.",
+ * recommandation:
+ * "If appropriate, create a Translation Text Set with the Translator credited there.",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ * } else {
+ * if (textSet.translators?.data.length === 0) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "No Translators",
+ * type: "Missing",
+ * severity: "High",
+ * description:
+ * "The Content is a Transcription but doesn't credit any Translators.",
+ * recommandation: "Add the appropriate Translators.",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ * if (
+ * textSet.transcribers?.data &&
+ * textSet.transcribers.data.length > 0
+ * ) {
+ * report.lines.push({
+ * subitems: [
+ * content.attributes.slug,
+ * `TextSet ${textSetIndex.toString()}`,
+ * ],
+ * name: "Credited Transcribers",
+ * type: "Error",
+ * severity: "High",
+ * description:
+ * "The Content is a Translation but credits one or more Transcribers.",
+ * recommandation:
+ * "If appropriate, create a Transcription Text Set with the Transcribers credited there.",
+ * backendUrl: backendUrl,
+ * frontendUrl: frontendUrl,
+ * });
+ * }
+ * }
+ *}
+ */
+ }
+
report.lines.push({
subitems: [content.attributes.slug],
- name: "No Text Set",
+ name: "No Sets",
type: "Missing",
severity: "Medium",
- description: "The Content has no Text Set.",
+ description: "The Content has no Sets.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
- } else {
- /*
- *const textSetLanguages: string[] = [];
- *if (content.attributes && textSet) {
- * if (textSet.language?.data?.id) {
- * if (textSet.language.data.id in textSetLanguages) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "Duplicate Language",
- * type: "Error",
- * severity: "High",
- * description: "",
- * recommandation: "",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * } else {
- * textSetLanguages.push(textSet.language.data.id);
- * }
- * } else {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "No Language",
- * type: "Error",
- * severity: "Very High",
- * description: "",
- * recommandation: "",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- *
- * if (!textSet.source_language?.data?.id) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "No Source Language",
- * type: "Error",
- * severity: "High",
- * description: "",
- * recommandation: "",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- *
- * if (textSet.status !== Enum_Componentsetstextset_Status.Done) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "Not Done Status",
- * type: "Improvement",
- * severity: "Low",
- * description: "",
- * recommandation: "",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- *
- * if (!textSet.text || textSet.text.length < 10) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "No Text",
- * type: "Missing",
- * severity: "Medium",
- * description: "",
- * recommandation: "",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- *
- * if (
- * textSet.source_language?.data?.id ===
- * textSet.language?.data?.id
- * ) {
- * if (textSet.transcribers?.data.length === 0) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "No Transcribers",
- * type: "Missing",
- * severity: "High",
- * description:
- * "The Content is a Transcription but doesn't credit any Transcribers.",
- * recommandation: "Add the appropriate Transcribers.",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- * if (
- * textSet.translators?.data &&
- * textSet.translators.data.length > 0
- * ) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "Credited Translators",
- * type: "Error",
- * severity: "High",
- * description:
- * "The Content is a Transcription but credits one or more Translators.",
- * recommandation:
- * "If appropriate, create a Translation Text Set with the Translator credited there.",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- * } else {
- * if (textSet.translators?.data.length === 0) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "No Translators",
- * type: "Missing",
- * severity: "High",
- * description:
- * "The Content is a Transcription but doesn't credit any Translators.",
- * recommandation: "Add the appropriate Translators.",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- * if (
- * textSet.transcribers?.data &&
- * textSet.transcribers.data.length > 0
- * ) {
- * report.lines.push({
- * subitems: [
- * content.attributes.slug,
- * `TextSet ${textSetIndex.toString()}`,
- * ],
- * name: "Credited Transcribers",
- * type: "Error",
- * severity: "High",
- * description:
- * "The Content is a Translation but credits one or more Transcribers.",
- * recommandation:
- * "If appropriate, create a Transcription Text Set with the Transcribers credited there.",
- * backendUrl: backendUrl,
- * frontendUrl: frontendUrl,
- * });
- * }
- * }
- *}
- */
}
-
- report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Sets",
- type: "Missing",
- severity: "Medium",
- description: "The Content has no Sets.",
- recommandation: "",
- backendUrl: backendUrl,
- frontendUrl: frontendUrl,
- });
- }
- );
+ );
+ }
}
- });
+ );
return report;
};
diff --git a/src/pages/dev/checkup/libraryitems.tsx b/src/pages/dev/checkup/libraryitems.tsx
index ebcc49c..e747cfe 100644
--- a/src/pages/dev/checkup/libraryitems.tsx
+++ b/src/pages/dev/checkup/libraryitems.tsx
@@ -65,7 +65,7 @@ const CheckupLibraryItems = ({
/>
{line.subitems.join(" -> ")}
{line.name}
- {line.type}
+
- {line.severity}
-
+ text={line.severity}
+ />
{line.description}
diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx
index f3a02d6..5f9ec40 100644
--- a/src/pages/library/[slug]/index.tsx
+++ b/src/pages/library/[slug]/index.tsx
@@ -221,15 +221,17 @@ const LibrarySlug = ({
{item.urls?.length ? (
{langui.available_at}
- {filterHasAttributes(item.urls).map((url, index) => (
-
-
-
- ))}
+ {filterHasAttributes(item.urls, ["url"] as const).map(
+ (url, index) => (
+
+
+
+ )
+ )}
) : (
{langui.item_not_available}
@@ -246,33 +248,32 @@ const LibrarySlug = ({
className="grid w-full grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-end
gap-8"
>
- {filterHasAttributes(item.gallery.data).map(
- (galleryItem, index) => (
-
- (
+
+ {
- const images: string[] = filterHasAttributes(
- item.gallery?.data
- ).map((image) =>
- getAssetURL(
- image.attributes.url,
- ImageQuality.Large
- )
- );
- openLightBox(images, index);
- }}
- >
-
+ getAssetURL(image.attributes.url, ImageQuality.Large)
+ );
+ openLightBox(images, index);
+ }}
+ >
+
-
-
- )
- )}
+ image={galleryItem.attributes}
+ />
+
+
+ ))}
)}
@@ -288,9 +289,9 @@ const LibrarySlug = ({
{langui.type}
- {prettyItemType(item.metadata[0], langui)}
+
{"›"}
- {prettyItemSubType(item.metadata[0])}
+
)}
@@ -331,8 +332,10 @@ const LibrarySlug = ({
{langui.categories}
- {item.categories.data.map((category) => (
- {category.attributes?.name}
+ {filterHasAttributes(item.categories.data, [
+ "attributes",
+ ] as const).map((category) => (
+
))}
@@ -458,7 +461,10 @@ const LibrarySlug = ({
className="grid w-full grid-cols-[repeat(auto-fill,minmax(15rem,1fr))]
items-end gap-8 mobile:grid-cols-2 thin:grid-cols-1"
>
- {filterHasAttributes(item.subitems.data).map((subitem) => (
+ {filterHasAttributes(item.subitems.data, [
+ "id",
+ "attributes",
+ ] as const).map((subitem) => (
)}
- {filterHasAttributes(item.contents.data).map(
- (rangedContent) => (
- (
+ ({
+ pre_title: translation.pre_title,
+ title: translation.title,
+ subtitle: translation.subtitle,
+ language:
+ translation.language?.data?.attributes?.code,
+ })),
+ categories: filterHasAttributes(
+ rangedContent.attributes.content.data.attributes
+ .categories?.data,
+ ["attributes"]
+ ).map((category) => category.attributes.short),
+ type:
+ rangedContent.attributes.content.data.attributes
+ .type?.data?.attributes?.titles?.[0]?.title ??
+ prettySlug(
rangedContent.attributes.content.data.attributes
- .translations
- ).map((translation) => ({
- pre_title: translation.pre_title,
- title: translation.title,
- subtitle: translation.subtitle,
- language:
- translation.language?.data?.attributes?.code,
- })),
- categories: filterHasAttributes(
- rangedContent.attributes.content.data.attributes
- .categories?.data
- ).map((category) => category.attributes.short),
- type:
- rangedContent.attributes.content.data.attributes
- .type?.data?.attributes?.titles?.[0]?.title ??
- prettySlug(
- rangedContent.attributes.content.data
- .attributes.type?.data?.attributes?.slug
- ),
- slug: rangedContent.attributes.content.data
- .attributes.slug,
- }
- : undefined
- }
- langui={langui}
- rangeStart={
- rangedContent.attributes.range[0]?.__typename ===
- "ComponentRangePageRange"
- ? `${rangedContent.attributes.range[0].starting_page}`
- : ""
- }
- slug={rangedContent.attributes.slug}
- parentSlug={item.slug}
- key={rangedContent.id}
- languages={languages}
- hasScanSet={
- isDefined(rangedContent.attributes.scan_set) &&
- rangedContent.attributes.scan_set.length > 0
- }
- />
- )
- )}
+ .type?.data?.attributes?.slug
+ ),
+ slug: rangedContent.attributes.content.data
+ .attributes.slug,
+ }
+ : undefined
+ }
+ langui={langui}
+ rangeStart={
+ rangedContent.attributes.range[0]?.__typename ===
+ "ComponentRangePageRange"
+ ? `${rangedContent.attributes.range[0].starting_page}`
+ : ""
+ }
+ slug={rangedContent.attributes.slug}
+ parentSlug={item.slug}
+ key={rangedContent.id}
+ languages={languages}
+ hasScanSet={
+ isDefined(rangedContent.attributes.scan_set) &&
+ rangedContent.attributes.scan_set.length > 0
+ }
+ />
+ ))}
)}
@@ -643,7 +650,9 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
const sdk = getReadySdk();
const libraryItems = await sdk.getLibraryItemsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- filterHasAttributes(libraryItems.libraryItems?.data).map((item) => {
+ filterHasAttributes(libraryItems.libraryItems?.data, [
+ "attributes",
+ ] as const).map((item) => {
context.locales?.map((local) =>
paths.push({ params: { slug: item.attributes.slug }, locale: local })
);
@@ -702,8 +711,6 @@ const ContentLine = ({
),
});
- console.log(prettySlug(slug, parentSlug));
-
return (
{content?.categories?.map((category, index) => (
- {category}
+
))}
{rangeStart}
{content?.type && (
-
{content.type}
+
)}
{
const sdk = getReadySdk();
const libraryItems = await sdk.getLibraryItemsSlugs({});
const paths: GetStaticPathsResult["paths"] = [];
- filterHasAttributes(libraryItems.libraryItems?.data).map((item) => {
+ filterHasAttributes(libraryItems.libraryItems?.data, [
+ "attributes",
+ ] as const).map((item) => {
context.locales?.map((local) =>
paths.push({ params: { slug: item.attributes.slug }, locale: local })
);
diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx
index 11cd7d9..fe25946 100644
--- a/src/pages/library/index.tsx
+++ b/src/pages/library/index.tsx
@@ -17,10 +17,7 @@ import {
prettyinlineTitle,
prettyItemSubType,
} from "helpers/formatters";
-import {
- LibraryItemUserStatus,
- SelectiveRequiredNonNullable,
-} from "helpers/types";
+import { LibraryItemUserStatus } from "helpers/types";
import { Icon } from "components/Ico";
import { WithLabel } from "components/Inputs/WithLabel";
import { TextInput } from "components/Inputs/TextInput";
@@ -35,6 +32,7 @@ import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholde
import { useAppLayout } from "contexts/AppLayoutContext";
import { convertPrice } from "helpers/numbers";
import { SmartList } from "components/SmartList";
+import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
/*
* ╭─────────────╮
@@ -97,10 +95,7 @@ const Library = ({
const filteringFunction = useCallback(
(
- item: SelectiveRequiredNonNullable<
- Props["items"][number],
- "attributes" | "id"
- >
+ item: SelectiveNonNullable
) => {
if (!showSubitems && !item.attributes.root_item) return false;
if (
@@ -143,14 +138,8 @@ const Library = ({
const sortingFunction = useCallback(
(
- a: SelectiveRequiredNonNullable<
- Props["items"][number],
- "attributes" | "id"
- >,
- b: SelectiveRequiredNonNullable<
- Props["items"][number],
- "attributes" | "id"
- >
+ a: SelectiveNonNullable,
+ b: SelectiveNonNullable
) => {
switch (sortingMethod) {
case 0: {
@@ -193,15 +182,13 @@ const Library = ({
const groupingFunction = useCallback(
(
- item: SelectiveRequiredNonNullable<
- Props["items"][number],
- "attributes" | "id"
- >
+ item: SelectiveNonNullable
): string[] => {
switch (groupingMethod) {
case 0: {
const categories = filterHasAttributes(
- item.attributes.categories?.data
+ item.attributes.categories?.data,
+ ["attributes"] as const
);
if (categories.length > 0) {
return categories.map((category) => category.attributes.name);
@@ -406,7 +393,7 @@ const Library = ({
() => (
item.id}
renderItem={({ item }) => (
{
const posts = await sdk.getPostsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- filterHasAttributes(posts.posts?.data).map((item) => {
- context.locales?.map((local) =>
- paths.push({ params: { slug: item.attributes.slug }, locale: local })
- );
- });
+ filterHasAttributes(posts.posts?.data, ["attributes"] as const).map(
+ (item) => {
+ context.locales?.map((local) =>
+ paths.push({ params: { slug: item.attributes.slug }, locale: local })
+ );
+ }
+ );
return {
paths,
fallback: "blocking",
diff --git a/src/pages/news/index.tsx b/src/pages/news/index.tsx
index 2c6308a..63f9e00 100644
--- a/src/pages/news/index.tsx
+++ b/src/pages/news/index.tsx
@@ -97,7 +97,7 @@ const News = ({
() => (
post.id}
langui={langui}
renderItem={({ item: post }) => (
diff --git a/src/pages/wiki/[slug]/index.tsx b/src/pages/wiki/[slug]/index.tsx
index 4bbd722..8854ade 100644
--- a/src/pages/wiki/[slug]/index.tsx
+++ b/src/pages/wiki/[slug]/index.tsx
@@ -100,8 +100,10 @@ const WikiPage = ({
{langui.categories}
- {page.categories?.data.map((category) => (
- {category.attributes?.name}
+ {filterHasAttributes(page.categories?.data, [
+ "attributes",
+ ] as const).map((category) => (
+
))}
@@ -116,30 +118,28 @@ const WikiPage = ({
)}
- {filterHasAttributes(page.definitions, ["translations"]).map(
- (definition, index) => (
- <>
- ({
- language: translation.language.data?.attributes?.code,
- definition: translation.definition,
- status: translation.status,
- }))}
- index={index + 1}
- languages={languages}
- langui={langui}
- categories={filterHasAttributes(
- definition.categories?.data
- ).map((category) => category.attributes.short)}
- />
-
- >
- )
- )}
+ {filterHasAttributes(page.definitions, [
+ "translations",
+ ] as const).map((definition, index) => (
+ <>
+ ({
+ language: translation?.language?.data?.attributes?.code,
+ definition: translation?.definition,
+ status: translation?.status,
+ }))}
+ index={index + 1}
+ languages={languages}
+ langui={langui}
+ categories={filterHasAttributes(definition.categories?.data, [
+ "attributes",
+ ] as const).map((category) => category.attributes.short)}
+ />
+
+ >
+ ))}
)}
@@ -194,14 +194,16 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
const sdk = getReadySdk();
const contents = await sdk.getWikiPagesSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- filterHasAttributes(contents.wikiPages?.data).map((wikiPage) => {
- context.locales?.map((local) =>
- paths.push({
- params: { slug: wikiPage.attributes.slug },
- locale: local,
- })
- );
- });
+ filterHasAttributes(contents.wikiPages?.data, ["attributes"] as const).map(
+ (wikiPage) => {
+ context.locales?.map((local) =>
+ paths.push({
+ params: { slug: wikiPage.attributes.slug },
+ locale: local,
+ })
+ );
+ }
+ );
return {
paths,
fallback: "blocking",
diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx
index dcaf051..54fa089 100644
--- a/src/pages/wiki/chronology.tsx
+++ b/src/pages/wiki/chronology.tsx
@@ -74,22 +74,24 @@ const Chronology = ({
horizontalLine
/>
- {filterHasAttributes(chronologyEras).map((era) => (
-
- 0 &&
- era.attributes.title[0]
- ? era.attributes.title[0].title
- : prettySlug(era.attributes.slug)
- }
- subtitle={`${era.attributes.starting_year} → ${era.attributes.ending_year}`}
- border
- />
-
- ))}
+ {filterHasAttributes(chronologyEras, ["attributes", "id"] as const).map(
+ (era) => (
+
+ 0 &&
+ era.attributes.title[0]
+ ? era.attributes.title[0].title
+ : prettySlug(era.attributes.slug)
+ }
+ subtitle={`${era.attributes.starting_year} → ${era.attributes.ending_year}`}
+ border
+ />
+
+ )
+ )}
),
[chronologyEras, langui]
diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx
index d958fcd..0f8d75a 100644
--- a/src/pages/wiki/index.tsx
+++ b/src/pages/wiki/index.tsx
@@ -120,36 +120,37 @@ const Wiki = ({
icon={Icon.ChevronLeft}
/>
)}
- {filterHasAttributes(filteredPages).map((page) => (
+ {filterHasAttributes(filteredPages, [
+ "id",
+ "attributes.translations",
+ ] as const).map((page) => (
- {page.attributes.translations && (
- ({
- 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={page.attributes.thumbnail?.data?.attributes}
- thumbnailAspectRatio={"4/3"}
- thumbnailRounded
- thumbnailForceAspectRatio
- languages={languages}
- slug={page.attributes.slug}
- keepInfoVisible={keepInfoVisible}
- bottomChips={page.attributes.categories?.data.map(
- (category) => category.attributes?.short ?? ""
- )}
- />
- )}
+ ({
+ 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={page.attributes.thumbnail?.data?.attributes}
+ thumbnailAspectRatio={"4/3"}
+ thumbnailRounded
+ thumbnailForceAspectRatio
+ languages={languages}
+ slug={page.attributes.slug}
+ keepInfoVisible={keepInfoVisible}
+ bottomChips={page.attributes.categories?.data.map(
+ (category) => category.attributes?.short ?? ""
+ )}
+ />
))}