2022-08-08 22:12:18 +02:00

764 lines
27 KiB
TypeScript

import { GetStaticProps } from "next";
import { useMemo } from "react";
import { AppLayout, AppLayoutRequired } from "components/AppLayout";
import { Chip } from "components/Chip";
import { Button } from "components/Inputs/Button";
import {
ContentPanel,
ContentPanelWidthSizes,
} from "components/Panels/ContentPanel";
import { ToolTip } from "components/ToolTip";
import {
DevGetLibraryItemsQuery,
Enum_Componentcollectionscomponentlibraryimages_Status,
} from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { Report, Severity } from "helpers/types/Report";
import { getOpenGraph } from "helpers/openGraph";
/*
* ╭────────╮
* ──────────────────────────────────────────╯ PAGE ╰─────────────────────────────────────────────
*/
interface Props extends AppStaticProps, AppLayoutRequired {
libraryItems: DevGetLibraryItemsQuery;
}
const CheckupLibraryItems = ({
libraryItems,
...otherProps
}: Props): JSX.Element => {
const testReport = testingLibraryItem(libraryItems);
const contentPanel = useMemo(
() => (
<ContentPanel width={ContentPanelWidthSizes.Full}>
{<h2 className="text-2xl">{testReport.title}</h2>}
<div className="my-4 grid grid-cols-[2em,3em,2fr,1fr,0.5fr,0.5fr,2fr] items-center gap-2">
<p></p>
<p></p>
<p className="font-headers">Ref</p>
<p className="font-headers">Name</p>
<p className="font-headers">Type</p>
<p className="font-headers">Severity</p>
<p className="font-headers">Description</p>
</div>
{testReport.lines
.sort((a, b) => a.name.localeCompare(b.name))
.sort((a, b) => b.severity - a.severity)
.map((line, index) => (
<div
key={index}
className="mb-2 grid
grid-cols-[2em,3em,2fr,1fr,0.5fr,0.5fr,2fr] items-center justify-items-start gap-2"
>
<Button
href={line.frontendUrl}
className="w-4 text-xs"
text="F"
alwaysNewTab
/>
<Button
href={line.backendUrl}
className="w-4 text-xs"
text="B"
alwaysNewTab
/>
<p>{line.subitems.join(" -> ")}</p>
<p>{line.name}</p>
<Chip text={line.type} />
<Chip
className={
line.severity === Severity.VeryHigh
? "bg-[#f00] font-bold !opacity-100"
: line.severity === Severity.High
? "bg-[#ff6600] font-bold !opacity-100"
: line.severity === Severity.Medium
? "bg-[#fff344] !opacity-100"
: ""
}
text={Severity[line.severity]}
/>
<ToolTip content={line.recommandation} placement="left">
<p>{line.description}</p>
</ToolTip>
</div>
))}
</ContentPanel>
),
[testReport.lines, testReport.title]
);
return <AppLayout contentPanel={contentPanel} {...otherProps} />;
};
export default CheckupLibraryItems;
/*
* ╭──────────────────────╮
* ───────────────────────────────────╯ NEXT DATA FETCHING ╰──────────────────────────────────────
*/
export const getStaticProps: GetStaticProps = async (context) => {
const sdk = getReadySdk();
const libraryItems = await sdk.devGetLibraryItems();
const appStaticProps = await getAppStaticProps(context);
const props: Props = {
...appStaticProps,
libraryItems: libraryItems,
openGraph: getOpenGraph(appStaticProps.langui, "Checkup Library Items"),
};
return {
props: props,
};
};
/*
* ╭───────────────────╮
* ─────────────────────────────────────╯ PRIVATE METHODS ╰───────────────────────────────────────
*/
const testingLibraryItem = (libraryItems: Props["libraryItems"]): Report => {
const report: Report = {
title: "Contents",
lines: [],
};
libraryItems.libraryItems?.data.map((item) => {
if (item.attributes) {
const backendUrl = `${process.env.NEXT_PUBLIC_URL_CMS}/admin/content-manager/collectionType/api::library-item.library-item/${item.id}`;
const frontendUrl = `${process.env.NEXT_PUBLIC_URL_SELF}/library/${item.attributes.slug}`;
if (item.attributes.categories?.data.length === 0) {
report.lines.push({
subitems: [item.attributes.slug],
name: "No Category",
type: "Missing",
severity: Severity.High,
description: "The Item has no Category.",
recommandation: "Select a Category in relation with the Item",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (
!item.attributes.root_item &&
item.attributes.subitem_of?.data.length === 0
) {
report.lines.push({
subitems: [item.attributes.slug],
name: "Disconnected Item",
type: "Error",
severity: Severity.VeryHigh,
description:
"The Item is neither a Root Item, nor is it a subitem of another item.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (item.attributes.contents?.data.length === 0) {
report.lines.push({
subitems: [item.attributes.slug],
name: "No Contents",
type: "Missing",
severity: Severity.Low,
description: "The Item has no Contents.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!item.attributes.thumbnail?.data?.id) {
report.lines.push({
subitems: [item.attributes.slug],
name: "No Thumbnail",
type: "Missing",
severity: Severity.High,
description: "The Item has no Thumbnail.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (item.attributes.images?.length === 0) {
report.lines.push({
subitems: [item.attributes.slug],
name: "No Images",
type: "Missing",
severity: Severity.Low,
description: "The Item has no Images.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
} else {
item.attributes.images?.map((image, imageIndex) => {
const imagesLanguages: string[] = [];
if (image && item.attributes) {
if (image.language?.data?.id) {
if (image.language.data.id in imagesLanguages) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "Duplicate Language",
type: "Error",
severity: Severity.High,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
} else {
imagesLanguages.push(image.language.data.id);
}
} else {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Language",
type: "Error",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.source_language?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Source Language",
type: "Error",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (
image.status !==
Enum_Componentcollectionscomponentlibraryimages_Status.Done
) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "Not Done Status",
type: "Improvement",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (image.source_language?.data?.id === image.language?.data?.id) {
if (image.scanners?.data.length === 0) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Scanners",
type: "Missing",
severity: Severity.High,
description:
"The Item is a Scan but doesn't credit any Scanners.",
recommandation: "Add the appropriate Scanners.",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (image.cleaners?.data.length === 0) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Cleaners",
type: "Missing",
severity: Severity.High,
description:
"The Item is a Scan but doesn't credit any Cleaners.",
recommandation: "Add the appropriate Cleaners.",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (
image.typesetters?.data &&
image.typesetters.data.length > 0
) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "Credited Typesetters",
type: "Error",
severity: Severity.High,
description:
"The Item is a Scan but credits one or more Typesetters.",
recommandation:
"If appropriate, create a Scanlation Images Set Set with the Typesetters credited there.",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
} else {
if (image.typesetters?.data.length === 0) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Typesetters",
type: "Missing",
severity: Severity.High,
description:
"The Item is a Scanlation but doesn't credit any Typesetters.",
recommandation: "Add the appropriate Typesetters.",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (image.scanners?.data && image.scanners.data.length > 0) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "Credited Scanners",
type: "Error",
severity: Severity.High,
description:
"The Item is a Scanlation but credits one or more Scanners.",
recommandation:
"If appropriate, create a Scanners Images Set Set with the Scanners credited there.",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
}
if (image.cover) {
if (!image.cover.front?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Cover",
],
name: "No Front",
type: "Missing",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.cover.spine?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Cover",
],
name: "No spine",
type: "Missing",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.cover.back?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Cover",
],
name: "No Back",
type: "Missing",
severity: Severity.High,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.cover.full?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Cover",
],
name: "No Full",
type: "Missing",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
} else {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Cover",
type: "Missing",
severity: Severity.Medium,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (image.dust_jacket) {
if (!image.dust_jacket.front?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Dust Jacket",
],
name: "No Front",
type: "Missing",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.dust_jacket.spine?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Dust Jacket",
],
name: "No spine",
type: "Missing",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.dust_jacket.back?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Dust Jacket",
],
name: "No Back",
type: "Missing",
severity: Severity.High,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.dust_jacket.full?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Dust Jacket",
],
name: "No Full",
type: "Missing",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.dust_jacket.flap_front?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Dust Jacket",
],
name: "No Flap Front",
type: "Missing",
severity: Severity.Medium,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.dust_jacket.flap_back?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Dust Jacket",
],
name: "No Flap Back",
type: "Missing",
severity: Severity.Medium,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
} else {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Dust Jacket",
type: "Missing",
severity: Severity.VeryLow,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (image.obi_belt) {
if (!image.obi_belt.front?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Obi Belt",
],
name: "No Front",
type: "Missing",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.obi_belt.spine?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Obi Belt",
],
name: "No spine",
type: "Missing",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.obi_belt.back?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Obi Belt",
],
name: "No Back",
type: "Missing",
severity: Severity.High,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.obi_belt.full?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Obi Belt",
],
name: "No Full",
type: "Missing",
severity: Severity.Low,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.obi_belt.flap_front?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Obi Belt",
],
name: "No Flap Front",
type: "Missing",
severity: Severity.Medium,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (!image.obi_belt.flap_back?.data?.id) {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
"Obi Belt",
],
name: "No Flap Back",
type: "Missing",
severity: Severity.Medium,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
} else {
report.lines.push({
subitems: [
item.attributes.slug,
`Images ${imageIndex.toString()}`,
],
name: "No Obi Belt",
type: "Missing",
severity: Severity.VeryLow,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
}
});
}
if (
item.attributes.descriptions &&
item.attributes.descriptions.length > 0
) {
const descriptionLanguages: string[] = [];
item.attributes.descriptions.map((description, descriptionIndex) => {
if (description && item.attributes) {
if (description.description.length < 10) {
report.lines.push({
subitems: [
item.attributes.slug,
`Description ${descriptionIndex}`,
],
name: "No Text",
type: "Missing",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (description.language?.data?.id) {
if (description.language.data.id in descriptionLanguages) {
report.lines.push({
subitems: [
item.attributes.slug,
`Description ${descriptionIndex}`,
],
name: "Duplicate Language",
type: "Error",
severity: Severity.High,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
} else {
descriptionLanguages.push(description.language.data.id);
}
} else {
report.lines.push({
subitems: [
item.attributes.slug,
`Description ${descriptionIndex}`,
],
name: "No Language",
type: "Error",
severity: Severity.VeryHigh,
description: "",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
}
});
} else {
report.lines.push({
subitems: [item.attributes.slug],
name: "No Description",
type: "Missing",
severity: Severity.Medium,
description: "The Item has no Description.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
if (item.attributes.urls?.length === 0) {
report.lines.push({
subitems: [item.attributes.slug],
name: "No URLs",
type: "Missing",
severity: Severity.VeryLow,
description: "The Item has no URLs.",
recommandation: "",
backendUrl: backendUrl,
frontendUrl: frontendUrl,
});
}
}
});
return report;
};