diff --git a/src/components/SearchFilters.tsx b/src/components/SearchFilters.tsx index 74fe228..185bdac 100644 --- a/src/components/SearchFilters.tsx +++ b/src/components/SearchFilters.tsx @@ -2,7 +2,6 @@ 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"; @@ -16,6 +15,7 @@ import { AnimatePresence, motion } from "motion/react"; import CloseIcon from "./icons/CloseIcon"; import Project from "../types/Project"; import FiltersIcon from "./icons/FiltersIcon"; +import MultiRangeSlider from "./ui/MultiRangeSlider"; function SearchFilters({ inModal = false, @@ -40,16 +40,24 @@ function SearchFilters({ }) { const [project, setProject] = useState(); const [unitTypes, setUnitTypes] = useState([]); - const [view, setView] = useState("Any view"); + const [view, setView] = useState("Any view"); - const [costInModal, setCostInModal] = useState<[number, number]>(cost); - const [areaInModal, setAreaInModal] = useState<[number, number]>(area); - const [floorInModal, setFloorInModal] = useState<[number, number]>(floor); + const [costInModal, setCostInModal] = useState(cost); + const [areaInModal, setAreaInModal] = useState(area); + const [floorInModal, setFloorInModal] = useState(floor); const debouncedCost = useDebounce(inModal ? costInModal : cost, 1000); const debouncedArea = useDebounce(inModal ? areaInModal : area, 1000); const debouncedFloor = useDebounce(inModal ? floorInModal : floor, 1000); + const [costChanged, setCostChanged] = useState(true); + const [areaChanged, setAreaChanged] = useState(true); + const [floorChanged, setFloorChanged] = useState(true); + + const debouncedCostChanged = useDebounce(costChanged, 1000); + const debouncedAreaChanged = useDebounce(areaChanged, 1000); + const debouncedFloorChanged = useDebounce(floorChanged, 1000); + const [searchParams, setSearchParams] = useSearchParams(); const { data: unitTypesInFilters } = useQuery({ @@ -57,11 +65,10 @@ function SearchFilters({ "filters", "unitTypes", project, - // debouncedArea, - // debouncedCost, - // debouncedFloor, - // view, - searchParams, + debouncedCostChanged ? debouncedCost : undefined, + debouncedAreaChanged ? debouncedArea : undefined, + debouncedFloorChanged ? debouncedFloor : undefined, + view, ], enabled: !!project, queryFn: () => @@ -71,15 +78,15 @@ function SearchFilters({ view !== "Any view" ? `&view=${view}` : "" }${ debouncedCost[0] >= 0 && debouncedCost[1] >= 0 - ? `&cost=${debouncedCost.map(Math.round).join(",")}` + ? `&cost=${debouncedCost.map(Math.round).join()}` : "" }${ debouncedFloor[0] >= 0 && debouncedFloor[1] >= 0 - ? `&floor=${debouncedFloor.map(Math.round).join(",")}` + ? `&floor=${debouncedFloor.map(Math.round).join()}` : "" }${ debouncedArea[0] >= 0 && debouncedArea[1] >= 0 - ? `&area=${debouncedArea.map(Math.round).join(",")}` + ? `&area=${debouncedArea.map(Math.round).join()}` : "" }` ) @@ -91,11 +98,10 @@ function SearchFilters({ "filters", "views", project, - debouncedArea, - debouncedCost, - debouncedFloor, + debouncedCostChanged ? debouncedCost : undefined, + debouncedAreaChanged ? debouncedArea : undefined, + debouncedFloorChanged ? debouncedFloor : undefined, unitTypes, - searchParams, ], enabled: !!project, queryFn: () => @@ -105,15 +111,15 @@ function SearchFilters({ .map((unitType) => `&unitTypes=${unitType}`) .join("")}${ debouncedCost[0] >= 0 && debouncedCost[1] >= 0 - ? `&cost=${debouncedCost.map(Math.round).join(",")}` + ? `&cost=${debouncedCost.map(Math.round).join()}` : "" }${ debouncedFloor[0] >= 0 && debouncedFloor[1] >= 0 - ? `&floor=${debouncedFloor.map(Math.round).join(",")}` + ? `&floor=${debouncedFloor.map(Math.round).join()}` : "" }${ debouncedArea[0] >= 0 && debouncedArea[1] >= 0 - ? `&area=${debouncedArea.map(Math.round).join(",")}` + ? `&area=${debouncedArea.map(Math.round).join()}` : "" }` ) @@ -125,11 +131,10 @@ function SearchFilters({ "filters", "cost", project, - // debouncedArea, - // debouncedFloor, - // unitTypes, - // view, - searchParams, + debouncedAreaChanged ? debouncedArea : undefined, + debouncedFloorChanged ? debouncedFloor : undefined, + unitTypes, + view, ], enabled: !!project, queryFn: () => @@ -139,11 +144,11 @@ function SearchFilters({ .map((unitType) => `&unitTypes=${unitType}`) .join("")}${view !== "Any view" ? `&view=${view}` : ""}${ debouncedFloor[0] >= 0 && debouncedFloor[1] >= 0 - ? `&floor=${debouncedFloor.map(Math.round).join(",")}` + ? `&floor=${debouncedFloor.map(Math.round).join()}` : "" }${ debouncedArea[0] >= 0 && debouncedArea[1] >= 0 - ? `&area=${debouncedArea.map(Math.round).join(",")}` + ? `&area=${debouncedArea.map(Math.round).join()}` : "" }` ) @@ -155,11 +160,10 @@ function SearchFilters({ "filters", "floor", project, - // debouncedArea, - // debouncedCost, - // unitTypes, - // view, - searchParams, + debouncedCostChanged ? debouncedCost : undefined, + debouncedAreaChanged ? debouncedArea : undefined, + unitTypes, + view, ], enabled: !!project, queryFn: () => @@ -169,11 +173,11 @@ function SearchFilters({ .map((unitType) => `&unitTypes=${unitType}`) .join("")}${view !== "Any view" ? `&view=${view}` : ""}${ debouncedCost[0] >= 0 && debouncedCost[1] >= 0 - ? `&cost=${debouncedCost.map(Math.round).join(",")}` + ? `&cost=${debouncedCost.map(Math.round).join()}` : "" }${ debouncedArea[0] >= 0 && debouncedArea[1] >= 0 - ? `&area=${debouncedArea.map(Math.round).join(",")}` + ? `&area=${debouncedArea.map(Math.round).join()}` : "" }` ) @@ -185,11 +189,10 @@ function SearchFilters({ "filters", "area", project, - // debouncedCost, - // debouncedFloor, - // unitTypes, - // view, - searchParams, + debouncedCostChanged ? debouncedCost : undefined, + debouncedFloorChanged ? debouncedFloor : undefined, + unitTypes, + view, ], enabled: !!project, queryFn: () => @@ -199,11 +202,11 @@ function SearchFilters({ .map((unitType) => `&unitTypes=${unitType}`) .join("")}${view !== "Any view" ? `&view=${view}` : ""}${ debouncedCost[0] >= 0 && debouncedCost[1] >= 0 - ? `&cost=${debouncedCost.map(Math.round).join(",")}` + ? `&cost=${debouncedCost.map(Math.round).join()}` : "" }${ debouncedFloor[0] >= 0 && debouncedFloor[1] >= 0 - ? `&floor=${debouncedFloor.map(Math.round).join(",")}` + ? `&floor=${debouncedFloor.map(Math.round).join()}` : "" }` ) @@ -226,26 +229,55 @@ function SearchFilters({ } useEffect(() => { - if (costInFilters && areaInFilters && floorInFilters) { - setCostInModal([costInFilters.min, costInFilters.max]); + if (areaInFilters) { setAreaInModal([areaInFilters.min, areaInFilters.max]); - setFloorInModal([floorInFilters.min, floorInFilters.max]); + setAreaChanged(false); } - }, [ - costInFilters, - areaInFilters, - floorInFilters, - setAreaInModal, - setCostInModal, - setFloorInModal, - ]); + }, [areaInFilters]); + + useEffect(() => { + if (costInFilters) { + setCostInModal([costInFilters.min, costInFilters.max]); + return () => setCostChanged(false); + } + }, [costInFilters]); + + useEffect(() => { + if (floorInFilters) { + setFloorInModal([floorInFilters.min, floorInFilters.max]); + setFloorChanged(false); + } + }, [floorInFilters]); useEffect(() => { if (inModal) return; setCost(costInModal); + }, [costInModal, inModal]); + + useEffect(() => { + if (inModal) return; setArea(areaInModal); + }, [areaInModal, inModal]); + + useEffect(() => { + if (inModal) return; setFloor(floorInModal); - }, [setCost, costInModal, setArea, areaInModal, setFloor, floorInModal]); + }, [floorInModal, inModal]); + + function handleCostChange([min, max]: [number, number]) { + setCostInModal([min, max]); + setCostChanged(true); + } + + function handleFloorChange([min, max]: [number, number]) { + setFloorInModal([min, max]); + setFloorChanged(true); + } + + function handleAreaChange([min, max]: [number, number]) { + setAreaInModal([min, max]); + setAreaChanged(true); + } const { data: count } = useQuery({ queryKey: [ @@ -272,22 +304,12 @@ function SearchFilters({ `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] - )}` - : "" + debouncedCost ? `&cost=${debouncedCost.map(Math.round).join()}` : "" }${ - debouncedArea - ? `&area=${Math.round(debouncedArea[0])},${Math.round( - debouncedArea[1] - )}` - : "" + debouncedArea ? `&area=${debouncedArea.map(Math.round).join()}` : "" }${ debouncedFloor - ? `&floor=${Math.round(debouncedFloor[0])},${Math.round( - debouncedFloor[1] - )}` + ? `&floor=${debouncedFloor.map(Math.round).join()}` : "" }` ) @@ -315,16 +337,6 @@ function SearchFilters({ }); } - 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) @@ -335,6 +347,16 @@ function SearchFilters({ }); } + 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 applyFilters() { setInModal(false); setSearchParams((prev) => { @@ -351,8 +373,6 @@ function SearchFilters({ window.scroll({ top: 0, behavior: "smooth" }); } - useEffect(() => {}, []); - return ( <> {inModal && ( @@ -435,7 +455,7 @@ function SearchFilters({ currentMin={inModal ? costInModal[0] : cost[0]} currentMax={inModal ? costInModal[1] : cost[1]} offset={1} - onChange={setCostInModal} + onChange={handleCostChange} label="Cost, AED" />