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) => ( - -
) : (

{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 ?? "" + )} + /> ))}