)}
@@ -144,16 +154,18 @@ export function ScanSet(props: Props): JSX.Element {
)}
@@ -163,16 +175,18 @@ export function ScanSet(props: Props): JSX.Element {
)}
@@ -188,18 +202,15 @@ export function ScanSet(props: Props): JSX.Element {
className="grid items-end gap-8 border-b-[3px] border-dotted pb-12 last-of-type:border-0
desktop:grid-cols-[repeat(auto-fill,_minmax(10rem,1fr))] mobile:grid-cols-2"
>
- {selectedScan.pages?.data.map((page, index) => (
+ {pages.map((page, index) => (
{
const images: string[] = [];
- selectedScan.pages?.data.map((image) => {
- if (
- image.attributes &&
- isDefinedAndNotEmpty(image.attributes.url)
- )
+ pages.map((image) => {
+ if (isDefinedAndNotEmpty(image.attributes.url))
images.push(
getAssetURL(image.attributes.url, ImageQuality.Large)
);
diff --git a/src/components/Library/ScanSetCover.tsx b/src/components/Library/ScanSetCover.tsx
index 5d346d9..485fba4 100644
--- a/src/components/Library/ScanSetCover.tsx
+++ b/src/components/Library/ScanSetCover.tsx
@@ -8,7 +8,7 @@ import {
} from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { getAssetURL, ImageQuality } from "helpers/img";
-import { getStatusDescription } from "helpers/others";
+import { filterHasAttributes, getStatusDescription } from "helpers/others";
import { useSmartLanguage } from "hooks/useSmartLanguage";
import { Fragment } from "react";
@@ -87,16 +87,16 @@ export function ScanSetCover(props: Props): JSX.Element {
{"Scanners"}:
- {selectedScan.scanners.data.map((scanner) => (
-
- {scanner.attributes && (
+ {filterHasAttributes(selectedScan.scanners.data).map(
+ (scanner) => (
+
- )}
-
- ))}
+
+ )
+ )}
)}
@@ -105,16 +105,16 @@ export function ScanSetCover(props: Props): JSX.Element {
{"Cleaners"}:
- {selectedScan.cleaners.data.map((cleaner) => (
-
- {cleaner.attributes && (
+ {filterHasAttributes(selectedScan.cleaners.data).map(
+ (cleaner) => (
+
- )}
-
- ))}
+
+ )
+ )}
)}
@@ -124,16 +124,16 @@ export function ScanSetCover(props: Props): JSX.Element {
{"Typesetters"}:
- {selectedScan.typesetters.data.map((typesetter) => (
-
- {typesetter.attributes && (
+ {filterHasAttributes(selectedScan.typesetters.data).map(
+ (typesetter) => (
+
- )}
-
- ))}
+
+ )
+ )}
)}
diff --git a/src/components/PanelComponents/ContentPlaceholder.tsx b/src/components/PanelComponents/ContentPlaceholder.tsx
new file mode 100644
index 0000000..935735b
--- /dev/null
+++ b/src/components/PanelComponents/ContentPlaceholder.tsx
@@ -0,0 +1,30 @@
+import { Ico, Icon } from "components/Ico";
+import { cIf, cJoin } from "helpers/className";
+import { isDefined } from "helpers/others";
+
+interface Props {
+ message: string;
+ icon?: Icon;
+}
+
+export function ContentPlaceholder(props: Props): JSX.Element {
+ const { message, icon } = props;
+ return (
+
+
+ {isDefined(icon) &&
}
+
+ {message}
+
+
+
+ );
+}
diff --git a/src/components/PanelComponents/NavOption.tsx b/src/components/PanelComponents/NavOption.tsx
index 53ab3d3..e616edf 100644
--- a/src/components/PanelComponents/NavOption.tsx
+++ b/src/components/PanelComponents/NavOption.tsx
@@ -17,7 +17,15 @@ interface Props {
}
export function NavOption(props: Props): JSX.Element {
- const { url, icon, title, subtitle, border, reduced, onClick } = props;
+ const {
+ url,
+ icon,
+ title,
+ subtitle,
+ border = false,
+ reduced = false,
+ onClick,
+ } = props;
const router = useRouter();
const isActive = useMemo(
() => router.asPath.startsWith(url),
@@ -36,7 +44,7 @@ export function NavOption(props: Props): JSX.Element {
}
placement="right"
className="text-left"
- disabled={reduced === false}
+ disabled={!reduced}
>
{
@@ -63,7 +71,7 @@ export function NavOption(props: Props): JSX.Element {
>
{icon &&
}
- {reduced === false && (
+ {!reduced && (
{title}
{isDefinedAndNotEmpty(subtitle) && (
diff --git a/src/components/Panels/ContentPanel.tsx b/src/components/Panels/ContentPanel.tsx
index 91f30f3..c3fbe8e 100644
--- a/src/components/Panels/ContentPanel.tsx
+++ b/src/components/Panels/ContentPanel.tsx
@@ -15,10 +15,10 @@ export function ContentPanel(props: Props): JSX.Element {
const { width = ContentPanelWidthSizes.Default, children } = props;
return (
-
+
{(!mainPanelReduced || !isDesktop) && (
- Accord’s Library
+ Accord’s Library
)}
{
- setMenuGestures(state);
+ setMenuGestures(!state);
}, [setMenuGestures, state]);
return (
diff --git a/src/components/PostPage.tsx b/src/components/PostPage.tsx
index 83167b2..07f8e75 100644
--- a/src/components/PostPage.tsx
+++ b/src/components/PostPage.tsx
@@ -1,7 +1,7 @@
import { AppStaticProps } from "graphql/getAppStaticProps";
import { getDescription } from "helpers/description";
import { prettySlug } from "helpers/formatters";
-import { getStatusDescription } from "helpers/others";
+import { filterHasAttributes, getStatusDescription } from "helpers/others";
import { PostWithTranslations } from "helpers/types";
import { useSmartLanguage } from "hooks/useSmartLanguage";
import { Fragment, useMemo } from "react";
@@ -102,14 +102,12 @@ export function PostPage(props: Props): JSX.Element {
{"Authors"}:
- {post.authors.data.map((author) => (
+ {filterHasAttributes(post.authors.data).map((author) => (
- {author.attributes && (
-
- )}
+
))}
diff --git a/src/components/PreviewCard.tsx b/src/components/PreviewCard.tsx
index ff3c330..2e2e095 100644
--- a/src/components/PreviewCard.tsx
+++ b/src/components/PreviewCard.tsx
@@ -244,7 +244,8 @@ export function PreviewCard(props: Props): JSX.Element {
cIf(
!keepInfoVisible,
`-inset-x-0.5 bottom-2 opacity-0 group-hover:opacity-100 hoverable:absolute
- hoverable:drop-shadow-shade-lg notHoverable:rounded-b-md`
+ hoverable:drop-shadow-shade-lg notHoverable:opacity-100
+ notHoverable:rounded-b-md`
)
)}
>
@@ -302,9 +303,7 @@ interface TranslatedProps
languages: AppStaticProps["languages"];
}
-export function TranslatedPreviewCard(
- props: Immutable
-): JSX.Element {
+export function TranslatedPreviewCard(props: TranslatedProps): JSX.Element {
const {
translations = [{ title: props.slug, language: "default" }],
slug,
diff --git a/src/components/PreviewLine.tsx b/src/components/PreviewLine.tsx
index a76e478..5e34e0c 100644
--- a/src/components/PreviewLine.tsx
+++ b/src/components/PreviewLine.tsx
@@ -89,7 +89,7 @@ interface TranslatedProps
}
export function TranslatedPreviewLine(
- props: Immutable
+ props: TranslatedProps
): JSX.Element {
const {
translations = [{ title: props.slug, language: "default" }],
diff --git a/src/components/RecorderChip.tsx b/src/components/RecorderChip.tsx
index 1da4460..9aadef6 100644
--- a/src/components/RecorderChip.tsx
+++ b/src/components/RecorderChip.tsx
@@ -2,6 +2,7 @@ import { Chip } from "components/Chip";
import { RecorderChipFragment } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { ImageQuality } from "helpers/img";
+import { filterHasAttributes } from "helpers/others";
import { Fragment } from "react";
import { Img } from "./Img";
@@ -33,13 +34,13 @@ export function RecorderChip(props: Props): JSX.Element {
{recorder.languages?.data && recorder.languages.data.length > 0 && (
{langui.languages}:
- {recorder.languages.data.map((language) => (
-
- {language.attributes && (
+ {filterHasAttributes(recorder.languages.data).map(
+ (language) => (
+
{language.attributes.code.toUpperCase()}
- )}
-
- ))}
+
+ )
+ )}
)}
{recorder.pronouns && (
diff --git a/src/components/ThumbnailHeader.tsx b/src/components/ThumbnailHeader.tsx
index 87dfd97..4d7445c 100644
--- a/src/components/ThumbnailHeader.tsx
+++ b/src/components/ThumbnailHeader.tsx
@@ -6,6 +6,7 @@ import { GetContentTextQuery, UploadImageFragment } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettyinlineTitle, prettySlug, slugify } from "helpers/formatters";
import { getAssetURL, ImageQuality } from "helpers/img";
+import { filterHasAttributes } from "helpers/others";
import { useLightBox } from "hooks/useLightBox";
@@ -89,9 +90,11 @@ export function ThumbnailHeader(props: Props): JSX.Element {
{langui.categories}
- {categories.data.map((category) => (
- {category.attributes?.name}
- ))}
+ {filterHasAttributes(categories.data).map(
+ (category) => (
+ {category.attributes.name}
+ )
+ )}
)}
diff --git a/src/components/Wiki/Chronology/ChronologyItemComponent.tsx b/src/components/Wiki/Chronology/ChronologyItemComponent.tsx
index c85c4bb..a2af90b 100644
--- a/src/components/Wiki/Chronology/ChronologyItemComponent.tsx
+++ b/src/components/Wiki/Chronology/ChronologyItemComponent.tsx
@@ -6,7 +6,11 @@ import {
GetChronologyItemsQuery,
} from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps";
-import { getStatusDescription } from "helpers/others";
+import {
+ filterDefined,
+ filterHasAttributes,
+ getStatusDescription,
+} from "helpers/others";
import { Fragment } from "react";
@@ -44,13 +48,16 @@ export function ChronologyItemComponent(props: Props): JSX.Element {
- {props.item.attributes.events?.map((event) => (
-
- {event && (
+ {props.item.attributes.events &&
+ filterHasAttributes(props.item.attributes.events, [
+ "id",
+ "translations",
+ ]).map((event) => (
+
- {event.translations?.map((translation, translationIndex) => (
-
- {translation && (
+ {filterDefined(event.translations).map(
+ (translation, translationIndex) => (
+
- )}
-
- ))}
+
+ )
+ )}
{event.source?.data ? (
@@ -109,9 +116,8 @@ export function ChronologyItemComponent(props: Props): JSX.Element {
)}
- )}
-
- ))}
+
+ ))}
);
diff --git a/src/helpers/libraryItem.ts b/src/helpers/libraryItem.ts
index df09011..bada7af 100644
--- a/src/helpers/libraryItem.ts
+++ b/src/helpers/libraryItem.ts
@@ -3,7 +3,7 @@ import { GetLibraryItemsPreviewQuery } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettyinlineTitle, prettyDate } from "./formatters";
import { convertPrice } from "./numbers";
-import { isDefined } from "./others";
+import { isDefined, mapRemoveEmptyValues } from "./others";
import { LibraryItemUserStatus } from "./types";
type Items = NonNullable["data"];
type GroupLibraryItems = Map;
@@ -13,67 +13,67 @@ export function getGroups(
groupByType: number,
items: Items
): GroupLibraryItems {
+ const groups: GroupLibraryItems = new Map();
+
switch (groupByType) {
case 0: {
- const typeGroup = new Map();
- typeGroup.set("Drakengard 1", []);
- typeGroup.set("Drakengard 1.3", []);
- typeGroup.set("Drakengard 2", []);
- typeGroup.set("Drakengard 3", []);
- typeGroup.set("Drakengard 4", []);
- typeGroup.set("NieR Gestalt", []);
- typeGroup.set("NieR Replicant", []);
- typeGroup.set("NieR Replicant ver.1.22474487139...", []);
- typeGroup.set("NieR:Automata", []);
- typeGroup.set("NieR Re[in]carnation", []);
- typeGroup.set("SINoALICE", []);
- typeGroup.set("Voice of Cards", []);
- typeGroup.set("Final Fantasy XIV", []);
- typeGroup.set("Thou Shalt Not Die", []);
- typeGroup.set("Bakuken", []);
- typeGroup.set("YoRHa", []);
- typeGroup.set("YoRHa Boys", []);
- typeGroup.set(langui.no_category, []);
+ const noCategory = langui.no_category ?? "No category";
+ groups.set("Drakengard 1", []);
+ groups.set("Drakengard 1.3", []);
+ groups.set("Drakengard 2", []);
+ groups.set("Drakengard 3", []);
+ groups.set("Drakengard 4", []);
+ groups.set("NieR Gestalt", []);
+ groups.set("NieR Replicant", []);
+ groups.set("NieR Replicant ver.1.22474487139...", []);
+ groups.set("NieR:Automata", []);
+ groups.set("NieR Re[in]carnation", []);
+ groups.set("SINoALICE", []);
+ groups.set("Voice of Cards", []);
+ groups.set("Final Fantasy XIV", []);
+ groups.set("Thou Shalt Not Die", []);
+ groups.set("Bakuken", []);
+ groups.set("YoRHa", []);
+ groups.set("YoRHa Boys", []);
+ groups.set(noCategory, []);
items.map((item) => {
if (item.attributes?.categories?.data.length === 0) {
- typeGroup.get(langui.no_category)?.push(item);
+ groups.get(noCategory)?.push(item);
} else {
item.attributes?.categories?.data.map((category) => {
- typeGroup.get(category.attributes?.name)?.push(item);
+ groups.get(category.attributes?.name ?? noCategory)?.push(item);
});
}
});
-
- return typeGroup;
+ break;
}
case 1: {
- const group = new Map();
- group.set(langui.audio ?? "Audio", []);
- group.set(langui.game ?? "Game", []);
- group.set(langui.textual ?? "Textual", []);
- group.set(langui.video ?? "Video", []);
- group.set(langui.other ?? "Other", []);
- group.set(langui.group ?? "Group", []);
- group.set(langui.no_type ?? "No type", []);
+ groups.set(langui.audio ?? "Audio", []);
+ groups.set(langui.game ?? "Game", []);
+ groups.set(langui.textual ?? "Textual", []);
+ groups.set(langui.video ?? "Video", []);
+ groups.set(langui.other ?? "Other", []);
+ groups.set(langui.group ?? "Group", []);
+ groups.set(langui.no_type ?? "No type", []);
items.map((item) => {
if (item.attributes?.metadata && item.attributes.metadata.length > 0) {
switch (item.attributes.metadata[0]?.__typename) {
case "ComponentMetadataAudio":
- group.get(langui.audio ?? "Audio")?.push(item);
+ groups.get(langui.audio ?? "Audio")?.push(item);
break;
case "ComponentMetadataGame":
- group.get(langui.game ?? "Game")?.push(item);
+ groups.get(langui.game ?? "Game")?.push(item);
break;
case "ComponentMetadataBooks":
- group.get(langui.textual ?? "Textual")?.push(item);
+ groups.get(langui.textual ?? "Textual")?.push(item);
break;
case "ComponentMetadataVideo":
- group.get(langui.video ?? "Video")?.push(item);
+ groups.get(langui.video ?? "Video")?.push(item);
break;
case "ComponentMetadataOther":
- group.get(langui.other ?? "Other")?.push(item);
+ groups.get(langui.other ?? "Other")?.push(item);
break;
case "ComponentMetadataGroup":
switch (
@@ -81,19 +81,19 @@ export function getGroups(
?.slug
) {
case "audio":
- group.get(langui.audio ?? "Audio")?.push(item);
+ groups.get(langui.audio ?? "Audio")?.push(item);
break;
case "video":
- group.get(langui.video ?? "Video")?.push(item);
+ groups.get(langui.video ?? "Video")?.push(item);
break;
case "game":
- group.get(langui.game ?? "Game")?.push(item);
+ groups.get(langui.game ?? "Game")?.push(item);
break;
case "textual":
- group.get(langui.textual ?? "Textual")?.push(item);
+ groups.get(langui.textual ?? "Textual")?.push(item);
break;
case "mixed":
- group.get(langui.group ?? "Group")?.push(item);
+ groups.get(langui.group ?? "Group")?.push(item);
break;
default: {
throw new Error(
@@ -107,10 +107,10 @@ export function getGroups(
}
}
} else {
- group.get(langui.no_type ?? "No type")?.push(item);
+ groups.get(langui.no_type ?? "No type")?.push(item);
}
});
- return group;
+ break;
}
case 2: {
@@ -121,29 +121,28 @@ export function getGroups(
years.push(item.attributes.release_date.year);
}
});
- const group = new Map();
+
years.sort((a, b) => a - b);
years.map((year) => {
- group.set(year.toString(), []);
+ groups.set(year.toString(), []);
});
- group.set(langui.no_year ?? "No year", []);
+ groups.set(langui.no_year ?? "No year", []);
items.map((item) => {
if (item.attributes?.release_date?.year) {
- group.get(item.attributes.release_date.year.toString())?.push(item);
+ groups.get(item.attributes.release_date.year.toString())?.push(item);
} else {
- group.get(langui.no_year ?? "No year")?.push(item);
+ groups.get(langui.no_year ?? "No year")?.push(item);
}
});
-
- return group;
+ break;
}
default: {
- const group = new Map();
- group.set("", items);
- return group;
+ groups.set("", items);
+ break;
}
}
+ return mapRemoveEmptyValues(groups);
}
export function filterItems(
@@ -155,7 +154,7 @@ export function filterItems(
showSecondaryItems: boolean,
filterUserStatus: LibraryItemUserStatus | undefined
): Items {
- return [...items].filter((item) => {
+ return items.filter((item) => {
if (!showSubitems && !item.attributes?.root_item) return false;
if (showSubitems && isUntangibleGroupItem(item.attributes?.metadata?.[0])) {
return false;
@@ -212,7 +211,7 @@ export function sortBy(
): Items {
switch (orderByType) {
case 0:
- return [...items].sort((a, b) => {
+ return items.sort((a, b) => {
const titleA = prettyinlineTitle(
"",
a.attributes?.title,
@@ -226,7 +225,7 @@ export function sortBy(
return titleA.localeCompare(titleB);
});
case 1:
- return [...items].sort((a, b) => {
+ return items.sort((a, b) => {
const priceA = a.attributes?.price
? convertPrice(a.attributes.price, currencies[0])
: 99999;
@@ -236,7 +235,7 @@ export function sortBy(
return priceA - priceB;
});
case 2:
- return [...items].sort((a, b) => {
+ return items.sort((a, b) => {
const dateA = a.attributes?.release_date
? prettyDate(a.attributes.release_date)
: "9999";
diff --git a/src/helpers/others.ts b/src/helpers/others.ts
index cdaa15b..64d2dce 100644
--- a/src/helpers/others.ts
+++ b/src/helpers/others.ts
@@ -4,6 +4,7 @@ import {
GetLibraryItemScansQuery,
} from "graphql/generated";
import { AppStaticProps } from "../graphql/getAppStaticProps";
+import { SelectiveRequiredNonNullable } from "./types";
type SortContentProps =
| NonNullable<
@@ -59,11 +60,6 @@ export function getStatusDescription(
}
}
-export function arrayMove(arr: T[], old_index: number, new_index: number) {
- arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
- return arr;
-}
-
export function isDefined(t: T): t is NonNullable {
return t !== null && t !== undefined;
}
@@ -78,6 +74,51 @@ export function isDefinedAndNotEmpty(
return isDefined(string) && string.length > 0;
}
-export function filterDefined(t: T[]): NonNullable[] {
+export function filterDefined(t: T[] | undefined | null): NonNullable[] {
+ if (isUndefined(t)) return [];
return t.filter((item) => isDefined(item)) as NonNullable[];
}
+
+export function filterHasAttributes>(
+ t: T[] | undefined | null,
+ attributes?: P[]
+): SelectiveRequiredNonNullable, P>[] {
+ if (isUndefined(t)) return [];
+ return 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>[];
+}
+
+export function iterateMap(
+ map: Map,
+ callbackfn: (key: K, value: V, index: number) => U
+): U[] {
+ const result: U[] = [];
+ let index = 0;
+ for (const [key, value] of map.entries()) {
+ result.push(callbackfn(key, value, index));
+ index += 1;
+ }
+ return result;
+}
+
+export function mapMoveEntry(
+ map: Map,
+ sourceIndex: number,
+ targetIndex: number
+) {
+ return new Map(arrayMove([...map], sourceIndex, targetIndex));
+}
+
+function arrayMove(arr: T[], sourceIndex: number, targetIndex: number) {
+ arr.splice(targetIndex, 0, arr.splice(sourceIndex, 1)[0]);
+ return arr;
+}
+
+export function mapRemoveEmptyValues(groups: Map): Map {
+ return new Map([...groups].filter(([_, items]) => items.length > 0));
+}
diff --git a/src/helpers/types.ts b/src/helpers/types.ts
index 973bc84..68714b9 100644
--- a/src/helpers/types.ts
+++ b/src/helpers/types.ts
@@ -30,9 +30,13 @@ export interface WikiPageWithTranslations
translations: NonNullable;
}
-export type RequiredNonNullable = Required<{
- [P in keyof T]: 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/hooks/useSmartLanguage.tsx b/src/hooks/useSmartLanguage.tsx
index d8ec52e..b3b454c 100644
--- a/src/hooks/useSmartLanguage.tsx
+++ b/src/hooks/useSmartLanguage.tsx
@@ -1,7 +1,7 @@
import { LanguageSwitcher } from "components/Inputs/LanguageSwitcher";
import { useAppLayout } from "contexts/AppLayoutContext";
import { AppStaticProps } from "graphql/getAppStaticProps";
-import { isDefined } from "helpers/others";
+import { filterDefined, isDefined } from "helpers/others";
import { useRouter } from "next/router";
import { useEffect, useMemo, useState } from "react";
@@ -39,11 +39,9 @@ export function useSmartLanguage(
const availableLocales = useMemo(() => {
const map = new Map();
- items.map((elem, index) => {
- if (isDefined(elem)) {
- const result = languageExtractor(elem);
- if (isDefined(result)) map.set(result, index);
- }
+ filterDefined(items).map((elem, index) => {
+ const result = languageExtractor(elem);
+ if (isDefined(result)) map.set(result, index);
});
return map;
}, [items, languageExtractor]);
diff --git a/src/pages/archives/videos/c/[uid].tsx b/src/pages/archives/videos/c/[uid].tsx
index 744853b..15cb249 100644
--- a/src/pages/archives/videos/c/[uid].tsx
+++ b/src/pages/archives/videos/c/[uid].tsx
@@ -24,7 +24,7 @@ import { Fragment, useState } from "react";
import { Icon } from "components/Ico";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { WithLabel } from "components/Inputs/WithLabel";
-import { isDefined } from "helpers/others";
+import { filterHasAttributes, isDefined } from "helpers/others";
interface Props extends AppStaticProps {
channel: NonNullable<
@@ -74,27 +74,25 @@ export default function Channel(props: 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"
>
- {channel?.videos?.data.map((video) => (
+ {filterHasAttributes(channel?.videos?.data).map((video) => (
- {video.attributes && (
-
- )}
+
))}
@@ -137,13 +135,12 @@ export async function getStaticPaths(
const channels = await sdk.getVideoChannelsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
if (channels.videoChannels?.data)
- channels.videoChannels.data.map((channel) => {
+ filterHasAttributes(channels.videoChannels.data).map((channel) => {
context.locales?.map((local) => {
- if (channel.attributes)
- paths.push({
- params: { uid: channel.attributes.uid },
- locale: local,
- });
+ paths.push({
+ params: { uid: channel.attributes.uid },
+ locale: local,
+ });
});
});
return {
diff --git a/src/pages/archives/videos/index.tsx b/src/pages/archives/videos/index.tsx
index 5aa39fb..f3b9414 100644
--- a/src/pages/archives/videos/index.tsx
+++ b/src/pages/archives/videos/index.tsx
@@ -18,6 +18,7 @@ import { GetVideosPreviewQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { prettyDate } from "helpers/formatters";
+import { filterHasAttributes } from "helpers/others";
import { getVideoThumbnailURL } from "helpers/videos";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { GetStaticPropsContext } from "next";
@@ -95,27 +96,25 @@ export default function Videos(props: Props): JSX.Element {
desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] mobile:grid-cols-2
thin:grid-cols-1"
>
- {paginatedVideos[page].map((video) => (
+ {filterHasAttributes(paginatedVideos[page]).map((video) => (
- {video.attributes && (
-
- )}
+
))}
diff --git a/src/pages/archives/videos/v/[uid].tsx b/src/pages/archives/videos/v/[uid].tsx
index 813e1a7..52ea437 100644
--- a/src/pages/archives/videos/v/[uid].tsx
+++ b/src/pages/archives/videos/v/[uid].tsx
@@ -18,7 +18,7 @@ import { GetVideoQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { prettyDate, prettyShortenNumber } from "helpers/formatters";
-import { isDefined } from "helpers/others";
+import { filterHasAttributes, isDefined } from "helpers/others";
import { getVideoFile } from "helpers/videos";
import { useMediaMobile } from "hooks/useMediaQuery";
import {
@@ -213,10 +213,9 @@ export async function getStaticPaths(
const videos = await sdk.getVideosSlugs();
const paths: GetStaticPathsResult["paths"] = [];
if (videos.videos?.data)
- videos.videos.data.map((video) => {
+ filterHasAttributes(videos.videos.data).map((video) => {
context.locales?.map((local) => {
- if (video.attributes)
- paths.push({ params: { uid: video.attributes.uid }, locale: local });
+ paths.push({ params: { uid: video.attributes.uid }, locale: local });
});
});
return {
diff --git a/src/pages/contents/[slug]/index.tsx b/src/pages/contents/[slug]/index.tsx
index 00f4061..407e957 100644
--- a/src/pages/contents/[slug]/index.tsx
+++ b/src/pages/contents/[slug]/index.tsx
@@ -26,7 +26,11 @@ import {
prettySlug,
} from "helpers/formatters";
import { isUntangibleGroupItem } from "helpers/libraryItem";
-import { getStatusDescription } from "helpers/others";
+import {
+ filterHasAttributes,
+ getStatusDescription,
+ isDefinedAndNotEmpty,
+} from "helpers/others";
import { ContentWithTranslations } from "helpers/types";
import { useMediaMobile } from "hooks/useMediaQuery";
import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
@@ -82,31 +86,29 @@ export default function Content(props: Props): JSX.Element {
horizontalLine
/>
- {selectedTranslation?.text_set && (
+ {selectedTranslation?.text_set?.source_language?.data?.attributes
+ ?.code !== undefined && (
- {selectedTranslation.text_set.source_language?.data?.attributes
- ?.code === selectedTranslation.language?.data?.attributes?.code
+ {selectedTranslation.text_set.source_language.data.attributes
+ .code === selectedTranslation.language?.data?.attributes?.code
? langui.transcript_notice
: langui.translation_notice}
- {selectedTranslation.text_set.source_language?.data?.attributes
- ?.code &&
- selectedTranslation.text_set.source_language.data.attributes
- .code !==
- selectedTranslation.language?.data?.attributes?.code && (
-
-
{langui.source_language}:
-
- {prettyLanguage(
- selectedTranslation.text_set.source_language.data.attributes
- .code,
- languages
- )}
-
-
- )}
+ {selectedTranslation.text_set.source_language.data.attributes.code !==
+ selectedTranslation.language?.data?.attributes?.code && (
+
+
{langui.source_language}:
+
+ {prettyLanguage(
+ selectedTranslation.text_set.source_language.data.attributes
+ .code,
+ languages
+ )}
+
+
+ )}
{langui.status}:
@@ -127,18 +129,16 @@ export default function Content(props: Props): JSX.Element {
{langui.transcribers}:
- {selectedTranslation.text_set.transcribers.data.map(
- (recorder) => (
-
- {recorder.attributes && (
-
- )}
-
- )
- )}
+ {filterHasAttributes(
+ selectedTranslation.text_set.transcribers.data
+ ).map((recorder) => (
+
+
+
+ ))}
)}
@@ -148,18 +148,16 @@ export default function Content(props: Props): JSX.Element {
{langui.translators}:
- {selectedTranslation.text_set.translators.data.map(
- (recorder) => (
-
- {recorder.attributes && (
-
- )}
-
- )
- )}
+ {filterHasAttributes(
+ selectedTranslation.text_set.translators.data
+ ).map((recorder) => (
+
+
+
+ ))}
)}
@@ -169,23 +167,21 @@ export default function Content(props: Props): JSX.Element {
{langui.proofreaders}:
- {selectedTranslation.text_set.proofreaders.data.map(
- (recorder) => (
-
- {recorder.attributes && (
-
- )}
-
- )
- )}
+ {filterHasAttributes(
+ selectedTranslation.text_set.proofreaders.data
+ ).map((recorder) => (
+
+
+
+ ))}
)}
- {selectedTranslation.text_set.notes && (
+ {isDefinedAndNotEmpty(selectedTranslation.text_set.notes) && (
{"Notes"}:
@@ -450,13 +446,12 @@ export async function getStaticPaths(
const sdk = getReadySdk();
const contents = await sdk.getContentsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- contents.contents?.data.map((item) => {
+ filterHasAttributes(contents.contents?.data).map((item) => {
context.locales?.map((local) => {
- if (item.attributes)
- paths.push({
- params: { slug: item.attributes.slug },
- locale: local,
- });
+ paths.push({
+ params: { slug: item.attributes.slug },
+ locale: local,
+ });
});
});
return {
diff --git a/src/pages/contents/index.tsx b/src/pages/contents/index.tsx
index 27a42a6..4f3fcfe 100644
--- a/src/pages/contents/index.tsx
+++ b/src/pages/contents/index.tsx
@@ -21,6 +21,12 @@ import { WithLabel } from "components/Inputs/WithLabel";
import { Button } from "components/Inputs/Button";
import { TextInput } from "components/Inputs/TextInput";
import { useMediaHoverable } from "hooks/useMediaQuery";
+import {
+ filterHasAttributes,
+ iterateMap,
+ mapRemoveEmptyValues,
+} from "helpers/others";
+import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
interface Props extends AppStaticProps {
contents: NonNullable["data"];
@@ -128,8 +134,18 @@ export default function Contents(props: Props): JSX.Element {
);
const contentPanel = (
- {[...groups].map(
- ([name, items], index) =>
+ {/* TODO: Add to langui */}
+ {groups.size === 0 && (
+
+ )}
+ {iterateMap(
+ groups,
+ (name, items, index) =>
items.length > 0 && (
{name && (
@@ -140,7 +156,10 @@ export default function Contents(props: Props): JSX.Element {
{name}
{`${items.reduce((currentSum, item) => {
if (effectiveCombineRelatedContent) {
- if (item.attributes?.group?.data?.attributes?.combine) {
+ if (
+ item.attributes?.group?.data?.attributes?.combine ===
+ true
+ ) {
return (
currentSum +
(item.attributes.group.data.attributes.contents?.data
@@ -161,50 +180,49 @@ export default function Contents(props: Props): JSX.Element {
className="grid grid-cols-2 items-end gap-8
desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] mobile:gap-4"
>
- {items.map((item) => (
+ {filterHasAttributes(items).map((item) => (
- {item.attributes && (
- ({
- pre_title: translation?.pre_title,
- title: translation?.title,
- subtitle: translation?.subtitle,
- language:
- translation?.language?.data?.attributes?.code,
- })
- )}
- slug={item.attributes.slug}
- languages={languages}
- thumbnail={item.attributes.thumbnail?.data?.attributes}
- thumbnailAspectRatio="3/2"
- thumbnailForceAspectRatio
- stackNumber={
- effectiveCombineRelatedContent &&
- item.attributes.group?.data?.attributes?.combine
- ? item.attributes.group.data.attributes.contents
- ?.data.length
- : 0
- }
- topChips={
- item.attributes.type?.data?.attributes
- ? [
- item.attributes.type.data.attributes.titles?.[0]
- ? item.attributes.type.data.attributes
- .titles[0]?.title
- : prettySlug(
- item.attributes.type.data.attributes.slug
- ),
- ]
- : undefined
- }
- bottomChips={item.attributes.categories?.data.map(
- (category) => category.attributes?.short ?? ""
- )}
- keepInfoVisible={keepInfoVisible}
- />
- )}
+ ({
+ pre_title: translation?.pre_title,
+ title: translation?.title,
+ subtitle: translation?.subtitle,
+ language:
+ translation?.language?.data?.attributes?.code,
+ })
+ )}
+ slug={item.attributes.slug}
+ languages={languages}
+ thumbnail={item.attributes.thumbnail?.data?.attributes}
+ thumbnailAspectRatio="3/2"
+ thumbnailForceAspectRatio
+ stackNumber={
+ effectiveCombineRelatedContent &&
+ item.attributes.group?.data?.attributes?.combine ===
+ true
+ ? item.attributes.group.data.attributes.contents?.data
+ .length
+ : 0
+ }
+ topChips={
+ item.attributes.type?.data?.attributes
+ ? [
+ item.attributes.type.data.attributes.titles?.[0]
+ ? item.attributes.type.data.attributes.titles[0]
+ ?.title
+ : prettySlug(
+ item.attributes.type.data.attributes.slug
+ ),
+ ]
+ : undefined
+ }
+ bottomChips={item.attributes.categories?.data.map(
+ (category) => category.attributes?.short ?? ""
+ )}
+ keepInfoVisible={keepInfoVisible}
+ />
))}
@@ -252,71 +270,72 @@ function getGroups(
groupByType: number,
items: Props["contents"]
): GroupContentItems {
+ const groups: GroupContentItems = new Map();
+
switch (groupByType) {
case 0: {
- const group = new Map();
- group.set("Drakengard 1", []);
- group.set("Drakengard 1.3", []);
- group.set("Drakengard 2", []);
- group.set("Drakengard 3", []);
- group.set("Drakengard 4", []);
- group.set("NieR Gestalt", []);
- group.set("NieR Replicant", []);
- group.set("NieR Replicant ver.1.22474487139...", []);
- group.set("NieR:Automata", []);
- group.set("NieR Re[in]carnation", []);
- group.set("SINoALICE", []);
- group.set("Voice of Cards", []);
- group.set("Final Fantasy XIV", []);
- group.set("Thou Shalt Not Die", []);
- group.set("Bakuken", []);
- group.set("YoRHa", []);
- group.set("YoRHa Boys", []);
- group.set(langui.no_category, []);
+ const noCategory = langui.no_category ?? "No category";
+ groups.set("Drakengard 1", []);
+ groups.set("Drakengard 1.3", []);
+ groups.set("Drakengard 2", []);
+ groups.set("Drakengard 3", []);
+ groups.set("Drakengard 4", []);
+ groups.set("NieR Gestalt", []);
+ groups.set("NieR Replicant", []);
+ groups.set("NieR Replicant ver.1.22474487139...", []);
+ groups.set("NieR:Automata", []);
+ groups.set("NieR Re[in]carnation", []);
+ groups.set("SINoALICE", []);
+ groups.set("Voice of Cards", []);
+ groups.set("Final Fantasy XIV", []);
+ groups.set("Thou Shalt Not Die", []);
+ groups.set("Bakuken", []);
+ groups.set("YoRHa", []);
+ groups.set("YoRHa Boys", []);
+ groups.set(noCategory, []);
items.map((item) => {
if (item.attributes?.categories?.data.length === 0) {
- group.get(langui.no_category)?.push(item);
+ groups.get(noCategory)?.push(item);
} else {
item.attributes?.categories?.data.map((category) => {
- group.get(category.attributes?.name)?.push(item);
+ groups.get(category.attributes?.name ?? noCategory)?.push(item);
});
}
});
- return group;
+ break;
}
case 1: {
- const group = new Map();
items.map((item) => {
+ const noType = langui.no_type ?? "No type";
const type =
item.attributes?.type?.data?.attributes?.titles?.[0]?.title ??
item.attributes?.type?.data?.attributes?.slug
? prettySlug(item.attributes.type.data.attributes.slug)
: langui.no_type;
- if (!group.has(type)) group.set(type, []);
- group.get(type)?.push(item);
+ if (!groups.has(type ?? noType)) groups.set(type ?? noType, []);
+ groups.get(type ?? noType)?.push(item);
});
- return group;
+ break;
}
default: {
- const group: GroupContentItems = new Map();
- group.set("", items);
- return group;
+ groups.set("", items);
}
}
+ return mapRemoveEmptyValues(groups);
}
function filterContents(
- contents: Immutable
,
+ contents: Props["contents"],
combineRelatedContent: boolean,
searchName: string
-): Immutable {
+): Props["contents"] {
return contents.filter((content) => {
if (
combineRelatedContent &&
- content.attributes?.group?.data?.attributes?.combine &&
+ content.attributes?.group?.data?.attributes?.combine === true &&
content.attributes.group.data.attributes.contents?.data[0].id !==
content.id
) {
diff --git a/src/pages/dev/checkup/contents.tsx b/src/pages/dev/checkup/contents.tsx
index 6036af6..64ffc9f 100644
--- a/src/pages/dev/checkup/contents.tsx
+++ b/src/pages/dev/checkup/contents.tsx
@@ -9,6 +9,7 @@ import { ToolTip } from "components/ToolTip";
import { DevGetContentsQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
+import { filterDefined, filterHasAttributes } from "helpers/others";
import { GetStaticPropsContext } from "next";
@@ -116,321 +117,319 @@ function testingContent(contents: Props["contents"]): Report {
lines: [],
};
- contents.contents?.data.map((content) => {
- if (content.attributes) {
- 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).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[] = [];
- content.attributes.translations?.map((translation, titleIndex) => {
- if (translation && content.attributes) {
- 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 {
+ 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: "No Language",
+ name: "Duplicate Language",
type: "Error",
- severity: "Very High",
+ severity: "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) {
- 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,
- * });
- * }
- * }
- *}
- */
+ titleLanguages.push(translation.language.data.id);
}
-
+ } else {
report.lines.push({
- subitems: [content.attributes.slug],
- name: "No Sets",
- type: "Missing",
- severity: "Medium",
- description: "The Content has no Sets.",
+ 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) {
+ 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 Sets",
+ type: "Missing",
+ severity: "Medium",
+ description: "The Content has no Sets.",
+ recommandation: "",
+ backendUrl: backendUrl,
+ frontendUrl: frontendUrl,
+ });
+ }
+ );
}
});
return report;
diff --git a/src/pages/library/[slug]/index.tsx b/src/pages/library/[slug]/index.tsx
index d40dfbe..6289977 100644
--- a/src/pages/library/[slug]/index.tsx
+++ b/src/pages/library/[slug]/index.tsx
@@ -35,7 +35,12 @@ import {
} from "helpers/formatters";
import { getAssetURL, ImageQuality } from "helpers/img";
import { convertMmToInch } from "helpers/numbers";
-import { isDefined, sortContent } from "helpers/others";
+import {
+ filterHasAttributes,
+ isDefined,
+ isDefinedAndNotEmpty,
+ sortContent,
+} from "helpers/others";
import { useLightBox } from "hooks/useLightBox";
import { AnchorIds, useScrollTopOnChange } from "hooks/useScrollTopOnChange";
@@ -172,7 +177,9 @@ export default function LibrarySlug(props: Props): JSX.Element {
)}
{item?.title}
- {item?.subtitle && {item.subtitle}
}
+ {item && isDefinedAndNotEmpty(item.subtitle) && (
+ {item.subtitle}
+ )}
{langui.available_at}
- {item.urls
- .filter((url) => url)
- .map((url, index) => (
-
- {url?.url && (
-
- )}
-
- ))}
+ {filterHasAttributes(item.urls).map((url, index) => (
+
+
+
+ ))}
) : (
{langui.item_not_available}
@@ -225,26 +228,19 @@ export default function LibrarySlug(props: Props): JSX.Element {
className="grid w-full grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-end
gap-8"
>
- {item.gallery.data.map((galleryItem, index) => (
-
- {galleryItem.attributes && (
+ {filterHasAttributes(item.gallery.data).map(
+ (galleryItem, index) => (
+
{
- if (item.gallery?.data) {
- const images: string[] = [];
- item.gallery.data.map((image) => {
- if (image.attributes)
- images.push(
- getAssetURL(
- image.attributes.url,
- ImageQuality.Large
- )
- );
- });
- openLightBox(images, index);
- }
+ const images: string[] = filterHasAttributes(
+ item.gallery?.data
+ ).map((image) =>
+ getAssetURL(image.attributes.url, ImageQuality.Large)
+ );
+ openLightBox(images, index);
}}
>
- )}
-
- ))}
+
+ )
+ )}
)}
@@ -437,46 +433,44 @@ export default function LibrarySlug(props: Props): JSX.Element {
className="grid w-full grid-cols-[repeat(auto-fill,minmax(15rem,1fr))]
items-end gap-8 mobile:grid-cols-2 thin:grid-cols-1"
>
- {item.subitems.data.map((subitem) => (
+ {filterHasAttributes(item.subitems.data).map((subitem) => (
- {subitem.attributes && subitem.id && (
- 0 &&
- subitem.attributes.metadata[0]
- ? [prettyItemSubType(subitem.attributes.metadata[0])]
- : []
- }
- bottomChips={subitem.attributes.categories?.data.map(
- (category) => category.attributes?.short ?? ""
- )}
- metadata={{
- currencies: currencies,
- release_date: subitem.attributes.release_date,
- price: subitem.attributes.price,
- position: "Bottom",
- }}
- infoAppend={
-
- }
- />
- )}
+ 0 &&
+ subitem.attributes.metadata[0]
+ ? [prettyItemSubType(subitem.attributes.metadata[0])]
+ : []
+ }
+ bottomChips={subitem.attributes.categories?.data.map(
+ (category) => category.attributes?.short ?? ""
+ )}
+ metadata={{
+ currencies: currencies,
+ release_date: subitem.attributes.release_date,
+ price: subitem.attributes.price,
+ position: "Bottom",
+ }}
+ infoAppend={
+
+ }
+ />
))}
@@ -548,13 +542,12 @@ export async function getStaticPaths(
const sdk = getReadySdk();
const libraryItems = await sdk.getLibraryItemsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- if (libraryItems.libraryItems) {
- libraryItems.libraryItems.data.map((item) => {
- context.locales?.map((local) => {
- paths.push({ params: { slug: item.attributes?.slug }, locale: local });
- });
- });
- }
+ filterHasAttributes(libraryItems.libraryItems?.data).map((item) => {
+ context.locales?.map((local) =>
+ paths.push({ params: { slug: item.attributes?.slug }, locale: local })
+ );
+ });
+
return {
paths,
fallback: "blocking",
diff --git a/src/pages/library/[slug]/scans.tsx b/src/pages/library/[slug]/scans.tsx
index 72ad4ef..5426039 100644
--- a/src/pages/library/[slug]/scans.tsx
+++ b/src/pages/library/[slug]/scans.tsx
@@ -15,7 +15,7 @@ import { GetLibraryItemScansQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { prettyinlineTitle, prettySlug } from "helpers/formatters";
-import { isDefined, sortContent } from "helpers/others";
+import { filterHasAttributes, isDefined, sortContent } from "helpers/others";
import { useLightBox } from "hooks/useLightBox";
import {
@@ -146,14 +146,12 @@ export async function getStaticPaths(
const sdk = getReadySdk();
const libraryItems = await sdk.getLibraryItemsSlugs({});
const paths: GetStaticPathsResult["paths"] = [];
- if (libraryItems.libraryItems) {
- libraryItems.libraryItems.data.map((item) => {
- context.locales?.map((local) => {
- if (item.attributes)
- paths.push({ params: { slug: item.attributes.slug }, locale: local });
- });
- });
- }
+ filterHasAttributes(libraryItems.libraryItems?.data).map((item) => {
+ context.locales?.map((local) =>
+ paths.push({ params: { slug: item.attributes.slug }, locale: local })
+ );
+ });
+
return {
paths,
fallback: "blocking",
diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx
index 6878aea..71e4326 100644
--- a/src/pages/library/index.tsx
+++ b/src/pages/library/index.tsx
@@ -31,7 +31,13 @@ import {
import { PreviewCard } from "components/PreviewCard";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { ButtonGroup } from "components/Inputs/ButtonGroup";
-import { isDefinedAndNotEmpty, isUndefined } from "helpers/others";
+import {
+ filterHasAttributes,
+ isDefinedAndNotEmpty,
+ isUndefined,
+ iterateMap,
+} from "helpers/others";
+import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
interface Props extends AppStaticProps {
items: NonNullable
["data"];
@@ -234,73 +240,74 @@ export default function Library(props: Props): JSX.Element {
);
const contentPanel = (
- {[...groups].map(([name, items]) => (
+ {/* TODO: Add to langui */}
+ {groups.size === 0 && (
+
+ )}
+ {iterateMap(groups, (name, items) => (
- {items.length > 0 && (
- <>
- {name && (
-
- {name}
- {`${items.length} ${
- items.length <= 1
- ? langui.result?.toLowerCase() ?? "result"
- : langui.results?.toLowerCase() ?? "results"
- }`}
-
- )}
-
+
+ )}
+
- {items.map((item) => (
-
- {isDefinedAndNotEmpty(item.id) && item.attributes && (
- 0 &&
- item.attributes.metadata[0]
- ? [prettyItemSubType(item.attributes.metadata[0])]
- : []
- }
- bottomChips={item.attributes.categories?.data.map(
- (category) => category.attributes?.short ?? ""
- )}
- metadata={{
- currencies: currencies,
- release_date: item.attributes.release_date,
- price: item.attributes.price,
- position: "Bottom",
- }}
- infoAppend={
-
- }
- />
- )}
-
- ))}
-
- >
- )}
+ >
+ {filterHasAttributes(items).map((item) => (
+
+ 0 &&
+ item.attributes.metadata[0]
+ ? [prettyItemSubType(item.attributes.metadata[0])]
+ : []
+ }
+ bottomChips={item.attributes.categories?.data.map(
+ (category) => category.attributes?.short ?? ""
+ )}
+ metadata={{
+ currencies: currencies,
+ release_date: item.attributes.release_date,
+ price: item.attributes.price,
+ position: "Bottom",
+ }}
+ infoAppend={
+
+ }
+ />
+
+ ))}
+
))}
diff --git a/src/pages/news/[slug].tsx b/src/pages/news/[slug].tsx
index 5d5f3cf..8b0f21b 100644
--- a/src/pages/news/[slug].tsx
+++ b/src/pages/news/[slug].tsx
@@ -5,7 +5,7 @@ import {
PostStaticProps,
} from "graphql/getPostStaticProps";
import { getReadySdk } from "graphql/sdk";
-import { isDefined } from "helpers/others";
+import { filterHasAttributes, isDefined } from "helpers/others";
import {
GetStaticPathsContext,
@@ -48,13 +48,12 @@ export async function getStaticPaths(
const sdk = getReadySdk();
const posts = await sdk.getPostsSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- if (posts.posts)
- posts.posts.data.map((item) => {
- context.locales?.map((local) => {
- if (item.attributes)
- paths.push({ params: { slug: item.attributes.slug }, locale: local });
- });
- });
+
+ filterHasAttributes(posts.posts?.data).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 5f5d741..d745795 100644
--- a/src/pages/news/index.tsx
+++ b/src/pages/news/index.tsx
@@ -19,6 +19,7 @@ import { WithLabel } from "components/Inputs/WithLabel";
import { TextInput } from "components/Inputs/TextInput";
import { Button } from "components/Inputs/Button";
import { useMediaHoverable } from "hooks/useMediaQuery";
+import { filterHasAttributes } from "helpers/others";
interface Props extends AppStaticProps {
posts: NonNullable["data"];
@@ -87,29 +88,27 @@ export default function News(props: Props): JSX.Element {
className="grid grid-cols-1 items-end gap-8
desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))]"
>
- {filteredItems.map((post) => (
+ {filterHasAttributes(filteredItems).map((post) => (
- {post.attributes && (
- category.attributes?.short ?? ""
- )}
- keepInfoVisible={keepInfoVisible}
- metadata={{
- release_date: post.attributes.date,
- position: "Top",
- }}
- />
- )}
+ category.attributes?.short ?? ""
+ )}
+ keepInfoVisible={keepInfoVisible}
+ metadata={{
+ release_date: post.attributes.date,
+ position: "Top",
+ }}
+ />
))}
@@ -145,19 +144,17 @@ export async function getStaticProps(
}
function sortPosts(posts: Props["posts"]): Props["posts"] {
- const sortedPosts = [...posts];
- sortedPosts
+ return posts
.sort((a, b) => {
const dateA = a.attributes?.date ? prettyDate(a.attributes.date) : "9999";
const dateB = b.attributes?.date ? prettyDate(b.attributes.date) : "9999";
return dateA.localeCompare(dateB);
})
.reverse();
- return sortedPosts;
}
function filterItems(posts: Props["posts"], searchName: string) {
- return [...posts].filter((post) => {
+ return posts.filter((post) => {
if (searchName.length > 1) {
if (
post.attributes?.translations?.[0]?.title
diff --git a/src/pages/wiki/[slug]/index.tsx b/src/pages/wiki/[slug]/index.tsx
index 32aec1b..7d70046 100644
--- a/src/pages/wiki/[slug]/index.tsx
+++ b/src/pages/wiki/[slug]/index.tsx
@@ -14,7 +14,11 @@ import { SubPanel } from "components/Panels/SubPanel";
import DefinitionCard from "components/Wiki/DefinitionCard";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
-import { isDefined, isDefinedAndNotEmpty } from "helpers/others";
+import {
+ filterHasAttributes,
+ isDefined,
+ isDefinedAndNotEmpty,
+} from "helpers/others";
import { WikiPageWithTranslations } from "helpers/types";
import { useSmartLanguage } from "hooks/useSmartLanguage";
import {
@@ -89,20 +93,24 @@ export default function WikiPage(props: Props): JSX.Element {
)}
- {page.definitions?.map((definition, index) => (
-
({
- language: translation?.language?.data?.attributes?.code,
- definition: translation?.definition,
- status: translation?.status,
- }))}
- index={index + 1}
- languages={languages}
- langui={langui}
- />
- ))}
+ {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}
+ />
+ )
+ )}
)}
@@ -147,14 +155,13 @@ export async function getStaticPaths(
const sdk = getReadySdk();
const contents = await sdk.getWikiPagesSlugs();
const paths: GetStaticPathsResult["paths"] = [];
- contents.wikiPages?.data.map((wikiPage) => {
- context.locales?.map((local) => {
- if (wikiPage.attributes)
- paths.push({
- params: { slug: wikiPage.attributes.slug },
- locale: local,
- });
- });
+ filterHasAttributes(contents.wikiPages?.data).map((wikiPage) => {
+ context.locales?.map((local) =>
+ paths.push({
+ params: { slug: wikiPage.attributes.slug },
+ locale: local,
+ })
+ );
});
return {
paths,
diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx
index 829d714..66f8d16 100644
--- a/src/pages/wiki/chronology.tsx
+++ b/src/pages/wiki/chronology.tsx
@@ -12,7 +12,7 @@ import { GetChronologyItemsQuery, GetErasQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { prettySlug } from "helpers/formatters";
-import { isDefined } from "helpers/others";
+import { filterHasAttributes, isDefined } from "helpers/others";
import { GetStaticPropsContext } from "next";
import { Fragment } from "react";
@@ -70,22 +70,20 @@ export default function Chronology(props: Props): JSX.Element {
horizontalLine
/>
- {chronologyEras.map((era) => (
+ {filterHasAttributes(chronologyEras).map((era) => (
- {era.attributes && (
- 0 &&
- era.attributes.title[0]
- ? era.attributes.title[0].title
- : prettySlug(era.attributes.slug)
- }
- subtitle={`${era.attributes.starting_year} → ${era.attributes.ending_year}`}
- border
- />
- )}
+ 0 &&
+ era.attributes.title[0]
+ ? era.attributes.title[0].title
+ : prettySlug(era.attributes.slug)
+ }
+ subtitle={`${era.attributes.starting_year} → ${era.attributes.ending_year}`}
+ border
+ />
))}
diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx
index 1826b9a..6b2ff7a 100644
--- a/src/pages/wiki/index.tsx
+++ b/src/pages/wiki/index.tsx
@@ -20,6 +20,8 @@ import { Switch } from "components/Inputs/Switch";
import { TextInput } from "components/Inputs/TextInput";
import { WithLabel } from "components/Inputs/WithLabel";
import { useMediaHoverable } from "hooks/useMediaQuery";
+import { filterHasAttributes } from "helpers/others";
+import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
interface Props extends AppStaticProps {
pages: NonNullable
["data"];
@@ -93,30 +95,37 @@ export default function Wiki(props: Props): JSX.Element {
className="grid grid-cols-2 items-end gap-8
desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))] mobile:gap-4"
>
- {filteredPages.map((page) => (
+ {/* TODO: Add to langui */}
+ {filteredPages.length === 0 && (
+
+ )}
+ {filterHasAttributes(filteredPages).map((page) => (
- {page.attributes && (
- ({
- title: translation?.title,
- 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,
+ 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 ?? ""
+ )}
+ />
))}
@@ -150,17 +159,15 @@ export async function getStaticProps(
}
function sortPages(pages: Props["pages"]): Props["pages"] {
- const sortedPages = [...pages];
- sortedPages.sort((a, b) => {
+ return pages.sort((a, b) => {
const slugA = a.attributes?.slug ?? "";
const slugB = b.attributes?.slug ?? "";
return slugA.localeCompare(slugB);
});
- return sortedPages;
}
function filterPages(posts: Props["pages"], searchName: string) {
- return [...posts].filter((post) => {
+ return posts.filter((post) => {
if (searchName.length > 1) {
if (
post.attributes?.translations?.[0]?.title
diff --git a/src/tailwind.css b/src/tailwind.css
index 0239426..3cda969 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -31,7 +31,7 @@ mark {
/* SCROLLBARS STYLING */
* {
- @apply [scrollbar-color:theme(colors.dark)_transparent] [scrollbar-width:thin];
+ @apply [scrollbar-color:theme(colors.dark/1)_transparent] [scrollbar-width:thin];
}
*::-webkit-scrollbar {