This commit is contained in:
2025-05-23 19:40:05 +05:00
parent 2ae130375a
commit 0341d28d2f
4 changed files with 242 additions and 132 deletions
+2 -1
View File
@@ -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
View File
@@ -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}
+16 -51
View File
@@ -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
View File
@@ -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}