This commit is contained in:
2024-09-09 18:36:36 +05:00
parent 9049662792
commit 708ed301a9
20 changed files with 5065 additions and 369 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ const ButtomPanel = () => {
setModal(<DisclaimerModal />);
};
return (
<div className="absolute z-20 bottom-0 left-0 w-full select-none touch-none pointer-events-none flex gap-2 justify-between items-end">
<div className="absolute bottom-0 left-0 z-20 flex items-end justify-between w-full gap-2 pointer-events-none select-none touch-none">
<div className="flex flex-col gap-2">
<div className="flex gap-2 pb-6 pl-6">
<Button
@@ -23,7 +23,7 @@ const ButtomPanel = () => {
{/* <Button text="Privacy Policy" buttonType="special" isCircleRounded /> */}
</div>
</div>
<div className="p-6">
<div className="p-6 max-sm:hidden">
<div className="bg-[#0D192266] rounded-full backdrop-blur-sm">
<img src="../images/masterplan/compass.png" alt="compass" />
</div>
+2 -2
View File
@@ -13,7 +13,7 @@ const ButtomPanelCompass = () => {
};
return (
<div className="absolute z-20 bottom-0 left-0 w-full select-none touch-none pointer-events-none flex gap-2 justify-between items-end">
<div className="absolute bottom-0 left-0 z-20 flex items-end justify-between w-full gap-2 pointer-events-none select-none touch-none">
<div className="flex flex-col gap-2">
<div className="flex gap-2 pb-6 pl-6">
<Button
@@ -26,7 +26,7 @@ const ButtomPanelCompass = () => {
{/* <Button text="Privacy Policy" buttonType="special" /> */}
</div>
</div>
<div className="p-6">
<div className="p-6 max-sm:hidden">
<div className="bg-[#0D192266] rounded-full backdrop-blur-sm">
<img
style={{ transform: `rotate(${currentCompassRotate - 180}deg)` }}
+6 -6
View File
@@ -8,13 +8,13 @@ import SocialButton from "./SocialButton";
function Footer2() {
return (
<div className="relative bg-white lg:p-10 px-4 py-8 rounded-t-2xl">
<div className="absolute top-0 left-0 lg:p-10 px-4 py-8">
<div className="relative px-4 py-8 bg-white lg:p-10 rounded-t-2xl">
<div className="absolute top-0 left-0 px-4 py-8 lg:p-10">
<Logo2Icon />
</div>
<div className="grid lg:grid-cols-2 gap-4 lg:w-full sm:w-1/2 w-full ml-auto max-sm:py-12">
<div className="flex flex-col justify-between self-end max-lg:order-last">
<div className="flex max-lg:flex-col lg:gap-10 gap-6">
<div className="grid w-full gap-4 ml-auto lg:grid-cols-2 lg:w-full sm:w-1/2 max-sm:py-12">
<div className="flex flex-col self-end justify-between max-lg:order-last">
<div className="flex gap-6 max-lg:flex-col lg:gap-10">
<p className="text-[#0D192266] text-sm">
For more information, visit our
<br />
@@ -66,7 +66,7 @@ function Footer2() {
</div>
</div>
</div>
<div className="absolute bottom-0 lg:right-0 max-lg:left-0 flex flex-col items-end justify-end lg:p-10 px-4 py-8">
<div className="absolute bottom-0 flex flex-col items-end justify-end px-4 py-8 lg:right-0 max-lg:left-0 lg:p-10">
<a href="#" className="text-xs font-semibold">
Privacy Policy
</a>
+3 -3
View File
@@ -25,7 +25,7 @@ function Header() {
}
return (
<div className="fixed top-0 left-0 w-full flex justify-between bg-white z-50">
<div className="fixed top-0 left-0 flex justify-between w-full bg-white z-[60]">
<div className="flex">
<div className="px-6 py-4 border-r border-[#E2E2DC]">
<Logo2Icon />
@@ -48,7 +48,7 @@ function Header() {
About IRTH
</NavLink>
<div className="w-px h-3 bg-[#E2E2DC]"></div>
<NavLink to="/favorites" className="p-4 relative">
<NavLink to="/favorites" className="relative p-4">
Favorites{" "}
{favoriteUnits.length > 0 && (
<div className="absolute right-0 top-2 w-4 h-4 bg-[#00BED7] rounded-full flex items-center justify-center">
@@ -66,7 +66,7 @@ function Header() {
</NavLink>
</div>
<div className="w-[230px]"></div>
<div className="xl:hidden px-4 py-2">
<div className="px-4 py-2 xl:hidden">
<Button2
variant="secondary"
size="small"
File diff suppressed because one or more lines are too long
@@ -1,15 +1,16 @@
import React, { useState } from "react";
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState } from "react";
import IUnit from "../../../types/IUnit";
import Button3 from "../../Button3";
import CloseIcon from "../../icons/CloseIcon";
import EastWingFloorLayout from "./EastWingFloorLayout";
import UnitPopup from "./UnitPopup";
import WestWingBottomFloorLayout from "./WestWingBottomFloorLayout";
import WestWingFloorLayout from "./WestWingFloorLayout";
import api from "../../../utils/api";
import useModal from "../../../store/useModal";
import UnitModal from "../../modals/UnitModal";
import { isMobile } from "react-device-detect";
import WestWingFloorPlanLower from "./WestWingFloorPlanLower";
import WestWingFloorPlanUpper from "./WestWingFloorPlanUpper";
import EastWingFloorPlan from "./EastWingFloorPlan";
interface Props {
floor: number;
@@ -71,8 +72,14 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
}
}
useEffect(() => {
if (!isMobile || !hoveredUnit || !type) return;
setModal(<UnitModal unit={hoveredUnit} type={type} />);
}, [hoveredUnit]);
return (
<div className="flex flex-col flex-1 gap-4 p-6 select-none mt-14">
<div className="flex flex-col flex-1 gap-4 p-4 select-none sm:p-6 mt-14">
<div className="flex items-start justify-between">
<div>
<p
@@ -90,8 +97,8 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
onClick={onClose}
/>
</div>
<div className="flex flex-col flex-1 space-y-2">
<div className="flex items-center justify-end p-4 bg-white xl:justify-between rounded-2xl">
<div className="flex flex-col flex-1 space-y-2 max-sm:w-screen max-sm:-m-4">
<div className="flex items-center justify-end p-4 bg-white xl:justify-between rounded-2xl max-xl:hidden">
<div className="flex gap-6 max-xl:hidden">
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#A19E9E] text-xs flex items-center justify-center"></div>
@@ -110,28 +117,28 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
<p className="text-xs font-semibold">2 Bedroom²</p>
</div>
</div>
<div className="text-xs text-white rounded-full bg-[#00BED7] px-2 py-[3px]">
{/* <div className="text-xs text-white rounded-full bg-[#00BED7] px-2 py-[3px] ">
0 units
</div>
</div> */}
</div>
<div className="relative flex flex-1 bg-white rounded-2xl">
<svg className="flex-1 p-10" onMouseMove={handleMouseMove}>
<div className="relative flex flex-1 sm:bg-white rounded-2xl">
<svg className="flex-1 p-2 sm:p-10" onMouseMove={handleMouseMove}>
{wing === "West" ? (
floor <= 21 ? (
<WestWingBottomFloorLayout
<WestWingFloorPlanLower
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
) : (
<WestWingFloorLayout
<WestWingFloorPlanUpper
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
)
) : (
<EastWingFloorLayout
<EastWingFloorPlan
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
@@ -21,7 +21,6 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 619.96 570.45"
className="w-full h-full"
>
<g>
<g>
@@ -1268,7 +1267,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fillRule: "evenodd",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1281,7 +1280,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1294,7 +1293,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1307,7 +1306,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1320,7 +1319,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1333,7 +1332,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1347,7 +1346,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fillRule: "evenodd",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1361,7 +1360,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fillRule: "evenodd",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1374,7 +1373,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1387,7 +1386,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1400,7 +1399,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1413,7 +1412,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1426,7 +1425,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1439,7 +1438,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
@@ -1452,7 +1451,7 @@ function WestWingFloorLayout({ onMouseEnter, onMouseLeave, onClick }: Props) {
fill: "rgba(255, 255, 255, 0)",
strokeWidth: 0,
}}
className="cursor-pointer transition-colors"
className="transition-colors cursor-pointer"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+14 -27
View File
@@ -1,44 +1,31 @@
const FiltersIcon = () => {
interface Props {
className?: string;
}
function FiltersIcon({ className = "" }: Props) {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M2.5 15.4167H17.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
<circle cx="12.0833" cy="15.4167" r="2.08333" fill="currentColor" />
<path
d="M2.5 4.58334H17.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
<ellipse
cx="14.5833"
cy="4.58333"
rx="2.08333"
ry="2.08333"
d="M3.69231 11.3333C3.30996 11.3333 3 11.6318 3 12C3 12.3682 3.30996 12.6667 3.69231 12.6667H4.72103C5.01509 13.5682 5.88978 14.2222 6.92308 14.2222C7.95638 14.2222 8.83106 13.5682 9.12512 12.6667H20.3077C20.69 12.6667 21 12.3682 21 12C21 11.6318 20.69 11.3333 20.3077 11.3333H9.12512C8.83106 10.4318 7.95638 9.77778 6.92308 9.77778C5.88978 9.77778 5.01509 10.4318 4.72103 11.3333H3.69231Z"
fill="currentColor"
/>
<path
d="M2.5 10H17.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
d="M3.69231 17.1111C3.30996 17.1111 3 17.4096 3 17.7778C3 18.146 3.30996 18.4444 3.69231 18.4444H12.1056C12.3997 19.346 13.2744 20 14.3077 20C15.341 20 16.2157 19.346 16.5097 18.4444H20.3077C20.69 18.4444 21 18.146 21 17.7778C21 17.4096 20.69 17.1111 20.3077 17.1111H16.5097C16.2157 16.2095 15.341 15.5556 14.3077 15.5556C13.2744 15.5556 12.3997 16.2095 12.1056 17.1111H3.69231Z"
fill="currentColor"
/>
<path
d="M7.49992 9.99999C7.49992 11.1506 6.56718 12.0833 5.41659 12.0833C4.26599 12.0833 3.33325 11.1506 3.33325 9.99999C3.33325 8.8494 4.26599 7.91666 5.41659 7.91666C6.56718 7.91666 7.49992 8.8494 7.49992 9.99999Z"
d="M3.69231 5.55556C3.30996 5.55556 3 5.85403 3 6.22222C3 6.59041 3.30996 6.88889 3.69231 6.88889H14.8749C15.1689 7.79047 16.0436 8.44444 17.0769 8.44444C18.1102 8.44444 18.9849 7.79047 19.279 6.88889H20.3077C20.69 6.88889 21 6.59041 21 6.22222C21 5.85403 20.69 5.55556 20.3077 5.55556H19.279C18.9849 4.65398 18.1102 4 17.0769 4C16.0436 4 15.1689 4.65398 14.8749 5.55556H3.69231Z"
fill="currentColor"
/>
</svg>
);
};
}
export default FiltersIcon;
@@ -34,7 +34,7 @@ const Map = () => {
}}
>
<WeatherWidget />
<ZoomControlls />
{!isMobile && <ZoomControlls />}
<TransformComponent
wrapperStyle={{
width: "calc(100vw + 400px)",
@@ -4,6 +4,7 @@ import { useTransformEffect } from "react-zoom-pan-pinch";
import { markers } from "../../../consts/markers";
import useMarker from "../../../store/useMarker";
import { useNavigate } from "react-router-dom";
import { isMobile } from "react-device-detect";
const Marker = (props: MarkerComponentProps) => {
const { setHoveredMarker, hoveredMarker } = useMarker();
@@ -24,7 +25,9 @@ const Marker = (props: MarkerComponentProps) => {
const handleOnClick = () => {
if (!currentMarker || currentMarker?.isDisabled) return;
navigate(`../masterplan/${currentMarker?.itemNumber}`);
navigate(
`../masterplan/${currentMarker?.itemNumber}${isMobile ? "/wing" : ""}`
);
setHoveredMarker(null);
};
@@ -25,7 +25,7 @@ const WeatherWidget = () => {
}, []);
return (
<div className="absolute top-[73.5px] left-4 bg-black rounded-2xl z-50 text-white bg-opacity-40 w-[144px] pt-4">
<div className="absolute top-[73.5px] left-4 bg-black rounded-2xl z-50 text-white bg-opacity-40 w-[144px] pt-4 max-sm:hidden">
<div className="flex justify-between px-4 text-[14px] font-medium">
<p>{day}</p>
<p>{formattedTime}</p>
@@ -36,7 +36,7 @@ const WeatherWidget = () => {
</p>
<p>{dayPart}</p>
</div>
<div className="px-4 items-center flex pb-2 pt-2">
<div className="flex items-center px-4 pt-2 pb-2">
<p className="text-[32px] font-medium">{temperature}°C</p>
</div>
</div>
@@ -14,7 +14,7 @@ const ZoomControlls = () => {
};
return (
<div className="absolute top-1/2 right-4 z-50 flex flex-col gap-2">
<div className="absolute z-50 flex flex-col gap-2 top-1/2 right-4 -translate-y-[50%]">
<Button
buttonType="primary"
icon={<ZoomIcon />}
+21 -9
View File
@@ -1,8 +1,11 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect } from "react";
import DownloadIcon from "../icons/DownloadIcon";
import useFavoritesStore from "../../store/useFavoritesStore";
function NavbarModal() {
const { favoriteUnits } = useFavoritesStore();
useEffect(() => {
document.body.style.overflow = "hidden";
@@ -34,9 +37,18 @@ function NavbarModal() {
<div className="flex flex-col gap-2">
<a
href="/favorites"
className="p-4 bg-white rounded-lg text-[#0D1922]"
className="p-4 bg-white rounded-lg text-[#0D1922] "
>
Favorites
<div className="relative w-fit">
Favorites
{favoriteUnits.length > 0 && (
<div className="absolute -right-[18px] -top-1 w-4 h-4 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-white text-[10px] font-mono font-semibold -ml-[0.5px]">
{favoriteUnits.length}
</p>
</div>
)}
</div>
</a>
<a href="/search" className="p-4 bg-white rounded-lg text-[#0D1922]">
Search
@@ -45,13 +57,13 @@ function NavbarModal() {
</div>
<div className="space-y-4">
<p className="font-semibold text-[#0D1922]">Brochures</p>
<div className="grid sm:grid-cols-2 gap-4">
<div className="grid gap-4 sm:grid-cols-2">
<div className="space-y-3">
<p className="text-sm text-[#0D1922]">Rove Home Marasi Drive</p>
<div className="flex flex-col gap-2">
<a
href="#"
className="flex items-center justify-between text-xs font-semibold rounded-lg bg-white px-3 py-2"
className="flex items-center justify-between px-3 py-2 text-xs font-semibold bg-white rounded-lg"
download
>
<p>Rove Main Brochure</p>
@@ -59,7 +71,7 @@ function NavbarModal() {
</a>
<a
href="#"
className="flex items-center justify-between text-xs font-semibold rounded-lg bg-white px-3 py-2"
className="flex items-center justify-between px-3 py-2 text-xs font-semibold bg-white rounded-lg"
download
>
<p>Rove Amenties Brochure</p>
@@ -67,7 +79,7 @@ function NavbarModal() {
</a>
<a
href="#"
className="flex items-center justify-between text-xs font-semibold rounded-lg bg-white px-3 py-2"
className="flex items-center justify-between px-3 py-2 text-xs font-semibold bg-white rounded-lg"
download
>
<p>Rove Technical Brochure</p>
@@ -80,7 +92,7 @@ function NavbarModal() {
<div className="flex flex-col gap-2">
<a
href="#"
className="flex items-center justify-between text-xs font-semibold rounded-lg bg-white px-3 py-2"
className="flex items-center justify-between px-3 py-2 text-xs font-semibold bg-white rounded-lg"
download
>
<p>Rove Main Brochure</p>
@@ -88,7 +100,7 @@ function NavbarModal() {
</a>
<a
href="#"
className="flex items-center justify-between text-xs font-semibold rounded-lg bg-white px-3 py-2"
className="flex items-center justify-between px-3 py-2 text-xs font-semibold bg-white rounded-lg"
download
>
<p>Rove Amenties Brochure</p>
@@ -96,7 +108,7 @@ function NavbarModal() {
</a>
<a
href="#"
className="flex items-center justify-between text-xs font-semibold rounded-lg bg-white px-3 py-2"
className="flex items-center justify-between px-3 py-2 text-xs font-semibold bg-white rounded-lg"
download
>
<p>Rove Technical Brochure</p>
+114 -92
View File
@@ -208,9 +208,9 @@ function UnitModal({ unit, type }: Props) {
className={`fixed top-0 left-0 w-full overflow-y-scroll h-screen pt-[56px] z-40 backdrop-blur select-none`}
>
<div className="flex justify-end min-h-full">
<div className="bg-[#F3F3F2] p-6 max-w-[1240px] w-full space-y-20">
<div className="flex gap-4">
<div className="left max-w-[800px] w-full flex flex-col gap-4">
<div className="bg-[#F3F3F2] lg:p-6 p-4 max-w-[1240px] w-full sm:space-y-20 space-y-10">
<div className="flex gap-2 sm:gap-4 max-lg:flex-col">
<div className="left lg:max-w-[800px] w-full flex flex-col gap-4">
<div className="flex justify-between gap-4">
<div className="flex items-center gap-4">
<Button
@@ -252,7 +252,7 @@ function UnitModal({ unit, type }: Props) {
</button>
</div>
</div>
<div className="bg-white p-10 rounded-2xl flex flex-col items-center justify-center gap-10 flex-1">
<div className="flex flex-col items-center justify-center flex-1 gap-10 p-10 bg-white rounded-2xl">
<div className="">
<img
src={getMainImage()}
@@ -270,124 +270,126 @@ function UnitModal({ unit, type }: Props) {
</div> */}
</div>
</div>
<div className="right w-[376px] min-w-[376px] space-y-2">
<div className="relative">
<img
src={getViewImage()}
alt=""
className="h-[328px] w-full object-cover rounded-2xl pointer-events-none"
/>
<div className="right lg:w-[376px] lg:min-w-[376px] grid lg:grid-cols-1 sm:grid-cols-2 grid-cols-1 gap-2 grid-rows">
<div className="relative max-sm:order-last">
<div
className="absolute top-0 left-0 w-full h-full rounded-2xl p-6 flex items-end"
className="lg:h-[328px] sm:h-full max-sm:aspect-square bg-center bg-no-repeat bg-cover rounded-2xl"
style={{ backgroundImage: `url('${getViewImage()}')` }}
></div>
<div
className="absolute top-0 left-0 flex items-end w-full h-full p-6 rounded-2xl"
style={{
background:
"linear-gradient(180deg, rgba(16, 41, 79, 0) 67.74%, rgba(16, 41, 79, 0.64) 100%)",
}}
>
<div className="text-white font-semibold space-y-1">
<div className="space-y-1 font-semibold text-white">
<p className="text-xs">View from window</p>
<p className="text-xl">{getViewText()}</p>
</div>
</div>
</div>
<div className="bg-white p-6 rounded-2xl space-y-6">
<div className="space-y-2 border-b border-[E2E2DC] pb-4">
<p className="text-xl text-[#0D1922] font-semibold">
{unit.unitName}, {unit.totalArea} Sqft
</p>
<div className="">
<p className="text-sm text-[#00BED7]">
Rove Home Marasi Drive
<div className="space-y-2">
<div className="p-4 space-y-6 bg-white sm:p-6 rounded-2xl">
<div className="space-y-2 border-b border-[E2E2DC] pb-4">
<p className="sm:text-xl text-[#0D1922] font-semibold">
{unit.unitName}, {unit.totalArea} Sqft
</p>
<div className="text-xs font-semibold flex items-center gap-2">
<p>{unit.unitNo[0] === "E" ? "East" : "West"} Wing</p>
<div className=""></div>
<p>Floor {unit.floor}</p>
<div className=""></div>
<p>{unit.unitNo}</p>
<div className="space-y-1">
<p className="text-sm text-[#00BED7]">
Rove Home Marasi Drive
</p>
<div className="flex items-center gap-2 sm:text-xs text-[10px] font-semibold">
<p>{unit.unitNo[0] === "E" ? "East" : "West"} Wing</p>
<div className="bg-[#E2E2DC] w-1 h-1 rounded-full"></div>
<p>Floor {unit.floor}</p>
<div className="bg-[#E2E2DC] w-1 h-1 rounded-full"></div>
<p>{unit.unitNo}</p>
</div>
</div>
</div>
<div className="space-y-2 max-sm:text-sm">
<div className="flex justify-between">
<p className="text-[#0D1922]/40">Total Area</p>
<p className="text-[#0D1922]">{unit.totalArea} Sqft</p>
</div>
<div className="flex justify-between">
<p className="text-[#0D1922]/40">Suite Area</p>
<p className="text-[#0D1922]">{unit.suiteArea} Sqft</p>
</div>
<div className="flex justify-between">
<p className="text-[#0D1922]/40">Balcony Area</p>
<p className="text-[#0D1922]">{unit.balconyArea} Sqft</p>
</div>
<div className="flex justify-between">
<p className="text-[#0D1922]/40">Status</p>
<p className="text-[#0D1922]">{unit.propertyStatus}</p>
</div>
<div className="flex justify-between">
<p className="text-[#0D1922]/40">Parking Space</p>
<p className="text-[#0D1922]">{unit.parkingSpaces}</p>
</div>
</div>
<p className="text-xl text-[#00BED7] font-semibold">
{unit.unitPrice ? (
<>
AED{" "}
{new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(unit.unitPrice)
.replaceAll(",", " ")}
</>
) : (
"Unavailable"
)}
</p>
</div>
<div className="space-y-2">
<div className="flex justify-between">
<p>Total Area</p>
<p className="text-[#0D1922]">{unit.totalArea} Sqft</p>
</div>
<div className="flex justify-between">
<p>Suite Area</p>
<p className="text-[#0D1922]">{unit.suiteArea} Sqft</p>
</div>
<div className="flex justify-between">
<p>Balcony Area</p>
<p className="text-[#0D1922]">{unit.balconyArea} Sqft</p>
</div>
<div className="flex justify-between">
<p>Status</p>
<p className="text-[#0D1922]">{unit.propertyStatus}</p>
</div>
<div className="flex justify-between">
<p>Parking Space</p>
<p className="text-[#0D1922]">{unit.parkingSpaces}</p>
</div>
</div>
<p className="text-xl text-[#00BED7] font-semibold">
{unit.unitPrice ? (
<>
AED{" "}
{new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(unit.unitPrice)
.replaceAll(",", " ")}
</>
) : (
"Unavailable"
<div className="flex gap-2 p-6 bg-white rounded-2xl">
{unitTypes.find((unitType) => unitType.type === type)
?.tourAvailable && (
<Button
buttonType="secondary"
icon={<VirtualTourIcon />}
text="3D tour"
className="justify-center w-full text-sm"
onClick={handleClickTour}
/>
)}
</p>
</div>
<div className="bg-white p-6 rounded-2xl flex gap-2">
{unitTypes.find((unitType) => unitType.type === type)
?.tourAvailable && (
<Button
buttonType="secondary"
icon={<VirtualTourIcon />}
text="3D tour"
className="justify-center text-sm w-full"
onClick={handleClickTour}
buttonType="cta"
icon={<BookingIcon />}
text="Send Enquiry"
className="text-[13.6px] justify-center disabled:hover:bg-[#ECEDEE] w-full"
disabled
/>
)}
<Button
buttonType="cta"
icon={<BookingIcon />}
text="Send Enquiry"
className="text-[13.6px] justify-center disabled:hover:bg-[#ECEDEE] w-full"
disabled
/>
</div>
</div>
</div>
</div>
<div className="flex gap-4">
<div className="p-8 bg-white rounded-2xl flex flex-col justify-between">
<div className="left w-[376px] min-w-[376px] space-y-6">
<div className="grid grid-cols-1 gap-3 sm:gap-4 sm:grid-cols-2">
<div className="flex flex-col justify-between gap-4 p-4 bg-white sm:p-8 rounded-2xl">
<div className="left lg:w-[376px] lg:min-w-[376px] space-y-6">
<div className="space-y-2">
<p className="text-[40px] text-[#0D1922] font-bold">
<p className="sm:text-[40px] text-2xl text-[#0D1922] font-bold sm:leading-[54px]">
{
unitTypes.find((unitType) => unitType.type === type)
?.title
}
</p>
<p className="text-xl text-[#00BED7] font-semibold">
<p className="sm:text-xl text-[#00BED7] font-semibold leading-[18.4px]">
{unitTypes.find((unitType) => unitType.type === type)?.desc}
</p>
</div>
<div className="space-y-2">
<p className="">
<div className="sm:leading-[22px]">
<p className="space-y-2 max-sm:text-sm">
{
unitTypes.find((unitType) => unitType.type === type)
?.texts[0]
}
</p>
<p className="">
<p className="space-y-2 max-sm:text-sm">
{
unitTypes.find((unitType) => unitType.type === type)
?.texts[1]
@@ -395,24 +397,44 @@ function UnitModal({ unit, type }: Props) {
</p>
</div>
</div>
<div className="">
<p className="">
<div className="space-y-1">
<p className="text-xs sm:text-sm">
Up to{" "}
{unitTypes.find((unitType) => unitType.type === type)?.sqft}{" "}
Sqft
</p>
<p></p>
<p className="text-xl text-[#00BED7] font-semibold">
{unit.unitPrice && (
<>
from AED{" "}
{new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(unit.unitPrice)
.replaceAll(",", " ")}
</>
)}
</p>
</div>
</div>
<div className="right">
<div>
<img
src={
unitTypes.find((unitType) => unitType.type === type)
?.imageDesc
}
alt=""
className="max-h-[644px] rounded-2xl pointer-events-none"
className="lg:max-h-[644px] h-full rounded-2xl pointer-events-none object-cover max-sm:aspect-square"
/>
{/* <div
className="lg:max-h-[644px] sm:h-full max-sm:aspect-square bg-center bg-no-repeat bg-cover rounded-2xl"
style={{
backgroundImage: `url('${
unitTypes.find((unitType) => unitType.type === type)
?.imageDesc
}')`,
}}
></div> */}
</div>
</div>
</div>
@@ -13,7 +13,7 @@ const ButtomPanelCompassVirtualTour = () => {
};
return (
<div className="absolute z-20 bottom-0 left-0 w-full select-none touch-none pointer-events-none flex gap-2 justify-between items-end">
<div className="absolute bottom-0 left-0 z-20 flex items-end justify-between w-full gap-2 pointer-events-none select-none touch-none">
<div className="flex flex-col gap-2">
<div className="flex gap-2 pb-6 pl-6">
<Button
@@ -26,7 +26,7 @@ const ButtomPanelCompassVirtualTour = () => {
{/* <Button text="Privacy Policy" buttonType="special" /> */}
</div>
</div>
<div className="p-6">
<div className="p-6 max-sm:hidden">
<div className="bg-[#0D192266] rounded-full backdrop-blur-sm">
<img
style={{ transform: `rotate(${currentCompassRotate - 180}deg)` }}
+549 -7
View File
@@ -1,13 +1,555 @@
import ComplexTopPanel from "../components/complexPage/ComplexTopPanel";
import ButtomPanelCompass from "../components/ButtomPanelCompass";
import SequenceWing from "../components/complexWingPage/SequenceWing/SequenceWing";
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useRef, useState } from "react";
import { Transition } from "react-transition-group";
import FloorPath from "../components/FloorPath";
import paths from "../data/floorPaths.json";
import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
import Button3 from "../components/Button3";
import InfoIcon from "../components/icons/InfoIcon";
import Header from "../components/Header";
import { useNavigate } from "react-router-dom";
import ArrowRightIcon from "../components/icons/ArrowRightIcon";
import FloorItem from "../components/Test/FloorItem";
import { isMobile } from "react-device-detect";
import FloorPlanSidebar from "../components/complexWingPage/FloorSidebar/FloorPlanSidebar";
import useModal from "../store/useModal";
const floors = [
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"24",
"25",
"26",
"27",
"28",
"29",
"30",
"31",
];
function ComplexWingPage() {
const { modal } = useModal();
const ref = useRef<HTMLImageElement>(null);
const [imageWidth, setImageWidth] = useState(0);
const [imageHeight, setImageHeight] = useState(0);
const [scaled, setScaled] = useState(false);
const [selectedWing, setSelectedWing] = useState<string>();
const [mousePos, setMousePos] = useState<[number, number]>([0, 0]);
const [showPopup, setShowPopup] = useState<boolean>(false);
const [selectedFloorPath, setSelectedFloorPath] = useState<SVGPathElement>();
const [hoveredFloor, setHoveredFloor] = useState<string>();
const navigate = useNavigate();
const [hoveredWing, setHoveredWing] = useState<string>();
const [selectedIndex] = useState<number>(0);
const [selectedFloor, setSelectedFloor] = useState<string>();
// const [showFloorPlanSidebar, setShowFloorPlanSidebar] = useState(false);
function handleResize() {
if (window.innerHeight > window.innerWidth) {
setScaled(true);
} else {
setScaled(false);
}
}
function handleMouseMove(e: React.MouseEvent<HTMLDivElement>) {
const x = e.clientX - e.currentTarget.getBoundingClientRect().left;
const y = e.clientY - e.currentTarget.getBoundingClientRect().top;
setMousePos([x, y]);
}
function handleMouseEnter(e: React.MouseEvent<SVGPathElement>) {
if (!e.currentTarget.dataset["wing"]) return;
setSelectedFloorPath(e.currentTarget);
setHoveredWing(e.currentTarget.dataset["wing"]);
setShowPopup(true);
}
function handleMouseLeave() {
setShowPopup(false);
}
function handleClick(e: React.MouseEvent<SVGPathElement>) {
setSelectedWing(e.currentTarget.dataset["wing"]);
setSelectedFloor(e.currentTarget.dataset["floor"]);
}
// function prev() {
// if (selectedIndex === 0) return;
// setSelectedIndex((prev) => prev - 1);
// }
// function next() {
// if (selectedIndex === floors.length - 1) return;
// setSelectedIndex((prev) => prev + 1);
// }
function handleLoadedData() {
setImageWidth(ref.current!.naturalWidth);
setImageHeight(ref.current!.naturalHeight);
}
useEffect(() => {
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
useEffect(() => {
setHoveredFloor(floors[selectedIndex]);
}, [selectedIndex]);
return (
<div className="overflow-hidden h-screen w-screen select-none">
<ComplexTopPanel />
<SequenceWing />
<ButtomPanelCompass />
<div
className="relative overflow-hidden h-dvh"
onMouseMove={handleMouseMove}
>
<Header />
<div
className={`absolute z-10 bg-white rounded-2xl w-[344px] transition-[opacity,transform] duration-300 p-6 space-y-4 pointer-events-none select-none ${
selectedFloorPath?.dataset["wing"] === "West"
? "-translate-x-[calc(100%+16px)]"
: "translate-x-4"
} -translate-y-[50%] ${showPopup ? "opacity-100" : "opacity-0"}`}
style={{ top: `${mousePos[1]}px`, left: `${mousePos[0]}px` }}
>
<div className="flex items-start justify-between pb-4 border-b border-[#E2E2DC]">
<div className="space-y-1">
<p className="text-xl text-[#0D1922] font-semibold">
{selectedFloorPath?.dataset["name"] === "Sky Garden"
? selectedFloorPath?.dataset["name"]
: `${selectedFloorPath?.dataset["floor"]} floor`}
</p>
<p className="text-xs font-semibold">
{selectedFloorPath?.dataset["name"] !== "Sky Garden" &&
`${selectedFloorPath?.dataset["wing"]} Wing`}
</p>
</div>
<div className="bg-[#00BED7] rounded-full px-2 py-[3px]">
<p className="text-xs font-semibold text-white">0 units</p>
</div>
</div>
{selectedFloorPath?.dataset["name"] !== "Sky Garden" ? (
<div className="grid grid-cols-2">
<div className="space-y-2">
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-[#00BED7] px-[4.5px] py-px rounded-full">
<p className="text-[10px] text-white font-semibold leading-[13.5px]">
0
</p>
</div>
<p className="text-sm">Studio Flex</p>
</div>
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-[#00BED7] px-[4.5px] py-px rounded-full">
<p className="text-[10px] text-white font-semibold leading-[13.5px]">
0
</p>
</div>
<p className="text-sm">Studio²</p>
</div>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-[#00BED7] px-[4.5px] py-px rounded-full">
<p className="text-[10px] text-white font-semibold leading-[13.5px]">
0
</p>
</div>
<p className="text-sm">1 Bedroom²</p>
</div>
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-[#00BED7] px-[4.5px] py-px rounded-full">
<p className="text-[10px] text-white font-semibold leading-[13.5px]">
0
</p>
</div>
<p className="text-sm">2 Bedroom²</p>
</div>
</div>
</div>
) : (
<div className="space-y-2">
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-[#00BED7] px-[4.5px] py-px rounded-full">
<p className="text-[10px] text-white font-semibold leading-[13.5px]">
0
</p>
</div>
<p className="text-sm">Indoor</p>
</div>
<div className="flex items-center gap-2">
<div className="w-4 h-4 bg-[#00BED7] px-[4.5px] py-px rounded-full">
<p className="text-[10px] text-white font-semibold leading-[13.5px]">
0
</p>
</div>
<p className="text-sm">Outdoor</p>
</div>
</div>
)}
</div>
<div className="absolute top-0 left-0 z-10">
<div className="p-4 mt-14">
<div className="flex gap-2">
<Button3
icon={<ArrowLeftIcon />}
onlyIcon
onClick={() => navigate("..")}
/>
<Button3
variant="secondary"
icon={<InfoIcon />}
onClick={() => navigate("/about-projects")}
>
About Projects
</Button3>
</div>
</div>
</div>
<div
className="transition-all duration-300"
style={{
transform: `translateX(${selectedFloor ? -25 : 0}%)`,
}}
>
<div className={`h-dvh ${scaled ? "scale-150 -translate-x-[1%]" : ""}`}>
<img
ref={ref}
src="/images/sequenceWing.jpg"
alt=""
className="object-cover w-full h-full"
onLoad={() => handleLoadedData()}
/>
<svg
viewBox={`0 0 ${imageWidth} ${imageHeight}`}
preserveAspectRatio="xMidYMid slice"
className="absolute top-0 left-0 w-full h-full"
>
{!isMobile ? (
paths.map((path, index) => (
<FloorPath
key={index}
{...path}
selected={
path["data-wing"] && path["data-floor"]
? path["data-wing"] === hoveredWing &&
path["data-floor"] === hoveredFloor
: false
}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
))
) : (
<>
<g
className={`transition-opacity duration-300 ${
selectedWing
? "opacity-100"
: "opacity-0 pointer-events-none"
}`}
>
{paths
.filter((path) => path["data-wing"] === selectedWing)
.map((path, index) => (
<FloorPath
key={index}
{...path}
selected={
path["data-wing"] && path["data-floor"]
? path["data-wing"] === selectedWing &&
path["data-floor"] === hoveredFloor
: false
}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
))}
</g>
<g
className={`transition-opacity duration-300 ${
selectedWing
? "opacity-0 pointer-events-none"
: "opacity-100"
}`}
>
<path
d="M1441.29,1493.16v23.81l-.29,1034.35h0v24.45c0,1.73,1.11,3.26,2.76,3.8l138.35,45.23c.76.25,1.57.27,2.34.04l316.3-90.81c.23-.06.46-.11.7-.13l58.15-5.9,3.6-.53.29-1015.83c0-2.21-1.79-4-4-4h-58.11l-321.31-34.62c-.3-.03-.6-.03-.9.01l-134.36,16.16c-2.01.24-3.52,1.94-3.52,3.97Z"
className={`fill-[#00bed7]/20`}
onClick={() => setSelectedWing("East")}
/>
<path
d="M2446,1515.51v-25.79c0-2.13-1.68-3.89-3.81-3.99l-136.64-6.53c-.32-.02-.64.01-.96.07l-28.81,5.68-249.29,22.69h-59c-2.21,0-4,1.79-4,4l-.29,1015.83,3.81.34,58.82,2.71c.25.01.5.04.74.1l248.44,59.2c.36.09.71.23,1.04.41l23.43,13.25c.75.43,1.62.6,2.48.49l140.27-18.21c1.99-.26,3.48-1.96,3.48-3.97v-24.64l.29-1041.64Z"
className={`fill-[#00bed7]/20`}
onClick={() => setSelectedWing("West")}
/>
</g>
</>
)}
<g>
<rect
x={2068}
y={1234}
width={224}
height={56}
rx={24}
ry={24}
style={{
fill: "#000",
opacity: 0.4,
strokeWidth: 0,
}}
/>
<g>
<path
d="M2105.55,1273.23l-6.47-22.91h4.46l4.13,16.83h.21l4.41-16.83h4.06l4.42,16.85h.2l4.13-16.85h4.46l-6.47,22.91h-4.09l-4.59-16.07h-.18l-4.6,16.07h-4.09Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2145.74,1264.51c0-1.51-.21-2.81-.63-3.9-.42-1.09-.99-1.99-1.72-2.7s-1.56-1.23-2.51-1.57c-.94-.34-1.94-.51-3-.51-1.64,0-3.07.37-4.28,1.12-1.22.75-2.16,1.79-2.84,3.13-.68,1.34-1.01,2.89-1.01,4.66s.34,3.36,1.01,4.68c.67,1.32,1.63,2.35,2.88,3.07,1.25.72,2.74,1.08,4.46,1.08,1.33,0,2.52-.2,3.56-.61,1.04-.41,1.89-.98,2.56-1.72s1.12-1.61,1.36-2.61l-3.78-.43c-.18.48-.44.89-.79,1.22s-.76.58-1.24.74c-.48.17-1.01.25-1.6.25-.88,0-1.65-.19-2.3-.56-.66-.38-1.17-.92-1.53-1.63-.35-.69-.53-1.51-.54-2.47h11.96v-1.24ZM2133.79,1263.02c.04-.67.21-1.3.51-1.87.35-.65.83-1.17,1.46-1.57.63-.4,1.35-.6,2.18-.6.78,0,1.46.18,2.04.53.59.35,1.04.83,1.37,1.44.33.61.5,1.3.5,2.08h-8.07Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2162.75,1260.59l-3.69.4c-.1-.37-.29-.72-.54-1.05s-.6-.59-1.03-.79c-.43-.2-.96-.3-1.59-.3-.84,0-1.55.18-2.12.55-.57.37-.85.84-.85,1.42,0,.5.18.91.55,1.22.38.31,1,.57,1.87.77l2.93.63c1.63.35,2.84.91,3.63,1.67.79.76,1.19,1.76,1.2,2.99,0,1.08-.32,2.03-.95,2.86s-1.49,1.47-2.59,1.93c-1.1.46-2.37.69-3.8.69-2.1,0-3.8-.44-5.08-1.33s-2.05-2.12-2.29-3.7l3.95-.38c.18.78.56,1.36,1.14,1.76.58.4,1.34.59,2.27.59s1.74-.2,2.32-.59c.59-.4.88-.88.88-1.47,0-.49-.19-.9-.57-1.22-.38-.32-.96-.57-1.75-.74l-2.93-.62c-1.65-.34-2.87-.92-3.66-1.74-.79-.82-1.18-1.85-1.17-3.1,0-1.06.28-1.98.87-2.76s1.4-1.38,2.45-1.81c1.05-.43,2.26-.64,3.63-.64,2.01,0,3.6.43,4.76,1.29s1.88,2.02,2.15,3.48Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2174.67,1269.9c-.11.03-.27.06-.49.1-.21.04-.45.06-.7.06-.34,0-.64-.05-.92-.16-.28-.1-.5-.3-.67-.59-.17-.29-.25-.7-.25-1.25v-8.88h3.39v-3.13h-3.39v-4.12h-4.05v4.12h-2.44v3.13h2.44v9.55c0,1.07.23,1.97.7,2.68.47.72,1.12,1.24,1.93,1.58.81.34,1.73.49,2.74.46.57-.01,1.06-.07,1.46-.16.4-.09.71-.17.92-.25l-.68-3.17Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2191.25,1273.23l-6.47-22.91h4.46l4.13,16.83h.21l4.41-16.83h4.06l4.42,16.85h.2l4.13-16.85h4.46l-6.47,22.91h-4.09l-4.59-16.07h-.18l-4.6,16.07h-4.09Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2220,1253.61c-.64,0-1.19-.21-1.66-.64s-.69-.95-.69-1.55.23-1.13.69-1.56c.46-.43,1.01-.64,1.66-.64s1.2.21,1.66.64c.46.43.69.95.69,1.56s-.23,1.12-.69,1.55c-.46.43-1.01.64-1.66.64ZM2217.96,1273.23v-17.18h4.05v17.18h-4.05Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2230.22,1263.16v10.07h-4.05v-17.18h3.87v2.92h.2c.39-.96,1.03-1.73,1.9-2.29.87-.57,1.94-.85,3.23-.85,1.19,0,2.22.25,3.1.76.88.51,1.57,1.24,2.06,2.2.49.96.73,2.13.72,3.5v10.94h-4.05v-10.31c0-1.15-.3-2.05-.89-2.7-.59-.65-1.41-.97-2.46-.97-.71,0-1.34.15-1.88.46-.55.31-.98.76-1.29,1.34s-.46,1.29-.46,2.11Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2252.85,1280.03c-1.45,0-2.7-.2-3.75-.59s-1.88-.92-2.52-1.57c-.63-.66-1.07-1.38-1.32-2.18l3.65-.88c.16.34.4.67.72,1,.31.33.74.61,1.27.83s1.21.33,2.02.33c1.15,0,2.1-.28,2.85-.83.75-.56,1.13-1.47,1.13-2.73v-3.26h-.2c-.21.42-.51.85-.91,1.29s-.92.81-1.58,1.11-1.47.45-2.45.45c-1.32,0-2.52-.31-3.59-.93s-1.92-1.55-2.55-2.8c-.63-1.24-.95-2.8-.95-4.67s.32-3.48.95-4.78c.63-1.3,1.48-2.29,2.56-2.96,1.07-.68,2.27-1.01,3.59-1.01,1.01,0,1.84.17,2.49.51.65.34,1.17.75,1.56,1.22.39.47.68.92.88,1.34h.22v-2.84h3.99v17.46c0,1.47-.35,2.68-1.05,3.65-.7.96-1.66,1.68-2.88,2.16-1.22.48-2.6.72-4.14.72ZM2252.88,1269.81c.86,0,1.59-.21,2.19-.63.6-.42,1.06-1.02,1.38-1.8.31-.78.47-1.72.47-2.82s-.15-2.03-.46-2.84c-.31-.81-.76-1.44-1.36-1.9-.6-.45-1.34-.68-2.21-.68s-1.66.23-2.26.7c-.6.47-1.06,1.11-1.37,1.93-.31.82-.46,1.74-.46,2.78s.15,1.97.46,2.76c.31.79.77,1.4,1.38,1.83s1.36.65,2.24.65Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
</g>
</g>
<g>
<rect
x={1618}
y={1234}
width={224}
height={56}
rx={24}
ry={24}
style={{
fill: "#000",
opacity: 0.4,
strokeWidth: 0,
}}
/>
<g>
<path
d="M1655.6,1273.23v-22.91h14.9v3.48h-10.75v6.22h9.98v3.48h-9.98v6.25h10.84v3.48h-14.99Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1679.5,1273.58c-1.09,0-2.07-.2-2.94-.59-.87-.39-1.55-.97-2.06-1.74s-.75-1.72-.75-2.84c0-.97.18-1.77.54-2.4.36-.63.85-1.14,1.47-1.52s1.32-.67,2.1-.87c.78-.2,1.59-.34,2.42-.43,1.01-.1,1.82-.2,2.45-.29.63-.09,1.08-.22,1.37-.4.29-.18.43-.47.43-.86v-.07c0-.84-.25-1.5-.75-1.96-.5-.46-1.22-.69-2.16-.69-.99,0-1.78.22-2.35.65s-.97.94-1.17,1.53l-3.78-.54c.3-1.04.79-1.92,1.48-2.62.69-.7,1.52-1.23,2.52-1.59.99-.35,2.09-.53,3.29-.53.83,0,1.65.1,2.47.29s1.57.51,2.25.96c.68.44,1.22,1.05,1.64,1.81.41.76.62,1.71.62,2.85v11.5h-3.89v-2.36h-.13c-.25.48-.59.92-1.03,1.34-.44.41-1,.75-1.67,1-.67.25-1.45.37-2.34.37ZM1680.55,1270.6c.81,0,1.52-.16,2.11-.49.6-.32,1.06-.75,1.38-1.29.32-.54.49-1.12.49-1.76v-2.02c-.13.1-.34.2-.64.29-.3.09-.64.17-1.01.23-.37.07-.74.13-1.11.18-.37.05-.68.1-.95.13-.6.08-1.15.22-1.62.4-.48.19-.85.45-1.13.78-.28.33-.41.76-.41,1.28,0,.75.27,1.31.82,1.69s1.24.57,2.08.57Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1706.24,1260.59l-3.69.4c-.1-.37-.29-.72-.54-1.05s-.6-.59-1.03-.79c-.43-.2-.96-.3-1.59-.3-.84,0-1.55.18-2.12.55-.57.37-.85.84-.84,1.42,0,.5.18.91.55,1.22.38.31,1,.57,1.87.77l2.93.63c1.63.35,2.84.91,3.63,1.67.79.76,1.2,1.76,1.2,2.99,0,1.08-.32,2.03-.95,2.86s-1.49,1.47-2.59,1.93-2.37.69-3.8.69c-2.1,0-3.8-.44-5.08-1.33-1.28-.88-2.05-2.12-2.29-3.7l3.95-.38c.18.78.56,1.36,1.14,1.76.58.4,1.34.59,2.27.59s1.74-.2,2.32-.59c.59-.4.88-.88.88-1.47,0-.49-.19-.9-.56-1.22-.38-.32-.96-.57-1.75-.74l-2.93-.62c-1.65-.34-2.87-.92-3.66-1.74-.79-.82-1.18-1.85-1.17-3.1,0-1.06.28-1.98.87-2.76s1.4-1.38,2.45-1.81c1.05-.43,2.26-.64,3.63-.64,2.01,0,3.6.43,4.76,1.29,1.16.86,1.88,2.02,2.15,3.48Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1718.16,1269.9c-.11.03-.27.06-.49.1-.21.04-.45.06-.7.06-.34,0-.64-.05-.92-.16s-.5-.3-.67-.59c-.17-.29-.25-.7-.25-1.25v-8.88h3.39v-3.13h-3.39v-4.12h-4.05v4.12h-2.44v3.13h2.44v9.55c0,1.07.23,1.97.7,2.68.47.72,1.12,1.24,1.93,1.58.81.34,1.73.49,2.74.46.57-.01,1.06-.07,1.46-.16.4-.09.71-.17.92-.25l-.68-3.17Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1734.74,1273.23l-6.47-22.91h4.46l4.13,16.83h.21l4.41-16.83h4.06l4.42,16.85h.2l4.13-16.85h4.46l-6.47,22.91h-4.09l-4.59-16.07h-.18l-4.6,16.07h-4.09Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1763.48,1253.61c-.64,0-1.19-.21-1.66-.64s-.69-.95-.69-1.55.23-1.13.69-1.56c.46-.43,1.01-.64,1.66-.64s1.2.21,1.66.64c.46.43.69.95.69,1.56s-.23,1.12-.69,1.55c-.46.43-1.01.64-1.66.64ZM1761.45,1273.23v-17.18h4.05v17.18h-4.05Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1773.71,1263.16v10.07h-4.05v-17.18h3.87v2.92h.2c.4-.96,1.03-1.73,1.9-2.29.87-.57,1.94-.85,3.23-.85,1.19,0,2.22.25,3.1.76.88.51,1.57,1.24,2.06,2.2.49.96.73,2.13.72,3.5v10.94h-4.05v-10.31c0-1.15-.3-2.05-.89-2.7-.59-.65-1.41-.97-2.46-.97-.71,0-1.34.15-1.89.46-.55.31-.98.76-1.29,1.34s-.46,1.29-.46,2.11Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1796.34,1280.03c-1.45,0-2.7-.2-3.75-.59s-1.88-.92-2.52-1.57c-.63-.66-1.07-1.38-1.32-2.18l3.65-.88c.16.34.4.67.72,1,.31.33.74.61,1.27.83.53.22,1.21.33,2.02.33,1.15,0,2.1-.28,2.85-.83s1.13-1.47,1.13-2.73v-3.26h-.2c-.21.42-.51.85-.91,1.29s-.92.81-1.58,1.11c-.65.3-1.47.45-2.46.45-1.32,0-2.51-.31-3.59-.93s-1.92-1.55-2.55-2.8c-.63-1.24-.95-2.8-.95-4.67s.32-3.48.95-4.78,1.48-2.29,2.56-2.96c1.07-.68,2.27-1.01,3.59-1.01,1.01,0,1.84.17,2.49.51.65.34,1.17.75,1.56,1.22.39.47.68.92.88,1.34h.22v-2.84h3.99v17.46c0,1.47-.35,2.68-1.05,3.65-.7.96-1.66,1.68-2.87,2.16-1.22.48-2.6.72-4.14.72ZM1796.37,1269.81c.86,0,1.59-.21,2.19-.63.6-.42,1.06-1.02,1.38-1.8s.47-1.72.47-2.82-.15-2.03-.46-2.84c-.31-.81-.76-1.44-1.36-1.9s-1.34-.68-2.21-.68-1.66.23-2.26.7c-.6.47-1.06,1.11-1.36,1.93-.31.82-.46,1.74-.46,2.78s.16,1.97.46,2.76c.31.79.77,1.4,1.38,1.83.61.44,1.36.65,2.24.65Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
</g>
</g>
</svg>
</div>
</div>
<div
className={`sm:hidden absolute bottom-0 w-full p-3 transition-opacity duration-300 ${
selectedWing ? "opacity-100" : "opacity-0 pointer-events-none"
}`}
>
<div className="relative px-4 pt-2 pb-4 space-y-3 bg-white rounded-lg">
<div className="relative overflow-hidden">
<div
id="test"
className="absolute top-[calc(50%-16px)] left-[calc(50%-16px)] w-8 h-6"
></div>
<div
id="floors"
className="relative flex gap-4 overflow-x-auto px-[calc(50%)] pt-2.5 pb-[18px] snap-x snap-mandatory"
>
{floors.map((floor) => (
<FloorItem
floor={floor}
onSelected={() => setHoveredFloor(floor)}
/>
))}
</div>
<div className="absolute top-0 left-0 w-full h-full pointer-events-none bg-gradient-to-r from-white via-transparent to-white"></div>
<div className="absolute top-0 left-0 flex justify-between w-full pointer-events-none">
<Button3
variant="secondary"
icon={<ArrowLeftIcon className="w-4 h-4" />}
onlyIcon
className="ring-0 w-9 h-9"
/>
<Button3
variant="secondary"
icon={<ArrowRightIcon className="w-4 h-4" />}
onlyIcon
className="ring-0 w-9 h-9"
/>
</div>
</div>
<div className="flex gap-2">
<Button3
variant="secondary"
size="small"
icon={<ArrowLeftIcon className="w-4 h-4" />}
className="w-full"
onClick={() => setSelectedWing(undefined)}
>
Back
</Button3>
<Button3
size="small"
icon={<ArrowRightIcon className="w-4 h-4" />}
className="flex-row-reverse w-full"
onClick={() => setSelectedFloor(hoveredFloor)}
>
Explore
</Button3>
</div>
</div>
</div>
<Transition
in={!!selectedFloor && !!selectedWing}
timeout={300}
mountOnEnter
unmountOnExit
>
{(state) => (
<div
className={`absolute top-0 h-dvh bg-[#F3F3F2] right-0 lg:w-1/2 w-full z-10 transition-all duration-300 flex flex-col ${state}`}
>
<FloorPlanSidebar
floor={+selectedFloor!}
wing={selectedWing!}
onClose={() => setSelectedFloor(undefined)}
/>
</div>
)}
</Transition>
{/* <ButtomPanelCompass /> */}
{modal}
</div>
);
}
+218 -184
View File
@@ -14,6 +14,10 @@ import UnitModalForSearchPage from "../components/modals/UnitModalForSearchPage"
import useFavoritesStore from "../store/useFavoritesStore";
import HeartFilledIcon from "../components/icons/HeartFilledIcon";
import { useSearchParams } from "react-router-dom";
import { isMobile } from "react-device-detect";
import CloseIcon from "../components/icons/CloseIcon";
import FiltersIcon from "../components/icons/FiltersIcon";
import Button3 from "../components/Button3";
function SearchPage() {
const [units, setUnits] = useState<IUnit[]>([]);
@@ -36,6 +40,7 @@ function SearchPage() {
const { setModal } = useModal();
const { favoriteUnits, setFavoriteUnits } = useFavoritesStore();
const [searchParams, setSearchParams] = useSearchParams();
const [showFilters, setShowFilters] = useState(false);
async function getUnits() {
try {
@@ -169,7 +174,6 @@ function SearchPage() {
}
function refreshFilters() {
console.log("call func refreshFilters");
setUnitTypeFilters([]);
setUnitViewFilters([]);
setCost([minCost, maxCost]);
@@ -379,6 +383,10 @@ function SearchPage() {
useEffect(() => {
getUnits();
if (!isMobile) {
setShowFilters(true);
}
}, []);
useEffect(() => {
@@ -397,22 +405,36 @@ function SearchPage() {
}, [units]);
return (
<div className="pt-[58px] flex select-none">
<div className="p-6 min-w-[360px] w-[360px] space-y-6 border-r border-[#E2E2DC]">
<div className="flex justify-between pb-4 border-b border-[#E2E2DC]">
<p className="text-2xl text-[#0D1922] font-semibold">Filters</p>
<button
className="w-10 h-10 bg-white rounded-full flex items-center justify-center bg-opacity-80 hover:bg-opacity-100 hover:text-[#0D1922] transition-all"
onClick={refreshFilters}
>
<RestartIcon className="w-5 h-5" />
</button>
<div className="pt-[58px] flex select-none relative">
<div
className={`lg:p-6 p-4 min-w-[360px] lg:w-[360px] w-full h-[calc(100vh-56px)] top-0 left-0 max-lg:mt-[56px] sm:space-y-6 space-y-4 border-r border-[#E2E2DC] max-lg:fixed z-10 bg-[#F3F3F2] max-lg:overflow-y-auto ${
!showFilters ? "max-lg:hidden" : ""
}`}
>
<div className="flex items-center justify-between pb-4 border-b border-[#E2E2DC]">
<p className="lg:text-2xl text-xl text-[#0D1922] font-semibold">
Filters
</p>
<div className="flex gap-2">
<button
className="w-10 h-10 bg-white rounded-full flex items-center justify-center bg-opacity-80 hover:bg-opacity-100 hover:text-[#0D1922] transition-all"
onClick={refreshFilters}
>
<RestartIcon className="w-5 h-5" />
</button>
<button
className="lg:hidden w-10 h-10 bg-white rounded-full flex items-center justify-center bg-opacity-80 hover:bg-opacity-100 hover:text-[#0D1922] transition-all"
onClick={() => setShowFilters(false)}
>
<CloseIcon className="w-5 h-5" />
</button>
</div>
</div>
<div className="space-y-4">
<p className="text-[#0D1922]">Apartment type</p>
<div className="space-y-2">
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="space-y-3 lg:space-y-4">
<p className="text-[#0D1922] text-sm">Apartment type</p>
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-1">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="Studio Flex"
checked={unitTypeFilters.some(
@@ -430,10 +452,10 @@ function SearchPage() {
}
}}
/>
<p>Studio Flex</p>
<p className="text-sm">Studio Flex</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitType === "Studio Flex")
.length
@@ -441,8 +463,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="Studio Squared"
checked={unitTypeFilters.some(
@@ -460,10 +482,10 @@ function SearchPage() {
}
}}
/>
<p>Studio²</p>
<p className="text-sm">Studio²</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitType === "Studio Squared")
.length
@@ -471,8 +493,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="1 BR Squared"
checked={unitTypeFilters.some(
@@ -490,10 +512,10 @@ function SearchPage() {
}
}}
/>
<p>1 Bedroom²</p>
<p className="text-sm">1 Bedroom²</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitType === "1 BR Squared")
.length
@@ -501,8 +523,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="2 BR Squared"
checked={unitTypeFilters.some(
@@ -520,10 +542,10 @@ function SearchPage() {
}
}}
/>
<p>2 Bedroom²</p>
<p className="text-sm">2 Bedroom²</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitType === "2 BR Squared")
.length
@@ -533,131 +555,133 @@ function SearchPage() {
</div>
</div>
</div>
<div className="space-y-3">
<div className="text-sm flex justify-between">
<p className="text-[#0D1922]">Cost</p>
<p className="text-[#0D192266]">AED</p>
</div>
<div className="">
<div className="flex">
<Input
value={new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(cost[0])
.replaceAll(",", " ")}
min={minCost}
max={maxCost}
onlyNumbers
readOnly
className="rounded-r-none"
onChange={(value) => setCost([value as number, cost[1]])}
/>
<Input
value={new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(cost[1])
.replaceAll(",", " ")}
min={minCost}
max={maxCost}
onlyNumbers
readOnly
className="rounded-r-none text-right"
onChange={(value) => setCost([cost[0], value as number])}
/>
<div className="grid grid-cols-1 gap-6 lg:grid-cols-1 sm:grid-cols-2">
<div className="space-y-3 lg:space-y-4">
<div className="flex justify-between text-sm">
<p className="text-[#0D1922]">Cost</p>
<p className="text-[#0D192266]">AED</p>
</div>
<div className="px-2 -mt-0.5">
<RangeSlider
min={minCost}
max={maxCost}
value={cost}
onInput={(value: number[]) => setCost(value)}
disabled
/>
<div className="">
<div className="flex">
<Input
value={new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(cost[0])
.replaceAll(",", " ")}
min={minCost}
max={maxCost}
onlyNumbers
readOnly
className="rounded-r-none"
onChange={(value) => setCost([value as number, cost[1]])}
/>
<Input
value={new Intl.NumberFormat("ar-AE", {
currency: "AED",
})
.format(cost[1])
.replaceAll(",", " ")}
min={minCost}
max={maxCost}
onlyNumbers
readOnly
className="text-right rounded-l-none"
onChange={(value) => setCost([cost[0], value as number])}
/>
</div>
<div className="px-2 -mt-0.5">
<RangeSlider
min={minCost}
max={maxCost}
value={cost}
onInput={(value: number[]) => setCost(value)}
disabled
/>
</div>
</div>
</div>
<div className="space-y-3 lg:space-y-4">
<div className="flex justify-between text-sm">
<p className="text-[#0D1922]">Total Area</p>
<p className="text-[#0D192266]">Sqft</p>
</div>
<div className="">
<div className="flex">
<Input
readOnly
value={totalArea[0]}
min={minTotalArea}
max={maxTotalArea}
onlyNumbers
className="rounded-r-none"
onChange={(value) =>
setTotalArea([value as number, totalArea[1]])
}
/>
<Input
readOnly
value={totalArea[1]}
min={minTotalArea}
max={maxTotalArea}
onlyNumbers
className="text-right rounded-l-none"
onChange={(value) =>
setTotalArea([totalArea[0], value as number])
}
/>
</div>
<div className="px-2 -mt-0.5">
<RangeSlider
min={minTotalArea}
max={maxTotalArea}
value={totalArea}
onInput={(value: number[]) => setTotalArea(value)}
/>
</div>
</div>
</div>
<div className="space-y-3 lg:space-y-4">
<div className="flex justify-between text-sm">
<p className="text-[#0D1922]">Floor</p>
</div>
<div className="">
<div className="flex">
<Input
readOnly
value={floor[0]}
min={minFloor}
max={maxFloor}
onlyNumbers
className="rounded-r-none"
onChange={(value) => setFloor([value as number, floor[1]])}
/>
<Input
readOnly
value={floor[1]}
min={minFloor}
max={maxFloor}
onlyNumbers
className="text-right rounded-l-none"
onChange={(value) => setFloor([floor[0], value as number])}
/>
</div>
<div className="px-2 -mt-0.5">
<RangeSlider
min={minFloor}
max={maxFloor}
value={floor}
onInput={(value: number[]) => setFloor(value)}
/>
</div>
</div>
</div>
</div>
<div className="space-y-3">
<div className="text-sm flex justify-between">
<p className="text-[#0D1922]">Total Area</p>
<p className="text-[#0D192266]">Sqft</p>
</div>
<div className="">
<div className="flex">
<Input
readOnly
value={totalArea[0]}
min={minTotalArea}
max={maxTotalArea}
onlyNumbers
className="rounded-r-none"
onChange={(value) =>
setTotalArea([value as number, totalArea[1]])
}
/>
<Input
readOnly
value={totalArea[1]}
min={minTotalArea}
max={maxTotalArea}
onlyNumbers
className="rounded-r-none text-right"
onChange={(value) =>
setTotalArea([totalArea[0], value as number])
}
/>
</div>
<div className="px-2 -mt-0.5">
<RangeSlider
min={minTotalArea}
max={maxTotalArea}
value={totalArea}
onInput={(value: number[]) => setTotalArea(value)}
/>
</div>
</div>
</div>
<div className="space-y-3">
<div className="text-sm flex justify-between">
<p className="text-[#0D1922]">Floor</p>
</div>
<div className="">
<div className="flex">
<Input
readOnly
value={floor[0]}
min={minFloor}
max={maxFloor}
onlyNumbers
className="rounded-r-none"
onChange={(value) => setFloor([value as number, floor[1]])}
/>
<Input
readOnly
value={floor[1]}
min={minFloor}
max={maxFloor}
onlyNumbers
className="rounded-r-none text-right"
onChange={(value) => setFloor([floor[0], value as number])}
/>
</div>
<div className="px-2 -mt-0.5">
<RangeSlider
min={minFloor}
max={maxFloor}
value={floor}
onInput={(value: number[]) => setFloor(value)}
/>
</div>
</div>
</div>
<div className="space-y-4">
<p className="text-[#0D1922]">View</p>
<div className="space-y-2">
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="space-y-3 lg:space-y-4">
<p className="text-[#0D1922] text-sm">View</p>
<div className="grid grid-cols-1 gap-2 lg:grid-cols-1 sm:grid-cols-2">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="BK/DT"
checked={unitViewFilters.some(
@@ -675,10 +699,10 @@ function SearchPage() {
}
}}
/>
<p>Burj Khalifa / Downtown</p>
<p className="text-sm">Burj Khalifa / Downtown</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitView.includes("BK/DT"))
.length
@@ -686,8 +710,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="Business Bay"
checked={unitViewFilters.some(
@@ -705,10 +729,10 @@ function SearchPage() {
}
}}
/>
<p>Business Bay</p>
<p className="text-sm">Business Bay</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitView === "Business Bay")
.length
@@ -716,8 +740,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="Amenities"
checked={unitViewFilters.some(
@@ -735,10 +759,10 @@ function SearchPage() {
}
}}
/>
<p>Amenities</p>
<p className="text-sm">Amenities</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitView.includes("Amenities"))
.length
@@ -746,8 +770,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="Canal"
checked={unitViewFilters.some(
@@ -765,10 +789,10 @@ function SearchPage() {
}
}}
/>
<p>Canal</p>
<p className="text-sm">Canal</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitView.includes("Canal"))
.length
@@ -776,8 +800,8 @@ function SearchPage() {
</p>
</div>
</div>
<div className="p-3 bg-white rounded-lg flex items-center justify-between">
<div className="flex gap-3">
<div className="flex items-center justify-between p-3 bg-white rounded-lg">
<div className="flex items-center gap-3">
<Checkbox2
filterName="Park"
checked={unitViewFilters.some(
@@ -795,10 +819,10 @@ function SearchPage() {
}
}}
/>
<p>Park</p>
<p className="text-sm">Park</p>
</div>
<div className="px-2 h-6 bg-[#00BED7] rounded-full flex items-center justify-center">
<p className="text-xs text-white font-semibold">
<p className="text-xs font-semibold text-white">
{
units.filter((unit) => unit.unitView.includes("Park"))
.length
@@ -809,31 +833,41 @@ function SearchPage() {
</div>
</div>
</div>
<div className="p-6 w-full">
<div className="w-full p-4 lg:p-6">
<div className="space-y-6">
<div className="flex justify-between pb-4 border-b border-[#E2E2DC]">
<div className="flex max-lg:flex-col gap-6 justify-between pb-4 border-b border-[#E2E2DC]">
<p className="text-2xl font-semibold">
<span className="text-[#0D1922]">Units</span>{" "}
{filteredUnits.length}
</p>
<button
className="bg-white rounded-lg flex items-center gap-2 justify-center text-[#00BED7] px-4 py-2.5"
onClick={() => setIsSortPriceAsc((prev) => !prev)}
>
<p className="text-sm">Sort by ascending price</p>
{/* descending */}
<ChevronDownIcon
className={`w-5 h-5 transition-transform ${
isSortPriceAsc ? "" : "rotate-180"
}`}
<div className="flex gap-2">
<button
className="bg-white w-full rounded-lg flex items-center gap-2 justify-between text-[#00BED7] px-4 py-2.5"
onClick={() => setIsSortPriceAsc((prev) => !prev)}
>
<p className="text-sm">Sort by ascending price</p>
{/* descending */}
<ChevronDownIcon
className={`w-5 h-5 transition-transform ${
isSortPriceAsc ? "" : "rotate-180"
}`}
/>
</button>
<Button3
variant="secondary"
size="small"
icon={<FiltersIcon className="w-5 h-5" />}
onlyIcon
className="lg:hidden"
onClick={() => setShowFilters(true)}
/>
</button>
</div>
</div>
<div className="grid grid-cols-4 gap-4">
<div className="grid gap-4 2xl:grid-cols-4 xl:grid-cols-3 sm:grid-cols-2">
{filteredUnits.map((unit) => (
<div
key={unit.id}
className="bg-white rounded-2xl p-4 space-y-4 flex flex-col justify-between"
className="flex flex-col justify-between p-4 space-y-4 bg-white rounded-2xl"
>
<div className="flex justify-between">
<div className="space-y-1">
+146
View File
@@ -317,6 +317,152 @@ function Test2Page() {
</g>
</>
)}
<g>
<rect
x={2068}
y={1234}
width={224}
height={56}
rx={24}
ry={24}
style={{
fill: "#000",
opacity: 0.4,
strokeWidth: 0,
}}
/>
<g>
<path
d="M2105.55,1273.23l-6.47-22.91h4.46l4.13,16.83h.21l4.41-16.83h4.06l4.42,16.85h.2l4.13-16.85h4.46l-6.47,22.91h-4.09l-4.59-16.07h-.18l-4.6,16.07h-4.09Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2145.74,1264.51c0-1.51-.21-2.81-.63-3.9-.42-1.09-.99-1.99-1.72-2.7s-1.56-1.23-2.51-1.57c-.94-.34-1.94-.51-3-.51-1.64,0-3.07.37-4.28,1.12-1.22.75-2.16,1.79-2.84,3.13-.68,1.34-1.01,2.89-1.01,4.66s.34,3.36,1.01,4.68c.67,1.32,1.63,2.35,2.88,3.07,1.25.72,2.74,1.08,4.46,1.08,1.33,0,2.52-.2,3.56-.61,1.04-.41,1.89-.98,2.56-1.72s1.12-1.61,1.36-2.61l-3.78-.43c-.18.48-.44.89-.79,1.22s-.76.58-1.24.74c-.48.17-1.01.25-1.6.25-.88,0-1.65-.19-2.3-.56-.66-.38-1.17-.92-1.53-1.63-.35-.69-.53-1.51-.54-2.47h11.96v-1.24ZM2133.79,1263.02c.04-.67.21-1.3.51-1.87.35-.65.83-1.17,1.46-1.57.63-.4,1.35-.6,2.18-.6.78,0,1.46.18,2.04.53.59.35,1.04.83,1.37,1.44.33.61.5,1.3.5,2.08h-8.07Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2162.75,1260.59l-3.69.4c-.1-.37-.29-.72-.54-1.05s-.6-.59-1.03-.79c-.43-.2-.96-.3-1.59-.3-.84,0-1.55.18-2.12.55-.57.37-.85.84-.85,1.42,0,.5.18.91.55,1.22.38.31,1,.57,1.87.77l2.93.63c1.63.35,2.84.91,3.63,1.67.79.76,1.19,1.76,1.2,2.99,0,1.08-.32,2.03-.95,2.86s-1.49,1.47-2.59,1.93c-1.1.46-2.37.69-3.8.69-2.1,0-3.8-.44-5.08-1.33s-2.05-2.12-2.29-3.7l3.95-.38c.18.78.56,1.36,1.14,1.76.58.4,1.34.59,2.27.59s1.74-.2,2.32-.59c.59-.4.88-.88.88-1.47,0-.49-.19-.9-.57-1.22-.38-.32-.96-.57-1.75-.74l-2.93-.62c-1.65-.34-2.87-.92-3.66-1.74-.79-.82-1.18-1.85-1.17-3.1,0-1.06.28-1.98.87-2.76s1.4-1.38,2.45-1.81c1.05-.43,2.26-.64,3.63-.64,2.01,0,3.6.43,4.76,1.29s1.88,2.02,2.15,3.48Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2174.67,1269.9c-.11.03-.27.06-.49.1-.21.04-.45.06-.7.06-.34,0-.64-.05-.92-.16-.28-.1-.5-.3-.67-.59-.17-.29-.25-.7-.25-1.25v-8.88h3.39v-3.13h-3.39v-4.12h-4.05v4.12h-2.44v3.13h2.44v9.55c0,1.07.23,1.97.7,2.68.47.72,1.12,1.24,1.93,1.58.81.34,1.73.49,2.74.46.57-.01,1.06-.07,1.46-.16.4-.09.71-.17.92-.25l-.68-3.17Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2191.25,1273.23l-6.47-22.91h4.46l4.13,16.83h.21l4.41-16.83h4.06l4.42,16.85h.2l4.13-16.85h4.46l-6.47,22.91h-4.09l-4.59-16.07h-.18l-4.6,16.07h-4.09Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2220,1253.61c-.64,0-1.19-.21-1.66-.64s-.69-.95-.69-1.55.23-1.13.69-1.56c.46-.43,1.01-.64,1.66-.64s1.2.21,1.66.64c.46.43.69.95.69,1.56s-.23,1.12-.69,1.55c-.46.43-1.01.64-1.66.64ZM2217.96,1273.23v-17.18h4.05v17.18h-4.05Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2230.22,1263.16v10.07h-4.05v-17.18h3.87v2.92h.2c.39-.96,1.03-1.73,1.9-2.29.87-.57,1.94-.85,3.23-.85,1.19,0,2.22.25,3.1.76.88.51,1.57,1.24,2.06,2.2.49.96.73,2.13.72,3.5v10.94h-4.05v-10.31c0-1.15-.3-2.05-.89-2.7-.59-.65-1.41-.97-2.46-.97-.71,0-1.34.15-1.88.46-.55.31-.98.76-1.29,1.34s-.46,1.29-.46,2.11Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M2252.85,1280.03c-1.45,0-2.7-.2-3.75-.59s-1.88-.92-2.52-1.57c-.63-.66-1.07-1.38-1.32-2.18l3.65-.88c.16.34.4.67.72,1,.31.33.74.61,1.27.83s1.21.33,2.02.33c1.15,0,2.1-.28,2.85-.83.75-.56,1.13-1.47,1.13-2.73v-3.26h-.2c-.21.42-.51.85-.91,1.29s-.92.81-1.58,1.11-1.47.45-2.45.45c-1.32,0-2.52-.31-3.59-.93s-1.92-1.55-2.55-2.8c-.63-1.24-.95-2.8-.95-4.67s.32-3.48.95-4.78c.63-1.3,1.48-2.29,2.56-2.96,1.07-.68,2.27-1.01,3.59-1.01,1.01,0,1.84.17,2.49.51.65.34,1.17.75,1.56,1.22.39.47.68.92.88,1.34h.22v-2.84h3.99v17.46c0,1.47-.35,2.68-1.05,3.65-.7.96-1.66,1.68-2.88,2.16-1.22.48-2.6.72-4.14.72ZM2252.88,1269.81c.86,0,1.59-.21,2.19-.63.6-.42,1.06-1.02,1.38-1.8.31-.78.47-1.72.47-2.82s-.15-2.03-.46-2.84c-.31-.81-.76-1.44-1.36-1.9-.6-.45-1.34-.68-2.21-.68s-1.66.23-2.26.7c-.6.47-1.06,1.11-1.37,1.93-.31.82-.46,1.74-.46,2.78s.15,1.97.46,2.76c.31.79.77,1.4,1.38,1.83s1.36.65,2.24.65Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
</g>
</g>
<g>
<rect
x={1618}
y={1234}
width={224}
height={56}
rx={24}
ry={24}
style={{
fill: "#000",
opacity: 0.4,
strokeWidth: 0,
}}
/>
<g>
<path
d="M1655.6,1273.23v-22.91h14.9v3.48h-10.75v6.22h9.98v3.48h-9.98v6.25h10.84v3.48h-14.99Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1679.5,1273.58c-1.09,0-2.07-.2-2.94-.59-.87-.39-1.55-.97-2.06-1.74s-.75-1.72-.75-2.84c0-.97.18-1.77.54-2.4.36-.63.85-1.14,1.47-1.52s1.32-.67,2.1-.87c.78-.2,1.59-.34,2.42-.43,1.01-.1,1.82-.2,2.45-.29.63-.09,1.08-.22,1.37-.4.29-.18.43-.47.43-.86v-.07c0-.84-.25-1.5-.75-1.96-.5-.46-1.22-.69-2.16-.69-.99,0-1.78.22-2.35.65s-.97.94-1.17,1.53l-3.78-.54c.3-1.04.79-1.92,1.48-2.62.69-.7,1.52-1.23,2.52-1.59.99-.35,2.09-.53,3.29-.53.83,0,1.65.1,2.47.29s1.57.51,2.25.96c.68.44,1.22,1.05,1.64,1.81.41.76.62,1.71.62,2.85v11.5h-3.89v-2.36h-.13c-.25.48-.59.92-1.03,1.34-.44.41-1,.75-1.67,1-.67.25-1.45.37-2.34.37ZM1680.55,1270.6c.81,0,1.52-.16,2.11-.49.6-.32,1.06-.75,1.38-1.29.32-.54.49-1.12.49-1.76v-2.02c-.13.1-.34.2-.64.29-.3.09-.64.17-1.01.23-.37.07-.74.13-1.11.18-.37.05-.68.1-.95.13-.6.08-1.15.22-1.62.4-.48.19-.85.45-1.13.78-.28.33-.41.76-.41,1.28,0,.75.27,1.31.82,1.69s1.24.57,2.08.57Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1706.24,1260.59l-3.69.4c-.1-.37-.29-.72-.54-1.05s-.6-.59-1.03-.79c-.43-.2-.96-.3-1.59-.3-.84,0-1.55.18-2.12.55-.57.37-.85.84-.84,1.42,0,.5.18.91.55,1.22.38.31,1,.57,1.87.77l2.93.63c1.63.35,2.84.91,3.63,1.67.79.76,1.2,1.76,1.2,2.99,0,1.08-.32,2.03-.95,2.86s-1.49,1.47-2.59,1.93-2.37.69-3.8.69c-2.1,0-3.8-.44-5.08-1.33-1.28-.88-2.05-2.12-2.29-3.7l3.95-.38c.18.78.56,1.36,1.14,1.76.58.4,1.34.59,2.27.59s1.74-.2,2.32-.59c.59-.4.88-.88.88-1.47,0-.49-.19-.9-.56-1.22-.38-.32-.96-.57-1.75-.74l-2.93-.62c-1.65-.34-2.87-.92-3.66-1.74-.79-.82-1.18-1.85-1.17-3.1,0-1.06.28-1.98.87-2.76s1.4-1.38,2.45-1.81c1.05-.43,2.26-.64,3.63-.64,2.01,0,3.6.43,4.76,1.29,1.16.86,1.88,2.02,2.15,3.48Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1718.16,1269.9c-.11.03-.27.06-.49.1-.21.04-.45.06-.7.06-.34,0-.64-.05-.92-.16s-.5-.3-.67-.59c-.17-.29-.25-.7-.25-1.25v-8.88h3.39v-3.13h-3.39v-4.12h-4.05v4.12h-2.44v3.13h2.44v9.55c0,1.07.23,1.97.7,2.68.47.72,1.12,1.24,1.93,1.58.81.34,1.73.49,2.74.46.57-.01,1.06-.07,1.46-.16.4-.09.71-.17.92-.25l-.68-3.17Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1734.74,1273.23l-6.47-22.91h4.46l4.13,16.83h.21l4.41-16.83h4.06l4.42,16.85h.2l4.13-16.85h4.46l-6.47,22.91h-4.09l-4.59-16.07h-.18l-4.6,16.07h-4.09Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1763.48,1253.61c-.64,0-1.19-.21-1.66-.64s-.69-.95-.69-1.55.23-1.13.69-1.56c.46-.43,1.01-.64,1.66-.64s1.2.21,1.66.64c.46.43.69.95.69,1.56s-.23,1.12-.69,1.55c-.46.43-1.01.64-1.66.64ZM1761.45,1273.23v-17.18h4.05v17.18h-4.05Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1773.71,1263.16v10.07h-4.05v-17.18h3.87v2.92h.2c.4-.96,1.03-1.73,1.9-2.29.87-.57,1.94-.85,3.23-.85,1.19,0,2.22.25,3.1.76.88.51,1.57,1.24,2.06,2.2.49.96.73,2.13.72,3.5v10.94h-4.05v-10.31c0-1.15-.3-2.05-.89-2.7-.59-.65-1.41-.97-2.46-.97-.71,0-1.34.15-1.89.46-.55.31-.98.76-1.29,1.34s-.46,1.29-.46,2.11Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
<path
d="M1796.34,1280.03c-1.45,0-2.7-.2-3.75-.59s-1.88-.92-2.52-1.57c-.63-.66-1.07-1.38-1.32-2.18l3.65-.88c.16.34.4.67.72,1,.31.33.74.61,1.27.83.53.22,1.21.33,2.02.33,1.15,0,2.1-.28,2.85-.83s1.13-1.47,1.13-2.73v-3.26h-.2c-.21.42-.51.85-.91,1.29s-.92.81-1.58,1.11c-.65.3-1.47.45-2.46.45-1.32,0-2.51-.31-3.59-.93s-1.92-1.55-2.55-2.8c-.63-1.24-.95-2.8-.95-4.67s.32-3.48.95-4.78,1.48-2.29,2.56-2.96c1.07-.68,2.27-1.01,3.59-1.01,1.01,0,1.84.17,2.49.51.65.34,1.17.75,1.56,1.22.39.47.68.92.88,1.34h.22v-2.84h3.99v17.46c0,1.47-.35,2.68-1.05,3.65-.7.96-1.66,1.68-2.87,2.16-1.22.48-2.6.72-4.14.72ZM1796.37,1269.81c.86,0,1.59-.21,2.19-.63.6-.42,1.06-1.02,1.38-1.8s.47-1.72.47-2.82-.15-2.03-.46-2.84c-.31-.81-.76-1.44-1.36-1.9s-1.34-.68-2.21-.68-1.66.23-2.26.7c-.6.47-1.06,1.11-1.36,1.93-.31.82-.46,1.74-.46,2.78s.16,1.97.46,2.76c.31.79.77,1.4,1.38,1.83.61.44,1.36.65,2.24.65Z"
style={{
fill: "#fff",
strokeWidth: 0,
}}
/>
</g>
</g>
</svg>
</div>
</div>