This commit is contained in:
2024-08-08 19:24:04 +05:00
parent 3c148129f7
commit 6a737c2d49
47 changed files with 672 additions and 95 deletions
+1
View File
@@ -18,6 +18,7 @@
"ky": "^1.3.0",
"lodash": "^4.17.21",
"multi-range-slider-react": "^2.0.7",
"openmeteo": "^1.1.4",
"react": "^18.2.0",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

+32 -65
View File
@@ -1,72 +1,39 @@
import { weatherApi } from "./urls";
/**
*
*
*/
type WeatherRes = {
cod: string;
message: number;
cnt: number;
list: {
dt: number;
main: {
temp: number;
feels_like: number;
temp_min: number;
temp_max: number;
pressure: number;
sea_level: number;
grnd_level: number;
humidity: number;
temp_kf: number;
};
weather: {
id: number;
main: string;
description: string;
icon: string;
}[];
clouds: {
all: number;
};
wind: {
speed: number;
deg: number;
gust: number;
};
visibility: number;
pop: number;
sys: {
pod: string;
};
dt_txt: string;
}[];
city: {
id: number;
name: string;
coord: {
lat: number;
lon: number;
};
country: string;
population: number;
timezone: number;
sunrise: number;
sunset: number;
};
};
import { fetchWeatherApi } from "openmeteo";
async function getWeather() {
const response = await fetch(weatherApi);
const fetchedData: WeatherRes = await response.json();
const params = {
latitude: 25.0772,
longitude: 55.3093,
current: "temperature_2m",
};
const url = "https://api.open-meteo.com/v1/forecast";
const responses = await fetchWeatherApi(url, params);
const listByDay = fetchedData.list.filter((day) =>
day.dt_txt.endsWith("15:00:00")
);
// Helper function to form time ranges
// const range = (start: number, stop: number, step: number) =>
// Array.from({ length: (stop - start) / step }, (_, i) => start + i * step);
return listByDay;
// Process first location. Add a for-loop for multiple locations or weather models
const response = responses[0];
// Attributes for timezone and location
const utcOffsetSeconds = response.utcOffsetSeconds();
// const timezone = response.timezone();
// const timezoneAbbreviation = response.timezoneAbbreviation();
// const latitude = response.latitude();
// const longitude = response.longitude();
const current = response.current()!;
// Note: The order of weather variables in the URL query and the indices below need to match!
const weatherData = {
current: {
time: new Date((Number(current.time()) + utcOffsetSeconds) * 1000),
temperature2m: current.variables(0)!.value(),
},
};
return weatherData.current.temperature2m;
}
export { getWeather };
@@ -0,0 +1,21 @@
interface Props {
title: string;
image: string;
}
function AdvantageCard({ title, image }: Props) {
return (
<div className="space-y-3 ">
<div className="flex">
<img src={image} alt="" className="aspect-video rounded-2xl w-full object-cover" />
</div>
<div className="flex items-center gap-1">
<div className="w-3 h-3 bg-[#00BED7] rounded-full"></div>
<p className="leading-[20px]">{title}</p>
</div>
</div>
);
}
export default AdvantageCard;
@@ -0,0 +1,22 @@
interface Props {
title: string;
desc: string;
image: string;
}
function AboutProjectPlaceCard({ title, desc, image }: Props) {
return (
<div className="bg-white rounded-2xl flex flex-col gap-2 p-3">
<div className="space-y-1">
<div className="flex items-center gap-1">
<div className="w-3 h-3 bg-[#00BED7] rounded-full"></div>
<p className="leading-[20px]">{title}</p>
</div>
<p className="text-[#73787C] text-sm leading-[20px]">{desc}</p>
</div>
<img src={image} alt="" className="w-16 h-16 self-end rounded-xl" />
</div>
);
}
export default AboutProjectPlaceCard;
@@ -0,0 +1,40 @@
interface Props {
title: string;
desc1: string;
desc2: string;
square: number;
price: number;
image: string;
}
function UnitCard({ title, desc1, desc2, square, price, image }: Props) {
return (
<div className="grid grid-cols-2">
<div className="p-10 flex flex-col justify-between gap-4 bg-white rounded-2xl">
<div className="space-y-4">
<p className="text-2xl text-[#0D1922] font-semibold">{title}</p>
<div className="space-y-2.5 leading-[20px]">
<p>{desc1}</p>
<p>{desc2}</p>
</div>
</div>
<div className="space-y-1">
<p className="text-sm text-[#0D1922]">{square} Sqft</p>
<p className="text-xl text-[#00BED7] font-semibold">
AED {Intl.NumberFormat("ar-AE").format(price)}
</p>
</div>
</div>
<div className="relative">
<div className="absolute h-full w-[10%] -translate-x-[50%] bg-white rounded-r-2xl"></div>
<img
src={image}
alt=""
className="w-full h-full aspect-square object-cover rounded-r-2xl"
/>
</div>
</div>
);
}
export default UnitCard;
+1 -1
View File
@@ -10,7 +10,7 @@ interface Props {
const variantClasses = {
primary: "bg-[#00BED7] text-white hover:bg-[#0AB3C9]",
secondary: "",
secondary: "bg-white hover:text-[#0D1922]",
};
const sizeClasses = {
@@ -0,0 +1,23 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { ReactNode, useEffect, useRef } from "react";
interface Props {
element: ReactNode;
className: string;
}
function ClassNameWrapper({ element, className }: Props) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!className.split(" ").length) return;
ref.current?.children
.item(0)
?.classList.add(...className.split(" ").filter(Boolean));
}, []);
return <div ref={ref}>{element}</div>;
}
export default ClassNameWrapper;
+77
View File
@@ -0,0 +1,77 @@
import FacebookIcon from "./icons/FacebookIcon";
import InstagramIcon from "./icons/InstagramIcon";
import LinkedInIcon from "./icons/LinkedInIcon";
import Logo2Icon from "./icons/Logo2Icon";
import TwitterIcon from "./icons/TwitterIcon";
import YoutubeIcon from "./icons/YoutubeIcon";
import SocialButton from "./SocialButton";
function Footer2() {
return (
<div className="bg-white p-10 rounded-t-2xl">
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col justify-between">
<Logo2Icon />
<div className="flex gap-10">
<p className="text-[#0D192266] text-sm">
For more information, visit our
<br />
website:{" "}
<a
href="https://www.irth.ae"
target="_blank"
className="text-[#00BED7]"
>
www.irth.ae
</a>
</p>
<div className="space-y-3">
<p className="text-[#0D192266] text-sm">Follow us for more:</p>
<div className="flex gap-1">
<SocialButton
icon={<YoutubeIcon />}
to="https://www.youtube.com/@IRTHgroup"
/>
<SocialButton
icon={<InstagramIcon />}
to="https://www.facebook.com/irth.group"
/>
<SocialButton
icon={<FacebookIcon />}
to="https://www.instagram.com/irth.group/"
/>
<SocialButton
icon={<LinkedInIcon />}
to="https://www.linkedin.com/company/irth-group-uae"
/>
<SocialButton
icon={<TwitterIcon />}
to="https://twitter.com/IRTHGroup"
/>
</div>
</div>
</div>
</div>
<div className="grid grid-cols-3 gap-4">
<div className="border-l border-[#E2E2DC] px-6 py-3.5 flex flex-col items-start gap-6">
<a href="/masterplan">Map</a>
<a href="/unit-types">Unit Types</a>
<a href="/about">About IRTH</a>
</div>
<div className="border-l border-[#E2E2DC] px-6 py-3.5 flex flex-col items-start gap-6">
<a href="/favorites">Favorites</a>
<a href="/search">Search</a>
{/* <a href="#">Brochures</a> */}
</div>
<div className="px-2.5 py-1 flex flex-col items-end justify-end gap-6">
<a href="#" className="text-xs font-semibold">
Privacy Policy
</a>
</div>
</div>
</div>
</div>
);
}
export default Footer2;
+21
View File
@@ -0,0 +1,21 @@
interface Props {
icon: JSX.Element;
to?: string;
className?: string;
onClick?: () => void;
}
function SocialButton({ icon, to, className = "", onClick }: Props) {
return (
<a
href={to}
target="_blank"
className={`p-1.5 bg-[#E2E2DC] rounded ${className}`}
onClick={onClick}
>
{icon}
</a>
);
}
export default SocialButton;
@@ -0,0 +1,23 @@
interface Props {
className?: string;
}
function FacebookIcon({ className }: Props) {
return (
<svg
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M11.8337 2.39575C10.8115 2.39575 9.83115 2.80181 9.10835 3.52461C8.38555 4.24741 7.97949 5.22773 7.97949 6.24992V8.39575H5.91699C5.81344 8.39575 5.72949 8.4797 5.72949 8.58325V11.4166C5.72949 11.5201 5.81344 11.6041 5.91699 11.6041H7.97949V17.4166C7.97949 17.5201 8.06344 17.6041 8.16699 17.6041H11.0003C11.1039 17.6041 11.1878 17.5201 11.1878 17.4166V11.6041H13.2686C13.3546 11.6041 13.4296 11.5455 13.4505 11.4621L14.1588 8.62873C14.1884 8.51039 14.0989 8.39575 13.9769 8.39575H11.1878V6.24992C11.1878 6.07863 11.2559 5.91436 11.377 5.79325C11.4981 5.67213 11.6624 5.60409 11.8337 5.60409H14.0003C14.1039 5.60409 14.1878 5.52014 14.1878 5.41659V2.58325C14.1878 2.4797 14.1039 2.39575 14.0003 2.39575H11.8337Z"
fill="currentColor"
/>
</svg>
);
}
export default FacebookIcon;
@@ -0,0 +1,23 @@
interface Props {
className?: string;
}
function InstagramIcon({ className }: Props) {
return (
<svg
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M13.75 1.875H6.25C5.09006 1.87624 3.97798 2.33758 3.15778 3.15778C2.33758 3.97798 1.87624 5.09006 1.875 6.25V13.75C1.87624 14.9099 2.33758 16.022 3.15778 16.8422C3.97798 17.6624 5.09006 18.1238 6.25 18.125H13.75C14.9099 18.1238 16.022 17.6624 16.8422 16.8422C17.6624 16.022 18.1238 14.9099 18.125 13.75V6.25C18.1238 5.09006 17.6624 3.97798 16.8422 3.15778C16.022 2.33758 14.9099 1.87624 13.75 1.875ZM10 13.75C9.25832 13.75 8.5333 13.5301 7.91661 13.118C7.29993 12.706 6.81928 12.1203 6.53545 11.4351C6.25162 10.7498 6.17736 9.99584 6.32206 9.26841C6.46675 8.54098 6.8239 7.8728 7.34835 7.34835C7.8728 6.8239 8.54098 6.46675 9.26841 6.32206C9.99584 6.17736 10.7498 6.25162 11.4351 6.53545C12.1203 6.81928 12.706 7.29993 13.118 7.91661C13.5301 8.5333 13.75 9.25832 13.75 10C13.749 10.9942 13.3535 11.9475 12.6505 12.6505C11.9475 13.3535 10.9942 13.749 10 13.75ZM14.6875 6.25C14.5021 6.25 14.3208 6.19502 14.1667 6.092C14.0125 5.98899 13.8923 5.84257 13.8214 5.67127C13.7504 5.49996 13.7318 5.31146 13.768 5.1296C13.8042 4.94775 13.8935 4.7807 14.0246 4.64959C14.1557 4.51848 14.3227 4.42919 14.5046 4.39301C14.6865 4.35684 14.875 4.37541 15.0463 4.44636C15.2176 4.51732 15.364 4.63748 15.467 4.79165C15.57 4.94582 15.625 5.12708 15.625 5.3125C15.625 5.56114 15.5262 5.7996 15.3504 5.97541C15.1746 6.15123 14.9361 6.25 14.6875 6.25ZM12.5 10C12.5 10.4945 12.3534 10.9778 12.0787 11.3889C11.804 11.8 11.4135 12.1205 10.9567 12.3097C10.4999 12.4989 9.99723 12.5484 9.51227 12.452C9.02732 12.3555 8.58186 12.1174 8.23223 11.7678C7.8826 11.4181 7.6445 10.9727 7.54804 10.4877C7.45157 10.0028 7.50108 9.50011 7.6903 9.04329C7.87952 8.58648 8.19995 8.19603 8.61107 7.92133C9.0222 7.64662 9.50555 7.5 10 7.5C10.663 7.5 11.2989 7.76339 11.7678 8.23223C12.2366 8.70107 12.5 9.33696 12.5 10Z"
fill="currentColor"
/>
</svg>
);
}
export default InstagramIcon;
@@ -0,0 +1,31 @@
interface Props {
className?: string;
}
function LinkedInIcon({ className }: Props) {
return (
<svg
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M3.95833 1.5625C2.98033 1.5625 2.1875 2.35533 2.1875 3.33333C2.1875 4.31134 2.98033 5.10417 3.95833 5.10417C4.93634 5.10417 5.72917 4.31134 5.72917 3.33333C5.72917 2.35533 4.93634 1.5625 3.95833 1.5625Z"
fill="currentColor"
/>
<path
d="M2.29167 6.5625C2.23414 6.5625 2.1875 6.60914 2.1875 6.66667V17.5C2.1875 17.5575 2.23414 17.6042 2.29167 17.6042H5.625C5.68253 17.6042 5.72917 17.5575 5.72917 17.5V6.66667C5.72917 6.60914 5.68253 6.5625 5.625 6.5625H2.29167Z"
fill="currentColor"
/>
<path
d="M7.70833 6.5625C7.6508 6.5625 7.60417 6.60914 7.60417 6.66667V17.5C7.60417 17.5575 7.6508 17.6042 7.70833 17.6042H11.0417C11.0992 17.6042 11.1458 17.5575 11.1458 17.5V11.6667C11.1458 11.2523 11.3105 10.8548 11.6035 10.5618C11.8965 10.2688 12.2939 10.1042 12.7083 10.1042C13.1227 10.1042 13.5202 10.2688 13.8132 10.5618C14.1062 10.8548 14.2708 11.2523 14.2708 11.6667V17.5C14.2708 17.5575 14.3175 17.6042 14.375 17.6042H17.7083C17.7659 17.6042 17.8125 17.5575 17.8125 17.5V10.3169C17.8125 8.29458 16.0537 6.7125 14.0415 6.89542C13.421 6.95183 12.8075 7.10609 12.2346 7.35162L11.1458 7.81822V6.66667C11.1458 6.60914 11.0992 6.5625 11.0417 6.5625H7.70833Z"
fill="currentColor"
/>
</svg>
);
}
export default LinkedInIcon;
+37
View File
@@ -0,0 +1,37 @@
function Logo2Icon() {
return (
<svg
width={86}
height={24}
viewBox="0 0 86 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_2242_54525)">
<path
d="M10.3982 0H0L2.49306 1.87928V22.1237L0 24H10.3982L7.90218 22.1237V1.87928L10.3982 0Z"
fill="#0D1922"
/>
<path
d="M83.5038 1.87928L85.9999 0H75.6016L78.0947 1.87928V11.2486H68.4735V1.87928L70.9665 0H60.5713L63.0644 1.87928V22.1237L60.5713 24H70.9665L68.4735 22.1237V12.2033H78.0947V22.1237L75.6016 24H85.9999L83.5038 22.1237V1.87928Z"
fill="#0D1922"
/>
<path
d="M57.6044 0H37.543L37.546 6.28536L40.633 0.954699H44.8931V22.1237L42.4001 24H52.7983L50.3023 22.1237V0.954699H54.5414L57.6254 6.28536V0.00602334L57.6044 0.0120467V0Z"
fill="#0D1922"
/>
<path
d="M21.2853 0.904414H23.7483C23.7483 0.904414 28.1554 0.741784 28.3204 5.36771C28.4854 9.99364 26.9704 12.3397 22.4913 12.1229V13.0234H24.2853L29.6075 24.0009H37.8847L34.8306 21.6518L29.8835 13.4179C29.8835 13.4179 26.9194 13.0746 26.3374 12.7523C26.3164 12.7523 34.1976 12.4692 34.2006 5.76224C34.2006 5.74417 34.6566 -0.00812154 24.8404 0.00392515L13.3711 0.0189835L15.8642 1.89525V22.1216L13.3711 24.0009H23.7693L21.2763 22.1216L21.2913 0.901403L21.2853 0.904414Z"
fill="#0D1922"
/>
</g>
<defs>
<clipPath id="clip0_2242_54525">
<rect width={86} height={24} fill="currentColor" />
</clipPath>
</defs>
</svg>
);
}
export default Logo2Icon;
@@ -0,0 +1,31 @@
interface Props {
className?: string;
}
function TwitterIcon({ className }: Props) {
return (
<svg
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M16.8207 16.6829L11.3222 8.69488L10.7006 7.79144L6.7675 2.0773L6.44149 1.60376H1.6084L2.78714 3.31669L8.01683 10.9152L8.63846 11.8177L12.8404 17.9229L13.1664 18.396H17.9995L16.8207 16.6831V16.6829ZM13.7408 17.3026L9.3753 10.96L8.75367 10.0571L3.68809 2.69713H5.8671L9.96377 8.64929L10.5854 9.55217L15.9199 17.3026H13.7409H13.7408Z"
fill="currentColor"
/>
<path
d="M8.75404 10.0569L9.37566 10.9598L8.63869 11.8175L2.98422 18.3957H1.58984L8.01706 10.915L8.75404 10.0569Z"
fill="currentColor"
/>
<path
d="M17.4177 1.60376L11.3225 8.69488L10.5855 9.55203L9.96387 8.64915L10.7008 7.79144L14.8297 2.98571L16.0234 1.60376H17.4177Z"
fill="currentColor"
/>
</svg>
);
}
export default TwitterIcon;
@@ -0,0 +1,20 @@
function YoutubeIcon() {
return (
<svg
width={20}
height={20}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M16.512 4.51942C17.2291 4.71335 17.7938 5.28486 17.9855 6.01043C18.3337 7.32568 18.3337 10.0697 18.3337 10.0697C18.3337 10.0697 18.3337 12.8139 17.9855 14.1291C17.7938 14.8546 17.2291 15.4261 16.512 15.62C15.2122 15.9725 10.0004 15.9725 10.0004 15.9725C10.0004 15.9725 4.78854 15.9725 3.48875 15.62C2.77171 15.4261 2.20692 14.8546 2.01528 14.1291C1.66699 12.8139 1.66699 10.0697 1.66699 10.0697C1.66699 10.0697 1.66699 7.32568 2.01528 6.01043C2.20692 5.28486 2.77171 4.71335 3.48875 4.51942C4.78854 4.16699 10.0004 4.16699 10.0004 4.16699C10.0004 4.16699 15.2122 4.16699 16.512 4.51942ZM8.61143 7.63914V12.5003L12.7781 10.0697L8.61143 7.63914Z"
fill="currentColor"
/>
</svg>
);
}
export default YoutubeIcon;
@@ -6,8 +6,6 @@ import { markers } from "../../../consts/markers";
import useMarker from "../../../store/useMarker";
import ZoomControlls from "./ZoomControlls";
import { Clouds } from "./Clouds";
import { getWeather } from "../../../api/weather";
import { useEffect } from "react";
import WeatherWidget from "./WeatherWidget";
const Map = () => {
@@ -21,12 +19,6 @@ const Map = () => {
};
});
useEffect(() => {
getWeather().then((data) => {
console.log(data);
});
}, []);
return (
<div className="relative">
<TransformWrapper
@@ -20,8 +20,7 @@ const WeatherWidget = () => {
useEffect(() => {
getWeather().then((data) => {
const temp = Math.round(data[0].main.temp);
setTemperature(temp);
setTemperature(Math.round(data));
});
}, []);
+3 -2
View File
@@ -7,7 +7,8 @@ import useModal from "../store/useModal";
import useFullScreen from "../store/useFullScreen";
import DesktopHeader from "../components/header/Header/DesktopHeader";
import MobileHeader from "../components/header/Header/MobileHeader";
import Footer from "../components/Footer";
// import Footer from "../components/Footer";
import Footer2 from "../components/Footer2";
function WithFooterLayout() {
const { modal } = useModal();
@@ -27,7 +28,7 @@ function WithFooterLayout() {
{isMobile ? <MobileHeader /> : <DesktopHeader />}
{modal}
<Outlet />
<Footer />
<Footer2 />
</FullScreen>
</>
);
+8 -3
View File
@@ -14,8 +14,9 @@ import UnitTypesItemPage from "./pages/UnitTypesItemPage";
import SearchPage2 from "./pages/SearchPage2";
import FavoritesPage2 from "./pages/FavoritesPage2";
import WithFooterLayout from "./layouts/WithFooterLayout";
// import AboutProjects2Page from "./pages/AboutProjects2Page";
import AboutProjectsPage from "./pages/AboutProjectsPage";
// import AboutProjectsPage from "./pages/AboutProjectsPage";
import AboutProjects2Page from "./pages/AboutProjects2Page";
import TestPage from "./pages/TestPage";
const router = createBrowserRouter([
{
@@ -42,6 +43,10 @@ const router = createBrowserRouter([
path: "virtual-tour/:unitType",
element: <VirtualTourPage />,
},
{
path: "test",
element: <TestPage />,
},
],
},
{
@@ -50,7 +55,7 @@ const router = createBrowserRouter([
children: [
{
path: "about-projects",
element: <AboutProjectsPage />,
element: <AboutProjects2Page />,
},
{
path: "about",
+214 -11
View File
@@ -1,20 +1,27 @@
import AdvantageCard from "../components/AboutProject/AdvantageCard";
import PlaceCard from "../components/AboutProject/PlaceCard";
import UnitCard from "../components/AboutProject/UnitCard";
import Button2 from "../components/Button2";
import ArrowLeftIcon from "../components/icons/ArrowLeftIcon";
import ArrowRightIcon from "../components/icons/ArrowRightIcon";
function AboutProjects2Page() {
return (
<div className="pt-[58px] space-y-[100px]">
<div className="px-6 pt-16 space-y-16">
<p className="text-[56px] text-[#0D1922] font-mixcase -tracking-[1.68px] uppercase leading-none">
<div className="mt-[58px] py-16 space-y-[100px]">
<div className="px-6 space-y-16">
<p className="text-[56px] text-[#0D1922] font-mixcase -tracking-[1.68px] leading-none">
Rove Home this residence a complete ecosystem that has everything
youll ever need. This isnt just where youll live. Its where youll
thrive.
youll ever need. This isnt just where youll live.
<br />
Its where youll thrive.
</p>
<div className="flex gap-6">
<div className="w-1/4 flex flex-col justify-between gap-6">
<div className="space-y-6">
<p className="text-xs font-semibold">ABOUT ROVE HOME</p>
<p className="text-2xl text-[#00BED7] font-semibold">
<p className="text-xs font-semibold text-[#73787C]">
ABOUT ROVE HOME
</p>
<p className="text-2xl font-semibold">
Embrace Roves forever-young spirit at Rove Home, where
inspiring design and vibrant art installations converge with an
exceptional location and an extended playlist of life-enhancing{" "}
@@ -24,7 +31,7 @@ function AboutProjects2Page() {
</div>
<div className="w-3/4">
<img
src=""
src="/images/pages/AboutProject/1.jpg"
alt=""
className="aspect-[22/9] h-full w-full rounded-2xl object-cover"
/>
@@ -33,8 +40,12 @@ function AboutProjects2Page() {
</div>
<div className="relative h-screen bg-blue-100">
<div className="absolute w-full h-full"></div>
<div className="absolute bottom-6 left-6 bg-white w-[378px] p-8 rounded-2xl space-y-8">
<img
src="/images/pages/AboutProject/2.jpg"
alt=""
className="object-cover h-screen w-full"
/>
<div className="absolute bottom-6 left-6 w-[378px] p-8 rounded-2xl space-y-8 bg-[#F3F3F2]">
<div className="space-y-4">
<p className="text-2xl text-[#00BED7] font-semibold">Rove Home</p>
<p>
@@ -51,7 +62,199 @@ function AboutProjects2Page() {
youll agree.
</p>
</div>
<div className=""></div>
<div className="flex justify-between">
<div className="flex gap-3">
<Button2
variant="secondary"
size="small"
icon={<ArrowLeftIcon className="w-5 h-5" />}
onlyIcon
/>
<Button2
variant="secondary"
size="small"
icon={<ArrowRightIcon className="w-5 h-5" />}
onlyIcon
/>
</div>
<p className="text-xl text-[#00BED7]">1/4</p>
</div>
</div>
</div>
<div className="px-6 space-y-[140px]">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-6">
<p className="text-xs text-[#73787C] font-semibold">
ROVE AROUND THE CITY
</p>
<div className="grid grid-cols-2 gap-x-4 gap-y-2">
<PlaceCard
title="Burj Khalifa"
desc="10 mins"
image="/images/pages/AboutProject/places/1.jpg"
/>
<PlaceCard
title="The Dubai Fountain"
desc="10 mins"
image="/images/pages/AboutProject/places/2.jpg"
/>
<PlaceCard
title="Dubai Mall"
desc="8 mins"
image="/images/pages/AboutProject/places/3.jpg"
/>
<PlaceCard
title="Dubai Opera"
desc="11 mins"
image="/images/pages/AboutProject/places/4.jpg"
/>
<PlaceCard
title="Marasi Promenade"
desc="4 mins"
image="/images/pages/AboutProject/places/5.jpg"
/>
<PlaceCard
title="Rove Downtown Hotel"
desc="10 mins"
image="/images/pages/AboutProject/places/6.jpg"
/>
<PlaceCard
title="Rove City Walk Hotel"
desc="12 mins"
image="/images/pages/AboutProject/places/7.jpg"
/>
<PlaceCard
title="City Walk"
desc="12 mins"
image="/images/pages/AboutProject/places/8.jpg"
/>
<PlaceCard
title="Coca Cola arena"
desc="14 mins"
image="/images/pages/AboutProject/places/9.jpg"
/>
<PlaceCard
title="Dubai International Airport"
desc="10 mins"
image="/images/pages/AboutProject/places/10.jpg"
/>
</div>
</div>
<div className="relative">
<img src="/images/pages/AboutProject/map.jpg" alt="" />
<div className="bg-gradient-to-r from-[#f3f3f2] to-transparent to-20% w-full h-full absolute top-0 left-0"></div>
</div>
</div>
<div className="space-y-6">
<p className="text-xs text-[#73787C]">ADVANTAGES</p>
<div className="grid grid-cols-2 gap-x-4 gap-y-14">
<AdvantageCard
title="Community"
image="/images/pages/AboutProject/advantages/1.jpg"
/>
<AdvantageCard
title="Rove-Inspired design"
image="/images/pages/AboutProject/advantages/2.jpg"
/>
<AdvantageCard
title="Fully loaded amenities"
image="/images/pages/AboutProject/advantages/3.jpg"
/>
<AdvantageCard
title="Add-on services"
image="/images/pages/AboutProject/advantages/4.jpg"
/>
<AdvantageCard
title="Central urban location"
image="/images/pages/AboutProject/advantages/5.jpg"
/>
</div>
</div>
<div className="space-y-16">
<p className="text-[56px] text-[#0D1922] font-mixcase -tracking-[3%] leading-[56px]">
Live in the future, today. Designed to embody Roves unique look and
feel, the interiors will feature intelligent and modular living
solutions by ORI, never seen before in UAE and the region.
</p>
<div className="space-y-6">
<p className="text-2xl font-semibold w-[40%]">
ORI introduces a revolutionary solution to apartment living, where
space is not just a constraint but an opportunity.
</p>
<div className="flex gap-4">
<div className="flex items-center gap-1">
<div className="w-3 h-3 bg-[#00BED7] rounded-full"></div>
<p className="text-[#0D1922]">Simple</p>
</div>
<div className="flex items-center gap-1">
<div className="w-3 h-3 bg-[#00BED7] rounded-full"></div>
<p className="text-[#0D1922]">Safe</p>
</div>
<div className="flex items-center gap-1">
<div className="w-3 h-3 bg-[#00BED7] rounded-full"></div>
<p className="text-[#0D1922]">Effortless</p>
</div>
</div>
<div className="flex gap-4 -translate-x-6 pl-6 pr-2">
<img
src="/images/pages/AboutProject/interiors/1.jpg"
alt=""
className="w-[40%] object-cover rounded-2xl"
/>
<img
src="/images/pages/AboutProject/interiors/2.jpg"
alt=""
className="w-[20%] object-cover rounded-2xl"
/>
<img
src="/images/pages/AboutProject/interiors/3.jpg"
alt=""
className="w-[40%] object-cover rounded-2xl"
/>
</div>
</div>
</div>
<div className="space-y-4">
<p className="text-xs text-[#73787C] font-semibold">
UNITS DESCRIPTION
</p>
<div className="grid grid-cols-2 gap-4">
<UnitCard
title="Studio flex"
desc1="Live in the future, today. In Studio Flex explore the ORI Cloud Bed, optimizing your living space with functionality and smart living."
desc2="Every inch is designed to provide more space for comfort and convenience. This feature increase your unit size by 33%"
square={341}
price={1048888}
image="/images/pages/AboutProject/units/1.jpg"
/>
<UnitCard
title="Studio²"
desc1="In Studio² experience the Flexibed, a smart innovation for modern living. When folded, it unveils a spacious living room creating a cohesive space that blends both style and functionality."
desc2=""
square={390}
price={1138888}
image="/images/pages/AboutProject/units/2.jpg"
/>
<UnitCard
title="1 Bedroom"
desc1="In 1 Bedroom² double up your space with next generation features that enhance smart living."
desc2="With pocket walls that disappear and a Flexibed that seamlessly converts, you can transform your living room into an extra bedroom, anytime you want!"
square={609}
price={1668888}
image="/images/pages/AboutProject/units/3.jpg"
/>
<UnitCard
title="2 Bedroom²"
desc1="In 2 Bedroom² discover extra functionality with added space and maximum value."
desc2="Whether you want to add a multipurpose spare room or double up your living space as a bedroom - every inch of space feels larger and works exactly how you want."
square={891}
price={2408888}
image="/images/pages/AboutProject/units/4.jpg"
/>
</div>
</div>
</div>
</div>
+5
View File
@@ -0,0 +1,5 @@
function TestPage() {
return <div>TestPage</div>;
}
export default TestPage;
+38 -3
View File
@@ -469,6 +469,13 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@openmeteo/sdk@^1.11.4":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@openmeteo/sdk/-/sdk-1.13.0.tgz#f3bbb0aba1bdd100951fa06c94e1b862cfa28a44"
integrity sha512-ALvG83/XjnwfapSVqEsZr0GfnTacXOvPKazN3LC2jw2ty4Yqs98oMZKBiWCJkfPbl2Ray7Yikzm6e4f7DXQhQQ==
dependencies:
flatbuffers "^24.3.25"
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
@@ -1513,6 +1520,11 @@ flat-cache@^3.0.4:
keyv "^4.5.3"
rimraf "^3.0.2"
flatbuffers@^24.3.25:
version "24.3.25"
resolved "https://registry.yarnpkg.com/flatbuffers/-/flatbuffers-24.3.25.tgz#e2f92259ba8aa53acd0af7844afb7c7eb95e7089"
integrity sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==
flatted@^3.2.9:
version "3.3.1"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz"
@@ -1997,6 +2009,14 @@ once@^1.3.0:
dependencies:
wrappy "1"
openmeteo@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/openmeteo/-/openmeteo-1.1.4.tgz#9582363637c6fb8f65f43fe54124d16f38a851f4"
integrity sha512-TalTDl0M7JJoeRTf+rWiFZ9SLvoxm7KkFLOQqcSjCiYs+bVMhax1qtryJqeZ1RF4W4Xfsgcl9x+VC1z39ULCxA==
dependencies:
"@openmeteo/sdk" "^1.11.4"
flatbuffers "^24.3.25"
optionator@^0.9.3:
version "0.9.3"
resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz"
@@ -2436,8 +2456,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==
@@ -2455,7 +2483,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==