Formatted all TS files + fixed ugly code in _app

This commit is contained in:
DrMint 2022-01-01 03:31:55 +01:00
parent 40046955fb
commit 7076b2d71e
18 changed files with 297 additions and 242 deletions

View File

@ -11,7 +11,7 @@ export type ChronologyItemComponentProps = {
export default function ChronologyItemComponent( export default function ChronologyItemComponent(
props: ChronologyItemComponentProps props: ChronologyItemComponentProps
) { ): JSX.Element {
function generateAnchor( function generateAnchor(
year: number, year: number,
month: number, month: number,
@ -87,8 +87,7 @@ export default function ChronologyItemComponent(
<div className={styles.events}> <div className={styles.events}>
{props.item.attributes.events.map((event: ChronologyItemsEvent) => ( {props.item.attributes.events.map((event: ChronologyItemsEvent) => (
<div className={styles.event} key={event.id}> <div className={styles.event} key={event.id}>
{event.translations.map( {event.translations.map((translation) => (
(translation) => (
<> <>
{translation.title ? <h3>{translation.title}</h3> : ""} {translation.title ? <h3>{translation.title}</h3> : ""}
@ -109,8 +108,7 @@ export default function ChronologyItemComponent(
"" ""
)} )}
</> </>
) ))}
)}
<p className={styles.source}> <p className={styles.source}>
{event.source.data {event.source.data

View File

@ -8,7 +8,7 @@ type ChronologyYearComponentProps = {
export default function ChronologyYearComponent( export default function ChronologyYearComponent(
props: ChronologyYearComponentProps props: ChronologyYearComponentProps
) { ): JSX.Element {
return ( return (
<div <div
className={styles.chronologyYear} className={styles.chronologyYear}

View File

@ -0,0 +1,58 @@
import styles from "styles/Library/LibraryItemComponent.module.css";
import { LibraryItem } from "queries/library";
import Link from "next/link";
import Image from "next/image";
import { BasicDate, getAssetURL } from "queries/helpers";
export type LibraryItemComponentProps = {
item: LibraryItem;
};
export default function LibraryItemComponent(
props: LibraryItemComponentProps
): JSX.Element {
function prettyTitleSubtitle(title: string, subtitle: string): string {
let result = title;
if (subtitle !== null) result += " - " + subtitle;
return result;
}
function prettyDate(date: BasicDate): string {
return (
date.year +
"/" +
date.month.toString().padStart(2, "0") +
"/" +
date.day.toString().padStart(2, "0")
);
}
return (
<Link href={"/library/" + props.item.attributes.slug} passHref>
<div className={styles.libraryItem}>
<h2>
{prettyTitleSubtitle(
props.item.attributes.title,
props.item.attributes.subtitle
)}
</h2>
<p>{prettyDate(props.item.attributes.release_date)}</p>
{props.item.attributes.thumbnail.data ? (
<Image
src={getAssetURL(
props.item.attributes.thumbnail.data.attributes.url
)}
alt={
props.item.attributes.thumbnail.data.attributes.alternativeText
}
width={props.item.attributes.thumbnail.data.attributes.width}
height={props.item.attributes.thumbnail.data.attributes.height}
/>
) : (
""
)}
</div>
</Link>
);
}

View File

@ -1,12 +1,14 @@
import styles from 'styles/Panels/ContentPanel.module.css' import styles from "styles/Panels/ContentPanel.module.css";
import panelStyles from 'styles/Panels/Panels.module.css' import panelStyles from "styles/Panels/Panels.module.css";
export default function ContentPanel({children}) { type ContentPanelProps = {
children: React.ReactNode;
};
export default function ContentPanel(props: ContentPanelProps): JSX.Element {
return ( return (
<div className={[panelStyles.panel, styles.panel].join(' ')}> <div className={[panelStyles.panel, styles.panel].join(" ")}>
<main className={styles.panelInside}> <main className={styles.panelInside}>{props.children}</main>
{children}
</main>
</div> </div>
) );
} }

View File

@ -1,14 +1,11 @@
import Link from 'next/link' import Link from "next/link";
import styles from 'styles/Panels/MainPanel.module.css' import styles from "styles/Panels/MainPanel.module.css";
import panelStyles from 'styles/Panels/Panels.module.css' import panelStyles from "styles/Panels/Panels.module.css";
import NavOption from 'components/Panels/NavOption' import NavOption from "components/Panels/NavOption";
export default function MainPanel() {
export default function MainPanel(): JSX.Element {
return ( return (
<div className={[panelStyles.panel, styles.panel].join(" ")}>
<div className={[panelStyles.panel, styles.panel].join(' ')}>
<Link href="/" passHref> <Link href="/" passHref>
<div className={styles.topLogo}> <div className={styles.topLogo}>
<img src="/icons/accords.svg" alt="" /> <img src="/icons/accords.svg" alt="" />
@ -49,11 +46,7 @@ export default function MainPanel() {
title="Archive" title="Archive"
/> />
<NavOption <NavOption url="/news" icon="/icons/newspaper-solid.svg" title="News" />
url="/news"
icon="/icons/newspaper-solid.svg"
title="News"
/>
<NavOption <NavOption
url="/gallery" url="/gallery"
@ -70,7 +63,11 @@ export default function MainPanel() {
<hr /> <hr />
<div className={styles.menuFooter}> <div className={styles.menuFooter}>
<p>This website&rsquo;s content is made available under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a> unless otherwise noted.</p> <p>
This website&rsquo;s content is made available under{" "}
<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a>{" "}
unless otherwise noted.
</p>
<a href="https://creativecommons.org/licenses/by-sa/4.0/"> <a href="https://creativecommons.org/licenses/by-sa/4.0/">
<div className={styles.menuFooterCC}> <div className={styles.menuFooterCC}>
<img src="/icons/creative-commons-brands.svg" alt="" /> <img src="/icons/creative-commons-brands.svg" alt="" />
@ -78,12 +75,20 @@ export default function MainPanel() {
<img src="/icons/creative-commons-sa-brands.svg" alt="" /> <img src="/icons/creative-commons-sa-brands.svg" alt="" />
</div> </div>
</a> </a>
<p>Accord&rsquo;s Library is not affiliated with or endorsed by SQUARE ENIX CO. LTD. All game assets and promotional materials belongs to © SQUARE ENIX CO. LTD.</p> <p>
Accord&rsquo;s Library is not affiliated with or endorsed by SQUARE
ENIX CO. LTD. All game assets and promotional materials belongs to ©
SQUARE ENIX CO. LTD.
</p>
<div className={styles.menuFooterSocials}> <div className={styles.menuFooterSocials}>
<a href="https://github.com/Accords-Library"><img src="/icons/github-brands.svg" alt="" /></a> <a href="https://github.com/Accords-Library">
<a href="https://accords-library.com/discord"><img src="/icons/discord-brands.svg" alt="" /></a> <img src="/icons/github-brands.svg" alt="" />
</a>
<a href="https://accords-library.com/discord">
<img src="/icons/discord-brands.svg" alt="" />
</a>
</div> </div>
</div> </div>
</div> </div>
) );
} }

View File

@ -1,28 +1,28 @@
import { useRouter } from 'next/router' import { useRouter } from "next/router";
import styles from 'styles/Panels/NavOption.module.css' import styles from "styles/Panels/NavOption.module.css";
import Link from 'next/link' import Link from "next/link";
type NavOptionProps = { type NavOptionProps = {
url: string, url: string;
icon?: string, icon?: string;
title: string, title: string;
subtitle?: string subtitle?: string;
border?: boolean border?: boolean;
} };
export default function NavOption(pageProps: NavOptionProps) { export default function NavOption(pageProps: NavOptionProps): JSX.Element {
const router = useRouter(); const router = useRouter();
let classNames = [styles.menuOption] let classNames = [styles.menuOption];
if (router.asPath.startsWith(pageProps.url)) classNames.push(styles.active) if (router.asPath.startsWith(pageProps.url)) classNames.push(styles.active);
if (pageProps.icon) classNames.push(styles.icon) if (pageProps.icon) classNames.push(styles.icon);
if (pageProps.border === true) classNames.push(styles.border) if (pageProps.border === true) classNames.push(styles.border);
return ( return (
<Link href={pageProps.url} passHref> <Link href={pageProps.url} passHref>
<div className={classNames.join(' ')}> <div className={classNames.join(" ")}>
{pageProps.icon && <img src={pageProps.icon} alt="" />} {pageProps.icon && <img src={pageProps.icon} alt="" />}
<h3>{pageProps.title}</h3> <h3>{pageProps.title}</h3>
{pageProps.subtitle && <p>{pageProps.subtitle}</p>} {pageProps.subtitle && <p>{pageProps.subtitle}</p>}
</div> </div>
</Link> </Link>
) );
} }

View File

@ -1,17 +1,15 @@
import styles from 'styles/Panels/ReturnButton.module.css' import styles from "styles/Panels/ReturnButton.module.css";
import Link from 'next/link' import Link from "next/link";
type ReturnButtonProps = { type ReturnButtonProps = {
url: string, url: string;
title: string title: string;
} };
export default function ReturnButton(pageProps: ReturnButtonProps) { export default function ReturnButton(props: ReturnButtonProps): JSX.Element {
return ( return (
<Link href={pageProps.url} passHref> <Link href={props.url} passHref>
<button> <button>&emsp;Return to {props.title}</button>
&emsp;Return to {pageProps.title}
</button>
</Link> </Link>
) );
} }

View File

@ -1,10 +1,14 @@
import styles from 'styles/Panels/SubPanel.module.css' import styles from "styles/Panels/SubPanel.module.css";
import panelStyles from 'styles/Panels/Panels.module.css' import panelStyles from "styles/Panels/Panels.module.css";
export default function SubPanel({children}) { type SubPanelProps = {
children: React.ReactNode;
};
export default function SubPanel(props: SubPanelProps): JSX.Element {
return ( return (
<div className={[panelStyles.panel, styles.panel].join(' ')}> <div className={[panelStyles.panel, styles.panel].join(" ")}>
{children} {props.children}
</div> </div>
) );
} }

View File

@ -1,7 +1,13 @@
import Link from "next/link"; import Link from "next/link";
import ContentPanel from "components/Panels/ContentPanel"; import ContentPanel from "components/Panels/ContentPanel";
import { applyCustomAppProps } from "./_app";
export default function FourOhFour() { applyCustomAppProps(FourOhFour, {
useSubPanel: false,
useContentPanel: true,
});
export default function FourOhFour(): JSX.Element {
return ( return (
<ContentPanel> <ContentPanel>
<h1>404 - Page Not Found</h1> <h1>404 - Page Not Found</h1>

View File

@ -3,46 +3,24 @@ import Head from "next/head";
import MainPanel from "components/Panels/MainPanel"; import MainPanel from "components/Panels/MainPanel";
import "styles/globals.css"; import "styles/globals.css";
function AccordsLibraryApp({ Component, pageProps }: AppProps) { export type CustomAppProps = {
/* [BIG HACK] useSubPanel: boolean;
Yes this is probably terrible, I'm trying to apply a different style to my appContainer div useContentPanel: boolean;
depending on if the page uses a subpanel or contentpanel, or both, or neither. This is because };
I want the first column to be always 20rem, the second one to be 20rem when it's the subbar, but
1fr if it's the content...
Anyway, there is probably a much better way to do this, it it might backfire in my face in the future export function applyCustomAppProps(
Much love, page: Function,
customAppProps: CustomAppProps
Mint ) {
*/ page.customAppProps = customAppProps;
const componentProcessed = Component(pageProps);
let useSubPanel = false;
let useContentPanel = false;
const children = componentProcessed.props.children;
if (Array.isArray(children)) {
children.forEach((child) => {
if (child.type.name === "SubPanel") {
useSubPanel = true;
} else if (child.type.name === "ContentPanel") {
useContentPanel = true;
}
});
} else {
if (children.type.name === "SubPanel") {
useSubPanel = true;
} else if (children.type.name === "ContentPanel") {
useContentPanel = true;
}
} }
export default function AccordsLibraryApp(appProps: AppProps) {
let additionalClasses = ""; let additionalClasses = "";
if (useSubPanel) additionalClasses += " withSubPanel"; if (appProps.Component.customAppProps.useSubPanel)
if (useContentPanel) additionalClasses += " withContentPanel"; additionalClasses += " withSubPanel";
if (appProps.Component.customAppProps.useContentPanel)
/* [End of BIG HACK] */ additionalClasses += " withContentPanel";
const siteTitle = const siteTitle =
"Accord's Library - Discover • Analyse • Translate • Archive"; "Accord's Library - Discover • Analyse • Translate • Archive";
@ -71,9 +49,7 @@ function AccordsLibraryApp({ Component, pageProps }: AppProps) {
<MainPanel /> <MainPanel />
{componentProcessed} <appProps.Component {...appProps.pageProps} />
</div> </div>
); );
} }
export default AccordsLibraryApp;

View File

@ -1,8 +1,13 @@
import type { NextPage } from "next";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import NavOption from "components/Panels/NavOption"; import NavOption from "components/Panels/NavOption";
import { applyCustomAppProps } from "pages/_app";
const Chronology: NextPage = () => { applyCustomAppProps(Chronology, {
useSubPanel: true,
useContentPanel: false,
});
export default function Chronology(): JSX.Element {
return ( return (
<> <>
<SubPanel> <SubPanel>
@ -37,5 +42,4 @@ const Chronology: NextPage = () => {
</SubPanel> </SubPanel>
</> </>
); );
}; }
export default Chronology;

View File

@ -11,14 +11,19 @@ import {
ChronologyEra, ChronologyEra,
ChronologyItemsEvent, ChronologyItemsEvent,
} from "queries/chronology/overview"; } from "queries/chronology/overview";
import { applyCustomAppProps } from "pages/_app";
type Props = { type Props = {
chronologyItems: ChronologyItem[]; chronologyItems: ChronologyItem[];
chronologyEras: ChronologyEra[]; chronologyEras: ChronologyEra[];
}; };
export default function ChronologyOverview(props: Props): JSX.Element { applyCustomAppProps(ChronologyOverview, {
useSubPanel: true,
useContentPanel: true,
});
export default function ChronologyOverview(props: Props): JSX.Element {
// Group by year the Chronology items // Group by year the Chronology items
let chronologyItemYearGroups: ChronologyItem[][] = []; let chronologyItemYearGroups: ChronologyItem[][] = [];
props.chronologyItems.map((item: ChronologyItem) => { props.chronologyItems.map((item: ChronologyItem) => {
@ -80,15 +85,11 @@ export default function ChronologyOverview(props: Props): JSX.Element {
}); });
})} })}
{chronologyItemYearGroups.map((items: ChronologyItem[], index: number) => { {chronologyItemYearGroups.map(
return ( (items: ChronologyItem[], index: number) => {
<ChronologyYearComponent return <ChronologyYearComponent key={index} items={items} />;
key={index} }
items={items} )}
/>
)
})}
</ContentPanel> </ContentPanel>
</> </>
); );

View File

@ -1,7 +1,12 @@
import type { NextPage } from "next";
import ContentPanel from "components/Panels/ContentPanel"; import ContentPanel from "components/Panels/ContentPanel";
import { applyCustomAppProps } from "./_app";
const Home: NextPage = () => { applyCustomAppProps(Home, {
useSubPanel: false,
useContentPanel: true,
});
export default function Home(): JSX.Element {
return ( return (
<> <>
<ContentPanel> <ContentPanel>
@ -129,6 +134,4 @@ const Home: NextPage = () => {
</ContentPanel> </ContentPanel>
</> </>
); );
}; }
export default Home;

View File

@ -6,16 +6,22 @@ import {
getBreadcrumbs, getBreadcrumbs,
getLibraryItemsSkeleton, getLibraryItemsSkeleton,
LibraryItem, LibraryItem,
LibrarySubItem LibrarySubItem,
} from "queries/library/[...slug]"; } from "queries/library/[...slug]";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { GetStaticProps } from "next"; import { GetStaticProps } from "next";
import { applyCustomAppProps } from "pages/_app";
type Props = { type Props = {
libraryItem: LibraryItem; libraryItem: LibraryItem;
}; };
applyCustomAppProps(Library, {
useSubPanel: false,
useContentPanel: true,
});
export default function Library(props: Props): JSX.Element { export default function Library(props: Props): JSX.Element {
const router = useRouter(); const router = useRouter();
return ( return (
@ -35,7 +41,8 @@ export default function Library(props: Props): JSX.Element {
height={props.libraryItem.attributes.thumbnail.data.attributes.height} height={props.libraryItem.attributes.thumbnail.data.attributes.height}
/> />
{props.libraryItem.attributes.subitems.data.map((subitem: LibrarySubItem) => ( {props.libraryItem.attributes.subitems.data.map(
(subitem: LibrarySubItem) => (
<Link <Link
href={router.asPath + "/" + subitem.attributes.slug} href={router.asPath + "/" + subitem.attributes.slug}
key={subitem.id} key={subitem.id}
@ -44,8 +51,13 @@ export default function Library(props: Props): JSX.Element {
<div> <div>
{subitem.attributes.thumbnail.data ? ( {subitem.attributes.thumbnail.data ? (
<Image <Image
src={getAssetURL(subitem.attributes.thumbnail.data.attributes.url)} src={getAssetURL(
alt={subitem.attributes.thumbnail.data.attributes.alternativeText} subitem.attributes.thumbnail.data.attributes.url
)}
alt={
subitem.attributes.thumbnail.data.attributes
.alternativeText
}
width={subitem.attributes.thumbnail.data.attributes.width} width={subitem.attributes.thumbnail.data.attributes.width}
height={subitem.attributes.thumbnail.data.attributes.height} height={subitem.attributes.thumbnail.data.attributes.height}
/> />
@ -54,9 +66,8 @@ export default function Library(props: Props): JSX.Element {
)} )}
</div> </div>
</Link> </Link>
))} )
)}
</ContentPanel> </ContentPanel>
</> </>
); );
@ -66,15 +77,15 @@ export const getStaticProps: GetStaticProps = async (context) => {
if (context.params && Array.isArray(context.params.slug) && context.locale) { if (context.params && Array.isArray(context.params.slug) && context.locale) {
return { return {
props: { props: {
libraryItem: (await getLibraryItem(context.params.slug, context.locale)), libraryItem: await getLibraryItem(context.params.slug, context.locale),
}, },
}; };
} }
return { props: {} }; return { props: {} };
} };
export async function getStaticPaths() { export async function getStaticPaths() {
const paths = (await getAllSlugs()); const paths = await getAllSlugs();
return { return {
paths, paths,
fallback: false, fallback: false,
@ -85,16 +96,16 @@ async function getAllSlugs() {
type Path = { type Path = {
params: { params: {
slug: string[]; slug: string[];
} };
} };
const data = (await getLibraryItemsSkeleton()); const data = await getLibraryItemsSkeleton();
const paths: Path[] = []; const paths: Path[] = [];
data.map((item) => { data.map((item) => {
const breadcrumbs = getBreadcrumbs([], item); const breadcrumbs = getBreadcrumbs([], item);
breadcrumbs.map((breadcrumb) => { breadcrumbs.map((breadcrumb) => {
paths.push({params: {slug: breadcrumb}}) paths.push({ params: { slug: breadcrumb } });
}) });
}) });
return paths; return paths;
} }

View File

@ -2,14 +2,18 @@ import { GetStaticProps } from "next";
import SubPanel from "components/Panels/SubPanel"; import SubPanel from "components/Panels/SubPanel";
import ContentPanel from "components/Panels/ContentPanel"; import ContentPanel from "components/Panels/ContentPanel";
import { LibraryItem, getLibraryItems } from "queries/library/index"; import { LibraryItem, getLibraryItems } from "queries/library/index";
import { BasicDate, getAssetURL } from "queries/helpers"; import LibraryItemComponent from "components/Library/LibraryItemComponent";
import Image from "next/image"; import { applyCustomAppProps } from "pages/_app";
import Link from "next/link";
type Props = { type Props = {
libraryItems: LibraryItem[]; libraryItems: LibraryItem[];
}; };
applyCustomAppProps(Library, {
useSubPanel: true,
useContentPanel: true,
});
export default function Library(props: Props): JSX.Element { export default function Library(props: Props): JSX.Element {
return ( return (
<> <>
@ -26,25 +30,7 @@ export default function Library(props: Props): JSX.Element {
<ContentPanel> <ContentPanel>
{props.libraryItems.map((item: LibraryItem) => ( {props.libraryItems.map((item: LibraryItem) => (
<Link href={"/library/" + item.attributes.slug} key={item.id} passHref> <LibraryItemComponent key={item.id} item={item} />
<div>
<p>
{prettyTitleSubtitle(item.attributes.title, item.attributes.subtitle)}
</p>
<p>{prettyDate(item.attributes.release_date)}</p>
{item.attributes.thumbnail.data ? (
<Image
src={getAssetURL(item.attributes.thumbnail.data.attributes.url)}
alt={item.attributes.thumbnail.data.attributes.alternativeText}
width={item.attributes.thumbnail.data.attributes.width}
height={item.attributes.thumbnail.data.attributes.height}
/>
) : (
""
)}
</div>
</Link>
))} ))}
</ContentPanel> </ContentPanel>
</> </>
@ -58,13 +44,3 @@ export const getStaticProps: GetStaticProps = async (context) => {
}, },
}; };
}; };
function prettyTitleSubtitle(title: string, subtitle: string): string {
let result = title;
if (subtitle !== null) result += " - " + subtitle;
return result;
}
function prettyDate(date: BasicDate): string {
return date.year + "/" + date.month + "/" + date.day;
}

View File

@ -1,4 +1,10 @@
import { BasicDate, BasicPrice, BasicSize, queryGraphQL, UploadImage } from "queries/helpers"; import {
BasicDate,
BasicPrice,
BasicSize,
queryGraphQL,
UploadImage,
} from "queries/helpers";
export type LibraryItemSkeleton = { export type LibraryItemSkeleton = {
attributes: { attributes: {
@ -63,7 +69,6 @@ export function getBreadcrumbs(
return result; return result;
} }
export type LibraryItem = { export type LibraryItem = {
id: string; id: string;
attributes: { attributes: {
@ -90,14 +95,13 @@ export type LibrarySubItem = {
subtitle: string; subtitle: string;
slug: string; slug: string;
thumbnail: UploadImage; thumbnail: UploadImage;
} };
} };
export async function getLibraryItem( export async function getLibraryItem(
slug: string[], slug: string[],
language_code: string | undefined language_code: string | undefined
): Promise<LibraryItem> { ): Promise<LibraryItem> {
return ( return (
await queryGraphQL( await queryGraphQL(
` `

View File

@ -1,4 +1,10 @@
import { UploadImage, queryGraphQL, BasicPrice, BasicDate, BasicSize } from "queries/helpers"; import {
UploadImage,
queryGraphQL,
BasicPrice,
BasicDate,
BasicSize,
} from "queries/helpers";
export type LibraryItem = { export type LibraryItem = {
id: string; id: string;

View File

@ -0,0 +1,3 @@
.libraryItem {
cursor: pointer;
}