Files
irth-new-client/src/pages/AboutComplexPage.tsx
T

366 lines
17 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
useScroll,
useTransform,
motion,
useInView,
AnimatePresence,
} 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';
function AboutComplexPage() {
const containerRef = useRef(null);
const sliderRef = useRef(null);
const mapRef = useRef(null);
const { width } = useWindowSize();
const [selectedCategorySlider, setSelectedCategorySlider] =
useState<keyof typeof dubaiMarinaSlider>('Wellness');
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ['start start', 'end start'],
});
const firstSectionOpacity = useTransform(scrollYProgress, [0, 0.2], [1, 0]);
const secondSectionY = useTransform(
scrollYProgress,
[0, 0.4],
['100dvh', '0dvh']
);
const isSliderInView = useInView(sliderRef, {
once: true,
amount: 0.1,
});
const isMapInView = useInView(mapRef, {
once: true,
margin: `0px 0px ${-window.innerHeight / 2}px 0px`,
});
return (
<div className='relative bg-white' ref={containerRef}>
<motion.section
className='md:h-[calc(100dvh-4.444vw)] w-full bg-white text-black 2xl: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'>
<img
src='/images/about-complex/dubai-marina/tower.jpg'
alt='dubai marina about'
className='h-full w-full object-cover object-top 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]'
/>
</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]'>
{`Rove Home
Dubai Marina`}
</h1>
<div className='space-y-2 font-[400]'>
{roveHomeDescription.map((description) => (
<TextBox text={description} />
))}
</div>
</div>
<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 '>
{`With an extended playlist of life-enhancing
amenities, Rove Home is a complete ecosystem
that has everything you'll ever need.`}
</p>
</div>
</div>
</motion.section>
<motion.section
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'>
{`Own the last slice of Dubai
Marina, ROVE Style`}
</h4>
<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]'>
Rove Home has it all
</h1>
<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] '>
{dubaiMarinaFeatures.map((feature) => (
<div
key={feature.name}
className={`rounded-3xl flex-1 2xl: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-2 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]`}
style={{
backgroundImage: `url(${feature.image})`,
}}
>
<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>
</h1>
<SliderMobile />
<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'
onClick={() =>
setSelectedCategorySlider(descriptionItem.title)
}
>
<div className='h-[2px] bg-gray-300 w-full'></div>
<h5
className={clsx(
'text-h5 tracking-[-0.02em] mt-[0.556vw] font-[500]',
descriptionItem.title === selectedCategorySlider &&
'text-[#00BED7]'
)}
>
{descriptionItem.title}
</h5>
<p
className={clsx(
'text-s leading-[125%] tracking-[-0.02em]',
descriptionItem.title === selectedCategorySlider &&
'text-[#0D1922]'
)}
>
{descriptionItem.description}
</p>
</div>
))}
</div>
<AnimatePresence mode='wait'>
<div
ref={sliderRef}
className='flex flex-col gap-8 max-md:hidden'
>
<motion.div
key={`slider-${selectedCategorySlider}`}
initial={{ opacity: 0, y: 40 }}
animate={
isSliderInView
? { opacity: 1, y: 0 }
: { opacity: 0, y: 140 }
}
exit={{ opacity: 0, y: -40 }}
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'
>
{sliderBadgesCategory[selectedCategorySlider].map(
(badgeItem, index) => (
<motion.div
key={badgeItem}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{
duration: 0.3,
delay: index * 0.1,
ease: 'easeOut',
}}
>
<TextBox text={badgeItem} />
</motion.div>
)
)}
</motion.div>
</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'>
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'>
{`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='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'>
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]'
>
<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]'
>
<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] '
>
<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]'
>
<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]'>
<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]'
>
<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]'
>
<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]'
>
<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]'
>
<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]'
>
<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]'>
<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'
>
Live central. Live centred
</h1>
<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' }}
animate={
isMapInView ? { width: '95.556vw' } : { width: '47.083vw' }
}
transition={{ duration: 0.6, ease: 'easeInOut' }}
/>
<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'
/>
<div className='absolute bottom-[1.111vw] right-[1.111vw] w-[11.111vw] h-[11.111vw]'>
<FullScreenButton
isFullScreen={false}
onClick={() => {}}
onFullScreenChange={() => {}}
/>
</div>
</div>
</div>
</div>
</motion.section>
</div>
);
}
export default AboutComplexPage;