-
{project}
+
{project}
{(unitNo.split("-")[0] === "W" ? "West" : "East") + " Wing"}
@@ -37,7 +37,7 @@ function UnitCard({
{squareFt.toLocaleString(undefined, { maximumFractionDigits: 2 })}{" "}
Sqft
-
+
AED {Intl.NumberFormat("en").format(salesPrice)}
diff --git a/src/components/UnitTypesSelect.tsx b/src/components/UnitTypesSelect.tsx
index 06a0d11..b858e95 100644
--- a/src/components/UnitTypesSelect.tsx
+++ b/src/components/UnitTypesSelect.tsx
@@ -1,30 +1,27 @@
+/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from "react";
-import { Filters } from "./SearchFilters";
import clsx from "clsx";
-import { useSearchParams } from "react-router";
function UnitTypesSelect({
- filters,
+ unitTypes,
onSelect,
+ defaultSelected = [],
}: {
- filters: Filters;
+ unitTypes: string[];
onSelect: (unitTypes: string[]) => void;
+ defaultSelected: string[];
}) {
- const [selectedUnitTypes, setSelectedUnitTypes] = useState
([]);
+ const [selectedUnitTypes, setSelectedUnitTypes] =
+ useState(defaultSelected);
- const [searchParams, setSearchParams] = useSearchParams();
+ useEffect(() => setSelectedUnitTypes(defaultSelected), [defaultSelected]);
- useEffect(() => onSelect(selectedUnitTypes), [onSelect, selectedUnitTypes]);
-
- useEffect(() => {
- const unitTypesValue = searchParams.getAll("unitTypes");
- if (unitTypesValue) setSelectedUnitTypes(unitTypesValue);
- }, [searchParams]);
+ useEffect(() => onSelect(selectedUnitTypes), [selectedUnitTypes]);
return (
- {filters.unitTypes.map((unitType) => (
-
(
+
{
setSelectedUnitTypes((prev) =>
@@ -32,22 +29,16 @@ function UnitTypesSelect({
? prev.filter((type) => type !== unitType)
: [...prev, unitType]
);
- setSearchParams((prev) => {
- if (prev.getAll("unitTypes").includes(unitType))
- prev.delete("unitTypes", unitType);
- else prev.append("unitTypes", unitType);
- return prev;
- });
}}
className={clsx(
- "2xl:px-[1.389vw] 2xl:py-[0.833vw] px-5 py-3 2xl:rounded-[2.778vw] rounded-[40px] 2xl:ring-[0.069vw] ring transition-[box-shadow] cursor-pointer",
+ "2xl:px-[1.389vw] 2xl:py-[0.833vw] px-5 py-3 2xl:rounded-[2.778vw] rounded-[40px] 2xl:ring-[0.069vw] ring transition-[box-shadow] cursor-pointer text-s",
selectedUnitTypes.includes(unitType)
? "ring-[#00BED7]"
- : "ring-[#E2E2DC]"
+ : "ring-[#E2E2DC] text-[#0D1922]/70"
)}
>
{unitType}
-
+
))}
);
diff --git a/src/components/ui/MultiRangeSlider.tsx b/src/components/ui/MultiRangeSlider.tsx
index 3105eff..53f33b3 100644
--- a/src/components/ui/MultiRangeSlider.tsx
+++ b/src/components/ui/MultiRangeSlider.tsx
@@ -16,8 +16,7 @@ interface IMultiRangeSlider {
offset: number;
disabled?: boolean;
label: string;
- onChangeMin: (min: number) => void;
- onChangeMax: (max: number) => void;
+ onChange: (value: [number, number]) => void;
}
function MultiRangeSlider({
@@ -25,8 +24,7 @@ function MultiRangeSlider({
currentMin,
max,
min,
- onChangeMin,
- onChangeMax,
+ onChange,
offset,
label,
disabled = false,
@@ -55,8 +53,8 @@ function MultiRangeSlider({
const value = calculateValue(clientX, current === "min");
if (value !== undefined) {
- if (current === "min") onChangeMin(value);
- else onChangeMax(value);
+ if (current === "min") onChange([value, currentMax]);
+ else onChange([currentMin, value]);
}
}
diff --git a/src/components/ui/Select.tsx b/src/components/ui/Select.tsx
index 75f7bba..719d8a1 100644
--- a/src/components/ui/Select.tsx
+++ b/src/components/ui/Select.tsx
@@ -25,6 +25,8 @@ function Select({
const ref = useClickAway(() => setIsShow(false));
+ useEffect(() => setSelectedOption(defaultOption), [defaultOption]);
+
useEffect(() => onSelect(selectedOption), [selectedOption]);
return (
diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx
index b8b7a2e..59b0965 100644
--- a/src/pages/SearchPage.tsx
+++ b/src/pages/SearchPage.tsx
@@ -1,15 +1,16 @@
-import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
+import { useInfiniteQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
import { IUnit } from "../types/IUnit";
import UnitCard from "../components/UnitCard";
import { useEffect, useRef, useState } from "react";
-import SearchFilters, { Filters } from "../components/SearchFilters";
+import SearchFilters from "../components/SearchFilters";
import { useNavigate, useSearchParams } from "react-router";
import Button from "../components/ui/Button";
import FiltersIcon from "../components/icons/FiltersIcon";
import RestartIcon from "../components/icons/RestartIcon";
import clsx from "clsx";
import { AnimatePresence, motion } from "motion/react";
+import { useDebounce } from "../hooks/useDebounce";
const STEP = 12;
@@ -17,42 +18,40 @@ function SearchPage() {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
- // const project = searchParams.get("project");
- // const unitTypes = searchParams.getAll("unitTypes");
- // const cost = searchParams.getAll("cost");
- // const floor = searchParams.getAll("floor");
- // const area = searchParams.getAll("area");
- // const view = searchParams.get("view");
+ const project = searchParams.get("project");
+ const unitTypes = searchParams.getAll("unitTypes");
+ const view = searchParams.get("view");
- const [project, setProject] = useState();
- const [unitTypes, setUnitTypes] = useState([]);
- const [cost, setCost] = useState([]);
- const [floor, setFloor] = useState([]);
- const [area, setArea] = useState([]);
- const [view, setView] = useState();
+ const [filtersInModal, setFiltersInModal] = useState(false);
- const { data: filters } = useQuery({
- queryKey: ["filters", project],
- enabled: !!project,
- queryFn: () =>
- api
- .get(`units/filters?${project ? `project=${project}` : ""}`)
- .json(),
- });
+ const [cost, setCost] = useState<[number, number]>([-1, -1]);
+ const [floor, setFloor] = useState<[number, number]>([-1, -1]);
+ const [area, setArea] = useState<[number, number]>([-1, -1]);
- useEffect(() => {
- setProject(searchParams.get("project"));
- setUnitTypes(searchParams.getAll("unitTypes"));
- setCost(searchParams.getAll("cost"));
- setFloor(searchParams.getAll("floor"));
- setArea(searchParams.getAll("area"));
- setView(searchParams.get("view"));
- }, [searchParams]);
+ const debouncedCost = useDebounce(cost, 500);
+ const debouncedFloor = useDebounce(floor, 500);
+ const debouncedArea = useDebounce(area, 500);
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteQuery({
initialPageParam: 0,
- queryKey: ["units", project, unitTypes, view, cost, floor, area],
+ queryKey: [
+ "units",
+ project,
+ unitTypes,
+ view,
+ debouncedCost,
+ debouncedFloor,
+ debouncedArea,
+ ],
+ enabled:
+ !!project &&
+ debouncedCost[0] >= 0 &&
+ debouncedCost[1] >= 0 &&
+ debouncedFloor[0] >= 0 &&
+ debouncedFloor[1] >= 0 &&
+ debouncedArea[0] >= 0 &&
+ debouncedArea[1] >= 0,
queryFn: async ({ pageParam = 0 }) =>
await api
.get(
@@ -60,9 +59,19 @@ function SearchPage() {
project ? `&project=${project}` : ""
}${unitTypes.map((unitType) => `&unitTypes=${unitType}`).join("")}${
view ? `&view=${view}` : ""
- }${cost.length > 0 ? `&cost=${cost.join(",")}` : ""}${
- floor.length > 0 ? `&floor=${floor.join(",")}` : ""
- }${area.length > 0 ? `&area=${area.join(",")}` : ""}`
+ }${
+ debouncedCost.length > 0
+ ? `&cost=${debouncedCost.map(Math.round).join(",")}`
+ : ""
+ }${
+ debouncedFloor.length > 0
+ ? `&floor=${debouncedFloor.map(Math.round).join(",")}`
+ : ""
+ }${
+ debouncedArea.length > 0
+ ? `&area=${debouncedArea.map(Math.round).join(",")}`
+ : ""
+ }`
)
.json(),
getNextPageParam: (lastPage, _, lastPageIndex) =>
@@ -72,8 +81,6 @@ function SearchPage() {
const filtersRef = useRef(null);
const observerRef = useRef(null);
- const [filtersInModal, setFiltersInModal] = useState(false);
-
useEffect(() => {
if (!hasNextPage || isFetchingNextPage) return;
const observerElement = observerRef.current;
@@ -119,27 +126,39 @@ function SearchPage() {
}, []);
return (
-
+ <>
-
+
- {project && unitTypes && cost && area && floor && (
-
- {data?.pages.map((page) =>
- page.map((unit) => )
- )}
-
- )}
+ {project &&
+ unitTypes &&
+ debouncedCost &&
+ debouncedArea &&
+ debouncedFloor && (
+
+ {data?.pages.map((page) =>
+ page.map((unit) => )
+ )}
+
+ )}
{showButtons && (
@@ -170,7 +189,7 @@ function SearchPage() {
)}
-
+ >
);
}