Added support for touch screens where hovering is not possible
This commit is contained in:
parent
c6b6ec1479
commit
0e35f5aed9
|
@ -22,12 +22,15 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
const subPanelClass =
|
const subPanelClass =
|
||||||
"fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:w-[20rem]";
|
"fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:w-[20rem]";
|
||||||
let contentPanelClass = "";
|
let contentPanelClass = "";
|
||||||
|
let turnSubIntoContent = false;
|
||||||
if (props.subPanel && props.contentPanel) {
|
if (props.subPanel && props.contentPanel) {
|
||||||
contentPanelClass =
|
contentPanelClass =
|
||||||
"fixed desktop:left-[40rem] desktop:top-0 desktop:bottom-0 desktop:right-0";
|
"fixed desktop:left-[40rem] desktop:top-0 desktop:bottom-0 desktop:right-0";
|
||||||
} else if (props.contentPanel) {
|
} else if (props.contentPanel) {
|
||||||
contentPanelClass =
|
contentPanelClass =
|
||||||
"fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:right-0";
|
"fixed desktop:left-[20rem] desktop:top-0 desktop:bottom-0 desktop:right-0";
|
||||||
|
} else if (props.subPanel) {
|
||||||
|
turnSubIntoContent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -52,7 +55,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
className="material-icons mt-[.1em] cursor-pointer"
|
className="material-icons mt-[.1em] cursor-pointer"
|
||||||
onClick={() => setsubPanelOpen(true)}
|
onClick={() => setsubPanelOpen(true)}
|
||||||
>
|
>
|
||||||
{props.subPanel
|
{props.subPanel && !turnSubIntoContent
|
||||||
? props.subPanelIcon
|
? props.subPanelIcon
|
||||||
? props.subPanelIcon
|
? props.subPanelIcon
|
||||||
: "tune"
|
: "tune"
|
||||||
|
@ -68,12 +71,21 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
{props.contentPanel}
|
{props.contentPanel}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
""
|
<div className="top-0 left-0 right-0 bottom-20 overflow-y-scroll fixed desktop:left-[40rem] desktop:top-0 desktop:bottom-0 desktop:right-0 opacity-40">
|
||||||
|
<div className="grid place-content-center h-full">
|
||||||
|
<div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9">
|
||||||
|
<p className="text-4xl">❮</p>
|
||||||
|
<p className="text-2xl w-64">Select one of the options in the sidebar</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Background when navbar is opened */}
|
{/* Background when navbar is opened */}
|
||||||
<div
|
<div
|
||||||
className={`fixed bg-dark inset-0 transition-opacity duration-500 ${
|
className={`fixed bg-dark inset-0 transition-opacity duration-500
|
||||||
|
${turnSubIntoContent ? "z-10" : ""}
|
||||||
|
${
|
||||||
mainPanelOpen || subPanelOpen
|
mainPanelOpen || subPanelOpen
|
||||||
? " opacity-50"
|
? " opacity-50"
|
||||||
: "opacity-0 translate-x-full"
|
: "opacity-0 translate-x-full"
|
||||||
|
@ -84,25 +96,30 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element {
|
||||||
}}
|
}}
|
||||||
></div>
|
></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 */}
|
{/* Sub panel */}
|
||||||
{props.subPanel ? (
|
{props.subPanel ? (
|
||||||
<div
|
<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
|
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"}`}
|
${
|
||||||
|
turnSubIntoContent
|
||||||
|
? "mobile:mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
${subPanelOpen ? "" : "mobile:translate-x-full"}`}
|
||||||
>
|
>
|
||||||
{props.subPanel}
|
{props.subPanel}
|
||||||
</div>
|
</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 z-20
|
||||||
|
${mainPanelOpen ? "" : "mobile:-translate-x-full"}`}
|
||||||
|
>
|
||||||
|
<MainPanel langui={props.langui} />
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ export default function LibraryContentPreview(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={"/library/content/" + item.slug} passHref>
|
<Link href={"/library/content/" + item.slug} passHref>
|
||||||
<div className="drop-shadow-dark-xl cursor-pointer grid items-end hover:rounded-3xl [--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform">
|
<div className="drop-shadow-dark-xl cursor-pointer grid items-end fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform">
|
||||||
{item.thumbnail.data ? (
|
{item.thumbnail.data ? (
|
||||||
<Image
|
<Image
|
||||||
className=" rounded-md"
|
className="rounded-md coarse:rounded-b-none"
|
||||||
src={getAssetURL(item.thumbnail.data.attributes.url)}
|
src={getAssetURL(item.thumbnail.data.attributes.url)}
|
||||||
alt={item.thumbnail.data.attributes.alternativeText}
|
alt={item.thumbnail.data.attributes.alternativeText}
|
||||||
height={item.thumbnail.data.attributes.height}
|
height={item.thumbnail.data.attributes.height}
|
||||||
|
@ -33,7 +33,18 @@ export default function LibraryContentPreview(
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full aspect-[3/2] bg-light rounded-lg"></div>
|
<div className="w-full aspect-[3/2] bg-light rounded-lg"></div>
|
||||||
)}
|
)}
|
||||||
<div className="linearbg-1 drop-shadow-dark-lg absolute bottom-2 inset-x-[-0.15rem] opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-1 text-left">
|
<div className="linearbg-1 fine:drop-shadow-dark-lg fine:absolute coarse:rounded-b-md bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2 text-left">
|
||||||
|
<div className="grid grid-flow-col gap-1 overflow-hidden place-content-start">
|
||||||
|
{item.type ? (
|
||||||
|
<Chip>
|
||||||
|
{item.type.data.attributes.titles.length > 0
|
||||||
|
? item.type.data.attributes.titles[0].title
|
||||||
|
: prettySlug(item.type.data.attributes.slug)}
|
||||||
|
</Chip>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{item.titles.length > 0 ? (
|
{item.titles.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
|
@ -45,20 +56,13 @@ export default function LibraryContentPreview(
|
||||||
<h1 className="text-lg">{prettySlug(item.slug)}</h1>
|
<h1 className="text-lg">{prettySlug(item.slug)}</h1>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-flow-col gap-1 overflow-hidden place-content-start">
|
<div className="grid grid-flow-col gap-1 overflow-x-scroll webkit-scrollbar:w-0 [scrollbar-width:none] place-content-start">
|
||||||
{item.categories.data.map((category) => (
|
{item.categories.data.map((category) => (
|
||||||
<Chip key={category.id} className="text-sm">
|
<Chip key={category.id} className="text-sm">
|
||||||
{category.attributes.short}
|
{category.attributes.short}
|
||||||
</Chip>
|
</Chip>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-flow-col gap-1 overflow-hidden place-content-start">
|
|
||||||
{item.type ? (
|
|
||||||
<Chip>{item.type.data.attributes.titles.length > 0 ? item.type.data.attributes.titles[0].title : prettySlug(item.type.data.attributes.slug)}</Chip>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { GetLibraryItemsPreviewQuery } from "graphql/operations-types";
|
import {
|
||||||
import { getAssetURL, prettyDate, prettyPrice } from "queries/helpers";
|
GetLibraryItemsPreviewQuery,
|
||||||
|
GetWebsiteInterfaceQuery,
|
||||||
|
} from "graphql/operations-types";
|
||||||
|
import {
|
||||||
|
getAssetURL,
|
||||||
|
prettyDate,
|
||||||
|
prettyPrice,
|
||||||
|
prettyItemSubType,
|
||||||
|
} from "queries/helpers";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import Chip from "components/Chip";
|
||||||
|
|
||||||
export type LibraryItemsPreviewProps = {
|
export type LibraryItemsPreviewProps = {
|
||||||
|
className?: string;
|
||||||
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
|
||||||
item: {
|
item: {
|
||||||
slug: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["slug"];
|
slug: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["slug"];
|
||||||
thumbnail: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["thumbnail"];
|
thumbnail: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["thumbnail"];
|
||||||
|
@ -11,6 +22,7 @@ export type LibraryItemsPreviewProps = {
|
||||||
subtitle: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["subtitle"];
|
subtitle: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["subtitle"];
|
||||||
price?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["price"];
|
price?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["price"];
|
||||||
release_date?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"];
|
release_date?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["release_date"];
|
||||||
|
metadata?: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,10 +30,13 @@ export default function LibraryItemsPreview(
|
||||||
props: LibraryItemsPreviewProps
|
props: LibraryItemsPreviewProps
|
||||||
): JSX.Element {
|
): JSX.Element {
|
||||||
const item = props.item;
|
const item = props.item;
|
||||||
|
const langui = props.langui;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={"/library/items/" + item.slug} passHref>
|
<Link href={"/library/items/" + item.slug} passHref>
|
||||||
<div className="drop-shadow-dark-xl cursor-pointer grid items-end hover:rounded-3xl [--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform">
|
<div
|
||||||
|
className={`drop-shadow-dark-xl cursor-pointer grid items-end hover:rounded-3xl fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform ${props.className}`}
|
||||||
|
>
|
||||||
{item.thumbnail.data ? (
|
{item.thumbnail.data ? (
|
||||||
<Image
|
<Image
|
||||||
src={getAssetURL(item.thumbnail.data.attributes.url)}
|
src={getAssetURL(item.thumbnail.data.attributes.url)}
|
||||||
|
@ -32,36 +47,48 @@ export default function LibraryItemsPreview(
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>
|
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>
|
||||||
)}
|
)}
|
||||||
<div className="linearbg-1 drop-shadow-dark-lg absolute bottom-2 inset-x-[-0.15rem] opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-4 text-left">
|
|
||||||
|
<div className="linearbg-1 fine:drop-shadow-dark-lg fine:absolute place-items-start bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2 text-left">
|
||||||
|
{item.metadata && item.metadata.length > 0 ? (
|
||||||
|
<div className="flex flex-row gap-1">
|
||||||
|
<Chip>{prettyItemSubType(item.metadata[0])}</Chip>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-lg leading-7">{item.title}</h2>
|
<h2 className="mobile:text-sm text-lg leading-5">{item.title}</h2>
|
||||||
<h3 className="leading-3">{item.subtitle}</h3>
|
<h3 className="mobile:text-xs leading-3">{item.subtitle}</h3>
|
||||||
</div>
|
|
||||||
<div className="grid grid-flow-col">
|
|
||||||
{item.release_date ? (
|
|
||||||
<p className="text-sm">
|
|
||||||
<span className="material-icons !text-base translate-y-[.15em] mr-1">
|
|
||||||
event
|
|
||||||
</span>
|
|
||||||
{prettyDate(item.release_date)}
|
|
||||||
</p>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{item.price ? (
|
|
||||||
<p className="text-sm justify-self-end">
|
|
||||||
<span className="material-icons !text-base translate-y-[.15em] mr-1">
|
|
||||||
shopping_cart
|
|
||||||
</span>
|
|
||||||
{prettyPrice(item.price)}
|
|
||||||
</p>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
{item.release_date || item.price ? (
|
||||||
|
<div className="grid grid-flow-col w-full">
|
||||||
|
{item.release_date ? (
|
||||||
|
<p className="mobile:text-xs text-sm">
|
||||||
|
<span className="material-icons !text-base translate-y-[.15em] mr-1">
|
||||||
|
event
|
||||||
|
</span>
|
||||||
|
{prettyDate(item.release_date)}
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
{item.price ? (
|
||||||
|
<p className="mobile:text-xs text-sm justify-self-end">
|
||||||
|
<span className="material-icons !text-base translate-y-[.15em] mr-1">
|
||||||
|
shopping_cart
|
||||||
|
</span>
|
||||||
|
{prettyPrice(item.price)}
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,58 +124,119 @@ query getChronologyItems($language_code: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
query getLibraryItemsPreview($language_code: String) {
|
query getLibraryItemsPreview($language_code: String) {
|
||||||
libraryItems(
|
libraryItems(
|
||||||
filters: { root_item: { eq: true } }
|
filters: { root_item: { eq: true } }
|
||||||
pagination: { limit: -1 }
|
pagination: { limit: -1 }
|
||||||
sort: ["title:asc", "subtitle:asc"]
|
sort: ["title:asc", "subtitle:asc"]
|
||||||
) {
|
) {
|
||||||
data {
|
data {
|
||||||
id
|
id
|
||||||
attributes {
|
attributes {
|
||||||
title
|
title
|
||||||
subtitle
|
subtitle
|
||||||
slug
|
slug
|
||||||
thumbnail {
|
thumbnail {
|
||||||
data {
|
data {
|
||||||
attributes {
|
attributes {
|
||||||
name
|
name
|
||||||
alternativeText
|
alternativeText
|
||||||
caption
|
caption
|
||||||
width
|
width
|
||||||
height
|
height
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
release_date {
|
release_date {
|
||||||
year
|
year
|
||||||
month
|
month
|
||||||
day
|
day
|
||||||
}
|
}
|
||||||
price {
|
price {
|
||||||
amount
|
amount
|
||||||
currency {
|
currency {
|
||||||
data {
|
data {
|
||||||
attributes {
|
attributes {
|
||||||
symbol
|
symbol
|
||||||
code
|
code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size {
|
metadata {
|
||||||
width
|
__typename
|
||||||
height
|
... on ComponentMetadataBooks {
|
||||||
thickness
|
subtype {
|
||||||
}
|
data {
|
||||||
descriptions(filters: { language: { code: { eq: $language_code } } }) {
|
attributes {
|
||||||
description
|
slug
|
||||||
}
|
titles(
|
||||||
}
|
filters: { language: { code: { eq: $language_code } } }
|
||||||
}
|
) {
|
||||||
}
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on ComponentMetadataGame {
|
||||||
|
platform {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
short
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on ComponentMetadataVideo {
|
||||||
|
subtype {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
titles(
|
||||||
|
filters: { language: { code: { eq: $language_code } } }
|
||||||
|
) {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on ComponentMetadataAudio {
|
||||||
|
subtype {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
titles(
|
||||||
|
filters: { language: { code: { eq: $language_code } } }
|
||||||
|
) {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on ComponentMetadataOther {
|
||||||
|
subtype {
|
||||||
|
data {
|
||||||
|
attributes {
|
||||||
|
slug
|
||||||
|
titles(
|
||||||
|
filters: { language: { code: { eq: $language_code } } }
|
||||||
|
) {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
query getLibraryItemsSlugs {
|
query getLibraryItemsSlugs {
|
||||||
libraryItems(pagination: { limit: -1 }) {
|
libraryItems(pagination: { limit: -1 }) {
|
||||||
data {
|
data {
|
||||||
|
|
|
@ -263,16 +263,90 @@ export type GetLibraryItemsPreviewQuery = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
size: {
|
metadata: Array<
|
||||||
__typename: "ComponentBasicsSize";
|
| {
|
||||||
width: number;
|
__typename: "ComponentMetadataBooks";
|
||||||
height: number;
|
subtype: {
|
||||||
thickness: number;
|
__typename: "TextualSubtypeEntityResponse";
|
||||||
};
|
data: {
|
||||||
descriptions: Array<{
|
__typename: "TextualSubtypeEntity";
|
||||||
__typename: "ComponentTranslationsLibraryItems";
|
attributes: {
|
||||||
description: string;
|
__typename: "TextualSubtype";
|
||||||
}>;
|
slug: string;
|
||||||
|
titles: Array<{
|
||||||
|
__typename: "ComponentTranslationsSimpleTitle";
|
||||||
|
title: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
__typename: "ComponentMetadataVideo";
|
||||||
|
subtype: {
|
||||||
|
__typename: "VideoSubtypeEntityResponse";
|
||||||
|
data: {
|
||||||
|
__typename: "VideoSubtypeEntity";
|
||||||
|
attributes: {
|
||||||
|
__typename: "VideoSubtype";
|
||||||
|
slug: string;
|
||||||
|
titles: Array<{
|
||||||
|
__typename: "ComponentTranslationsSimpleTitle";
|
||||||
|
title: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
__typename: "ComponentMetadataGame";
|
||||||
|
platform: {
|
||||||
|
__typename: "GamePlatformEntityResponse";
|
||||||
|
data: {
|
||||||
|
__typename: "GamePlatformEntity";
|
||||||
|
attributes: {
|
||||||
|
__typename: "GamePlatform";
|
||||||
|
short: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
__typename: "ComponentMetadataAudio";
|
||||||
|
subtype: {
|
||||||
|
__typename: "AudioSubtypeEntityResponse";
|
||||||
|
data: {
|
||||||
|
__typename: "AudioSubtypeEntity";
|
||||||
|
attributes: {
|
||||||
|
__typename: "AudioSubtype";
|
||||||
|
slug: string;
|
||||||
|
titles: Array<{
|
||||||
|
__typename: "ComponentTranslationsSimpleTitle";
|
||||||
|
title: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
__typename: "ComponentMetadataOther";
|
||||||
|
subtype: {
|
||||||
|
__typename: "OtherSubtypeEntityResponse";
|
||||||
|
data: {
|
||||||
|
__typename: "OtherSubtypeEntity";
|
||||||
|
attributes: {
|
||||||
|
__typename: "OtherSubtype";
|
||||||
|
slug: string;
|
||||||
|
titles: Array<{
|
||||||
|
__typename: "ComponentTranslationsSimpleTitle";
|
||||||
|
title: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
| { __typename: "Error" }
|
||||||
|
>;
|
||||||
};
|
};
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,8 @@ import {
|
||||||
getAssetURL,
|
getAssetURL,
|
||||||
prettyDate,
|
prettyDate,
|
||||||
prettyinlineTitle,
|
prettyinlineTitle,
|
||||||
|
prettyItemType,
|
||||||
|
prettyItemSubType,
|
||||||
prettyPrice,
|
prettyPrice,
|
||||||
prettySlug,
|
prettySlug,
|
||||||
} from "queries/helpers";
|
} from "queries/helpers";
|
||||||
|
@ -29,7 +31,7 @@ import Chip from "components/Chip";
|
||||||
import Button from "components/Button";
|
import Button from "components/Button";
|
||||||
import HorizontalLine from "components/HorizontalLine";
|
import HorizontalLine from "components/HorizontalLine";
|
||||||
import AppLayout from "components/AppLayout";
|
import AppLayout from "components/AppLayout";
|
||||||
import LibraryMediaPreview from "components/Library/LibraryItemsPreview";
|
import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
|
||||||
|
|
||||||
type LibrarySlugProps = {
|
type LibrarySlugProps = {
|
||||||
libraryItem: GetLibraryItemQuery;
|
libraryItem: GetLibraryItemQuery;
|
||||||
|
@ -194,19 +196,11 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
{item.metadata.length > 0 ? (
|
{item.metadata.length > 0 ? (
|
||||||
<div className="grid place-items-center">
|
<div className="grid place-items-center">
|
||||||
<h3 className="text-xl">{langui.global_type}</h3>
|
<h3 className="text-xl">{langui.global_type}</h3>
|
||||||
<Button>
|
<div className="grid grid-flow-col gap-1">
|
||||||
{item.metadata[0].__typename === "ComponentMetadataAudio"
|
<Chip>{prettyItemType(item.metadata[0], langui)}</Chip>
|
||||||
? langui.library_item_type_audio
|
{"›"}
|
||||||
: item.metadata[0].__typename === "ComponentMetadataBooks"
|
<Chip>{prettyItemSubType(item.metadata[0])}</Chip>
|
||||||
? langui.library_item_type_textual
|
</div>
|
||||||
: 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>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
|
@ -273,19 +267,6 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
<div className="grid grid-cols-2 w-full place-content-between">
|
<div className="grid grid-cols-2 w-full place-content-between">
|
||||||
{item.metadata[0].__typename === "ComponentMetadataBooks" ? (
|
{item.metadata[0].__typename === "ComponentMetadataBooks" ? (
|
||||||
<>
|
<>
|
||||||
<div className="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">
|
<div className="grid place-content-start grid-flow-col gap-4">
|
||||||
<p className="font-bold">{langui.global_pages}:</p>
|
<p className="font-bold">{langui.global_pages}:</p>
|
||||||
<p>{item.metadata[0].page_count}</p>
|
<p>{item.metadata[0].page_count}</p>
|
||||||
|
@ -368,11 +349,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (
|
item.metadata[0].subtype.data.attributes.slug === "variant-set" ? (
|
||||||
<div id="variants" className="grid place-items-center gap-8 w-full">
|
<div id="variants" className="grid place-items-center gap-8 w-full">
|
||||||
<h2 className="text-2xl">{langui.library_item_variants}</h2>
|
<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">
|
<div className="grid gap-8 items-end mobile:grid-cols-2 grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
|
||||||
{item.subitems.data.map((variant) => (
|
{item.subitems.data.map((variant) => (
|
||||||
<LibraryMediaPreview
|
<LibraryItemsPreview
|
||||||
key={variant.id}
|
key={variant.id}
|
||||||
item={variant.attributes}
|
item={variant.attributes}
|
||||||
|
langui={langui}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -380,11 +362,12 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
|
||||||
) : (
|
) : (
|
||||||
<div id="subitems" className="grid place-items-center gap-8 w-full">
|
<div id="subitems" className="grid place-items-center gap-8 w-full">
|
||||||
<h2 className="text-2xl">{langui.library_item_subitems}</h2>
|
<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">
|
<div className="grid gap-8 items-end mobile:grid-cols-2 grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] w-full">
|
||||||
{item.subitems.data.map((subitem) => (
|
{item.subitems.data.map((subitem) => (
|
||||||
<LibraryMediaPreview
|
<LibraryItemsPreview
|
||||||
key={subitem.id}
|
key={subitem.id}
|
||||||
item={subitem.attributes}
|
item={subitem.attributes}
|
||||||
|
langui={langui}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -41,9 +41,13 @@ export default function Library(props: LibraryProps): JSX.Element {
|
||||||
);
|
);
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
<ContentPanel width={ContentPanelWidthSizes.large}>
|
<ContentPanel width={ContentPanelWidthSizes.large}>
|
||||||
<div className="grid gap-8 items-end grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))]">
|
<div className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))]">
|
||||||
{props.libraryItems.libraryItems.data.map((item) => (
|
{props.libraryItems.libraryItems.data.map((item) => (
|
||||||
<LibraryItemsPreview key={item.id} item={item.attributes} />
|
<LibraryItemsPreview
|
||||||
|
key={item.id}
|
||||||
|
item={item.attributes}
|
||||||
|
langui={langui}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</ContentPanel>
|
</ContentPanel>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import { GetLibraryItemsPreviewQuery } from "graphql/operations-types";
|
import {
|
||||||
|
GetLibraryItemsPreviewQuery,
|
||||||
|
GetWebsiteInterfaceQuery,
|
||||||
|
} from "graphql/operations-types";
|
||||||
|
|
||||||
export function getAssetURL(url: string): string {
|
export function getAssetURL(url: string): string {
|
||||||
return process.env.NEXT_PUBLIC_URL_CMS + url;
|
return process.env.NEXT_PUBLIC_URL_CMS + url;
|
||||||
|
@ -45,6 +48,47 @@ export function prettyinlineTitle(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function prettyItemType(
|
||||||
|
metadata: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number],
|
||||||
|
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"]
|
||||||
|
): string {
|
||||||
|
const type = metadata.__typename;
|
||||||
|
switch (metadata.__typename) {
|
||||||
|
case "ComponentMetadataAudio":
|
||||||
|
return langui.library_item_type_audio;
|
||||||
|
case "ComponentMetadataBooks":
|
||||||
|
return langui.library_item_type_textual;
|
||||||
|
case "ComponentMetadataGame":
|
||||||
|
return langui.library_item_type_game;
|
||||||
|
case "ComponentMetadataVideo":
|
||||||
|
return langui.library_item_type_video;
|
||||||
|
case "ComponentMetadataOther":
|
||||||
|
return langui.library_item_type_other;
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prettyItemSubType(
|
||||||
|
metadata: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["metadata"][number],
|
||||||
|
): string {
|
||||||
|
switch (metadata.__typename) {
|
||||||
|
case "ComponentMetadataAudio":
|
||||||
|
case "ComponentMetadataBooks":
|
||||||
|
case "ComponentMetadataVideo":
|
||||||
|
case "ComponentMetadataOther": {
|
||||||
|
return metadata.subtype.data.attributes.titles.length > 0
|
||||||
|
? metadata.subtype.data.attributes.titles[0].title
|
||||||
|
: prettySlug(metadata.subtype.data.attributes.slug);
|
||||||
|
}
|
||||||
|
case "ComponentMetadataGame":
|
||||||
|
return metadata.platform.data.attributes.short;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function capitalizeString(string: string): string {
|
export function capitalizeString(string: string): string {
|
||||||
function capitalizeWord(word: string): string {
|
function capitalizeWord(word: string): string {
|
||||||
return word.charAt(0).toUpperCase() + word.substring(1);
|
return word.charAt(0).toUpperCase() + word.substring(1);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
@layer base {
|
@layer base {
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
@apply p-0 m-0 bg-light text-black;
|
@apply p-0 m-0 bg-light text-black mobile:text-[90%];
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
@apply w-3;
|
@apply w-3 mobile:w-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar-track {
|
*::-webkit-scrollbar-track {
|
||||||
|
|
|
@ -14,9 +14,11 @@ module.exports = {
|
||||||
headers: ["Vollkorn"],
|
headers: ["Vollkorn"],
|
||||||
},
|
},
|
||||||
screens: {
|
screens: {
|
||||||
desktop: {'min': '70rem'},
|
desktop: { min: "70rem" },
|
||||||
mobile: {'max': '70rem'},
|
mobile: { max: "70rem" },
|
||||||
}
|
coarse: { raw: "(pointer: coarse)" },
|
||||||
|
fine: { raw: "(pointer: fine)" },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
require("@tailwindcss/typography"),
|
require("@tailwindcss/typography"),
|
||||||
|
|
Loading…
Reference in New Issue