/* eslint-disable react-hooks/exhaustive-deps */ import { useQuery } from "@tanstack/react-query"; import RestartIcon from "./icons/RestartIcon"; import Button from "./ui/Button"; import MultiRangeSlider from "./ui/MultiRangeSlider"; import { api } from "../api/ky"; import { RefObject, useEffect, useState } from "react"; import { useSearchParams } from "react-router"; import { projects } from "../data/projects"; import { useDebounce } from "../hooks/useDebounce"; import clsx from "clsx"; import ProjectSelect from "./ProjectSelect"; import UnitTypesSelect from "./UnitTypesSelect"; import Select from "./ui/Select"; import { AnimatePresence, motion } from "motion/react"; import CloseIcon from "./icons/CloseIcon"; import Project from "../types/Project"; export interface Filters { unitTypes: string[]; views: string[]; area: [number, number]; cost: [number, number]; floor: [number, number]; } function SearchFilters({ inModal = false, setInModal, ref, cost, floor, area, setCost, setFloor, setArea, }: { inModal?: boolean; setInModal: (inModal: boolean) => void; ref?: RefObject; cost: [number, number]; floor: [number, number]; area: [number, number]; setCost: (cost: [number, number]) => void; setFloor: (floor: [number, number]) => void; setArea: (area: [number, number]) => void; }) { const [project, setProject] = useState(); const [unitTypes, setUnitTypes] = useState([]); const [view, setView] = useState("Any view"); const [searchParams, setSearchParams] = useSearchParams(); const { data: filters } = useQuery({ queryKey: ["filters", project], enabled: !!project, queryFn: () => api .get(`units/filters?${project ? `project=${project}` : ""}`) .json(), }); useEffect(() => { const projectValue = searchParams.get("project") || projects[0].title; if (projectValue) setProject(projectValue); const viewValue = searchParams.get("view"); if (viewValue) setView(viewValue); const unitTypesValue = searchParams.getAll("unitTypes"); if (unitTypesValue) setUnitTypes(unitTypesValue); }, [searchParams]); function resetFilters() { window.location.href = "/search"; } const [costInModal, setCostInModal] = useState<[number, number]>(cost); const [areaInModal, setAreaInModal] = useState<[number, number]>(area); const [floorInModal, setFloorInModal] = useState<[number, number]>(floor); useEffect(() => { if (filters) { setCostInModal(filters.cost); setAreaInModal(filters.area); setFloorInModal(filters.floor); } }, [filters, setAreaInModal, setCostInModal, setFloorInModal]); useEffect(() => { if (inModal) return; setCost(costInModal); setArea(areaInModal); setFloor(floorInModal); }, [setCost, costInModal, setArea, areaInModal, setFloor, floorInModal]); const debouncedCost = useDebounce(inModal ? costInModal : cost, 500); const debouncedArea = useDebounce(inModal ? areaInModal : area, 500); const debouncedFloor = useDebounce(inModal ? floorInModal : floor, 500); const { data: count } = useQuery({ queryKey: [ "units", "count", project, unitTypes, view, debouncedCost, debouncedArea, debouncedFloor, ], enabled: !!project && debouncedCost[0] >= 0 && debouncedCost[1] >= 0 && debouncedArea[0] >= 0 && debouncedArea[1] >= 0 && debouncedFloor[0] >= 0 && debouncedFloor[1] >= 0, queryFn: () => api .get( `units/count?${project ? `project=${project}` : ""}${unitTypes .map((unitType) => `&unitTypes=${unitType}`) .join("")}${view !== "Any view" ? `&view=${view}` : ""}${ debouncedCost ? `&cost=${Math.round(debouncedCost[0])},${Math.round( debouncedCost[1] )}` : "" }${ debouncedArea ? `&area=${Math.round(debouncedArea[0])},${Math.round( debouncedArea[1] )}` : "" }${ debouncedFloor ? `&floor=${Math.round(debouncedFloor[0])},${Math.round( debouncedFloor[1] )}` : "" }` ) .json(), }); function handleClose() { const projectValue = searchParams.get("project") || projects[0].title; if (projectValue) setProject(projectValue); const viewValue = searchParams.get("view"); setView(viewValue || "Any view"); const unitTypesValue = searchParams.getAll("unitTypes"); if (unitTypesValue) setUnitTypes(unitTypesValue); setInModal(false); } function handleSelectProject(project: Project) { setProject(project.title); if (!inModal) setSearchParams((prev) => { prev.set("project", project.title); return prev; }); } function handleSelectView(view: string) { setView(view); if (!inModal) setSearchParams((prev) => { if (view !== "Any view") prev.set("view", view); else prev.delete("view"); return prev; }); } function handleSelectUnitTypes(unitTypes: string[]) { setUnitTypes(unitTypes); if (!inModal) setSearchParams((prev) => { prev.delete("unitTypes"); unitTypes.forEach((unitType) => prev.append("unitTypes", unitType)); return prev; }); } function applyFilters() { setInModal(false); setSearchParams((prev) => { prev.set("project", project!); if (view !== "Any view") prev.set("view", view); else prev.delete("view"); prev.delete("unitTypes"); unitTypes.forEach((unitType) => prev.append("unitTypes", unitType)); return prev; }); setCost(costInModal); setArea(areaInModal); setFloor(floorInModal); window.scroll({ top: 0, behavior: "smooth" }); } return ( <> {inModal && (
)}
{inModal && ( )}

Search

{project && ( title === project)!} /> )}

{filters && ( <>

Apartment type