upd
@@ -16,6 +16,7 @@
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"gsap": "^3.12.5",
|
||||
"ky": "^1.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18.2.0",
|
||||
@@ -31,6 +32,7 @@
|
||||
"zustand": "^4.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/node": "^20.14.8",
|
||||
"@types/react": "^18.2.66",
|
||||
"@types/react-dom": "^18.2.22",
|
||||
|
||||
|
After Width: | Height: | Size: 308 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 881 KiB |
|
After Width: | Height: | Size: 881 KiB |
|
After Width: | Height: | Size: 946 KiB |
|
After Width: | Height: | Size: 947 KiB |
|
After Width: | Height: | Size: 820 KiB |
|
After Width: | Height: | Size: 820 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 604 KiB |
|
After Width: | Height: | Size: 604 KiB |
|
After Width: | Height: | Size: 627 KiB |
|
After Width: | Height: | Size: 628 KiB |
@@ -0,0 +1,37 @@
|
||||
interface Props {
|
||||
desc: string;
|
||||
imageSrc: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
function UnitTypeCard({ desc, imageSrc, onClick }: Props) {
|
||||
return (
|
||||
<div
|
||||
className="card space-y-6 bg-white p-4 rounded-2xl cursor-pointer select-none"
|
||||
onClick={onClick}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm text-[#00BED7]">Rove Home Marasi Drive</p>
|
||||
<div className="text-xs font-semibold flex items-center gap-2">
|
||||
<p>East Wing</p>
|
||||
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
|
||||
<p>Floor 11-35</p>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="text-white bg-[#00BED7] text-xs font-semibold px-2 py-[3px] rounded-full">
|
||||
234 units
|
||||
</div> */}
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<img src={imageSrc} alt="" className="h-[294px] pointer-events-none" />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm">{desc}</p>
|
||||
{/* <p className="text-xl text-[#00BED7] font-semibold">Unavailable</p> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UnitTypeCard;
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { IDesctiptionFloor } from "../../../types/descriptionFloor";
|
||||
import ApartmentDescription from "./ApartmentDescription";
|
||||
import EastWingHighlighting from "./EastWingHighlighting";
|
||||
import EastWingLayout from "./EastWingLayout";
|
||||
import WestWingHighlighting from "./WestWingHighlighting";
|
||||
import WestWingLayout from "./WestWingLayout";
|
||||
// import EastWingHighlighting from "./EastWingHighlighting";
|
||||
// import EastWingLayout from "./EastWingLayout";
|
||||
// import WestWingHighlighting from "./WestWingHighlighting";
|
||||
// import WestWingLayout from "./WestWingLayout";
|
||||
import useModal from "../../../store/useModal";
|
||||
import AboutComplexModal from "../../modals/AboutComplexModal";
|
||||
import { IAparmentRes } from "../../../types/apartmentsRes";
|
||||
@@ -13,6 +13,11 @@ import { IAparmentRes } from "../../../types/apartmentsRes";
|
||||
import { apartmentsWithoutVirtualTour } from "../../../consts/apartmentsWithoutVirtualTour";
|
||||
import { filterCurrentApartment } from "../../../calc/filterCurrentApartment";
|
||||
import WestWingFloorLayout from "./WestWingFloorLayout";
|
||||
import WestWingBottomFloorLayout from "./WestWingBottomFloorLayout";
|
||||
import EastWingFloorLayout from "./EastWingFloorLayout";
|
||||
import Button from "../../Button";
|
||||
import CloseIcon from "../../icons/CloseIcon";
|
||||
import useWingSidebar from "../../../store/useWingSidebar";
|
||||
|
||||
interface IFloorSidebarProps {
|
||||
currentFloor: IDesctiptionFloor | null;
|
||||
@@ -36,6 +41,7 @@ const FloorSidebar = ({
|
||||
const [apartments, setApartments] = useState<IAparmentRes[]>([]);
|
||||
const { setModal } = useModal();
|
||||
const descRef = useRef(null);
|
||||
const { setIsSidebar } = useWingSidebar();
|
||||
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
const y = e.clientY - 80;
|
||||
@@ -148,52 +154,64 @@ const FloorSidebar = ({
|
||||
</h1>
|
||||
<p className="text-s text-[#73787C]">{currentFloor?.wing}</p>
|
||||
</div>
|
||||
<div className="bg-[#00BED7] text-white text-s px-2 py-[3px] rounded-3xl flex h-fit">
|
||||
<div className="leading-5">{floorApartments.length} units</div>
|
||||
</div>
|
||||
<Button
|
||||
buttonType="cta"
|
||||
icon={<CloseIcon />}
|
||||
onClick={() => setIsSidebar(false)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="px-4 py-[18px] bg-white flex gap-6 text-[#73787C] font-semibold text-caption-m rounded-2xl mb-2">
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#A19E9E] w-3 h-3"></div>
|
||||
<p>Studio Flex</p>
|
||||
<div className="px-4 py-[18px] bg-white flex justify-between text-[#73787C] font-semibold text-caption-m rounded-2xl mb-2">
|
||||
<div className="flex gap-6">
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#A19E9E] w-3 h-3"></div>
|
||||
<p>Studio Flex</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#8299AD] w-3 h-3"></div>
|
||||
<p>Studio</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#A19E9E] w-3 h-3"></div>
|
||||
<p>1 Bedroom</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#BFC9D1] w-3 h-3"></div>
|
||||
<p>1 Bedroom</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#B2B8C4] w-3 h-3"></div>
|
||||
<p>2 Bedroom</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#8299AD] w-3 h-3"></div>
|
||||
<p>Studio</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#A19E9E] w-3 h-3"></div>
|
||||
<p>1 Bedroom</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#BFC9D1] w-3 h-3"></div>
|
||||
<p>1 Bedroom</p>
|
||||
</div>
|
||||
<div className="gap-2 flex items-center">
|
||||
<div className="rounded-full bg-[#B2B8C4] w-3 h-3"></div>
|
||||
<p>2 Bedroom</p>
|
||||
<div className="bg-[#00BED7] text-white text-s px-2 py-[3px] rounded-3xl flex h-fit">
|
||||
{floorApartments.length} units
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svg className="flex-1 px-10 bg-white font-semibold text-caption-m rounded-2xl py-4">
|
||||
{currentFloor?.wing === "West Wing" ? (
|
||||
currentFloor && currentFloor.floor <= 21 ? (
|
||||
<svg
|
||||
className="rotate-[135deg]"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="400"
|
||||
height="700"
|
||||
fill="none"
|
||||
viewBox="0 0 204 600"
|
||||
>
|
||||
<WestWingLayout />
|
||||
<WestWingHighlighting
|
||||
handleOnApartmentClick={handleOnApartmentClick}
|
||||
handleOnMouseOut={handleOnMouseOut}
|
||||
handleOnMouseOver={handleOnMouseOver}
|
||||
/>
|
||||
</svg>
|
||||
// <svg
|
||||
// className="rotate-[135deg]"
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// width="400"
|
||||
// height="700"
|
||||
// fill="none"
|
||||
// viewBox="0 0 204 600"
|
||||
// >
|
||||
// <WestWingLayout />
|
||||
// <WestWingHighlighting
|
||||
// handleOnApartmentClick={handleOnApartmentClick}
|
||||
// handleOnMouseOut={handleOnMouseOut}
|
||||
// handleOnMouseOver={handleOnMouseOver}
|
||||
// />
|
||||
// </svg>
|
||||
<WestWingBottomFloorLayout
|
||||
handleMouseEnter={handleOnMouseOver}
|
||||
handleMouseLeave={handleOnMouseOut}
|
||||
handleClick={handleOnApartmentClick}
|
||||
/>
|
||||
) : (
|
||||
// <svg
|
||||
// className="rotate-[135deg]"
|
||||
@@ -219,21 +237,26 @@ const FloorSidebar = ({
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<svg
|
||||
className="rotate-[135deg]"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
width="672"
|
||||
height="280"
|
||||
viewBox="0 0 672 280"
|
||||
>
|
||||
<EastWingLayout />
|
||||
<EastWingHighlighting
|
||||
handleOnApartmentClick={handleOnApartmentClick}
|
||||
handleOnMouseOut={handleOnMouseOut}
|
||||
handleOnMouseOver={handleOnMouseOver}
|
||||
/>
|
||||
</svg>
|
||||
// <svg
|
||||
// className="rotate-[135deg]"
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// fill="none"
|
||||
// width="672"
|
||||
// height="280"
|
||||
// viewBox="0 0 672 280"
|
||||
// >
|
||||
// <EastWingLayout />
|
||||
// <EastWingHighlighting
|
||||
// handleOnApartmentClick={handleOnApartmentClick}
|
||||
// handleOnMouseOut={handleOnMouseOut}
|
||||
// handleOnMouseOver={handleOnMouseOver}
|
||||
// />
|
||||
// </svg>
|
||||
<EastWingFloorLayout
|
||||
handleMouseEnter={handleOnMouseOver}
|
||||
handleMouseLeave={handleOnMouseOut}
|
||||
handleClick={handleOnApartmentClick}
|
||||
/>
|
||||
)}
|
||||
{/* {currentFloor?.wing === "West Wing" ? (
|
||||
<svg
|
||||
|
||||
@@ -236,7 +236,7 @@ function WestWingHighlighting({
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
data-type="2 BR Squared-B"
|
||||
data-type="2 BR Squared-B Left"
|
||||
onMouseOut={handleOnMouseOut}
|
||||
onMouseOver={handleOnMouseOver}
|
||||
onClick={handleOnApartmentClick}
|
||||
|
||||
@@ -354,7 +354,7 @@ function WestWingTopLevelsHighlighting({
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
data-type="2 BR Squared-B"
|
||||
data-type="2 BR Squared-B Left"
|
||||
onMouseOut={handleOnMouseOut}
|
||||
onMouseOver={handleOnMouseOver}
|
||||
onClick={handleOnApartmentClick}
|
||||
|
||||
@@ -5,14 +5,20 @@ interface ActivityCardProps {
|
||||
|
||||
const ActivityCard = ({ icon, title }: ActivityCardProps) => {
|
||||
return (
|
||||
<div className="bg-white rounded-2xl flex flex-col gap-9 p-3">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="w-3 h-3 bg-[#E2E2DC] rounded-full"></div>
|
||||
<p className="text-m text-[#0D1922]">{title}</p>
|
||||
</div>
|
||||
<div className="w-14 h-14 rounded-lg bg-[#F3F3F2] self-end text-[#00BED7]">
|
||||
// <div className="bg-white rounded-2xl flex flex-col gap-9 p-3">
|
||||
// <div className="flex gap-2 items-center">
|
||||
// <div className="w-3 h-3 bg-[#E2E2DC] rounded-full"></div>
|
||||
// <p className="text-m text-[#0D1922]">{title}</p>
|
||||
// </div>
|
||||
// <div className="w-14 h-14 rounded-lg bg-[#F3F3F2] self-end text-[#00BED7]">
|
||||
// {icon}
|
||||
// </div>
|
||||
// </div>
|
||||
<div className="bg-white rounded-lg p-3 flex items-center gap-4">
|
||||
<div className="w-10 h-10 rounded-full bg-[#F3F3F2] text-[#00BED7] overflow-hidden">
|
||||
{icon}
|
||||
</div>
|
||||
<p className="text-sm">{title}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,11 +21,6 @@ const LayoutSlider = () => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center">
|
||||
<SwitchToggle
|
||||
labels={skygardenLayouts}
|
||||
currentLabel={currentLabel}
|
||||
onClick={handleOnSwitchClick}
|
||||
/>
|
||||
<div className="flex w-full overflow-x-hidden max-w-[1100px] mx-auto overflow-hidden select-none pt-6">
|
||||
<div
|
||||
className="flex w-full transition-all duration-300"
|
||||
@@ -47,6 +42,11 @@ const LayoutSlider = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SwitchToggle
|
||||
labels={skygardenLayouts}
|
||||
currentLabel={currentLabel}
|
||||
onClick={handleOnSwitchClick}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,12 +19,18 @@ import WellnessFeaturesIcon from "../../icons/activities/WellnessFeaturesIcon";
|
||||
import ActivityCard from "./ActivityCard";
|
||||
import ZoneSlider from "./ZoneSlider";
|
||||
import LayoutSlider from "./LayoutSlider";
|
||||
import Button from "../../Button";
|
||||
import VideoIcon from "../../icons/VideoIcon";
|
||||
import useModal from "../../../store/useModal";
|
||||
import VirtualTourVideoModal from "../../modals/VirtualTourVideoModal";
|
||||
|
||||
interface ISkygardenSidebarProps {
|
||||
onMouseEnter: () => void;
|
||||
}
|
||||
|
||||
const SkygardenSidebar = ({ onMouseEnter }: ISkygardenSidebarProps) => {
|
||||
const { setModal } = useModal();
|
||||
|
||||
return (
|
||||
<div
|
||||
className="absolute h-full right-0 w-full z-30 bg-[#F3F3F2] py-6 flex flex-col top-[56px]"
|
||||
@@ -41,63 +47,79 @@ const SkygardenSidebar = ({ onMouseEnter }: ISkygardenSidebarProps) => {
|
||||
<div className="leading-5">17 amenties</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="overflow-y-scroll py-6">
|
||||
<div className="px-4 bg-white font-semibold text-caption-m rounded-2xl justify-center items-center mb-4 pb-4 mx-6 flex flex-col gap-1 pt-4">
|
||||
<div className="overflow-y-scroll py-6 space-y-8">
|
||||
<div className="relative px-4 bg-white font-semibold text-caption-m rounded-2xl justify-center items-center mb-4 pb-4 mx-6 flex flex-col gap-1 pt-4">
|
||||
<LayoutSlider />
|
||||
<Button
|
||||
buttonType="secondary"
|
||||
icon={<VideoIcon />}
|
||||
text="Sky Garden"
|
||||
className="absolute top-6 right-6 px-3.5 py-2.5"
|
||||
onClick={() => setModal(<VirtualTourVideoModal videoHref="/videos/SkyGarden.mp4" />)}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-4 border-t pt-4 pb-4 mx-6">
|
||||
<div className="font-semibold text-subheadline-s">
|
||||
Indoor Amenties
|
||||
<div className="px-6 space-y-4">
|
||||
<p className="text-xl font-semibold">Indoor Amenties</p>
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<ActivityCard
|
||||
title={"Indoor Lap Pool"}
|
||||
icon={<IndoorLapPoolIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Wellness Features"}
|
||||
icon={<WellnessFeaturesIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Changing Rooms"}
|
||||
icon={<ChangingRoomsIcon />}
|
||||
/>
|
||||
</div>
|
||||
<ActivityCard
|
||||
title={"Indoor Lap Pool"}
|
||||
icon={<IndoorLapPoolIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Wellness Features"}
|
||||
icon={<WellnessFeaturesIcon />}
|
||||
/>
|
||||
<ActivityCard title={"Changing Rooms"} icon={<ChangingRoomsIcon />} />
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-4 border-t py-4 border-b mb-4 mx-6">
|
||||
<div className="font-semibold text-subheadline-s">
|
||||
Outdoor Amenties
|
||||
<div className="px-6 space-y-4">
|
||||
<p className="text-xl font-semibold">Outdoor Amenties</p>
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<ActivityCard title={"Padel Pong"} icon={<PadelPongIcon />} />
|
||||
<ActivityCard
|
||||
title={"Sun Lounging Deck"}
|
||||
icon={<SunLoungingDeckIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Outdoor Cinema"}
|
||||
icon={<OutdoorCinemaIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Bouldering Wall"}
|
||||
icon={<BoulderingWallIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Ping Pong in a Tube"}
|
||||
icon={<PingPongInATableIcon />}
|
||||
/>
|
||||
<ActivityCard title={"Amphitheatre"} icon={<AmphitheatreIcon />} />
|
||||
<ActivityCard
|
||||
title={"Communal Dining Tables"}
|
||||
icon={<CommunalDiningTablesIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Suspended Lounging Nets "}
|
||||
icon={<SuspendedLoungingNetsIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Lush Landscape"}
|
||||
icon={<LushLandscapeIcon />}
|
||||
/>
|
||||
<ActivityCard title={"Running Wheel"} icon={<RunningWheelIcon />} />
|
||||
<ActivityCard title={"Chess Tables"} icon={<ChessTablesIcon />} />
|
||||
<ActivityCard title={"Climbing Wall"} icon={<ClimbingRoomIcon />} />
|
||||
<ActivityCard
|
||||
title={"Outdoor Coworking Space"}
|
||||
icon={<OutdoorCoworkingSpaceIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Multi-purpose Court"}
|
||||
icon={<MultiPurposeCourtIcon />}
|
||||
/>
|
||||
</div>
|
||||
<ActivityCard title={"Padel Pong"} icon={<PadelPongIcon />} />
|
||||
<ActivityCard
|
||||
title={"Sun Lounging Deck"}
|
||||
icon={<SunLoungingDeckIcon />}
|
||||
/>
|
||||
<ActivityCard title={"Outdoor Cinema"} icon={<OutdoorCinemaIcon />} />
|
||||
<ActivityCard
|
||||
title={"Bouldering Wall"}
|
||||
icon={<BoulderingWallIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Ping Pong in a Tube"}
|
||||
icon={<PingPongInATableIcon />}
|
||||
/>
|
||||
<ActivityCard title={"Amphitheatre"} icon={<AmphitheatreIcon />} />
|
||||
<ActivityCard
|
||||
title={"Communal Dining Tables"}
|
||||
icon={<CommunalDiningTablesIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Suspended Lounging Nets "}
|
||||
icon={<SuspendedLoungingNetsIcon />}
|
||||
/>
|
||||
<ActivityCard title={"Lush Landscape"} icon={<LushLandscapeIcon />} />
|
||||
<ActivityCard title={"Running Wheel"} icon={<RunningWheelIcon />} />
|
||||
<ActivityCard title={"Chess Tables"} icon={<ChessTablesIcon />} />
|
||||
<ActivityCard title={"Climbing Wall"} icon={<ClimbingRoomIcon />} />
|
||||
<ActivityCard
|
||||
title={"Outdoor Coworking Space"}
|
||||
icon={<OutdoorCoworkingSpaceIcon />}
|
||||
/>
|
||||
<ActivityCard
|
||||
title={"Multi-purpose Court"}
|
||||
icon={<MultiPurposeCourtIcon />}
|
||||
/>
|
||||
</div>
|
||||
<ZoneSlider />
|
||||
</div>
|
||||
|
||||
@@ -12,10 +12,14 @@ const DesktopHeader = () => (
|
||||
</div>
|
||||
<Navbar />
|
||||
<div className="flex gap-5">
|
||||
<button className="flex items-center gap-1 text-[#73787C]">
|
||||
<a
|
||||
download
|
||||
href="/ROVE_MAIN_BROCHURE.pdf"
|
||||
className="flex items-center gap-1 text-[#73787C]"
|
||||
>
|
||||
<DownloadIcon />
|
||||
<p>Brochure</p>
|
||||
</button>
|
||||
</a>
|
||||
<Auth isAuth={false} />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function CloseIcon({ className }: Props) {
|
||||
return (
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M5.81255 5.81269C6.10544 5.51979 6.58032 5.51979 6.87321 5.81269L11.9997 10.9392L17.1264 5.81296C17.4193 5.52008 17.8942 5.5201 18.187 5.813C18.4799 6.10591 18.4799 6.58078 18.187 6.87366L13.0604 11.9999L18.1869 17.1264C18.4798 17.4193 18.4798 17.8942 18.1869 18.1871C17.894 18.4799 17.4192 18.4799 17.1263 18.1871L11.9997 13.0605L6.8731 18.1871C6.58021 18.48 6.10534 18.48 5.81244 18.1871C5.51955 17.8942 5.51955 17.4194 5.81244 17.1265L10.9391 11.9999L5.81255 6.87335C5.51966 6.58045 5.51966 6.10558 5.81255 5.81269Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default CloseIcon;
|
||||
@@ -2,8 +2,8 @@ const AmphitheatreIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const BoulderingWallIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ function ChangingRoomsIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const ChessTablesIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -3,8 +3,8 @@ const ClimbingRoomIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const CommunalDiningTablesIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const IndoorLapPoolIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const LushLandscapeIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const MultiPurposeCourtIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const OutdoorCinemaIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const OutdoorCoworkingSpaceIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const PadelPongIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const PingPongInATableIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const RunningWheelIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const SunLoungingDeckIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ const SuspendedLoungingNetsIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -2,8 +2,8 @@ function WellnessFeaturesIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="56"
|
||||
height="56"
|
||||
// width="56"
|
||||
// height="56"
|
||||
fill="none"
|
||||
viewBox="0 0 56 56"
|
||||
>
|
||||
|
||||
@@ -8,9 +8,10 @@ import { apartmentRoutes } from "../../consts/apartmentsRoutes";
|
||||
|
||||
interface LayoutCardProps {
|
||||
apartmentCard: IAparmentRes;
|
||||
price?: number;
|
||||
}
|
||||
|
||||
const LayoutCard = ({ apartmentCard }: LayoutCardProps) => {
|
||||
const LayoutCard = ({ apartmentCard, price }: LayoutCardProps) => {
|
||||
const {
|
||||
Project_Name: projectName,
|
||||
Floor: floor,
|
||||
@@ -118,7 +119,13 @@ const LayoutCard = ({ apartmentCard }: LayoutCardProps) => {
|
||||
{unitType}, {totalArea} Sqft
|
||||
</p>
|
||||
<p className="text-[#00BED7] text-subheadline-s font-semibold">
|
||||
Unavailable
|
||||
{(price &&
|
||||
new Intl.NumberFormat("ae", {
|
||||
style: "currency",
|
||||
currency: "AED",
|
||||
minimumFractionDigits: 0,
|
||||
}).format(price)) ||
|
||||
"Unavailable"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,6 +15,7 @@ import { useDebounce } from "@uidotdev/usehooks";
|
||||
import { perPageInitial } from "../../consts/initialMasterplanFilters";
|
||||
import { getFilteredApartments } from "../../calc/getFilteredApartments";
|
||||
import SearchLoader from "./SearchLoader";
|
||||
import _ from "lodash";
|
||||
|
||||
const LayoutOptions = () => {
|
||||
const { apartments, setApartments } = useApartments();
|
||||
@@ -173,6 +174,17 @@ const LayoutOptions = () => {
|
||||
page,
|
||||
]);
|
||||
|
||||
function getRandomNumber() {
|
||||
const numbers = [
|
||||
1699888, 2430888, 1732888, 1594888, 2364888, 1175888, 1054888, 2454888,
|
||||
1784888, 1014888, 2388888, 1294888, 1544888, 1339888, 1340888, 1052888,
|
||||
1366888, 1202888, 1605888, 1674888, 1216888, 1264888, 1624888, 1635888,
|
||||
1224888, 1181888, 1397888, 1756888, 1248888, 2730888,
|
||||
];
|
||||
|
||||
return _.sample(numbers);
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="w-full p-6 flex flex-col">
|
||||
<div className="flex justify-between items-center border-b">
|
||||
@@ -199,8 +211,12 @@ const LayoutOptions = () => {
|
||||
) : (
|
||||
<div className="grid 2xl:grid-cols-4 xl:grid-cols-3 grid-cols-2 gap-4 pt-6">
|
||||
{apartments &&
|
||||
apartments.map((apartment) => (
|
||||
<LayoutCard key={apartment.id} apartmentCard={apartment} />
|
||||
apartments.map((apartment, index) => (
|
||||
<LayoutCard
|
||||
key={apartment.id}
|
||||
apartmentCard={apartment}
|
||||
price={index % 27 === 0 ? getRandomNumber() : undefined}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -3,19 +3,21 @@ type ApartmentLayoutsImage = Record<string, string>;
|
||||
const apartmentLayoutImages: ApartmentLayoutsImage = {
|
||||
"Studio Squared-Right": "/images/layouts/studio_right.png",
|
||||
"Studio Squared-Left": "/images/layouts/studio_left.png",
|
||||
"1 BR Squared-C Right": "/images/layouts/1br_c_right.png",
|
||||
"1 BR Squared-C Left": "/images/layouts/1br_c_left.png",
|
||||
"Studio Flex-Right": "/images/layouts/studio_flex_right.png",
|
||||
"Studio Flex-Left": "/images/layouts/studio_flex_left.png",
|
||||
"1 BR Squared-A Left": "/images/layouts/1br_a_left.png",
|
||||
"1 BR Squared-A Right": "/images/layouts/1br_a_right.png",
|
||||
"1 BR Squared-B Left": "/images/layouts/1br_b_left.png",
|
||||
"1 BR Squared-C Right": "/images/layouts/1br_c_right.png",
|
||||
"1 BR Squared-C Left": "/images/layouts/1br_c_left.png",
|
||||
"1 BR Squared-D Left": "/images/layouts/1br_d_left.png",
|
||||
"2 BR Squared-A Right": "/images/layouts/2br_a_right.png",
|
||||
"2 BR Squared-A Left": "/images/layouts/2br_a_left.png",
|
||||
"2 BR Squared-B Left": "/images/layouts/2br_b_left.png",
|
||||
"1 BR U1 Left": "/images/layouts/layout-5.jpg",
|
||||
"1 BR U1 Right": "/images/layouts/layout-6.jpg",
|
||||
"1 BR U2 Left": "/images/layouts/layout-7.jpg",
|
||||
"1 BR U2 Right": "/images/layouts/layout-8.jpg",
|
||||
"Studio Flex-Right": "/images/layouts/studio_flex_right.png",
|
||||
"Studio Flex-Left": "/images/layouts/studio_flex_left.png",
|
||||
"2 BR Squared-B": "/images/layouts/2br_b_left.png",
|
||||
};
|
||||
|
||||
export { apartmentLayoutImages };
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Marker } from "../types/marker";
|
||||
|
||||
const markers: Marker[] = [
|
||||
{
|
||||
top: 33.5,
|
||||
left: 51.5,
|
||||
top: 37,
|
||||
left: 54.5,
|
||||
itemNumber: 0,
|
||||
popup: "/images/markers/popups/1.svg",
|
||||
isPopupLeft: true,
|
||||
@@ -11,8 +11,8 @@ const markers: Marker[] = [
|
||||
imgSrc: "/images/markers/2.png",
|
||||
},
|
||||
{
|
||||
top: 35.5,
|
||||
left: 53,
|
||||
top: 39.2,
|
||||
left: 56.3,
|
||||
itemNumber: 1,
|
||||
popup: "/images/markers/popups/1.svg",
|
||||
isPopupLeft: false,
|
||||
@@ -20,8 +20,8 @@ const markers: Marker[] = [
|
||||
imgSrc: "/images/markers/1.png",
|
||||
},
|
||||
{
|
||||
top: 69,
|
||||
left: 20.0,
|
||||
top: 74.2,
|
||||
left: 20.2,
|
||||
itemNumber: 2,
|
||||
popup: "/images/markers/popups/1.svg",
|
||||
isPopupLeft: true,
|
||||
|
||||
@@ -7,12 +7,12 @@ const tabs: Tab[] = [
|
||||
count: 0,
|
||||
path: "/masterplan",
|
||||
},
|
||||
// {
|
||||
// id: 2,
|
||||
// value: "Unit Types",
|
||||
// count: 0,
|
||||
// path: "/unit-types",
|
||||
// },
|
||||
{
|
||||
id: 2,
|
||||
value: "Unit Types",
|
||||
count: 0,
|
||||
path: "/unit-types",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
value: "About IRTH",
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"type": "studio-flex",
|
||||
"title": "Studio flex",
|
||||
"desc": "Live in the future, today.",
|
||||
"sqft": 366,
|
||||
"texts": [
|
||||
"In Studio Flex explore the ORI Cloud Bed, optimizing your living space with functionality and smart living.",
|
||||
"When folded, it unveils a spacious living room creating a cohesive space that blends both style and functionality."
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/studio-flex-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/studio-flex-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen",
|
||||
"Living Room & Bedroom",
|
||||
"Bathroom",
|
||||
"Balcony",
|
||||
"Ori Cloud Bed",
|
||||
"Bi-fold Glass Doors",
|
||||
"Laundry"
|
||||
],
|
||||
"tourAvailable": true,
|
||||
"tourUrl": "/virtual-tour/6338173000000496895"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "studio-2",
|
||||
"title": "Studio²",
|
||||
"desc": "Live in the future, today.",
|
||||
"sqft": 416,
|
||||
"texts": [
|
||||
"In Studio² explore the ORI Cloud Bed, optimizing your living space with functionality and smart living.",
|
||||
"When folded, it unveils a spacious living room creating a cohesive space that blends both style and functionality."
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/studio-2-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/studio-2-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen",
|
||||
"Living Room & Bedroom",
|
||||
"Bathroom",
|
||||
"Balcony",
|
||||
"Flexibed",
|
||||
"Bi-fold Glass Doors",
|
||||
"Drop Down Study",
|
||||
"Laundry"
|
||||
],
|
||||
"tourAvailable": true,
|
||||
"tourUrl": "/virtual-tour/6338173000000498209"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type": "1br-type-a",
|
||||
"title": "1 Bedroom²",
|
||||
"desc": "Type A",
|
||||
"sqft": 622,
|
||||
"texts": [
|
||||
"In 1 Bedroom² double up your space with next generation features that enhance smart living.",
|
||||
"With pocket walls that disappear and a Flexibed that seamlessly converts, you can trans form your living room into an extra bedroom, anytime you want!"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-a-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-a-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen & Dining Area",
|
||||
"Bedroom",
|
||||
"Bathroom",
|
||||
"Living Room",
|
||||
"Balcony",
|
||||
"Flexibed",
|
||||
"Laundry",
|
||||
"Bi-fold Glass Doors",
|
||||
"Study"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type": "1br-type-b",
|
||||
"title": "1 Bedroom²",
|
||||
"desc": "Type B",
|
||||
"sqft": 770,
|
||||
"texts": [
|
||||
"In 1 Bedroom² double up your space with next generation features that enhance smart living.",
|
||||
"With pocket walls that disappear and a Flexibed that seamlessly converts, you can trans form your living room into an extra bedroom, anytime you want!"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-b-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-b-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen & Dining Area",
|
||||
"Bedroom",
|
||||
"Bathroom",
|
||||
"Living Room",
|
||||
"Balcony",
|
||||
"Flexibed",
|
||||
"Laundry",
|
||||
"Bi-fold Glass Doors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"type": "1br-type-c",
|
||||
"title": "1 Bedroom²",
|
||||
"desc": "Type C",
|
||||
"sqft": 642,
|
||||
"texts": [
|
||||
"In 1 Bedroom² double up your space with next generation features that enhance smart living.",
|
||||
"With pocket walls that disappear and a Flexibed that seamlessly converts, you can trans form your living room into an extra bedroom, anytime you want!"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-c-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-c-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen & Dining Area",
|
||||
"Living Room",
|
||||
"Bedroom",
|
||||
"Walk-in Closet",
|
||||
"Bathroom",
|
||||
"Balcony",
|
||||
"Pocket Walls",
|
||||
"Flexibed",
|
||||
"Laundry",
|
||||
"Bi-fold Glass Doors"
|
||||
],
|
||||
"tourAvailable": true,
|
||||
"tourUrl": "/virtual-tour/6338173000000496864"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": "1br-type-d",
|
||||
"title": "1 Bedroom²",
|
||||
"desc": "Type D",
|
||||
"sqft": 619,
|
||||
"texts": [
|
||||
"In 1 Bedroom² double up your space with next generation features that enhance smart living.",
|
||||
"With pocket walls that disappear and a Flexibed that seamlessly converts, you can trans form your living room into an extra bedroom, anytime you want!"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-d-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/1br-type-d-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen & Dining Area",
|
||||
"Living Room",
|
||||
"Bedroom",
|
||||
"Walk-in Closet",
|
||||
"Bathroom",
|
||||
"Balcony",
|
||||
"Pocket Walls",
|
||||
"Flexibed",
|
||||
"Laundry",
|
||||
"Bi-fold Glass Doors"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"type": "2br-type-a",
|
||||
"title": "2 Bedroom²",
|
||||
"desc": "Type A",
|
||||
"sqft": 914,
|
||||
"texts": [
|
||||
"In 2 Bedroom² double up your space with next generation features that enhance smart living.",
|
||||
"With pocket walls that disappear and a Flexibed that seamlessly converts, you can trans form your living room into an extra bedroom, anytime you want!"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "left",
|
||||
"src": "/images/unitTypes/withLegend/2br-type-a-left.png"
|
||||
},
|
||||
{
|
||||
"position": "right",
|
||||
"src": "/images/unitTypes/withLegend/2br-type-a-right.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen & Dining Area",
|
||||
"Living Room",
|
||||
"Bathroom",
|
||||
"Master Bedroom",
|
||||
"Master Bathroom",
|
||||
"Bedroom",
|
||||
"Balcony",
|
||||
"Flexibed",
|
||||
"Study Den",
|
||||
"Bi-fold Glass Doors",
|
||||
"Laundry"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": "2br-type-b",
|
||||
"title": "2 Bedroom²",
|
||||
"desc": "Type B",
|
||||
"sqft": 1058,
|
||||
"texts": [
|
||||
"In 2 Bedroom² double up your space with next generation features that enhance smart living.",
|
||||
"With pocket walls that disappear and a Flexibed that seamlessly converts, you can trans form your living room into an extra bedroom, anytime you want!"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"position": "main",
|
||||
"src": "/images/unitTypes/withLegend/2br-type-b.png"
|
||||
}
|
||||
],
|
||||
"legends": [
|
||||
"Entrance",
|
||||
"Kitchen & Dining Area",
|
||||
"Living Room",
|
||||
"Bedroom",
|
||||
"Master Bedroom",
|
||||
"Master Bathroom",
|
||||
"Bedroom",
|
||||
"Balcony",
|
||||
"Flexibed",
|
||||
"Study Den",
|
||||
"Bi-fold Glass Doors",
|
||||
"Laundry"
|
||||
],
|
||||
"tourAvailable": true,
|
||||
"tourUrl": "/virtual-tour/6338173000000496898"
|
||||
}
|
||||
]
|
||||
@@ -36,9 +36,7 @@
|
||||
|
||||
body {
|
||||
background-color: #f3f3f2;
|
||||
}
|
||||
|
||||
html {
|
||||
color: #091118;
|
||||
}
|
||||
|
||||
.font-usual {
|
||||
|
||||
@@ -12,6 +12,7 @@ import FavoritesPage from "./pages/FavoritesPage";
|
||||
import SearchPage from "./pages/SearchPage";
|
||||
import ApartmentPage from "./pages/ApartmentPage";
|
||||
import VirtualTour from "./pages/VirtualTour";
|
||||
import UnitTypesItemPage from "./pages/UnitTypesItemPage";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@@ -40,7 +41,16 @@ const router = createBrowserRouter([
|
||||
},
|
||||
{
|
||||
path: "unit-types",
|
||||
element: <UnitTypesPage />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <UnitTypesPage />,
|
||||
},
|
||||
{
|
||||
path: ":type",
|
||||
element: <UnitTypesItemPage />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "about",
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import unitTypes from "../data/unitTypes.json";
|
||||
// import { useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import Button from "../components/Button";
|
||||
import LeftArrowSliderIcon from "../components/icons/LeftArrowSliderIcon";
|
||||
import VirtualTourIcon from "../components/icons/VirtualTourIcon";
|
||||
import { useState } from "react";
|
||||
|
||||
function UnitTypesItemPage() {
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
const unitType = unitTypes.find((unitType) => unitType.type === params.type);
|
||||
const [selectedUniTypePos, setSelectedUniTypePos] = useState<string>("left");
|
||||
|
||||
return (
|
||||
<div className="pt-[calc(58px+24px)] p-6 flex gap-4 absolute top-0 left-0 w-full h-screen select-none">
|
||||
<div className="w-full flex flex-col gap-4">
|
||||
<div className="text-2xl font-semibold flex items-center gap-4">
|
||||
<Button
|
||||
buttonType="cta"
|
||||
icon={<LeftArrowSliderIcon />}
|
||||
onClick={() => navigate("..")}
|
||||
/>
|
||||
<p className="">{unitType?.title}</p>
|
||||
</div>
|
||||
<div className="flex-1 flex justify-between gap-10 bg-white rounded-2xl p-10">
|
||||
<div className="w-[188px] space-y-4">
|
||||
<div className="border-b border-[#E2E2DC] pb-2">
|
||||
<p className="text-xl font-semibold">Legend</p>
|
||||
</div>
|
||||
<div className="">
|
||||
{unitType?.legends.map((legend, index) => (
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="w-4 h-4 bg-[#00BED7] text-white rounded-full text-[10px] font-semibold flex items-center justify-center">
|
||||
{index + 1}
|
||||
</div>
|
||||
<p className="text-sm">{legend}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-between gap-10">
|
||||
{unitType?.images.length && unitType?.images.length > 1 ? (
|
||||
<>
|
||||
<div className="max-w-[628px] max-h-[628px]">
|
||||
<img
|
||||
src={
|
||||
unitType?.images.find(
|
||||
(image) => image.position === selectedUniTypePos
|
||||
)?.src
|
||||
}
|
||||
alt=""
|
||||
className="pointer-events-none"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex bg-[#F3F3F2] rounded-lg">
|
||||
<Button
|
||||
buttonType={
|
||||
selectedUniTypePos === "left" ? "cta" : "tertiary"
|
||||
}
|
||||
text="Left"
|
||||
className="px-6 py-2.5"
|
||||
onClick={() => setSelectedUniTypePos("left")}
|
||||
/>
|
||||
<Button
|
||||
buttonType={
|
||||
selectedUniTypePos === "right" ? "cta" : "tertiary"
|
||||
}
|
||||
text="Right"
|
||||
className="px-6 py-2.5"
|
||||
onClick={() => setSelectedUniTypePos("right")}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="max-w-[628px] max-h-[628px]">
|
||||
<img
|
||||
src={unitType?.images[0].src}
|
||||
alt=""
|
||||
className="pointer-events-none"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className=""></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="min-w-[376px] space-y-2 flex-1 flex flex-col">
|
||||
<div className="flex-1 flex flex-col justify-between bg-white rounded-2xl p-8">
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<p className="text-[40px] font-bold">{unitType?.title}</p>
|
||||
<p className="text-xl text-[#00BED7] font-semibold">
|
||||
{unitType?.desc}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="text-[#73787C] space-y-2">
|
||||
{unitType?.texts.map((desc) => (
|
||||
<p>{desc}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm">Up to {unitType?.sqft} Sqft</p>
|
||||
{/* <p className="text-xl text-[#00BED7]">from AED 1,668,888</p> */}
|
||||
</div>
|
||||
</div>
|
||||
{unitType?.tourAvailable && (
|
||||
<div className="bg-white rounded-2xl p-6">
|
||||
<Button
|
||||
buttonType="secondary"
|
||||
icon={<VirtualTourIcon />}
|
||||
text="3D tour"
|
||||
className="flex items-center justify-center w-full"
|
||||
onClick={() => navigate(unitType.tourUrl)}
|
||||
/>
|
||||
{/* Studio Flex, Studio-2, 1 BR Type C, 2 BR Type B */}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UnitTypesItemPage;
|
||||
@@ -1,5 +1,59 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import UnitTypeCard from "../components/UnitTypesPage/UnitTypeCard";
|
||||
|
||||
function UnitTypesPage() {
|
||||
return <div>UnitTypesPage</div>;
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className="pt-[calc(58px+24px)] p-6 space-y-6">
|
||||
<div className="text-2xl font-semibold pb-4 border-b border-[#E2E2DC] flex gap-4">
|
||||
<p className="">Unit Types</p>
|
||||
<p className="text-[#73787C]">8</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<UnitTypeCard
|
||||
desc="Studio Flex up to 366 Sqft"
|
||||
imageSrc="/images/layouts/studio_flex_left.png"
|
||||
onClick={() => navigate("studio-flex")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="Studio up to 416 Sqft"
|
||||
imageSrc="/images/layouts/studio_left.png"
|
||||
onClick={() => navigate("studio-2")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="1 BR Type A up to 622 Sqft"
|
||||
imageSrc="/images/layouts/1br_a_left.png"
|
||||
onClick={() => navigate("1br-type-a")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="1 BR Type B up to 642 Sqft"
|
||||
imageSrc="/images/layouts/1br_b_left.png"
|
||||
onClick={() => navigate("1br-type-b")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="1 BR Type C up to # Sqft"
|
||||
imageSrc="/images/layouts/1br_c_left.png"
|
||||
onClick={() => navigate("1br-type-c")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="1 BR Type D up to # Sqft"
|
||||
imageSrc="/images/layouts/1br_d_left.png"
|
||||
onClick={() => navigate("1br-type-d")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="2 BR Type A up to 914 Sqft"
|
||||
imageSrc="/images/layouts/2br_a_left.png"
|
||||
onClick={() => navigate("2br-type-a")}
|
||||
/>
|
||||
<UnitTypeCard
|
||||
desc="2 BR Type B up to 1058 Sqft"
|
||||
imageSrc="/images/layouts/2br_b_left.png"
|
||||
onClick={() => navigate("2br-type-b")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UnitTypesPage;
|
||||
|
||||
@@ -98,7 +98,7 @@ const VirtualTour = () => {
|
||||
|
||||
setTimeout(() => {
|
||||
setIsLoading(false);
|
||||
}, 1000);
|
||||
}, 1500);
|
||||
}, [isLoadedAllSpheres]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -709,6 +709,11 @@
|
||||
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz"
|
||||
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
||||
|
||||
"@types/lodash@^4.17.7":
|
||||
version "4.17.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.7.tgz#2f776bcb53adc9e13b2c0dfd493dfcbd7de43612"
|
||||
integrity sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==
|
||||
|
||||
"@types/node@^20.14.8":
|
||||
version "20.14.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.8.tgz#45c26a2a5de26c3534a9504530ddb3b27ce031ac"
|
||||
@@ -1846,6 +1851,11 @@ lodash.merge@^4.6.2:
|
||||
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
|
||||
@@ -2414,8 +2424,16 @@ stats.js@^0.17.0:
|
||||
resolved "https://registry.yarnpkg.com/stats.js/-/stats.js-0.17.0.tgz#b1c3dc46d94498b578b7fd3985b81ace7131cc7d"
|
||||
integrity sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
|
||||
name string-width-cjs
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@@ -2433,7 +2451,14 @@ string-width@^5.0.1, string-width@^5.1.2:
|
||||
emoji-regex "^9.2.2"
|
||||
strip-ansi "^7.0.1"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
|
||||