upd
This commit is contained in:
@@ -1 +1,2 @@
|
||||
VITE_API_URL=http://194.26.138.94:4002
|
||||
VITE_API_URL=http://localhost:4002
|
||||
# VITE_API_URL=http://194.26.138.94:4002
|
||||
+114
-29
@@ -145,25 +145,59 @@ function Header() {
|
||||
<div className="flex-1 space-y-4">
|
||||
<p className="text-s font-medium">Rove Home Marasi Drive</p>
|
||||
<div className="flex gap-2 flex-col">
|
||||
{[
|
||||
"Rove Main Brochure",
|
||||
"Rove Amenties Brochure",
|
||||
"Rove Technical Brochure",
|
||||
].map((title) => (
|
||||
<BrochureButton title={title} key={title} />
|
||||
))}
|
||||
<BrochureButton
|
||||
title={"Main Brochure"}
|
||||
link="/files/marasi-drive/Main Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Amenties Brochure"}
|
||||
link="/files/marasi-drive/Amenties Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Technical Brochure"}
|
||||
link="/files/marasi-drive/Technical Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Factsheet"}
|
||||
link="/files/marasi-drive/Factsheet.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Reasons to buy"}
|
||||
link="/files/marasi-drive/Reasons to Buy.pdf"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 space-y-4">
|
||||
<p className="text-s font-medium">Rove Home Downtown</p>
|
||||
<div className="flex gap-2 flex-col">
|
||||
{[
|
||||
"Rove Main Brochure",
|
||||
"Rove Amenties Brochure",
|
||||
"Rove Technical Brochure",
|
||||
].map((title) => (
|
||||
<BrochureButton title={title} key={title} />
|
||||
))}
|
||||
<BrochureButton
|
||||
title={"Main Brochure"}
|
||||
link="/files/downtown/Main Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Amenties Brochure"}
|
||||
link="/files/downtown/Amenties Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Unit Plans"}
|
||||
link="/files/downtown/Unit Plan.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Typical Floor plan 2-13"}
|
||||
link="/files/downtown/Typical Floor plan 2-13.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Typical Floor plan 14-19"}
|
||||
link="/files/downtown/Typical Floor plan 14-19.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Factsheet"}
|
||||
link="/files/downtown/Factsheet.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Reasons to buy"}
|
||||
link="/files/downtown/Reasons to Buy.pdf"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -268,25 +302,59 @@ function BrochuresDropdown() {
|
||||
<div className="flex-1 space-y-4">
|
||||
<p className="text-s font-medium">Rove Home Marasi Drive</p>
|
||||
<div className="flex flex-col gap-[0.556vw]">
|
||||
{[
|
||||
"Rove Main Brochure",
|
||||
"Rove Amenties Brochure",
|
||||
"Rove Technical Brochure",
|
||||
].map((title) => (
|
||||
<BrochureButton title={title} key={title} />
|
||||
))}
|
||||
<BrochureButton
|
||||
title={"Main Brochure"}
|
||||
link="/files/marasi-drive/Main Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Amenties Brochure"}
|
||||
link="/files/marasi-drive/Amenties Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Technical Brochure"}
|
||||
link="/files/marasi-drive/Technical Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Factsheet"}
|
||||
link="/files/marasi-drive/Factsheet.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Reasons to buy"}
|
||||
link="/files/marasi-drive/Reasons to Buy.pdf"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 space-y-4">
|
||||
<p className="text-s font-medium">Rove Home Downtown</p>
|
||||
<div className="flex flex-col gap-[0.556vw]">
|
||||
{[
|
||||
"Rove Main Brochure",
|
||||
"Rove Amenties Brochure",
|
||||
"Rove Technical Brochure",
|
||||
].map((title) => (
|
||||
<BrochureButton title={title} key={title} />
|
||||
))}
|
||||
<BrochureButton
|
||||
title={"Main Brochure"}
|
||||
link="/files/downtown/Main Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Amenties Brochure"}
|
||||
link="/files/downtown/Amenties Brochure.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Unit Plans"}
|
||||
link="/files/downtown/Unit Plan.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Typical Floor plan 2-13"}
|
||||
link="/files/downtown/Typical Floor plan 2-13.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Typical Floor plan 14-19"}
|
||||
link="/files/downtown/Typical Floor plan 14-19.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Factsheet"}
|
||||
link="/files/downtown/Factsheet.pdf"
|
||||
/>
|
||||
<BrochureButton
|
||||
title={"Reasons to buy"}
|
||||
link="/files/downtown/Reasons to Buy.pdf"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
@@ -296,12 +364,29 @@ function BrochuresDropdown() {
|
||||
);
|
||||
}
|
||||
|
||||
export function BrochureButton({ title }: { title: string }) {
|
||||
export function BrochureButton({
|
||||
title,
|
||||
link,
|
||||
}: {
|
||||
title: string;
|
||||
link: string;
|
||||
}) {
|
||||
const handleDownload = () => {
|
||||
const anchor = document.createElement("a");
|
||||
anchor.href = link;
|
||||
anchor.download = title; // Use the title as the filename
|
||||
anchor.style.display = "none";
|
||||
document.body.appendChild(anchor);
|
||||
anchor.click();
|
||||
document.body.removeChild(anchor);
|
||||
};
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="large"
|
||||
className="w-full !bg-[#F3F3F2] !justify-between group hover:!bg-[#F3F3F2]"
|
||||
onClick={handleDownload}
|
||||
>
|
||||
<span className="text-nowrap text-caption-m group-hover:text-[#0D1922] transition-colors duration-300">
|
||||
{title}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import RestartIcon from "./icons/RestartIcon";
|
||||
import Button from "./ui/Button";
|
||||
import { api } from "../api/ky";
|
||||
import { RefObject, useEffect, useState } from "react";
|
||||
import { RefObject, useEffect } from "react";
|
||||
import { projects } from "../data/projects";
|
||||
import clsx from "clsx";
|
||||
import ProjectSelect from "./ProjectSelect";
|
||||
@@ -29,6 +29,13 @@ function SearchFilters({
|
||||
view,
|
||||
setView,
|
||||
ref,
|
||||
project,
|
||||
setProject,
|
||||
allUnitTypes,
|
||||
allCost,
|
||||
allFloors,
|
||||
allArea,
|
||||
allViews,
|
||||
}: {
|
||||
inModal?: boolean;
|
||||
setInModal: (inModal: boolean) => void;
|
||||
@@ -43,59 +50,17 @@ function SearchFilters({
|
||||
setSelectedUnitTypes: (selectedUnitTypes: string[]) => void;
|
||||
view: string;
|
||||
setView: (view: string) => void;
|
||||
project: string;
|
||||
setProject: (project: string) => void;
|
||||
allUnitTypes: string[];
|
||||
allCost: { min: number; max: number };
|
||||
allFloors: { min: number; max: number };
|
||||
allArea: { min: number; max: number };
|
||||
allViews: string[];
|
||||
}) {
|
||||
const [project, setProject] = useState<string>("Rove Home Marasi Drive");
|
||||
// const [project, setProject] = useState<string>("Rove Home Marasi Drive");
|
||||
|
||||
const { data: allUnitTypes } = useQuery({
|
||||
queryKey: ["filters", "unitTypes", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/unitTypes?project=${project}`).json<string[]>(),
|
||||
});
|
||||
|
||||
const { data: allViews } = useQuery({
|
||||
queryKey: ["filters", "views", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/views?project=${project}`).json<string[]>(),
|
||||
});
|
||||
|
||||
const { data: allFloors } = useQuery({
|
||||
queryKey: ["filters", "floors", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/floor?project=${project}`).json<{
|
||||
min: number;
|
||||
max: number;
|
||||
}>(),
|
||||
});
|
||||
|
||||
const { data: allCost } = useQuery({
|
||||
queryKey: ["filters", "cost", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/cost?project=${project}`).json<{
|
||||
min: number;
|
||||
max: number;
|
||||
}>(),
|
||||
});
|
||||
|
||||
const { data: allArea } = useQuery({
|
||||
queryKey: ["filters", "area", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/area?project=${project}`).json<{
|
||||
min: number;
|
||||
max: number;
|
||||
}>(),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (allFloors) setFloor([allFloors.min, allFloors.max]);
|
||||
}, [allFloors]);
|
||||
|
||||
useEffect(() => {
|
||||
if (allCost) setCost([allCost.min, allCost.max]);
|
||||
}, [allCost]);
|
||||
|
||||
useEffect(() => {
|
||||
if (allArea) setArea([allArea.min, allArea.max]);
|
||||
}, [allArea]);
|
||||
|
||||
// useQuery({
|
||||
// queryKey: ["filters", "unitTypes", project],
|
||||
|
||||
+110
-51
@@ -1,4 +1,5 @@
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
|
||||
import { api } from "../api/ky";
|
||||
import { IUnit } from "../types/IUnit";
|
||||
import UnitCard from "../components/UnitCard";
|
||||
@@ -18,9 +19,9 @@ const STEP = 12;
|
||||
|
||||
function SearchPage() {
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
// const project = searchParams.get("project");
|
||||
const [project] = useState("Rove Home Marasi Drive");
|
||||
const [project, setProject] = useState(
|
||||
searchParams.get("project") || "Rove Home Marasi Drive"
|
||||
);
|
||||
const [selectedUnitTypes, setSelectedUnitTypes] = useState<string[]>([]);
|
||||
// const unitTypes = searchParams.getAll("unitTypes");
|
||||
// const view = searchParams.get("view");
|
||||
@@ -36,6 +37,104 @@ function SearchPage() {
|
||||
"Sort by ascending price"
|
||||
);
|
||||
|
||||
const filtersRef = useRef<HTMLDivElement>(null);
|
||||
const observerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => window.scrollTo({ top: 0, behavior: "smooth" }), []);
|
||||
|
||||
const [showButtons, setShowButtons] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const observerElement = filtersRef.current;
|
||||
const observer = new IntersectionObserver((entries) =>
|
||||
setShowButtons(!entries[0].isIntersecting)
|
||||
);
|
||||
if (observerElement) observer.observe(observerElement);
|
||||
|
||||
return () => {
|
||||
if (observerElement) observer.unobserve(observerElement);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const [footerReached, setFooterReached] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const footer = document.querySelector("footer");
|
||||
const observer = new IntersectionObserver((entries) =>
|
||||
setFooterReached(entries[0].isIntersecting)
|
||||
);
|
||||
if (footer) observer.observe(footer);
|
||||
|
||||
return () => {
|
||||
if (footer) observer.unobserve(footer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const [activeFiltersCount, setActiveFiltersCount] = useState(0);
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
setActiveFiltersCount(
|
||||
+searchParams.has("view") +
|
||||
+searchParams.has("unitTypes") +
|
||||
+searchParams.has("cost") +
|
||||
+searchParams.has("floor") +
|
||||
+searchParams.has("area")
|
||||
),
|
||||
[searchParams]
|
||||
);
|
||||
|
||||
const { data: allUnitTypes } = useQuery({
|
||||
queryKey: ["filters", "unitTypes", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/unitTypes?project=${project}`).json<string[]>(),
|
||||
});
|
||||
|
||||
const { data: allViews } = useQuery({
|
||||
queryKey: ["filters", "views", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/views?project=${project}`).json<string[]>(),
|
||||
});
|
||||
|
||||
const { data: allFloors } = useQuery({
|
||||
queryKey: ["filters", "floors", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/floor?project=${project}`).json<{
|
||||
min: number;
|
||||
max: number;
|
||||
}>(),
|
||||
});
|
||||
|
||||
const { data: allCost } = useQuery({
|
||||
queryKey: ["filters", "cost", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/cost?project=${project}`).json<{
|
||||
min: number;
|
||||
max: number;
|
||||
}>(),
|
||||
});
|
||||
|
||||
const { data: allArea } = useQuery({
|
||||
queryKey: ["filters", "area", project],
|
||||
queryFn: () =>
|
||||
api.get(`units/filters/area?project=${project}`).json<{
|
||||
min: number;
|
||||
max: number;
|
||||
}>(),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (allFloors) setFloor([allFloors.min, allFloors.max]);
|
||||
}, [allFloors]);
|
||||
|
||||
useEffect(() => {
|
||||
if (allCost) setCost([allCost.min, allCost.max]);
|
||||
}, [allCost]);
|
||||
|
||||
useEffect(() => {
|
||||
if (allArea) setArea([allArea.min, allArea.max]);
|
||||
}, [allArea]);
|
||||
|
||||
const { data, fetchNextPage, isLoading, hasNextPage, isFetchingNextPage } =
|
||||
useInfiniteQuery({
|
||||
initialPageParam: 0,
|
||||
@@ -83,11 +182,6 @@ function SearchPage() {
|
||||
lastPage.length < STEP ? undefined : lastPageIndex + STEP,
|
||||
});
|
||||
|
||||
const filtersRef = useRef<HTMLDivElement>(null);
|
||||
const observerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => window.scrollTo({ top: 0, behavior: "smooth" }), []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasNextPage || isFetchingNextPage) return;
|
||||
const observerElement = observerRef.current;
|
||||
@@ -104,51 +198,16 @@ function SearchPage() {
|
||||
};
|
||||
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
|
||||
|
||||
const [showButtons, setShowButtons] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const observerElement = filtersRef.current;
|
||||
const observer = new IntersectionObserver((entries) =>
|
||||
setShowButtons(!entries[0].isIntersecting)
|
||||
);
|
||||
if (observerElement) observer.observe(observerElement);
|
||||
|
||||
return () => {
|
||||
if (observerElement) observer.unobserve(observerElement);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const [footerReached, setFooterReached] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const footer = document.querySelector("footer");
|
||||
const observer = new IntersectionObserver((entries) =>
|
||||
setFooterReached(entries[0].isIntersecting)
|
||||
);
|
||||
if (footer) observer.observe(footer);
|
||||
|
||||
return () => {
|
||||
if (footer) observer.unobserve(footer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const [activeFiltersCount, setActiveFiltersCount] = useState(0);
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
setActiveFiltersCount(
|
||||
+searchParams.has("view") +
|
||||
+searchParams.has("unitTypes") +
|
||||
+searchParams.has("cost") +
|
||||
+searchParams.has("floor") +
|
||||
+searchParams.has("area")
|
||||
),
|
||||
[searchParams]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchFilters
|
||||
allUnitTypes={allUnitTypes || []}
|
||||
allCost={allCost || { min: 0, max: 0 }}
|
||||
allFloors={allFloors || { min: 0, max: 0 }}
|
||||
allArea={allArea || { min: 0, max: 0 }}
|
||||
allViews={allViews || []}
|
||||
project={project}
|
||||
setProject={setProject}
|
||||
selectedUnitTypes={selectedUnitTypes}
|
||||
setSelectedUnitTypes={setSelectedUnitTypes}
|
||||
view={view}
|
||||
|
||||
Reference in New Issue
Block a user