Merge pull request #6 from Accords-Library/develop
Fixed all UX problems pointed out by groof
This commit is contained in:
commit
e1dfdbd87e
|
@ -12,6 +12,7 @@ import { useMediaCoarse, useMediaMobile } from "hooks/useMediaQuery";
|
||||||
import ReactTooltip from "react-tooltip";
|
import ReactTooltip from "react-tooltip";
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { ImageQuality } from "./Img";
|
import { ImageQuality } from "./Img";
|
||||||
|
import Popup from "./Popup";
|
||||||
|
|
||||||
type AppLayoutProps = {
|
type AppLayoutProps = {
|
||||||
subPanel?: React.ReactNode;
|
subPanel?: React.ReactNode;
|
||||||
|
@ -124,27 +125,6 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
<meta name="twitter:image" content={metaImage.image}></meta>
|
<meta name="twitter:image" content={metaImage.image}></meta>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
{/* Navbar */}
|
|
||||||
<div className="fixed inset-0 top-auto h-20 border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
|
|
||||||
<span
|
|
||||||
className="material-icons mt-[.1em] cursor-pointer"
|
|
||||||
onClick={() => appLayout.setMainPanelOpen(true)}
|
|
||||||
>
|
|
||||||
menu
|
|
||||||
</span>
|
|
||||||
<p className="text-2xl font-black font-headers">{props.navTitle}</p>
|
|
||||||
<span
|
|
||||||
className="material-icons mt-[.1em] cursor-pointer"
|
|
||||||
onClick={() => appLayout.setSubPanelOpen(true)}
|
|
||||||
>
|
|
||||||
{props.subPanel && !turnSubIntoContent
|
|
||||||
? props.subPanelIcon
|
|
||||||
? props.subPanelIcon
|
|
||||||
: "tune"
|
|
||||||
: ""}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Content panel */}
|
{/* Content panel */}
|
||||||
<div
|
<div
|
||||||
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light texture-paper-dots ${contentPanelClass}`}
|
className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light texture-paper-dots ${contentPanelClass}`}
|
||||||
|
@ -181,10 +161,10 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
{/* Sub panel */}
|
{/* Sub panel */}
|
||||||
{props.subPanel ? (
|
{props.subPanel ? (
|
||||||
<div
|
<div
|
||||||
className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
className={`${subPanelClass} border-r-[1px] mobile:bottom-20 mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots
|
||||||
${
|
${
|
||||||
turnSubIntoContent
|
turnSubIntoContent
|
||||||
? "mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0"
|
? "mobile:translate-x-0 mobile:left-0 mobile:border-l-0"
|
||||||
: !appLayout.subPanelOpen
|
: !appLayout.subPanelOpen
|
||||||
? "mobile:translate-x-full"
|
? "mobile:translate-x-full"
|
||||||
: ""
|
: ""
|
||||||
|
@ -198,7 +178,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
|
|
||||||
{/* Main panel */}
|
{/* Main panel */}
|
||||||
<div
|
<div
|
||||||
className={`${mainPanelClass} border-r-[1px] border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light texture-paper-dots
|
className={`${mainPanelClass} border-r-[1px] mobile:bottom-20 border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light texture-paper-dots
|
||||||
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
||||||
>
|
>
|
||||||
<MainPanel langui={props.langui} />
|
<MainPanel langui={props.langui} />
|
||||||
|
@ -218,38 +198,55 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Language selection background */}
|
{/* Navbar */}
|
||||||
<div
|
<div className="fixed inset-0 z-30 top-auto h-20 border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots">
|
||||||
className={`fixed bg-shade inset-0 transition-all duration-500 z-20 grid place-content-center ${
|
<span
|
||||||
appLayout.languagePanelOpen
|
className="material-icons mt-[.1em] cursor-pointer"
|
||||||
? "bg-opacity-60"
|
onClick={() => {
|
||||||
: "bg-opacity-0 pointer-events-none touch-none"
|
appLayout.setMainPanelOpen(!appLayout.mainPanelOpen);
|
||||||
}`}
|
appLayout.setSubPanelOpen(false);
|
||||||
onClick={() => {
|
}}
|
||||||
appLayout.setLanguagePanelOpen(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`p-10 bg-light rounded-lg shadow-2xl shadow-shade grid gap-4 place-items-center transition-transform ${
|
|
||||||
appLayout.languagePanelOpen ? "scale-100" : "scale-0"
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<h2 className="text-2xl">{props.langui.select_language}</h2>
|
{appLayout.mainPanelOpen ? "close" : "menu"}
|
||||||
<div className="flex flex-wrap flex-row gap-2">
|
</span>
|
||||||
{router.locales?.sort().map((locale) => (
|
<p className="text-2xl font-black font-headers">{props.navTitle}</p>
|
||||||
<Button
|
<span
|
||||||
key={locale}
|
className="material-icons mt-[.1em] cursor-pointer"
|
||||||
active={locale === router.locale}
|
onClick={() => {
|
||||||
href={router.asPath}
|
appLayout.setSubPanelOpen(!appLayout.subPanelOpen);
|
||||||
locale={locale}
|
appLayout.setMainPanelOpen(false);
|
||||||
>
|
}}
|
||||||
{prettyLanguage(locale)}
|
>
|
||||||
</Button>
|
{props.subPanel && !turnSubIntoContent
|
||||||
))}
|
? appLayout.subPanelOpen
|
||||||
</div>
|
? "close"
|
||||||
</div>
|
: props.subPanelIcon
|
||||||
|
? props.subPanelIcon
|
||||||
|
: "tune"
|
||||||
|
: ""}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Popup
|
||||||
|
state={appLayout.languagePanelOpen}
|
||||||
|
setState={appLayout.setLanguagePanelOpen}
|
||||||
|
>
|
||||||
|
<h2 className="text-2xl">{props.langui.select_language}</h2>
|
||||||
|
<div className="flex flex-wrap flex-row gap-2">
|
||||||
|
{router.locales?.sort().map((locale) => (
|
||||||
|
<Button
|
||||||
|
key={locale}
|
||||||
|
active={locale === router.locale}
|
||||||
|
href={router.asPath}
|
||||||
|
locale={locale}
|
||||||
|
onClick={() => appLayout.setLanguagePanelOpen(false)}
|
||||||
|
>
|
||||||
|
{prettyLanguage(locale)}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Popup>
|
||||||
|
|
||||||
<ReactTooltip
|
<ReactTooltip
|
||||||
id="MainPanelTooltip"
|
id="MainPanelTooltip"
|
||||||
place="right"
|
place="right"
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
import Button from "components/Button";
|
||||||
|
import Chip from "components/Chip";
|
||||||
|
import {
|
||||||
|
GetLibraryItemQuery,
|
||||||
|
GetWebsiteInterfaceQuery,
|
||||||
|
} from "graphql/operations-types";
|
||||||
|
import { prettyinlineTitle, prettySlug } from "queries/helpers";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
type ContentTOCLineProps = {
|
||||||
|
content: GetLibraryItemQuery["libraryItems"]["data"][number]["attributes"]["contents"]["data"][number];
|
||||||
|
parentSlug: string;
|
||||||
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ContentTOCLine(
|
||||||
|
props: ContentTOCLineProps
|
||||||
|
): JSX.Element {
|
||||||
|
const content = props.content;
|
||||||
|
const langui = props.langui;
|
||||||
|
|
||||||
|
const [opened, setOpened] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`grid gap-2 px-4 rounded-lg ${
|
||||||
|
opened && "bg-mid shadow-inner-sm shadow-shade h-auto py-3 my-2"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="grid gap-4 place-items-center grid-cols-[auto_auto_1fr_auto_12ch] thin:grid-cols-[auto_auto_1fr_auto]">
|
||||||
|
<a>
|
||||||
|
<h3 className="cursor-pointer" onClick={() => setOpened(!opened)}>
|
||||||
|
{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, props.parentSlug)}
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div className="flex flex-row flex-wrap 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="justify-self-end thin:hidden">
|
||||||
|
{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-flow-col place-content-start place-items-center gap-2 ${
|
||||||
|
opened ? "grid" : "hidden"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span className="material-icons text-dark">
|
||||||
|
subdirectory_arrow_right
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{content.attributes.scan_set.length > 0 ? (
|
||||||
|
<Button
|
||||||
|
href={`/contents/${content.attributes.content.data.attributes.slug}/scans/`}
|
||||||
|
>
|
||||||
|
{langui.view_scans}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
|
{content.attributes.content.data ? (
|
||||||
|
<Button
|
||||||
|
href={`/contents/${content.attributes.content.data.attributes.slug}`}
|
||||||
|
>
|
||||||
|
{langui.open_content}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
|
{content.attributes.scan_set.length === 0 &&
|
||||||
|
!content.attributes.content.data
|
||||||
|
? "The content is not available"
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import Button from "components/Button";
|
import Button from "components/Button";
|
||||||
|
import HorizontalLine from "components/HorizontalLine";
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||||
|
|
||||||
|
@ -6,14 +7,37 @@ type ReturnButtonProps = {
|
||||||
href: string;
|
href: string;
|
||||||
title: string;
|
title: string;
|
||||||
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
|
displayOn: ReturnButtonType;
|
||||||
|
horizontalLine?: boolean;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum ReturnButtonType {
|
||||||
|
Mobile,
|
||||||
|
Desktop,
|
||||||
|
Both,
|
||||||
|
}
|
||||||
|
|
||||||
export default function ReturnButton(props: ReturnButtonProps): JSX.Element {
|
export default function ReturnButton(props: ReturnButtonProps): JSX.Element {
|
||||||
const appLayout = useAppLayout();
|
const appLayout = useAppLayout();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button onClick={() => appLayout.setSubPanelOpen(false)} href={props.href}>
|
<div
|
||||||
❮ {props.langui.return_to} {props.title}
|
className={`${
|
||||||
</Button>
|
props.displayOn === ReturnButtonType.Mobile
|
||||||
|
? "desktop:hidden"
|
||||||
|
: props.displayOn === ReturnButtonType.Desktop
|
||||||
|
? "mobile:hidden"
|
||||||
|
: ""
|
||||||
|
} ${props.className}`}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
onClick={() => appLayout.setSubPanelOpen(false)}
|
||||||
|
href={props.href}
|
||||||
|
>
|
||||||
|
❮ {props.langui.return_to} {props.title}
|
||||||
|
</Button>
|
||||||
|
{props.horizontalLine && <HorizontalLine />}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { Dispatch, SetStateAction } from "react";
|
||||||
|
|
||||||
|
export type PopupProps = {
|
||||||
|
setState: Dispatch<SetStateAction<boolean | undefined>>;
|
||||||
|
state?: boolean;
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Popup(props: PopupProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`fixed inset-0 z-20 grid place-content-center ${
|
||||||
|
props.state ? "" : "pointer-events-none touch-none"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`fixed bg-shade inset-0 transition-all duration-500 ${
|
||||||
|
props.state ? "bg-opacity-60" : "bg-opacity-0"
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
props.setState(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`p-10 bg-light rounded-lg shadow-2xl shadow-shade grid gap-4 place-items-center transition-transform ${
|
||||||
|
props.state ? "scale-100" : "scale-0"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -4,7 +4,9 @@ import { getWebsiteInterface } from "graphql/operations";
|
||||||
import { GetStaticProps } from "next";
|
import { GetStaticProps } from "next";
|
||||||
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
import { GetWebsiteInterfaceQuery } from "graphql/operations-types";
|
||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
import ReturnButton, {
|
||||||
|
ReturnButtonType,
|
||||||
|
} from "components/PanelComponents/ReturnButton";
|
||||||
|
|
||||||
type FourOhFourProps = {
|
type FourOhFourProps = {
|
||||||
langui: GetWebsiteInterfaceQuery;
|
langui: GetWebsiteInterfaceQuery;
|
||||||
|
@ -15,7 +17,12 @@ export default function FourOhFour(props: FourOhFourProps): JSX.Element {
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
<h1>404 - {langui.page_not_found}</h1>
|
<h1>404 - {langui.page_not_found}</h1>
|
||||||
<ReturnButton href="/" title="Home" langui={langui} />
|
<ReturnButton
|
||||||
|
href="/"
|
||||||
|
title="Home"
|
||||||
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Both}
|
||||||
|
/>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -14,7 +14,9 @@ import HorizontalLine from "components/HorizontalLine";
|
||||||
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
import SubPanel from "components/Panels/SubPanel";
|
import SubPanel from "components/Panels/SubPanel";
|
||||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
import ReturnButton, {
|
||||||
|
ReturnButtonType,
|
||||||
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import { prettyinlineTitle, prettySlug } from "queries/helpers";
|
import { prettyinlineTitle, prettySlug } from "queries/helpers";
|
||||||
|
|
||||||
type ContentIndexProps = {
|
type ContentIndexProps = {
|
||||||
|
@ -27,12 +29,25 @@ export default function ContentIndex(props: ContentIndexProps): JSX.Element {
|
||||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href="/contents" title={"Contents"} langui={langui} />
|
<ReturnButton
|
||||||
<HorizontalLine />
|
href="/contents"
|
||||||
|
title={"Contents"}
|
||||||
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Desktop}
|
||||||
|
horizontalLine
|
||||||
|
/>
|
||||||
|
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
);
|
);
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
|
<ReturnButton
|
||||||
|
href="/contents"
|
||||||
|
title={"Contents"}
|
||||||
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Mobile}
|
||||||
|
className="mb-10"
|
||||||
|
/>
|
||||||
<div className="grid place-items-center">
|
<div className="grid place-items-center">
|
||||||
<ThumbnailHeader content={content} langui={langui} />
|
<ThumbnailHeader content={content} langui={langui} />
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ import {
|
||||||
import ContentPanel from "components/Panels/ContentPanel";
|
import ContentPanel from "components/Panels/ContentPanel";
|
||||||
import HorizontalLine from "components/HorizontalLine";
|
import HorizontalLine from "components/HorizontalLine";
|
||||||
import SubPanel from "components/Panels/SubPanel";
|
import SubPanel from "components/Panels/SubPanel";
|
||||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
import ReturnButton, {
|
||||||
|
ReturnButtonType,
|
||||||
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
import ThumbnailHeader from "components/Content/ThumbnailHeader";
|
||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
import Markdawn from "components/Markdown/Markdawn";
|
import Markdawn from "components/Markdown/Markdawn";
|
||||||
|
@ -46,10 +48,10 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
||||||
href={`/contents/${content.slug}`}
|
href={`/contents/${content.slug}`}
|
||||||
title={"Content"}
|
title={"Content"}
|
||||||
langui={langui}
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Desktop}
|
||||||
|
horizontalLine
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
{content.text_set.length > 0 ? (
|
{content.text_set.length > 0 ? (
|
||||||
<div className="grid gap-5">
|
<div className="grid gap-5">
|
||||||
<h2 className="text-xl">
|
<h2 className="text-xl">
|
||||||
|
@ -138,6 +140,13 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
|
||||||
);
|
);
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel>
|
<ContentPanel>
|
||||||
|
<ReturnButton
|
||||||
|
href={`/contents/${content.slug}`}
|
||||||
|
title={"Content"}
|
||||||
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Mobile}
|
||||||
|
className="mb-10"
|
||||||
|
/>
|
||||||
<div className="grid place-items-center">
|
<div className="grid place-items-center">
|
||||||
<ThumbnailHeader content={content} langui={langui} />
|
<ThumbnailHeader content={content} langui={langui} />
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ import {
|
||||||
sortContent,
|
sortContent,
|
||||||
} from "queries/helpers";
|
} from "queries/helpers";
|
||||||
import SubPanel from "components/Panels/SubPanel";
|
import SubPanel from "components/Panels/SubPanel";
|
||||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
import ReturnButton, {
|
||||||
|
ReturnButtonType,
|
||||||
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import NavOption from "components/PanelComponents/NavOption";
|
import NavOption from "components/PanelComponents/NavOption";
|
||||||
import Chip from "components/Chip";
|
import Chip from "components/Chip";
|
||||||
import Button from "components/Button";
|
import Button from "components/Button";
|
||||||
|
@ -37,6 +39,7 @@ import InsetBox from "components/InsetBox";
|
||||||
import Img, { ImageQuality } from "components/Img";
|
import Img, { ImageQuality } from "components/Img";
|
||||||
import { useAppLayout } from "contexts/AppLayoutContext";
|
import { useAppLayout } from "contexts/AppLayoutContext";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
import ContentTOCLine from "components/Library/ContentTOCLine";
|
||||||
|
|
||||||
interface LibrarySlugProps {
|
interface LibrarySlugProps {
|
||||||
libraryItem: GetLibraryItemQuery;
|
libraryItem: GetLibraryItemQuery;
|
||||||
|
@ -58,8 +61,13 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href="/library/" title={langui.library} langui={langui} />
|
<ReturnButton
|
||||||
<HorizontalLine />
|
href="/library/"
|
||||||
|
title={langui.library}
|
||||||
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Desktop}
|
||||||
|
horizontalLine
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="grid gap-4">
|
<div className="grid gap-4">
|
||||||
<NavOption
|
<NavOption
|
||||||
|
@ -109,8 +117,15 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
|
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||||
|
<ReturnButton
|
||||||
|
href="/library/"
|
||||||
|
title={langui.library}
|
||||||
|
langui={langui}
|
||||||
|
displayOn={ReturnButtonType.Mobile}
|
||||||
|
className="mb-10"
|
||||||
|
/>
|
||||||
<div className="grid place-items-center gap-12">
|
<div className="grid place-items-center gap-12">
|
||||||
<div className="drop-shadow-shade-xl w-full h-[50vh] mobile:h-[80vh] mb-16 relative cursor-pointer">
|
<div className="drop-shadow-shade-xl w-full h-[50vh] mobile:h-[60vh] desktop:mb-16 relative cursor-pointer">
|
||||||
{item.thumbnail.data ? (
|
{item.thumbnail.data ? (
|
||||||
<Img
|
<Img
|
||||||
image={item.thumbnail.data.attributes}
|
image={item.thumbnail.data.attributes}
|
||||||
|
@ -347,90 +362,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
<h2 className="text-2xl">{langui.contents}</h2>
|
<h2 className="text-2xl">{langui.contents}</h2>
|
||||||
<div className="grid gap-4 w-full">
|
<div className="grid gap-4 w-full">
|
||||||
{item.contents.data.map((content) => (
|
{item.contents.data.map((content) => (
|
||||||
<div
|
<ContentTOCLine
|
||||||
id={content.attributes.slug}
|
langui={langui}
|
||||||
|
content={content}
|
||||||
|
parentSlug={item.slug}
|
||||||
key={content.id}
|
key={content.id}
|
||||||
className="grid gap-2 px-4 rounded-lg target:bg-mid target:shadow-inner-sm target:shadow-shade target:h-auto target:py-3 target:my-2 target:[--displaySubContentMenu:grid] [--displaySubContentMenu:none]"
|
/>
|
||||||
>
|
|
||||||
<div className="grid gap-4 place-items-center grid-cols-[auto_auto_1fr_auto_12ch] thin:grid-cols-[auto_auto_1fr_auto]">
|
|
||||||
<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="flex flex-row flex-wrap 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="justify-self-end thin:hidden">
|
|
||||||
{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-flow-col place-content-start place-items-center gap-2 [display:var(--displaySubContentMenu)]">
|
|
||||||
<span className="material-icons text-dark">
|
|
||||||
subdirectory_arrow_right
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{content.attributes.scan_set.length > 0 ? (
|
|
||||||
<Button
|
|
||||||
href={`/contents/${content.attributes.content.data.attributes.slug}/scans/`}
|
|
||||||
>
|
|
||||||
{langui.view_scans}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
|
|
||||||
{content.attributes.content.data ? (
|
|
||||||
<Button
|
|
||||||
href={`/contents/${content.attributes.content.data.attributes.slug}`}
|
|
||||||
>
|
|
||||||
{langui.open_content}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
|
|
||||||
{content.attributes.scan_set.length === 0 &&
|
|
||||||
!content.attributes.content.data
|
|
||||||
? "The content is not available"
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,9 @@ import {
|
||||||
getWebsiteInterface,
|
getWebsiteInterface,
|
||||||
} from "graphql/operations";
|
} from "graphql/operations";
|
||||||
import NavOption from "components/PanelComponents/NavOption";
|
import NavOption from "components/PanelComponents/NavOption";
|
||||||
import ReturnButton from "components/PanelComponents/ReturnButton";
|
import ReturnButton, {
|
||||||
|
ReturnButtonType,
|
||||||
|
} from "components/PanelComponents/ReturnButton";
|
||||||
import HorizontalLine from "components/HorizontalLine";
|
import HorizontalLine from "components/HorizontalLine";
|
||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
import {
|
import {
|
||||||
|
@ -72,9 +74,6 @@ export default function DataChronology(
|
||||||
|
|
||||||
const subPanel = (
|
const subPanel = (
|
||||||
<SubPanel>
|
<SubPanel>
|
||||||
<ReturnButton href="/data" title="Data" langui={langui} />
|
|
||||||
<HorizontalLine />
|
|
||||||
|
|
||||||
{props.chronologyEras.chronologyEras.data.map((era) => (
|
{props.chronologyEras.chronologyEras.data.map((era) => (
|
||||||
<NavOption
|
<NavOption
|
||||||
key={era.id}
|
key={era.id}
|
||||||
|
|
Loading…
Reference in New Issue