168 lines
5.2 KiB
TypeScript
168 lines
5.2 KiB
TypeScript
import { AppLayout } from "components/AppLayout";
|
|
import { InsetBox } from "components/InsetBox";
|
|
import { NavOption } from "components/PanelComponents/NavOption";
|
|
import {
|
|
ReturnButton,
|
|
ReturnButtonType,
|
|
} from "components/PanelComponents/ReturnButton";
|
|
import { ContentPanel } from "components/Panels/ContentPanel";
|
|
import { SubPanel } from "components/Panels/SubPanel";
|
|
import { ChronologyYearComponent } from "components/Wiki/Chronology/ChronologyYearComponent";
|
|
import { GetChronologyItemsQuery, GetErasQuery } from "graphql/generated";
|
|
import { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps";
|
|
import { getReadySdk } from "graphql/sdk";
|
|
import { prettySlug } from "helpers/formatters";
|
|
import { isDefined } from "helpers/others";
|
|
import { GetStaticPropsContext } from "next";
|
|
import { Fragment } from "react";
|
|
|
|
interface Props extends AppStaticProps {
|
|
chronologyItems: NonNullable<
|
|
GetChronologyItemsQuery["chronologyItems"]
|
|
>["data"];
|
|
chronologyEras: NonNullable<GetErasQuery["chronologyEras"]>["data"];
|
|
}
|
|
|
|
export default function Chronology(props: Props): JSX.Element {
|
|
const { chronologyItems, chronologyEras, langui } = props;
|
|
|
|
// Group by year the Chronology items
|
|
const chronologyItemYearGroups: Props["chronologyItems"][number][][][] = [];
|
|
|
|
chronologyEras.map(() => {
|
|
chronologyItemYearGroups.push([]);
|
|
});
|
|
|
|
let currentChronologyEraIndex = 0;
|
|
chronologyItems.map((item) => {
|
|
if (item.attributes) {
|
|
if (
|
|
item.attributes.year >
|
|
(chronologyEras[currentChronologyEraIndex].attributes?.ending_year ??
|
|
999999)
|
|
) {
|
|
currentChronologyEraIndex += 1;
|
|
}
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(
|
|
chronologyItemYearGroups[currentChronologyEraIndex],
|
|
item.attributes.year
|
|
)
|
|
) {
|
|
chronologyItemYearGroups[currentChronologyEraIndex][
|
|
item.attributes.year
|
|
].push(item);
|
|
} else {
|
|
chronologyItemYearGroups[currentChronologyEraIndex][
|
|
item.attributes.year
|
|
] = [item];
|
|
}
|
|
}
|
|
});
|
|
|
|
const subPanel = (
|
|
<SubPanel>
|
|
<ReturnButton
|
|
href="/wiki"
|
|
title={langui.wiki}
|
|
langui={langui}
|
|
displayOn={ReturnButtonType.Desktop}
|
|
horizontalLine
|
|
/>
|
|
|
|
{chronologyEras.map((era) => (
|
|
<Fragment key={era.id}>
|
|
{era.attributes && (
|
|
<NavOption
|
|
url={`#${era.attributes.slug}`}
|
|
title={
|
|
era.attributes.title &&
|
|
era.attributes.title.length > 0 &&
|
|
era.attributes.title[0]
|
|
? era.attributes.title[0].title
|
|
: prettySlug(era.attributes.slug)
|
|
}
|
|
subtitle={`${era.attributes.starting_year} → ${era.attributes.ending_year}`}
|
|
border
|
|
/>
|
|
)}
|
|
</Fragment>
|
|
))}
|
|
</SubPanel>
|
|
);
|
|
|
|
const contentPanel = (
|
|
<ContentPanel>
|
|
<ReturnButton
|
|
href="/wiki"
|
|
title={langui.wiki}
|
|
langui={langui}
|
|
displayOn={ReturnButtonType.Mobile}
|
|
className="mb-10"
|
|
/>
|
|
|
|
{chronologyItemYearGroups.map((era, eraIndex) => (
|
|
<Fragment key={eraIndex}>
|
|
<InsetBox
|
|
id={chronologyEras[eraIndex].attributes?.slug}
|
|
className="my-8 grid gap-4 text-center"
|
|
>
|
|
<h2 className="text-2xl">
|
|
{chronologyEras[eraIndex].attributes?.title?.[0]
|
|
? chronologyEras[eraIndex].attributes?.title?.[0]?.title
|
|
: prettySlug(chronologyEras[eraIndex].attributes?.slug)}
|
|
</h2>
|
|
<p className="whitespace-pre-line ">
|
|
{chronologyEras[eraIndex].attributes?.title?.[0]
|
|
? chronologyEras[eraIndex].attributes?.title?.[0]?.description
|
|
: ""}
|
|
</p>
|
|
</InsetBox>
|
|
{era.map((items, index) => (
|
|
<Fragment key={index}>
|
|
{items[0].attributes && isDefined(items[0].attributes.year) && (
|
|
<ChronologyYearComponent
|
|
year={items[0].attributes.year}
|
|
items={items}
|
|
langui={langui}
|
|
/>
|
|
)}
|
|
</Fragment>
|
|
))}
|
|
</Fragment>
|
|
))}
|
|
</ContentPanel>
|
|
);
|
|
|
|
return (
|
|
<AppLayout
|
|
navTitle={langui.chronology}
|
|
contentPanel={contentPanel}
|
|
subPanel={subPanel}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export async function getStaticProps(
|
|
context: GetStaticPropsContext
|
|
): Promise<{ notFound: boolean } | { props: Props }> {
|
|
const sdk = getReadySdk();
|
|
const chronologyItems = await sdk.getChronologyItems({
|
|
language_code: context.locale ?? "en",
|
|
});
|
|
const chronologyEras = await sdk.getEras({
|
|
language_code: context.locale ?? "en",
|
|
});
|
|
if (!chronologyItems.chronologyItems || !chronologyEras.chronologyEras)
|
|
return { notFound: true };
|
|
const props: Props = {
|
|
...(await getAppStaticProps(context)),
|
|
chronologyItems: chronologyItems.chronologyItems.data,
|
|
chronologyEras: chronologyEras.chronologyEras.data,
|
|
};
|
|
return {
|
|
props: props,
|
|
};
|
|
}
|