2022-05-17 23:16:22 +02:00

147 lines
4.5 KiB
TypeScript

import { AppLayout } from "components/AppLayout";
import { PageSelector } from "components/Inputs/PageSelector";
import { Switch } from "components/Inputs/Switch";
import { PanelHeader } from "components/PanelComponents/PanelHeader";
import {
ReturnButton,
ReturnButtonType,
} from "components/PanelComponents/ReturnButton";
import {
ContentPanel,
ContentPanelWidthSizes,
} from "components/Panels/ContentPanel";
import { SubPanel } from "components/Panels/SubPanel";
import { PreviewCard } from "components/PreviewCard";
import { GetVideosPreviewQuery } from "graphql/generated";
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
import { getReadySdk } from "graphql/sdk";
import { prettyDate } from "helpers/formatters";
import { getVideoThumbnailURL } from "helpers/videos";
import { GetStaticPropsContext } from "next";
import { Fragment, useState } from "react";
interface Props extends AppStaticProps {
videos: NonNullable<GetVideosPreviewQuery["videos"]>["data"];
}
export default function Videos(props: Props): JSX.Element {
const { langui, videos } = props;
videos
.sort((a, b) => {
const dateA = a.attributes?.published_date
? prettyDate(a.attributes.published_date)
: "9999";
const dateB = b.attributes?.published_date
? prettyDate(b.attributes.published_date)
: "9999";
return dateA.localeCompare(dateB);
})
.reverse();
const itemPerPage = 50;
const paginatedVideos: Props["videos"][] = [];
for (let index = 0; itemPerPage * index < videos.length; index += 1) {
paginatedVideos.push(
videos.slice(index * itemPerPage, (index + 1) * itemPerPage)
);
}
const [page, setPage] = useState(0);
const [keepInfoVisible, setKeepInfoVisible] = useState(true);
const subPanel = (
<SubPanel>
<ReturnButton
href="/archives/"
title={"Archives"}
langui={langui}
displayOn={ReturnButtonType.desktop}
className="mb-10"
/>
<PanelHeader
icon="movie"
title="Videos"
description={langui.archives_description}
/>
<div className="flex flex-row gap-2 place-items-center coarse:hidden">
<p className="flex-shrink-0">{langui.always_show_info}:</p>
<Switch setState={setKeepInfoVisible} state={keepInfoVisible} />
</div>
</SubPanel>
);
const contentPanel = (
<ContentPanel width={ContentPanelWidthSizes.large}>
<PageSelector
maxPage={Math.floor(videos.length / itemPerPage)}
page={page}
setPage={setPage}
className="mb-12"
/>
<div
className="grid gap-8 items-start thin:grid-cols-1 mobile:grid-cols-2
desktop:grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]
pb-12 border-b-[3px] border-dotted last-of-type:border-0"
>
{paginatedVideos[page].map((video) => (
<Fragment key={video.id}>
{video.attributes && (
<PreviewCard
href={`/archives/videos/v/${video.attributes.uid}`}
title={video.attributes.title}
thumbnail={getVideoThumbnailURL(video.attributes.uid)}
thumbnailAspectRatio="16/9"
keepInfoVisible={keepInfoVisible}
metadata={{
release_date: video.attributes.published_date,
views: video.attributes.views,
author: video.attributes.channel?.data?.attributes?.title,
position: "Top",
}}
hoverlay={{
__typename: "Video",
duration: video.attributes.duration,
}}
/>
)}
</Fragment>
))}
</div>
<PageSelector
maxPage={Math.floor(videos.length / itemPerPage)}
page={page}
setPage={setPage}
className="mt-12"
/>
</ContentPanel>
);
return (
<AppLayout
navTitle={langui.archives}
subPanel={subPanel}
contentPanel={contentPanel}
{...props}
/>
);
}
export async function getStaticProps(
context: GetStaticPropsContext
): Promise<{ notFound: boolean } | { props: Props }> {
const sdk = getReadySdk();
const videos = await sdk.getVideosPreview();
if (!videos.videos) return { notFound: true };
const props: Props = {
...(await getAppStaticProps(context)),
videos: videos.videos.data,
};
return {
props: props,
};
}