import { Transition } from "@headlessui/react"; import clsx from "clsx"; import { FormEvent, Fragment, useEffect, useState } from "react"; import { Colors } from "../../../application/enums/shared/Colors"; import { useOuterClick } from "../../../utils/shared/KeypressUtils"; import { updateItemByIdx } from "../../../utils/shared/ObjectUtils"; import FilterEmptyIcon from "../icons/FilterEmptyIcon"; import FilterFilledIcon from "../icons/FilterFilledIcon"; import InputCheckboxInline from "./InputCheckboxInline"; import InputSearch from "./InputSearch"; import InputSelector from "./InputSelector"; import { useApp } from "../../../hooks"; import { useSearchParams } from "next/navigation"; export type FilterDto = { name: string; title: string; options?: { name: string; value: string; color?: Colors }[]; hideSearch?: boolean; isBoolean?: boolean; }; export type FilterValueDto = FilterDto & { selected: boolean; value?: string; }; interface Props { filters: FilterDto[]; withSearch?: boolean; withName?: boolean; // saveEntityFilters?: { // entity: EntityWithDetails; // currentView: EntityView | null; // onSaveFilters: (filters: FilterValueDto[]) => void; // }; } export default function InputFilters({ filters, withSearch = true }: Props) { const { t } = useApp(); const [searchParams, setSearchParams] = useSearchParams(); const [opened, setOpened] = useState(false); const [items, setItems] = useState([]); const [filteredItems, setFilteredItems] = useState(0); const [searchInput, setSearchInput] = useState(""); useEffect(() => { const items: FilterValueDto[] = filters.map((item) => { const value = searchParams[item.name] ?? undefined; return { ...item, selected: value !== undefined, value, }; }); setItems(items); setSearchInput(searchParams["q"] ?? ""); // eslint-disable-next-line react-hooks/exhaustive-deps }, [filters]); useEffect(() => { const appliedFilters: FilterValueDto[] = []; items.forEach((item) => { const value = searchParams[item.name] ?? undefined; if (value) { appliedFilters.push(item); } }); if (withSearch) { setFilteredItems(appliedFilters.length + (searchParams["q"] ? 1 : 0)); } else { setFilteredItems(appliedFilters.length); } }, [items, searchInput, searchParams, withSearch]); // useEffect(() => { // const searchInput = searchParams.get("q"); // setSearchInput(searchInput ?? ""); // const newItems = items; // items.forEach((item, idx) => { // const valueInParam = searchParams.get(item.name); // if (valueInParam) { // newItems[idx].selected = true; // newItems[idx].value = valueInParam.toString(); // } else { // newItems[idx].selected = false; // newItems[idx].value = undefined; // } // }); // setItems(newItems); // // eslint-disable-next-line react-hooks/exhaustive-deps // }, [searchParams]); function onClear() { setOpened(false); items.forEach((item) => { //@ts-ignore searchParams.delete(item.name); item.selected = false; item.value = undefined; }); setItems(items); //@ts-ignore searchParams.delete("page"); //@ts-ignore searchParams.delete("q"); setSearchInput(""); //@ts-ignore setSearchParams(searchParams); } function onSubmit(e: FormEvent) { e.preventDefault(); items.forEach((item) => { if (item.selected && item.value) { //@ts-ignore searchParams.set(item.name, item.value?.toString() ?? ""); } else { //@ts-ignore searchParams.delete(item.name); } }); if (searchInput) { //@ts-ignore searchParams.set("q", searchInput); } else { //@ts-ignore searchParams.delete("q"); } //@ts-ignore searchParams.delete("page"); //@ts-ignore setSearchParams(searchParams); setOpened(false); } const clickOutside = useOuterClick(() => setOpened(false)); return (
{t("shared.filters")}
{withSearch && (
)} {items.map((filter, idx) => { return (
{ updateItemByIdx(items, setItems, idx, { selected: Boolean(e), }); }} />
{filter.selected && (
{filter.options && filter.options.length > 0 ? (
{ return { value: item.value, name: item.name ? t(item.name) : item.value, color: item.color, }; })} value={filter.value} withLabel={false} setValue={(e) => { updateItemByIdx(items, setItems, idx, { value: e, }); }} className="w-full pb-1" />
) : filter.isBoolean ? (
{ updateItemByIdx(items, setItems, idx, { value: e, }); }} className="w-full pb-1" />
) : (
contains
{ updateItemByIdx(items, setItems, idx, { value: e.currentTarget.value, }); }} />
)}
)}
); })} {/* {saveEntityFilters && (
)} */}
); }