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 { DevGetContentsQuery } from "graphql/generated"; import { getReadySdk } from "graphql/sdk"; import { filterDefined, filterHasAttributes } from "helpers/others"; import { Report, Severity } from "helpers/types/Report"; import { getOpenGraph } from "helpers/openGraph"; import { getLangui } from "graphql/fetchLocalData"; /* * ╭────────╮ * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── */ interface Props extends AppLayoutRequired { contents: DevGetContentsQuery; } const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => { const testReport = useMemo(() => testingContent(contents), [contents]); const contentPanel = useMemo( () => ( {{testReport.title}} Ref Name Type Severity Description {testReport.lines .sort((a, b) => a.name.localeCompare(b.name)) .sort((a, b) => b.severity - a.severity) .map((line, index) => ( {line.subitems.join(" -> ")} {line.name} {line.description} ))} ), [testReport.lines, testReport.title] ); return ; }; export default CheckupContents; /* * ╭──────────────────────╮ * ───────────────────────────────────╯ NEXT DATA FETCHING ╰────────────────────────────────────── */ export const getStaticProps: GetStaticProps = async (context) => { const sdk = getReadySdk(); const langui = getLangui(context.locale); const contents = await sdk.devGetContents(); const props: Props = { contents: contents, openGraph: getOpenGraph(langui, "Checkup Contents"), }; return { props: props, }; }; /* * ╭───────────────────╮ * ─────────────────────────────────────╯ PRIVATE METHODS ╰─────────────────────────────────────── */ const testingContent = (contents: Props["contents"]): Report => { const report: Report = { title: "Contents", lines: [], }; 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: Severity.High, 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 Type", type: "Missing", severity: Severity.High, 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: 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: 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: Severity.High, description: "The Content has no Titles.", recommandation: "", backendUrl: backendUrl, frontendUrl: frontendUrl, }); } else { const titleLanguages: string[] = []; if ( content.attributes.translations && content.attributes.translations.length > 0 ) { 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: 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: "No Language", type: "Error", severity: Severity.VeryHigh, 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: Severity.Medium, description: "", recommandation: "", backendUrl: backendUrl, frontendUrl: frontendUrl, }); } if (!translation.text_set) { report.lines.push({ subitems: [ content.attributes.slug, translation.language?.data?.attributes?.code ?? "", ], name: "No Text Set", type: "Missing", severity: Severity.High, description: "The Content has no Text Set.", recommandation: "", backendUrl: backendUrl, frontendUrl: frontendUrl, }); } } ); } else { report.lines.push({ subitems: [content.attributes.slug], name: "No Translations", type: "Missing", severity: Severity.High, description: "The Content has no Translations.", recommandation: "", backendUrl: backendUrl, frontendUrl: frontendUrl, }); } } } ); return report; };
Ref
Name
Type
Severity
Description
{line.subitems.join(" -> ")}
{line.name}
{line.description}