447 lines
17 KiB
TypeScript
447 lines
17 KiB
TypeScript
/* eslint-disable react-hooks/exhaustive-deps */
|
|
import useModal from "../../store/useModal";
|
|
import IUnit from "../../types/IUnit";
|
|
import Button from "../Button";
|
|
import ArrowLeftIcon from "../icons/ArrowLeftIcon";
|
|
import BookingIcon from "../icons/BookingIcon";
|
|
import HeartIcon from "../icons/HeartIcon";
|
|
import VirtualTourIcon from "../icons/VirtualTourIcon";
|
|
import unitTypes from "../../data/unitTypes.json";
|
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
import { useEffect } from "react";
|
|
import useFavoritesStore from "../../store/useFavoritesStore";
|
|
import HeartFilledIcon from "../icons/HeartFilledIcon";
|
|
import ShareIcon from "../icons/ShareIcon";
|
|
|
|
interface Props {
|
|
unit: IUnit;
|
|
type: string;
|
|
}
|
|
|
|
function UnitModal({ unit, type }: Props) {
|
|
const { setModal } = useModal();
|
|
const navigate = useNavigate();
|
|
const { favoriteUnits, setFavoriteUnits } = useFavoritesStore();
|
|
const location = useLocation();
|
|
|
|
function getViewImage(): string {
|
|
const unitView = unit.unitView;
|
|
|
|
console.log(unitView);
|
|
|
|
if (unitView.includes("BK/DT")) {
|
|
return "/images/views/burj-khalifa.jpg";
|
|
} else if (unitView.includes("Business Bay")) {
|
|
return "/images/views/business-bay.jpg";
|
|
} else if (unitView.includes("Canal")) {
|
|
return "/images/views/canal.jpg";
|
|
} else if (unitView.includes("Park")) {
|
|
return "/images/views/park.jpg";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
function getViewText() {
|
|
const unitView = unit.unitView;
|
|
|
|
console.log(unitView);
|
|
|
|
if (unitView.includes("BK/DT")) {
|
|
return "Burj Khalifa / Downtown";
|
|
} else if (unitView.includes("Business Bay")) {
|
|
return "Business Bay";
|
|
} else if (unitView.includes("Canal")) {
|
|
return "Dubai Canal";
|
|
} else if (unitView.includes("Park")) {
|
|
return "Park";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
function getMainImage(): string {
|
|
const side = unit.unitNo[0];
|
|
const floor = Number(unit.floor);
|
|
const unitNumber = Number(unit.unitNo.split("-")[1].slice(-2));
|
|
|
|
if (side === "W") {
|
|
// Side "W"
|
|
if (floor < 24) {
|
|
switch (unitNumber) {
|
|
case 1:
|
|
return "/images/layouts/2br_a_left.jpg";
|
|
case 2:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 3:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 4:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 5:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 6:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 7:
|
|
return "/images/layouts/1br_a_left.jpg";
|
|
case 8:
|
|
return "/images/layouts/1br_a_left.jpg";
|
|
case 9:
|
|
return "/images/layouts/studio_flex_left.jpg";
|
|
case 10:
|
|
return "/images/layouts/studio_flex_left.jpg";
|
|
case 11:
|
|
return "/images/layouts/studio_flex_left.jpg";
|
|
case 12:
|
|
return "/images/layouts/studio_flex_left.jpg";
|
|
case 13:
|
|
return "/images/layouts/studio_flex_left.jpg";
|
|
case 14:
|
|
return "/images/layouts/studio_flex_left.jpg";
|
|
case 15:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 16:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 17:
|
|
return "/images/layouts/2br_b_left.jpg";
|
|
}
|
|
} else {
|
|
switch (unitNumber) {
|
|
case 1:
|
|
return "/images/layouts/2br_a_left.jpg";
|
|
case 2:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 3:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 4:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 5:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 6:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 7:
|
|
return "/images/layouts/1br_a_left.jpg";
|
|
case 8:
|
|
return "/images/layouts/1br_a_left.jpg";
|
|
case 9:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 10:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 11:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 12:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 13:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 14:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 15:
|
|
return "/images/layouts/2br_b_left.jpg";
|
|
}
|
|
}
|
|
} else {
|
|
// Side "E"
|
|
switch (unitNumber) {
|
|
case 1:
|
|
return "/images/layouts/2br_a_left.jpg";
|
|
case 2:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 3:
|
|
return "/images/layouts/1br_d_left.jpg";
|
|
case 4:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 5:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 6:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 7:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 8:
|
|
return "/images/layouts/1br_b_left.jpg";
|
|
case 9:
|
|
return "/images/layouts/1br_b_left.jpg";
|
|
case 10:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 11:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 12:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 13:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 14:
|
|
return "/images/layouts/studio_left.jpg";
|
|
case 15:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
case 16:
|
|
return "/images/layouts/1br_c_left.jpg";
|
|
}
|
|
}
|
|
|
|
console.log(side, floor, unitNumber);
|
|
|
|
return "";
|
|
}
|
|
|
|
function addOrRemoveFromFavorites(unit: IUnit) {
|
|
if (!favoriteUnits.some((favoriteUnit) => favoriteUnit.id === unit.id)) {
|
|
setFavoriteUnits([...favoriteUnits, unit]);
|
|
} else {
|
|
setFavoriteUnits(
|
|
favoriteUnits.filter((favoriteUnit) => favoriteUnit.id !== unit.id)
|
|
);
|
|
}
|
|
}
|
|
|
|
function handleClickTour() {
|
|
navigate(`/virtual-tour/${type}?unitNo=${unit.unitNo}`);
|
|
}
|
|
|
|
useEffect(() => {
|
|
document.body.classList.add("overflow-y-hidden");
|
|
|
|
return () => {
|
|
document.body.classList.remove("overflow-y-hidden");
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div
|
|
className={`fixed top-0 left-0 w-full overflow-y-scroll h-dvh pt-[56px] z-40 backdrop-blur select-none`}
|
|
>
|
|
<div className="flex justify-end min-h-full">
|
|
<div className="bg-[#F3F3F2] lg:p-6 p-4 max-w-[1240px] w-full sm:space-y-20 space-y-10">
|
|
<div className="flex gap-2 sm:gap-4 max-lg:flex-col">
|
|
<div className="left lg:max-w-[800px] w-full flex flex-col gap-4">
|
|
<div className="flex justify-between gap-4">
|
|
<div className="flex items-center gap-4">
|
|
<Button
|
|
buttonType="cta"
|
|
icon={<ArrowLeftIcon />}
|
|
onClick={() => setModal(null)}
|
|
/>
|
|
<p className="text-2xl font-[#0D1922] font-semibold">
|
|
{
|
|
unitTypes.find((unitType) => unitType.type === type)
|
|
?.title
|
|
}
|
|
</p>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<button
|
|
className="w-10 h-10 flex items-center justify-center border border-[#E2E2DC] rounded-full bg-[#FFFFFF] bg-opacity-80 hover:text-[#0D1922] hover:bg-opacity-100 hover:border-[#00BED7] transition-all"
|
|
onClick={() =>
|
|
navigator.share({
|
|
title: "IRTH",
|
|
text: `${unit.unitNo}`,
|
|
url: `/search${location.search}`,
|
|
})
|
|
}
|
|
>
|
|
<ShareIcon className="w-5 h-5" />
|
|
</button>
|
|
<button
|
|
className="w-10 h-10 flex items-center justify-center border border-[#E2E2DC] rounded-full bg-[#FFFFFF] bg-opacity-80 hover:text-[#0D1922] hover:bg-opacity-100 hover:border-[#00BED7] transition-all"
|
|
onClick={() => addOrRemoveFromFavorites(unit)}
|
|
>
|
|
{favoriteUnits.some(
|
|
(favoriteUnit) => favoriteUnit.id === unit.id
|
|
) ? (
|
|
<HeartFilledIcon className="w-5 h-5" />
|
|
) : (
|
|
<HeartIcon className="w-5 h-5" />
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col items-center justify-center flex-1 gap-10 p-4 bg-white sm:p-10 rounded-2xl">
|
|
<div className="">
|
|
<img
|
|
src={getMainImage()}
|
|
alt=""
|
|
className="max-h-[580px] pointer-events-none"
|
|
/>
|
|
</div>
|
|
{/* <div className="bg-[#F3F3F2] rounded-lg flex">
|
|
<Button buttonType="cta" text="Layout" />
|
|
<Button
|
|
buttonType="tertiary"
|
|
text="On the Floor"
|
|
className="px-6 py-2.5 text-[#0D1922] hover:text-[#00BED7]"
|
|
/>
|
|
</div> */}
|
|
</div>
|
|
</div>
|
|
<div className="right lg:w-[376px] lg:min-w-[376px] grid lg:grid-cols-1 sm:grid-cols-2 grid-cols-1 gap-2 grid-rows">
|
|
<div className="relative max-sm:order-last">
|
|
<div
|
|
className="lg:h-[328px] sm:h-full max-sm:aspect-square bg-center bg-no-repeat bg-cover rounded-2xl"
|
|
style={{ backgroundImage: `url('${getViewImage()}')` }}
|
|
></div>
|
|
|
|
<div
|
|
className="absolute top-0 left-0 flex items-end w-full h-full p-6 rounded-2xl"
|
|
style={{
|
|
background:
|
|
"linear-gradient(180deg, rgba(16, 41, 79, 0) 67.74%, rgba(16, 41, 79, 0.64) 100%)",
|
|
}}
|
|
>
|
|
<div className="space-y-1 font-semibold text-white">
|
|
<p className="text-xs">View from window</p>
|
|
<p className="text-xl">{getViewText()}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<div className="p-4 space-y-6 bg-white sm:p-6 rounded-2xl">
|
|
<div className="space-y-2 border-b border-[E2E2DC] pb-4">
|
|
<p className="sm:text-xl text-[#0D1922] font-semibold">
|
|
{unit.unitName}, {unit.totalArea} Sqft
|
|
</p>
|
|
<div className="space-y-1">
|
|
<p className="text-sm text-[#00BED7]">
|
|
Rove Home Marasi Drive
|
|
</p>
|
|
<div className="flex items-center gap-2 sm:text-xs text-[10px] font-semibold">
|
|
<p>{unit.unitNo[0] === "E" ? "East" : "West"} Wing</p>
|
|
<div className="bg-[#E2E2DC] w-1 h-1 rounded-full"></div>
|
|
<p>Floor {unit.floor}</p>
|
|
<div className="bg-[#E2E2DC] w-1 h-1 rounded-full"></div>
|
|
<p>{unit.unitNo}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="space-y-2 max-sm:text-sm">
|
|
<div className="flex justify-between">
|
|
<p className="text-[#0D1922]/40">Total Area</p>
|
|
<p className="text-[#0D1922]">{unit.totalArea} Sqft</p>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<p className="text-[#0D1922]/40">Suite Area</p>
|
|
<p className="text-[#0D1922]">{unit.suiteArea} Sqft</p>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<p className="text-[#0D1922]/40">Balcony Area</p>
|
|
<p className="text-[#0D1922]">{unit.balconyArea} Sqft</p>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<p className="text-[#0D1922]/40">Status</p>
|
|
<p className="text-[#0D1922]">{unit.propertyStatus}</p>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<p className="text-[#0D1922]/40">Parking Space</p>
|
|
<p className="text-[#0D1922]">{unit.parkingSpaces}</p>
|
|
</div>
|
|
</div>
|
|
<p className="text-xl text-[#00BED7] font-semibold">
|
|
{unit.unitPrice ? (
|
|
<>
|
|
AED{" "}
|
|
{new Intl.NumberFormat("ar-AE", {
|
|
currency: "AED",
|
|
})
|
|
.format(unit.unitPrice)
|
|
.replaceAll(",", " ")}
|
|
</>
|
|
) : (
|
|
"Unavailable"
|
|
)}
|
|
</p>
|
|
</div>
|
|
<div className="flex gap-2 p-6 bg-white rounded-2xl">
|
|
{unitTypes.find((unitType) => unitType.type === type)
|
|
?.tourAvailable && (
|
|
<Button
|
|
buttonType="secondary"
|
|
icon={<VirtualTourIcon />}
|
|
text="3D tour"
|
|
className="justify-center w-full text-sm"
|
|
onClick={handleClickTour}
|
|
/>
|
|
)}
|
|
<Button
|
|
buttonType="cta"
|
|
icon={<BookingIcon />}
|
|
text="Send Enquiry"
|
|
className="text-[13.6px] justify-center disabled:hover:bg-[#ECEDEE] w-full"
|
|
disabled
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-1 gap-3 sm:gap-4 sm:grid-cols-2">
|
|
<div className="flex flex-col justify-between gap-4 p-4 bg-white sm:p-8 rounded-2xl">
|
|
<div className="left lg:w-[376px] lg:min-w-[376px] space-y-6">
|
|
<div className="space-y-2">
|
|
<p className="sm:text-[40px] text-2xl text-[#0D1922] font-bold sm:leading-[54px]">
|
|
{
|
|
unitTypes.find((unitType) => unitType.type === type)
|
|
?.title
|
|
}
|
|
</p>
|
|
<p className="sm:text-xl text-[#00BED7] font-semibold leading-[18.4px]">
|
|
{unitTypes.find((unitType) => unitType.type === type)?.desc}
|
|
</p>
|
|
</div>
|
|
<div className="sm:leading-[22px]">
|
|
<p className="space-y-2 max-sm:text-sm">
|
|
{
|
|
unitTypes.find((unitType) => unitType.type === type)
|
|
?.texts[0]
|
|
}
|
|
</p>
|
|
<p className="space-y-2 max-sm:text-sm">
|
|
{
|
|
unitTypes.find((unitType) => unitType.type === type)
|
|
?.texts[1]
|
|
}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="space-y-1">
|
|
<p className="text-xs sm:text-sm">
|
|
Up to{" "}
|
|
{unitTypes.find((unitType) => unitType.type === type)?.sqft}{" "}
|
|
Sqft
|
|
</p>
|
|
<p className="text-xl text-[#00BED7] font-semibold">
|
|
{unit.unitPrice && (
|
|
<>
|
|
from AED{" "}
|
|
{new Intl.NumberFormat("ar-AE", {
|
|
currency: "AED",
|
|
})
|
|
.format(unit.unitPrice)
|
|
.replaceAll(",", " ")}
|
|
</>
|
|
)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<img
|
|
src={
|
|
unitTypes.find((unitType) => unitType.type === type)
|
|
?.imageDesc
|
|
}
|
|
alt=""
|
|
className="lg:max-h-[644px] sm:h-full rounded-2xl pointer-events-none object-cover max-sm:aspect-square"
|
|
/>
|
|
{/* <div
|
|
className="lg:max-h-[644px] sm:h-full max-sm:aspect-square bg-center bg-no-repeat bg-cover rounded-2xl"
|
|
style={{
|
|
backgroundImage: `url('${
|
|
unitTypes.find((unitType) => unitType.type === type)
|
|
?.imageDesc
|
|
}')`,
|
|
}}
|
|
></div> */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default UnitModal;
|