upd
This commit is contained in:
@@ -7,15 +7,15 @@ import Select from "./ui/Select";
|
||||
function ProjectSelect({
|
||||
projects,
|
||||
onSelect,
|
||||
defaultProject,
|
||||
}: {
|
||||
projects: Project[];
|
||||
onSelect: (project: Project) => void;
|
||||
defaultProject: Project;
|
||||
}) {
|
||||
const [selectedProject, setSelectedProject] = useState(projects[0]);
|
||||
const [selectedProject, setSelectedProject] = useState(defaultProject);
|
||||
|
||||
useEffect(() => {
|
||||
onSelect(selectedProject);
|
||||
}, [selectedProject]);
|
||||
useEffect(() => onSelect(selectedProject), [selectedProject]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -45,9 +45,11 @@ function ProjectSelect({
|
||||
options={projects.map((project) => project.title)}
|
||||
onSelect={(option) =>
|
||||
setSelectedProject(
|
||||
projects.find((project) => project.title === option) || projects[0]
|
||||
projects.find((project) => project.title === option) ||
|
||||
defaultProject
|
||||
)
|
||||
}
|
||||
defaultOption={defaultProject.title}
|
||||
className="md:hidden"
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -24,12 +24,14 @@ export interface Filters {
|
||||
|
||||
function SearchFilters({
|
||||
inModal = false,
|
||||
filters,
|
||||
ref,
|
||||
}: {
|
||||
inModal?: boolean;
|
||||
filters?: Filters;
|
||||
ref?: RefObject<HTMLDivElement | null>;
|
||||
}) {
|
||||
const [project, setProject] = useState<string>(projects[0].title);
|
||||
const [project, setProject] = useState<string>();
|
||||
const [unitTypes, setUnitTypes] = useState<string[]>([]);
|
||||
const [view, setView] = useState<string>("Any view");
|
||||
|
||||
@@ -37,19 +39,10 @@ function SearchFilters({
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { data: filters } = useQuery({
|
||||
queryKey: ["filters", project],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(`units/filters?${project ? `project=${project}` : ""}`)
|
||||
.json<Filters>(),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const projectValue = searchParams.get("project");
|
||||
// const unitTypesValue = searchParams.getAll("unitTypes");
|
||||
if (projectValue) setProject(projectValue);
|
||||
// if (unitTypesValue) setUnitTypes(unitTypesValue);
|
||||
|
||||
const viewValue = searchParams.get("view");
|
||||
if (viewValue) setView(viewValue);
|
||||
}, [searchParams]);
|
||||
@@ -110,6 +103,7 @@ function SearchFilters({
|
||||
debouncedMinFloor,
|
||||
debouncedMaxFloor,
|
||||
],
|
||||
enabled: !!project,
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(
|
||||
@@ -138,43 +132,6 @@ function SearchFilters({
|
||||
.json<number>(),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedMinCost && debouncedMaxCost)
|
||||
setSearchParams((prev) => {
|
||||
prev.set(
|
||||
"cost",
|
||||
`${Math.round(debouncedMinCost)},${Math.round(debouncedMaxCost)}`
|
||||
);
|
||||
return prev;
|
||||
});
|
||||
|
||||
if (debouncedMinArea && debouncedMaxArea)
|
||||
setSearchParams((prev) => {
|
||||
prev.set(
|
||||
"area",
|
||||
`${Math.round(debouncedMinArea)},${Math.round(debouncedMaxArea)}`
|
||||
);
|
||||
return prev;
|
||||
});
|
||||
|
||||
if (debouncedMinFloor && debouncedMaxFloor)
|
||||
setSearchParams((prev) => {
|
||||
prev.set(
|
||||
"floor",
|
||||
`${Math.round(debouncedMinFloor)},${Math.round(debouncedMaxFloor)}`
|
||||
);
|
||||
return prev;
|
||||
});
|
||||
}, [
|
||||
debouncedMinCost,
|
||||
debouncedMaxCost,
|
||||
debouncedMinArea,
|
||||
debouncedMaxArea,
|
||||
debouncedMinFloor,
|
||||
debouncedMaxFloor,
|
||||
setSearchParams,
|
||||
]);
|
||||
|
||||
function handleProjectSelect(project: Project) {
|
||||
setProject(project.title);
|
||||
setSearchParams((prev) => {
|
||||
@@ -208,7 +165,13 @@ function SearchFilters({
|
||||
<p className="2xl:text-[2.222vw] md:max-2xl:text-[32px] text-2xl font-semibold leading-[135%]">
|
||||
Search
|
||||
</p>
|
||||
<ProjectSelect projects={projects} onSelect={handleProjectSelect} />
|
||||
{project && (
|
||||
<ProjectSelect
|
||||
projects={projects}
|
||||
onSelect={handleProjectSelect}
|
||||
defaultProject={projects.find(({ title }) => title === project)!}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<hr className="2xl:h-[0.069vw] h-px border-[#E2E2DC]" />
|
||||
{filters && (
|
||||
@@ -255,6 +218,7 @@ function SearchFilters({
|
||||
label="View"
|
||||
options={["Any view", ...filters.views]}
|
||||
onSelect={handleViewSelect}
|
||||
defaultOption={view}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center 2xl:gap-[1.111vw] md:max-2xl:gap-4">
|
||||
|
||||
@@ -18,7 +18,6 @@ function UnitTypesSelect({
|
||||
|
||||
useEffect(() => {
|
||||
const unitTypesValue = searchParams.getAll("unitTypes");
|
||||
|
||||
if (unitTypesValue) setSelectedUnitTypes(unitTypesValue);
|
||||
}, [searchParams]);
|
||||
|
||||
|
||||
@@ -6,24 +6,26 @@ import { useClickAway } from "@uidotdev/usehooks";
|
||||
import clsx from "clsx";
|
||||
import ChevronDownIcon from "../icons/ChevronDownIcon";
|
||||
import CheckIcon from "../icons/CheckIcon";
|
||||
|
||||
function Select({
|
||||
options,
|
||||
onSelect,
|
||||
className = "",
|
||||
label = "",
|
||||
defaultOption = "",
|
||||
}: {
|
||||
options: string[];
|
||||
onSelect: (option: string) => void;
|
||||
defaultOption: string;
|
||||
className?: string;
|
||||
label?: string;
|
||||
}) {
|
||||
const [isShow, setIsShow] = useState(false);
|
||||
const [selectedOption, setSelectedOption] = useState(options[0]);
|
||||
const [selectedOption, setSelectedOption] = useState(defaultOption);
|
||||
|
||||
const ref = useClickAway<HTMLDivElement>(() => setIsShow(false));
|
||||
|
||||
useEffect(() => {
|
||||
onSelect(selectedOption);
|
||||
}, [selectedOption]);
|
||||
useEffect(() => onSelect(selectedOption), [selectedOption]);
|
||||
|
||||
return (
|
||||
<div ref={ref} className={clsx("relative", className)}>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const projects = [
|
||||
import Project from "../types/Project";
|
||||
|
||||
export const projects: Project[] = [
|
||||
{
|
||||
title: "Rove Home Marasi Drive",
|
||||
img: "/images/search/rove_home_marasi_drive.png",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "./index.css";
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router";
|
||||
@@ -60,6 +61,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={route} />
|
||||
<ModalContainer />
|
||||
<ReactQueryDevtools />
|
||||
</QueryClientProvider>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { useInfiniteQuery, useQuery } 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 SearchFilters, { Filters } from "../components/SearchFilters";
|
||||
import { useNavigate, useSearchParams } from "react-router";
|
||||
import Button from "../components/ui/Button";
|
||||
import FiltersIcon from "../components/icons/FiltersIcon";
|
||||
@@ -17,12 +17,37 @@ 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 cost = searchParams.getAll("cost");
|
||||
// const floor = searchParams.getAll("floor");
|
||||
// const area = searchParams.getAll("area");
|
||||
// const view = searchParams.get("view");
|
||||
|
||||
const [project, setProject] = useState<string>();
|
||||
const [unitTypes, setUnitTypes] = useState<string[]>([]);
|
||||
const [cost, setCost] = useState<string[]>([]);
|
||||
const [floor, setFloor] = useState<string[]>([]);
|
||||
const [area, setArea] = useState<string[]>([]);
|
||||
const [view, setView] = useState<string>();
|
||||
|
||||
const { data: filters } = useQuery({
|
||||
queryKey: ["filters", project],
|
||||
enabled: !!project,
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(`units/filters?${project ? `project=${project}` : ""}`)
|
||||
.json<Filters>(),
|
||||
});
|
||||
|
||||
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 { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
|
||||
useInfiniteQuery({
|
||||
@@ -95,7 +120,11 @@ function SearchPage() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SearchFilters ref={filtersRef} inModal={filtersInModal} />
|
||||
<SearchFilters
|
||||
ref={filtersRef}
|
||||
inModal={filtersInModal}
|
||||
filters={filters}
|
||||
/>
|
||||
<div className="2xl:p-[2.222vw] p-4">
|
||||
<AnimatePresence mode="wait">
|
||||
{project && unitTypes && cost && area && floor && (
|
||||
|
||||
Reference in New Issue
Block a user