This commit is contained in:
2025-05-13 18:50:24 +05:00
parent 599e3bb4cb
commit 385878aa84
14 changed files with 325 additions and 191 deletions
+48 -50
View File
@@ -1,111 +1,109 @@
import { Link } from 'react-router';
import YoutubeIcon from './icons/YoutubeIcon';
import InstagramIcon from './icons/InstagramIcon';
import FacebookIcon from './icons/FacebookIcon';
import LinkedInIcon from './icons/LinkedInIcon';
import TwitterIcon from './icons/TwitterIcon';
import { Link } from "react-router";
import YoutubeIcon from "./icons/YoutubeIcon";
import InstagramIcon from "./icons/InstagramIcon";
import FacebookIcon from "./icons/FacebookIcon";
import LinkedInIcon from "./icons/LinkedInIcon";
import TwitterIcon from "./icons/TwitterIcon";
import ChevronDownIcon from "./icons/ChevronDownIcon";
function Footer() {
return (
<footer className='2xl:px-[2.222vw] 2xl:pb-[2.222vw] 2xl:pt-[2.778vw] md:max-2xl:p-6 px-4 py-6 grid 2xl:grid-cols-6 md:max-2xl:grid-cols-4 grid-cols-2 2xl:grid-rows-2 2xl:gap-x-[1.667vw] 2xl:gap-y-[1.111vw] max-2xl:gap-y-6 2xl:rounded-t-[1.667vw] rounded-t-3xl outline outline-[#E2E2DC] bg-white'>
<footer className="2xl:px-[2.222vw] 2xl:pb-[2.222vw] 2xl:pt-[2.778vw] md:max-2xl:p-6 px-4 py-6 grid 2xl:grid-cols-6 md:max-2xl:grid-cols-4 grid-cols-2 2xl:grid-rows-2 2xl:gap-x-[1.667vw] 2xl:gap-y-[1.111vw] max-2xl:gap-y-6 2xl:rounded-t-[1.667vw] rounded-t-3xl outline outline-[#E2E2DC] bg-white">
<img
src='/images/logo.svg'
className='2xl:w-[5.972vw] w-[86px] cursor-pointer'
src="/images/logo.svg"
className="2xl:w-[5.972vw] w-[86px] cursor-pointer"
onClick={() => {
window.location.href = '/';
window.location.href = "/";
}}
alt='IRTH'
alt="IRTH"
/>
<p className='2xl:max-w-[17.083vw] text-s text-[#0D1922]/40 2xl:col-start-1 md:max-2xl:col-start-3 max-2xl:col-span-3 md:max-2xl:row-start-2 max-md:row-start-3 max-md:mt-12'>
<p className="2xl:max-w-[17.083vw] text-s text-[#0D1922]/40 2xl:col-start-1 md:max-2xl:col-start-3 max-2xl:col-span-3 md:max-2xl:row-start-2 max-md:row-start-3 md:max-2xl:mt-[52px] max-md:mt-12">
For more information, visit
<br />
our website: 
<Link
className='text-[#00BED7] md:underline'
to={'https://www.irth.ae'}
>
<Link className="text-[#00BED7] underline" to={"https://www.irth.ae"}>
www.irth.ae
</Link>
</p>
<div className='2xl:space-y-[0.833vw] space-y-3 md:max-2xl:col-start-3 max-2xl:col-span-3 md:max-2xl:row-start-3 max-md:row-start-4 max-md:mt-6'>
<p className='text-s text-[#0D1922]/40'>Follow us for more:</p>
<div className='flex 2xl:gap-[0.278vw] gap-1'>
<div className='2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded'>
<div className='2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70'>
<div className="2xl:space-y-[0.833vw] space-y-3 md:max-2xl:col-start-3 max-2xl:col-span-3 md:max-2xl:row-start-3 max-md:row-start-4 max-md:mt-6">
<p className="text-s text-[#0D1922]/40">Follow us for more:</p>
<div className="flex 2xl:gap-[0.278vw] gap-1">
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[2.222vw] 2xl:h-[2.222vw] md:max-2xl:w-8 md:max-2xl:h-8 w-9 h-9 text-[#0D1922]/70">
<YoutubeIcon />
</div>
</div>
<div className='2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded'>
<div className='2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70'>
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[2.222vw] 2xl:h-[2.222vw] md:max-2xl:w-8 md:max-2xl:h-8 w-9 h-9 text-[#0D1922]/70">
<InstagramIcon />
</div>
</div>
<div className='2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded'>
<div className='2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70'>
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[2.222vw] 2xl:h-[2.222vw] md:max-2xl:w-8 md:max-2xl:h-8 w-9 h-9 text-[#0D1922]/70">
<FacebookIcon />
</div>
</div>
<div className='2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded'>
<div className='2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70'>
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[2.222vw] 2xl:h-[2.222vw] md:max-2xl:w-8 md:max-2xl:h-8 w-9 h-9 text-[#0D1922]/70">
<LinkedInIcon />
</div>
</div>
<div className='2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded'>
<div className='2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 text-[#0D1922]/70'>
<div className="2xl:p-[0.417vw] p-1.5 bg-[#E2E2DC] 2xl:rounded-[0.278vw] rounded">
<div className="2xl:w-[2.222vw] 2xl:h-[2.222vw] md:max-2xl:w-8 md:max-2xl:h-8 w-9 h-9 text-[#0D1922]/70">
<TwitterIcon />
</div>
</div>
</div>
</div>
<div className='2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] pl-4 flex flex-col 2xl:col-start-4 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-3 col-start-1 max-md:mt-4'>
<div className="2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] pl-4 flex flex-col items-start 2xl:col-start-4 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-3 col-start-1">
<Link
to={'/'}
className='text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit'
to={"/"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
Map
</Link>
<Link
to={'/unit-types'}
className='text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit'
to={"/unit-types"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
Unit Types
</Link>
<Link
to={'/about-irth'}
className='text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit'
to={"/about-irth"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
About IRTH
</Link>
</div>
<div className='2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] pl-4 flex flex-col 2xl:col-start-5 2xl:row-start-1 2xl:row-span-2 max-2xl:col-span-2 max-md:mt-4'>
<div className="2xl:border-l-[0.069vw] border-l border-[#E2E2DC] 2xl:pl-[1.111vw] md:max-2xl:pl-6 pl-3.5 flex flex-col items-start 2xl:col-start-5 2xl:row-start-1 2xl:row-span-2">
<Link
to={'/favorites'}
className='text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit'
to={"/favorites"}
className="text-btn-l flex-1 content-center md:my-4 my-[13px] text-[#0D1922]/70"
>
Favorites
</Link>
<Link
to={'/search'}
className='text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit'
to={"/search"}
className="text-btn-l flex-1 content-center md:my-4 my-2.5 text-[#0D1922]/70"
>
Search
</Link>
<Link
to={'/'}
className='text-m flex-1 content-center max-2xl:py-2.5 text-[#0D1922]/70 w-fit'
>
Brochures
</Link>
<button className="text-btn-l flex-1 content-center md:my-3 text-[#0D1922]/70 flex items-center gap-2">
<span>Brochures</span>
<div className="2xl:w-[1.667vw] 2xl:h-[1.667vw] md:max-2xl:w-6 md:max-2xl:h-6 w-5 h-5">
<ChevronDownIcon />
</div>
</button>
</div>
<div className='content-end 2xl:text-right 2xl:col-start-6 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-1 md:max-2xl:row-start-3 max-md:col-span-3 max-md:pt-3 max-md:border-t border-[#E2E2DC]'>
<div className="content-end 2xl:text-right 2xl:col-start-6 2xl:row-start-1 2xl:row-span-2 md:max-2xl:col-start-1 md:max-2xl:row-start-3 max-md:col-span-3 max-md:pt-3 max-md:border-t border-[#E2E2DC]">
<Link
to={'/'}
className='2xl:text-caption-m text-caption-s max-2xl:text-[#73787C] text-[#0D1922]/70'
to={"/"}
className="md:text-caption-m text-caption-s max-2xl:text-[#73787C] text-[#0D1922]/70"
>
Privacy Policy
</Link>
+123 -76
View File
@@ -1,16 +1,17 @@
import { NavLink } from "react-router";
import { Link, NavLink } from "react-router";
import LocationIcon from "./icons/LocationIcon";
import clsx from "clsx";
import ArrowDownIcon from "./icons/ArrowDownIcon";
import { useState } from "react";
import Button from "./ui/Button";
import BurgerIcon from "./icons/BurgerIcon";
import EntranceIcon from "./icons/EntranceIcon";
import { AnimatePresence, motion } from "motion/react";
import DownloadIcon from "./icons/DownloadIcon";
import { useClickAway } from "@uidotdev/usehooks";
import CloseIcon from "./icons/CloseIcon";
import ChevronRightIcon from "./icons/ChevronRightIcon";
import { projects } from "../data/projects";
import useModalStore from "../stores/useModalStore";
import PrivacyPolicyModal from "./modals/PrivacyPolicyModal";
import ChevronDownIcon from "./icons/ChevronDownIcon";
function Header() {
function handleLogoClick() {
@@ -38,7 +39,7 @@ function Header() {
</div>
</div>
<Menu />
<div className="flex justify-end flex-1 max-md:hidden">
<div className="flex justify-end flex-1">
<ProfileBar />
</div>
</header>
@@ -50,9 +51,11 @@ export default Header;
function Menu() {
const [opened, setOpened] = useState(false);
const { setModal } = useModalStore();
return (
<>
<div className="max-2xl:order-2">
<div className="max-2xl:order-2 z-10">
<nav className="flex 2xl:gap-[0.278vw] gap-1 items-center max-2xl:hidden">
<NavItem href={"/"} title={"Map"} />
<NavItem href={"/unit-types"} title={"Unit Types"} />
@@ -67,59 +70,107 @@ function Menu() {
className="2xl:hidden !outline !outline-[#E2E2DC] md:mr-6 mr-4"
onClick={() => setOpened((prev) => !prev)}
>
<span className="w-5 h-5 text-[#0D1922]">
<div className="w-5 h-5">
{opened ? <CloseIcon /> : <BurgerIcon />}
</span>
</div>
</Button>
</div>
{/* <AnimatePresence>
<AnimatePresence mode="wait">
{opened && (
<motion.div
initial={{ opacity: 0, y: "-100%" }}
animate={{ opacity: 1, y: "0%" }}
exit={{ opacity: 0, y: "-100%" }}
transition={{ bounce: 0, duration: 0.3 }}
className="2xl:hidden absolute top-full md:p-4 p-3 bg-[#F3F3F2] w-full rounded-b-2xl flex flex-col gap-4 -z-20"
className="2xl:hidden absolute top-full md:p-4 p-3 w-full rounded-b-2xl flex flex-col gap-10 bg-white overflow-y-auto max-h-[calc(100dvh-56px)]"
>
<div className="grid md:grid-cols-2 md:grid-rows-3 gap-2">
<NavItem href={"/"} title={"Map"} />
<div className="space-y-4">
<p className="text-h3 font-medium">Projects</p>
<div className="flex gap-2 flex-wrap max-md:flex-col items-start">
{projects.map(({ img, title }, index) => (
<Link
key={index}
to={
title.endsWith("Dubai Marina")
? "/"
: `/complex/${title
.split(" ")
.slice(-2)
.join("-")
.toLowerCase()}`
}
className="p-1 pr-5 flex gap-2 items-center flex-nowrap ring-[#E2E2DC] ring-1 rounded-[40px]"
>
<img src={img} alt={title} className="w-10 h-10" />
<span className="text-s text-[#0D1922]/70">{title}</span>
</Link>
))}
<Link
to="/"
className="px-5 py-3.5 content-center ring-[#E2E2DC] ring rounded-[40px] text-s text-[#0D1922]/70"
>
Show on Map
</Link>
</div>
</div>
<div className="grid md:grid-cols-2 md:gap-4 gap-2">
<NavItem href={"/unit-types"} title={"Unit Types"} />
<NavItem href={"/about"} title={"About IRTH"} />
<NavItem href={"/favorites"} title={"Favorites"} />
<NavItem href={"/search"} title={"Search"} />
</div>
<hr className="border-[#E2E2DC] border" />
<p className="font-medium">Brochures</p>
<div className="max-2xl:hidden p-[0.278vw] flex gap-[0.278vw] z-0 justify-stretch items-stretch fixed top-[calc(3.889vw+20px)] left-[58.264vw] w-[32.222vw] rounded-[1.111vw] bg-white shadow-[0_2px_8px_rgba(0,0,0,0.15)]">
<div className="flex-1">
<p className="text-s font-medium px-[1.111vw] py-[0.833vw]">
Rove Home Marasi Drive
</p>
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
<div className="outline-[0.069vw] outline-[#E2E2DC]" />
<div className="flex-1">
<p className="text-s font-medium px-[1.111vw] py-[0.833vw]">
Rove Home Downtown
</p>
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
<hr className="border-[#E2E2DC]" />
<div className="space-y-6">
<p className="font-medium text-h3">Brochures</p>
<div className="p-[0.278vw] flex md:gap-[1.111vw] gap-6 z-0 justify-stretch items-stretch max-md:flex-col">
<div className="flex-1 space-y-4">
<p className="text-s font-medium">Rove Home Marasi Drive</p>
<div className="flex gap-2 flex-col">
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
</div>
<div className="flex-1 space-y-4">
<p className="text-s font-medium">Rove Home Downtown</p>
<div className="flex gap-2 flex-col">
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
</div>
</div>
</div>
<div className="pt-6 p-4 flex justify-between items-end bottom-0 left-0 w-full bg-white">
<p className="text-s text-[#0D1922]/40 max-w-[246px]">
For more information, visit our website:{" "}
<Link
to="https://www.irth.ae"
className="underline text-[#00BED7]"
>
www.irth.ae
</Link>
</p>
<Button
variant="tertiary"
size="small"
className="!px-3"
onClick={() => setModal(<PrivacyPolicyModal />)}
>
Privacy Policy
</Button>
</div>
</motion.div>
)}
</AnimatePresence> */}
</AnimatePresence>
</>
);
}
@@ -130,25 +181,22 @@ function NavItem({ href, title }: { href: string; title: string }) {
to={href}
className={({ isActive }) =>
clsx(
"text-m 2xl:px-[1.25vw] 2xl:py-[0.903vw] p-4 max-2xl:bg-[#FFFFFF]/80 2xl:rounded-[0.833vw] rounded-xl transition-colors duration-300 !leading-none text-[#0D1922]/70 flex items-center justify-between",
"text-btn-m 2xl:px-[1.25vw] 2xl:py-[0.903vw] p-4 2xl:rounded-[0.833vw] rounded-xl transition-colors duration-300 !leading-none max-2xl:text-center max-2xl:bg-[#F3F3F2]",
isActive && "2xl:bg-[#00BED7] 2xl:text-[#FFFFFF]"
)
}
>
{title}
<span className="w-5 h-5 2xl:hidden">
<ChevronRightIcon />
</span>
</NavLink>
);
}
function ProfileBar() {
return (
<Button className="2xl:mr-[2.222vw] mr-4 text-[#0D1922]/70">
<span className="2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5">
<EntranceIcon />
</span>
<Button
variant="secondary"
className="2xl:mr-[2.222vw] mr-4 text-[#0D1922]/70 !bg-[#F3F3F2]"
>
Login
</Button>
);
@@ -166,14 +214,14 @@ function BrochuresDropdown() {
className="2xl:px-[0.972vw] 2xl:py-[0.694vw] px-3.5 py-2.5 flex items-center max-2xl:hidden"
onClick={() => setOpened((prev) => !prev)}
>
<span className="text-[0.972vw] leading-none">Brochures</span>
<span className="text-btn-m text-[#0D1922]">Brochures</span>
<span
className={clsx(
"text-[#0D1922]/70 2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 transition-transform duration-300",
"2xl:w-[1.389vw] 2xl:h-[1.389vw] w-5 h-5 transition-transform duration-300",
opened && "rotate-180"
)}
>
<ArrowDownIcon />
<ChevronDownIcon />
</span>
</Button>
<AnimatePresence>
@@ -183,32 +231,31 @@ function BrochuresDropdown() {
animate={{ opacity: 1, x: "0%" }}
exit={{ opacity: 0, x: "100%" }}
transition={{ bounce: 0, duration: 0.3 }}
className="max-2xl:hidden p-[0.278vw] flex gap-[0.278vw] z-0 justify-stretch items-stretch fixed top-[calc(3.889vw+20px)] left-[58.264vw] w-[32.222vw] rounded-[1.111vw] bg-white shadow-[0_2px_8px_rgba(0,0,0,0.15)]"
className="max-2xl:hidden p-[1.667vw] flex gap-[1.111vw] z-0 justify-stretch items-stretch fixed top-[calc(3.889vw+20px)] left-[58.264vw] w-[32.222vw] rounded-[1.111vw] bg-white shadow-[0_2px_8px_rgba(0,0,0,0.15)]"
>
<div className="flex-1">
<p className="text-s font-medium px-[1.111vw] py-[0.833vw]">
Rove Home Marasi Drive
</p>
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
<div className="flex-1 space-y-4">
<p className="text-s font-medium">Rove Home Marasi Drive</p>
<div className="flex flex-col gap-[0.556vw]">
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
</div>
<div className="outline-[0.069vw] outline-[#E2E2DC]" />
<div className="flex-1">
<p className="text-s font-medium px-[1.111vw] py-[0.833vw]">
Rove Home Downtown
</p>
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
<div className="flex-1 space-y-4">
<p className="text-s font-medium">Rove Home Downtown</p>
<div className="flex flex-col gap-[0.556vw]">
{[
"Rove Main Brochure",
"Rove Amenties Brochure",
"Rove Technical Brochure",
].map((title) => (
<BrochureButton title={title} key={title} />
))}
</div>
</div>
</motion.div>
)}
@@ -222,7 +269,7 @@ export function BrochureButton({ title }: { title: string }) {
<Button
variant="secondary"
size="large"
className="w-full !bg-[#FFFFFF]/80 !rounded-lg !justify-between group hover:!bg-[#F3F3F2]"
className="w-full !bg-[#F3F3F2] !justify-between group hover:!bg-[#F3F3F2]"
>
<span className="text-nowrap text-caption-m group-hover:text-[#0D1922] transition-colors duration-300">
{title}
+2 -2
View File
@@ -661,7 +661,7 @@ function Map({ maxZoom = 1 }: MapProps) {
<TouchIcon />
</span>
</div>
<p className="text-sm text-center">Tap to move</p>
<p className="text-s text-center">Tap to move</p>
</div>
</motion.div>
) : (
@@ -681,7 +681,7 @@ function Map({ maxZoom = 1 }: MapProps) {
<MoveIcon />
</span>
</div>
<p className="text-sm">Zoom and Move to select a location</p>
<p className="text-s">Zoom and Move to select a location</p>
</div>
</motion.div>
))}
+24 -8
View File
@@ -4,16 +4,20 @@ import { useEffect, useState } from "react";
import Project from "../types/Project";
import Select from "./ui/Select";
function ProjectSelect({
function ProjectSelect<T extends boolean = false>({
projects,
onSelect,
defaultProject,
withAll,
}: {
projects: Project[];
onSelect: (project: Project) => void;
defaultProject: Project;
onSelect: (project: Project | null) => void;
defaultProject: T extends false ? Project : null;
withAll?: T;
}) {
const [selectedProject, setSelectedProject] = useState(defaultProject);
const [selectedProject, setSelectedProject] = useState<Project | null>(
defaultProject
);
useEffect(() => setSelectedProject(defaultProject), [defaultProject]);
@@ -22,12 +26,23 @@ function ProjectSelect({
return (
<>
<div className="flex 2xl:gap-[0.556vw] gap-2 max-md:hidden">
{withAll && (
<div
className={clsx(
"2xl:rounded-[2.778vw] rounded-[40px] 2xl:py-[0.972vw] 2xl:px-[1.389vw] p-1 flex items-center 2xl:gap-[0.556vw] gap-2 text-s 2xl:ring-[0.069vw] ring transition-[box-shadow] cursor-pointer",
!selectedProject ? "ring-[#00BED7]" : "ring-[#E2E2DC]"
)}
onClick={() => setSelectedProject(null)}
>
All Projects
</div>
)}
{projects.map((project) => (
<div
key={project.title}
className={clsx(
"2xl:rounded-[2.778vw] rounded-[40px] 2xl:p-[0.278vw] p-1 flex items-center 2xl:gap-[0.556vw] gap-2 text-s 2xl:ring-[0.069vw] ring transition-[box-shadow] cursor-pointer",
project.title === selectedProject.title
selectedProject && project.title === selectedProject.title
? "ring-[#00BED7]"
: "ring-[#E2E2DC]"
)}
@@ -41,7 +56,9 @@ function ProjectSelect({
<p
className={clsx(
"2xl:mr-[1.111vw] mr-6",
selectedProject.title !== project.title && "text-[#0D1922]/70"
selectedProject &&
selectedProject.title !== project.title &&
"text-[#0D1922]/70"
)}
>
{project.title}
@@ -49,7 +66,6 @@ function ProjectSelect({
</div>
))}
</div>
<Select
options={projects.map((project) => project.title)}
onSelect={(option) =>
@@ -58,7 +74,7 @@ function ProjectSelect({
defaultProject
)
}
defaultOption={defaultProject.title}
defaultOption={defaultProject ? defaultProject.title : "All"}
className="md:hidden"
/>
</>
+5 -4
View File
@@ -340,10 +340,11 @@ function SearchFilters({
});
}, [debouncedFloor, debouncedFloorTouched]);
function handleSelectProject(project: Project) {
setProject(project.title);
function handleSelectProject(project: Project | null) {
setProject(project?.title);
setSearchParams((prev) => {
prev.set("project", project.title);
if (project) prev.set("project", project.title);
else prev.delete("project");
return prev;
});
}
@@ -431,7 +432,7 @@ function SearchFilters({
)}
<div className="2xl:space-y-[2.222vw] space-y-8">
<div className="2xl:space-y-[1.111vw] space-y-4">
<p className="2xl:text-[2.222vw] md:max-2xl:text-[32px] text-2xl font-medium leading-[135%]">
<p className="text-h2 font-medium">
{inModal ? "Filters" : "Search"}
</p>
<div className={clsx(!inModal && "max-md:hidden")}>
+1 -1
View File
@@ -56,7 +56,7 @@ function UnitCard({ unit }: { unit: IUnit }) {
maximumFractionDigits: 2,
})} Sqft`}
</p>
<p className="text-[#00BED7] text-subheadline-s font-medium">
<p className="text-[#00BED7] text-h4 font-medium">
{`AED ${Intl.NumberFormat("ar-AE", {
currency: "AED",
minimumFractionDigits: 0,
+1 -1
View File
@@ -18,7 +18,7 @@ function UnitTypeCard({ project, type }: { project: string; type: UnitType }) {
<img src={type.img} alt="" />
<div className="space-y-1 2xl:space-y-[0.278vw]">
<p className="text-s text-[#0D1922]/70">{type.area}</p>
<p className="text-subheadline-s font-medium">{type.name}</p>
<p className="text-h4 font-medium">{type.name}</p>
</div>
</div>
);
+6 -6
View File
@@ -1,24 +1,24 @@
export default function DisclaimerModal() {
return (
<div className="bg-white z-40 2xl:rounded-[0.556vw] rounded-lg py-[37px] px-8 2xl:w-[29.236vw] md:max-2xl:w-[54.818vw] w-full">
<h2 className="text-subheadline-m font-medium py-6 2xl:border-t-[0.139vw] border-t-2 border-[#00BED7] w-fit">
<h3 className="text-h3 font-medium py-6 2xl:border-t-[0.139vw] border-t-2 border-[#00BED7] w-fit">
Disclaimer
</h2>
</h3>
<div className="flex flex-col gap-4">
<p className="text-caption-m">
<p className="text-s">
This masterplan has been designed solely to provide an impression of
the Rove Home projects as well as the approximate location of existing
and proposed facilities, services, and destinations and is not
intended for any other purpose.
</p>
<p className="text-caption-m">
<p className="text-s">
All elements including the interior design used in the units and
images shown in the virtual tour are only for illustration. The
pictures of the proposed residential units, furniture, landscaping,
amenities, color schemes, fixtures, and accessories among all other
items are illustrative to showcase the units.
</p>
<p className="text-caption-m">
<p className="text-s">
IRTH does not make any representation or give any warranty concerning
the future developments shown, or the current or future amenities,
location, or existence of any facilities, services, and destinations.
@@ -26,7 +26,7 @@ export default function DisclaimerModal() {
information are approximate and for indicative purposes only and are
not to scale.
</p>
<p className="text-caption-m">
<p className="text-s">
IRTH gives notice that this virtual tour (including units, amenities,
plans of the property) does not constitute any part of a sale offer or
sale and purchase contract.
+2 -2
View File
@@ -2,9 +2,9 @@ function PrivacyPolicyModal() {
return (
<div className="2xl:rounded-[1.111vw] bg-white rounded-2xl 2xl:p-[2.222vw] 2xl:w-[38.889vw] p-8">
<div className="bg-[#00BED7] 2xl:h-[0.139vw] h-0.5 2xl:w-[8.646vw] 2xl:rounded-[0.208vw] rounded-[3px]" />
<h2 className="text-subheadline-m font-medium py-6">
<h3 className="text-h3 font-medium py-6">
Privacy Policy for IRTH Group and its companies:
</h2>
</h3>
<div className="space-y-4">
<p className="text-caption-s">
At IRTH Group and its companies, we are committed to protecting the
+6
View File
@@ -0,0 +1,6 @@
export const SORT_OPTIONS = {
"Sort by ascending price": "cost asc",
"Sort by descending price": "cost desc",
"Sort by ascending area": "sqft asc",
"Sort by descending area": "sqft desc",
};
+58
View File
@@ -47,4 +47,62 @@ button {
.text-caption-s {
@apply 2xl:text-[clamp(10px,0.694vw,12px)] text-[10px] leading-[135%];
}
/* */
.text-h1 {
@apply 2xl:text-[3.889vw] text-[56px] leading-none;
}
.text-h15 {
@apply 2xl:text-[2.778vw] text-[40px] leading-[135%];
}
.text-h2 {
@apply 2xl:text-[2.222vw] text-[32px] leading-[125%];
}
.text-h3 {
@apply 2xl:text-[1.667vw] text-[24px] leading-[135%];
}
.text-h4 {
@apply 2xl:text-[1.389vw] text-[20px] leading-[120%];
}
.text-h5 {
@apply 2xl:text-[0.972vw] text-sm leading-[125%];
}
.text-l {
@apply 2xl:text-[1.389vw] text-[20px] leading-[135%];
}
.text-m {
@apply 2xl:text-[1.111vw] leading-[125%];
}
.text-s {
@apply 2xl:text-[0.972vw] text-sm leading-[140%];
}
.text-btn-l {
@apply 2xl:text-[1.111vw] leading-none;
}
.text-bnt-m {
@apply 2xl:text-[0.972vw] text-sm leading-none;
}
.text-btn-s {
@apply 2xl:text-[0.833vw] text-xs leading-none;
}
.text-caption-m {
@apply 2xl:text-[0.833vw] text-xs leading-[135%];
}
.text-caption-s {
@apply 2xl:text-[0.694vw] text-[10px] leading-[135%];
}
}
+42 -30
View File
@@ -1,52 +1,64 @@
import clsx from 'clsx';
import ProjectSelect from '../components/ProjectSelect';
import { projects } from '../data/projects';
import Select from '../components/ui/Select';
import Button from '../components/ui/Button';
import ChartIcon from '../components/icons/ChartIcon';
import { useFavoritesUnitsStore } from '../stores/useFavoritesUnitsStore';
import UnitCard from '../components/UnitCard';
import clsx from "clsx";
import ProjectSelect from "../components/ProjectSelect";
import { projects } from "../data/projects";
import Select from "../components/ui/Select";
import Button from "../components/ui/Button";
import ChartIcon from "../components/icons/ChartIcon";
import { useFavoritesUnitsStore } from "../stores/useFavoritesUnitsStore";
import UnitCard from "../components/UnitCard";
import { useState } from "react";
import { SORT_OPTIONS } from "../data/sortOptions";
function FavoritesPage() {
const { favoriteUnits } = useFavoritesUnitsStore();
const [sort, setSort] = useState<keyof typeof SORT_OPTIONS>(
"Sort by ascending price"
);
const [selectedProject, setSelectedProject] = useState<string>();
return (
<div className='flex flex-col gap-6'>
<div className="flex flex-col gap-6">
<div
className={clsx(
'2xl:p-[2.222vw] md:max-2xl:p-6 p-4 bg-white 2xl:rounded-b-[1.667vw] rounded-b-3xl 2xl:space-y-[2.222vw] md:max-2xl:space-y-8 space-y-4',
'2xl:px-[2.222vw] md:max-2xl:px-6 px-4'
"2xl:p-[2.222vw] md:max-2xl:p-6 p-4 bg-white 2xl:rounded-b-[1.667vw] rounded-b-3xl 2xl:space-y-[2.222vw] md:max-2xl:space-y-8 space-y-4",
"2xl:px-[2.222vw] md:max-2xl:px-6 px-4"
)}
>
<div className='2xl:space-y-[1.111vw] space-y-4'>
<p className='2xl:text-[2.222vw] md:max-2xl:text-[32px] text-2xl font-medium leading-[135%]'>
Favorites
</p>
<div className="2xl:space-y-[1.111vw] space-y-4">
<p className="text-h2 font-medium">Favorites</p>
<ProjectSelect
projects={projects}
onSelect={() => {}}
defaultProject={projects[0]}
onSelect={(project) => setSelectedProject(project?.title)}
defaultProject={null}
withAll
/>
</div>
</div>
<div className='px-8'>
<div className='flex gap-4'>
<div className="2xl:px-[2.222vw] md:max-2xl:px-6 px-4">
<div className="flex 2xl:gap-[1.111vw] gap-4">
<Select
options={['All', 'Favorites']}
onSelect={() => {}}
defaultOption='All'
className='w-[22.778vw]'
options={Object.keys(SORT_OPTIONS)}
defaultOption={sort}
onSelect={(opt) => setSort(opt as keyof typeof SORT_OPTIONS)}
className="2xl:w-[22.778vw] md:max-2xl:max-w-[45.833vw]"
/>
<Button variant='secondary' size='large' className='text-black'>
<div className='2xl:w-[1.667vw] 2xl:h-[1.667vw] w-6 h-6'>
<Button variant="secondary" size="large">
<div className="2xl:w-[1.667vw] 2xl:h-[1.667vw] w-6 h-6">
<ChartIcon />
</div>
<p className='text-m leading-0'>Compare</p>
<p className="text-btn-l">Compare</p>
</Button>
</div>
<div className='2xl:grid-cols-4 md:max-2xl:grid-cols-2 grid 2xl:gap-[1.111vw] gap-4 py-6'>
{favoriteUnits.map((unit) => (
<UnitCard key={unit.id} unit={unit} />
))}
<div className="2xl:grid-cols-4 md:max-2xl:grid-cols-2 grid 2xl:gap-[1.111vw] gap-4 py-6">
{favoriteUnits
.filter(
(unit) => !selectedProject || unit.project === selectedProject
)
.map((unit) => (
<UnitCard key={unit.id} unit={unit} />
))}
</div>
</div>
</div>
+1 -7
View File
@@ -13,13 +13,7 @@ import { AnimatePresence, motion } from "motion/react";
import { useDebounce } from "../hooks/useDebounce";
import Select from "../components/ui/Select";
import Skeleton from "react-loading-skeleton";
const SORT_OPTIONS = {
"Sort by ascending price": "cost asc",
"Sort by descending price": "cost desc",
"Sort by ascending area": "sqft asc",
"Sort by descending area": "sqft desc",
};
import { SORT_OPTIONS } from "../data/sortOptions";
const STEP = 12;
+6 -4
View File
@@ -4,9 +4,11 @@ import { projects } from "../data/projects";
import clsx from "clsx";
import UnitTypeCard from "../components/UnitTypeCard";
import { AnimatePresence, motion } from "motion/react";
import Project from "../types/Project";
function UnitTypesPage() {
const [selectedProject, setSelectedProject] = useState(projects[0]);
const [selectedProject, setSelectedProject] = useState<Project | null>(
projects[0]
);
return (
<div className="">
@@ -29,13 +31,13 @@ function UnitTypesPage() {
<AnimatePresence mode="wait">
<motion.div
layout
key={selectedProject.title}
key={selectedProject?.title}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="m-4 md:max-2xl:m-6 2xl:m-[2.222vw] grid grid-cols-1 md:max-2xl:grid-cols-2 2xl:grid-cols-4 gap-4 2xl:gap-[1.111vw]"
>
{selectedProject.types?.map((type, index) => (
{selectedProject?.types?.map((type, index) => (
<UnitTypeCard
key={index}
project={selectedProject.title}