Merge pull request #1 from Accords-Library/develop

New translation system and filtering/group for Library Items
This commit is contained in:
DrMint 2022-03-05 16:37:58 +01:00 committed by GitHub
commit 30a2b8ceda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 580 additions and 245 deletions

View File

@ -3,7 +3,7 @@ module.exports = {
swcMinify: true, swcMinify: true,
reactStrictMode: true, reactStrictMode: true,
i18n: { i18n: {
locales: ["en", "fr", "ja", "es", "xx"], locales: ["en", "fr", "ja", "es"],
defaultLocale: "en", defaultLocale: "en",
}, },
images: { images: {

View File

@ -1 +1 @@
npx next dev -p 12500 npx next dev -p 12499

View File

@ -88,7 +88,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
const metaDescription = props.description const metaDescription = props.description
? props.description ? props.description
: "Accord's Library aims at gathering and archiving all of Yoko Taros work. Yoko Taro is a Japanese video game director and scenario writer."; : props.langui.default_description;
return ( return (
<div className={appLayout.darkMode ? "set-theme-dark" : "set-theme-light"}> <div className={appLayout.darkMode ? "set-theme-dark" : "set-theme-light"}>
@ -104,12 +104,8 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
content={`${titlePrefix} - ${ogTitle}`} content={`${titlePrefix} - ${ogTitle}`}
></meta> ></meta>
{props.description && (
<>
<meta name="description" content={metaDescription} /> <meta name="description" content={metaDescription} />
<meta name="twitter:description" content={metaDescription}></meta> <meta name="twitter:description" content={metaDescription}></meta>
</>
)}
<meta property="og:image" content={metaImage.image}></meta> <meta property="og:image" content={metaImage.image}></meta>
<meta property="og:image:secure_url" content={metaImage.image}></meta> <meta property="og:image:secure_url" content={metaImage.image}></meta>
@ -160,7 +156,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
<div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40"> <div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40">
<p className="text-4xl"></p> <p className="text-4xl"></p>
<p className="text-2xl w-64"> <p className="text-2xl w-64">
Select one of the options in the sidebar {props.langui.select_option_sidebar}
</p> </p>
</div> </div>
</div> </div>
@ -238,7 +234,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
appLayout.languagePanelOpen ? "scale-100" : "scale-0" appLayout.languagePanelOpen ? "scale-100" : "scale-0"
}`} }`}
> >
<h2 className="text-2xl">Select a language</h2> <h2 className="text-2xl">{props.langui.select_language}</h2>
<div className="flex flex-wrap flex-row gap-2"> <div className="flex flex-wrap flex-row gap-2">
{router.locales?.sort().map((locale) => ( {router.locales?.sort().map((locale) => (
<Button <Button

View File

@ -5,7 +5,7 @@ type ButtonProps = {
id?: string; id?: string;
className?: string; className?: string;
href?: string; href?: string;
children: React.ReactChild | React.ReactChild[]; children: React.ReactNode;
active?: boolean; active?: boolean;
locale?: string; locale?: string;
onClick?: MouseEventHandler<HTMLDivElement>; onClick?: MouseEventHandler<HTMLDivElement>;

View File

@ -1,6 +1,6 @@
type ChipProps = { type ChipProps = {
className?: string; className?: string;
children: React.ReactChild | React.ReactChild[]; children: React.ReactNode;
"data-tip"?: string; "data-tip"?: string;
"data-for"?: string; "data-for"?: string;
"data-html"?: boolean; "data-html"?: boolean;

View File

@ -55,7 +55,7 @@ export default function ThumbnailHeader(
<div className="grid grid-flow-col gap-8"> <div className="grid grid-flow-col gap-8">
{content.type ? ( {content.type ? (
<div className="grid place-items-center place-content-start gap-2"> <div className="grid place-items-center place-content-start gap-2">
<h3 className="text-xl">{langui.global_type}</h3> <h3 className="text-xl">{langui.type}</h3>
<Button> <Button>
{content.type.data.attributes.titles.length > 0 {content.type.data.attributes.titles.length > 0
? content.type.data.attributes.titles[0].title ? content.type.data.attributes.titles[0].title
@ -68,7 +68,7 @@ export default function ThumbnailHeader(
{content.categories.data.length > 0 ? ( {content.categories.data.length > 0 ? (
<div className="grid place-items-center place-content-start gap-2"> <div className="grid place-items-center place-content-start gap-2">
<h3 className="text-xl">{langui.global_categories}</h3> <h3 className="text-xl">{langui.categories}</h3>
{content.categories.data.map((category) => ( {content.categories.data.map((category) => (
<Button key={category.id}>{category.attributes.name}</Button> <Button key={category.id}>{category.attributes.name}</Button>
))} ))}

View File

@ -1,6 +1,6 @@
type InsetBoxProps = { type InsetBoxProps = {
className?: string; className?: string;
children: React.ReactChild | React.ReactChild[]; children: React.ReactNode;
id?: string; id?: string;
}; };

View File

@ -30,7 +30,7 @@ export default function LibraryItemsPreview(
{item.thumbnail.data ? ( {item.thumbnail.data ? (
<Img <Img
image={item.thumbnail.data.attributes} image={item.thumbnail.data.attributes}
quality={ImageQuality.Medium} quality={ImageQuality.Small}
/> />
) : ( ) : (
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div> <div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>

View File

@ -13,7 +13,7 @@ export default function ReturnButton(props: ReturnButtonProps): JSX.Element {
return ( return (
<Button onClick={() => appLayout.setSubPanelOpen(false)} href={props.href}> <Button onClick={() => appLayout.setSubPanelOpen(false)} href={props.href}>
&emsp;{props.langui.global_return_label} {props.title} &emsp;{props.langui.return_to} {props.title}
</Button> </Button>
); );
} }

View File

@ -1,6 +1,5 @@
import Link from "next/link"; import Link from "next/link";
import NavOption from "components/PanelComponents/NavOption"; import NavOption from "components/PanelComponents/NavOption";
import SVG from "components/SVG";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Button from "components/Button"; import Button from "components/Button";
import HorizontalLine from "components/HorizontalLine"; import HorizontalLine from "components/HorizontalLine";
@ -84,8 +83,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/library" url="/library"
icon="library_books" icon="library_books"
title={langui.main_library} title={langui.library}
subtitle={langui.main_library_description} subtitle={langui.library_short_description}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -94,8 +93,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/contents" url="/contents"
icon="workspaces" icon="workspaces"
title="Contents" title={langui.contents}
subtitle="Explore all content and filter by type or category" subtitle={langui.contents_short_description}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -104,8 +103,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/wiki" url="/wiki"
icon="travel_explore" icon="travel_explore"
title={langui.main_wiki} title={langui.wiki}
subtitle={langui.main_wiki_description} subtitle={langui.wiki_short_description}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -114,8 +113,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/chronicles" url="/chronicles"
icon="watch_later" icon="watch_later"
title={langui.main_chronicles} title={langui.chronicles}
subtitle={langui.main_chronicles_description} subtitle={langui.chronicles_short_description}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -126,7 +125,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/news" url="/news"
icon="feed" icon="feed"
title={langui.main_news} title={langui.news}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -135,7 +134,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/merch" url="/merch"
icon="store" icon="store"
title={langui.main_merch} title={langui.merch}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -144,7 +143,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/gallery" url="/gallery"
icon="collections" icon="collections"
title={langui.main_gallery} title={langui.gallery}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -153,7 +152,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/archives" url="/archives"
icon="inventory" icon="inventory"
title={langui.main_archives} title={langui.archives}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -162,7 +161,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
<NavOption <NavOption
url="/about-us" url="/about-us"
icon="info" icon="info"
title={langui.main_about_us} title={langui.about_us}
tooltipId="MainPanelTooltip" tooltipId="MainPanelTooltip"
reduced={appLayout.mainPanelReduced && isDesktop} reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)} onClick={() => appLayout.setMainPanelOpen(false)}
@ -176,8 +175,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
}`} }`}
> >
<p> <p>
{langui.main_licensing ? ( {langui.licensing_notice ? (
<Markdown>{langui.main_licensing}</Markdown> <Markdown>{langui.licensing_notice}</Markdown>
) : ( ) : (
"" ""
)} )}
@ -194,8 +193,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
</div> </div>
</a> </a>
<p> <p>
{langui.main_copyright ? ( {langui.copyright_notice ? (
<Markdown>{langui.main_copyright}</Markdown> <Markdown>{langui.copyright_notice}</Markdown>
) : ( ) : (
"" ""
)} )}

67
src/components/Select.tsx Normal file
View File

@ -0,0 +1,67 @@
import { Dispatch, SetStateAction, useState } from "react";
export type SelectProps = {
setState: Dispatch<SetStateAction<number>>;
state: number;
options: string[];
selected?: number;
allowEmpty?: boolean;
className?: string;
onChange?: Function;
};
export default function Select(props: SelectProps): JSX.Element {
const [opened, setOpened] = useState(false);
return (
<div
className={`relative transition-[filter] ${
opened && "drop-shadow-shade-lg z-10"
} ${props.className}`}
>
<div
className={`outline outline-mid outline-2 outline-offset-[-2px] hover:outline-[transparent] bg-light rounded-[1em] p-1 grid grid-flow-col grid-cols-[1fr_auto_auto] place-items-center cursor-pointer hover:bg-mid transition-all ${
opened && "outline-[transparent] rounded-b-none"
}`}
>
<p onClick={() => setOpened(!opened)} className="w-full">
{props.state === -1 ? "—" : props.options[props.state]}
</p>
{props.state >= 0 && props.allowEmpty && (
<span
onClick={() => props.setState(-1)}
className="material-icons !text-xs"
>
close
</span>
)}
<span onClick={() => setOpened(!opened)} className="material-icons">
{opened ? "arrow_drop_up" : "arrow_drop_down"}
</span>
</div>
<div
className={`left-0 right-0 rounded-b-[1em] ${
opened ? "absolute" : "hidden"
}`}
>
{props.options.map((option, index) => (
<>
{index !== props.state && (
<div
className="bg-light hover:bg-mid transition-colors cursor-pointer p-1 last-of-type:rounded-b-[1em]"
key={option}
id={option}
onClick={() => {
setOpened(false);
props.setState(index);
}}
>
{option}
</div>
)}
</>
))}
</div>
</div>
);
}

26
src/components/Switch.tsx Normal file
View File

@ -0,0 +1,26 @@
import { Dispatch, SetStateAction } from "react";
export type SwitchProps = {
setState: Dispatch<SetStateAction<boolean>>;
state: boolean;
className?: string;
};
export default function Select(props: SwitchProps): JSX.Element {
return (
<div
className={`h-6 w-12 rounded-full border-2 border-mid grid transition-colors relative cursor-pointer ${
props.className
} ${props.state ? "bg-mid" : "bg-light"}`}
onClick={() => {
props.setState(!props.state);
}}
>
<div
className={`bg-dark aspect-square rounded-full absolute top-0 bottom-0 left-0 transition-transform ${
props.state && "translate-x-[115%]"
}`}
></div>
</div>
);
}

View File

@ -1,72 +1,87 @@
query getWebsiteInterface($language_code: String) { query getWebsiteInterface($language_code: String) {
websiteInterfaces(filters: { language: { code: { eq: $language_code } } }) { websiteInterfaces(
filters: { ui_language: { code: { eq: $language_code } } }
) {
data { data {
attributes { attributes {
main_library library
main_library_description contents
main_news wiki
main_merch chronicles
main_gallery library_short_description
main_archives contents_short_description
main_about_us wiki_short_description
main_licensing chronicles_short_description
main_copyright news
merch
gallery
archives
about_us
licensing_notice
copyright_notice
contents_description
type
category
categories
size
release_date
release_year
details
price
width
height
thickness
subitem
subitems
subitem_of
variant
variants
variant_of
summary
audio
video
textual
game
other
return_to
left_to_right
right_to_left
page
pages
page_order
binding
type_information
front_matter
back_matter
open_content
read_content
watch_content
listen_content
view_scans
paperback
hardcover
languages
select_language
language
library_description library_description
library_item_summary
library_item_gallery
library_item_details
library_item_subitems
library_item_variants
library_item_content
global_return_label
global_subitem_of
global_type
global_width
global_height
global_thickness
global_binding
global_language
global_languages
global_page
global_pages
global_page_order
global_release_date
global_price
library_item_physical_size
library_item_type_information
library_item_front_matter
library_item_back_matter
library_item_type_textual
library_item_type_audio
library_item_type_game
library_item_type_video
library_item_type_other
library_item_open_content
library_item_view_scans
content_read_content
content_watch_content
content_listen_content
global_category
global_categories
global_paperback
global_hardcover
global_left_to_right
global_right_to_left
main_wiki
main_wiki_description
main_chronicles
main_chronicles_description
library_items
library_items_description
library_content
library_content_description
wiki_description wiki_description
news_description
chronicles_description chronicles_description
news_description
merch_description
gallery_description gallery_description
archives_description archives_description
about_us_description about_us_description
merch_description page_not_found
default_description
name
show_subitems
show_primary_items
show_secondary_items
no_type
no_year
order_by
group_by
select_option_sidebar
} }
} }
} }
@ -125,17 +140,14 @@ query getChronologyItems($language_code: String) {
} }
query getLibraryItemsPreview($language_code: String) { query getLibraryItemsPreview($language_code: String) {
libraryItems( libraryItems(pagination: { limit: -1 }) {
filters: { root_item: { eq: true } }
pagination: { limit: -1 }
sort: ["title:asc", "subtitle:asc"]
) {
data { data {
id id
attributes { attributes {
title title
subtitle subtitle
slug slug
root_item
thumbnail { thumbnail {
data { data {
attributes { attributes {

View File

@ -86,71 +86,84 @@ export type GetWebsiteInterfaceQuery = {
__typename: "WebsiteInterfaceEntity"; __typename: "WebsiteInterfaceEntity";
attributes: { attributes: {
__typename: "WebsiteInterface"; __typename: "WebsiteInterface";
main_library: string; library: string;
main_library_description: string; contents: string;
main_news: string; wiki: string;
main_merch: string; chronicles: string;
main_gallery: string; library_short_description: string;
main_archives: string; contents_short_description: string;
main_about_us: string; wiki_short_description: string;
main_licensing: string; chronicles_short_description: string;
main_copyright: string; news: string;
merch: string;
gallery: string;
archives: string;
about_us: string;
licensing_notice: string;
copyright_notice: string;
contents_description: string;
type: string;
category: string;
categories: string;
size: string;
release_date: string;
release_year: string;
details: string;
price: string;
width: string;
height: string;
thickness: string;
subitem: string;
subitems: string;
subitem_of: string;
variant: string;
variants: string;
variant_of: string;
summary: string;
audio: string;
video: string;
textual: string;
game: string;
other: string;
return_to: string;
left_to_right: string;
right_to_left: string;
page: string;
pages: string;
page_order: string;
binding: string;
type_information: string;
front_matter: string;
back_matter: string;
open_content: string;
read_content: string;
watch_content: string;
listen_content: string;
view_scans: string;
paperback: string;
hardcover: string;
languages: string;
select_language: string;
language: string;
library_description: string; library_description: string;
library_item_summary: string;
library_item_gallery: string;
library_item_details: string;
library_item_subitems: string;
library_item_variants: string;
library_item_content: string;
global_return_label: string;
global_subitem_of: string;
global_type: string;
global_width: string;
global_height: string;
global_thickness: string;
global_binding: string;
global_language: string;
global_languages: string;
global_page: string;
global_pages: string;
global_page_order: string;
global_release_date: string;
global_price: string;
library_item_physical_size: string;
library_item_type_information: string;
library_item_front_matter: string;
library_item_back_matter: string;
library_item_type_textual: string;
library_item_type_audio: string;
library_item_type_game: string;
library_item_type_video: string;
library_item_type_other: string;
library_item_open_content: string;
library_item_view_scans: string;
content_read_content: string;
content_watch_content: string;
content_listen_content: string;
global_category: string;
global_categories: string;
global_paperback: string;
global_hardcover: string;
global_left_to_right: string;
global_right_to_left: string;
main_wiki: string;
main_wiki_description: string;
main_chronicles: string;
main_chronicles_description: string;
library_items: string;
library_items_description: string;
library_content: string;
library_content_description: string;
wiki_description: string; wiki_description: string;
news_description: string;
chronicles_description: string; chronicles_description: string;
news_description: string;
merch_description: string;
gallery_description: string; gallery_description: string;
archives_description: string; archives_description: string;
about_us_description: string; about_us_description: string;
merch_description: string; page_not_found: string;
default_description: string;
name: string;
show_subitems: string;
show_primary_items: string;
show_secondary_items: string;
no_type: string;
no_year: string;
order_by: string;
group_by: string;
select_option_sidebar: string;
}; };
}>; }>;
}; };
@ -238,6 +251,7 @@ export type GetLibraryItemsPreviewQuery = {
title: string; title: string;
subtitle: string; subtitle: string;
slug: string; slug: string;
root_item: boolean;
thumbnail: { thumbnail: {
__typename: "UploadFileEntityResponse"; __typename: "UploadFileEntityResponse";
data: { data: {

View File

@ -4,6 +4,7 @@ import { getWebsiteInterface } from "graphql/operations";
import { GetStaticProps } from "next"; import { GetStaticProps } from "next";
import { GetWebsiteInterfaceQuery } from "graphql/operations-types"; import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import ReturnButton from "components/PanelComponents/ReturnButton";
type FourOhFourProps = { type FourOhFourProps = {
langui: GetWebsiteInterfaceQuery; langui: GetWebsiteInterfaceQuery;
@ -13,13 +14,13 @@ export default function FourOhFour(props: FourOhFourProps): JSX.Element {
const langui = props.langui.websiteInterfaces.data[0].attributes; const langui = props.langui.websiteInterfaces.data[0].attributes;
const contentPanel = ( const contentPanel = (
<ContentPanel> <ContentPanel>
<h1>404 - Page Not Found</h1> <h1>404 - {langui.page_not_found}</h1>
<Link href="/"> <ReturnButton href="/" title="Home" langui={langui} />
<a>Go back home</a>
</Link>
</ContentPanel> </ContentPanel>
); );
return <AppLayout navTitle="404" langui={langui} contentPanel={contentPanel} />; return (
<AppLayout navTitle="404" langui={langui} contentPanel={contentPanel} />
);
} }
export const getStaticProps: GetStaticProps = async (context) => { export const getStaticProps: GetStaticProps = async (context) => {

View File

@ -15,14 +15,14 @@ export default function AboutUs(props: AboutUsProps): JSX.Element {
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="info" icon="info"
title={langui.main_about_us} title={langui.about_us}
description={langui.about_us_description} description={langui.about_us_description}
/> />
</SubPanel> </SubPanel>
); );
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_about_us} navTitle={langui.about_us}
langui={langui} langui={langui}
subPanel={subPanel} subPanel={subPanel}
/> />

View File

@ -15,14 +15,14 @@ export default function Archives(props: ArchivesProps): JSX.Element {
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="inventory" icon="inventory"
title={langui.main_archives} title={langui.archives}
description={langui.archives_description} description={langui.archives_description}
/> />
</SubPanel> </SubPanel>
); );
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_archives} navTitle={langui.archives}
langui={langui} langui={langui}
subPanel={subPanel} subPanel={subPanel}
/> />

View File

@ -15,14 +15,14 @@ export default function Chronicles(props: ChroniclesProps): JSX.Element {
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="watch_later" icon="watch_later"
title={langui.main_chronicles} title={langui.chronicles}
description={langui.chronicles_description} description={langui.chronicles_description}
/> />
</SubPanel> </SubPanel>
); );
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_chronicles} navTitle={langui.chronicles}
langui={langui} langui={langui}
subPanel={subPanel} subPanel={subPanel}
/> />

View File

@ -40,7 +40,7 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element {
{content.text_set.length > 0 ? ( {content.text_set.length > 0 ? (
<Button href={`/contents/${content.slug}/read/`}> <Button href={`/contents/${content.slug}/read/`}>
{langui.content_read_content} {langui.read_content}
</Button> </Button>
) : ( ) : (
"" ""
@ -48,7 +48,7 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element {
{content.audio_set.length > 0 ? ( {content.audio_set.length > 0 ? (
<Button href={`/contents/${content.slug}/listen/`}> <Button href={`/contents/${content.slug}/listen/`}>
{langui.content_listen_content} {langui.listen_content}
</Button> </Button>
) : ( ) : (
"" ""
@ -56,7 +56,7 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element {
{content.video_set.length > 0 ? ( {content.video_set.length > 0 ? (
<Button href={`/contents/${content.slug}/watch/`}> <Button href={`/contents/${content.slug}/watch/`}>
{langui.content_watch_content} {langui.watch_content}
</Button> </Button>
) : ( ) : (
"" ""

View File

@ -18,7 +18,7 @@ export default function Gallery(props: GalleryProps): JSX.Element {
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_gallery} navTitle={langui.gallery}
langui={langui} langui={langui}
contentPanel={contentPanel} contentPanel={contentPanel}
/> />

View File

@ -141,13 +141,11 @@ export default function Home(props: HomeProps): JSX.Element {
); );
return ( return (
<>
<AppLayout <AppLayout
navTitle={"Accords Library"} navTitle={"Home"}
langui={langui} langui={langui}
contentPanel={contentPanel} contentPanel={contentPanel}
/> />
</>
); );
} }

View File

@ -58,16 +58,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<ReturnButton <ReturnButton href="/library/" title={langui.library} langui={langui} />
href="/library/"
title={langui.main_library}
langui={langui}
/>
<HorizontalLine /> <HorizontalLine />
<div className="grid gap-4"> <div className="grid gap-4">
<NavOption <NavOption
title={langui.library_item_summary} title={langui.summary}
url="#summary" url="#summary"
border border
onClick={() => appLayout.setSubPanelOpen(false)} onClick={() => appLayout.setSubPanelOpen(false)}
@ -75,7 +71,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.gallery.data.length > 0 ? ( {item.gallery.data.length > 0 ? (
<NavOption <NavOption
title={langui.library_item_gallery} title={langui.gallery}
url="#gallery" url="#gallery"
border border
onClick={() => appLayout.setSubPanelOpen(false)} onClick={() => appLayout.setSubPanelOpen(false)}
@ -85,7 +81,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
)} )}
<NavOption <NavOption
title={langui.library_item_details} title={langui.details}
url="#details" url="#details"
border border
onClick={() => appLayout.setSubPanelOpen(false)} onClick={() => appLayout.setSubPanelOpen(false)}
@ -93,11 +89,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.subitems.data.length > 0 ? ( {item.subitems.data.length > 0 ? (
<NavOption <NavOption
title={ title={isVariantSet ? langui.variants : langui.subitems}
isVariantSet
? langui.library_item_variants
: langui.library_item_subitems
}
url={isVariantSet ? "#variants" : "#subitems"} url={isVariantSet ? "#variants" : "#subitems"}
border border
onClick={() => appLayout.setSubPanelOpen(false)} onClick={() => appLayout.setSubPanelOpen(false)}
@ -107,11 +99,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
)} )}
{item.contents.data.length > 0 ? ( {item.contents.data.length > 0 ? (
<NavOption <NavOption title={langui.contents} url="#contents" border />
title={langui.library_item_content}
url="#content"
border
/>
) : ( ) : (
"" ""
)} )}
@ -140,7 +128,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
<div className="w-[clamp(0px,100%,42rem)] grid place-items-center gap-8"> <div className="w-[clamp(0px,100%,42rem)] grid place-items-center gap-8">
{item.subitem_of.data.length > 0 ? ( {item.subitem_of.data.length > 0 ? (
<div className="grid place-items-center"> <div className="grid place-items-center">
<p>{langui.global_subitem_of}</p> <p>{langui.subitem_of}</p>
<Button <Button
href={`/library/${item.subitem_of.data[0].attributes.slug}`} href={`/library/${item.subitem_of.data[0].attributes.slug}`}
> >
@ -172,7 +160,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.gallery.data.length > 0 ? ( {item.gallery.data.length > 0 ? (
<div id="gallery" className="grid place-items-center gap-8 w-full"> <div id="gallery" className="grid place-items-center gap-8 w-full">
<h2 className="text-2xl">{langui.library_item_gallery}</h2> <h2 className="text-2xl">{langui.gallery}</h2>
<div className="grid w-full gap-8 items-end grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]"> <div className="grid w-full gap-8 items-end grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]">
{item.gallery.data.map((galleryItem) => ( {item.gallery.data.map((galleryItem) => (
<div <div
@ -197,12 +185,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
<InsetBox id="details" className="grid place-items-center"> <InsetBox id="details" className="grid place-items-center">
<div className="w-[clamp(0px,100%,42rem)] grid place-items gap-8"> <div className="w-[clamp(0px,100%,42rem)] grid place-items gap-8">
<h2 className="text-2xl text-center"> <h2 className="text-2xl text-center">
{langui.library_item_details} {langui.details}
</h2> </h2>
<div className="grid grid-flow-col w-full place-content-between"> <div className="grid grid-flow-col w-full place-content-between">
{item.metadata.length > 0 ? ( {item.metadata.length > 0 ? (
<div className="grid place-items-center"> <div className="grid place-items-center">
<h3 className="text-xl">{langui.global_type}</h3> <h3 className="text-xl">{langui.type}</h3>
<div className="grid grid-flow-col gap-1"> <div className="grid grid-flow-col gap-1">
<Chip>{prettyItemType(item.metadata[0], langui)}</Chip> <Chip>{prettyItemType(item.metadata[0], langui)}</Chip>
{""} {""}
@ -215,7 +203,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.release_date ? ( {item.release_date ? (
<div className="grid place-items-center"> <div className="grid place-items-center">
<h3 className="text-xl">{langui.global_release_date}</h3> <h3 className="text-xl">{langui.release_date}</h3>
<p>{prettyDate(item.release_date)}</p> <p>{prettyDate(item.release_date)}</p>
</div> </div>
) : ( ) : (
@ -224,7 +212,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.price ? ( {item.price ? (
<div className="grid place-items-center"> <div className="grid place-items-center">
<h3 className="text-xl">{langui.global_price}</h3> <h3 className="text-xl">{langui.price}</h3>
<p>{prettyPrice(item.price)}</p> <p>{prettyPrice(item.price)}</p>
</div> </div>
) : ( ) : (
@ -233,17 +221,17 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
</div> </div>
{item.size ? ( {item.size ? (
<> <>
<h3 className="text-xl">{langui.library_item_physical_size}</h3> <h3 className="text-xl">{langui.size}</h3>
<div className="grid grid-flow-col w-full place-content-between"> <div className="grid grid-flow-col w-full place-content-between">
<div className="flex flex-row flex-wrap place-items-start gap-4"> <div className="flex flex-row flex-wrap place-items-start gap-4">
<p className="font-bold">{langui.global_width}:</p> <p className="font-bold">{langui.width}:</p>
<div> <div>
<p>{item.size.width} mm</p> <p>{item.size.width} mm</p>
<p>{convertMmToInch(item.size.width)} in</p> <p>{convertMmToInch(item.size.width)} in</p>
</div> </div>
</div> </div>
<div className="flex flex-row flex-wrap place-items-start gap-4"> <div className="flex flex-row flex-wrap place-items-start gap-4">
<p className="font-bold">{langui.global_height}:</p> <p className="font-bold">{langui.height}:</p>
<div> <div>
<p>{item.size.height} mm</p> <p>{item.size.height} mm</p>
<p>{convertMmToInch(item.size.height)} in</p> <p>{convertMmToInch(item.size.height)} in</p>
@ -251,7 +239,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
</div> </div>
{item.size.thickness ? ( {item.size.thickness ? (
<div className="flex flex-row flex-wrap place-items-start gap-4"> <div className="flex flex-row flex-wrap place-items-start gap-4">
<p className="font-bold">{langui.global_thickness}:</p> <p className="font-bold">{langui.thickness}:</p>
<div> <div>
<p>{item.size.thickness} mm</p> <p>{item.size.thickness} mm</p>
<p>{convertMmToInch(item.size.thickness)} in</p> <p>{convertMmToInch(item.size.thickness)} in</p>
@ -269,44 +257,44 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
{item.metadata.length > 0 ? ( {item.metadata.length > 0 ? (
<> <>
<h3 className="text-xl"> <h3 className="text-xl">
{langui.library_item_type_information} {langui.type_information}
</h3> </h3>
<div className="grid grid-cols-2 w-full place-content-between"> <div className="grid grid-cols-2 w-full place-content-between">
{item.metadata[0].__typename === "ComponentMetadataBooks" ? ( {item.metadata[0].__typename === "ComponentMetadataBooks" ? (
<> <>
<div className="flex flex-row place-content-start gap-4"> <div className="flex flex-row place-content-start gap-4">
<p className="font-bold">{langui.global_pages}:</p> <p className="font-bold">{langui.pages}:</p>
<p>{item.metadata[0].page_count}</p> <p>{item.metadata[0].page_count}</p>
</div> </div>
<div className="flex flex-row place-content-start gap-4"> <div className="flex flex-row place-content-start gap-4">
<p className="font-bold">{langui.global_binding}:</p> <p className="font-bold">{langui.binding}:</p>
<p> <p>
{item.metadata[0].binding_type === {item.metadata[0].binding_type ===
Enum_Componentmetadatabooks_Binding_Type.Paperback Enum_Componentmetadatabooks_Binding_Type.Paperback
? langui.global_paperback ? langui.paperback
: item.metadata[0].binding_type === : item.metadata[0].binding_type ===
Enum_Componentmetadatabooks_Binding_Type.Hardcover Enum_Componentmetadatabooks_Binding_Type.Hardcover
? langui.global_hardcover ? langui.hardcover
: ""} : ""}
</p> </p>
</div> </div>
<div className="flex flex-row place-content-start gap-4"> <div className="flex flex-row place-content-start gap-4">
<p className="font-bold">{langui.global_page_order}:</p> <p className="font-bold">{langui.page_order}:</p>
<p> <p>
{item.metadata[0].page_order === {item.metadata[0].page_order ===
Enum_Componentmetadatabooks_Page_Order.LeftToRight Enum_Componentmetadatabooks_Page_Order.LeftToRight
? langui.global_left_to_right ? langui.left_to_right
: item.metadata[0].page_order === : item.metadata[0].page_order ===
Enum_Componentmetadatabooks_Page_Order.RightToLeft Enum_Componentmetadatabooks_Page_Order.RightToLeft
? langui.global_right_to_left ? langui.right_to_left
: ""} : ""}
</p> </p>
</div> </div>
<div className="flex flex-row place-content-start gap-4"> <div className="flex flex-row place-content-start gap-4">
<p className="font-bold">{langui.global_languages}:</p> <p className="font-bold">{langui.languages}:</p>
{item.metadata[0].languages.data.map((lang) => ( {item.metadata[0].languages.data.map((lang) => (
<p key={lang.attributes.code}> <p key={lang.attributes.code}>
{lang.attributes.name} {lang.attributes.name}
@ -327,7 +315,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
"ComponentMetadataOther" ? ( "ComponentMetadataOther" ? (
<> <>
<div className="flex flex-row place-content-start gap-4"> <div className="flex flex-row place-content-start gap-4">
<p className="font-bold">{langui.global_type}:</p> <p className="font-bold">{langui.type}:</p>
<Chip> <Chip>
{item.metadata[0].subtype.data.attributes.titles {item.metadata[0].subtype.data.attributes.titles
.length > 0 .length > 0
@ -357,8 +345,8 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
> >
<h2 className="text-2xl"> <h2 className="text-2xl">
{isVariantSet {isVariantSet
? langui.library_item_variants ? langui.variants
: langui.library_item_subitems} : langui.subitems}
</h2> </h2>
<div className="grid gap-8 items-end mobile:grid-cols-2 grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full"> <div className="grid gap-8 items-end mobile:grid-cols-2 grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
{item.subitems.data.map((subitem) => ( {item.subitems.data.map((subitem) => (
@ -374,8 +362,8 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
)} )}
{item.contents.data.length > 0 ? ( {item.contents.data.length > 0 ? (
<div id="content" className="w-full grid place-items-center gap-8"> <div id="contents" className="w-full grid place-items-center gap-8">
<h2 className="text-2xl">{langui.library_item_content}</h2> <h2 className="text-2xl">{langui.contents}</h2>
<div className="grid gap-4 w-full"> <div className="grid gap-4 w-full">
{item.contents.data.map((content) => ( {item.contents.data.map((content) => (
<div <div
@ -440,7 +428,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
<Button <Button
href={`/contents/${content.attributes.content.data.attributes.slug}/scans/`} href={`/contents/${content.attributes.content.data.attributes.slug}/scans/`}
> >
{langui.library_item_view_scans} {langui.view_scans}
</Button> </Button>
) : ( ) : (
"" ""
@ -450,7 +438,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
<Button <Button
href={`/contents/${content.attributes.content.data.attributes.slug}`} href={`/contents/${content.attributes.content.data.attributes.slug}`}
> >
{langui.library_item_open_content} {langui.open_content}
</Button> </Button>
) : ( ) : (
"" ""
@ -474,7 +462,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_library} navTitle={langui.library}
title={prettyinlineTitle("", item.title, item.subtitle)} title={prettyinlineTitle("", item.title, item.subtitle)}
langui={langui} langui={langui}
contentPanel={contentPanel} contentPanel={contentPanel}

View File

@ -14,35 +14,113 @@ import {
import PanelHeader from "components/PanelComponents/PanelHeader"; import PanelHeader from "components/PanelComponents/PanelHeader";
import AppLayout from "components/AppLayout"; import AppLayout from "components/AppLayout";
import LibraryItemsPreview from "components/Library/LibraryItemsPreview"; import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
import Select from "components/Select";
import { useEffect, useState } from "react";
import { prettyDate, prettyinlineTitle } from "queries/helpers";
import Switch from "components/Switch";
type LibraryProps = { type LibraryProps = {
libraryItems: GetLibraryItemsPreviewQuery; libraryItems: GetLibraryItemsPreviewQuery;
langui: GetWebsiteInterfaceQuery; langui: GetWebsiteInterfaceQuery;
}; };
type GroupLibraryItems = Map<
string,
GetLibraryItemsPreviewQuery["libraryItems"]["data"]
>;
export default function Library(props: LibraryProps): JSX.Element { export default function Library(props: LibraryProps): JSX.Element {
const langui = props.langui.websiteInterfaces.data[0].attributes; const langui = props.langui.websiteInterfaces.data[0].attributes;
const [showSubitems, setShowSubitems] = useState<boolean>(false);
const [sortingMethod, setSortingMethod] = useState<number>(0);
const [groupingMethod, setGroupingMethod] = useState<number>(-1);
const [filteredItems, setFilteredItems] = useState<
LibraryProps["libraryItems"]["libraryItems"]["data"]
>(filterItems(showSubitems, props.libraryItems.libraryItems.data));
const [sortedItems, setSortedItem] = useState<
LibraryProps["libraryItems"]["libraryItems"]["data"]
>(sortBy(groupingMethod, filteredItems));
const [groups, setGroups] = useState<GroupLibraryItems>(
getGroups(langui, groupingMethod, sortedItems)
);
useEffect(() => {
setFilteredItems(
filterItems(showSubitems, props.libraryItems.libraryItems.data)
);
}, [showSubitems, props.libraryItems.libraryItems.data]);
useEffect(() => {
setSortedItem(sortBy(sortingMethod, filteredItems));
}, [filteredItems, sortingMethod]);
useEffect(() => {
setGroups(getGroups(langui, groupingMethod, sortedItems));
}, [langui, groupingMethod, sortedItems]);
const subPanel = ( const subPanel = (
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="library_books" icon="library_books"
title={langui.main_library} title={langui.library}
description={langui.library_description} description={langui.library_description}
/> />
<div className="flex flex-row gap-2 place-items-center">
<p className="flex-shrink-0">{langui.group_by}:</p>
<Select
className="w-full"
options={[langui.category, langui.type, langui.release_year]}
state={groupingMethod}
setState={setGroupingMethod}
allowEmpty
/>
</div>
<div className="flex flex-row gap-2 place-items-center">
<p className="flex-shrink-0">{langui.order_by}:</p>
<Select
className="w-full"
options={[langui.name, langui.price, langui.release_date]}
state={sortingMethod}
setState={setSortingMethod}
/>
</div>
<div className="flex flex-row gap-2 place-items-center">
<p className="flex-shrink-0">{langui.show_subitems}:</p>
<Switch state={showSubitems} setState={setShowSubitems} />
</div>
</SubPanel> </SubPanel>
); );
const contentPanel = ( const contentPanel = (
<ContentPanel width={ContentPanelWidthSizes.large}> <ContentPanel width={ContentPanelWidthSizes.large}>
<div className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))]"> {[...groups].map(([name, items]) => (
{props.libraryItems.libraryItems.data.map((item) => ( <>
{items.length > 0 && (
<>
<h2 className="text-2xl pb-2 pt-10 first-of-type:pt-0">{name}</h2>
<div
key={name}
className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0"
>
{items.map((item) => (
<LibraryItemsPreview key={item.id} item={item.attributes} /> <LibraryItemsPreview key={item.id} item={item.attributes} />
))} ))}
</div> </div>
</>
)}
</>
))}
</ContentPanel> </ContentPanel>
); );
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_library} navTitle={langui.library}
langui={langui} langui={langui}
subPanel={subPanel} subPanel={subPanel}
contentPanel={contentPanel} contentPanel={contentPanel}
@ -67,3 +145,159 @@ export const getStaticProps: GetStaticProps = async (context) => {
return { props: {} }; return { props: {} };
} }
}; };
function getGroups(
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"],
groupByType: number,
items: LibraryProps["libraryItems"]["libraryItems"]["data"]
): GroupLibraryItems {
switch (groupByType) {
case 0:
return new Map();
case 1:
const groupType: GroupLibraryItems = new Map();
groupType.set(langui.audio, []);
groupType.set(langui.game, []);
groupType.set(langui.textual, []);
groupType.set(langui.video, []);
groupType.set(langui.other, []);
groupType.set(langui.no_type, []);
items.map((item) => {
if (item.attributes.metadata.length > 0) {
switch (item.attributes.metadata[0].__typename) {
case "ComponentMetadataAudio":
groupType.get(langui.audio)?.push(item);
break;
case "ComponentMetadataGame":
groupType.get(langui.game)?.push(item);
break;
case "ComponentMetadataBooks":
groupType.get(langui.textual)?.push(item);
break;
case "ComponentMetadataVideo":
groupType.get(langui.video)?.push(item);
break;
case "ComponentMetadataOther":
switch (
item.attributes.metadata[0].subtype.data.attributes.slug
) {
case "audio-case":
groupType.get(langui.audio)?.push(item);
break;
case "video-case":
groupType.get(langui.video)?.push(item);
break;
case "game-case":
groupType.get(langui.game)?.push(item);
break;
default:
groupType.get(langui.other)?.push(item);
break;
}
break;
}
} else {
groupType.get(langui.no_type)?.push(item);
}
});
return groupType;
case 2:
const years: number[] = [];
items.map((item) => {
if (item.attributes.release_date) {
if (!years.includes(item.attributes.release_date.year))
years.push(item.attributes.release_date.year);
}
});
const groupYear: GroupLibraryItems = new Map();
years.sort();
years.map((year) => {
groupYear.set(year.toString(), []);
});
groupYear.set(langui.no_year, []);
items.map((item) => {
if (item.attributes.release_date) {
groupYear
.get(item.attributes.release_date.year.toString())
?.push(item);
} else {
groupYear.get(langui.no_year)?.push(item);
}
});
return groupYear;
default:
const groupDefault: GroupLibraryItems = new Map();
groupDefault.set("", items);
return groupDefault;
}
}
function filterItems(
showSubitems: boolean,
items: LibraryProps["libraryItems"]["libraryItems"]["data"]
): LibraryProps["libraryItems"]["libraryItems"]["data"] {
return [...items].filter((item) => {
let result = true;
if (!showSubitems && !item.attributes.root_item) result = false;
if (
item.attributes.metadata.length > 0 &&
item.attributes.metadata[0].__typename === "ComponentMetadataOther" &&
(item.attributes.metadata[0].subtype.data.attributes.slug ===
"variant-set" ||
item.attributes.metadata[0].subtype.data.attributes.slug ===
"relation-set")
)
result = false;
return result;
});
}
function sortBy(
orderByType: number,
items: LibraryProps["libraryItems"]["libraryItems"]["data"]
): LibraryProps["libraryItems"]["libraryItems"]["data"] {
switch (orderByType) {
case 0:
return [...items].sort((a, b) => {
const titleA = prettyinlineTitle(
"",
a.attributes.title,
a.attributes.subtitle
);
const titleB = prettyinlineTitle(
"",
b.attributes.title,
b.attributes.subtitle
);
return titleA.localeCompare(titleB);
});
case 1:
return [...items].sort((a, b) => {
const priceA = a.attributes.price ? a.attributes.price.amount : 99999;
const priceB = b.attributes.price ? b.attributes.price.amount : 99999;
return priceA - priceB;
});
case 2:
return [...items].sort((a, b) => {
const dateA =
a.attributes.release_date !== null
? prettyDate(a.attributes.release_date)
: "9999";
const dateB =
b.attributes.release_date !== null
? prettyDate(b.attributes.release_date)
: "9999";
return dateA.localeCompare(dateB);
});
default:
return items;
}
}

View File

@ -15,7 +15,7 @@ export default function Merch(props: MerchProps): JSX.Element {
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="store" icon="store"
title={langui.main_merch} title={langui.merch}
description={langui.merch_description} description={langui.merch_description}
/> />
</SubPanel> </SubPanel>
@ -23,7 +23,7 @@ export default function Merch(props: MerchProps): JSX.Element {
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_merch} navTitle={langui.merch}
langui={langui} langui={langui}
subPanel={subPanel} subPanel={subPanel}
/> />

View File

@ -15,7 +15,7 @@ export default function News(props: NewsProps): JSX.Element {
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="feed" icon="feed"
title={langui.main_news} title={langui.news}
description={langui.news_description} description={langui.news_description}
/> />
</SubPanel> </SubPanel>
@ -23,7 +23,7 @@ export default function News(props: NewsProps): JSX.Element {
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_news} navTitle={langui.news}
langui={langui} langui={langui}
subPanel={subPanel} subPanel={subPanel}
/> />

View File

@ -16,7 +16,7 @@ export default function Hubs(props: WikiProps): JSX.Element {
<SubPanel> <SubPanel>
<PanelHeader <PanelHeader
icon="travel_explore" icon="travel_explore"
title={langui.main_wiki} title={langui.wiki}
description={langui.wiki_description} description={langui.wiki_description}
/> />
</SubPanel> </SubPanel>
@ -25,7 +25,7 @@ export default function Hubs(props: WikiProps): JSX.Element {
return ( return (
<AppLayout <AppLayout
navTitle={langui.main_wiki} navTitle={langui.wiki}
langui={langui} langui={langui}
contentPanel={contentPanel} contentPanel={contentPanel}
subPanel={subPanel} subPanel={subPanel}

View File

@ -64,15 +64,15 @@ export function prettyItemType(
const type = metadata.__typename; const type = metadata.__typename;
switch (metadata.__typename) { switch (metadata.__typename) {
case "ComponentMetadataAudio": case "ComponentMetadataAudio":
return langui.library_item_type_audio; return langui.audio;
case "ComponentMetadataBooks": case "ComponentMetadataBooks":
return langui.library_item_type_textual; return langui.textual;
case "ComponentMetadataGame": case "ComponentMetadataGame":
return langui.library_item_type_game; return langui.game;
case "ComponentMetadataVideo": case "ComponentMetadataVideo":
return langui.library_item_type_video; return langui.video;
case "ComponentMetadataOther": case "ComponentMetadataOther":
return langui.library_item_type_other; return langui.other;
default: default:
return ""; return "";
} }