Improved the filterHasAttributes + Chip
This commit is contained in:
parent
ae25df8d72
commit
de3f385458
|
@ -188,14 +188,13 @@ export const AppLayout = ({
|
||||||
return memo;
|
return memo;
|
||||||
}, [router.locale, router.locales]);
|
}, [router.locale, router.locales]);
|
||||||
|
|
||||||
const currencyOptions = useMemo(() => {
|
const currencyOptions = useMemo(
|
||||||
const memo: string[] = [];
|
() =>
|
||||||
filterHasAttributes(currencies).map((currentCurrency) => {
|
filterHasAttributes(currencies, ["attributes"] as const).map(
|
||||||
if (isDefinedAndNotEmpty(currentCurrency.attributes.code))
|
(currentCurrency) => currentCurrency.attributes.code
|
||||||
memo.push(currentCurrency.attributes.code);
|
),
|
||||||
});
|
[currencies]
|
||||||
return memo;
|
);
|
||||||
}, [currencies]);
|
|
||||||
|
|
||||||
const [currencySelect, setCurrencySelect] = useState<number>(-1);
|
const [currencySelect, setCurrencySelect] = useState<number>(-1);
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,12 @@ import { cJoin } from "helpers/className";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
children: React.ReactNode;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
export const Chip = ({ className, children }: Props): JSX.Element => (
|
export const Chip = ({ className, text }: Props): JSX.Element => (
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
`grid place-content-center place-items-center whitespace-nowrap rounded-full
|
`grid place-content-center place-items-center whitespace-nowrap rounded-full
|
||||||
|
@ -21,6 +21,6 @@ export const Chip = ({ className, children }: Props): JSX.Element => (
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{children}
|
{text}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -103,7 +103,7 @@ export const ScanSet = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const pages = useMemo(
|
const pages = useMemo(
|
||||||
() => selectedScan && filterHasAttributes(selectedScan.pages?.data),
|
() => filterHasAttributes(selectedScan?.pages?.data, ["attributes"]),
|
||||||
[selectedScan]
|
[selectedScan]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -119,12 +119,15 @@ export const ScanSet = ({
|
||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<Chip>
|
{/* TODO: Add Scan and Scanlation to langui */}
|
||||||
{selectedScan.language?.data?.attributes?.code ===
|
<Chip
|
||||||
|
text={
|
||||||
|
selectedScan.language?.data?.attributes?.code ===
|
||||||
selectedScan.source_language?.data?.attributes?.code
|
selectedScan.source_language?.data?.attributes?.code
|
||||||
? "Scan"
|
? "Scan"
|
||||||
: "Scanlation"}
|
: "Scanlation"
|
||||||
</Chip>
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row flex-wrap place-items-center gap-4 pb-6">
|
<div className="flex flex-row flex-wrap place-items-center gap-4 pb-6">
|
||||||
|
@ -144,7 +147,7 @@ export const ScanSet = ({
|
||||||
content={getStatusDescription(selectedScan.status, langui)}
|
content={getStatusDescription(selectedScan.status, langui)}
|
||||||
maxWidth={"20rem"}
|
maxWidth={"20rem"}
|
||||||
>
|
>
|
||||||
<Chip>{selectedScan.status}</Chip>
|
<Chip text={selectedScan.status} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -153,16 +156,17 @@ export const ScanSet = ({
|
||||||
{/* TODO: Add Scanner to langui */}
|
{/* TODO: Add Scanner to langui */}
|
||||||
<p className="font-headers font-bold">{"Scanners"}:</p>
|
<p className="font-headers font-bold">{"Scanners"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(selectedScan.scanners.data).map(
|
{filterHasAttributes(selectedScan.scanners.data, [
|
||||||
(scanner) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((scanner) => (
|
||||||
<Fragment key={scanner.id}>
|
<Fragment key={scanner.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
recorder={scanner.attributes}
|
recorder={scanner.attributes}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -172,16 +176,17 @@ export const ScanSet = ({
|
||||||
{/* TODO: Add Cleaners to langui */}
|
{/* TODO: Add Cleaners to langui */}
|
||||||
<p className="font-headers font-bold">{"Cleaners"}:</p>
|
<p className="font-headers font-bold">{"Cleaners"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(selectedScan.cleaners.data).map(
|
{filterHasAttributes(selectedScan.cleaners.data, [
|
||||||
(cleaner) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((cleaner) => (
|
||||||
<Fragment key={cleaner.id}>
|
<Fragment key={cleaner.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
recorder={cleaner.attributes}
|
recorder={cleaner.attributes}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -189,27 +194,28 @@ export const ScanSet = ({
|
||||||
{selectedScan.typesetters &&
|
{selectedScan.typesetters &&
|
||||||
selectedScan.typesetters.data.length > 0 && (
|
selectedScan.typesetters.data.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
{/* TODO: Add Cleaners to Typesetters */}
|
{/* TODO: Add typesetter to langui */}
|
||||||
<p className="font-headers font-bold">{"Typesetters"}:</p>
|
<p className="font-headers font-bold">{"Typesetters"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(selectedScan.typesetters.data).map(
|
{filterHasAttributes(selectedScan.typesetters.data, [
|
||||||
(typesetter) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((typesetter) => (
|
||||||
<Fragment key={typesetter.id}>
|
<Fragment key={typesetter.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
recorder={typesetter.attributes}
|
recorder={typesetter.attributes}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isDefinedAndNotEmpty(selectedScan.notes) && (
|
{isDefinedAndNotEmpty(selectedScan.notes) && (
|
||||||
<ToolTip content={selectedScan.notes}>
|
<ToolTip content={selectedScan.notes}>
|
||||||
{/* TODO: Add Notes to Typesetters */}
|
{/* TODO: Add Notes to langui */}
|
||||||
<Chip>{"Notes"}</Chip>
|
<Chip text={"Notes"} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -224,13 +230,9 @@ export const ScanSet = ({
|
||||||
className="cursor-pointer transition-transform
|
className="cursor-pointer transition-transform
|
||||||
drop-shadow-shade-lg hover:scale-[1.02]"
|
drop-shadow-shade-lg hover:scale-[1.02]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const images: string[] = [];
|
const images = pages.map((image) =>
|
||||||
pages.map((image) => {
|
|
||||||
if (isDefinedAndNotEmpty(image.attributes.url))
|
|
||||||
images.push(
|
|
||||||
getAssetURL(image.attributes.url, ImageQuality.Large)
|
getAssetURL(image.attributes.url, ImageQuality.Large)
|
||||||
);
|
);
|
||||||
});
|
|
||||||
openLightBox(images, index);
|
openLightBox(images, index);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -80,12 +80,15 @@ export const ScanSetCover = ({
|
||||||
{"Cover"}
|
{"Cover"}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<Chip>
|
{/* TODO: Add Scan and Scanlation to langui */}
|
||||||
{selectedScan.language?.data?.attributes?.code ===
|
<Chip
|
||||||
|
text={
|
||||||
|
selectedScan.language?.data?.attributes?.code ===
|
||||||
selectedScan.source_language?.data?.attributes?.code
|
selectedScan.source_language?.data?.attributes?.code
|
||||||
? "Scan"
|
? "Scan"
|
||||||
: "Scanlation"}
|
: "Scanlation"
|
||||||
</Chip>
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row flex-wrap place-items-center gap-4 pb-6">
|
<div className="flex flex-row flex-wrap place-items-center gap-4 pb-6">
|
||||||
|
@ -97,7 +100,7 @@ export const ScanSetCover = ({
|
||||||
content={getStatusDescription(selectedScan.status, langui)}
|
content={getStatusDescription(selectedScan.status, langui)}
|
||||||
maxWidth={"20rem"}
|
maxWidth={"20rem"}
|
||||||
>
|
>
|
||||||
<Chip>{selectedScan.status}</Chip>
|
<Chip text={selectedScan.status} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -106,16 +109,17 @@ export const ScanSetCover = ({
|
||||||
{/* TODO: Add Scanner to langui */}
|
{/* TODO: Add Scanner to langui */}
|
||||||
<p className="font-headers font-bold">{"Scanners"}:</p>
|
<p className="font-headers font-bold">{"Scanners"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(selectedScan.scanners.data).map(
|
{filterHasAttributes(selectedScan.scanners.data, [
|
||||||
(scanner) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((scanner) => (
|
||||||
<Fragment key={scanner.id}>
|
<Fragment key={scanner.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
recorder={scanner.attributes}
|
recorder={scanner.attributes}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -125,16 +129,17 @@ export const ScanSetCover = ({
|
||||||
{/* TODO: Add Cleaners to langui */}
|
{/* TODO: Add Cleaners to langui */}
|
||||||
<p className="font-headers font-bold">{"Cleaners"}:</p>
|
<p className="font-headers font-bold">{"Cleaners"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(selectedScan.cleaners.data).map(
|
{filterHasAttributes(selectedScan.cleaners.data, [
|
||||||
(cleaner) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((cleaner) => (
|
||||||
<Fragment key={cleaner.id}>
|
<Fragment key={cleaner.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
recorder={cleaner.attributes}
|
recorder={cleaner.attributes}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -145,16 +150,17 @@ export const ScanSetCover = ({
|
||||||
{/* TODO: Add Cleaners to Typesetters */}
|
{/* TODO: Add Cleaners to Typesetters */}
|
||||||
<p className="font-headers font-bold">{"Typesetters"}:</p>
|
<p className="font-headers font-bold">{"Typesetters"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(selectedScan.typesetters.data).map(
|
{filterHasAttributes(selectedScan.typesetters.data, [
|
||||||
(typesetter) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((typesetter) => (
|
||||||
<Fragment key={typesetter.id}>
|
<Fragment key={typesetter.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
recorder={typesetter.attributes}
|
recorder={typesetter.attributes}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -171,11 +177,10 @@ export const ScanSetCover = ({
|
||||||
className="cursor-pointer transition-transform
|
className="cursor-pointer transition-transform
|
||||||
drop-shadow-shade-lg hover:scale-[1.02]"
|
drop-shadow-shade-lg hover:scale-[1.02]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const imgs: string[] = [];
|
const imgs = coverImages.map((img) =>
|
||||||
coverImages.map((img) => {
|
getAssetURL(img.url, ImageQuality.Large)
|
||||||
if (img.url)
|
);
|
||||||
imgs.push(getAssetURL(img.url, ImageQuality.Large));
|
|
||||||
});
|
|
||||||
openLightBox(imgs, index);
|
openLightBox(imgs, index);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -104,7 +104,7 @@ export const PostPage = ({
|
||||||
)}
|
)}
|
||||||
maxWidth={"20rem"}
|
maxWidth={"20rem"}
|
||||||
>
|
>
|
||||||
<Chip>{selectedTranslation.status}</Chip>
|
<Chip text={selectedTranslation.status} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -113,7 +113,10 @@ export const PostPage = ({
|
||||||
<div>
|
<div>
|
||||||
<p className="font-headers font-bold">{"Authors"}:</p>
|
<p className="font-headers font-bold">{"Authors"}:</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(post.authors.data).map((author) => (
|
{filterHasAttributes(post.authors.data, [
|
||||||
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((author) => (
|
||||||
<Fragment key={author.id}>
|
<Fragment key={author.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
|
|
@ -262,7 +262,7 @@ export const PreviewCard = ({
|
||||||
{topChips && topChips.length > 0 && (
|
{topChips && topChips.length > 0 && (
|
||||||
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
||||||
{topChips.map((text, index) => (
|
{topChips.map((text, index) => (
|
||||||
<Chip key={index}>{text}</Chip>
|
<Chip key={index} text={text} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -281,9 +281,7 @@ export const PreviewCard = ({
|
||||||
{bottomChips && bottomChips.length > 0 && (
|
{bottomChips && bottomChips.length > 0 && (
|
||||||
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
||||||
{bottomChips.map((text, index) => (
|
{bottomChips.map((text, index) => (
|
||||||
<Chip key={index} className="text-sm">
|
<Chip key={index} className="text-sm" text={text} />
|
||||||
{text}
|
|
||||||
</Chip>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -52,7 +52,7 @@ const PreviewLine = ({
|
||||||
{topChips && topChips.length > 0 && (
|
{topChips && topChips.length > 0 && (
|
||||||
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
||||||
{topChips.map((text, index) => (
|
{topChips.map((text, index) => (
|
||||||
<Chip key={index}>{text}</Chip>
|
<Chip key={index} text={text} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -68,9 +68,7 @@ const PreviewLine = ({
|
||||||
{bottomChips && bottomChips.length > 0 && (
|
{bottomChips && bottomChips.length > 0 && (
|
||||||
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
<div className="grid grid-flow-col place-content-start gap-1 overflow-hidden">
|
||||||
{bottomChips.map((text, index) => (
|
{bottomChips.map((text, index) => (
|
||||||
<Chip key={index} className="text-sm">
|
<Chip key={index} className="text-sm" text={text} />
|
||||||
{text}
|
|
||||||
</Chip>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -38,19 +38,19 @@ export const RecorderChip = ({ recorder, langui }: Props): JSX.Element => (
|
||||||
{recorder.languages?.data && recorder.languages.data.length > 0 && (
|
{recorder.languages?.data && recorder.languages.data.length > 0 && (
|
||||||
<div className="flex flex-row flex-wrap gap-1">
|
<div className="flex flex-row flex-wrap gap-1">
|
||||||
<p>{langui.languages}:</p>
|
<p>{langui.languages}:</p>
|
||||||
{filterHasAttributes(recorder.languages.data).map(
|
{filterHasAttributes(recorder.languages.data, [
|
||||||
(language) => (
|
"attributes",
|
||||||
|
] as const).map((language) => (
|
||||||
<Fragment key={language.attributes.code}>
|
<Fragment key={language.attributes.code}>
|
||||||
<Chip>{language.attributes.code.toUpperCase()}</Chip>
|
<Chip text={language.attributes.code.toUpperCase()} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{recorder.pronouns && (
|
{recorder.pronouns && (
|
||||||
<div className="flex flex-row flex-wrap gap-1">
|
<div className="flex flex-row flex-wrap gap-1">
|
||||||
<p>{langui.pronouns}:</p>
|
<p>{langui.pronouns}:</p>
|
||||||
<Chip>{recorder.pronouns}</Chip>
|
<Chip text={recorder.pronouns} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,10 +60,13 @@ export const RecorderChip = ({ recorder, langui }: Props): JSX.Element => (
|
||||||
}
|
}
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<Chip key={recorder.anonymous_code}>
|
<Chip
|
||||||
{recorder.anonymize
|
key={recorder.anonymous_code}
|
||||||
|
text={
|
||||||
|
recorder.anonymize
|
||||||
? `Recorder#${recorder.anonymous_code}`
|
? `Recorder#${recorder.anonymous_code}`
|
||||||
: recorder.username}
|
: recorder.username
|
||||||
</Chip>
|
}
|
||||||
|
/>
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
);
|
);
|
||||||
|
|
|
@ -146,11 +146,13 @@ export const SmartList = <T,>({
|
||||||
first-of-type:pt-0"
|
first-of-type:pt-0"
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
<Chip>{`${groupItems.length} ${
|
<Chip
|
||||||
|
text={`${groupItems.length} ${
|
||||||
groupItems.length <= 1
|
groupItems.length <= 1
|
||||||
? langui.result?.toLowerCase() ?? ""
|
? langui.result?.toLowerCase() ?? ""
|
||||||
: langui.results?.toLowerCase() ?? ""
|
: langui.results?.toLowerCase() ?? ""
|
||||||
}`}</Chip>
|
}`}
|
||||||
|
/>
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -80,12 +80,12 @@ export const ThumbnailHeader = ({
|
||||||
<div className="flex flex-col place-items-center gap-2">
|
<div className="flex flex-col place-items-center gap-2">
|
||||||
<h3 className="text-xl">{langui.type}</h3>
|
<h3 className="text-xl">{langui.type}</h3>
|
||||||
<div className="flex flex-row flex-wrap">
|
<div className="flex flex-row flex-wrap">
|
||||||
<Chip>
|
<Chip
|
||||||
{type.data.attributes.titles &&
|
text={
|
||||||
type.data.attributes.titles.length > 0
|
type.data.attributes.titles?.[0]?.title ??
|
||||||
? type.data.attributes.titles[0]?.title
|
prettySlug(type.data.attributes.slug)
|
||||||
: prettySlug(type.data.attributes.slug)}
|
}
|
||||||
</Chip>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -94,8 +94,11 @@ export const ThumbnailHeader = ({
|
||||||
<div className="flex flex-col place-items-center gap-2">
|
<div className="flex flex-col place-items-center gap-2">
|
||||||
<h3 className="text-xl">{langui.categories}</h3>
|
<h3 className="text-xl">{langui.categories}</h3>
|
||||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||||
{filterHasAttributes(categories.data).map((category) => (
|
{filterHasAttributes(categories.data, [
|
||||||
<Chip key={category.id}>{category.attributes.name}</Chip>
|
"attributes",
|
||||||
|
"id",
|
||||||
|
] as const).map((category) => (
|
||||||
|
<Chip key={category.id} text={category.attributes.name} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -57,7 +57,7 @@ export const ChronologyItemComponent = ({
|
||||||
filterHasAttributes(item.attributes.events, [
|
filterHasAttributes(item.attributes.events, [
|
||||||
"id",
|
"id",
|
||||||
"translations",
|
"translations",
|
||||||
]).map((event) => (
|
] as const).map((event) => (
|
||||||
<Fragment key={event.id}>
|
<Fragment key={event.id}>
|
||||||
<div className="m-0">
|
<div className="m-0">
|
||||||
{filterDefined(event.translations).map(
|
{filterDefined(event.translations).map(
|
||||||
|
@ -77,7 +77,7 @@ export const ChronologyItemComponent = ({
|
||||||
)}
|
)}
|
||||||
maxWidth={"20rem"}
|
maxWidth={"20rem"}
|
||||||
>
|
>
|
||||||
<Chip>{translation.status}</Chip>
|
<Chip text={translation.status} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
)}
|
)}
|
||||||
{translation.title ? (
|
{translation.title ? (
|
||||||
|
|
|
@ -62,7 +62,7 @@ const DefinitionCard = ({
|
||||||
content={getStatusDescription(selectedTranslation.status, langui)}
|
content={getStatusDescription(selectedTranslation.status, langui)}
|
||||||
maxWidth={"20rem"}
|
maxWidth={"20rem"}
|
||||||
>
|
>
|
||||||
<Chip>{selectedTranslation.status}</Chip>
|
<Chip text={selectedTranslation.status} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -72,7 +72,7 @@ const DefinitionCard = ({
|
||||||
<Separator />
|
<Separator />
|
||||||
<div className="flex flex-row gap-1">
|
<div className="flex flex-row gap-1">
|
||||||
{categories.map((category, categoryIndex) => (
|
{categories.map((category, categoryIndex) => (
|
||||||
<Chip key={categoryIndex}>{category}</Chip>
|
<Chip key={categoryIndex} text={category} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -60,20 +60,20 @@ export const prettyinlineTitle = (
|
||||||
export const prettyItemType = (
|
export const prettyItemType = (
|
||||||
metadata: any,
|
metadata: any,
|
||||||
langui: AppStaticProps["langui"]
|
langui: AppStaticProps["langui"]
|
||||||
): string | null | undefined => {
|
): string => {
|
||||||
switch (metadata.__typename) {
|
switch (metadata.__typename) {
|
||||||
case "ComponentMetadataAudio":
|
case "ComponentMetadataAudio":
|
||||||
return langui.audio;
|
return langui.audio ?? "Audio";
|
||||||
case "ComponentMetadataBooks":
|
case "ComponentMetadataBooks":
|
||||||
return langui.textual;
|
return langui.textual ?? "Textual";
|
||||||
case "ComponentMetadataGame":
|
case "ComponentMetadataGame":
|
||||||
return langui.game;
|
return langui.game ?? "Game";
|
||||||
case "ComponentMetadataVideo":
|
case "ComponentMetadataVideo":
|
||||||
return langui.video;
|
return langui.video ?? "Video";
|
||||||
case "ComponentMetadataGroup":
|
case "ComponentMetadataGroup":
|
||||||
return langui.group;
|
return langui.group ?? "Group";
|
||||||
case "ComponentMetadataOther":
|
case "ComponentMetadataOther":
|
||||||
return langui.other;
|
return langui.other ?? "Other";
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { AppStaticProps } from "../graphql/getAppStaticProps";
|
import { AppStaticProps } from "../graphql/getAppStaticProps";
|
||||||
import { SelectiveRequiredNonNullable } from "./types";
|
import { PathDot, SelectiveNonNullable } from "./types/SelectiveNonNullable";
|
||||||
import {
|
import {
|
||||||
Enum_Componentsetstextset_Status,
|
Enum_Componentsetstextset_Status,
|
||||||
GetLibraryItemQuery,
|
GetLibraryItemQuery,
|
||||||
|
@ -71,21 +71,29 @@ export const filterDefined = <T>(t: T[] | null | undefined): NonNullable<T>[] =>
|
||||||
? []
|
? []
|
||||||
: (t.filter((item) => isDefined(item)) as NonNullable<T>[]);
|
: (t.filter((item) => isDefined(item)) as NonNullable<T>[]);
|
||||||
|
|
||||||
export const filterHasAttributes = <T, P extends keyof NonNullable<T>>(
|
export const filterHasAttributes = <T, P extends PathDot<T>>(
|
||||||
t: T[] | null | undefined,
|
t: T[] | null | undefined,
|
||||||
attributes?: P[]
|
paths: readonly P[]
|
||||||
): SelectiveRequiredNonNullable<NonNullable<T>, P>[] =>
|
): SelectiveNonNullable<T, typeof paths[number]>[] =>
|
||||||
isUndefined(t)
|
isUndefined(t)
|
||||||
? []
|
? []
|
||||||
: (t.filter((item) => {
|
: (t.filter((item) =>
|
||||||
|
hasAttributes(item, paths)
|
||||||
|
) as unknown as SelectiveNonNullable<T, typeof paths[number]>[]);
|
||||||
|
|
||||||
|
const hasAttributes = <T>(item: T, paths: readonly PathDot<T>[]): boolean => {
|
||||||
if (isDefined(item)) {
|
if (isDefined(item)) {
|
||||||
const attributesToCheck = attributes ?? (Object.keys(item) as P[]);
|
return paths.every((path) => {
|
||||||
return attributesToCheck.every((attribute) =>
|
const attributeToCheck = (path as string).split(".")[0];
|
||||||
isDefined(item[attribute])
|
return (
|
||||||
|
isDefined(attributeToCheck) &&
|
||||||
|
Object.keys(item).includes(attributeToCheck) &&
|
||||||
|
isDefined(item[attributeToCheck as keyof T])
|
||||||
);
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}) as unknown as SelectiveRequiredNonNullable<NonNullable<T>, P>[]);
|
};
|
||||||
|
|
||||||
export const iterateMap = <K, V, U>(
|
export const iterateMap = <K, V, U>(
|
||||||
map: Map<K, V>,
|
map: Map<K, V>,
|
||||||
|
@ -95,7 +103,6 @@ export const iterateMap = <K, V, U>(
|
||||||
const toList = [...map];
|
const toList = [...map];
|
||||||
if (isDefined(sortingFunction)) {
|
if (isDefined(sortingFunction)) {
|
||||||
toList.sort(sortingFunction);
|
toList.sort(sortingFunction);
|
||||||
console.log(toList.sort(sortingFunction));
|
|
||||||
}
|
}
|
||||||
return toList.map(([key, value], index) => callbackfn(key, value, index));
|
return toList.map(([key, value], index) => callbackfn(key, value, index));
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,8 @@ import {
|
||||||
GetWikiPageQuery,
|
GetWikiPageQuery,
|
||||||
} from "graphql/generated";
|
} from "graphql/generated";
|
||||||
|
|
||||||
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
type Post = NonNullable<
|
type Post = NonNullable<
|
||||||
NonNullable<GetPostQuery["posts"]>["data"][number]["attributes"]
|
NonNullable<GetPostQuery["posts"]>["data"][number]["attributes"]
|
||||||
>;
|
>;
|
||||||
|
@ -12,6 +14,8 @@ export interface PostWithTranslations extends Omit<Post, "translations"> {
|
||||||
translations: NonNullable<Post["translations"]>;
|
translations: NonNullable<Post["translations"]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
export type Content = NonNullable<
|
export type Content = NonNullable<
|
||||||
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
|
NonNullable<GetContentTextQuery["contents"]>["data"][number]["attributes"]
|
||||||
>;
|
>;
|
||||||
|
@ -20,6 +24,8 @@ export interface ContentWithTranslations extends Omit<Content, "translations"> {
|
||||||
translations: NonNullable<Content["translations"]>;
|
translations: NonNullable<Content["translations"]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
type WikiPage = NonNullable<
|
type WikiPage = NonNullable<
|
||||||
NonNullable<GetWikiPageQuery["wikiPages"]>["data"][number]["attributes"]
|
NonNullable<GetWikiPageQuery["wikiPages"]>["data"][number]["attributes"]
|
||||||
>;
|
>;
|
||||||
|
@ -29,13 +35,13 @@ export interface WikiPageWithTranslations
|
||||||
translations: NonNullable<WikiPage["translations"]>;
|
translations: NonNullable<WikiPage["translations"]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
|
|
||||||
export type RequiredNonNullable<T> = {
|
export type RequiredNonNullable<T> = {
|
||||||
[P in keyof T]-?: NonNullable<T[P]>;
|
[P in keyof T]-?: NonNullable<T[P]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SelectiveRequiredNonNullable<T, K extends keyof T> = Omit<T, K> & {
|
// ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||||
[P in K]-?: NonNullable<T[P]>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum LibraryItemUserStatus {
|
export enum LibraryItemUserStatus {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
type JoinDot<K extends string, P extends string> = `${K}${"" extends K
|
||||||
|
? ""
|
||||||
|
: "."}${P}`;
|
||||||
|
|
||||||
|
export type PathDot<T, Acc extends string = ""> = T extends object
|
||||||
|
? {
|
||||||
|
[K in keyof T]: K extends string
|
||||||
|
? JoinDot<Acc, K> | PathDot<T[K], JoinDot<Acc, K>>
|
||||||
|
: never;
|
||||||
|
}[keyof T]
|
||||||
|
: Acc;
|
||||||
|
|
||||||
|
type PathHead<T extends unknown[]> = T extends [infer head]
|
||||||
|
? head
|
||||||
|
: T extends [infer head, ...infer rest]
|
||||||
|
? head
|
||||||
|
: "";
|
||||||
|
|
||||||
|
type PathRest<T extends unknown[]> = T extends [infer head, ...infer rest]
|
||||||
|
? rest extends []
|
||||||
|
? never
|
||||||
|
: rest
|
||||||
|
: never;
|
||||||
|
|
||||||
|
type PathLast<T extends unknown[]> = T["length"] extends 1 ? true : false;
|
||||||
|
|
||||||
|
type Recursive<T, Path extends unknown[]> = PathHead<Path> extends keyof T
|
||||||
|
? Omit<T, PathHead<Path>> & {
|
||||||
|
[P in PathHead<Path>]-?: PathLast<Path> extends true
|
||||||
|
? NonNullable<T[P]>
|
||||||
|
: Recursive<NonNullable<T[P]>, PathRest<Path>>;
|
||||||
|
}
|
||||||
|
: T;
|
||||||
|
|
||||||
|
type Split<
|
||||||
|
Str,
|
||||||
|
Cache extends string[] = []
|
||||||
|
> = Str extends `${infer Method}.${infer PathRest}`
|
||||||
|
? Split<PathRest, [...Cache, Method]>
|
||||||
|
: Str extends `${infer PathLast}`
|
||||||
|
? [...Cache, PathLast]
|
||||||
|
: never;
|
||||||
|
|
||||||
|
export type SelectiveNonNullable<T, P extends PathDot<T>> = Recursive<
|
||||||
|
NonNullable<T>,
|
||||||
|
Split<P>
|
||||||
|
>;
|
|
@ -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
|
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"
|
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) => (
|
||||||
<Fragment key={video.id}>
|
<Fragment key={video.id}>
|
||||||
<PreviewCard
|
<PreviewCard
|
||||||
href={`/archives/videos/v/${video.attributes.uid}`}
|
href={`/archives/videos/v/${video.attributes.uid}`}
|
||||||
|
@ -152,7 +154,9 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const channels = await sdk.getVideoChannelsSlugs();
|
const channels = await sdk.getVideoChannelsSlugs();
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
if (channels.videoChannels?.data)
|
if (channels.videoChannels?.data)
|
||||||
filterHasAttributes(channels.videoChannels.data).map((channel) => {
|
filterHasAttributes(channels.videoChannels.data, [
|
||||||
|
"attributes",
|
||||||
|
] as const).map((channel) => {
|
||||||
context.locales?.map((local) => {
|
context.locales?.map((local) => {
|
||||||
paths.push({
|
paths.push({
|
||||||
params: { uid: channel.attributes.uid },
|
params: { uid: channel.attributes.uid },
|
||||||
|
|
|
@ -92,7 +92,7 @@ const Videos = ({ langui, videos, ...otherProps }: Props): JSX.Element => {
|
||||||
() => (
|
() => (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(videos)}
|
items={filterHasAttributes(videos, ["id", "attributes"] as const)}
|
||||||
getItemId={(item) => item.id}
|
getItemId={(item) => item.id}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -238,11 +238,13 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const videos = await sdk.getVideosSlugs();
|
const videos = await sdk.getVideosSlugs();
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
if (videos.videos?.data)
|
if (videos.videos?.data)
|
||||||
filterHasAttributes(videos.videos.data).map((video) => {
|
filterHasAttributes(videos.videos.data, ["attributes"] as const).map(
|
||||||
|
(video) => {
|
||||||
context.locales?.map((local) => {
|
context.locales?.map((local) => {
|
||||||
paths.push({ params: { uid: video.attributes.uid }, locale: local });
|
paths.push({ params: { uid: video.attributes.uid }, locale: local });
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
paths,
|
paths,
|
||||||
fallback: "blocking",
|
fallback: "blocking",
|
||||||
|
|
|
@ -114,13 +114,13 @@ const Content = ({
|
||||||
<p className="font-headers font-bold">
|
<p className="font-headers font-bold">
|
||||||
{langui.source_language}:
|
{langui.source_language}:
|
||||||
</p>
|
</p>
|
||||||
<Chip>
|
<Chip
|
||||||
{prettyLanguage(
|
text={prettyLanguage(
|
||||||
selectedTranslation.text_set.source_language.data.attributes
|
selectedTranslation.text_set.source_language.data.attributes
|
||||||
.code,
|
.code,
|
||||||
languages
|
languages
|
||||||
)}
|
)}
|
||||||
</Chip>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ const Content = ({
|
||||||
)}
|
)}
|
||||||
maxWidth={"20rem"}
|
maxWidth={"20rem"}
|
||||||
>
|
>
|
||||||
<Chip>{selectedTranslation.text_set.status}</Chip>
|
<Chip text={selectedTranslation.text_set.status} />
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -146,7 +146,8 @@ const Content = ({
|
||||||
</p>
|
</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(
|
{filterHasAttributes(
|
||||||
selectedTranslation.text_set.transcribers.data
|
selectedTranslation.text_set.transcribers.data,
|
||||||
|
["attributes", "id"] as const
|
||||||
).map((recorder) => (
|
).map((recorder) => (
|
||||||
<Fragment key={recorder.id}>
|
<Fragment key={recorder.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
|
@ -167,7 +168,8 @@ const Content = ({
|
||||||
</p>
|
</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(
|
{filterHasAttributes(
|
||||||
selectedTranslation.text_set.translators.data
|
selectedTranslation.text_set.translators.data,
|
||||||
|
["attributes", "id"] as const
|
||||||
).map((recorder) => (
|
).map((recorder) => (
|
||||||
<Fragment key={recorder.id}>
|
<Fragment key={recorder.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
|
@ -188,7 +190,8 @@ const Content = ({
|
||||||
</p>
|
</p>
|
||||||
<div className="grid place-content-center place-items-center gap-2">
|
<div className="grid place-content-center place-items-center gap-2">
|
||||||
{filterHasAttributes(
|
{filterHasAttributes(
|
||||||
selectedTranslation.text_set.proofreaders.data
|
selectedTranslation.text_set.proofreaders.data,
|
||||||
|
["attributes", "id"] as const
|
||||||
).map((recorder) => (
|
).map((recorder) => (
|
||||||
<Fragment key={recorder.id}>
|
<Fragment key={recorder.id}>
|
||||||
<RecorderChip
|
<RecorderChip
|
||||||
|
@ -221,10 +224,12 @@ const Content = ({
|
||||||
{langui.source}
|
{langui.source}
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-6 grid place-items-center gap-6 text-left">
|
<div className="mt-6 grid place-items-center gap-6 text-left">
|
||||||
{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 =
|
const libraryItem =
|
||||||
rangedContent.attributes?.library_item?.data;
|
rangedContent.attributes.library_item.data;
|
||||||
if (libraryItem?.attributes && libraryItem.id) {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={libraryItem.attributes.slug}
|
key={libraryItem.attributes.slug}
|
||||||
|
@ -250,9 +255,10 @@ const Content = ({
|
||||||
]
|
]
|
||||||
: []
|
: []
|
||||||
}
|
}
|
||||||
bottomChips={libraryItem.attributes.categories?.data.map(
|
bottomChips={filterHasAttributes(
|
||||||
(category) => category.attributes?.short ?? ""
|
libraryItem.attributes.categories?.data,
|
||||||
)}
|
["attributes"] as const
|
||||||
|
).map((category) => category.attributes.short)}
|
||||||
metadata={{
|
metadata={{
|
||||||
currencies: currencies,
|
currencies: currencies,
|
||||||
release_date: libraryItem.attributes.release_date,
|
release_date: libraryItem.attributes.release_date,
|
||||||
|
@ -272,8 +278,6 @@ const Content = ({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return <></>;
|
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -507,14 +511,16 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const contents = await sdk.getContentsSlugs();
|
const contents = await sdk.getContentsSlugs();
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
filterHasAttributes(contents.contents?.data).map((item) => {
|
filterHasAttributes(contents.contents?.data, ["attributes"] as const).map(
|
||||||
|
(item) => {
|
||||||
context.locales?.map((local) => {
|
context.locales?.map((local) => {
|
||||||
paths.push({
|
paths.push({
|
||||||
params: { slug: item.attributes.slug },
|
params: { slug: item.attributes.slug },
|
||||||
locale: local,
|
locale: local,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
paths,
|
paths,
|
||||||
fallback: "blocking",
|
fallback: "blocking",
|
||||||
|
|
|
@ -21,8 +21,8 @@ import { Icon } from "components/Ico";
|
||||||
import { filterDefined, filterHasAttributes } from "helpers/others";
|
import { filterDefined, filterHasAttributes } from "helpers/others";
|
||||||
import { GetContentsQuery } from "graphql/generated";
|
import { GetContentsQuery } from "graphql/generated";
|
||||||
import { SmartList } from "components/SmartList";
|
import { SmartList } from "components/SmartList";
|
||||||
import { SelectiveRequiredNonNullable } from "helpers/types";
|
|
||||||
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
|
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
|
||||||
|
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -73,7 +73,7 @@ const Contents = ({
|
||||||
|
|
||||||
const groupingFunction = useCallback(
|
const groupingFunction = useCallback(
|
||||||
(
|
(
|
||||||
item: SelectiveRequiredNonNullable<
|
item: SelectiveNonNullable<
|
||||||
NonNullable<GetContentsQuery["contents"]>["data"][number],
|
NonNullable<GetContentsQuery["contents"]>["data"][number],
|
||||||
"attributes" | "id"
|
"attributes" | "id"
|
||||||
>
|
>
|
||||||
|
@ -81,7 +81,8 @@ const Contents = ({
|
||||||
switch (groupingMethod) {
|
switch (groupingMethod) {
|
||||||
case 0: {
|
case 0: {
|
||||||
const categories = filterHasAttributes(
|
const categories = filterHasAttributes(
|
||||||
item.attributes.categories?.data
|
item.attributes.categories?.data,
|
||||||
|
["attributes"] as const
|
||||||
);
|
);
|
||||||
if (categories.length > 0) {
|
if (categories.length > 0) {
|
||||||
return categories.map((category) => category.attributes.name);
|
return categories.map((category) => category.attributes.name);
|
||||||
|
@ -106,10 +107,7 @@ const Contents = ({
|
||||||
|
|
||||||
const filteringFunction = useCallback(
|
const filteringFunction = useCallback(
|
||||||
(
|
(
|
||||||
item: SelectiveRequiredNonNullable<
|
item: SelectiveNonNullable<Props["contents"][number], "attributes" | "id">
|
||||||
Props["contents"][number],
|
|
||||||
"attributes" | "id"
|
|
||||||
>
|
|
||||||
) => {
|
) => {
|
||||||
if (
|
if (
|
||||||
effectiveCombineRelatedContent &&
|
effectiveCombineRelatedContent &&
|
||||||
|
@ -217,7 +215,7 @@ const Contents = ({
|
||||||
() => (
|
() => (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(contents)}
|
items={filterHasAttributes(contents, ["attributes", "id"] as const)}
|
||||||
getItemId={(item) => item.id}
|
getItemId={(item) => item.id}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -60,7 +60,7 @@ const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
/>
|
/>
|
||||||
<p>{line.subitems.join(" -> ")}</p>
|
<p>{line.subitems.join(" -> ")}</p>
|
||||||
<p>{line.name}</p>
|
<p>{line.name}</p>
|
||||||
<Chip>{line.type}</Chip>
|
<Chip text={line.type} />
|
||||||
<Chip
|
<Chip
|
||||||
className={
|
className={
|
||||||
line.severity === "Very High"
|
line.severity === "Very High"
|
||||||
|
@ -71,9 +71,8 @@ const CheckupContents = ({ contents, ...otherProps }: Props): JSX.Element => {
|
||||||
? "bg-[#fff344] !opacity-100"
|
? "bg-[#fff344] !opacity-100"
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
>
|
text={line.severity}
|
||||||
{line.severity}
|
/>
|
||||||
</Chip>
|
|
||||||
<ToolTip content={line.recommandation} placement="left">
|
<ToolTip content={line.recommandation} placement="left">
|
||||||
<p>{line.description}</p>
|
<p>{line.description}</p>
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
|
@ -138,7 +137,8 @@ const testingContent = (contents: Props["contents"]): Report => {
|
||||||
lines: [],
|
lines: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
filterHasAttributes(contents.contents?.data).map((content) => {
|
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 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}`;
|
const frontendUrl = `${process.env.NEXT_PUBLIC_URL_SELF}/contents/${content.attributes.slug}`;
|
||||||
|
|
||||||
|
@ -452,6 +452,7 @@ const testingContent = (contents: Props["contents"]): Report => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return report;
|
return report;
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,7 +65,7 @@ const CheckupLibraryItems = ({
|
||||||
/>
|
/>
|
||||||
<p>{line.subitems.join(" -> ")}</p>
|
<p>{line.subitems.join(" -> ")}</p>
|
||||||
<p>{line.name}</p>
|
<p>{line.name}</p>
|
||||||
<Chip>{line.type}</Chip>
|
<Chip text={line.type} />
|
||||||
<Chip
|
<Chip
|
||||||
className={
|
className={
|
||||||
line.severity === "Very High"
|
line.severity === "Very High"
|
||||||
|
@ -76,9 +76,8 @@ const CheckupLibraryItems = ({
|
||||||
? "bg-[#fff344] !opacity-100"
|
? "bg-[#fff344] !opacity-100"
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
>
|
text={line.severity}
|
||||||
{line.severity}
|
/>
|
||||||
</Chip>
|
|
||||||
<ToolTip content={line.recommandation} placement="left">
|
<ToolTip content={line.recommandation} placement="left">
|
||||||
<p>{line.description}</p>
|
<p>{line.description}</p>
|
||||||
</ToolTip>
|
</ToolTip>
|
||||||
|
|
|
@ -221,7 +221,8 @@ const LibrarySlug = ({
|
||||||
{item.urls?.length ? (
|
{item.urls?.length ? (
|
||||||
<div className="flex flex-row place-items-center gap-3">
|
<div className="flex flex-row place-items-center gap-3">
|
||||||
<p>{langui.available_at}</p>
|
<p>{langui.available_at}</p>
|
||||||
{filterHasAttributes(item.urls).map((url, index) => (
|
{filterHasAttributes(item.urls, ["url"] as const).map(
|
||||||
|
(url, index) => (
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
<Button
|
<Button
|
||||||
href={url.url}
|
href={url.url}
|
||||||
|
@ -229,7 +230,8 @@ const LibrarySlug = ({
|
||||||
text={prettyURL(url.url)}
|
text={prettyURL(url.url)}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
)
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p>{langui.item_not_available}</p>
|
<p>{langui.item_not_available}</p>
|
||||||
|
@ -246,20 +248,20 @@ const LibrarySlug = ({
|
||||||
className="grid w-full grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-end
|
className="grid w-full grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))] items-end
|
||||||
gap-8"
|
gap-8"
|
||||||
>
|
>
|
||||||
{filterHasAttributes(item.gallery.data).map(
|
{filterHasAttributes(item.gallery.data, [
|
||||||
(galleryItem, index) => (
|
"id",
|
||||||
|
"attributes",
|
||||||
|
] as const).map((galleryItem, index) => (
|
||||||
<Fragment key={galleryItem.id}>
|
<Fragment key={galleryItem.id}>
|
||||||
<div
|
<div
|
||||||
className="relative aspect-square cursor-pointer
|
className="relative aspect-square cursor-pointer
|
||||||
transition-transform hover:scale-[1.02]"
|
transition-transform hover:scale-[1.02]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const images: string[] = filterHasAttributes(
|
const images: string[] = filterHasAttributes(
|
||||||
item.gallery?.data
|
item.gallery?.data,
|
||||||
|
["attributes"] as const
|
||||||
).map((image) =>
|
).map((image) =>
|
||||||
getAssetURL(
|
getAssetURL(image.attributes.url, ImageQuality.Large)
|
||||||
image.attributes.url,
|
|
||||||
ImageQuality.Large
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
openLightBox(images, index);
|
openLightBox(images, index);
|
||||||
}}
|
}}
|
||||||
|
@ -271,8 +273,7 @@ const LibrarySlug = ({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -288,9 +289,9 @@ const LibrarySlug = ({
|
||||||
<div className="grid place-content-start place-items-center">
|
<div className="grid place-content-start place-items-center">
|
||||||
<h3 className="text-xl">{langui.type}</h3>
|
<h3 className="text-xl">{langui.type}</h3>
|
||||||
<div className="grid grid-flow-col gap-1">
|
<div className="grid grid-flow-col gap-1">
|
||||||
<Chip>{prettyItemType(item.metadata[0], langui)}</Chip>
|
<Chip text={prettyItemType(item.metadata[0], langui)} />
|
||||||
{"›"}
|
{"›"}
|
||||||
<Chip>{prettyItemSubType(item.metadata[0])}</Chip>
|
<Chip text={prettyItemSubType(item.metadata[0])} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -331,8 +332,10 @@ const LibrarySlug = ({
|
||||||
<div className="flex flex-col place-items-center gap-2">
|
<div className="flex flex-col place-items-center gap-2">
|
||||||
<h3 className="text-xl">{langui.categories}</h3>
|
<h3 className="text-xl">{langui.categories}</h3>
|
||||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||||
{item.categories.data.map((category) => (
|
{filterHasAttributes(item.categories.data, [
|
||||||
<Chip key={category.id}>{category.attributes?.name}</Chip>
|
"attributes",
|
||||||
|
] as const).map((category) => (
|
||||||
|
<Chip key={category.id} text={category.attributes.name} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -458,7 +461,10 @@ const LibrarySlug = ({
|
||||||
className="grid w-full grid-cols-[repeat(auto-fill,minmax(15rem,1fr))]
|
className="grid w-full grid-cols-[repeat(auto-fill,minmax(15rem,1fr))]
|
||||||
items-end gap-8 mobile:grid-cols-2 thin:grid-cols-1"
|
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) => (
|
||||||
<Fragment key={subitem.id}>
|
<Fragment key={subitem.id}>
|
||||||
<PreviewCard
|
<PreviewCard
|
||||||
href={`/library/${subitem.attributes.slug}`}
|
href={`/library/${subitem.attributes.slug}`}
|
||||||
|
@ -506,8 +512,9 @@ const LibrarySlug = ({
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="grid w-full gap-4">
|
<div className="grid w-full gap-4">
|
||||||
{filterHasAttributes(item.contents.data).map(
|
{filterHasAttributes(item.contents.data, [
|
||||||
(rangedContent) => (
|
"attributes",
|
||||||
|
] as const).map((rangedContent) => (
|
||||||
<ContentLine
|
<ContentLine
|
||||||
content={
|
content={
|
||||||
rangedContent.attributes.content?.data?.attributes
|
rangedContent.attributes.content?.data?.attributes
|
||||||
|
@ -524,14 +531,15 @@ const LibrarySlug = ({
|
||||||
})),
|
})),
|
||||||
categories: filterHasAttributes(
|
categories: filterHasAttributes(
|
||||||
rangedContent.attributes.content.data.attributes
|
rangedContent.attributes.content.data.attributes
|
||||||
.categories?.data
|
.categories?.data,
|
||||||
|
["attributes"]
|
||||||
).map((category) => category.attributes.short),
|
).map((category) => category.attributes.short),
|
||||||
type:
|
type:
|
||||||
rangedContent.attributes.content.data.attributes
|
rangedContent.attributes.content.data.attributes
|
||||||
.type?.data?.attributes?.titles?.[0]?.title ??
|
.type?.data?.attributes?.titles?.[0]?.title ??
|
||||||
prettySlug(
|
prettySlug(
|
||||||
rangedContent.attributes.content.data
|
rangedContent.attributes.content.data.attributes
|
||||||
.attributes.type?.data?.attributes?.slug
|
.type?.data?.attributes?.slug
|
||||||
),
|
),
|
||||||
slug: rangedContent.attributes.content.data
|
slug: rangedContent.attributes.content.data
|
||||||
.attributes.slug,
|
.attributes.slug,
|
||||||
|
@ -554,8 +562,7 @@ const LibrarySlug = ({
|
||||||
rangedContent.attributes.scan_set.length > 0
|
rangedContent.attributes.scan_set.length > 0
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -643,7 +650,9 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const libraryItems = await sdk.getLibraryItemsSlugs();
|
const libraryItems = await sdk.getLibraryItemsSlugs();
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
filterHasAttributes(libraryItems.libraryItems?.data).map((item) => {
|
filterHasAttributes(libraryItems.libraryItems?.data, [
|
||||||
|
"attributes",
|
||||||
|
] as const).map((item) => {
|
||||||
context.locales?.map((local) =>
|
context.locales?.map((local) =>
|
||||||
paths.push({ params: { slug: item.attributes.slug }, locale: local })
|
paths.push({ params: { slug: item.attributes.slug }, locale: local })
|
||||||
);
|
);
|
||||||
|
@ -702,8 +711,6 @@ const ContentLine = ({
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(prettySlug(slug, parentSlug));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cJoin(
|
className={cJoin(
|
||||||
|
@ -730,13 +737,13 @@ const ContentLine = ({
|
||||||
</a>
|
</a>
|
||||||
<div className="flex flex-row flex-wrap gap-1">
|
<div className="flex flex-row flex-wrap gap-1">
|
||||||
{content?.categories?.map((category, index) => (
|
{content?.categories?.map((category, index) => (
|
||||||
<Chip key={index}>{category}</Chip>
|
<Chip key={index} text={category} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<p className="h-4 w-full border-b-2 border-dotted border-black opacity-30"></p>
|
<p className="h-4 w-full border-b-2 border-dotted border-black opacity-30"></p>
|
||||||
<p>{rangeStart}</p>
|
<p>{rangeStart}</p>
|
||||||
{content?.type && (
|
{content?.type && (
|
||||||
<Chip className="justify-self-end thin:hidden">{content.type}</Chip>
|
<Chip className="justify-self-end thin:hidden" text={content.type} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -177,7 +177,9 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const libraryItems = await sdk.getLibraryItemsSlugs({});
|
const libraryItems = await sdk.getLibraryItemsSlugs({});
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
filterHasAttributes(libraryItems.libraryItems?.data).map((item) => {
|
filterHasAttributes(libraryItems.libraryItems?.data, [
|
||||||
|
"attributes",
|
||||||
|
] as const).map((item) => {
|
||||||
context.locales?.map((local) =>
|
context.locales?.map((local) =>
|
||||||
paths.push({ params: { slug: item.attributes.slug }, locale: local })
|
paths.push({ params: { slug: item.attributes.slug }, locale: local })
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,10 +17,7 @@ import {
|
||||||
prettyinlineTitle,
|
prettyinlineTitle,
|
||||||
prettyItemSubType,
|
prettyItemSubType,
|
||||||
} from "helpers/formatters";
|
} from "helpers/formatters";
|
||||||
import {
|
import { LibraryItemUserStatus } from "helpers/types";
|
||||||
LibraryItemUserStatus,
|
|
||||||
SelectiveRequiredNonNullable,
|
|
||||||
} from "helpers/types";
|
|
||||||
import { Icon } from "components/Ico";
|
import { Icon } from "components/Ico";
|
||||||
import { WithLabel } from "components/Inputs/WithLabel";
|
import { WithLabel } from "components/Inputs/WithLabel";
|
||||||
import { TextInput } from "components/Inputs/TextInput";
|
import { TextInput } from "components/Inputs/TextInput";
|
||||||
|
@ -35,6 +32,7 @@ import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholde
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { convertPrice } from "helpers/numbers";
|
import { convertPrice } from "helpers/numbers";
|
||||||
import { SmartList } from "components/SmartList";
|
import { SmartList } from "components/SmartList";
|
||||||
|
import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ╭─────────────╮
|
* ╭─────────────╮
|
||||||
|
@ -97,10 +95,7 @@ const Library = ({
|
||||||
|
|
||||||
const filteringFunction = useCallback(
|
const filteringFunction = useCallback(
|
||||||
(
|
(
|
||||||
item: SelectiveRequiredNonNullable<
|
item: SelectiveNonNullable<Props["items"][number], "attributes" | "id">
|
||||||
Props["items"][number],
|
|
||||||
"attributes" | "id"
|
|
||||||
>
|
|
||||||
) => {
|
) => {
|
||||||
if (!showSubitems && !item.attributes.root_item) return false;
|
if (!showSubitems && !item.attributes.root_item) return false;
|
||||||
if (
|
if (
|
||||||
|
@ -143,14 +138,8 @@ const Library = ({
|
||||||
|
|
||||||
const sortingFunction = useCallback(
|
const sortingFunction = useCallback(
|
||||||
(
|
(
|
||||||
a: SelectiveRequiredNonNullable<
|
a: SelectiveNonNullable<Props["items"][number], "attributes" | "id">,
|
||||||
Props["items"][number],
|
b: SelectiveNonNullable<Props["items"][number], "attributes" | "id">
|
||||||
"attributes" | "id"
|
|
||||||
>,
|
|
||||||
b: SelectiveRequiredNonNullable<
|
|
||||||
Props["items"][number],
|
|
||||||
"attributes" | "id"
|
|
||||||
>
|
|
||||||
) => {
|
) => {
|
||||||
switch (sortingMethod) {
|
switch (sortingMethod) {
|
||||||
case 0: {
|
case 0: {
|
||||||
|
@ -193,15 +182,13 @@ const Library = ({
|
||||||
|
|
||||||
const groupingFunction = useCallback(
|
const groupingFunction = useCallback(
|
||||||
(
|
(
|
||||||
item: SelectiveRequiredNonNullable<
|
item: SelectiveNonNullable<Props["items"][number], "attributes" | "id">
|
||||||
Props["items"][number],
|
|
||||||
"attributes" | "id"
|
|
||||||
>
|
|
||||||
): string[] => {
|
): string[] => {
|
||||||
switch (groupingMethod) {
|
switch (groupingMethod) {
|
||||||
case 0: {
|
case 0: {
|
||||||
const categories = filterHasAttributes(
|
const categories = filterHasAttributes(
|
||||||
item.attributes.categories?.data
|
item.attributes.categories?.data,
|
||||||
|
["attributes"] as const
|
||||||
);
|
);
|
||||||
if (categories.length > 0) {
|
if (categories.length > 0) {
|
||||||
return categories.map((category) => category.attributes.name);
|
return categories.map((category) => category.attributes.name);
|
||||||
|
@ -406,7 +393,7 @@ const Library = ({
|
||||||
() => (
|
() => (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(items)}
|
items={filterHasAttributes(items, ["id", "attributes"] as const)}
|
||||||
getItemId={(item) => item.id}
|
getItemId={(item) => item.id}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<PreviewCard
|
<PreviewCard
|
||||||
|
|
|
@ -47,11 +47,13 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const posts = await sdk.getPostsSlugs();
|
const posts = await sdk.getPostsSlugs();
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
|
|
||||||
filterHasAttributes(posts.posts?.data).map((item) => {
|
filterHasAttributes(posts.posts?.data, ["attributes"] as const).map(
|
||||||
|
(item) => {
|
||||||
context.locales?.map((local) =>
|
context.locales?.map((local) =>
|
||||||
paths.push({ params: { slug: item.attributes.slug }, locale: local })
|
paths.push({ params: { slug: item.attributes.slug }, locale: local })
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
paths,
|
paths,
|
||||||
fallback: "blocking",
|
fallback: "blocking",
|
||||||
|
|
|
@ -97,7 +97,7 @@ const News = ({
|
||||||
() => (
|
() => (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
<ContentPanel width={ContentPanelWidthSizes.Full}>
|
||||||
<SmartList
|
<SmartList
|
||||||
items={filterHasAttributes(posts)}
|
items={filterHasAttributes(posts, ["attributes", "id"] as const)}
|
||||||
getItemId={(post) => post.id}
|
getItemId={(post) => post.id}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
renderItem={({ item: post }) => (
|
renderItem={({ item: post }) => (
|
||||||
|
|
|
@ -100,8 +100,10 @@ const WikiPage = ({
|
||||||
{langui.categories}
|
{langui.categories}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
<div className="flex flex-row flex-wrap place-content-center gap-2">
|
||||||
{page.categories?.data.map((category) => (
|
{filterHasAttributes(page.categories?.data, [
|
||||||
<Chip key={category.id}>{category.attributes?.name}</Chip>
|
"attributes",
|
||||||
|
] as const).map((category) => (
|
||||||
|
<Chip key={category.id} text={category.attributes.name} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -116,30 +118,28 @@ const WikiPage = ({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{filterHasAttributes(page.definitions, ["translations"]).map(
|
{filterHasAttributes(page.definitions, [
|
||||||
(definition, index) => (
|
"translations",
|
||||||
|
] as const).map((definition, index) => (
|
||||||
<>
|
<>
|
||||||
<DefinitionCard
|
<DefinitionCard
|
||||||
key={index}
|
key={index}
|
||||||
source={definition.source?.data?.attributes?.name}
|
source={definition.source?.data?.attributes?.name}
|
||||||
translations={filterHasAttributes(
|
translations={definition.translations.map((translation) => ({
|
||||||
definition.translations
|
language: translation?.language?.data?.attributes?.code,
|
||||||
).map((translation) => ({
|
definition: translation?.definition,
|
||||||
language: translation.language.data?.attributes?.code,
|
status: translation?.status,
|
||||||
definition: translation.definition,
|
|
||||||
status: translation.status,
|
|
||||||
}))}
|
}))}
|
||||||
index={index + 1}
|
index={index + 1}
|
||||||
languages={languages}
|
languages={languages}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
categories={filterHasAttributes(
|
categories={filterHasAttributes(definition.categories?.data, [
|
||||||
definition.categories?.data
|
"attributes",
|
||||||
).map((category) => category.attributes.short)}
|
] as const).map((category) => category.attributes.short)}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
</>
|
</>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
|
@ -194,14 +194,16 @@ export const getStaticPaths: GetStaticPaths = async (context) => {
|
||||||
const sdk = getReadySdk();
|
const sdk = getReadySdk();
|
||||||
const contents = await sdk.getWikiPagesSlugs();
|
const contents = await sdk.getWikiPagesSlugs();
|
||||||
const paths: GetStaticPathsResult["paths"] = [];
|
const paths: GetStaticPathsResult["paths"] = [];
|
||||||
filterHasAttributes(contents.wikiPages?.data).map((wikiPage) => {
|
filterHasAttributes(contents.wikiPages?.data, ["attributes"] as const).map(
|
||||||
|
(wikiPage) => {
|
||||||
context.locales?.map((local) =>
|
context.locales?.map((local) =>
|
||||||
paths.push({
|
paths.push({
|
||||||
params: { slug: wikiPage.attributes.slug },
|
params: { slug: wikiPage.attributes.slug },
|
||||||
locale: local,
|
locale: local,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
paths,
|
paths,
|
||||||
fallback: "blocking",
|
fallback: "blocking",
|
||||||
|
|
|
@ -74,7 +74,8 @@ const Chronology = ({
|
||||||
horizontalLine
|
horizontalLine
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{filterHasAttributes(chronologyEras).map((era) => (
|
{filterHasAttributes(chronologyEras, ["attributes", "id"] as const).map(
|
||||||
|
(era) => (
|
||||||
<Fragment key={era.id}>
|
<Fragment key={era.id}>
|
||||||
<NavOption
|
<NavOption
|
||||||
url={`#${era.attributes.slug}`}
|
url={`#${era.attributes.slug}`}
|
||||||
|
@ -89,7 +90,8 @@ const Chronology = ({
|
||||||
border
|
border
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
)
|
||||||
|
)}
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
),
|
),
|
||||||
[chronologyEras, langui]
|
[chronologyEras, langui]
|
||||||
|
|
|
@ -120,9 +120,11 @@ const Wiki = ({
|
||||||
icon={Icon.ChevronLeft}
|
icon={Icon.ChevronLeft}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{filterHasAttributes(filteredPages).map((page) => (
|
{filterHasAttributes(filteredPages, [
|
||||||
|
"id",
|
||||||
|
"attributes.translations",
|
||||||
|
] as const).map((page) => (
|
||||||
<Fragment key={page.id}>
|
<Fragment key={page.id}>
|
||||||
{page.attributes.translations && (
|
|
||||||
<TranslatedPreviewCard
|
<TranslatedPreviewCard
|
||||||
href={`/wiki/${page.attributes.slug}`}
|
href={`/wiki/${page.attributes.slug}`}
|
||||||
translations={page.attributes.translations.map(
|
translations={page.attributes.translations.map(
|
||||||
|
@ -149,7 +151,6 @@ const Wiki = ({
|
||||||
(category) => category.attributes?.short ?? ""
|
(category) => category.attributes?.short ?? ""
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue