This commit is contained in:
2025-05-23 17:14:43 +05:00
11 changed files with 232 additions and 273 deletions
+1
View File
@@ -15,6 +15,7 @@ function FloorPopup({ title, position }: FloorMarkerProps) {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.1 }}
style={{ top: position[1], left: position[0] }}
className="absolute z-100 2xl:rounded-[1.111vw] 2xl:p-[1.111vw] p-4 rounded-2xl flex flex-col 2xl:gap-[1.111vw] bg-white transition-opacity duration-300 -translate-x-[calc(100%+1.25vw)] -translate-y-1/2 2xl:w-[17.222vw] md:max-2xl:w-70 w-screen"
>
+15 -1
View File
@@ -1,4 +1,4 @@
import { useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { markers } from "../data/markers";
import { floorsMasks } from "../data/masks";
import Compass from "./Compass";
@@ -10,6 +10,8 @@ import PrivacyPolicyButton from "./PrivacyPolicyButton";
import Button from "./ui/Button";
import { useNavigate } from "react-router";
import FloorPopup from "./FloorPopup";
import { useQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
function FloorSelect({ complexName }: { complexName: string }) {
const navigate = useNavigate();
@@ -37,6 +39,18 @@ function FloorSelect({ complexName }: { complexName: string }) {
}
}
const { data } = useQuery({
queryKey: ["floors-data", complexName],
queryFn: () =>
api
.get(`units/get-floors-data/${complexName}`)
.json<({ floor: number } & Record<string, number>)[]>(),
});
useEffect(() => {
console.log(data);
}, [data]);
return (
<div
className="overflow-hidden h-full w-full relative"
+1 -1
View File
@@ -36,7 +36,7 @@ function Header() {
return (
<>
<header className="sticky top-0 left-0 w-full h-14 md:max-2xl:h-16 2xl:h-[7.5vh] flex items-center justify-center bg-white ring ring-[#E2E2DC] z-2">
<header className="sticky top-0 left-0 w-full h-14 md:max-2xl:h-16 2xl:h-[max(7.5vh,4.444vw)] flex items-center justify-center bg-white ring ring-[#E2E2DC] z-2">
<div className="flex 2xl:gap-[1.111vw] gap-4 flex-1">
<div
className="2xl:px-[2.222vw] 2xl:py-[1.111vw] md:max-2xl:px-6 max-md:px-4 py-4 cursor-pointer"
+2 -2
View File
@@ -16,7 +16,7 @@ import { getWeather } from "../api/weather";
import { isMobile } from "react-device-detect";
import useWindowSize from "../hooks/useWindowSize";
import TouchIcon from "./icons/map/TouchIcon";
import NewSelectedComplexCard from "./NewSelectedComplexCard";
import SelectedComplexCard from "./SelectedComplexCard";
interface Position {
x: number;
@@ -700,7 +700,7 @@ function Map({ maxZoom = 1 }: MapProps) {
<Compass />
<AnimatePresence>
{isMobile && hoveredMarker && (
<NewSelectedComplexCard
<SelectedComplexCard
onClose={() => setHoveredMarker(null)}
marker={hoveredMarker}
/>
-90
View File
@@ -1,90 +0,0 @@
import { motion } from "motion/react";
import HumanIcon from "./icons/HumanIcon";
import Button from "./ui/Button";
import ArrowRightIcon from "./icons/ArrowRightIcon";
import CloseIcon from "./icons/CloseIcon";
import { useQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
import IMarker from "../types/IMarker";
import { formattedUnitTypes } from "../data/formattedUnitTypes";
import { useNavigate } from "react-router";
function NewSelectedComplexCard({
marker,
onClose,
}: {
marker: IMarker;
onClose: () => void;
}) {
const { data: unitTypes } = useQuery({
queryKey: ["filters", "unitTypes", marker.title],
queryFn: () =>
api
.get(`units/filters/unitTypes?project=Rove Home ${marker.title}`)
.json<string[]>(),
});
const navigate = useNavigate();
return (
<motion.div
key={marker.name}
initial={{ opacity: 0, y: "100%" }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: "100%" }}
transition={{ duration: 0.3 }}
className="absolute w-full p-4 pb-6 bottom-0 bg-white rounded-t-2xl z-1"
>
<div className="space-y-4">
<div className="left-1/2 -translate-x-1/2 top-2 absolute bg-[#E2E2DC] w-[6.667vw] aspect-[6/1] rounded-2xl" />
<Button
onlyIcon
className="!bg-[#F3F3F2] absolute top-4 right-4"
onClick={onClose}
>
<span className="w-5 h-5 text-[#0D1922]">
<CloseIcon />
</span>
</Button>
<div className="space-y-2">
<p className="text-h5 font-medium">{marker.title}</p>
<div className="flex gap-1">
<div className="px-2 py-0.5 bg-[#F3F3F2] rounded">
<p className="text-caption-s opacity-70"># Apartments</p>
</div>
<div className="rounded px-2 py-0.5 flex items-center justify-center gap-1 bg-[#30B216]/8">
<span className="text-[#30B216] w-[3.333vw] h-[3.333vw]">
<HumanIcon />
</span>
<p className="text-caption-s text-[#30B216]">Virtual Tour</p>
</div>
</div>
</div>
<hr className="border-[#E2E2DC] h-px" />
<div className="space-y-2">
{unitTypes?.map((unitType) => (
<div key={unitType} className="flex items-center gap-2">
<div className="rounded-full flex justify-center items-center w-[4.444vw] h-[4.444vw] bg-[#00BED7] text-white text-caption-s">
4
</div>
<p className="opacity-70 text-caption-m">
{formattedUnitTypes.get(unitType)}
</p>
</div>
))}
</div>
<Button
className="w-full"
onTouchStart={() => navigate(`/complex/${marker.name}`)}
>
<p className="text-btn-m">Explore</p>
<span className="w-5 h-5">
<ArrowRightIcon />
</span>
</Button>
</div>
</motion.div>
);
}
export default NewSelectedComplexCard;
+15 -3
View File
@@ -260,6 +260,18 @@ function SearchFilters({
setView(view);
}
function handleSelectCost(newCostRange: [number, number]) {
setCost(newCostRange);
}
function handleSelectFloor(newFloorRange: [number, number]) {
setFloor(newFloorRange);
}
function handleSelectArea(newAreaRange: [number, number]) {
setArea(newAreaRange);
}
function resetFilters() {
setView("Any view");
setSelectedUnitTypes([]);
@@ -372,7 +384,7 @@ function SearchFilters({
currentMin={cost[0] === -1 ? allCost.min : cost[0]}
currentMax={cost[1] === -1 ? allCost.max : cost[1]}
offset={0}
onChange={setCost}
onChange={handleSelectCost}
label="Cost, AED"
/>
</motion.div>
@@ -391,7 +403,7 @@ function SearchFilters({
currentMin={floor[0] === -1 ? allFloors.min : floor[0]}
currentMax={floor[1] === -1 ? allFloors.max : floor[1]}
offset={0}
onChange={setFloor}
onChange={handleSelectFloor}
label="Floor"
/>
</motion.div>
@@ -410,7 +422,7 @@ function SearchFilters({
currentMin={area[0] === -1 ? allArea.min : area[0]}
currentMax={area[1] === -1 ? allArea.max : area[1]}
offset={0}
onChange={setArea}
onChange={handleSelectArea}
label="Total Area, Sqft"
/>
</motion.div>
+72 -62
View File
@@ -1,80 +1,90 @@
import { useNavigate } from "react-router";
import ArrowRightIcon from "./icons/ArrowRightIcon";
import Button from "./ui/Button";
import { motion } from "motion/react";
import IMarker from "../types/IMarker";
import { useEffect, useState } from "react";
import clsx from "clsx";
import HumanIcon from "./icons/HumanIcon";
import Button from "./ui/Button";
import ArrowRightIcon from "./icons/ArrowRightIcon";
import CloseIcon from "./icons/CloseIcon";
import { useQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
import IMarker from "../types/IMarker";
import { formattedUnitTypes } from "../data/formattedUnitTypes";
import { useNavigate } from "react-router";
export default function SelectedComplexCard({ marker }: { marker: IMarker }) {
const navigate = useNavigate();
const [isImageLoaded, setIsImageLoaded] = useState(false);
useEffect(() => setIsImageLoaded(false), [marker]);
const { data: count } = useQuery({
queryKey: ["units", "count", `Rove Home ${marker.title}`],
function SelectedComplexCard({
marker,
onClose,
}: {
marker: IMarker;
onClose: () => void;
}) {
const { data: unitTypes } = useQuery({
queryKey: ["filters", "unitTypes", marker.title],
queryFn: () =>
api.get(`units/count?project=Rove Home ${marker.title}`).json<number>(),
api
.get(`units/filters/unitTypes?project=Rove Home ${marker.title}`)
.json<string[]>(),
});
const navigate = useNavigate();
return (
<motion.div
id={`selected-complex-card`}
key={marker.id}
initial={{ opacity: 0, bottom: -16 }}
animate={{ opacity: 1, bottom: 0 }}
exit={{ opacity: 0, bottom: -16 }}
key={marker.name}
initial={{ opacity: 0, y: "100%" }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: "100%" }}
transition={{ duration: 0.3 }}
className="absolute w-full p-4 pb-6 bottom-0 bg-white rounded-t-2xl z-1"
>
<div className="rounded-2xl flex gap-3 p-4 bg-white absolute bottom-3 left-3 w-[calc(100%-24px)]">
<div className="relative w-26 h-26">
<img
src={`/images/map/markers/cards/${marker.name}.jpg`}
alt={marker.title}
className={clsx(
"rounded transition-opacity duration-300 pointer-events-none",
isImageLoaded ? "opacity-100" : "opacity-0"
)}
onLoad={() => setIsImageLoaded(true)}
/>
<div
className={clsx(
"absolute inset-0 flex items-center justify-center tran",
isImageLoaded ? "opacity-0" : "opacity-100"
)}
>
<p className="text-xs">Loading...</p>
<div className="space-y-4">
<div className="left-1/2 -translate-x-1/2 top-2 absolute bg-[#E2E2DC] w-[6.667vw] aspect-[6/1] rounded-2xl" />
<Button
onlyIcon
className="!bg-[#F3F3F2] absolute top-4 right-4"
onClick={onClose}
>
<span className="w-5 h-5 text-[#0D1922]">
<CloseIcon />
</span>
</Button>
<div className="space-y-2">
<p className="text-h5 font-medium">{marker.title}</p>
<div className="flex gap-1">
<div className="px-2 py-0.5 bg-[#F3F3F2] rounded">
<p className="text-caption-s opacity-70"># Apartments</p>
</div>
<div className="rounded px-2 py-0.5 flex items-center justify-center gap-1 bg-[#30B216]/8">
<span className="text-[#30B216] w-[3.333vw] h-[3.333vw]">
<HumanIcon />
</span>
<p className="text-caption-s text-[#30B216]">Virtual Tour</p>
</div>
</div>
</div>
<div className="flex flex-col justify-between border-b border-[#E2E2DC] flex-1">
<div className="flex justify-between gap-4">
<p className="font-medium leading-[115%]">
Rove Home
<br />
{marker.title}
</p>
<p className="text-[#00BED7] text-[10px] leading-[135%]">
{count} units
</p>
</div>
<Button
disabled
variant="tertiary"
size="small"
className="w-fit"
onTouchStart={() => navigate(`/complex/${marker.name}`)}
>
Explore
<span className="w-4 h-4">
<ArrowRightIcon />
</span>
</Button>
<hr className="border-[#E2E2DC] h-px" />
<div className="space-y-2">
{unitTypes?.map((unitType) => (
<div key={unitType} className="flex items-center gap-2">
<div className="rounded-full flex justify-center items-center w-[4.444vw] h-[4.444vw] bg-[#00BED7] text-white text-caption-s">
4
</div>
<p className="opacity-70 text-caption-m">
{formattedUnitTypes.get(unitType)}
</p>
</div>
))}
</div>
<Button
className="w-full"
onTouchStart={() => navigate(`/complex/${marker.name}`)}
>
<p className="text-btn-m">Explore</p>
<span className="w-5 h-5">
<ArrowRightIcon />
</span>
</Button>
</div>
</motion.div>
);
}
export default SelectedComplexCard;
+5 -1
View File
@@ -181,7 +181,11 @@ function SequenceSlider({ complexName }: SequenceSliderProps) {
]
}`}
className="fill-[#00BED7] cursor-pointer transition-opacity duration-300 opacity-0 hover:opacity-40"
onClick={() => navigate("floors")}
onClick={() => {
if (complexName !== "dubai-marina") {
navigate("floors");
}
}}
/>
</svg>
)}
+8 -1
View File
@@ -45,7 +45,14 @@ function MultiRangeSlider({
: Math.min(Math.max(newValue, currentMin + offset), max);
}
const [value, setValue] = useState<[number, number]>([min, max]);
const [value, setValue] = useState<[number, number]>([
currentMin,
currentMax,
]);
useEffect(() => {
setValue([currentMin, currentMax]);
}, [currentMin, currentMax]);
function handleChange(
e: MouseEvent | TouchEvent | ReactMouseEvent | ReactTouchEvent
+1 -1
View File
@@ -5,7 +5,7 @@ function LayoutWithoutFooter() {
return (
<div className="flex flex-col select-none min-h-dvh">
<Header />
<div className="2xl:h-[calc(100dvh-7.5vh)] md:max-2xl:h-[calc(100dvh-64px)] h-[calc(100dvh-56px)]">
<div className="2xl:h-[calc(100dvh-max(7.5vh,4.444vw))] md:max-2xl:h-[calc(100dvh-64px)] h-[calc(100dvh-56px)]">
<Outlet />
</div>
</div>
+112 -111
View File
@@ -4,23 +4,23 @@ import {
motion,
useInView,
AnimatePresence,
} from 'motion/react';
import { useRef, useState } from 'react';
} from "motion/react";
import { useRef, useState } from "react";
import {
dubaiMarinaFeatures,
dubaiMarinaDescription,
roveHomeDescription,
dubaiMarinaSlider,
sliderBadgesCategory,
} from '../data/aboutDubaiMarina';
import EqualIcon from '../components/icons/EqualIcon';
import TextBox from '../components/ui/TextBox';
import clsx from 'clsx';
import Slider from '../components/Slider';
import PlusIcon from '../components/icons/map/PlusIcon';
import useWindowSize from '../hooks/useWindowSize';
import FullScreenButton from '../components/FullScreenButton';
import SliderMobile from '../components/SliderMobile';
} from "../data/aboutDubaiMarina";
import EqualIcon from "../components/icons/EqualIcon";
import TextBox from "../components/ui/TextBox";
import clsx from "clsx";
import Slider from "../components/Slider";
import PlusIcon from "../components/icons/map/PlusIcon";
import useWindowSize from "../hooks/useWindowSize";
import FullScreenButton from "../components/FullScreenButton";
import SliderMobile from "../components/SliderMobile";
function AboutComplexPage() {
const containerRef = useRef(null);
@@ -29,11 +29,11 @@ function AboutComplexPage() {
const { width } = useWindowSize();
const [selectedCategorySlider, setSelectedCategorySlider] =
useState<keyof typeof dubaiMarinaSlider>('Wellness');
useState<keyof typeof dubaiMarinaSlider>("Wellness");
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ['start start', 'end start'],
offset: ["start start", "end start"],
});
const firstSectionOpacity = useTransform(scrollYProgress, [0, 0.2], [1, 0]);
@@ -41,7 +41,7 @@ function AboutComplexPage() {
const secondSectionY = useTransform(
scrollYProgress,
[0, 0.4],
['100dvh', '0dvh']
["100dvh", "0dvh"]
);
const isSliderInView = useInView(sliderRef, {
@@ -54,44 +54,44 @@ function AboutComplexPage() {
});
return (
<div className='relative bg-white' ref={containerRef}>
<div className="relative bg-white" ref={containerRef}>
<motion.section
className='md:h-[calc(100dvh-4.444vw)] w-full bg-white text-black md:fixed top-[4.444vw] left-0 right-0 z-0 max-md:top-[15.556vw]]
max-md:bg-[url(/images/about-complex/dubai-marina/tower-mobile.png)] max-md:bg-cover max-md:bg-top max-md:bg-no-repeat max-md:aspect-[360/584]'
className="md:h-[calc(100dvh-4.444vw)] w-full bg-white text-black md:fixed top-[4.444vw] left-0 right-0 z-0 max-md:top-[15.556vw]]
max-md:bg-[url(/images/about-complex/dubai-marina/tower-mobile.png)] max-md:bg-cover max-md:bg-top max-md:bg-no-repeat max-md:aspect-[360/584]"
style={{
opacity: width > 768 ? firstSectionOpacity : 1,
}}
>
<div className='absolute inset-0 max-md:relative'>
<div className="absolute inset-0 max-md:relative">
<img
src='/images/about-complex/dubai-marina/tower.jpg'
alt='dubai marina about'
className='h-full w-full object-contain object-bottom max-md:hidden'
src="/images/about-complex/dubai-marina/tower.jpg"
alt="dubai marina about"
className="h-full w-full object-contain object-bottom max-md:hidden"
/>
<img
src='/images/about-complex/dubai-marina/logo.png'
alt='dubai marina about'
className='absolute top-[5vw] right-[2.778vw] w-[9.931vw] h-[4.444vw] max-md:top-[6.667vw] max-md:right-[4.444vw] max-md:w-[21.389vw] max-md:h-[9.444vw]'
src="/images/about-complex/dubai-marina/logo.png"
alt="dubai marina about"
className="absolute top-[5vw] right-[2.778vw] w-[9.931vw] h-[4.444vw] max-md:top-[6.667vw] max-md:right-[4.444vw] max-md:w-[21.389vw] max-md:h-[9.444vw]"
/>
</div>
<div className='relative h-full flex flex-col justify-between 2xl:gap-[4.444vw] flex-1 w-full pt-[5vw] pb-[2.5vw] pl-[2.222vw] max-md:px-[4.444vw] max-md:block '>
<div className='font-bold whitespace-pre-line space-y-8 max-md:space-y-4'>
<h1 className='text-[5vw] leading-none tracking-[-0.07em] font-mixcase-unmixed font-[500] max-md:text-[8.889vw]'>
<div className="relative h-full flex flex-col justify-between 2xl:gap-[4.444vw] flex-1 w-full pt-[5vw] pb-[2.5vw] pl-[2.222vw] max-md:px-[4.444vw] max-md:block ">
<div className="font-bold whitespace-pre-line space-y-8 max-md:space-y-4">
<h1 className="text-[5vw] leading-none tracking-[-0.07em] font-mixcase-unmixed font-[500] max-md:text-[8.889vw]">
{`Rove Home
Dubai Marina`}
</h1>
<div className='space-y-2 font-[400]'>
<div className="space-y-2 font-[400]">
{roveHomeDescription.map((description) => (
<TextBox text={description} />
<TextBox text={description} key={description} />
))}
</div>
</div>
<div className='space-y-8 max-md:hidden'>
<h4 className='text-h4 text-[#00BED7] font-[500] whitespace-pre-line'>
<div className="space-y-8 max-md:hidden">
<h4 className="text-h4 text-[#00BED7] font-[500] whitespace-pre-line">
{`Own the last slice of
Dubai Marina, ROVE Style`}
</h4>
<p className='text-s text-[#0D1922B2] whitespace-pre-line '>
<p className="text-s text-[#0D1922B2] whitespace-pre-line ">
{`With an extended playlist of life-enhancing
amenities, Rove Home is a complete ecosystem
that has everything you'll ever need.`}
@@ -100,80 +100,81 @@ function AboutComplexPage() {
</div>
</motion.section>
<motion.section
className='w-full text-white bg-white flex justify-center max-md:top-0 max-md:overflow-x-clip'
className="w-full text-white bg-white flex justify-center max-md:top-0 max-md:overflow-x-clip"
style={{
y: width > 768 ? secondSectionY : 0,
zIndex: 1,
}}
>
<div className='w-full'>
<div className='flex flex-col items-center gap-[2.222vw] w-full max-md:py-[8.889vw] max-md:px-[4.444vw]'>
<div className='space-y-8 min-md:hidden self-start'>
<h4 className='text-h4 text-[#00BED7] font-[500] whitespace-pre-line'>
<div className="w-full">
<div className="flex flex-col items-center gap-[2.222vw] w-full max-md:py-[8.889vw] max-md:px-[4.444vw]">
<div className="space-y-8 min-md:hidden self-start">
<h4 className="text-h4 text-[#00BED7] font-[500] whitespace-pre-line">
{`Own the last slice of Dubai
Marina, ROVE Style`}
</h4>
<p className='text-s text-[#0D1922B2] whitespace-pre-line '>
<p className="text-s text-[#0D1922B2] whitespace-pre-line ">
{`With an extended playlist of life-enhancing
amenities, Rove Home is a complete ecosystem
that has everything you'll ever need.`}
</p>
</div>
<div className='2xl:px-[2.222vw] flex pt-[7.222vw] flex-col items-center gap-[2.222vw] max-md:pt-[17.778vw]'>
<h1 className='text-[3.889vw] text-[#0D1922] font-mixcase-unmixed max-md:text-[6.667vw]'>
<div className="2xl:px-[2.222vw] flex pt-[7.222vw] flex-col items-center gap-[2.222vw] max-md:pt-[17.778vw]">
<h1 className="text-[3.889vw] text-[#0D1922] font-mixcase-unmixed max-md:text-[6.667vw]">
Rove Home has it all
</h1>
<p className='text-s text-[#0D1922B2] text-center tracking-[-0.02em] whitespace-pre-line'>
<p className="text-s text-[#0D1922B2] text-center tracking-[-0.02em] whitespace-pre-line">
{`Rove Home Dubai Marina features modern-day
conveniences, carefully curated for an active
and social lifestyle.`}
</p>
</div>
<div className='flex gap-[0.556vw] mt-[0.833vw] 2xl:h-[26.667vw] max-md:pl-[4.444vw] max-md:pr-[2vw] max-md:gap-[2.222vw] max-md:snap-x max-md:py-[6.667vw] max-md:overflow-x-auto max-md:self-start max-md:w-screen max-md:-ml-[4.444vw] '>
<div className="flex gap-[0.556vw] mt-[0.833vw] 2xl:h-[26.667vw] max-md:pl-[4.444vw] max-md:pr-[2vw] max-md:gap-[2.222vw] max-md:snap-x max-md:snap-mandatory max-md:py-[6.667vw] max-md:overflow-x-auto max-md:self-start max-md:w-screen max-md:-ml-[4.444vw] ">
{dubaiMarinaFeatures.map((feature) => (
<div
key={feature.name}
className={`rounded-3xl flex-1 md:h-[26.667vw] w-full flex flex-col items-center py-[1.667vw] justify-end bg-cover bg-center bg-no-repeat relative before:absolute before:inset-0 before:bg-[#0D1922]/10 before:z-1 before:rounded-3xl
max-md:w-[91.111vw] max-md:flex-none aspect-[268/384] max-md:aspect-[328/287] max-md:snap-always max-md:snap-center max-md:py-[4.444vw]`}
max-md:w-[91.111vw] max-md:flex-none aspect-[268/384] max-md:aspect-[328/287] max-md:snap-alwaysa max-md:snap-center max-md:py-[4.444vw]`}
style={{
backgroundImage: `url(${feature.image})`,
}}
>
<h5 className='text-h5 text-white tracking-[-0.02em] z-2'>
<h5 className="text-h5 text-white tracking-[-0.02em] z-2">
{feature.name}
</h5>
</div>
))}
</div>
</div>
<div className='flex flex-col items-center pt-[4.444vw] px-8 gap-[4.444vw] max-md:px-[4.444vw]'>
<h1 className='font-mixcase-unmixed 2xl:text-[3.889vw] text-[#0D1922] tracking-[-0.05em] max-md:text-2xl'>
Dubai, <span className='text-[#0D192266]'>within reach</span>
<div className="flex flex-col items-center pt-[4.444vw] px-8 gap-[4.444vw] max-md:px-[4.444vw]">
<h1 className="font-mixcase-unmixed 2xl:text-[3.889vw] text-[#0D1922] tracking-[-0.05em] max-md:text-2xl">
Dubai, <span className="text-[#0D192266]">within reach</span>
</h1>
<SliderMobile />
<div className='flex w-full text-[#0D1922]/40 gap-[1.111vw] max-md:hidden'>
<div className="flex w-full text-[#0D1922]/40 gap-[1.111vw] max-md:hidden">
{dubaiMarinaDescription.map((descriptionItem) => (
<div
className='flex-1 text-center flex flex-col gap-[1.111vw] cursor-pointer hover:text-[#0D1922B2] transition-all duration-200'
key={descriptionItem.title}
className="flex-1 text-center flex flex-col gap-[1.111vw] cursor-pointer hover:text-[#0D1922B2] transition-all duration-200"
onClick={() =>
setSelectedCategorySlider(descriptionItem.title)
}
>
<div className='h-[2px] bg-gray-300 w-full'></div>
<div className="h-[2px] bg-gray-300 w-full"></div>
<h5
className={clsx(
'text-h5 tracking-[-0.02em] mt-[0.556vw] font-[500]',
"text-h5 tracking-[-0.02em] mt-[0.556vw] font-[500]",
descriptionItem.title === selectedCategorySlider &&
'text-[#00BED7]'
"text-[#00BED7]"
)}
>
{descriptionItem.title}
</h5>
<p
className={clsx(
'text-s leading-[125%] tracking-[-0.02em]',
"text-s leading-[125%] tracking-[-0.02em]",
descriptionItem.title === selectedCategorySlider &&
'text-[#0D1922]'
"text-[#0D1922]"
)}
>
{descriptionItem.description}
@@ -181,10 +182,10 @@ function AboutComplexPage() {
</div>
))}
</div>
<AnimatePresence mode='wait'>
<AnimatePresence mode="wait">
<div
ref={sliderRef}
className='flex flex-col gap-8 max-md:hidden'
className="flex flex-col gap-8 max-md:hidden"
>
<motion.div
key={`slider-${selectedCategorySlider}`}
@@ -195,13 +196,13 @@ function AboutComplexPage() {
: { opacity: 0, y: 140 }
}
exit={{ opacity: 0, y: -40 }}
transition={{ duration: 0.6, ease: 'easeIn' }}
transition={{ duration: 0.6, ease: "easeIn" }}
>
<Slider categoryName={selectedCategorySlider} />
</motion.div>
<motion.div
key={`badges-${selectedCategorySlider}`}
className='flex gap-[0.556vw] w-[63.333vw] flex-wrap justify-center'
className="flex gap-[0.556vw] w-[63.333vw] flex-wrap justify-center"
>
{sliderBadgesCategory[selectedCategorySlider].map(
(badgeItem, index) => (
@@ -212,7 +213,7 @@ function AboutComplexPage() {
transition={{
duration: 0.3,
delay: index * 0.1,
ease: 'easeOut',
ease: "easeOut",
}}
>
<TextBox text={badgeItem} />
@@ -223,131 +224,131 @@ function AboutComplexPage() {
</div>
</AnimatePresence>
</div>
<div className='text-center w-full flex flex-col items-center gap-[2.222vw] bg-white max-md:gap-[6.667vw]'>
<h1 className='font-mixcase-unmixed text-[3.889vw] text-[#0D1922] w-[44.861vw] leading-[100%] tracking-[-0.05em] pt-[8.056vw] max-md:text-[6.667vw] max-md:w-full'>
<div className="text-center w-full flex flex-col items-center gap-[2.222vw] bg-white max-md:gap-[6.667vw]">
<h1 className="font-mixcase-unmixed text-[3.889vw] text-[#0D1922] w-[44.861vw] leading-[100%] tracking-[-0.05em] pt-[8.056vw] max-md:text-[6.667vw] max-md:w-full">
Dubai's first-ever combinable Apartments
</h1>
<TextBox text='On-demand' />
<p className='text-s text-[#0D1922B2] leading-[140%] tracking-[-0.02em] whitespace-pre-line'>
<TextBox text="On-demand" />
<p className="text-s text-[#0D1922B2] leading-[140%] tracking-[-0.02em] whitespace-pre-line">
{`Enjoy the option to combine 2 apartments and create
a larger space and configuration.`}
</p>
<div className='flex gap-4 relative max-md:flex-col max-md:gap-[2.222vw] max-md:w-full max-md:px-[4.444vw]'>
<div className="flex gap-4 relative max-md:flex-col max-md:gap-[2.222vw] max-md:w-full max-md:px-[4.444vw]">
<div
className='w-[19.028vw] text-[#0D1922] h-[27.778vw] p-[1.667vw] rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/studio.png)] bg-[length:7.778vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:25.556vw_58.333vw] max-md:p-[4.444vw]'
className="w-[19.028vw] text-[#0D1922] h-[27.778vw] p-[1.667vw] rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/studio.png)] bg-[length:7.778vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:25.556vw_58.333vw] max-md:p-[4.444vw]"
>
<h4 className='text-h4 tracking-[-0.02em] font-[500] max-md:text-h5'>
<h4 className="text-h4 tracking-[-0.02em] font-[500] max-md:text-h5">
Studio²
</h4>
</div>
<div
className='w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[18.500vw] self-center
max-md:top-[71.111vw] max-md:left-[45vw]'
className="w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[18.500vw] self-center
max-md:top-[71.111vw] max-md:left-[45vw]"
>
<span className='w-5 h-5'>
<span className="w-5 h-5">
<PlusIcon />
</span>
</div>
<div
className='w-[19.028vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/studio.png)] bg-[length:7.778vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:25.556vw_58.333vw] max-md:p-[4.444vw]'
className="w-[19.028vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/studio.png)] bg-[length:7.778vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:25.556vw_58.333vw] max-md:p-[4.444vw]"
>
<h4 className='text-h4 tracking-[-0.02em] font-[500] max-md:text-h5'>
<h4 className="text-h4 tracking-[-0.02em] font-[500] max-md:text-h5">
Studio²
</h4>
</div>
<div
className='w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[38.333vw] self-center
max-md:top-[148.611vw] max-md:left-[45vw] '
className="w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[38.333vw] self-center
max-md:top-[148.611vw] max-md:left-[45vw] "
>
<span className='w-5 h-5'>
<span className="w-5 h-5">
<EqualIcon />
</span>
</div>
<div
className='w-[30.972vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/1_bedroom.png)] bg-[length:15.972vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[111.111vw] max-md:bg-[length:63.889vw_71.389vw] max-md:p-[4.444vw]'
className="w-[30.972vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/1_bedroom.png)] bg-[length:15.972vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[111.111vw] max-md:bg-[length:63.889vw_71.389vw] max-md:p-[4.444vw]"
>
<h4 className='text-h4 tracking-[-0.02em] font-[500] max-md:text-h5'>
<h4 className="text-h4 tracking-[-0.02em] font-[500] max-md:text-h5">
1 Bedroom²
</h4>
</div>
</div>
<h5 className='2xl:hidden text-h5 text-[#0D1922B2]'>or</h5>
<div className='flex gap-4 relative max-md:flex-col max-md:gap-[2.222vw] max-md:w-full max-md:px-[4.444vw]'>
<h5 className="2xl:hidden text-h5 text-[#0D1922B2]">or</h5>
<div className="flex gap-4 relative max-md:flex-col max-md:gap-[2.222vw] max-md:w-full max-md:px-[4.444vw]">
<div
className='w-[19.028vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/2_studio.png)] bg-[length:13.125vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:38.889vw_52.5vw] max-md:p-[4.444vw]'
className="w-[19.028vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/2_studio.png)] bg-[length:13.125vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:38.889vw_52.5vw] max-md:p-[4.444vw]"
>
<h4 className='text-h4 tracking-[-0.02em] font-[500] max-md:text-h5'>
<h4 className="text-h4 tracking-[-0.02em] font-[500] max-md:text-h5">
Studio²
</h4>
</div>
<div
className='w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[18.500vw] self-center
max-md:top-[71.111vw] max-md:left-[45vw]'
className="w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[18.500vw] self-center
max-md:top-[71.111vw] max-md:left-[45vw]"
>
<span className='w-5 h-5'>
<span className="w-5 h-5">
<PlusIcon />
</span>
</div>
<div
className='w-[30.972vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/1_bedroom_rotated.png)] bg-[length:17.847vw_13.681vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:56.111vw_43.056vw] max-md:p-[4.444vw]'
className="w-[30.972vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/1_bedroom_rotated.png)] bg-[length:17.847vw_13.681vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[75.556vw] max-md:bg-[length:56.111vw_43.056vw] max-md:p-[4.444vw]"
>
<h4 className='text-h4 tracking-[-0.02em] font-[500] max-md:text-h5'>
<h4 className="text-h4 tracking-[-0.02em] font-[500] max-md:text-h5">
1 Bedroom²
</h4>
</div>
<div
className='w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[50.300vw] self-center
max-md:top-[148.611vw] max-md:left-[45vw]'
className="w-10 h-10 rounded-full bg-[#0D1922] flex items-center justify-center absolute left-[50.300vw] self-center
max-md:top-[148.611vw] max-md:left-[45vw]"
>
<span className='w-5 h-5'>
<span className="w-5 h-5">
<EqualIcon />
</span>
</div>
<div
className='w-[30.972vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/2_bedroom.png)] bg-[length:19.028vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[111.111vw] max-md:bg-[length:76.267vw_71.389vw] max-md:p-[4.444vw]'
className="w-[30.972vw] text-[#0D1922] h-[27.778vw] p-6 rounded-2xl bg-[#F3F3F2] text-left bg-[url(/images/about-complex/dubai-marina/2_bedroom.png)] bg-[length:19.028vw_17.847vw] bg-no-repeat bg-center
max-md:w-full max-md:h-[111.111vw] max-md:bg-[length:76.267vw_71.389vw] max-md:p-[4.444vw]"
>
<h4 className='text-h4 tracking-[-0.02em] font-[500] max-md:text-h5'>
<h4 className="text-h4 tracking-[-0.02em] font-[500] max-md:text-h5">
2 Bedroom²
</h4>
</div>
</div>
</div>
<div className='flex flex-col items-center gap-[2.222vw] bg-white px-[2.222vw] pb-[8.333vw] max-md:gap-[6.667vw] max-md:px-[4.444vw]'>
<div className="flex flex-col items-center gap-[2.222vw] bg-white px-[2.222vw] pb-[8.333vw] max-md:gap-[6.667vw] max-md:px-[4.444vw]">
<h1
className='font-mixcase-unmixed text-[3.889vw] text-[#0D1922] w-[44.861vw] leading-[100%] tracking-[-0.05em] pt-[7.222vw] text-center
max-md:text-[6.667vw] max-md:w-full'
className="font-mixcase-unmixed text-[3.889vw] text-[#0D1922] w-[44.861vw] leading-[100%] tracking-[-0.05em] pt-[7.222vw] text-center
max-md:text-[6.667vw] max-md:w-full"
>
Live central. Live centred
</h1>
<p className='text-s text-[#0D1922B2] leading-[140%] tracking-[-0.02em] text-center 2xl:whitespace-pre-line'>
<p className="text-s text-[#0D1922B2] leading-[140%] tracking-[-0.02em] text-center 2xl:whitespace-pre-line">
{`Located in the heart of Dubai Marina, Rove Home Dubai Marina is where active
living meets modern convenience. Enjoy an energetic lifestyle surrounded by
trendy cafés, shops, and entertainment options all within reach.`}
</p>
<motion.img
ref={mapRef}
src='/images/about-complex/dubai-marina/central_map.png'
alt='central map'
className='rounded-3xl object-cover object-center aspect-[1376/609] max-md:hidden'
initial={{ width: '47.083vw' }}
src="/images/about-complex/dubai-marina/central_map.png"
alt="central map"
className="rounded-3xl object-cover object-center aspect-[1376/609] max-md:hidden"
initial={{ width: "47.083vw" }}
animate={
isMapInView ? { width: '95.556vw' } : { width: '47.083vw' }
isMapInView ? { width: "95.556vw" } : { width: "47.083vw" }
}
transition={{ duration: 0.6, ease: 'easeInOut' }}
transition={{ duration: 0.6, ease: "easeInOut" }}
/>
<div className='min-md:hidden relative w-[89.167vw] aspect-square overflow-hidden rounded-2xl'>
<div className="min-md:hidden relative w-[89.167vw] aspect-square overflow-hidden rounded-2xl">
<img
src='/images/about-complex/dubai-marina/central_map.png'
alt='central map'
className='w-full h-full object-cover object-center scale-120'
src="/images/about-complex/dubai-marina/central_map.png"
alt="central map"
className="w-full h-full object-cover object-center scale-120"
/>
<div className='absolute bottom-[1.111vw] right-[1.111vw] w-[11.111vw] h-[11.111vw]'>
<div className="absolute bottom-[1.111vw] right-[1.111vw] w-[11.111vw] h-[11.111vw]">
<FullScreenButton
isFullScreen={false}
onClick={() => {}}