import AppLayout from "components/AppLayout"; import Chip from "components/Chip"; import Select from "components/Inputs/Select"; import Switch from "components/Inputs/Switch"; import PanelHeader from "components/PanelComponents/PanelHeader"; import ContentPanel, { ContentPanelWidthSizes, } from "components/Panels/ContentPanel"; import SubPanel from "components/Panels/SubPanel"; import ThumbnailPreview from "components/PreviewCard"; import { GetLibraryItemsPreviewQuery } from "graphql/generated"; import { getReadySdk } from "graphql/sdk"; import { GetStaticPropsContext } from "next"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import { convertPrice, prettyDate, prettyinlineTitle, prettyItemSubType, } from "queries/helpers"; import { useEffect, useState } from "react"; interface Props extends AppStaticProps { items: Exclude< GetLibraryItemsPreviewQuery["libraryItems"], null | undefined >["data"]; } type GroupLibraryItems = Map; export default function Library(props: Props): JSX.Element { const { langui, items: libraryItems, currencies } = props; const [showSubitems, setShowSubitems] = useState(false); const [showPrimaryItems, setShowPrimaryItems] = useState(true); const [showSecondaryItems, setShowSecondaryItems] = useState(false); const [sortingMethod, setSortingMethod] = useState(0); const [groupingMethod, setGroupingMethod] = useState(-1); const [keepInfoVisible, setKeepInfoVisible] = useState(false); const [filteredItems, setFilteredItems] = useState( filterItems( showSubitems, showPrimaryItems, showSecondaryItems, libraryItems ) ); const [sortedItems, setSortedItem] = useState( sortBy(groupingMethod, filteredItems, currencies) ); const [groups, setGroups] = useState( getGroups(langui, groupingMethod, sortedItems) ); useEffect(() => { setFilteredItems( filterItems( showSubitems, showPrimaryItems, showSecondaryItems, libraryItems ) ); }, [showSubitems, libraryItems, showPrimaryItems, showSecondaryItems]); useEffect(() => { setSortedItem(sortBy(sortingMethod, filteredItems, currencies)); }, [currencies, filteredItems, sortingMethod]); useEffect(() => { setGroups(getGroups(langui, groupingMethod, sortedItems)); }, [langui, groupingMethod, sortedItems]); const subPanel = (

{langui.group_by}:

{langui.show_subitems}:

{langui.show_primary_items}:

{langui.show_secondary_items}:

{"Always show info"}:

); const contentPanel = ( {[...groups].map(([name, items]) => ( <> {items.length > 0 && ( <> {name && (

{name} {`${items.length} ${ items.length <= 1 ? langui.result?.toLowerCase() ?? "result" : langui.results?.toLowerCase() ?? "results" }`}

)}
{items.map((item) => ( <> {item.attributes && ( 0 && item.attributes.metadata[0] ? [prettyItemSubType(item.attributes.metadata[0])] : [] } bottomChips={item.attributes.categories?.data.map( (category) => category.attributes?.short ?? "" )} metadata={{ currencies: currencies, release_date: item.attributes.release_date, price: item.attributes.price, position: "Bottom", }} /> )} ))}
)} ))}
); return ( ); } export async function getStaticProps( context: GetStaticPropsContext ): Promise<{ notFound: boolean } | { props: Props }> { const sdk = getReadySdk(); const items = await sdk.getLibraryItemsPreview({ language_code: context.locale ?? "en", }); if (!items.libraryItems) return { notFound: true }; const props: Props = { ...(await getAppStaticProps(context)), items: items.libraryItems.data, }; return { props: props, }; } function getGroups( langui: AppStaticProps["langui"], groupByType: number, items: Props["items"] ): GroupLibraryItems { switch (groupByType) { case 0: { const typeGroup = new Map(); typeGroup.set("Drakengard 1", []); typeGroup.set("Drakengard 1.3", []); typeGroup.set("Drakengard 2", []); typeGroup.set("Drakengard 3", []); typeGroup.set("Drakengard 4", []); typeGroup.set("NieR Gestalt", []); typeGroup.set("NieR Replicant", []); typeGroup.set("NieR Replicant ver.1.22474487139...", []); typeGroup.set("NieR:Automata", []); typeGroup.set("NieR Re[in]carnation", []); typeGroup.set("SINoALICE", []); typeGroup.set("Voice of Cards", []); typeGroup.set("Final Fantasy XIV", []); typeGroup.set("Thou Shalt Not Die", []); typeGroup.set("Bakuken", []); typeGroup.set("YoRHa", []); typeGroup.set("YoRHa Boys", []); typeGroup.set(langui.no_category, []); items.map((item) => { if (item.attributes?.categories?.data.length === 0) { typeGroup.get(langui.no_category)?.push(item); } else { item.attributes?.categories?.data.map((category) => { typeGroup.get(category.attributes?.name)?.push(item); }); } }); return typeGroup; } case 1: { const group: GroupLibraryItems = new Map(); group.set(langui.audio ?? "Audio", []); group.set(langui.game ?? "Game", []); group.set(langui.textual ?? "Textual", []); group.set(langui.video ?? "Video", []); group.set(langui.other ?? "Other", []); group.set(langui.group ?? "Group", []); group.set(langui.no_type ?? "No type", []); items.map((item) => { if (item.attributes?.metadata && item.attributes.metadata.length > 0) { switch (item.attributes.metadata[0]?.__typename) { case "ComponentMetadataAudio": group.get(langui.audio ?? "Audio")?.push(item); break; case "ComponentMetadataGame": group.get(langui.game ?? "Game")?.push(item); break; case "ComponentMetadataBooks": group.get(langui.textual ?? "Textual")?.push(item); break; case "ComponentMetadataVideo": group.get(langui.video ?? "Video")?.push(item); break; case "ComponentMetadataOther": group.get(langui.other ?? "Other")?.push(item); break; case "ComponentMetadataGroup": switch ( item.attributes.metadata[0]?.subitems_type?.data?.attributes ?.slug ) { case "audio": group.get(langui.audio ?? "Audio")?.push(item); break; case "video": group.get(langui.video ?? "Video")?.push(item); break; case "game": group.get(langui.game ?? "Game")?.push(item); break; case "textual": group.get(langui.textual ?? "Textual")?.push(item); break; case "mixed": group.get(langui.group ?? "Group")?.push(item); break; default: { throw new Error( "An unexpected subtype of group-metadata was given" ); } } break; default: { throw new Error("An unexpected type of metadata was given"); } } } else { group.get(langui.no_type ?? "No type")?.push(item); } }); return group; } case 2: { const years: number[] = []; items.map((item) => { if (item.attributes?.release_date?.year) { if (!years.includes(item.attributes.release_date.year)) years.push(item.attributes.release_date.year); } }); const group: GroupLibraryItems = new Map(); years.sort((a, b) => a - b); years.map((year) => { group.set(year.toString(), []); }); group.set(langui.no_year ?? "No year", []); items.map((item) => { if (item.attributes?.release_date?.year) { group.get(item.attributes.release_date.year.toString())?.push(item); } else { group.get(langui.no_year ?? "No year")?.push(item); } }); return group; } default: { const group: GroupLibraryItems = new Map(); group.set("", items); return group; } } } function filterItems( showSubitems: boolean, showPrimaryItems: boolean, showSecondaryItems: boolean, items: Props["items"] ): Props["items"] { return [...items].filter((item) => { if (!showSubitems && !item.attributes?.root_item) return false; if ( showSubitems && item.attributes?.metadata?.[0]?.__typename === "ComponentMetadataGroup" && (item.attributes.metadata[0].subtype?.data?.attributes?.slug === "variant-set" || item.attributes.metadata[0].subtype?.data?.attributes?.slug === "relation-set") ) return false; if (item.attributes?.primary && !showPrimaryItems) return false; if (!item.attributes?.primary && !showSecondaryItems) return false; return true; }); } function sortBy( orderByType: number, items: Props["items"], currencies: AppStaticProps["currencies"] ): Props["items"] { switch (orderByType) { case 0: return [...items].sort((a, b) => { const titleA = prettyinlineTitle( "", a.attributes?.title, a.attributes?.subtitle ); const titleB = prettyinlineTitle( "", b.attributes?.title, b.attributes?.subtitle ); return titleA.localeCompare(titleB); }); case 1: return [...items].sort((a, b) => { const priceA = a.attributes?.price ? convertPrice(a.attributes.price, currencies[0]) : 99999; const priceB = b.attributes?.price ? convertPrice(b.attributes.price, currencies[0]) : 99999; return priceA - priceB; }); case 2: return [...items].sort((a, b) => { const dateA = a.attributes?.release_date ? prettyDate(a.attributes.release_date) : "9999"; const dateB = b.attributes?.release_date ? prettyDate(b.attributes.release_date) : "9999"; return dateA.localeCompare(dateB); }); default: return items; } }