Удалены компоненты FlatCard и ProjectFilter; обновлены стили в Footer и SearchFilters, добавлены новые компоненты ProjectSelect и UnitTypesSelect для улучшения фильтрации проектов.

This commit is contained in:
2025-04-28 19:23:11 +05:00
parent a44f2fbb98
commit f82b114db1
9 changed files with 200 additions and 109 deletions
+36 -27
View File
@@ -7,96 +7,105 @@ import TwitterIcon from "./icons/TwitterIcon";
function Footer() {
return (
<footer className="lg:px-[2.222vw] lg:pb-[2.222vw] lg:pt-[2.778vw] md:max-lg:p-6 px-4 py-6 grid md:grid-cols-6 grid-cols-3 lg:grid-rows-2 lg:gap-x-[1.667vw] lg:gap-y-[1.111vw] max-lg:gap-y-6 lg:rounded-t-[1.667vw] rounded-t-3xl outline outline-[#E2E2DC] bg-white">
<footer className="2xl:px-[2.222vw] 2xl:pb-[2.222vw] 2xl:pt-[2.778vw] md:max-2xl:p-6 px-4 py-6 grid 2xl:grid-cols-6 md:max-2xl:grid-cols-4 grid-cols-2 2xl:grid-rows-2 2xl:gap-x-[1.667vw] 2xl:gap-y-[1.111vw] max-2xl:gap-y-6 2xl:rounded-t-[1.667vw] rounded-t-3xl outline outline-[#E2E2DC] bg-white">
<img
src="/images/logo.svg"
className="lg:w-[5.972vw] w-[86px] cursor-pointer"
className="2xl:w-[5.972vw] w-[86px] cursor-pointer"
onClick={() => {
window.location.href = "/";
}}
alt="IRTH"
/>
<p className="lg:max-w-[17.083vw] text-s text-[#0D1922]/40 lg:col-start-1 md:max-lg:col-start-4 max-lg:col-span-3 md:max-lg:row-start-2 max-md:row-start-3 max-lg:pt-4 max-lg:border-t border-[#E2E2DC]">
<p className="2xl:max-w-[17.083vw] text-s text-[#0D1922]/40 2xl:col-start-1 md:max-2xl:col-start-3 max-2xl:col-span-3 md:max-2xl:row-start-2 max-md:row-start-3 max-md:mt-12">
For more information, visit
<br />
our website: 
<Link className="text-[#00BED7] underline" to={"https://www.irth.ae"}>
<Link
className="text-[#00BED7] md:underline"
to={"https://www.irth.ae"}
>
www.irth.ae
</Link>
</p>
<div className="lg:space-y-[0.833vw] space-y-3 md:max-lg:col-start-4 max-lg:col-span-3 md:max-lg:row-start-3 max-md:row-start-4 max-lg:mb-9">
<div className="2xl:space-y-[0.833vw] space-y-3 md:max-2xl:col-start-3 max-2xl:col-span-3 md:max-2xl:row-start-3 max-md:row-start-4 max-md:mt-6">
<p className="text-s text-[#0D1922]/40">Follow us for more:</p>
<div className="flex lg:gap-[0.278vw] gap-1">
<div className="lg:p-[0.417vw] p-1.5 bg-[#E2E2DC] lg:rounded-[0.278vw] rounded">
<div className="lg:w-[1.389vw] lg:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<div className="flex 2xl:gap-[0.278vw] gap-1">
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<YoutubeIcon />
</div>
</div>
<div className="lg:p-[0.417vw] p-1.5 bg-[#E2E2DC] lg:rounded-[0.278vw] rounded">
<div className="lg:w-[1.389vw] lg:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<InstagramIcon />
</div>
</div>
<div className="lg:p-[0.417vw] p-1.5 bg-[#E2E2DC] lg:rounded-[0.278vw] rounded">
<div className="lg:w-[1.389vw] lg:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<FacebookIcon />
</div>
</div>
<div className="lg:p-[0.417vw] p-1.5 bg-[#E2E2DC] lg:rounded-[0.278vw] rounded">
<div className="lg:w-[1.389vw] lg:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<LinkedInIcon />
</div>
</div>
<div className="lg:p-[0.417vw] p-1.5 bg-[#E2E2DC] lg:rounded-[0.278vw] rounded">
<div className="lg:w-[1.389vw] lg:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
<TwitterIcon />
</div>
</div>
</div>
</div>
<div className="lg:border-l-[0.069vw] border-[#E2E2DC] lg:pl-[1.111vw] flex flex-col lg:col-start-4 lg:row-start-1 lg:row-span-2 md:max-lg:col-start-4 col-start-1 max-lg:pt-4 max-lg:border-t">
<Link to={"/"} className="text-m flex-1 content-center max-lg:py-2.5">
<div className="2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] pl-4 flex flex-col 2xl:col-start-4 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-3 col-start-1 max-md:mt-4">
<Link
to={"/"}
className="text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit"
>
Map
</Link>
<Link
to={"/unit-types"}
className="text-m flex-1 content-center max-lg:py-2.5"
className="text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit"
>
Unit Types
</Link>
<Link
to={"/about-irth"}
className="text-m flex-1 content-center max-lg:py-2.5"
className="text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit"
>
About IRTH
</Link>
</div>
<div className="lg:border-l-[0.069vw] border-[#E2E2DC] lg:pl-[1.111vw] flex flex-col lg:col-start-5 lg:row-start-1 lg:row-span-2 max-lg:col-span-2 max-lg:pt-4 max-lg:border-t">
<div className="2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] pl-4 flex flex-col 2xl:col-start-5 2xl:row-start-1 2xl:row-span-2 max-2xl:col-span-2 max-md:mt-4">
<Link
to={"/favorites"}
className="text-m flex-1 content-center max-lg:py-2.5"
to={"/favourites"}
className="text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit"
>
Favorites
</Link>
<Link
to={"/search"}
className="text-m flex-1 content-center max-lg:py-2.5"
className="text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit"
>
Search
</Link>
<Link to={"/"} className="text-m flex-1 content-center max-lg:py-2.5">
<Link
to={"/"}
className="text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit"
>
Brochures
</Link>
</div>
<div className="content-end lg:text-right lg:col-start-6 lg:row-start-1 lg:row-span-2 md:max-lg:col-start-1 md:max-lg:row-start-3 max-md:col-span-3 max-md:pt-3 max-md:border-t border-[#E2E2DC]">
<div className="content-end 2xl:text-right 2xl:col-start-6 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-1 md:max-2xl:row-start-3 max-md:col-span-3 max-md:pt-3 max-md:border-t border-[#E2E2DC]">
<Link
to={"/"}
className="lg:text-caption-m text-caption-s max-lg:text-[#73787C]"
className="2xl:text-caption-m text-caption-s max-2xl:text-[#73787C] text-[#0D1922]/70"
>
Privacy Policy
</Link>
-32
View File
@@ -1,32 +0,0 @@
import clsx from "clsx";
import { useSearchParams } from "react-router";
function ProjectFilter({ title, img }: { title: string; img: string }) {
const [searchParams, setSearchParams] = useSearchParams();
return (
<div
onClick={() => {
setSearchParams((prev) => {
prev.set("project", title);
return prev;
});
}}
className={clsx(
"2xl:rounded-[2.778vw] rounded-[40px] 2xl:p-[0.278vw] p-1 flex items-center 2xl:gap-[0.556vw] gap-2 text-s 2xl:outline-[0.069vw] outline transition-colors duration-300 cursor-pointer",
searchParams.get("project") === title
? "outline-[#00BED7]"
: "outline-[#E2E2DC]"
)}
>
<img
src={img}
alt=""
className="object-cover 2xl:w-[2.778vw] w-10 aspect-square rounded-full"
/>
<p className="2xl:mr-[1.111vw] mr-6">{title}</p>
</div>
);
}
export default ProjectFilter;
+4 -3
View File
@@ -22,11 +22,12 @@ function ProjectSelect({
<div className="flex 2xl:gap-[0.556vw] gap-2 max-md:hidden">
{projects.map((project) => (
<div
key={project.title}
className={clsx(
"2xl:rounded-[2.778vw] rounded-[40px] 2xl:p-[0.278vw] p-1 flex items-center 2xl:gap-[0.556vw] gap-2 text-s 2xl:outline-[0.069vw] outline transition-colors duration-300 cursor-pointer",
"2xl:rounded-[2.778vw] rounded-[40px] 2xl:p-[0.278vw] p-1 flex items-center 2xl:gap-[0.556vw] gap-2 text-s 2xl:ring-[0.069vw] ring transition-[box-shadow] cursor-pointer",
project.title === selectedProject.title
? "outline-[#00BED7]"
: "outline-[#E2E2DC]"
? "ring-[#00BED7]"
: "ring-[#E2E2DC]"
)}
onClick={() => setSelectedProject(project)}
>
+59 -24
View File
@@ -4,14 +4,17 @@ import Button from "./ui/Button";
import MultiRangeSlider from "./ui/MultiRangeSlider";
import { api } from "../api/ky";
import { RefObject, useEffect, useState } from "react";
import ProjectFilter from "./ProjectFilter";
import { useNavigate, useSearchParams } from "react-router";
import UnitTypesFilter from "./UnitTypesFilter";
import { projects } from "../data/projects";
import { useDebounce } from "../hooks/useDebounce";
import clsx from "clsx";
import ProjectSelect from "./ProjectSelect";
import Project from "../types/Project";
import UnitTypesSelect from "./UnitTypesSelect";
import Select from "./ui/Select";
import { AnimatePresence, motion } from "motion/react";
interface Filters {
export interface Filters {
unitTypes: string[];
views: string[];
area: [number, number];
@@ -26,8 +29,9 @@ function SearchFilters({
inModal?: boolean;
ref?: RefObject<HTMLDivElement | null>;
}) {
const [project, setProject] = useState<string>();
const [project, setProject] = useState<string>(projects[0].title);
const [unitTypes, setUnitTypes] = useState<string[]>([]);
const [view, setView] = useState<string>("Any view");
const [searchParams, setSearchParams] = useSearchParams();
@@ -43,9 +47,11 @@ function SearchFilters({
useEffect(() => {
const projectValue = searchParams.get("project");
const unitTypesValue = searchParams.getAll("unitTypes");
// const unitTypesValue = searchParams.getAll("unitTypes");
if (projectValue) setProject(projectValue);
if (unitTypesValue) setUnitTypes(unitTypesValue);
// if (unitTypesValue) setUnitTypes(unitTypesValue);
const viewValue = searchParams.get("view");
if (viewValue) setView(viewValue);
}, [searchParams]);
useEffect(() => {
@@ -69,7 +75,6 @@ function SearchFilters({
const [currentMaxFloor, setCurrentMaxFloor] = useState<number>();
function resetFilters() {
setProject(undefined);
setUnitTypes([]);
if (filters) {
setCurrentMinCost(filters.cost[0]);
@@ -97,6 +102,7 @@ function SearchFilters({
"count",
project,
unitTypes,
view,
debouncedMinCost,
debouncedMaxCost,
debouncedMinArea,
@@ -109,7 +115,7 @@ function SearchFilters({
.get(
`units/count?${project ? `project=${project}` : ""}${unitTypes
.map((unitType) => `&unitTypes=${unitType}`)
.join("")}${
.join("")}${view !== "Any view" ? `&view=${view}` : ""}${
debouncedMinCost && debouncedMaxCost
? `&cost=${Math.round(debouncedMinCost)},${Math.round(
debouncedMaxCost
@@ -169,11 +175,32 @@ function SearchFilters({
setSearchParams,
]);
function handleProjectSelect(project: Project) {
setProject(project.title);
setSearchParams((prev) => {
prev.set("project", project.title);
return prev;
});
}
function handleUnitTypesSelect(unitTypes: string[]) {
setUnitTypes(unitTypes);
}
function handleViewSelect(view: string) {
setView(view);
setSearchParams((prev) => {
if (view !== "Any view") prev.set("view", view);
else prev.delete("view");
return prev;
});
}
return (
<div
ref={ref}
className={clsx(
"2xl:p-[2.222vw] md:max-2xl:p-6 p-4 2xl:-mx-[2.222vw] md:max-2xl:-mx-6 -mx-4 bg-white 2xl:rounded-b-[1.667vw] rounded-b-3xl 2xl:space-y-[2.222vw] md:max-2xl:space-y-8 space-y-4",
"2xl:p-[2.222vw] md:max-2xl:p-6 p-4 bg-white 2xl:rounded-b-[1.667vw] rounded-b-3xl 2xl:space-y-[2.222vw] md:max-2xl:space-y-8 space-y-4",
inModal && "fixed top-[7.222vw] w-[calc(100vw-4.444vw)]"
)}
>
@@ -181,26 +208,17 @@ function SearchFilters({
<p className="2xl:text-[2.222vw] md:max-2xl:text-[32px] text-2xl font-semibold leading-[135%]">
Search
</p>
<div className="flex 2xl:gap-[0.556vw] gap-2">
{projects.map((project) => (
<ProjectFilter
key={project.title}
title={project.title}
img={project.img}
/>
))}
</div>
<ProjectSelect projects={projects} onSelect={handleProjectSelect} />
</div>
<hr className="2xl:h-[0.069vw] h-px border-[#E2E2DC]" />
{filters && (
<>
<div className="2xl:space-y-[0.556vw] space-y-2">
<p>Apartment type</p>
<div className="flex 2xl:gap-[0.556vw] gap-2">
{filters.unitTypes.map((unitType) => (
<UnitTypesFilter key={unitType} title={unitType} />
))}
</div>
<UnitTypesSelect
filters={filters}
onSelect={handleUnitTypesSelect}
/>
</div>
<div className="grid 2xl:grid-cols-4 md:max-2xl:grid-cols-2 md:max-2xl:grid-rows-2 2xl:gap-[1.111vw] gap-4">
<MultiRangeSlider
@@ -233,12 +251,29 @@ function SearchFilters({
onChangeMax={setCurrentMaxArea}
label="Total Area, Sqft"
/>
<Select
label="View"
options={["Any view", ...filters.views]}
onSelect={handleViewSelect}
/>
</div>
<div className="flex items-center 2xl:gap-[1.111vw] md:max-2xl:gap-4">
{inModal ? (
<Button>Show {count} apartments</Button>
) : (
<p className="text-[#00BED7] text-s">{count} Apartments found</p>
<AnimatePresence mode="wait">
{count && (
<motion.p
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
key={count}
className="text-[#00BED7] text-s"
>
{count} Apartments found
</motion.p>
)}
</AnimatePresence>
)}
<Button variant="secondary" onClick={resetFilters}>
<span className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70">
@@ -2,7 +2,7 @@ import { IUnit } from "../types/IUnit";
import HeartIcon from "./icons/HeartIcon";
import Button from "./ui/Button";
function FlatCard({
function UnitCard({
project,
unitNo,
floor,
@@ -45,4 +45,4 @@ function FlatCard({
);
}
export default FlatCard;
export default UnitCard;
+57
View File
@@ -0,0 +1,57 @@
import { useEffect, useState } from "react";
import { Filters } from "./SearchFilters";
import clsx from "clsx";
import { useSearchParams } from "react-router";
function UnitTypesSelect({
filters,
onSelect,
}: {
filters: Filters;
onSelect: (unitTypes: string[]) => void;
}) {
const [selectedUnitTypes, setSelectedUnitTypes] = useState<string[]>([]);
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => onSelect(selectedUnitTypes), [onSelect, selectedUnitTypes]);
useEffect(() => {
const unitTypesValue = searchParams.getAll("unitTypes");
if (unitTypesValue) setSelectedUnitTypes(unitTypesValue);
}, [searchParams]);
return (
<div className="flex 2xl:gap-[0.556vw] gap-2">
{filters.unitTypes.map((unitType) => (
<div
key={unitType}
onClick={() => {
setSelectedUnitTypes((prev) =>
prev.includes(unitType)
? 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",
selectedUnitTypes.includes(unitType)
? "ring-[#00BED7]"
: "ring-[#E2E2DC]"
)}
>
{unitType}
</div>
))}
</div>
);
}
export default UnitTypesSelect;
+6 -6
View File
@@ -83,17 +83,17 @@ function MultiRangeSlider({
return (
<div className="2xl:space-y-[0.556vw] space-y-2">
<p className="text-s">{label}</p>
<div className="bg-white/80 rounded-lg relative p-3 flex justify-between border !border-[#E2E2DC]">
<p className="text-s text-[#0D1922]/70">{label}</p>
<div className="bg-white/80 2xl:rounded-[0.833vw] rounded-xl relative 2xl:px-[1.111vw] 2xl:py-[0.972vw] px-4 py-3.5 flex justify-between 2xl:ring-[0.069vw] ring-1 ring-[#E2E2DC]">
<p className={clsx("text-s", disabled && "text-[#0D1922]/40")}>
{Intl.NumberFormat("en").format(Math.round(currentMin))}
</p>
<p className={clsx("text-s", disabled && "text-[#0D1922]/40")}>
{Intl.NumberFormat("en").format(Math.round(currentMax))}
</p>
<div className="absolute bottom-0 left-0 w-full px-4 translate-y-1/2">
<div className="absolute bottom-0 left-0 w-full 2xl:px-[1.111vw] px-4 translate-y-1/2">
<div
className="relative flex h-4"
className="relative flex 2xl:h-[1.111vw] h-4"
ref={rangeRef}
onMouseMove={
handleChange as React.MouseEventHandler<HTMLDivElement>
@@ -108,7 +108,7 @@ function MultiRangeSlider({
left: `${((currentMin - min) / (max - min)) * 100}%`,
}}
className={clsx(
"h-0.5 self-center relative",
"2xl:h-[0.139vw] h-0.5 self-center relative",
disabled ? "bg-[#D2D2D2]" : "bg-[#00BED7]"
)}
/>
@@ -119,7 +119,7 @@ function MultiRangeSlider({
onTouchStart={() => setCurrent(type as "min" | "max")}
style={getThumbStyle(type === "min" ? currentMin : currentMax)}
className={clsx(
"rounded-full w-4 h-4 absolute bottom-0 -translate-x-1/2",
"rounded-full 2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4 absolute bottom-0 -translate-x-1/2",
current === type ? "cursor-grabbing" : "cursor-grab",
disabled ? "bg-[#D2D2D2] !cursor-default" : "bg-[#00BED7]"
)}
+11 -4
View File
@@ -10,10 +10,12 @@ function Select({
options,
onSelect,
className = "",
label = "",
}: {
options: string[];
onSelect: (option: string) => void;
className?: string;
label?: string;
}) {
const [isShow, setIsShow] = useState(false);
const [selectedOption, setSelectedOption] = useState(options[0]);
@@ -25,9 +27,14 @@ function Select({
return (
<div ref={ref} className={clsx("relative", className)}>
{label && (
<p className="text-s text-[#0D1922]/70 2xl:mb-[0.556vw] mb-2">
{label}
</p>
)}
<button
className={clsx(
"px-4 py-[14px] rounded-xl ring-1 transition-[box-shadow] w-full text-left flex items-center justify-between group",
"2xl:px-[1.111vw] px-4 2xl:py-[0.833vw] py-3 2xl:rounded-[0.833vw] rounded-xl 2xl:ring-[0.069vw] ring-1 transition-[box-shadow] w-full text-left flex items-center justify-between group",
isShow ? " ring-[#00BED7]" : "ring-[#E2E2DC]"
)}
onClick={() => setIsShow(!isShow)}
@@ -35,7 +42,7 @@ function Select({
<p className="text-s">{selectedOption}</p>
<ChevronDownIcon
className={clsx(
"w-6 h-6 flex-shrink-0 group-hover:text-[#00BED7] transition-[color,rotate]",
"2xl:w-[1.667vw] 2xl:h-[1.667vw] w-6 h-6 flex-shrink-0 group-hover:text-[#00BED7] transition-[color,rotate]",
isShow && "rotate-180"
)}
/>
@@ -47,7 +54,7 @@ function Select({
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.15 }}
className="absolute mt-1 p-1 space-y-0.5 shadow-[0px_2px_8px_rgba(0,0,0,0.15)] rounded-xl bg-white w-full z-10"
className="absolute 2xl:mt-[0.278vw] 2xl:pt-[0.278vw] mt-1 p-1 2xl:space-y-[0.139vw] space-y-0.5 shadow-[0px_2px_8px_rgba(0,0,0,0.15)] rounded-xl bg-white w-full z-10"
>
{options.map((option, index) => (
<button
@@ -67,7 +74,7 @@ function Select({
{option}
</p>
{selectedOption === option && (
<CheckIcon className="w-6 h-6 flex-shrink-0 text-[#00BED7]" />
<CheckIcon className="2xl:w-[1.667vw] 2xl:h-[1.667vw] w-6 h-6 flex-shrink-0 text-[#00BED7]" />
)}
</button>
))}
+25 -11
View File
@@ -1,7 +1,7 @@
import { useInfiniteQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
import { IUnit } from "../types/IUnit";
import FlatCard from "../components/FlatCard";
import UnitCard from "../components/UnitCard";
import { useEffect, useRef, useState } from "react";
import SearchFilters from "../components/SearchFilters";
import { useNavigate, useSearchParams } from "react-router";
@@ -9,6 +9,7 @@ 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";
const STEP = 12;
@@ -21,21 +22,22 @@ function SearchPage() {
const cost = searchParams.getAll("cost");
const floor = searchParams.getAll("floor");
const area = searchParams.getAll("area");
const view = searchParams.get("view");
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useInfiniteQuery({
initialPageParam: 0,
queryKey: ["units", project, unitTypes, cost, floor, area],
queryKey: ["units", project, unitTypes, view, cost, floor, area],
queryFn: async ({ pageParam = 0 }) =>
await api
.get(
`units?offset=${pageParam}&limit=${STEP}${
project ? `&project=${project}` : ""
}${unitTypes.map((unitType) => `&unitTypes=${unitType}`).join("")}${
cost.length > 0 ? `&cost=${cost.join(",")}` : ""
}${floor.length > 0 ? `&floor=${floor.join(",")}` : ""}${
area.length > 0 ? `&area=${area.join(",")}` : ""
}`
view ? `&view=${view}` : ""
}${cost.length > 0 ? `&cost=${cost.join(",")}` : ""}${
floor.length > 0 ? `&floor=${floor.join(",")}` : ""
}${area.length > 0 ? `&area=${area.join(",")}` : ""}`
)
.json<IUnit[]>(),
getNextPageParam: (lastPage, _, lastPageIndex) =>
@@ -92,12 +94,24 @@ function SearchPage() {
}, []);
return (
<div className="">
<div>
<SearchFilters ref={filtersRef} inModal={filtersInModal} />
<div className="2xl:grid-cols-4 md:max-2xl:grid-cols-2 grid 2xl:gap-[1.111vw] gap-4 2xl:pt-[1.111vw] pt-4">
{data?.pages.flat().map((unit) => (
<FlatCard key={unit.id} {...unit} />
))}
<div className="2xl:p-[2.222vw] p-4">
<AnimatePresence mode="wait">
{project && unitTypes && cost && area && floor && (
<motion.div
key={project + unitTypes + view + cost + area + floor}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="2xl:grid-cols-4 md:max-2xl:grid-cols-2 grid 2xl:gap-[1.111vw] gap-4"
>
{data?.pages.map((page) =>
page.map((unit) => <UnitCard key={unit.id} {...unit} />)
)}
</motion.div>
)}
</AnimatePresence>
</div>
{showButtons && (
<div