completed search page, some chasnges buttons in sequence

This commit is contained in:
2025-04-30 13:05:02 +05:00
parent 8af3ed8f5e
commit f0f4e6f234
11 changed files with 189 additions and 69 deletions
+69 -10
View File
@@ -1,22 +1,29 @@
import { useInfiniteQuery } from "@tanstack/react-query";
import { useInfiniteQuery, useQueryClient } 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 from "../components/SearchFilters";
import { useNavigate, useSearchParams } from "react-router";
import SearchFilters, { Filters } from "../components/SearchFilters";
import { 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";
import Select from "../components/ui/Select";
const SORT_OPTIONS = {
"Sort by ascending price": "cost asc",
"Sort by descending price": "cost desc",
"Sort by ascending area": "sqft asc",
"Sort by descending area": "sqft desc",
};
const STEP = 12;
function SearchPage() {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const project = searchParams.get("project");
const unitTypes = searchParams.getAll("unitTypes");
@@ -32,6 +39,10 @@ function SearchPage() {
const debouncedFloor = useDebounce(floor, 500);
const debouncedArea = useDebounce(area, 500);
const [sort, setSort] = useState<keyof typeof SORT_OPTIONS>(
"Sort by ascending price"
);
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteQuery({
initialPageParam: 0,
@@ -43,6 +54,7 @@ function SearchPage() {
debouncedCost,
debouncedFloor,
debouncedArea,
sort,
],
enabled:
!!project &&
@@ -71,7 +83,7 @@ function SearchPage() {
debouncedArea.length > 0
? `&area=${debouncedArea.map(Math.round).join(",")}`
: ""
}`
}${sort ? `&order=${SORT_OPTIONS[sort].split(" ").join(",")}` : ""}`
)
.json<IUnit[]>(),
getNextPageParam: (lastPage, _, lastPageIndex) =>
@@ -125,6 +137,37 @@ function SearchPage() {
};
}, []);
const [activeFiltersCount, setActiveFiltersCount] = useState(0);
const queryClient = useQueryClient();
useEffect(() => {
const filters = queryClient.getQueryData<Filters>(["filters", project]);
if (filters) {
setActiveFiltersCount(
+!!view +
+!!unitTypes.length +
+(debouncedCost[0] !== filters.cost[0]) +
+(debouncedCost[1] !== filters.cost[1]) +
+(debouncedArea[0] !== filters.area[0]) +
+(debouncedArea[1] !== filters.area[1]) +
+(debouncedFloor[0] !== filters.floor[0]) +
+(debouncedFloor[1] !== filters.floor[1])
);
}
}, [
queryClient,
unitTypes,
view,
project,
debouncedCost,
cost,
debouncedArea,
area,
debouncedFloor,
floor,
]);
return (
<>
<SearchFilters
@@ -133,13 +176,21 @@ function SearchPage() {
setInModal={setFiltersInModal}
{...{ area, cost, floor, setArea, setCost, setFloor }}
/>
<div className="2xl:p-[2.222vw] p-4 min-h-dvh">
<div className="2xl:p-[2.222vw] p-4 min-h-dvh 2xl:space-y-[1.111vw] space-y-4">
<Select
options={Object.keys(SORT_OPTIONS)}
defaultOption={sort}
onSelect={(opt) => setSort(opt as keyof typeof SORT_OPTIONS)}
className="2xl:max-w-[22.778vw] md:max-2xl:max-w-[45.833vw]"
/>
<hr className="2xl:h-[0.069vw] border-[#E2E2DC]" />
<AnimatePresence mode="wait">
{project &&
unitTypes &&
debouncedCost &&
debouncedArea &&
debouncedFloor && (
debouncedFloor &&
sort && (
<motion.div
key={
project +
@@ -147,7 +198,8 @@ function SearchPage() {
view +
debouncedCost +
debouncedArea +
debouncedFloor
debouncedFloor +
sort
}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
@@ -170,16 +222,23 @@ function SearchPage() {
: "top-[calc(100dvh-2.222vw)] -translate-y-full"
)}
>
<Button onClick={() => setFiltersInModal(true)}>
<Button onClick={() => setFiltersInModal(true)} className="relative">
<span className="2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4 text-white">
<FiltersIcon />
</span>
<span className="text-caption-m">Filters</span>
{!!activeFiltersCount && (
<div className="absolute 2xl:top-[0.139vw] 2xl:right-[0.139vw] top-0.5 right-0.5 rounded-full w-4 text-caption-s aspect-square bg-white text-[#00BED7]">
{activeFiltersCount}
</div>
)}
</Button>
<Button
variant="secondary"
className="2xl:!outline-[0.069vw] !outline !outline-[#E2E2DC]"
onClick={() => navigate("/search")}
onClick={() => {
window.location.href = "/search";
}}
>
<span className="2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4 text-[#0D1922]/70">
<RestartIcon />