Support for mobile view, new app layout system
This commit is contained in:
parent
cc9bed6667
commit
f13b93887f
|
@ -0,0 +1,108 @@
|
|||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import MainPanel from "./Panels/MainPanel";
|
||||
import { useState } from "react";
|
||||
import Head from "next/head";
|
||||
|
||||
type AppLayoutProps = {
|
||||
subPanel?: React.ReactNode;
|
||||
subPanelIcon?: string;
|
||||
contentPanel?: React.ReactNode;
|
||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||
title: string;
|
||||
};
|
||||
|
||||
export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||
const titlePrefix = "Accord’s Library";
|
||||
|
||||
const [mainPanelOpen, setMainPanelOpen] = useState(false);
|
||||
const [subPanelOpen, setsubPanelOpen] = useState(false);
|
||||
|
||||
const mainPanelClass =
|
||||
"fixed desktop:left-0 desktop:top-0 desktop:bottom-0 desktop:w-[20rem]";
|
||||
const subPanelClass =
|
||||
"fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:w-[20rem]";
|
||||
let contentPanelClass = "";
|
||||
if (props.subPanel && props.contentPanel) {
|
||||
contentPanelClass =
|
||||
"fixed desktop:left-[40rem] desktop:top-0 desktop:bottom-0 desktop:right-0";
|
||||
} else if (props.contentPanel) {
|
||||
contentPanelClass =
|
||||
"fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:right-0";
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>
|
||||
{props.title ? `${titlePrefix} - ${props.title}` : titlePrefix}
|
||||
</title>
|
||||
</Head>
|
||||
|
||||
{/* Navbar */}
|
||||
<div className="fixed bottom-0 left-0 right-0 h-20 bg-light border-t-[1px] border-dark grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden">
|
||||
<span
|
||||
id="navbar-main-button"
|
||||
className="material-icons mt-[.1em] cursor-pointer"
|
||||
onClick={() => setMainPanelOpen(true)}
|
||||
>
|
||||
menu
|
||||
</span>
|
||||
<p className="text-2xl font-black font-headers">{props.title}</p>
|
||||
<span
|
||||
className="material-icons mt-[.1em] cursor-pointer"
|
||||
onClick={() => setsubPanelOpen(true)}
|
||||
>
|
||||
{props.subPanel
|
||||
? props.subPanelIcon
|
||||
? props.subPanelIcon
|
||||
: "tune"
|
||||
: ""}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Content panel */}
|
||||
{props.contentPanel ? (
|
||||
<div
|
||||
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll ${contentPanelClass}`}
|
||||
>
|
||||
{props.contentPanel}
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{/* Background when navbar is opened */}
|
||||
<div
|
||||
className={`fixed bg-dark inset-0 transition-opacity duration-500 ${
|
||||
mainPanelOpen || subPanelOpen
|
||||
? " opacity-50"
|
||||
: "opacity-0 translate-x-full"
|
||||
}`}
|
||||
onClick={() => {
|
||||
setMainPanelOpen(false);
|
||||
setsubPanelOpen(false);
|
||||
}}
|
||||
></div>
|
||||
|
||||
{/* Main panel */}
|
||||
<div
|
||||
className={`${mainPanelClass} border-r-[1px] border-black top-0 bottom-0 left-0 right-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-500
|
||||
${mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
||||
>
|
||||
<MainPanel langui={props.langui} />
|
||||
</div>
|
||||
|
||||
{/* Sub panel */}
|
||||
{props.subPanel ? (
|
||||
<div
|
||||
className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black top-0 bottom-0 right-0 left-12 bg-light overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-500
|
||||
${subPanelOpen ? "" : "mobile:translate-x-full"}`}
|
||||
>
|
||||
{props.subPanel}
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -104,9 +104,14 @@ export default function ChronologyItemComponent(
|
|||
))}
|
||||
|
||||
<p className="text-dark text-xs inline-grid place-items-center grid-flow-col gap-1">
|
||||
{event.source.data
|
||||
? "(" + event.source.data.attributes.name + ")"
|
||||
: <><span className="material-icons !text-sm">warning</span>No sources!</>}
|
||||
{event.source.data ? (
|
||||
"(" + event.source.data.attributes.name + ")"
|
||||
) : (
|
||||
<>
|
||||
<span className="material-icons !text-sm">warning</span>No
|
||||
sources!
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { getAssetURL, prettySlug } from "queries/helpers";
|
|||
import Image from "next/image";
|
||||
import Button from "components/Button";
|
||||
|
||||
export type Props = {
|
||||
export type ThumbnailHeaderProps = {
|
||||
content: {
|
||||
slug: GetContentQuery["contents"]["data"][number]["attributes"]["slug"];
|
||||
thumbnail: GetContentQuery["contents"]["data"][number]["attributes"]["thumbnail"];
|
||||
|
@ -17,7 +17,9 @@ export type Props = {
|
|||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||
};
|
||||
|
||||
export default function ThumbnailHeader(props: Props): JSX.Element {
|
||||
export default function ThumbnailHeader(
|
||||
props: ThumbnailHeaderProps
|
||||
): JSX.Element {
|
||||
const content = props.content;
|
||||
const langui = props.langui;
|
||||
|
||||
|
|
|
@ -7,11 +7,7 @@ export default function HorizontalLine(
|
|||
): JSX.Element {
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"h-0 w-full my-8 border-t-[3px] border-dotted border-black" +
|
||||
" " +
|
||||
props.className
|
||||
}
|
||||
className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black ${props.className}`}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,5 +3,13 @@ type ScenBreakProps = {
|
|||
};
|
||||
|
||||
export default function SceneBreak(props: ScenBreakProps): JSX.Element {
|
||||
return <div className={"h-0 text-center text-3xl text-dark mt-16 mb-20" + " " + props.className}>* * *</div>;
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"h-0 text-center text-3xl text-dark mt-16 mb-20" + " " + props.className
|
||||
}
|
||||
>
|
||||
* * *
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ type NavOptionProps = {
|
|||
export default function NavOption(props: NavOptionProps): JSX.Element {
|
||||
const router = useRouter();
|
||||
const isActive = router.asPath.startsWith(props.url);
|
||||
const divActive = "bg-mid"
|
||||
const divActive = "bg-mid";
|
||||
const border = "border-2 border-mid";
|
||||
const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid transition-colors ${props.border ? border: ""} ${isActive ? divActive : ""}`;
|
||||
const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid transition-colors ${
|
||||
props.border ? border : ""
|
||||
} ${isActive ? divActive : ""}`;
|
||||
|
||||
if (props.icon) {
|
||||
return (
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import HorizontalLine from "components/HorizontalLine";
|
||||
|
||||
type NavOptionProps = {
|
||||
type PanelHeaderProps = {
|
||||
icon?: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export default function PanelHeader(props: NavOptionProps): JSX.Element {
|
||||
export default function PanelHeader(props: PanelHeaderProps): JSX.Element {
|
||||
return (
|
||||
<div className="w-full grid place-items-center">
|
||||
{props.icon ? (
|
||||
|
|
|
@ -8,5 +8,9 @@ type ReturnButtonProps = {
|
|||
};
|
||||
|
||||
export default function ReturnButton(props: ReturnButtonProps): JSX.Element {
|
||||
return <Button href={props.href}>❮ {props.langui.global_return_label} {props.title}</Button>;
|
||||
return (
|
||||
<Button href={props.href}>
|
||||
❮ {props.langui.global_return_label} {props.title}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,11 +11,12 @@ export enum ContentPanelWidthSizes {
|
|||
|
||||
export default function ContentPanel(props: ContentPanelProps): JSX.Element {
|
||||
const width = props.width ? props.width : ContentPanelWidthSizes.default;
|
||||
const widthCSS = width === ContentPanelWidthSizes.default ? "w-[45rem]" : "w-full";
|
||||
const widthCSS =
|
||||
width === ContentPanelWidthSizes.default ? "max-w-[45rem]" : "w-full";
|
||||
const prose = props.autoformat ? "prose" : "";
|
||||
|
||||
return (
|
||||
<div className={`grid overflow-y-scroll max-h-screen h-screen py-20 px-10`}>
|
||||
<div className={`grid pt-10 pb-20 px-6 desktop:py-20 desktop:px-10`}>
|
||||
<main className={`${prose} ${widthCSS} place-self-center text-justify`}>
|
||||
{props.children}
|
||||
</main>
|
||||
|
|
|
@ -7,15 +7,15 @@ import HorizontalLine from "components/HorizontalLine";
|
|||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import Markdown from "markdown-to-jsx";
|
||||
|
||||
type Props = {
|
||||
type MainPanelProps = {
|
||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||
};
|
||||
|
||||
export default function MainPanel(props: Props): JSX.Element {
|
||||
export default function MainPanel(props: MainPanelProps): JSX.Element {
|
||||
const langui = props.langui;
|
||||
const router = useRouter();
|
||||
return (
|
||||
<div className="grid webkit-scrollbar:w-0 [scrollbar-width:none] overflow-y-scroll border-r-[1px] border-black max-h-screen h-screen justify-center content-start p-8 gap-y-2 justify-items-center text-center">
|
||||
<div className="grid justify-center content-start p-8 gap-y-2 justify-items-center text-center">
|
||||
<div className="">
|
||||
<div className="grid place-items-center">
|
||||
<Link href="/" passHref>
|
||||
|
|
|
@ -4,7 +4,7 @@ type SubPanelProps = {
|
|||
|
||||
export default function SubPanel(props: SubPanelProps): JSX.Element {
|
||||
return (
|
||||
<div className="grid webkit-scrollbar:w-0 [scrollbar-width:none] overflow-y-scroll border-r-[1px] border-black max-h-screen h-screen justify-center content-start p-8 gap-y-2 justify-items-center text-center">
|
||||
<div className="grid justify-center content-start p-8 gap-y-2 justify-items-center text-center">
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -9,12 +9,7 @@ export type SVGProps = {
|
|||
export default function SVG(props: SVGProps): JSX.Element {
|
||||
return (
|
||||
<div className={props.className}>
|
||||
<Image
|
||||
src={props.src}
|
||||
alt={props.src}
|
||||
height={1000}
|
||||
width={1000}
|
||||
/>
|
||||
<Image src={props.src} alt={props.src} height={1000} width={1000} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -268,12 +268,14 @@ query getLibraryItem($slug: String, $language_code: String) {
|
|||
}
|
||||
}
|
||||
... on ComponentMetadataVideo {
|
||||
resolution
|
||||
audio_languages {
|
||||
subtype {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
name
|
||||
titles(
|
||||
filters: { language: { code: { eq: $language_code } } }
|
||||
) {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,14 +326,6 @@ query getLibraryItem($slug: String, $language_code: String) {
|
|||
}
|
||||
}
|
||||
}
|
||||
languages {
|
||||
data {
|
||||
attributes {
|
||||
code
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
... on ComponentMetadataOther {
|
||||
subtype {
|
||||
|
|
|
@ -403,17 +403,18 @@ export type GetLibraryItemQuery = {
|
|||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataVideo";
|
||||
resolution: Enum_Componentmetadatavideo_Resolution;
|
||||
audio_languages: {
|
||||
__typename: "LanguageRelationResponseCollection";
|
||||
data: Array<{
|
||||
__typename: "LanguageEntity";
|
||||
subtype: {
|
||||
__typename: "VideoSubtypeEntityResponse";
|
||||
data: {
|
||||
__typename: "VideoSubtypeEntity";
|
||||
attributes: {
|
||||
__typename: "Language";
|
||||
code: string;
|
||||
name: string;
|
||||
__typename: "VideoSubtype";
|
||||
titles: Array<{
|
||||
__typename: "ComponentTranslationsSimpleTitle";
|
||||
title: string;
|
||||
}>;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
}
|
||||
| {
|
||||
|
@ -478,17 +479,6 @@ export type GetLibraryItemQuery = {
|
|||
};
|
||||
};
|
||||
};
|
||||
languages: {
|
||||
__typename: "LanguageRelationResponseCollection";
|
||||
data: Array<{
|
||||
__typename: "LanguageEntity";
|
||||
attributes: {
|
||||
__typename: "Language";
|
||||
code: string;
|
||||
name: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
}
|
||||
| {
|
||||
__typename: "ComponentMetadataOther";
|
||||
|
|
|
@ -430,11 +430,6 @@ type ComponentCollectionsComponentWeaponStory {
|
|||
|
||||
type ComponentMetadataAudio {
|
||||
id: ID!
|
||||
languages(
|
||||
filters: LanguageFiltersInput
|
||||
pagination: PaginationArg = {}
|
||||
sort: [String] = []
|
||||
): LanguageRelationResponseCollection
|
||||
subtype: AudioSubtypeEntityResponse
|
||||
}
|
||||
|
||||
|
@ -492,22 +487,9 @@ type ComponentMetadataOther {
|
|||
subtype: OtherSubtypeEntityResponse
|
||||
}
|
||||
|
||||
enum ENUM_COMPONENTMETADATAVIDEO_RESOLUTION {
|
||||
SD_480p
|
||||
HD_720p
|
||||
FullHD_1080p
|
||||
QuadHD_2160p
|
||||
}
|
||||
|
||||
type ComponentMetadataVideo {
|
||||
id: ID!
|
||||
resolution: ENUM_COMPONENTMETADATAVIDEO_RESOLUTION
|
||||
audio_languages(
|
||||
filters: LanguageFiltersInput
|
||||
pagination: PaginationArg = {}
|
||||
sort: [String] = []
|
||||
): LanguageRelationResponseCollection
|
||||
sub_languages: LanguageEntityResponse
|
||||
subtype: VideoSubtypeEntityResponse
|
||||
}
|
||||
|
||||
input ComponentPageBuilderComponentPaneFiltersInput {
|
||||
|
@ -2193,6 +2175,46 @@ type TextualSubtypeEntityResponseCollection {
|
|||
meta: ResponseCollectionMeta!
|
||||
}
|
||||
|
||||
input VideoSubtypeFiltersInput {
|
||||
id: IDFilterInput
|
||||
slug: StringFilterInput
|
||||
createdAt: DateTimeFilterInput
|
||||
updatedAt: DateTimeFilterInput
|
||||
and: [VideoSubtypeFiltersInput]
|
||||
or: [VideoSubtypeFiltersInput]
|
||||
not: VideoSubtypeFiltersInput
|
||||
}
|
||||
|
||||
input VideoSubtypeInput {
|
||||
slug: String
|
||||
titles: [ComponentTranslationsSimpleTitleInput]
|
||||
}
|
||||
|
||||
type VideoSubtype {
|
||||
slug: String!
|
||||
titles(
|
||||
filters: ComponentTranslationsSimpleTitleFiltersInput
|
||||
pagination: PaginationArg = {}
|
||||
sort: [String] = []
|
||||
): [ComponentTranslationsSimpleTitle]
|
||||
createdAt: DateTime
|
||||
updatedAt: DateTime
|
||||
}
|
||||
|
||||
type VideoSubtypeEntity {
|
||||
id: ID
|
||||
attributes: VideoSubtype
|
||||
}
|
||||
|
||||
type VideoSubtypeEntityResponse {
|
||||
data: VideoSubtypeEntity
|
||||
}
|
||||
|
||||
type VideoSubtypeEntityResponseCollection {
|
||||
data: [VideoSubtypeEntity!]!
|
||||
meta: ResponseCollectionMeta!
|
||||
}
|
||||
|
||||
input WeaponStoryFiltersInput {
|
||||
id: IDFilterInput
|
||||
slug: StringFilterInput
|
||||
|
@ -2379,6 +2401,24 @@ input WebsiteInterfaceFiltersInput {
|
|||
chronology_overview_description: StringFilterInput
|
||||
chronology_walkthrough: StringFilterInput
|
||||
chronology_walkthrough_description: StringFilterInput
|
||||
library_item_front_matter: StringFilterInput
|
||||
library_item_back_matter: StringFilterInput
|
||||
library_item_type_textual: StringFilterInput
|
||||
library_item_type_audio: StringFilterInput
|
||||
library_item_type_game: StringFilterInput
|
||||
library_item_type_video: StringFilterInput
|
||||
library_item_type_other: StringFilterInput
|
||||
library_item_open_content: StringFilterInput
|
||||
library_item_view_scans: StringFilterInput
|
||||
content_read_content: StringFilterInput
|
||||
content_watch_content: StringFilterInput
|
||||
content_listen_content: StringFilterInput
|
||||
global_category: StringFilterInput
|
||||
global_categories: StringFilterInput
|
||||
global_paperback: StringFilterInput
|
||||
global_hardcover: StringFilterInput
|
||||
global_left_to_right: StringFilterInput
|
||||
global_right_to_left: StringFilterInput
|
||||
createdAt: DateTimeFilterInput
|
||||
updatedAt: DateTimeFilterInput
|
||||
and: [WebsiteInterfaceFiltersInput]
|
||||
|
@ -2432,6 +2472,24 @@ input WebsiteInterfaceInput {
|
|||
chronology_overview_description: String
|
||||
chronology_walkthrough: String
|
||||
chronology_walkthrough_description: 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
|
||||
}
|
||||
|
||||
type WebsiteInterface {
|
||||
|
@ -2480,6 +2538,24 @@ type WebsiteInterface {
|
|||
chronology_overview_description: String
|
||||
chronology_walkthrough: String
|
||||
chronology_walkthrough_description: 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
|
||||
createdAt: DateTime
|
||||
updatedAt: DateTime
|
||||
}
|
||||
|
@ -2567,6 +2643,7 @@ union GenericMorph =
|
|||
| Recorder
|
||||
| Source
|
||||
| TextualSubtype
|
||||
| VideoSubtype
|
||||
| WeaponStory
|
||||
| WeaponStoryGroup
|
||||
| WeaponStoryType
|
||||
|
@ -2707,6 +2784,12 @@ type Query {
|
|||
pagination: PaginationArg = {}
|
||||
sort: [String] = []
|
||||
): TextualSubtypeEntityResponseCollection
|
||||
videoSubtype(id: ID): VideoSubtypeEntityResponse
|
||||
videoSubtypes(
|
||||
filters: VideoSubtypeFiltersInput
|
||||
pagination: PaginationArg = {}
|
||||
sort: [String] = []
|
||||
): VideoSubtypeEntityResponseCollection
|
||||
weaponStory(id: ID): WeaponStoryEntityResponse
|
||||
weaponStories(
|
||||
filters: WeaponStoryFiltersInput
|
||||
|
@ -2823,6 +2906,12 @@ type Mutation {
|
|||
data: TextualSubtypeInput!
|
||||
): TextualSubtypeEntityResponse
|
||||
deleteTextualSubtype(id: ID!): TextualSubtypeEntityResponse
|
||||
createVideoSubtype(data: VideoSubtypeInput!): VideoSubtypeEntityResponse
|
||||
updateVideoSubtype(
|
||||
id: ID!
|
||||
data: VideoSubtypeInput!
|
||||
): VideoSubtypeEntityResponse
|
||||
deleteVideoSubtype(id: ID!): VideoSubtypeEntityResponse
|
||||
createWeaponStory(data: WeaponStoryInput!): WeaponStoryEntityResponse
|
||||
updateWeaponStory(id: ID!, data: WeaponStoryInput!): WeaponStoryEntityResponse
|
||||
deleteWeaponStory(id: ID!): WeaponStoryEntityResponse
|
||||
|
|
|
@ -1,42 +1,30 @@
|
|||
import Link from "next/link";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import { applyCustomAppProps } from "./_app";
|
||||
import Head from "next/head";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import { GetStaticProps } from "next";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(FourOhFour, {
|
||||
useSubPanel: false,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type FourOhFourProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function FourOhFour(props: Props): JSX.Element {
|
||||
export default function FourOhFour(props: FourOhFourProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Accord’s Library - 404</title>
|
||||
</Head>
|
||||
<MainPanel langui={langui} />
|
||||
<ContentPanel>
|
||||
<h1>404 - Page Not Found</h1>
|
||||
<Link href="/">
|
||||
<a>Go back home</a>
|
||||
</Link>
|
||||
</ContentPanel>
|
||||
</>
|
||||
const contentPanel = (
|
||||
<ContentPanel>
|
||||
<h1>404 - Page Not Found</h1>
|
||||
<Link href="/">
|
||||
<a>Go back home</a>
|
||||
</Link>
|
||||
</ContentPanel>
|
||||
);
|
||||
return <AppLayout title="404" langui={langui} contentPanel={contentPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: FourOhFourProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,37 +1,9 @@
|
|||
import type { AppProps } from "next/app";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import "tailwind.css";
|
||||
import "@fontsource/zen-maru-gothic/500.css";
|
||||
import "@fontsource/vollkorn/700.css";
|
||||
import "@fontsource/material-icons";
|
||||
|
||||
export type CustomAppProps = {
|
||||
useSubPanel: boolean;
|
||||
useContentPanel: boolean;
|
||||
};
|
||||
|
||||
export function applyCustomAppProps(
|
||||
page: Function,
|
||||
customAppProps: CustomAppProps
|
||||
) {
|
||||
page.customAppProps = customAppProps;
|
||||
}
|
||||
|
||||
export default function AccordsLibraryApp(appProps: AppProps) {
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
appProps.Component.customAppProps.useSubPanel &&
|
||||
appProps.Component.customAppProps.useContentPanel
|
||||
? "grid grid-cols-[20rem_20rem_1fr]"
|
||||
: appProps.Component.customAppProps.useSubPanel
|
||||
? "grid grid-cols-[20rem_20rem]"
|
||||
: appProps.Component.customAppProps.useContentPanel
|
||||
? "grid grid-cols-[20rem_1fr]"
|
||||
: "grid grid-cols-[20rem]"
|
||||
}
|
||||
>
|
||||
<appProps.Component {...appProps.pageProps} />
|
||||
</div>
|
||||
);
|
||||
return <appProps.Component {...appProps.pageProps} />;
|
||||
}
|
||||
|
|
|
@ -1,41 +1,31 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(AboutUs, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type AboutUsProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function AboutUs(props: Props): JSX.Element {
|
||||
export default function AboutUs(props: AboutUsProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="info"
|
||||
title={langui.main_about_us}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>Hello</ContentPanel>
|
||||
</>
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="info"
|
||||
title={langui.main_about_us}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
return <AppLayout title="404" langui={langui} subPanel={subPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: AboutUsProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,41 +1,31 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(Archives, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type ArchivesProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Archives(props: Props): JSX.Element {
|
||||
export default function Archives(props: ArchivesProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="inventory"
|
||||
title={langui.main_archives}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>Hello</ContentPanel>
|
||||
</>
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="inventory"
|
||||
title={langui.main_archives}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
return <AppLayout title="Archives" langui={langui} subPanel={subPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: ArchivesProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,41 +1,31 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(Chronicles, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type ChroniclesProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Chronicles(props: Props): JSX.Element {
|
||||
export default function Chronicles(props: ChroniclesProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="watch_later"
|
||||
title="Chronicles"
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>Hello</ContentPanel>
|
||||
</>
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="watch_later"
|
||||
title="Chronicles"
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
return <AppLayout title="Chronicles" langui={langui} subPanel={subPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: ChroniclesProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import {
|
||||
getContent,
|
||||
getContentsSlugs,
|
||||
|
@ -10,62 +9,55 @@ import {
|
|||
GetWebsiteInterfaceQuery,
|
||||
} from "graphql/operations-types";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import Image from "next/image";
|
||||
import { getAssetURL, prettySlug } from "queries/helpers";
|
||||
import Button from "components/Button";
|
||||
import HorizontalLine from "components/HorizontalLine";
|
||||
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
type Props = {
|
||||
type ContentIndexProps = {
|
||||
content: GetContentQuery;
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
applyCustomAppProps(Library, {
|
||||
useSubPanel: false,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
export default function Library(props: Props): JSX.Element {
|
||||
export default function ContentIndex(props: ContentIndexProps): JSX.Element {
|
||||
const content = props.content.contents.data[0].attributes;
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const contentPanel = (
|
||||
<ContentPanel>
|
||||
<div className="grid place-items-center">
|
||||
<ThumbnailHeader content={content} langui={langui} />
|
||||
|
||||
<HorizontalLine />
|
||||
|
||||
{content.text_set.length > 0 ? (
|
||||
<Button href={`/content/${content.slug}/read/`}>
|
||||
{langui.content_read_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.audio_set.length > 0 ? (
|
||||
<Button href={`/content/${content.slug}/listen/`}>
|
||||
{langui.content_listen_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.video_set.length > 0 ? (
|
||||
<Button href={`/content/${content.slug}/watch/`}>
|
||||
{langui.content_watch_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<ContentPanel>
|
||||
<div className="grid place-items-center">
|
||||
<ThumbnailHeader content={content} langui={langui} />
|
||||
|
||||
<HorizontalLine />
|
||||
|
||||
{content.text_set.length > 0 ? (
|
||||
<Button href={`/content/${content.slug}/read/`}>
|
||||
{langui.content_read_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.audio_set.length > 0 ? (
|
||||
<Button href={`/content/${content.slug}/listen/`}>
|
||||
{langui.content_listen_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.video_set.length > 0 ? (
|
||||
<Button href={`/content/${content.slug}/watch/`}>
|
||||
{langui.content_watch_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
</>
|
||||
<AppLayout title="Content" langui={langui} contentPanel={contentPanel} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -75,7 +67,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
|||
if (context.params.slug instanceof Array)
|
||||
context.params.slug = context.params.slug.join("");
|
||||
|
||||
const props: Props = {
|
||||
const props: ContentIndexProps = {
|
||||
content: await getContent({
|
||||
slug: context.params.slug,
|
||||
language_code: context.locale,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import {
|
||||
getContentsSlugs,
|
||||
getContentText,
|
||||
|
@ -10,60 +9,59 @@ import {
|
|||
GetWebsiteInterfaceQuery,
|
||||
} from "graphql/operations-types";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import Image from "next/image";
|
||||
import { getAssetURL, prettySlug } from "queries/helpers";
|
||||
import Button from "components/Button";
|
||||
import HorizontalLine from "components/HorizontalLine";
|
||||
import Markdown from "markdown-to-jsx";
|
||||
import SubPanel from "components/Panels/SubPanel";
|
||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
||||
import SceneBreak from "components/Markdown/SceneBreak";
|
||||
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
type Props = {
|
||||
type ContentReadProps = {
|
||||
content: GetContentTextQuery;
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
applyCustomAppProps(Library, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
export default function Library(props: Props): JSX.Element {
|
||||
export default function ContentRead(props: ContentReadProps): JSX.Element {
|
||||
const content = props.content.contents.data[0].attributes;
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<ReturnButton
|
||||
href={`/content/${content.slug}`}
|
||||
title={"Content"}
|
||||
langui={langui}
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
const contentPanel = (
|
||||
<ContentPanel>
|
||||
<div className="grid place-items-center">
|
||||
<ThumbnailHeader content={content} langui={langui} />
|
||||
|
||||
<HorizontalLine />
|
||||
|
||||
{content.text_set.length > 0 ? (
|
||||
<Markdown
|
||||
className="prose prose-lg text-black pt-12"
|
||||
options={{ overrides: { hr: { component: SceneBreak } } }}
|
||||
>
|
||||
{content.text_set[0].text}
|
||||
</Markdown>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<ReturnButton
|
||||
href={`/content/${content.slug}`}
|
||||
title={"Content"}
|
||||
langui={langui}
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>
|
||||
<div className="grid place-items-center">
|
||||
<ThumbnailHeader content={content} langui={langui} />
|
||||
|
||||
<HorizontalLine />
|
||||
|
||||
{content.text_set.length > 0 ? (
|
||||
<Markdown
|
||||
className="prose prose-lg text-black pt-12"
|
||||
options={{ overrides: { hr: { component: SceneBreak } } }}
|
||||
>
|
||||
{content.text_set[0].text}
|
||||
</Markdown>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
</>
|
||||
<AppLayout
|
||||
title="Read"
|
||||
langui={langui}
|
||||
contentPanel={contentPanel}
|
||||
subPanel={subPanel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -73,7 +71,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
|||
if (context.params.slug instanceof Array)
|
||||
context.params.slug = context.params.slug.join("");
|
||||
|
||||
const props: Props = {
|
||||
const props: ContentReadProps = {
|
||||
content: await getContentText({
|
||||
slug: context.params.slug,
|
||||
language_code: context.locale,
|
||||
|
|
|
@ -2,7 +2,6 @@ import { GetStaticProps } from "next";
|
|||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import SubPanel from "components/Panels/SubPanel";
|
||||
import ChronologyYearComponent from "components/Chronology/ChronologyYearComponent";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import {
|
||||
GetChronologyItemsQuery,
|
||||
GetErasQuery,
|
||||
|
@ -16,22 +15,20 @@ import {
|
|||
import NavOption from "components/PanelComponents/NavOption";
|
||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
||||
import HorizontalLine from "components/HorizontalLine";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
interface Props {
|
||||
interface DataChronologyProps {
|
||||
chronologyItems: GetChronologyItemsQuery;
|
||||
chronologyEras: GetErasQuery;
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
}
|
||||
|
||||
applyCustomAppProps(ChronologyOverview, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
export default function ChronologyOverview(props: Props): JSX.Element {
|
||||
// Group by year the Chronology items
|
||||
export default function DataChronology(
|
||||
props: DataChronologyProps
|
||||
): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
|
||||
// Group by year the Chronology items
|
||||
let chronologyItemYearGroups: GetChronologyItemsQuery["chronologyItems"]["data"][number][][] =
|
||||
[];
|
||||
|
||||
|
@ -45,46 +42,54 @@ export default function ChronologyOverview(props: Props): JSX.Element {
|
|||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<ReturnButton href="/data" title="Data" langui={langui} />
|
||||
<HorizontalLine />
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<ReturnButton href="/data" title="Data" langui={langui} />
|
||||
<HorizontalLine />
|
||||
|
||||
{props.chronologyEras.chronologyEras.data.map((era) => (
|
||||
<NavOption
|
||||
key={era.id}
|
||||
url={"#" + era.attributes.slug}
|
||||
title={era.attributes.title[0] ? era.attributes.title[0].title : ""}
|
||||
subtitle={
|
||||
era.attributes.starting_year + " → " + era.attributes.ending_year
|
||||
}
|
||||
border={true}
|
||||
/>
|
||||
))}
|
||||
</SubPanel>
|
||||
|
||||
<ContentPanel>
|
||||
{chronologyItemYearGroups.map((items, index: number) => {
|
||||
if (items && items[0].attributes.year) {
|
||||
return (
|
||||
<ChronologyYearComponent
|
||||
key={index}
|
||||
year={items[0].attributes.year}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
{props.chronologyEras.chronologyEras.data.map((era) => (
|
||||
<NavOption
|
||||
key={era.id}
|
||||
url={"#" + era.attributes.slug}
|
||||
title={era.attributes.title[0] ? era.attributes.title[0].title : ""}
|
||||
subtitle={
|
||||
era.attributes.starting_year + " → " + era.attributes.ending_year
|
||||
}
|
||||
})}
|
||||
</ContentPanel>
|
||||
</>
|
||||
border={true}
|
||||
/>
|
||||
))}
|
||||
</SubPanel>
|
||||
);
|
||||
|
||||
const contentPanel = (
|
||||
<ContentPanel>
|
||||
{chronologyItemYearGroups.map((items, index: number) => {
|
||||
if (items && items[0].attributes.year) {
|
||||
return (
|
||||
<ChronologyYearComponent
|
||||
key={index}
|
||||
year={items[0].attributes.year}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
return (
|
||||
<AppLayout
|
||||
title="Chronology"
|
||||
langui={langui}
|
||||
contentPanel={contentPanel}
|
||||
subPanel={subPanel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: DataChronologyProps = {
|
||||
chronologyItems: await getChronologyItems({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,68 +1,61 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import NavOption from "components/PanelComponents/NavOption";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(Data, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: false,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type DataProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Data(props: Props): JSX.Element {
|
||||
export default function Data(props: DataProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="travel_explore"
|
||||
title={langui.main_data}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="travel_explore"
|
||||
title={langui.main_data}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
|
||||
<NavOption
|
||||
url="/data/timelines"
|
||||
title={langui.chronology_timelines}
|
||||
subtitle={langui.chronology_timelines_description}
|
||||
border={true}
|
||||
/>
|
||||
<NavOption
|
||||
url="/data/timelines"
|
||||
title={langui.chronology_timelines}
|
||||
subtitle={langui.chronology_timelines_description}
|
||||
border={true}
|
||||
/>
|
||||
|
||||
<NavOption
|
||||
url="/data/chronology"
|
||||
title="Chronology"
|
||||
subtitle={langui.chronology_overview_description}
|
||||
border={true}
|
||||
/>
|
||||
<NavOption
|
||||
url="/data/chronology"
|
||||
title="Chronology"
|
||||
subtitle={langui.chronology_overview_description}
|
||||
border={true}
|
||||
/>
|
||||
|
||||
<NavOption
|
||||
url="/data/weapon-stories"
|
||||
title="Weapon Stories"
|
||||
subtitle="Reiciendis id reiciendis at ullam."
|
||||
border={true}
|
||||
/>
|
||||
<NavOption
|
||||
url="/data/weapon-stories"
|
||||
title="Weapon Stories"
|
||||
subtitle="Reiciendis id reiciendis at ullam."
|
||||
border={true}
|
||||
/>
|
||||
|
||||
<NavOption
|
||||
url="/data/glossary"
|
||||
title="Glossary"
|
||||
subtitle="Reiciendis id reiciendis at ullam."
|
||||
border={true}
|
||||
/>
|
||||
</SubPanel>
|
||||
</>
|
||||
<NavOption
|
||||
url="/data/glossary"
|
||||
title="Glossary"
|
||||
subtitle="Reiciendis id reiciendis at ullam."
|
||||
border={true}
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
|
||||
return <AppLayout title="Content" langui={langui} subPanel={subPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: DataProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,34 +1,29 @@
|
|||
import MainPanel from "components/Panels/MainPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
|
||||
applyCustomAppProps(Gallery, {
|
||||
useSubPanel: false,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type GalleryProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Gallery(props: Props): JSX.Element {
|
||||
export default function Gallery(props: GalleryProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const contentPanel = (
|
||||
<iframe
|
||||
className="w-full h-screen"
|
||||
src="https://gallery.accords-library.com/posts"
|
||||
></iframe>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<iframe
|
||||
className="w-full h-screen"
|
||||
src="https://gallery.accords-library.com/posts"
|
||||
></iframe>
|
||||
</>
|
||||
<AppLayout title="Content" langui={langui} contentPanel={contentPanel} />
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: GalleryProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(Hubs, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type HubsProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Hubs(props: Props): JSX.Element {
|
||||
export default function Hubs(props: HubsProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="workspaces"
|
||||
title={langui.main_hub}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
const contentPanel = <ContentPanel>Hello</ContentPanel>;
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="workspaces"
|
||||
title={langui.main_hub}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>Hello</ContentPanel>
|
||||
</>
|
||||
<AppLayout
|
||||
title="Hub"
|
||||
langui={langui}
|
||||
contentPanel={contentPanel}
|
||||
subPanel={subPanel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: HubsProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,160 +1,150 @@
|
|||
import AppLayout from "components/AppLayout";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import Head from "next/head";
|
||||
import { applyCustomAppProps } from "./_app";
|
||||
|
||||
applyCustomAppProps(Home, {
|
||||
useSubPanel: false,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type HomeProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Home(props: Props): JSX.Element {
|
||||
export default function Home(props: HomeProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
|
||||
const contentPanel = (
|
||||
<ContentPanel autoformat={true}>
|
||||
<h2>Discover • Analyse • Translate • Archive</h2>
|
||||
<h2>What is this?</h2>
|
||||
<p>
|
||||
Accord’s Library aims at gathering and archiving all of Yoko
|
||||
Taro’s work. Yoko Taro is a Japanese video game director and
|
||||
scenario writer. He is best-known for his work on the NieR and
|
||||
Drakengard (Drag-on Dragoon) franchises. To complement his games, Yoko
|
||||
Taro likes to publish side materials in the form of books, novellas,
|
||||
artbooks, stage plays, manga, drama CDs, and comics. Those side
|
||||
materials can be very difficult to find. His work goes all the way back
|
||||
to 2003, and most of them are out of print after having been released
|
||||
solely in Japan, sometimes in limited quantities. Their prices on the
|
||||
second hand market have skyrocketed, ranging all the way to hundreds if
|
||||
not thousand of dollars for the rarest items.
|
||||
</p>
|
||||
<p>
|
||||
This is where this library takes its meaning, in trying to help the
|
||||
community grow by providing translators, writers, and wiki’s
|
||||
contributors a simple way to access these records filled with stories,
|
||||
artworks, and knowledge.
|
||||
</p>
|
||||
<p>
|
||||
We are a small group of Yoko Taro’s fans that decided to join
|
||||
forces and create a website and a community. Our motto is{" "}
|
||||
<strong>Discover • Analyze • Translate • Archive</strong> (D.A.T.A. for
|
||||
short). We started with the goal of gathering and archiving as much
|
||||
side-materials/merch as possible. But since then, our ambition grew and
|
||||
we decided to create a full-fledged website that will also include news
|
||||
articles, lore, summaries, translations, and transcriptions. Hopefully
|
||||
one day, we will be up there in the list of notable resources for
|
||||
Drakengard and NieR fans.
|
||||
</p>
|
||||
<h2>What’s on this website?</h2>
|
||||
<p>
|
||||
<strong>
|
||||
<a href="https://accords-library.com/compendium/">The Compendium</a>
|
||||
</strong>
|
||||
: This is where we will list every NieR/DOD/other Yoko Tato merch,
|
||||
games, books, novel, stage play, CD... well everything! For each, we
|
||||
will provide photos and/or scans of the content, information about what
|
||||
it is, when and how it was released, size, initial price...
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
<a href="https://accords-library.com/news/">News</a>
|
||||
</strong>
|
||||
: Yes because we also want to create our own content! So there you will
|
||||
find translations, transcriptions, unboxing, news about future
|
||||
merch/game releases, maybe some guides. We don’t see this website
|
||||
as being purely a showcase of our work, but also of the community, and
|
||||
as such, we will be accepting applications for becoming contributors on
|
||||
the website. For the applicant, there is no deadline or article quota,
|
||||
it merely means that we will have access to the website Post Writing
|
||||
tools and will be able to submit a draft that can be published once
|
||||
verified by an editor. Anyway, that’s at least the plan, we will
|
||||
think more about this until the website’s official launch.
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
<a href="https://accords-library.com/data/">Data</a>
|
||||
</strong>
|
||||
: There we will publish lore/knowledge about the Yokoverse: Dictionary,
|
||||
Timeline, Weapons Stories, Game summaries... We have not yet decided how
|
||||
deep we want to go as they are already quite a few resources out there.{" "}
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Gallery
|
||||
</a>
|
||||
</strong>
|
||||
: A fully tagged Danbooru-styled gallery with currently more than a
|
||||
thousand unique artworks. If you are unfamiliar with this kind of
|
||||
gallery, it comes with a powerful search function that allows you to
|
||||
search for specific images: want to search for images with both Caim and
|
||||
Inuart, just type{" "}
|
||||
<kbd>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts/query=Caim%20Inuart"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Caim Inuart
|
||||
</a>
|
||||
</kbd>
|
||||
. If you want images of Devola OR Popola, you can use a comma{" "}
|
||||
<kbd>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts/query=Popola%2CDevola"
|
||||
data-type="URL"
|
||||
data-id="https://gallery.accords-library.com/posts/query=Popola%2CDevola"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Popola,Devola
|
||||
</a>
|
||||
</kbd>
|
||||
. You can also negate a tag: i.e. images of 9S without any pods around,
|
||||
search for{" "}
|
||||
<kbd>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts/query=9S%20-Pods"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
9S -Pods
|
||||
</a>
|
||||
</kbd>
|
||||
. Anyway, there is a lot more to it, you can click on "Syntax
|
||||
help" next to the Search button for even neater functions. Btw, you
|
||||
can create an account to favorite, upvote/downvote posts, or if you want
|
||||
to help tagging them. There isn’t currently a way for new users to
|
||||
upload images, you’ll have to contact us first and we can decide
|
||||
to enable this function on your account.
|
||||
</p>
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Accord’s Library - Home</title>
|
||||
</Head>
|
||||
|
||||
<MainPanel langui={langui} />
|
||||
|
||||
<ContentPanel autoformat={true}>
|
||||
<h2>Discover • Analyse • Translate • Archive</h2>
|
||||
<h2>What is this?</h2>
|
||||
<p>
|
||||
Accord’s Library aims at gathering and archiving all of Yoko
|
||||
Taro’s work. Yoko Taro is a Japanese video game director and
|
||||
scenario writer. He is best-known for his work on the NieR and
|
||||
Drakengard (Drag-on Dragoon) franchises. To complement his games, Yoko
|
||||
Taro likes to publish side materials in the form of books, novellas,
|
||||
artbooks, stage plays, manga, drama CDs, and comics. Those side
|
||||
materials can be very difficult to find. His work goes all the way
|
||||
back to 2003, and most of them are out of print after having been
|
||||
released solely in Japan, sometimes in limited quantities. Their
|
||||
prices on the second hand market have skyrocketed, ranging all the way
|
||||
to hundreds if not thousand of dollars for the rarest items.
|
||||
</p>
|
||||
<p>
|
||||
This is where this library takes its meaning, in trying to help the
|
||||
community grow by providing translators, writers, and wiki’s
|
||||
contributors a simple way to access these records filled with stories,
|
||||
artworks, and knowledge.
|
||||
</p>
|
||||
<p>
|
||||
We are a small group of Yoko Taro’s fans that decided to join
|
||||
forces and create a website and a community. Our motto is{" "}
|
||||
<strong>Discover • Analyze • Translate • Archive</strong> (D.A.T.A.
|
||||
for short). We started with the goal of gathering and archiving as
|
||||
much side-materials/merch as possible. But since then, our ambition
|
||||
grew and we decided to create a full-fledged website that will also
|
||||
include news articles, lore, summaries, translations, and
|
||||
transcriptions. Hopefully one day, we will be up there in the list of
|
||||
notable resources for Drakengard and NieR fans.
|
||||
</p>
|
||||
<h2>What’s on this website?</h2>
|
||||
<p>
|
||||
<strong>
|
||||
<a href="https://accords-library.com/compendium/">The Compendium</a>
|
||||
</strong>
|
||||
: This is where we will list every NieR/DOD/other Yoko Tato merch,
|
||||
games, books, novel, stage play, CD... well everything! For each, we
|
||||
will provide photos and/or scans of the content, information about
|
||||
what it is, when and how it was released, size, initial price...
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
<a href="https://accords-library.com/news/">News</a>
|
||||
</strong>
|
||||
: Yes because we also want to create our own content! So there you
|
||||
will find translations, transcriptions, unboxing, news about future
|
||||
merch/game releases, maybe some guides. We don’t see this
|
||||
website as being purely a showcase of our work, but also of the
|
||||
community, and as such, we will be accepting applications for becoming
|
||||
contributors on the website. For the applicant, there is no deadline
|
||||
or article quota, it merely means that we will have access to the
|
||||
website Post Writing tools and will be able to submit a draft that can
|
||||
be published once verified by an editor. Anyway, that’s at least
|
||||
the plan, we will think more about this until the website’s
|
||||
official launch.
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
<a href="https://accords-library.com/data/">Data</a>
|
||||
</strong>
|
||||
: There we will publish lore/knowledge about the Yokoverse:
|
||||
Dictionary, Timeline, Weapons Stories, Game summaries... We have not
|
||||
yet decided how deep we want to go as they are already quite a few
|
||||
resources out there.{" "}
|
||||
</p>
|
||||
<p>
|
||||
<strong>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Gallery
|
||||
</a>
|
||||
</strong>
|
||||
: A fully tagged Danbooru-styled gallery with currently more than a
|
||||
thousand unique artworks. If you are unfamiliar with this kind of
|
||||
gallery, it comes with a powerful search function that allows you to
|
||||
search for specific images: want to search for images with both Caim
|
||||
and Inuart, just type{" "}
|
||||
<kbd>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts/query=Caim%20Inuart"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Caim Inuart
|
||||
</a>
|
||||
</kbd>
|
||||
. If you want images of Devola OR Popola, you can use a comma{" "}
|
||||
<kbd>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts/query=Popola%2CDevola"
|
||||
data-type="URL"
|
||||
data-id="https://gallery.accords-library.com/posts/query=Popola%2CDevola"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
Popola,Devola
|
||||
</a>
|
||||
</kbd>
|
||||
. You can also negate a tag: i.e. images of 9S without any pods
|
||||
around, search for{" "}
|
||||
<kbd>
|
||||
<a
|
||||
href="https://gallery.accords-library.com/posts/query=9S%20-Pods"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
9S -Pods
|
||||
</a>
|
||||
</kbd>
|
||||
. Anyway, there is a lot more to it, you can click on "Syntax
|
||||
help" next to the Search button for even neater functions. Btw,
|
||||
you can create an account to favorite, upvote/downvote posts, or if
|
||||
you want to help tagging them. There isn’t currently a way for
|
||||
new users to upload images, you’ll have to contact us first and
|
||||
we can decide to enable this function on your account.
|
||||
</p>
|
||||
</ContentPanel>
|
||||
<AppLayout title="Home" langui={langui} contentPanel={contentPanel} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: HomeProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -3,7 +3,6 @@ import ContentPanel, {
|
|||
} from "components/Panels/ContentPanel";
|
||||
import Image from "next/image";
|
||||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import {
|
||||
getLibraryItem,
|
||||
getLibraryItemsSlugs,
|
||||
|
@ -30,21 +29,469 @@ import LibraryItemComponent from "components/Library/LibraryItemComponent";
|
|||
import Chip from "components/Chip";
|
||||
import Button from "components/Button";
|
||||
import HorizontalLine from "components/HorizontalLine";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
type Props = {
|
||||
type LibrarySlugProps = {
|
||||
libraryItem: GetLibraryItemQuery;
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
applyCustomAppProps(Library, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
export default function Library(props: Props): JSX.Element {
|
||||
export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||
const item = props.libraryItem.libraryItems.data[0].attributes;
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<ReturnButton
|
||||
title={langui.main_library}
|
||||
href="/library"
|
||||
langui={langui}
|
||||
/>
|
||||
<HorizontalLine />
|
||||
|
||||
<NavOption
|
||||
title={langui.library_item_summary}
|
||||
url="#summary"
|
||||
border={true}
|
||||
/>
|
||||
|
||||
{item.gallery.data.length > 0 ? (
|
||||
<NavOption
|
||||
title={langui.library_item_gallery}
|
||||
url="#gallery"
|
||||
border={true}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
<NavOption
|
||||
title={langui.library_item_details}
|
||||
url="#details"
|
||||
border={true}
|
||||
/>
|
||||
|
||||
{item.subitems.data.length > 0 ? (
|
||||
item.metadata.length > 0 &&
|
||||
item.metadata[0].__typename === "ComponentMetadataOther" &&
|
||||
item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (
|
||||
<NavOption
|
||||
title={langui.library_item_variants}
|
||||
url="#variants"
|
||||
border={true}
|
||||
/>
|
||||
) : (
|
||||
<NavOption
|
||||
title={langui.library_item_subitems}
|
||||
url="#subitems"
|
||||
border={true}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.contents.data.length > 0 ? (
|
||||
<NavOption
|
||||
title={langui.library_item_content}
|
||||
url="#content"
|
||||
border={true}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</SubPanel>
|
||||
);
|
||||
|
||||
const contentPanel = (
|
||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||
<div className="grid place-items-center gap-12">
|
||||
<div className="drop-shadow-dark-xl w-96 max-w-full mb-16">
|
||||
{item.thumbnail.data ? (
|
||||
<Image
|
||||
src={getAssetURL(item.thumbnail.data.attributes.url)}
|
||||
alt={item.thumbnail.data.attributes.alternativeText}
|
||||
width={item.thumbnail.data.attributes.width}
|
||||
height={item.thumbnail.data.attributes.height}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full aspect-[21/29.7] bg-light rounded-xl"></div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="summary"
|
||||
className="bg-mid w-full grid place-items-center p-8 rounded-2xl"
|
||||
>
|
||||
<div className="w-[clamp(0px,100%,42rem)] grid place-items-center gap-8">
|
||||
{item.subitem_of.data.length > 0 ? (
|
||||
<div className="grid place-items-center">
|
||||
<p>{langui.global_subitem_of}</p>
|
||||
<Button
|
||||
href={`/library/${item.subitem_of.data[0].attributes.slug}`}
|
||||
>
|
||||
{prettyinlineTitle(
|
||||
"",
|
||||
item.subitem_of.data[0].attributes.title,
|
||||
item.subitem_of.data[0].attributes.subtitle
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<div className="grid place-items-center">
|
||||
<h1 className="text-3xl">{item.title}</h1>
|
||||
{item.subtitle ? (
|
||||
<h2 className="text-2xl">{item.subtitle}</h2>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
{item.descriptions.length > 0 ? (
|
||||
<p>{item.descriptions[0].description}</p>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.gallery.data.length > 0 ? (
|
||||
<div id="gallery" className="grid place-items-center gap-8 w-full">
|
||||
<h2 className="text-2xl">{langui.library_item_gallery}</h2>
|
||||
<div className="grid w-full gap-8 items-end grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]">
|
||||
{item.gallery.data.map((galleryItem) => (
|
||||
<div
|
||||
key={galleryItem.id}
|
||||
className="relative aspect-square hover:scale-[1.02] transition-transform cursor-pointer"
|
||||
>
|
||||
<div className="bg-light absolute inset-0 rounded-lg shadow-md"></div>
|
||||
<Image
|
||||
className="rounded-lg"
|
||||
src={getAssetURL(galleryItem.attributes.url)}
|
||||
alt={galleryItem.attributes.alternativeText}
|
||||
width={galleryItem.attributes.width}
|
||||
height={galleryItem.attributes.height}
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
<div
|
||||
id="details"
|
||||
className="bg-mid w-full grid place-items-center p-8 rounded-2xl"
|
||||
>
|
||||
<div className="w-[clamp(0px,100%,42rem)] grid place-items gap-8">
|
||||
<h2 className="text-2xl text-center">
|
||||
{langui.library_item_details}
|
||||
</h2>
|
||||
<div className="grid grid-flow-col w-full place-content-between">
|
||||
{item.metadata.length > 0 ? (
|
||||
<div className="grid place-items-center">
|
||||
<h3 className="text-xl">{langui.global_type}</h3>
|
||||
<Button>
|
||||
{item.metadata[0].__typename === "ComponentMetadataAudio"
|
||||
? langui.library_item_type_audio
|
||||
: item.metadata[0].__typename === "ComponentMetadataBooks"
|
||||
? langui.library_item_type_textual
|
||||
: item.metadata[0].__typename === "ComponentMetadataGame"
|
||||
? langui.library_item_type_game
|
||||
: item.metadata[0].__typename === "ComponentMetadataOther"
|
||||
? langui.library_item_type_game
|
||||
: item.metadata[0].__typename === "ComponentMetadataVideo"
|
||||
? langui.library_item_type_video
|
||||
: ""}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.release_date ? (
|
||||
<div className="grid place-items-center">
|
||||
<h3 className="text-xl">{langui.global_release_date}</h3>
|
||||
<p>{prettyDate(item.release_date)}</p>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.release_date ? (
|
||||
<div className="grid place-items-center">
|
||||
<h3 className="text-xl">{langui.global_price}</h3>
|
||||
<p>{prettyPrice(item.price)}</p>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
{item.size ? (
|
||||
<>
|
||||
<h3 className="text-xl">{langui.library_item_physical_size}</h3>
|
||||
<div className="grid grid-flow-col w-full place-content-between">
|
||||
<div className="grid place-items-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_width}:</p>
|
||||
<div>
|
||||
<p>{item.size.width} mm</p>
|
||||
<p>{convertMmToInch(item.size.width)} in</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid place-items-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_height}:</p>
|
||||
<div>
|
||||
<p>{item.size.height} mm</p>
|
||||
<p>{convertMmToInch(item.size.height)} in</p>
|
||||
</div>
|
||||
</div>
|
||||
{item.size.thickness ? (
|
||||
<div className="grid place-items-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_thickness}:</p>
|
||||
<div>
|
||||
<p>{item.size.thickness} mm</p>
|
||||
<p>{convertMmToInch(item.size.thickness)} in</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.metadata.length > 0 ? (
|
||||
<>
|
||||
<h3 className="text-xl">
|
||||
{langui.library_item_type_information}
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 w-full place-content-between">
|
||||
{item.metadata[0].__typename === "ComponentMetadataBooks" ? (
|
||||
<>
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_type}:</p>
|
||||
<Chip>
|
||||
{item.metadata[0].subtype.data.attributes.titles
|
||||
.length > 0
|
||||
? item.metadata[0].subtype.data.attributes.titles[0]
|
||||
.title
|
||||
: prettySlug(
|
||||
item.metadata[0].subtype.data.attributes.slug
|
||||
)}
|
||||
</Chip>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_pages}:</p>
|
||||
<p>{item.metadata[0].page_count}</p>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_binding}:</p>
|
||||
<p>
|
||||
{item.metadata[0].binding_type ===
|
||||
Enum_Componentmetadatabooks_Binding_Type.Paperback
|
||||
? langui.global_paperback
|
||||
: item.metadata[0].binding_type ===
|
||||
Enum_Componentmetadatabooks_Binding_Type.Hardcover
|
||||
? langui.global_hardcover
|
||||
: ""}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_page_order}:</p>
|
||||
<p>
|
||||
{item.metadata[0].page_order ===
|
||||
Enum_Componentmetadatabooks_Page_Order.LeftToRight
|
||||
? langui.global_left_to_right
|
||||
: item.metadata[0].page_order ===
|
||||
Enum_Componentmetadatabooks_Page_Order.RightToLeft
|
||||
? langui.global_right_to_left
|
||||
: ""}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_languages}:</p>
|
||||
{item.metadata[0].languages.data.map((lang) => (
|
||||
<p key={lang.attributes.code}>
|
||||
{lang.attributes.name}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataAudio" ? (
|
||||
<></>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataVideo" ? (
|
||||
<></>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataGame" ? (
|
||||
<></>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataOther" ? (
|
||||
<>
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_type}:</p>
|
||||
<Chip>
|
||||
{item.metadata[0].subtype.data.attributes.titles
|
||||
.length > 0
|
||||
? item.metadata[0].subtype.data.attributes.titles[0]
|
||||
.title
|
||||
: prettySlug(
|
||||
item.metadata[0].subtype.data.attributes.slug
|
||||
)}
|
||||
</Chip>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.subitems.data.length > 0 ? (
|
||||
item.metadata.length > 0 &&
|
||||
item.metadata[0].__typename === "ComponentMetadataOther" &&
|
||||
item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (
|
||||
<div id="variants" className="grid place-items-center gap-8 w-full">
|
||||
<h2 className="text-2xl">{langui.library_item_variants}</h2>
|
||||
<div className="grid gap-8 items-end grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
|
||||
{item.subitems.data.map((variant) => (
|
||||
<LibraryItemComponent
|
||||
key={variant.id}
|
||||
item={variant.attributes}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div id="subitems" className="grid place-items-center gap-8 w-full">
|
||||
<h2 className="text-2xl">{langui.library_item_subitems}</h2>
|
||||
<div className="grid gap-8 items-end grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
|
||||
{item.subitems.data.map((subitem) => (
|
||||
<LibraryItemComponent
|
||||
key={subitem.id}
|
||||
item={subitem.attributes}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.contents.data.length > 0 ? (
|
||||
<div id="content" className="w-full grid place-items-center gap-8">
|
||||
<h2 className="text-2xl">{langui.library_item_content}</h2>
|
||||
<div className="grid gap-4 w-full">
|
||||
{item.contents.data.map((content) => (
|
||||
<div
|
||||
id={content.attributes.slug}
|
||||
key={content.id}
|
||||
className=" grid gap-2 h-6 overflow-hidden px-4 rounded-lg target:bg-mid target:h-auto target:py-3 target:my-2"
|
||||
>
|
||||
<div className="grid gap-4 place-items-center grid-cols-[auto_auto_1fr_auto_9em] ">
|
||||
<a href={`#${content.attributes.slug}`}>
|
||||
<h3>
|
||||
{content.attributes.content.data &&
|
||||
content.attributes.content.data.attributes.titles
|
||||
.length > 0
|
||||
? prettyinlineTitle(
|
||||
content.attributes.content.data.attributes
|
||||
.titles[0].pre_title,
|
||||
content.attributes.content.data.attributes
|
||||
.titles[0].title,
|
||||
content.attributes.content.data.attributes
|
||||
.titles[0].subtitle
|
||||
)
|
||||
: prettySlug(content.attributes.slug, item.slug)}
|
||||
</h3>
|
||||
</a>
|
||||
<div className="grid grid-flow-col gap-1">
|
||||
{content.attributes.content.data?.attributes.categories.data.map(
|
||||
(category) => (
|
||||
<Chip key={category.id}>
|
||||
{category.attributes.short}
|
||||
</Chip>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
<p className="border-b-2 h-4 w-full border-black border-dotted opacity-30"></p>
|
||||
<p>
|
||||
{content.attributes.range[0].__typename ===
|
||||
"ComponentRangePageRange"
|
||||
? content.attributes.range[0].starting_page
|
||||
: ""}
|
||||
</p>
|
||||
{content.attributes.content.data ? (
|
||||
<Chip className="place-self-end">
|
||||
{content.attributes.content.data.attributes.type.data
|
||||
.attributes.titles.length > 0
|
||||
? content.attributes.content.data.attributes.type.data
|
||||
.attributes.titles[0].title
|
||||
: prettySlug(
|
||||
content.attributes.content.data.attributes.type
|
||||
.data.attributes.slug
|
||||
)}
|
||||
</Chip>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<div className="grid grid-flow-col place-content-start place-items-center gap-2">
|
||||
<span className="material-icons text-dark">
|
||||
subdirectory_arrow_right
|
||||
</span>
|
||||
|
||||
{content.attributes.scan_set.length > 0 ? (
|
||||
<Button
|
||||
href={`/content/${content.attributes.content.data.attributes.slug}/scans/`}
|
||||
>
|
||||
{langui.library_item_view_scans}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.attributes.content.data ? (
|
||||
<Button
|
||||
href={`/content/${content.attributes.content.data.attributes.slug}`}
|
||||
>
|
||||
{langui.library_item_open_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.attributes.scan_set.length === 0 &&
|
||||
!content.attributes.content.data
|
||||
? "The content is not available"
|
||||
: ""}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
);
|
||||
|
||||
item.contents.data.sort((a, b) => {
|
||||
if (
|
||||
|
@ -60,474 +507,12 @@ export default function Library(props: Props): JSX.Element {
|
|||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<ReturnButton
|
||||
title={langui.main_library}
|
||||
href="/library"
|
||||
langui={langui}
|
||||
/>
|
||||
<HorizontalLine />
|
||||
|
||||
<NavOption
|
||||
title={langui.library_item_summary}
|
||||
url="#summary"
|
||||
border={true}
|
||||
/>
|
||||
|
||||
{item.gallery.data.length > 0 ? (
|
||||
<NavOption
|
||||
title={langui.library_item_gallery}
|
||||
url="#gallery"
|
||||
border={true}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
<NavOption
|
||||
title={langui.library_item_details}
|
||||
url="#details"
|
||||
border={true}
|
||||
/>
|
||||
|
||||
{item.subitems.data.length > 0 ? (
|
||||
item.metadata.length > 0 &&
|
||||
item.metadata[0].__typename === "ComponentMetadataOther" &&
|
||||
item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (
|
||||
<NavOption
|
||||
title={langui.library_item_variants}
|
||||
url="#variants"
|
||||
border={true}
|
||||
/>
|
||||
) : (
|
||||
<NavOption
|
||||
title={langui.library_item_subitems}
|
||||
url="#subitems"
|
||||
border={true}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.contents.data.length > 0 ? (
|
||||
<NavOption
|
||||
title={langui.library_item_content}
|
||||
url="#content"
|
||||
border={true}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</SubPanel>
|
||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||
<div className="grid place-items-center gap-12">
|
||||
<div className="drop-shadow-dark-xl w-96 max-w-full mb-16">
|
||||
{item.thumbnail.data ? (
|
||||
<Image
|
||||
src={getAssetURL(item.thumbnail.data.attributes.url)}
|
||||
alt={item.thumbnail.data.attributes.alternativeText}
|
||||
width={item.thumbnail.data.attributes.width}
|
||||
height={item.thumbnail.data.attributes.height}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full aspect-[21/29.7] bg-light rounded-xl"></div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="summary"
|
||||
className="bg-mid w-full grid place-items-center p-8 rounded-2xl"
|
||||
>
|
||||
<div className="w-[clamp(0px,100%,42rem)] grid place-items-center gap-8">
|
||||
{item.subitem_of.data.length > 0 ? (
|
||||
<div className="grid place-items-center">
|
||||
<p>{langui.global_subitem_of}</p>
|
||||
<Button
|
||||
href={`/library/${item.subitem_of.data[0].attributes.slug}`}
|
||||
>
|
||||
{prettyinlineTitle(
|
||||
"",
|
||||
item.subitem_of.data[0].attributes.title,
|
||||
item.subitem_of.data[0].attributes.subtitle
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<div className="grid place-items-center">
|
||||
<h1 className="text-3xl">{item.title}</h1>
|
||||
{item.subtitle ? (
|
||||
<h2 className="text-2xl">{item.subtitle}</h2>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
{item.descriptions.length > 0 ? (
|
||||
<p>{item.descriptions[0].description}</p>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.gallery.data.length > 0 ? (
|
||||
<div id="gallery" className="grid place-items-center gap-8 w-full">
|
||||
<h2 className="text-2xl">{langui.library_item_gallery}</h2>
|
||||
<div className="grid w-full gap-8 items-end grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]">
|
||||
{item.gallery.data.map((galleryItem) => (
|
||||
<div
|
||||
key={galleryItem.id}
|
||||
className="relative aspect-square hover:scale-[1.02] transition-transform cursor-pointer"
|
||||
>
|
||||
<div className="bg-light absolute inset-0 rounded-lg shadow-md"></div>
|
||||
<Image
|
||||
className="rounded-lg"
|
||||
src={getAssetURL(galleryItem.attributes.url)}
|
||||
alt={galleryItem.attributes.alternativeText}
|
||||
width={galleryItem.attributes.width}
|
||||
height={galleryItem.attributes.height}
|
||||
layout="fill"
|
||||
objectFit="cover"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
<div
|
||||
id="details"
|
||||
className="bg-mid w-full grid place-items-center p-8 rounded-2xl"
|
||||
>
|
||||
<div className="w-[clamp(0px,100%,42rem)] grid place-items gap-8">
|
||||
<h2 className="text-2xl text-center">
|
||||
{langui.library_item_details}
|
||||
</h2>
|
||||
<div className="grid grid-flow-col w-full place-content-between">
|
||||
{item.metadata.length > 0 ? (
|
||||
<div className="grid place-items-center">
|
||||
<h3 className="text-xl">{langui.global_type}</h3>
|
||||
<Button>
|
||||
{item.metadata[0].__typename === "ComponentMetadataAudio"
|
||||
? langui.library_item_type_audio
|
||||
: item.metadata[0].__typename ===
|
||||
"ComponentMetadataBooks"
|
||||
? langui.library_item_type_textual
|
||||
: item.metadata[0].__typename ===
|
||||
"ComponentMetadataGame"
|
||||
? langui.library_item_type_game
|
||||
: item.metadata[0].__typename ===
|
||||
"ComponentMetadataOther"
|
||||
? langui.library_item_type_game
|
||||
: item.metadata[0].__typename ===
|
||||
"ComponentMetadataVideo"
|
||||
? langui.library_item_type_video
|
||||
: ""}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.release_date ? (
|
||||
<div className="grid place-items-center">
|
||||
<h3 className="text-xl">{langui.global_release_date}</h3>
|
||||
<p>{prettyDate(item.release_date)}</p>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.release_date ? (
|
||||
<div className="grid place-items-center">
|
||||
<h3 className="text-xl">{langui.global_price}</h3>
|
||||
<p>{prettyPrice(item.price)}</p>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
{item.size ? (
|
||||
<>
|
||||
<h3 className="text-xl">
|
||||
{langui.library_item_physical_size}
|
||||
</h3>
|
||||
<div className="grid grid-flow-col w-full place-content-between">
|
||||
<div className="grid place-items-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_width}:</p>
|
||||
<div>
|
||||
<p>{item.size.width} mm</p>
|
||||
<p>{convertMmToInch(item.size.width)} in</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid place-items-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_height}:</p>
|
||||
<div>
|
||||
<p>{item.size.height} mm</p>
|
||||
<p>{convertMmToInch(item.size.height)} in</p>
|
||||
</div>
|
||||
</div>
|
||||
{item.size.thickness ? (
|
||||
<div className="grid place-items-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_thickness}:</p>
|
||||
<div>
|
||||
<p>{item.size.thickness} mm</p>
|
||||
<p>{convertMmToInch(item.size.thickness)} in</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.metadata.length > 0 ? (
|
||||
<>
|
||||
<h3 className="text-xl">
|
||||
{langui.library_item_type_information}
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 w-full place-content-between">
|
||||
{item.metadata[0].__typename ===
|
||||
"ComponentMetadataBooks" ? (
|
||||
<>
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_type}:</p>
|
||||
<Chip>
|
||||
{item.metadata[0].subtype.data.attributes.titles
|
||||
.length > 0
|
||||
? item.metadata[0].subtype.data.attributes
|
||||
.titles[0].title
|
||||
: prettySlug(
|
||||
item.metadata[0].subtype.data.attributes.slug
|
||||
)}
|
||||
</Chip>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_pages}:</p>
|
||||
<p>{item.metadata[0].page_count}</p>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_binding}:</p>
|
||||
<p>
|
||||
{item.metadata[0].binding_type ===
|
||||
Enum_Componentmetadatabooks_Binding_Type.Paperback
|
||||
? langui.global_paperback
|
||||
: item.metadata[0].binding_type ===
|
||||
Enum_Componentmetadatabooks_Binding_Type.Hardcover
|
||||
? langui.global_hardcover
|
||||
: ""}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">
|
||||
{langui.global_page_order}:
|
||||
</p>
|
||||
<p>
|
||||
{item.metadata[0].page_order ===
|
||||
Enum_Componentmetadatabooks_Page_Order.LeftToRight
|
||||
? langui.global_left_to_right
|
||||
: item.metadata[0].page_order ===
|
||||
Enum_Componentmetadatabooks_Page_Order.RightToLeft
|
||||
? langui.global_right_to_left
|
||||
: ""}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">
|
||||
{langui.global_languages}:
|
||||
</p>
|
||||
{item.metadata[0].languages.data.map((lang) => (
|
||||
<p key={lang.attributes.code}>
|
||||
{lang.attributes.name}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataAudio" ? (
|
||||
<></>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataVideo" ? (
|
||||
<></>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataGame" ? (
|
||||
<></>
|
||||
) : item.metadata[0].__typename ===
|
||||
"ComponentMetadataOther" ? (
|
||||
<>
|
||||
<div className="grid place-content-start grid-flow-col gap-4">
|
||||
<p className="font-bold">{langui.global_type}:</p>
|
||||
<Chip>
|
||||
{item.metadata[0].subtype.data.attributes.titles
|
||||
.length > 0
|
||||
? item.metadata[0].subtype.data.attributes
|
||||
.titles[0].title
|
||||
: prettySlug(
|
||||
item.metadata[0].subtype.data.attributes.slug
|
||||
)}
|
||||
</Chip>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.subitems.data.length > 0 ? (
|
||||
item.metadata.length > 0 &&
|
||||
item.metadata[0].__typename === "ComponentMetadataOther" &&
|
||||
item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (
|
||||
<div
|
||||
id="variants"
|
||||
className="grid place-items-center gap-8 w-full"
|
||||
>
|
||||
<h2 className="text-2xl">{langui.library_item_variants}</h2>
|
||||
<div className="grid gap-8 items-end grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
|
||||
{item.subitems.data.map((variant) => (
|
||||
<LibraryItemComponent
|
||||
key={variant.id}
|
||||
item={variant.attributes}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
id="subitems"
|
||||
className="grid place-items-center gap-8 w-full"
|
||||
>
|
||||
<h2 className="text-2xl">{langui.library_item_subitems}</h2>
|
||||
<div className="grid gap-8 items-end grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
|
||||
{item.subitems.data.map((subitem) => (
|
||||
<LibraryItemComponent
|
||||
key={subitem.id}
|
||||
item={subitem.attributes}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{item.contents.data.length > 0 ? (
|
||||
<div id="content" className="w-full grid place-items-center gap-8">
|
||||
<h2 className="text-2xl">{langui.library_item_content}</h2>
|
||||
<div className="grid gap-4 w-full">
|
||||
{item.contents.data.map((content) => (
|
||||
<div
|
||||
id={content.attributes.slug}
|
||||
key={content.id}
|
||||
className=" grid gap-2 h-6 overflow-hidden px-4 rounded-lg target:bg-mid target:h-auto target:py-3 target:my-2"
|
||||
>
|
||||
<div className="grid gap-4 place-items-center grid-cols-[auto_auto_1fr_auto_9em] ">
|
||||
<a href={`#${content.attributes.slug}`}>
|
||||
<h3>
|
||||
{content.attributes.content.data &&
|
||||
content.attributes.content.data.attributes.titles
|
||||
.length > 0
|
||||
? prettyinlineTitle(
|
||||
content.attributes.content.data.attributes
|
||||
.titles[0].pre_title,
|
||||
content.attributes.content.data.attributes
|
||||
.titles[0].title,
|
||||
content.attributes.content.data.attributes
|
||||
.titles[0].subtitle
|
||||
)
|
||||
: prettySlug(content.attributes.slug, item.slug)}
|
||||
</h3>
|
||||
</a>
|
||||
<div className="grid grid-flow-col gap-1">
|
||||
{content.attributes.content.data?.attributes.categories.data.map(
|
||||
(category) => (
|
||||
<Chip key={category.id}>
|
||||
{category.attributes.short}
|
||||
</Chip>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
<p className="border-b-2 h-4 w-full border-black border-dotted opacity-30"></p>
|
||||
<p>
|
||||
{content.attributes.range[0].__typename ===
|
||||
"ComponentRangePageRange"
|
||||
? content.attributes.range[0].starting_page
|
||||
: ""}
|
||||
</p>
|
||||
{content.attributes.content.data ? (
|
||||
<Chip className="place-self-end">
|
||||
{content.attributes.content.data.attributes.type.data
|
||||
.attributes.titles.length > 0
|
||||
? content.attributes.content.data.attributes.type
|
||||
.data.attributes.titles[0].title
|
||||
: prettySlug(
|
||||
content.attributes.content.data.attributes.type
|
||||
.data.attributes.slug
|
||||
)}
|
||||
</Chip>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<div className="grid grid-flow-col place-content-start place-items-center gap-2">
|
||||
<span className="material-icons text-dark">
|
||||
subdirectory_arrow_right
|
||||
</span>
|
||||
|
||||
{content.attributes.scan_set.length > 0 ? (
|
||||
<Button
|
||||
href={`/content/${content.attributes.content.data.attributes.slug}/scans/`}
|
||||
>
|
||||
{langui.library_item_view_scans}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.attributes.content.data ? (
|
||||
<Button
|
||||
href={`/content/${content.attributes.content.data.attributes.slug}`}
|
||||
>
|
||||
{langui.library_item_open_content}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
|
||||
{content.attributes.scan_set.length === 0 &&
|
||||
!content.attributes.content.data
|
||||
? "The content is not available"
|
||||
: ""}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
</>
|
||||
<AppLayout
|
||||
title="Library"
|
||||
langui={langui}
|
||||
contentPanel={contentPanel}
|
||||
subPanel={subPanel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -537,7 +522,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
|||
if (context.params.slug instanceof Array)
|
||||
context.params.slug = context.params.slug.join("");
|
||||
|
||||
const props: Props = {
|
||||
const props: LibrarySlugProps = {
|
||||
libraryItem: await getLibraryItem({
|
||||
slug: context.params.slug,
|
||||
language_code: context.locale,
|
||||
|
|
|
@ -4,7 +4,6 @@ import ContentPanel, {
|
|||
ContentPanelWidthSizes,
|
||||
} from "components/Panels/ContentPanel";
|
||||
import LibraryItemComponent from "components/Library/LibraryItemComponent";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import {
|
||||
GetLibraryItemsPreviewQuery,
|
||||
GetWebsiteInterfaceQuery,
|
||||
|
@ -14,49 +13,46 @@ import {
|
|||
getWebsiteInterface,
|
||||
} from "graphql/operations";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import Head from "next/head";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
type Props = {
|
||||
type LibraryProps = {
|
||||
libraryItems: GetLibraryItemsPreviewQuery;
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
applyCustomAppProps(Library, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
export default function Library(props: Props): JSX.Element {
|
||||
export default function Library(props: LibraryProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="library_books"
|
||||
title={langui.main_library}
|
||||
description={langui.library_description}
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
const contentPanel = (
|
||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||
<div className="grid gap-8 items-end grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]">
|
||||
{props.libraryItems.libraryItems.data.map((item) => (
|
||||
<LibraryItemComponent key={item.id} item={item.attributes} />
|
||||
))}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Accord’s Library - Library</title>
|
||||
</Head>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="library_books"
|
||||
title={langui.main_library}
|
||||
description={langui.library_description}
|
||||
/>
|
||||
</SubPanel>
|
||||
|
||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||
<div className="grid gap-8 items-end grid-cols-[repeat(auto-fill,_minmax(15rem,1fr))]">
|
||||
{props.libraryItems.libraryItems.data.map((item) => (
|
||||
<LibraryItemComponent key={item.id} item={item.attributes} />
|
||||
))}
|
||||
</div>
|
||||
</ContentPanel>
|
||||
</>
|
||||
<AppLayout
|
||||
title="Library"
|
||||
langui={langui}
|
||||
subPanel={subPanel}
|
||||
contentPanel={contentPanel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: LibraryProps = {
|
||||
libraryItems: await getLibraryItemsPreview({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,41 +1,32 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(Merch, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type MerchProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function Merch(props: Props): JSX.Element {
|
||||
export default function Merch(props: MerchProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="store"
|
||||
title={langui.main_merch}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>Hello</ContentPanel>
|
||||
</>
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="store"
|
||||
title={langui.main_merch}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
|
||||
return <AppLayout title="Merch" langui={langui} subPanel={subPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: MerchProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -1,41 +1,32 @@
|
|||
import SubPanel from "components/Panels/SubPanel";
|
||||
import { applyCustomAppProps } from "pages/_app";
|
||||
import PanelHeader from "components/PanelComponents/PanelHeader";
|
||||
import MainPanel from "components/Panels/MainPanel";
|
||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||
import { GetStaticProps } from "next";
|
||||
import { getWebsiteInterface } from "graphql/operations";
|
||||
import ContentPanel from "components/Panels/ContentPanel";
|
||||
import AppLayout from "components/AppLayout";
|
||||
|
||||
applyCustomAppProps(News, {
|
||||
useSubPanel: true,
|
||||
useContentPanel: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
type NewsProps = {
|
||||
langui: GetWebsiteInterfaceQuery;
|
||||
};
|
||||
|
||||
export default function News(props: Props): JSX.Element {
|
||||
export default function News(props: NewsProps): JSX.Element {
|
||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||
return (
|
||||
<>
|
||||
<MainPanel langui={langui} />
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="feed"
|
||||
title={langui.main_news}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
<ContentPanel>Hello</ContentPanel>
|
||||
</>
|
||||
const subPanel = (
|
||||
<SubPanel>
|
||||
<PanelHeader
|
||||
icon="feed"
|
||||
title={langui.main_news}
|
||||
description="Reiciendis id reiciendis at ullam. Corrupti voluptatibus quo magnam enim voluptas eaque. Quia id consequatur fuga magni. Voluptate eaque pariatur porro voluptate rerum. Harum velit in laborum eligendi. Nihil eius dolor et omnis."
|
||||
/>
|
||||
</SubPanel>
|
||||
);
|
||||
|
||||
return <AppLayout title="Merch" langui={langui} subPanel={subPanel} />;
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
if (context.locale) {
|
||||
const props: Props = {
|
||||
const props: NewsProps = {
|
||||
langui: await getWebsiteInterface({
|
||||
language_code: context.locale,
|
||||
}),
|
||||
|
|
|
@ -57,4 +57,4 @@ export function capitalizeString(string: string): string {
|
|||
|
||||
export function convertMmToInch(mm: number): string {
|
||||
return (mm * 0.03937008).toPrecision(3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ module.exports = {
|
|||
body: ["Zen Maru Gothic"],
|
||||
headers: ["Vollkorn"],
|
||||
},
|
||||
screens: {
|
||||
desktop: {'min': '70rem'},
|
||||
mobile: {'max': '70rem'},
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
require("@tailwindcss/typography"),
|
||||
|
|
Loading…
Reference in New Issue