Mass use of Immutable

This commit is contained in:
DrMint 2022-05-08 21:37:41 +02:00
parent 02e03071a0
commit 0591fa22d4
65 changed files with 375 additions and 338 deletions

View File

@ -1,9 +1,10 @@
import Button from "components/Inputs/Button"; import Button from "components/Inputs/Button";
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import { UploadImageFragment } from "graphql/generated"; import { UploadImageFragment } from "graphql/generated";
import { prettyLanguage, prettySlug } from "helpers/formatters";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettyLanguage, prettySlug } from "helpers/formatters";
import { getOgImage, ImageQuality, OgImage } from "helpers/img"; import { getOgImage, ImageQuality, OgImage } from "helpers/img";
import { Immutable } from "helpers/types";
import { useMediaMobile } from "hooks/useMediaQuery"; import { useMediaMobile } from "hooks/useMediaQuery";
import Head from "next/head"; import Head from "next/head";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
@ -24,8 +25,19 @@ interface Props extends AppStaticProps {
description?: string; description?: string;
} }
export default function AppLayout(props: Props): JSX.Element { export default function AppLayout(props: Immutable<Props>): JSX.Element {
const { langui, currencies, languages, subPanel, contentPanel } = props; const {
langui,
currencies,
languages,
subPanel,
contentPanel,
thumbnail,
title,
navTitle,
description,
subPanelIcon,
} = props;
const router = useRouter(); const router = useRouter();
const isMobile = useMediaMobile(); const isMobile = useMediaMobile();
const appLayout = useAppLayout(); const appLayout = useAppLayout();
@ -58,8 +70,8 @@ export default function AppLayout(props: Props): JSX.Element {
const turnSubIntoContent = subPanel && !contentPanel; const turnSubIntoContent = subPanel && !contentPanel;
const titlePrefix = "Accords Library"; const titlePrefix = "Accords Library";
const metaImage: OgImage = props.thumbnail const metaImage: OgImage = thumbnail
? getOgImage(ImageQuality.Og, props.thumbnail) ? getOgImage(ImageQuality.Og, thumbnail)
: { : {
image: "/default_og.jpg", image: "/default_og.jpg",
width: 1200, width: 1200,
@ -67,9 +79,9 @@ export default function AppLayout(props: Props): JSX.Element {
alt: "Accord's Library Logo", alt: "Accord's Library Logo",
}; };
const ogTitle = const ogTitle =
props.title ?? props.navTitle ?? prettySlug(router.asPath.split("/").pop()); title ?? navTitle ?? prettySlug(router.asPath.split("/").pop());
const metaDescription = props.description ?? langui.default_description ?? ""; const metaDescription = description ?? langui.default_description ?? "";
useEffect(() => { useEffect(() => {
document.getElementsByTagName("html")[0].style.fontSize = `${ document.getElementsByTagName("html")[0].style.fontSize = `${
@ -114,7 +126,7 @@ export default function AppLayout(props: Props): JSX.Element {
}, [currencySelect]); }, [currencySelect]);
let gridCol = ""; let gridCol = "";
if (props.subPanel) { if (subPanel) {
if (appLayout.mainPanelReduced) { if (appLayout.mainPanelReduced) {
gridCol = "grid-cols-[6rem_20rem_1fr]"; gridCol = "grid-cols-[6rem_20rem_1fr]";
} else { } else {
@ -260,8 +272,8 @@ export default function AppLayout(props: Props): JSX.Element {
{subPanel && !turnSubIntoContent {subPanel && !turnSubIntoContent
? appLayout.subPanelOpen ? appLayout.subPanelOpen
? "close" ? "close"
: props.subPanelIcon : subPanelIcon
? props.subPanelIcon ? subPanelIcon
: "tune" : "tune"
: ""} : ""}
</span> </span>

View File

@ -1,9 +1,11 @@
import { Immutable } from "helpers/types";
interface Props { interface Props {
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
} }
export default function Chip(props: Props): JSX.Element { export default function Chip(props: Immutable<Props>): JSX.Element {
return ( return (
<div <div
className={`grid place-content-center place-items-center text-xs pb-[0.14rem] whitespace-nowrap px-1.5 border-[1px] rounded-full opacity-70 transition-[color,_opacity,_border-color] hover:opacity-100 ${props.className}`} className={`grid place-content-center place-items-center text-xs pb-[0.14rem] whitespace-nowrap px-1.5 border-[1px] rounded-full opacity-70 transition-[color,_opacity,_border-color] hover:opacity-100 ${props.className}`}

View File

@ -1,8 +1,10 @@
import { Immutable } from "helpers/types";
interface Props { interface Props {
className?: string; className?: string;
} }
export default function HorizontalLine(props: Props): JSX.Element { export default function HorizontalLine(props: Immutable<Props>): JSX.Element {
return ( return (
<div <div
className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black ${props.className}`} className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black ${props.className}`}

View File

@ -1,5 +1,6 @@
import { UploadImageFragment } from "graphql/generated"; import { UploadImageFragment } from "graphql/generated";
import { ImageQuality, getImgSizesByQuality, getAssetURL } from "helpers/img"; import { getAssetURL, getImgSizesByQuality, ImageQuality } from "helpers/img";
import { Immutable } from "helpers/types";
import Image, { ImageProps } from "next/image"; import Image, { ImageProps } from "next/image";
interface Props { interface Props {
@ -12,7 +13,7 @@ interface Props {
priority?: ImageProps["priority"]; priority?: ImageProps["priority"];
} }
export default function Img(props: Props): JSX.Element { export default function Img(props: Immutable<Props>): JSX.Element {
if (typeof props.image === "string") { if (typeof props.image === "string") {
return ( return (
<img <img

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { MouseEventHandler } from "react"; import { MouseEventHandler } from "react";
@ -14,7 +15,7 @@ interface Props {
badgeNumber?: number; badgeNumber?: number;
} }
export default function Button(props: Props): JSX.Element { export default function Button(props: Immutable<Props>): JSX.Element {
const { const {
draggable, draggable,
id, id,
@ -39,11 +40,15 @@ export default function Button(props: Props): JSX.Element {
transition-all select-none hover:[--opacityBadge:0] --opacityBadge:100 ${className} ${ transition-all select-none hover:[--opacityBadge:0] --opacityBadge:100 ${className} ${
active active
? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed" ? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed"
: "cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:text-light active:drop-shadow-black-lg active:border-black" : `cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg
active:bg-black active:text-light active:drop-shadow-black-lg active:border-black`
}`} }`}
> >
{badgeNumber && ( {badgeNumber && (
<div className="opacity-[var(--opacityBadge)] transition-opacity grid place-items-center absolute -top-3 -right-2 bg-dark w-8 h-8 text-light font-bold rounded-full"> <div
className="opacity-[var(--opacityBadge)] transition-opacity grid place-items-center
absolute -top-3 -right-2 bg-dark w-8 h-8 text-light font-bold rounded-full"
>
{badgeNumber} {badgeNumber}
</div> </div>
)} )}

View File

@ -1,5 +1,6 @@
import { prettyLanguage } from "helpers/formatters";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettyLanguage } from "helpers/formatters";
import { Immutable } from "helpers/types";
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
import ToolTip from "../ToolTip"; import ToolTip from "../ToolTip";
import Button from "./Button"; import Button from "./Button";
@ -12,7 +13,7 @@ interface Props {
setLocalesIndex: Dispatch<SetStateAction<number | undefined>>; setLocalesIndex: Dispatch<SetStateAction<number | undefined>>;
} }
export default function LanguageSwitcher(props: Props): JSX.Element { export default function LanguageSwitcher(props: Immutable<Props>): JSX.Element {
const { locales, className, localesIndex, setLocalesIndex } = props; const { locales, className, localesIndex, setLocalesIndex } = props;
return ( return (

View File

@ -1,4 +1,5 @@
import { arrayMove } from "helpers/others"; import { arrayMove } from "helpers/others";
import { Immutable } from "helpers/types";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
interface Props { interface Props {
@ -7,7 +8,7 @@ interface Props {
onChange?: (items: Map<string, string>) => void; onChange?: (items: Map<string, string>) => void;
} }
export default function OrderableList(props: Props): JSX.Element { export default function OrderableList(props: Immutable<Props>): JSX.Element {
const [items, setItems] = useState<Map<string, string>>(props.items); const [items, setItems] = useState<Map<string, string>>(props.items);
useEffect(() => { useEffect(() => {

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
import Button from "./Button"; import Button from "./Button";
@ -8,7 +9,7 @@ interface Props {
setPage: Dispatch<SetStateAction<number>>; setPage: Dispatch<SetStateAction<number>>;
} }
export default function PageSelector(props: Props): JSX.Element { export default function PageSelector(props: Immutable<Props>): JSX.Element {
const { page, setPage, maxPage } = props; const { page, setPage, maxPage } = props;
return ( return (

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import { Dispatch, SetStateAction, useState } from "react"; import { Dispatch, SetStateAction, useState } from "react";
interface Props { interface Props {
@ -9,7 +10,7 @@ interface Props {
className?: string; className?: string;
} }
export default function Select(props: Props): JSX.Element { export default function Select(props: Immutable<Props>): JSX.Element {
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);
return ( return (

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
interface Props { interface Props {
@ -6,7 +7,7 @@ interface Props {
className?: string; className?: string;
} }
export default function Switch(props: Props): JSX.Element { export default function Switch(props: Immutable<Props>): JSX.Element {
return ( return (
<div <div
className={`h-6 w-12 rounded-full border-2 border-mid grid transition-colors relative cursor-pointer ${ className={`h-6 w-12 rounded-full border-2 border-mid grid transition-colors relative cursor-pointer ${

View File

@ -1,10 +1,12 @@
import { Immutable } from "helpers/types";
interface Props { interface Props {
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
id?: string; id?: string;
} }
export default function InsetBox(props: Props): JSX.Element { export default function InsetBox(props: Immutable<Props>): JSX.Element {
return ( return (
<div <div
id={props.id} id={props.id}

View File

@ -1,8 +1,9 @@
import Chip from "components/Chip"; import Chip from "components/Chip";
import Button from "components/Inputs/Button"; import Button from "components/Inputs/Button";
import { GetLibraryItemQuery } from "graphql/generated"; import { GetLibraryItemQuery } from "graphql/generated";
import { prettyinlineTitle, prettySlug } from "helpers/formatters";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettyinlineTitle, prettySlug } from "helpers/formatters";
import { Immutable } from "helpers/types";
import { useState } from "react"; import { useState } from "react";
interface Props { interface Props {
@ -20,7 +21,7 @@ interface Props {
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
} }
export default function ContentLine(props: Props): JSX.Element { export default function ContentLine(props: Immutable<Props>): JSX.Element {
const { content, langui, parentSlug } = props; const { content, langui, parentSlug } = props;
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);

View File

@ -5,9 +5,10 @@ import RecorderChip from "components/RecorderChip";
import ToolTip from "components/ToolTip"; import ToolTip from "components/ToolTip";
import { GetLibraryItemScansQuery } from "graphql/generated"; import { GetLibraryItemScansQuery } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { getStatusDescription } from "helpers/others";
import { getAssetFilename, getAssetURL, ImageQuality } from "helpers/img"; import { getAssetFilename, getAssetURL, ImageQuality } from "helpers/img";
import { isInteger } from "helpers/numbers"; import { isInteger } from "helpers/numbers";
import { getStatusDescription } from "helpers/others";
import { Immutable } from "helpers/types";
import useSmartLanguage from "hooks/useSmartLanguage"; import useSmartLanguage from "hooks/useSmartLanguage";
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
@ -50,7 +51,7 @@ interface Props {
>["content"]; >["content"];
} }
export default function ScanSet(props: Props): JSX.Element { export default function ScanSet(props: Immutable<Props>): JSX.Element {
const { const {
setLightboxOpen, setLightboxOpen,
setLightboxImages, setLightboxImages,
@ -68,7 +69,8 @@ export default function ScanSet(props: Props): JSX.Element {
languages: languages, languages: languages,
languageExtractor: (item) => item?.language?.data?.attributes?.code, languageExtractor: (item) => item?.language?.data?.attributes?.code,
transform: (item) => { transform: (item) => {
item?.pages?.data.sort((a, b) => { const newItem = { ...item } as Props["scanSet"][number];
newItem?.pages?.data.sort((a, b) => {
if (a.attributes?.url && b.attributes?.url) { if (a.attributes?.url && b.attributes?.url) {
let aName = getAssetFilename(a.attributes.url); let aName = getAssetFilename(a.attributes.url);
let bName = getAssetFilename(b.attributes.url); let bName = getAssetFilename(b.attributes.url);
@ -91,7 +93,7 @@ export default function ScanSet(props: Props): JSX.Element {
} }
return 0; return 0;
}); });
return item; return newItem;
}, },
}); });

View File

@ -7,8 +7,9 @@ import {
UploadImageFragment, UploadImageFragment,
} from "graphql/generated"; } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { getStatusDescription } from "helpers/others";
import { getAssetURL, ImageQuality } from "helpers/img"; import { getAssetURL, ImageQuality } from "helpers/img";
import { getStatusDescription } from "helpers/others";
import { Immutable } from "helpers/types";
import useSmartLanguage from "hooks/useSmartLanguage"; import useSmartLanguage from "hooks/useSmartLanguage";
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
@ -30,7 +31,7 @@ interface Props {
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
} }
export default function ScanSetCover(props: Props): JSX.Element { export default function ScanSetCover(props: Immutable<Props>): JSX.Element {
const { const {
setLightboxOpen, setLightboxOpen,
setLightboxImages, setLightboxImages,

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
import Hotkeys from "react-hot-keys"; import Hotkeys from "react-hot-keys";
import { useSwipeable } from "react-swipeable"; import { useSwipeable } from "react-swipeable";
@ -15,7 +16,7 @@ interface Props {
setIndex: Dispatch<SetStateAction<number>>; setIndex: Dispatch<SetStateAction<number>>;
} }
export default function LightBox(props: Props): JSX.Element { export default function LightBox(props: Immutable<Props>): JSX.Element {
const { state, setState, images, index, setIndex } = props; const { state, setState, images, index, setIndex } = props;
function handlePrevious() { function handlePrevious() {

View File

@ -6,6 +6,7 @@ import ToolTip from "components/ToolTip";
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import { slugify } from "helpers/formatters"; import { slugify } from "helpers/formatters";
import { getAssetURL, ImageQuality } from "helpers/img"; import { getAssetURL, ImageQuality } from "helpers/img";
import { Immutable } from "helpers/types";
import Markdown from "markdown-to-jsx"; import Markdown from "markdown-to-jsx";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import React, { useState } from "react"; import React, { useState } from "react";
@ -16,7 +17,7 @@ interface Props {
text: string; text: string;
} }
export default function Markdawn(props: Props): JSX.Element { export default function Markdawn(props: Immutable<Props>): JSX.Element {
const appLayout = useAppLayout(); const appLayout = useAppLayout();
const text = preprocessMarkDawn(props.text); const text = preprocessMarkDawn(props.text);

View File

@ -1,4 +1,5 @@
import { slugify } from "helpers/formatters"; import { slugify } from "helpers/formatters";
import { Immutable } from "helpers/types";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { preprocessMarkDawn } from "./Markdawn"; import { preprocessMarkDawn } from "./Markdawn";
@ -7,7 +8,7 @@ interface Props {
title?: string; title?: string;
} }
export default function TOCComponent(props: Props): JSX.Element { export default function TOCComponent(props: Immutable<Props>): JSX.Element {
const { text, title } = props; const { text, title } = props;
const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title); const toc = getTocFromMarkdawn(preprocessMarkDawn(text), title);
const router = useRouter(); const router = useRouter();

View File

@ -1,4 +1,5 @@
import ToolTip from "components/ToolTip"; import ToolTip from "components/ToolTip";
import { Immutable } from "helpers/types";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { MouseEventHandler } from "react"; import { MouseEventHandler } from "react";
@ -12,7 +13,7 @@ interface Props {
onClick?: MouseEventHandler<HTMLDivElement>; onClick?: MouseEventHandler<HTMLDivElement>;
} }
export default function NavOption(props: Props): JSX.Element { export default function NavOption(props: Immutable<Props>): JSX.Element {
const router = useRouter(); const router = useRouter();
const isActive = router.asPath.startsWith(props.url); const isActive = router.asPath.startsWith(props.url);
const divActive = "bg-mid shadow-inner-sm shadow-shade"; const divActive = "bg-mid shadow-inner-sm shadow-shade";

View File

@ -1,4 +1,5 @@
import HorizontalLine from "components/HorizontalLine"; import HorizontalLine from "components/HorizontalLine";
import { Immutable } from "helpers/types";
interface Props { interface Props {
icon?: string; icon?: string;
@ -6,7 +7,7 @@ interface Props {
description?: string | null | undefined; description?: string | null | undefined;
} }
export default function PanelHeader(props: Props): JSX.Element { export default function PanelHeader(props: Immutable<Props>): JSX.Element {
return ( return (
<> <>
<div className="w-full grid place-items-center"> <div className="w-full grid place-items-center">

View File

@ -2,6 +2,7 @@ import HorizontalLine from "components/HorizontalLine";
import Button from "components/Inputs/Button"; import Button from "components/Inputs/Button";
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
interface Props { interface Props {
href: string; href: string;
@ -18,7 +19,7 @@ export enum ReturnButtonType {
both = "both", both = "both",
} }
export default function ReturnButton(props: Props): JSX.Element { export default function ReturnButton(props: Immutable<Props>): JSX.Element {
const appLayout = useAppLayout(); const appLayout = useAppLayout();
return ( return (

View File

@ -1,3 +1,5 @@
import { Immutable } from "helpers/types";
interface Props { interface Props {
children: React.ReactNode; children: React.ReactNode;
autoformat?: boolean; autoformat?: boolean;
@ -9,7 +11,7 @@ export enum ContentPanelWidthSizes {
large = "large", large = "large",
} }
export default function ContentPanel(props: Props): JSX.Element { export default function ContentPanel(props: Immutable<Props>): JSX.Element {
const width = props.width ? props.width : ContentPanelWidthSizes.default; const width = props.width ? props.width : ContentPanelWidthSizes.default;
const widthCSS = const widthCSS =
width === ContentPanelWidthSizes.default ? "max-w-2xl" : "w-full"; width === ContentPanelWidthSizes.default ? "max-w-2xl" : "w-full";

View File

@ -7,12 +7,13 @@ import { useMediaDesktop } from "hooks/useMediaQuery";
import Markdown from "markdown-to-jsx"; import Markdown from "markdown-to-jsx";
import Link from "next/link"; import Link from "next/link";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
interface Props { interface Props {
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
} }
export default function MainPanel(props: Props): JSX.Element { export default function MainPanel(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const isDesktop = useMediaDesktop(); const isDesktop = useMediaDesktop();
const appLayout = useAppLayout(); const appLayout = useAppLayout();

View File

@ -1,8 +1,10 @@
import { Immutable } from "helpers/types";
interface Props { interface Props {
children: React.ReactNode; children: React.ReactNode;
} }
export default function SubPanel(props: Props): JSX.Element { export default function SubPanel(props: Immutable<Props>): JSX.Element {
return ( return (
<div className="grid pt-10 pb-20 px-6 desktop:py-8 desktop:px-10 gap-y-2 text-center"> <div className="grid pt-10 pb-20 px-6 desktop:py-8 desktop:px-10 gap-y-2 text-center">
{props.children} {props.children}

View File

@ -1,4 +1,5 @@
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import { Immutable } from "helpers/types";
import { Dispatch, SetStateAction, useEffect } from "react"; import { Dispatch, SetStateAction, useEffect } from "react";
import Hotkeys from "react-hot-keys"; import Hotkeys from "react-hot-keys";
@ -13,7 +14,7 @@ interface Props {
padding?: boolean; padding?: boolean;
} }
export default function Popup(props: Props): JSX.Element { export default function Popup(props: Immutable<Props>): JSX.Element {
const { const {
setState, setState,
state, state,

View File

@ -1,7 +1,7 @@
import { prettySlug } from "helpers/formatters";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettySlug } from "helpers/formatters";
import { getStatusDescription } from "helpers/others"; import { getStatusDescription } from "helpers/others";
import { Post } from "helpers/types"; import { Immutable, PostWithTranslations } from "helpers/types";
import useSmartLanguage from "hooks/useSmartLanguage"; import useSmartLanguage from "hooks/useSmartLanguage";
import AppLayout from "./AppLayout"; import AppLayout from "./AppLayout";
import Chip from "./Chip"; import Chip from "./Chip";
@ -16,7 +16,7 @@ import ThumbnailHeader from "./ThumbnailHeader";
import ToolTip from "./ToolTip"; import ToolTip from "./ToolTip";
interface Props { interface Props {
post: Post; post: PostWithTranslations;
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
languages: AppStaticProps["languages"]; languages: AppStaticProps["languages"];
currencies: AppStaticProps["currencies"]; currencies: AppStaticProps["currencies"];
@ -31,7 +31,7 @@ interface Props {
appendBody?: JSX.Element; appendBody?: JSX.Element;
} }
export default function PostPage(props: Props): JSX.Element { export default function PostPage(props: Immutable<Props>): JSX.Element {
const { const {
post, post,
langui, langui,

View File

@ -4,14 +4,15 @@ import {
PricePickerFragment, PricePickerFragment,
UploadImageFragment, UploadImageFragment,
} from "graphql/generated"; } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { import {
prettyDate, prettyDate,
prettyDuration, prettyDuration,
prettyPrice, prettyPrice,
prettyShortenNumber, prettyShortenNumber,
} from "helpers/formatters"; } from "helpers/formatters";
import { AppStaticProps } from "graphql/getAppStaticProps";
import { ImageQuality } from "helpers/img"; import { ImageQuality } from "helpers/img";
import { Immutable } from "helpers/types";
import Link from "next/link"; import Link from "next/link";
import Chip from "./Chip"; import Chip from "./Chip";
import Img from "./Img"; import Img from "./Img";
@ -43,7 +44,7 @@ interface Props {
| { __typename: "anotherHoverlayName" }; | { __typename: "anotherHoverlayName" };
} }
export default function ThumbnailPreview(props: Props): JSX.Element { export default function ThumbnailPreview(props: Immutable<Props>): JSX.Element {
const { const {
href, href,
thumbnail, thumbnail,

View File

@ -1,5 +1,6 @@
import { UploadImageFragment } from "graphql/generated"; import { UploadImageFragment } from "graphql/generated";
import { ImageQuality } from "helpers/img"; import { ImageQuality } from "helpers/img";
import { Immutable } from "helpers/types";
import Link from "next/link"; import Link from "next/link";
import Chip from "./Chip"; import Chip from "./Chip";
import Img from "./Img"; import Img from "./Img";
@ -15,7 +16,7 @@ interface Props {
bottomChips?: string[]; bottomChips?: string[];
} }
export default function PreviewLine(props: Props): JSX.Element { export default function PreviewLine(props: Immutable<Props>): JSX.Element {
const { const {
href, href,
thumbnail, thumbnail,

View File

@ -2,6 +2,7 @@ import Chip from "components/Chip";
import { RecorderChipFragment } from "graphql/generated"; import { RecorderChipFragment } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { ImageQuality } from "helpers/img"; import { ImageQuality } from "helpers/img";
import { Immutable } from "helpers/types";
import Img from "./Img"; import Img from "./Img";
import Markdawn from "./Markdown/Markdawn"; import Markdawn from "./Markdown/Markdawn";
import ToolTip from "./ToolTip"; import ToolTip from "./ToolTip";
@ -12,7 +13,7 @@ interface Props {
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
} }
export default function RecorderChip(props: Props): JSX.Element { export default function RecorderChip(props: Immutable<Props>): JSX.Element {
const { recorder, langui } = props; const { recorder, langui } = props;
return ( return (
<ToolTip <ToolTip

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import Image from "next/image"; import Image from "next/image";
interface Props { interface Props {
@ -6,7 +7,7 @@ interface Props {
className?: string; className?: string;
} }
export default function SVG(props: Props): JSX.Element { export default function SVG(props: Immutable<Props>): JSX.Element {
return ( return (
<div className={props.className}> <div className={props.className}>
<Image <Image

View File

@ -3,9 +3,10 @@ import Img from "components/Img";
import InsetBox from "components/InsetBox"; import InsetBox from "components/InsetBox";
import Markdawn from "components/Markdown/Markdawn"; import Markdawn from "components/Markdown/Markdawn";
import { GetContentQuery, UploadImageFragment } from "graphql/generated"; import { GetContentQuery, UploadImageFragment } from "graphql/generated";
import { prettyinlineTitle, prettySlug, slugify } from "helpers/formatters";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { prettyinlineTitle, prettySlug, slugify } from "helpers/formatters";
import { ImageQuality } from "helpers/img"; import { ImageQuality } from "helpers/img";
import { Immutable } from "helpers/types";
interface Props { interface Props {
pre_title?: string | null | undefined; pre_title?: string | null | undefined;
@ -31,7 +32,7 @@ interface Props {
languageSwitcher?: JSX.Element; languageSwitcher?: JSX.Element;
} }
export default function ThumbnailHeader(props: Props): JSX.Element { export default function ThumbnailHeader(props: Immutable<Props>): JSX.Element {
const { const {
langui, langui,
pre_title, pre_title,

View File

@ -4,12 +4,12 @@ import "tippy.js/animations/scale-subtle.css";
interface Props extends TippyProps {} interface Props extends TippyProps {}
export default function ToolTip(props: Props): JSX.Element { export default function ToolTip(props: Props): JSX.Element {
const newProps = { ...props }; const newProps: Props = {
delay: [150, 0],
// Set defaults interactive: true,
if (newProps.delay === undefined) newProps.delay = [150, 0]; animation: "scale-subtle",
if (newProps.interactive === undefined) newProps.interactive = true; ...props,
if (newProps.animation === undefined) newProps.animation = "scale-subtle"; };
return ( return (
<Tippy className={`text-[80%] ${newProps.className}`} {...newProps}> <Tippy className={`text-[80%] ${newProps.className}`} {...newProps}>

View File

@ -6,6 +6,7 @@ import {
} from "graphql/generated"; } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { getStatusDescription } from "helpers/others"; import { getStatusDescription } from "helpers/others";
import { Immutable } from "helpers/types";
interface Props { interface Props {
item: Exclude< item: Exclude<
@ -16,7 +17,9 @@ interface Props {
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
} }
export default function ChronologyItemComponent(props: Props): JSX.Element { export default function ChronologyItemComponent(
props: Immutable<Props>
): JSX.Element {
const { langui } = props; const { langui } = props;
function generateAnchor( function generateAnchor(

View File

@ -1,6 +1,7 @@
import ChronologyItemComponent from "components/Wiki/Chronology/ChronologyItemComponent"; import ChronologyItemComponent from "components/Wiki/Chronology/ChronologyItemComponent";
import { GetChronologyItemsQuery } from "graphql/generated"; import { GetChronologyItemsQuery } from "graphql/generated";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
interface Props { interface Props {
year: number; year: number;
@ -11,7 +12,9 @@ interface Props {
langui: AppStaticProps["langui"]; langui: AppStaticProps["langui"];
} }
export default function ChronologyYearComponent(props: Props): JSX.Element { export default function ChronologyYearComponent(
props: Immutable<Props>
): JSX.Element {
const { langui } = props; const { langui } = props;
return ( return (

View File

@ -1,3 +1,4 @@
import { Immutable } from "helpers/types";
import useDarkMode from "hooks/useDarkMode"; import useDarkMode from "hooks/useDarkMode";
import useStateWithLocalStorage from "hooks/useStateWithLocalStorage"; import useStateWithLocalStorage from "hooks/useStateWithLocalStorage";
import React, { ReactNode, useContext, useState } from "react"; import React, { ReactNode, useContext, useState } from "react";
@ -76,7 +77,7 @@ interface Props {
children: ReactNode; children: ReactNode;
} }
export function AppContextProvider(props: Props): JSX.Element { export function AppContextProvider(props: Immutable<Props>): JSX.Element {
const [subPanelOpen, setSubPanelOpen] = useStateWithLocalStorage< const [subPanelOpen, setSubPanelOpen] = useStateWithLocalStorage<
boolean | undefined boolean | undefined
>("subPanelOpen", initialState.subPanelOpen); >("subPanelOpen", initialState.subPanelOpen);

View File

@ -4,9 +4,10 @@ import {
GetWebsiteInterfaceQuery, GetWebsiteInterfaceQuery,
} from "graphql/generated"; } from "graphql/generated";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
export interface AppStaticProps { export type AppStaticProps = Immutable<{
langui: Exclude< langui: Exclude<
Exclude< Exclude<
GetWebsiteInterfaceQuery["websiteInterfaces"], GetWebsiteInterfaceQuery["websiteInterfaces"],
@ -19,7 +20,7 @@ export interface AppStaticProps {
null | undefined null | undefined
>["data"]; >["data"];
languages: Exclude<GetLanguagesQuery["languages"], null | undefined>["data"]; languages: Exclude<GetLanguagesQuery["languages"], null | undefined>["data"];
} }>;
export async function getAppStaticProps( export async function getAppStaticProps(
context: GetStaticPropsContext context: GetStaticPropsContext
@ -50,9 +51,11 @@ export async function getAppStaticProps(
}) })
).websiteInterfaces?.data[0].attributes; ).websiteInterfaces?.data[0].attributes;
return { const appStaticProps: AppStaticProps = {
langui: langui ?? ({} as AppStaticProps["langui"]), langui: langui ?? {},
currencies: currencies?.data ?? ({} as AppStaticProps["currencies"]), currencies: currencies?.data ?? [],
languages: languages?.data ?? ({} as AppStaticProps["languages"]), languages: languages?.data ?? [],
}; };
return appStaticProps;
} }

View File

@ -0,0 +1,32 @@
import { PostWithTranslations } from "helpers/types";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "./getAppStaticProps";
import { getReadySdk } from "./sdk";
export interface PostStaticProps extends AppStaticProps {
post: PostWithTranslations;
}
export function getPostStaticProps(
slug: string
): (
context: GetStaticPropsContext
) => Promise<{ notFound: boolean } | { props: PostStaticProps }> {
return async (context: GetStaticPropsContext) => {
const sdk = getReadySdk();
const post = await sdk.getPost({
slug: slug,
language_code: context.locale ?? "en",
});
if (post.posts?.data[0].attributes?.translations) {
const props: PostStaticProps = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes as PostWithTranslations,
};
return {
props: props,
};
}
return { notFound: true };
};
}

View File

@ -1,8 +1,9 @@
import { DatePickerFragment, PricePickerFragment } from "graphql/generated"; import { DatePickerFragment, PricePickerFragment } from "graphql/generated";
import { AppStaticProps } from "../graphql/getAppStaticProps"; import { AppStaticProps } from "../graphql/getAppStaticProps";
import { convertPrice } from "./numbers"; import { convertPrice } from "./numbers";
import { Immutable } from "./types";
export function prettyDate(datePicker: DatePickerFragment): string { export function prettyDate(datePicker: Immutable<DatePickerFragment>): string {
let result = ""; let result = "";
if (datePicker.year) result += datePicker.year.toString(); if (datePicker.year) result += datePicker.year.toString();
if (datePicker.month) if (datePicker.month)
@ -13,7 +14,7 @@ export function prettyDate(datePicker: DatePickerFragment): string {
} }
export function prettyPrice( export function prettyPrice(
pricePicker: PricePickerFragment, pricePicker: Immutable<PricePickerFragment>,
currencies: AppStaticProps["currencies"], currencies: AppStaticProps["currencies"],
targetCurrencyCode?: string targetCurrencyCode?: string
): string { ): string {
@ -57,7 +58,7 @@ export function prettyinlineTitle(
} }
export function prettyItemType( export function prettyItemType(
metadata: any, metadata: Immutable<any>,
langui: AppStaticProps["langui"] langui: AppStaticProps["langui"]
): string | undefined | null { ): string | undefined | null {
switch (metadata.__typename) { switch (metadata.__typename) {
@ -79,7 +80,7 @@ export function prettyItemType(
} }
export function prettyItemSubType( export function prettyItemSubType(
metadata: metadata: Immutable<
| { | {
__typename: "ComponentMetadataAudio"; __typename: "ComponentMetadataAudio";
subtype?: { subtype?: {
@ -156,6 +157,7 @@ export function prettyItemSubType(
} }
| { __typename: "Error" } | { __typename: "Error" }
| null | null
>
): string { ): string {
if (metadata) { if (metadata) {
switch (metadata.__typename) { switch (metadata.__typename) {

View File

@ -1,4 +1,5 @@
import { UploadImageFragment } from "graphql/generated"; import { UploadImageFragment } from "graphql/generated";
import { Immutable } from "./types";
export enum ImageQuality { export enum ImageQuality {
Small = "small", Small = "small",
@ -24,7 +25,10 @@ export function getAssetFilename(path: string): string {
return result[0]; return result[0];
} }
export function getAssetURL(url: string, quality: ImageQuality): string { export function getAssetURL(
url: string,
quality: Immutable<ImageQuality>
): string {
let newUrl = url; let newUrl = url;
newUrl = newUrl.replace(/^\/uploads/u, `/${quality}`); newUrl = newUrl.replace(/^\/uploads/u, `/${quality}`);
newUrl = newUrl.replace(/.jpg$/u, ".webp"); newUrl = newUrl.replace(/.jpg$/u, ".webp");
@ -67,8 +71,8 @@ export function getImgSizesByQuality(
} }
export function getOgImage( export function getOgImage(
quality: ImageQuality, quality: Immutable<ImageQuality>,
image: UploadImageFragment image: Immutable<UploadImageFragment>
): OgImage { ): OgImage {
const imgSize = getImgSizesByQuality( const imgSize = getImgSizesByQuality(
image.width ?? 0, image.width ?? 0,

View File

@ -1,11 +1,11 @@
import { GetCurrenciesQuery, PricePickerFragment } from "graphql/generated"; import { GetCurrenciesQuery, PricePickerFragment } from "graphql/generated";
import { Immutable } from "./types";
export function convertPrice( export function convertPrice(
pricePicker: PricePickerFragment, pricePicker: Immutable<PricePickerFragment>,
targetCurrency: Exclude< targetCurrency: Immutable<
GetCurrenciesQuery["currencies"], Exclude<GetCurrenciesQuery["currencies"], null | undefined>["data"][number]
null | undefined >
>["data"][number]
): number { ): number {
if ( if (
pricePicker.amount && pricePicker.amount &&

View File

@ -4,36 +4,42 @@ import {
GetLibraryItemScansQuery, GetLibraryItemScansQuery,
} from "graphql/generated"; } from "graphql/generated";
import { AppStaticProps } from "../graphql/getAppStaticProps"; import { AppStaticProps } from "../graphql/getAppStaticProps";
import { Immutable } from "./types";
export function sortContent( type SortContentProps =
contents: | Exclude<
| Exclude< Exclude<
Exclude< GetLibraryItemQuery["libraryItems"],
GetLibraryItemQuery["libraryItems"],
null | undefined
>["data"][number]["attributes"],
null | undefined null | undefined
>["contents"] >["data"][number]["attributes"],
| Exclude< null | undefined
Exclude< >["contents"]
GetLibraryItemScansQuery["libraryItems"], | Exclude<
null | undefined Exclude<
>["data"][number]["attributes"], GetLibraryItemScansQuery["libraryItems"],
null | undefined null | undefined
>["contents"] >["data"][number]["attributes"],
) { null | undefined
contents?.data.sort((a, b) => { >["contents"];
if (
a.attributes?.range[0]?.__typename === "ComponentRangePageRange" && export function sortContent(contents: Immutable<SortContentProps>) {
b.attributes?.range[0]?.__typename === "ComponentRangePageRange" if (contents) {
) { const newContent = { ...contents } as SortContentProps;
return ( newContent?.data.sort((a, b) => {
a.attributes.range[0].starting_page - if (
b.attributes.range[0].starting_page a.attributes?.range[0]?.__typename === "ComponentRangePageRange" &&
); b.attributes?.range[0]?.__typename === "ComponentRangePageRange"
} ) {
return 0; return (
}); a.attributes.range[0].starting_page -
b.attributes.range[0].starting_page
);
}
return 0;
});
return newContent as Immutable<SortContentProps>;
}
return contents;
} }
export function getStatusDescription( export function getStatusDescription(

View File

@ -1,9 +1,22 @@
import { GetPostQuery } from "graphql/generated"; import { GetPostQuery } from "graphql/generated";
import React from "react";
export type Post = Exclude< type Post = Exclude<
Exclude< Exclude<
GetPostQuery["posts"], GetPostQuery["posts"],
null | undefined null | undefined
>["data"][number]["attributes"], >["data"][number]["attributes"],
null | undefined null | undefined
>; >;
export interface PostWithTranslations extends Omit<Post, "translations"> {
translations: Exclude<Post["translations"], null | undefined>;
}
type ImmutableBlackList<T> = JSX.Element | React.ReactNode | Function;
export type Immutable<T> = {
readonly [K in keyof T]: T[K] extends ImmutableBlackList<T>
? T[K]
: Immutable<T[K]>;
};

View File

@ -1,14 +1,15 @@
import LanguageSwitcher from "components/Inputs/LanguageSwitcher"; import LanguageSwitcher from "components/Inputs/LanguageSwitcher";
import { useAppLayout } from "contexts/AppLayoutContext"; import { useAppLayout } from "contexts/AppLayoutContext";
import { AppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
interface Props<T> { interface Props<T> {
items: T[]; items: Immutable<T[]>;
languages: AppStaticProps["languages"]; languages: AppStaticProps["languages"];
languageExtractor: (item: T) => string | undefined; languageExtractor: (item: Immutable<T>) => string | undefined;
transform?: (item: T) => T; transform?: (item: Immutable<T>) => Immutable<T>;
} }
function getPreferredLanguage( function getPreferredLanguage(
@ -25,7 +26,7 @@ function getPreferredLanguage(
export default function useSmartLanguage<T>( export default function useSmartLanguage<T>(
props: Props<T> props: Props<T>
): [T | undefined, () => JSX.Element] { ): [Immutable<T | undefined>, () => JSX.Element] {
const { const {
items, items,
languageExtractor, languageExtractor,
@ -39,7 +40,8 @@ export default function useSmartLanguage<T>(
const [selectedTranslationIndex, setSelectedTranslationIndex] = useState< const [selectedTranslationIndex, setSelectedTranslationIndex] = useState<
number | undefined number | undefined
>(); >();
const [selectedTranslation, setSelectedTranslation] = useState<T>(); const [selectedTranslation, setSelectedTranslation] =
useState<Immutable<T>>();
useEffect(() => { useEffect(() => {
items.map((elem, index) => { items.map((elem, index) => {
@ -58,8 +60,9 @@ export default function useSmartLanguage<T>(
}, [appLayout.preferredLanguages, availableLocales, router.locale]); }, [appLayout.preferredLanguages, availableLocales, router.locale]);
useEffect(() => { useEffect(() => {
if (selectedTranslationIndex !== undefined) if (selectedTranslationIndex !== undefined) {
setSelectedTranslation(transform(items[selectedTranslationIndex])); setSelectedTranslation(transform(items[selectedTranslationIndex]));
}
}, [items, selectedTranslationIndex, transform]); }, [items, selectedTranslationIndex, transform]);
return [ return [

View File

@ -3,12 +3,13 @@ import ReturnButton, {
ReturnButtonType, ReturnButtonType,
} from "components/PanelComponents/ReturnButton"; } from "components/PanelComponents/ReturnButton";
import ContentPanel from "components/Panels/ContentPanel"; import ContentPanel from "components/Panels/ContentPanel";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function FourOhFour(props: Props): JSX.Element { export default function FourOhFour(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const contentPanel = ( const contentPanel = (
<ContentPanel> <ContentPanel>

View File

@ -3,12 +3,13 @@ import ReturnButton, {
ReturnButtonType, ReturnButtonType,
} from "components/PanelComponents/ReturnButton"; } from "components/PanelComponents/ReturnButton";
import ContentPanel from "components/Panels/ContentPanel"; import ContentPanel from "components/Panels/ContentPanel";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function FiveHundred(props: Props): JSX.Element { export default function FiveHundred(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const contentPanel = ( const contentPanel = (
<ContentPanel> <ContentPanel>

View File

@ -1,14 +1,13 @@
import PostPage from "components/PostPage"; import PostPage from "components/PostPage";
import { getReadySdk } from "graphql/sdk"; import {
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; getPostStaticProps,
import { Post } from "helpers/types"; PostStaticProps,
import { GetStaticPropsContext } from "next"; } from "graphql/getPostStaticProps";
import { Immutable } from "helpers/types";
interface Props extends AppStaticProps { export default function AccordsHandbook(
post: Post; props: Immutable<PostStaticProps>
} ): JSX.Element {
export default function AccordsHandbook(props: Props): JSX.Element {
const { post, langui, languages, currencies } = props; const { post, langui, languages, currencies } = props;
return ( return (
<PostPage <PostPage
@ -24,21 +23,4 @@ export default function AccordsHandbook(props: Props): JSX.Element {
); );
} }
export async function getStaticProps( export const getStaticProps = getPostStaticProps("accords-handbook");
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const slug = "accords-handbook";
const post = await sdk.getPost({
slug: slug,
language_code: context.locale ?? "en",
});
if (!post.posts?.data[0].attributes) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes,
};
return {
props: props,
};
}

View File

@ -1,19 +1,18 @@
import InsetBox from "components/InsetBox"; import InsetBox from "components/InsetBox";
import PostPage from "components/PostPage"; import PostPage from "components/PostPage";
import { randomInt } from "crypto"; import {
import { getReadySdk } from "graphql/sdk"; getPostStaticProps,
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; PostStaticProps,
import { Post } from "helpers/types"; } from "graphql/getPostStaticProps";
import { GetStaticPropsContext } from "next"; import { randomInt } from "helpers/numbers";
import { Immutable } from "helpers/types";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { RequestMailProps, ResponseMailProps } from "pages/api/mail"; import { RequestMailProps, ResponseMailProps } from "pages/api/mail";
import { useState } from "react"; import { useState } from "react";
interface Props extends AppStaticProps { export default function AboutUs(
post: Post; props: Immutable<PostStaticProps>
} ): JSX.Element {
export default function AboutUs(props: Props): JSX.Element {
const { post, langui, languages, currencies } = props; const { post, langui, languages, currencies } = props;
const router = useRouter(); const router = useRouter();
@ -182,21 +181,4 @@ export default function AboutUs(props: Props): JSX.Element {
); );
} }
export async function getStaticProps( export const getStaticProps = getPostStaticProps("contact");
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const slug = "contact";
const post = await sdk.getPost({
slug: slug,
language_code: context.locale ?? "en",
});
if (!post.posts?.data[0].attributes) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes,
};
return {
props: props,
};
}

View File

@ -2,12 +2,13 @@ import AppLayout from "components/AppLayout";
import NavOption from "components/PanelComponents/NavOption"; import NavOption from "components/PanelComponents/NavOption";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function AboutUs(props: Props): JSX.Element { export default function AboutUs(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>

View File

@ -1,14 +1,10 @@
import PostPage from "components/PostPage"; import PostPage from "components/PostPage";
import { getReadySdk } from "graphql/sdk"; import {
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; getPostStaticProps,
import { Post } from "helpers/types"; PostStaticProps,
import { GetStaticPropsContext } from "next"; } from "graphql/getPostStaticProps";
interface Props extends AppStaticProps { export default function Legality(props: PostStaticProps): JSX.Element {
post: Post;
}
export default function SiteInformation(props: Props): JSX.Element {
const { post, langui, languages, currencies } = props; const { post, langui, languages, currencies } = props;
return ( return (
<PostPage <PostPage
@ -24,21 +20,4 @@ export default function SiteInformation(props: Props): JSX.Element {
); );
} }
export async function getStaticProps( export const getStaticProps = getPostStaticProps("legality");
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const slug = "legality";
const post = await sdk.getPost({
slug: slug,
language_code: context.locale ?? "en",
});
if (!post.posts?.data[0].attributes) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes,
};
return {
props: props,
};
}

View File

@ -1,13 +1,10 @@
import PostPage from "components/PostPage"; import PostPage from "components/PostPage";
import { getReadySdk } from "graphql/sdk"; import {
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; getPostStaticProps,
import { Post } from "helpers/types"; PostStaticProps,
import { GetStaticPropsContext } from "next"; } from "graphql/getPostStaticProps";
interface Props extends AppStaticProps { export default function SharingPolicy(props: PostStaticProps): JSX.Element {
post: Post;
}
export default function SharingPolicy(props: Props): JSX.Element {
const { post, langui, languages, currencies } = props; const { post, langui, languages, currencies } = props;
return ( return (
<PostPage <PostPage
@ -23,21 +20,4 @@ export default function SharingPolicy(props: Props): JSX.Element {
); );
} }
export async function getStaticProps( export const getStaticProps = getPostStaticProps("sharing-policy");
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const slug = "sharing-policy";
const post = await sdk.getPost({
slug: slug,
language_code: context.locale ?? "en",
});
if (!post.posts?.data[0].attributes) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes,
};
return {
props: props,
};
}

View File

@ -2,12 +2,13 @@ import AppLayout from "components/AppLayout";
import NavOption from "components/PanelComponents/NavOption"; import NavOption from "components/PanelComponents/NavOption";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function Archives(props: Props): JSX.Element { export default function Archives(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>

View File

@ -3,10 +3,11 @@ import PanelHeader from "components/PanelComponents/PanelHeader";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function Chronicles(props: Props): JSX.Element { export default function Chronicles(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>

View File

@ -13,14 +13,15 @@ import RecorderChip from "components/RecorderChip";
import ThumbnailHeader from "components/ThumbnailHeader"; import ThumbnailHeader from "components/ThumbnailHeader";
import ToolTip from "components/ToolTip"; import ToolTip from "components/ToolTip";
import { GetContentTextQuery } from "graphql/generated"; import { GetContentTextQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { import {
prettyinlineTitle, prettyinlineTitle,
prettyLanguage, prettyLanguage,
prettySlug, prettySlug,
} from "helpers/formatters"; } from "helpers/formatters";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getStatusDescription } from "helpers/others"; import { getStatusDescription } from "helpers/others";
import { Immutable } from "helpers/types";
import { useMediaMobile } from "hooks/useMediaQuery"; import { useMediaMobile } from "hooks/useMediaQuery";
import useSmartLanguage from "hooks/useSmartLanguage"; import useSmartLanguage from "hooks/useSmartLanguage";
import { import {
@ -40,7 +41,7 @@ interface Props extends AppStaticProps {
>["data"][number]["id"]; >["data"][number]["id"];
} }
export default function Content(props: Props): JSX.Element { export default function Content(props: Immutable<Props>): JSX.Element {
const { langui, content, languages } = props; const { langui, content, languages } = props;
const isMobile = useMediaMobile(); const isMobile = useMediaMobile();

View File

@ -9,19 +9,20 @@ import ContentPanel, {
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import ThumbnailPreview from "components/PreviewCard"; import ThumbnailPreview from "components/PreviewCard";
import { GetContentsQuery } from "graphql/generated"; import { GetContentsQuery } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { prettyinlineTitle, prettySlug } from "helpers/formatters";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { prettySlug, prettyinlineTitle } from "helpers/formatters";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
contents: Exclude<GetContentsQuery["contents"], null | undefined>["data"]; contents: Exclude<GetContentsQuery["contents"], null | undefined>["data"];
} }
type GroupContentItems = Map<string, Props["contents"]>; type GroupContentItems = Map<string, Immutable<Props["contents"]>>;
export default function Contents(props: Props): JSX.Element { export default function Contents(props: Immutable<Props>): JSX.Element {
const { langui, contents } = props; const { langui, contents } = props;
const [groupingMethod, setGroupingMethod] = useState<number>(-1); const [groupingMethod, setGroupingMethod] = useState<number>(-1);
@ -172,7 +173,7 @@ export async function getStaticProps(
function getGroups( function getGroups(
langui: AppStaticProps["langui"], langui: AppStaticProps["langui"],
groupByType: number, groupByType: number,
items: Props["contents"] items: Immutable<Props["contents"]>
): GroupContentItems { ): GroupContentItems {
switch (groupByType) { switch (groupByType) {
case 0: { case 0: {
@ -209,7 +210,7 @@ function getGroups(
} }
case 1: { case 1: {
const group: GroupContentItems = new Map(); const group = new Map();
items.map((item) => { items.map((item) => {
const type = const type =
item.attributes?.type?.data?.attributes?.titles?.[0]?.title ?? item.attributes?.type?.data?.attributes?.titles?.[0]?.title ??

View File

@ -9,15 +9,16 @@ import {
DevGetContentsQuery, DevGetContentsQuery,
Enum_Componentsetstextset_Status, Enum_Componentsetstextset_Status,
} from "graphql/generated"; } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
contents: DevGetContentsQuery; contents: DevGetContentsQuery;
} }
export default function CheckupContents(props: Props): JSX.Element { export default function CheckupContents(props: Immutable<Props>): JSX.Element {
const { contents } = props; const { contents } = props;
const testReport = testingContent(contents); const testReport = testingContent(contents);
@ -112,7 +113,7 @@ type ReportLine = {
frontendUrl: string; frontendUrl: string;
}; };
function testingContent(contents: Props["contents"]): Report { function testingContent(contents: Immutable<Props["contents"]>): Report {
const report: Report = { const report: Report = {
title: "Contents", title: "Contents",
lines: [], lines: [],

View File

@ -9,15 +9,18 @@ import {
DevGetLibraryItemsQuery, DevGetLibraryItemsQuery,
Enum_Componentcollectionscomponentlibraryimages_Status, Enum_Componentcollectionscomponentlibraryimages_Status,
} from "graphql/generated"; } from "graphql/generated";
import { getReadySdk } from "graphql/sdk";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
libraryItems: DevGetLibraryItemsQuery; libraryItems: DevGetLibraryItemsQuery;
} }
export default function CheckupLibraryItems(props: Props): JSX.Element { export default function CheckupLibraryItems(
props: Immutable<Props>
): JSX.Element {
const { libraryItems } = props; const { libraryItems } = props;
const testReport = testingLibraryItem(libraryItems); const testReport = testingLibraryItem(libraryItems);
@ -113,7 +116,9 @@ type ReportLine = {
}; };
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
function testingLibraryItem(libraryItems: Props["libraryItems"]): Report { function testingLibraryItem(
libraryItems: Immutable<Props["libraryItems"]>
): Report {
const report: Report = { const report: Report = {
title: "Contents", title: "Contents",
lines: [], lines: [],

View File

@ -6,14 +6,15 @@ import ContentPanel, {
} from "components/Panels/ContentPanel"; } from "components/Panels/ContentPanel";
import Popup from "components/Popup"; import Popup from "components/Popup";
import ToolTip from "components/ToolTip"; import ToolTip from "components/ToolTip";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import TurndownService from "turndown"; import TurndownService from "turndown";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function Editor(props: Props): JSX.Element { export default function Editor(props: Immutable<Props>): JSX.Element {
const handleInput = useCallback((text: string) => { const handleInput = useCallback((text: string) => {
setMarkdown(text); setMarkdown(text);
}, []); }, []);

View File

@ -1,10 +1,11 @@
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function Gallery(props: Props): JSX.Element { export default function Gallery(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const contentPanel = ( const contentPanel = (
<iframe <iframe

View File

@ -1,14 +1,11 @@
import PostPage from "components/PostPage"; import PostPage from "components/PostPage";
import { getReadySdk } from "graphql/sdk"; import {
import { GetStaticPropsContext } from "next"; getPostStaticProps,
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; PostStaticProps,
import { Post } from "helpers/types"; } from "graphql/getPostStaticProps";
import { Immutable } from "helpers/types";
interface Props extends AppStaticProps { export default function Home(props: Immutable<PostStaticProps>): JSX.Element {
post: Post;
}
export default function Home(props: Props): JSX.Element {
const { post, langui, languages, currencies } = props; const { post, langui, languages, currencies } = props;
return ( return (
<PostPage <PostPage
@ -31,21 +28,4 @@ export default function Home(props: Props): JSX.Element {
); );
} }
export async function getStaticProps( export const getStaticProps = getPostStaticProps("home");
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const slug = "home";
const post = await sdk.getPost({
slug: slug,
language_code: context.locale ?? "en",
});
if (!post.posts?.data[0].attributes) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes,
};
return {
props: props,
};
}

View File

@ -21,6 +21,7 @@ import {
Enum_Componentmetadatabooks_Page_Order, Enum_Componentmetadatabooks_Page_Order,
GetLibraryItemQuery, GetLibraryItemQuery,
} from "graphql/generated"; } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { import {
prettyDate, prettyDate,
@ -30,10 +31,10 @@ import {
prettyPrice, prettyPrice,
prettyURL, prettyURL,
} from "helpers/formatters"; } from "helpers/formatters";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { sortContent } from "helpers/others";
import { getAssetURL, ImageQuality } from "helpers/img"; import { getAssetURL, ImageQuality } from "helpers/img";
import { convertMmToInch } from "helpers/numbers"; import { convertMmToInch } from "helpers/numbers";
import { sortContent } from "helpers/others";
import { Immutable } from "helpers/types";
import { import {
GetStaticPathsContext, GetStaticPathsContext,
GetStaticPathsResult, GetStaticPathsResult,
@ -52,7 +53,7 @@ interface Props extends AppStaticProps {
>["data"][number]["id"]; >["data"][number]["id"];
} }
export default function LibrarySlug(props: Props): JSX.Element { export default function LibrarySlug(props: Immutable<Props>): JSX.Element {
const { item, langui, currencies } = props; const { item, langui, currencies } = props;
const appLayout = useAppLayout(); const appLayout = useAppLayout();

View File

@ -22,6 +22,7 @@ import {
GetStaticPropsContext, GetStaticPropsContext,
} from "next"; } from "next";
import { useState } from "react"; import { useState } from "react";
import { Immutable } from "helpers/types";
interface Props extends AppStaticProps { interface Props extends AppStaticProps {
item: Exclude< item: Exclude<
@ -34,7 +35,7 @@ interface Props extends AppStaticProps {
>["data"][number]["id"]; >["data"][number]["id"];
} }
export default function LibrarySlug(props: Props): JSX.Element { export default function LibrarySlug(props: Immutable<Props>): JSX.Element {
const { item, langui, languages } = props; const { item, langui, languages } = props;
const appLayout = useAppLayout(); const appLayout = useAppLayout();

View File

@ -9,14 +9,15 @@ import ContentPanel, {
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import ThumbnailPreview from "components/PreviewCard"; import ThumbnailPreview from "components/PreviewCard";
import { GetLibraryItemsPreviewQuery } from "graphql/generated"; import { GetLibraryItemsPreviewQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { import {
prettyDate, prettyDate,
prettyinlineTitle, prettyinlineTitle,
prettyItemSubType, prettyItemSubType,
} from "helpers/formatters"; } from "helpers/formatters";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { convertPrice } from "helpers/numbers"; import { convertPrice } from "helpers/numbers";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@ -27,9 +28,9 @@ interface Props extends AppStaticProps {
>["data"]; >["data"];
} }
type GroupLibraryItems = Map<string, Props["items"]>; type GroupLibraryItems = Map<string, Immutable<Props["items"]>>;
export default function Library(props: Props): JSX.Element { export default function Library(props: Immutable<Props>): JSX.Element {
const { langui, items: libraryItems, currencies } = props; const { langui, items: libraryItems, currencies } = props;
const [showSubitems, setShowSubitems] = useState<boolean>(false); const [showSubitems, setShowSubitems] = useState<boolean>(false);
@ -39,7 +40,7 @@ export default function Library(props: Props): JSX.Element {
const [groupingMethod, setGroupingMethod] = useState<number>(-1); const [groupingMethod, setGroupingMethod] = useState<number>(-1);
const [keepInfoVisible, setKeepInfoVisible] = useState(false); const [keepInfoVisible, setKeepInfoVisible] = useState(false);
const [filteredItems, setFilteredItems] = useState<Props["items"]>( const [filteredItems, setFilteredItems] = useState(
filterItems( filterItems(
showSubitems, showSubitems,
showPrimaryItems, showPrimaryItems,
@ -48,11 +49,11 @@ export default function Library(props: Props): JSX.Element {
) )
); );
const [sortedItems, setSortedItem] = useState<Props["items"]>( const [sortedItems, setSortedItem] = useState(
sortBy(groupingMethod, filteredItems, currencies) sortBy(groupingMethod, filteredItems, currencies)
); );
const [groups, setGroups] = useState<GroupLibraryItems>( const [groups, setGroups] = useState(
getGroups(langui, groupingMethod, sortedItems) getGroups(langui, groupingMethod, sortedItems)
); );
@ -224,7 +225,7 @@ export async function getStaticProps(
function getGroups( function getGroups(
langui: AppStaticProps["langui"], langui: AppStaticProps["langui"],
groupByType: number, groupByType: number,
items: Props["items"] items: Immutable<Props["items"]>
): GroupLibraryItems { ): GroupLibraryItems {
switch (groupByType) { switch (groupByType) {
case 0: { case 0: {
@ -262,7 +263,7 @@ function getGroups(
} }
case 1: { case 1: {
const group: GroupLibraryItems = new Map(); const group = new Map();
group.set(langui.audio ?? "Audio", []); group.set(langui.audio ?? "Audio", []);
group.set(langui.game ?? "Game", []); group.set(langui.game ?? "Game", []);
group.set(langui.textual ?? "Textual", []); group.set(langui.textual ?? "Textual", []);
@ -334,7 +335,7 @@ function getGroups(
years.push(item.attributes.release_date.year); years.push(item.attributes.release_date.year);
} }
}); });
const group: GroupLibraryItems = new Map(); const group = new Map();
years.sort((a, b) => a - b); years.sort((a, b) => a - b);
years.map((year) => { years.map((year) => {
group.set(year.toString(), []); group.set(year.toString(), []);
@ -352,7 +353,7 @@ function getGroups(
} }
default: { default: {
const group: GroupLibraryItems = new Map(); const group = new Map();
group.set("", items); group.set("", items);
return group; return group;
} }
@ -363,9 +364,10 @@ function filterItems(
showSubitems: boolean, showSubitems: boolean,
showPrimaryItems: boolean, showPrimaryItems: boolean,
showSecondaryItems: boolean, showSecondaryItems: boolean,
items: Props["items"] items: Immutable<Props["items"]>
): Props["items"] { ): Immutable<Props["items"]> {
return [...items].filter((item) => { const fileredItems = [...items] as Props["items"];
fileredItems.filter((item) => {
if (!showSubitems && !item.attributes?.root_item) return false; if (!showSubitems && !item.attributes?.root_item) return false;
if ( if (
showSubitems && showSubitems &&
@ -380,13 +382,14 @@ function filterItems(
if (!item.attributes?.primary && !showSecondaryItems) return false; if (!item.attributes?.primary && !showSecondaryItems) return false;
return true; return true;
}); });
return fileredItems as Immutable<Props["items"]>;
} }
function sortBy( function sortBy(
orderByType: number, orderByType: number,
items: Props["items"], items: Immutable<Props["items"]>,
currencies: AppStaticProps["currencies"] currencies: AppStaticProps["currencies"]
): Props["items"] { ): Immutable<Props["items"]> {
switch (orderByType) { switch (orderByType) {
case 0: case 0:
return [...items].sort((a, b) => { return [...items].sort((a, b) => {

View File

@ -1,11 +1,12 @@
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function Merch(props: Props): JSX.Element { export default function Merch(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>

View File

@ -1,23 +1,20 @@
import PostPage from "components/PostPage"; import PostPage from "components/PostPage";
import { GetPostQuery } from "graphql/generated"; import { AppStaticProps } from "graphql/getAppStaticProps";
import {
getPostStaticProps,
PostStaticProps,
} from "graphql/getPostStaticProps";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { Immutable } from "helpers/types";
import { Post } from "helpers/types";
import { import {
GetStaticPathsContext, GetStaticPathsContext,
GetStaticPathsResult, GetStaticPathsResult,
GetStaticPropsContext, GetStaticPropsContext,
} from "next"; } from "next";
interface Props extends AppStaticProps { interface Props extends AppStaticProps, PostStaticProps {}
post: Post;
postId: Exclude<
GetPostQuery["posts"],
null | undefined
>["data"][number]["id"];
}
export default function LibrarySlug(props: Props): JSX.Element { export default function LibrarySlug(props: Immutable<Props>): JSX.Element {
const { post, langui, languages, currencies } = props; const { post, langui, languages, currencies } = props;
return ( return (
<PostPage <PostPage
@ -37,21 +34,8 @@ export default function LibrarySlug(props: Props): JSX.Element {
export async function getStaticProps( export async function getStaticProps(
context: GetStaticPropsContext context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> { ): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const slug = context.params?.slug ? context.params.slug.toString() : ""; const slug = context.params?.slug ? context.params.slug.toString() : "";
const post = await sdk.getPost({ return await getPostStaticProps(slug)(context);
slug: slug,
language_code: context.locale ?? "en",
});
if (!post.posts?.data[0].attributes) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
post: post.posts.data[0].attributes,
postId: post.posts.data[0].id,
};
return {
props: props,
};
} }
export async function getStaticPaths( export async function getStaticPaths(

View File

@ -7,9 +7,10 @@ import ContentPanel, {
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import ThumbnailPreview from "components/PreviewCard"; import ThumbnailPreview from "components/PreviewCard";
import { GetPostsPreviewQuery } from "graphql/generated"; import { GetPostsPreviewQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk"; import { getReadySdk } from "graphql/sdk";
import { prettyDate, prettySlug } from "helpers/formatters"; import { prettyDate, prettySlug } from "helpers/formatters";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next"; import { GetStaticPropsContext } from "next";
import { useState } from "react"; import { useState } from "react";
@ -17,19 +18,12 @@ interface Props extends AppStaticProps {
posts: Exclude<GetPostsPreviewQuery["posts"], null | undefined>["data"]; posts: Exclude<GetPostsPreviewQuery["posts"], null | undefined>["data"];
} }
export default function News(props: Props): JSX.Element { export default function News(props: Immutable<Props>): JSX.Element {
const { langui, posts } = props; const { langui } = props;
const posts = sortPosts(props.posts);
const [keepInfoVisible, setKeepInfoVisible] = useState(true); const [keepInfoVisible, setKeepInfoVisible] = useState(true);
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();
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
@ -103,3 +97,17 @@ export async function getStaticProps(
props: props, props: props,
}; };
} }
function sortPosts(
posts: Immutable<Props["posts"]>
): Immutable<Props["posts"]> {
const sortedPosts = [...posts] as Props["posts"];
sortedPosts
.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 as Immutable<Props["posts"]>;
}

View File

@ -2,12 +2,13 @@ import AppLayout from "components/AppLayout";
import NavOption from "components/PanelComponents/NavOption"; import NavOption from "components/PanelComponents/NavOption";
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import { GetStaticPropsContext } from "next";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { Immutable } from "helpers/types";
import { GetStaticPropsContext } from "next";
interface Props extends AppStaticProps {} interface Props extends AppStaticProps {}
export default function Wiki(props: Props): JSX.Element { export default function Wiki(props: Immutable<Props>): JSX.Element {
const { langui } = props; const { langui } = props;
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>