More filtering options in Library
This commit is contained in:
parent
8684640ef4
commit
7c8fb24d67
|
@ -30,7 +30,7 @@ export default function LibraryItemsPreview(
|
||||||
{item.thumbnail.data ? (
|
{item.thumbnail.data ? (
|
||||||
<Img
|
<Img
|
||||||
image={item.thumbnail.data.attributes}
|
image={item.thumbnail.data.attributes}
|
||||||
quality={ImageQuality.Medium}
|
quality={ImageQuality.Small}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>
|
<div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div>
|
||||||
|
|
|
@ -13,22 +13,22 @@ export type SelectOption = {
|
||||||
label: string;
|
label: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function selectOptionsIncludes(
|
|
||||||
options: SelectOption[],
|
|
||||||
newOption: SelectOption
|
|
||||||
) {
|
|
||||||
options.map((option) => {
|
|
||||||
if (option.label === newOption.label) return true;
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Select(props: SelectProps): JSX.Element {
|
export default function Select(props: SelectProps): JSX.Element {
|
||||||
const [selected, setSelected] = useState(
|
const [selected, setSelected] = useState(
|
||||||
props.selected ? props.selected : props.allowEmpty ? -1 : 0
|
props.selected ? props.selected : props.allowEmpty ? -1 : 0
|
||||||
);
|
);
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (props.onChange) {
|
||||||
|
if (selected >= 0) {
|
||||||
|
props.onChange(props.options[selected].name);
|
||||||
|
} else {
|
||||||
|
props.onChange("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [props, selected]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative transition-[filter] ${
|
className={`relative transition-[filter] ${
|
||||||
|
@ -45,10 +45,7 @@ export default function Select(props: SelectProps): JSX.Element {
|
||||||
</p>
|
</p>
|
||||||
{selected >= 0 && props.allowEmpty && (
|
{selected >= 0 && props.allowEmpty && (
|
||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => setSelected(-1)}
|
||||||
setSelected(-1);
|
|
||||||
props.onChange && props.onChange("");
|
|
||||||
}}
|
|
||||||
className="material-icons !text-xs"
|
className="material-icons !text-xs"
|
||||||
>
|
>
|
||||||
close
|
close
|
||||||
|
@ -73,7 +70,6 @@ export default function Select(props: SelectProps): JSX.Element {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpened(false);
|
setOpened(false);
|
||||||
setSelected(index);
|
setSelected(index);
|
||||||
props.onChange && props.onChange(props.options[index].name);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{option.label}
|
{option.label}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Dispatch, SetStateAction } from "react";
|
||||||
|
|
||||||
|
export type SwitchProps = {
|
||||||
|
setState: Dispatch<SetStateAction<boolean>>;
|
||||||
|
state: boolean;
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Select(props: SwitchProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`h-6 w-12 rounded-full border-2 border-mid grid transition-colors relative cursor-pointer ${
|
||||||
|
props.className
|
||||||
|
} ${props.state ? "bg-mid" : "bg-light"}`}
|
||||||
|
onClick={() => {
|
||||||
|
props.setState(!props.state);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`bg-dark aspect-square rounded-full absolute top-0 bottom-0 left-0 transition-transform ${
|
||||||
|
props.state && "translate-x-[115%]"
|
||||||
|
}`}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -126,7 +126,6 @@ query getChronologyItems($language_code: String) {
|
||||||
|
|
||||||
query getLibraryItemsPreview($language_code: String) {
|
query getLibraryItemsPreview($language_code: String) {
|
||||||
libraryItems(
|
libraryItems(
|
||||||
filters: { root_item: { eq: true } }
|
|
||||||
pagination: { limit: -1 }
|
pagination: { limit: -1 }
|
||||||
) {
|
) {
|
||||||
data {
|
data {
|
||||||
|
@ -135,6 +134,7 @@ query getLibraryItemsPreview($language_code: String) {
|
||||||
title
|
title
|
||||||
subtitle
|
subtitle
|
||||||
slug
|
slug
|
||||||
|
root_item
|
||||||
thumbnail {
|
thumbnail {
|
||||||
data {
|
data {
|
||||||
attributes {
|
attributes {
|
||||||
|
|
|
@ -238,6 +238,7 @@ export type GetLibraryItemsPreviewQuery = {
|
||||||
title: string;
|
title: string;
|
||||||
subtitle: string;
|
subtitle: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
|
root_item: boolean;
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
__typename: "UploadFileEntityResponse";
|
__typename: "UploadFileEntityResponse";
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -17,6 +17,7 @@ import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
|
||||||
import Select from "components/Select";
|
import Select from "components/Select";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { prettyDate, prettyinlineTitle } from "queries/helpers";
|
import { prettyDate, prettyinlineTitle } from "queries/helpers";
|
||||||
|
import Switch from "components/Switch";
|
||||||
|
|
||||||
type LibraryProps = {
|
type LibraryProps = {
|
||||||
libraryItems: GetLibraryItemsPreviewQuery;
|
libraryItems: GetLibraryItemsPreviewQuery;
|
||||||
|
@ -31,21 +32,31 @@ type GroupLibraryItems = Map<
|
||||||
export default function Library(props: LibraryProps): JSX.Element {
|
export default function Library(props: LibraryProps): JSX.Element {
|
||||||
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
const langui = props.langui.websiteInterfaces.data[0].attributes;
|
||||||
|
|
||||||
|
const [showSubitems, setShowSubitems] = useState<boolean>(false);
|
||||||
|
const [sortingMethod, setSortingMethod] = useState<string>("title");
|
||||||
|
const [groupingMethod, setGroupingMethod] = useState<string>("");
|
||||||
|
|
||||||
|
const [filteredItems, setFilteredItems] = useState<
|
||||||
|
LibraryProps["libraryItems"]["libraryItems"]["data"]
|
||||||
|
>(filterItems(showSubitems, props.libraryItems.libraryItems.data));
|
||||||
|
|
||||||
const [sortedItems, setSortedItem] = useState<
|
const [sortedItems, setSortedItem] = useState<
|
||||||
LibraryProps["libraryItems"]["libraryItems"]["data"]
|
LibraryProps["libraryItems"]["libraryItems"]["data"]
|
||||||
>(sortBy("title", props.libraryItems.libraryItems.data));
|
>(sortBy(groupingMethod, filteredItems));
|
||||||
|
|
||||||
const [sortingMethod, setSortingMethod] = useState<string>("title");
|
|
||||||
|
|
||||||
const [groups, setGroups] = useState<GroupLibraryItems>(
|
const [groups, setGroups] = useState<GroupLibraryItems>(
|
||||||
getGroups("", sortedItems)
|
getGroups("", sortedItems)
|
||||||
);
|
);
|
||||||
|
|
||||||
const [groupingMethod, setGroupingMethod] = useState<string>("");
|
useEffect(() => {
|
||||||
|
setFilteredItems(
|
||||||
|
filterItems(showSubitems, props.libraryItems.libraryItems.data)
|
||||||
|
);
|
||||||
|
}, [showSubitems, props.libraryItems.libraryItems.data]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSortedItem(sortBy(sortingMethod, props.libraryItems.libraryItems.data));
|
setSortedItem(sortBy(sortingMethod, filteredItems));
|
||||||
}, [props.libraryItems.libraryItems.data, sortingMethod]);
|
}, [filteredItems, sortingMethod]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setGroups(getGroups(groupingMethod, sortedItems));
|
setGroups(getGroups(groupingMethod, sortedItems));
|
||||||
|
@ -85,6 +96,11 @@ export default function Library(props: LibraryProps): JSX.Element {
|
||||||
onChange={setSortingMethod}
|
onChange={setSortingMethod}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-row gap-2 place-items-center">
|
||||||
|
<p className="flex-shrink-0">Show subitems:</p>
|
||||||
|
<Switch state={showSubitems} setState={setShowSubitems} />
|
||||||
|
</div>
|
||||||
</SubPanel>
|
</SubPanel>
|
||||||
);
|
);
|
||||||
const contentPanel = (
|
const contentPanel = (
|
||||||
|
@ -93,10 +109,10 @@ export default function Library(props: LibraryProps): JSX.Element {
|
||||||
<>
|
<>
|
||||||
{items.length > 0 && (
|
{items.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<h2 className="text-2xl pb-2">{name}</h2>
|
<h2 className="text-2xl pb-2 pt-10 first-of-type:pt-0">{name}</h2>
|
||||||
<div
|
<div
|
||||||
key={name}
|
key={name}
|
||||||
className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12"
|
className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0"
|
||||||
>
|
>
|
||||||
{items.map((item) => (
|
{items.map((item) => (
|
||||||
<LibraryItemsPreview key={item.id} item={item.attributes} />
|
<LibraryItemsPreview key={item.id} item={item.attributes} />
|
||||||
|
@ -168,7 +184,26 @@ function getGroups(
|
||||||
groupType.get("Video")?.push(item);
|
groupType.get("Video")?.push(item);
|
||||||
break;
|
break;
|
||||||
case "ComponentMetadataOther":
|
case "ComponentMetadataOther":
|
||||||
groupType.get("Other")?.push(item);
|
switch (
|
||||||
|
item.attributes.metadata[0].subtype.data.attributes.slug
|
||||||
|
) {
|
||||||
|
case "audio-case":
|
||||||
|
groupType.get("Audio")?.push(item);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "video-case":
|
||||||
|
groupType.get("Video")?.push(item);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "game-case":
|
||||||
|
groupType.get("Game")?.push(item);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
groupType.get("Other")?.push(item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -210,6 +245,26 @@ function getGroups(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterItems(
|
||||||
|
showSubitems: boolean,
|
||||||
|
items: LibraryProps["libraryItems"]["libraryItems"]["data"]
|
||||||
|
): LibraryProps["libraryItems"]["libraryItems"]["data"] {
|
||||||
|
return [...items].filter((item) => {
|
||||||
|
let result = true;
|
||||||
|
if (!showSubitems && !item.attributes.root_item) result = false;
|
||||||
|
if (
|
||||||
|
item.attributes.metadata.length > 0 &&
|
||||||
|
item.attributes.metadata[0].__typename === "ComponentMetadataOther" &&
|
||||||
|
(item.attributes.metadata[0].subtype.data.attributes.slug ===
|
||||||
|
"variant-set" ||
|
||||||
|
item.attributes.metadata[0].subtype.data.attributes.slug ===
|
||||||
|
"relation-set")
|
||||||
|
)
|
||||||
|
result = false;
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function sortBy(
|
function sortBy(
|
||||||
orderByType: string,
|
orderByType: string,
|
||||||
items: LibraryProps["libraryItems"]["libraryItems"]["data"]
|
items: LibraryProps["libraryItems"]["libraryItems"]["data"]
|
||||||
|
|
Loading…
Reference in New Issue