2022-06-18 21:53:23 +02:00

184 lines
5.7 KiB
TypeScript

import { AppLayout } from "components/AppLayout";
import { NavOption } from "components/PanelComponents/NavOption";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
import { SubPanel } from "components/Panels/SubPanel";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { GetStaticPropsContext } from "next";
import { Icon } from "components/Ico";
import { getReadySdk } from "graphql/sdk";
import { GetWikiPagesPreviewsQuery } from "graphql/generated";
import {
ContentPanel,
ContentPanelWidthSizes,
} from "components/Panels/ContentPanel";
import { Fragment, useMemo, useState } from "react";
import { TranslatedPreviewCard } from "components/PreviewCard";
import { HorizontalLine } from "components/HorizontalLine";
import { Button } from "components/Inputs/Button";
import { Switch } from "components/Inputs/Switch";
import { TextInput } from "components/Inputs/TextInput";
import { WithLabel } from "components/Inputs/WithLabel";
import { useMediaHoverable } from "hooks/useMediaQuery";
import { filterHasAttributes } from "helpers/others";
import { ContentPlaceholder } from "components/PanelComponents/ContentPlaceholder";
interface Props extends AppStaticProps {
pages: NonNullable<GetWikiPagesPreviewsQuery["wikiPages"]>["data"];
}
const defaultFiltersState = {
searchName: "",
keepInfoVisible: true,
};
export default function Wiki(props: Props): JSX.Element {
const { langui, languages } = props;
const pages = sortPages(props.pages);
const hoverable = useMediaHoverable();
const [searchName, setSearchName] = useState(defaultFiltersState.searchName);
const [keepInfoVisible, setKeepInfoVisible] = useState(
defaultFiltersState.keepInfoVisible
);
const filteredPages = useMemo(
() => filterPages(pages, searchName),
[pages, searchName]
);
const subPanel = (
<SubPanel>
<PanelHeader
icon={Icon.TravelExplore}
title={langui.wiki}
description={langui.wiki_description}
/>
<TextInput
className="mb-6 w-full"
placeholder={langui.search_title ?? undefined}
state={searchName}
setState={setSearchName}
/>
{hoverable && (
<WithLabel
label={langui.always_show_info}
input={
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
}
/>
)}
<Button
className="mt-8"
text={langui.reset_all_filters}
icon={Icon.Replay}
onClick={() => {
setSearchName(defaultFiltersState.searchName);
setKeepInfoVisible(defaultFiltersState.keepInfoVisible);
}}
/>
<HorizontalLine />
{/* TODO: Langui */}
<p className="mb-4 font-headers text-xl">Special Pages</p>
<NavOption title={langui.chronology} url="/wiki/chronology" border />
</SubPanel>
);
const contentPanel = (
<ContentPanel width={ContentPanelWidthSizes.Full}>
<div
className="grid grid-cols-2 items-end gap-8
desktop:grid-cols-[repeat(auto-fill,_minmax(20rem,1fr))] mobile:gap-4"
>
{/* TODO: Add to langui */}
{filteredPages.length === 0 && (
<ContentPlaceholder
message={
"No results. You can try changing or resetting the search parameters."
}
icon={Icon.ChevronLeft}
/>
)}
{filterHasAttributes(filteredPages).map((page) => (
<Fragment key={page.id}>
<TranslatedPreviewCard
href={`/wiki/${page.attributes.slug}`}
translations={page.attributes.translations?.map(
(translation) => ({
title: translation?.title,
description: translation?.summary,
language: translation?.language?.data?.attributes?.code,
})
)}
thumbnail={page.attributes.thumbnail?.data?.attributes}
thumbnailAspectRatio={"4/3"}
thumbnailRounded
thumbnailForceAspectRatio
languages={languages}
slug={page.attributes.slug}
keepInfoVisible={keepInfoVisible}
bottomChips={page.attributes.categories?.data.map(
(category) => category.attributes?.short ?? ""
)}
/>
</Fragment>
))}
</div>
</ContentPanel>
);
return (
<AppLayout
navTitle={langui.wiki}
subPanel={subPanel}
contentPanel={contentPanel}
subPanelIcon={Icon.Search}
{...props}
/>
);
}
export async function getStaticProps(
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const pages = await sdk.getWikiPagesPreviews({});
if (!pages.wikiPages?.data) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
pages: pages.wikiPages.data,
};
return {
props: props,
};
}
function sortPages(pages: Props["pages"]): Props["pages"] {
return pages.sort((a, b) => {
const slugA = a.attributes?.slug ?? "";
const slugB = b.attributes?.slug ?? "";
return slugA.localeCompare(slugB);
});
}
function filterPages(posts: Props["pages"], searchName: string) {
return posts.filter((post) => {
if (searchName.length > 1) {
if (
post.attributes?.translations?.[0]?.title
.toLowerCase()
.includes(searchName.toLowerCase()) === true
) {
return true;
}
return false;
}
return true;
});
}