import { GetStaticProps } from "next"; import { useState, useMemo, useCallback } from "react"; import { useBoolean } from "usehooks-ts"; import { AppLayout, AppLayoutRequired } 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 { 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 { useDeviceSupportsHover } 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 { getOpenGraph } from "helpers/openGraph"; import { HorizontalLine } from "components/HorizontalLine"; import { TranslatedPreviewCard } from "components/PreviewCard"; import { useIsContentPanelAtLeast } from "hooks/useContainerQuery"; import { cJoin, cIf } from "helpers/className"; import { useAppLayout } from "contexts/AppLayoutContext"; import { getLangui } from "graphql/fetchLocalData"; /* * ╭─────────────╮ * ────────────────────────────────────────╯ CONSTANTS ╰────────────────────────────────────────── */ const DEFAULT_FILTERS_STATE = { groupingMethod: -1, keepInfoVisible: false, searchName: "", }; /* * ╭────────╮ * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── */ interface Props extends AppLayoutRequired { contents: NonNullable["data"]; } const Contents = ({ contents, ...otherProps }: Props): JSX.Element => { const hoverable = useDeviceSupportsHover(); const { langui } = useAppLayout(); const isContentPanelAtLeast4xl = useIsContentPanelAtLeast("4xl"); const [groupingMethod, setGroupingMethod] = useState( DEFAULT_FILTERS_STATE.groupingMethod ); const { value: keepInfoVisible, toggle: toggleKeepInfoVisible, setValue: setKeepInfoVisible, } = useBoolean(DEFAULT_FILTERS_STATE.keepInfoVisible); const [searchName, setSearchName] = useState( DEFAULT_FILTERS_STATE.searchName ); 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 (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; }, [searchName] ); const subPanel = useMemo( () => (