import { GetStaticProps } from "next"; import { useState, useMemo, useCallback } from "react"; import { AppLayout } from "components/AppLayout"; 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 { AppStaticProps, getAppStaticProps } from "graphql/getAppStaticProps"; import { getReadySdk } from "graphql/sdk"; import { prettyinlineTitle, prettySlug } from "helpers/formatters"; import { TextInput } from "components/Inputs/TextInput"; import { WithLabel } from "components/Inputs/WithLabel"; import { Button } from "components/Inputs/Button"; import { useMediaHoverable } from "hooks/useMediaQuery"; import { Icon } from "components/Ico"; import { filterDefined, filterHasAttributes } from "helpers/others"; import { GetContentsQuery } from "graphql/generated"; import { SmartList } from "components/SmartList"; import { SelectiveNonNullable } from "helpers/types/SelectiveNonNullable"; import { useBoolean } from "hooks/useBoolean"; import { TranslatedPreviewCard } from "components/Translated"; /* * ╭─────────────╮ * ────────────────────────────────────────╯ CONSTANTS ╰────────────────────────────────────────── */ const DEFAULT_FILTERS_STATE = { groupingMethod: -1, keepInfoVisible: false, combineRelatedContent: true, searchName: "", }; /* * ╭────────╮ * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── */ interface Props extends AppStaticProps { contents: NonNullable["data"]; } const Contents = ({ langui, contents, languages, ...otherProps }: Props): JSX.Element => { const hoverable = useMediaHoverable(); const [groupingMethod, setGroupingMethod] = useState( DEFAULT_FILTERS_STATE.groupingMethod ); const { state: keepInfoVisible, toggleState: toggleKeepInfoVisible, setState: setKeepInfoVisible, } = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible); const { state: combineRelatedContent, toggleState: toggleCombineRelatedContent, setState: setCombineRelatedContent, } = useBoolean(DEFAULT_FILTERS_STATE.combineRelatedContent); const [searchName, setSearchName] = useState( DEFAULT_FILTERS_STATE.searchName ); const effectiveCombineRelatedContent = useMemo( () => (searchName.length > 1 ? false : combineRelatedContent), [combineRelatedContent, searchName.length] ); const groupingFunction = useCallback( ( item: SelectiveNonNullable< NonNullable["data"][number], "attributes" | "id" > ): string[] => { switch (groupingMethod) { case 0: { const categories = filterHasAttributes( item.attributes.categories?.data, ["attributes"] as const ); if (categories.length > 0) { return categories.map((category) => category.attributes.name); } return [langui.no_category ?? "No category"]; } case 1: { return [ item.attributes.type?.data?.attributes?.titles?.[0]?.title ?? item.attributes.type?.data?.attributes?.slug ? prettySlug(item.attributes.type.data.attributes.slug) : langui.no_type ?? "No type", ]; } default: { return [""]; } } }, [groupingMethod, langui] ); const filteringFunction = useCallback( ( item: SelectiveNonNullable ) => { if ( effectiveCombineRelatedContent && item.attributes.group?.data?.attributes?.combine === true && item.attributes.group.data.attributes.contents?.data[0].id !== item.id ) { return false; } if (searchName.length > 1) { if ( filterDefined(item.attributes.translations).find((translation) => prettyinlineTitle( translation.pre_title, translation.title, translation.subtitle ) .toLowerCase() .includes(searchName.toLowerCase()) ) ) { return true; } return false; } return true; }, [effectiveCombineRelatedContent, searchName] ); const subPanel = useMemo( () => ( } /> 1} input={ } /> {hoverable && ( } /> )}