upd
@@ -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",
|
||||
|
||||
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 587 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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));
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
you’ll ever need. This isn’t just where you’ll live. It’s where you’ll
|
||||
thrive.
|
||||
you’ll ever need. This isn’t just where you’ll live.
|
||||
<br />
|
||||
It’s where you’ll 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 Rove’s 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() {
|
||||
you’ll 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 Rove’s 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>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
function TestPage() {
|
||||
return <div>TestPage</div>;
|
||||
}
|
||||
|
||||
export default TestPage;
|
||||
@@ -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==
|
||||
|
||||