264 lines
9.9 KiB
TypeScript
264 lines
9.9 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import useSphere from "../../store/useSphere";
|
|
import { IAppartmentComplex, ISphere } from "../../types/apartmentSphere";
|
|
import Button from "../Button";
|
|
import BookingIcon from "../icons/BookingIcon";
|
|
import ChevronDownIcon from "../icons/ChevronDownIcon";
|
|
import HeartIcon from "../icons/Heart";
|
|
import MapVectorIcon from "../icons/MapVectorIcon";
|
|
import useCompass from "../../store/useCompass";
|
|
import LeftArrowIcon from "../icons/LeftArrowIcon";
|
|
import InfoIcon from "../icons/InfoIcon";
|
|
import { useNavigate } from "react-router-dom";
|
|
import useModal from "../../store/useModal";
|
|
import { SendEnquiryModal } from "../modals/SendEnquryModal";
|
|
import { IAparmentRes } from "../../types/apartmentsRes";
|
|
import useFavorites from "../../store/useFavorites";
|
|
|
|
interface VirtualTourSidebarProps {
|
|
appartmentSphere: null | IAppartmentComplex;
|
|
apartment: null | IAparmentRes;
|
|
}
|
|
|
|
const VirtualTourSidebar = ({
|
|
appartmentSphere,
|
|
apartment,
|
|
}: VirtualTourSidebarProps) => {
|
|
const { currentCompassRotate } = useCompass();
|
|
const [isActive, setIsActive] = useState(false);
|
|
const { setSelectedSphere, selectedSphere } = useSphere();
|
|
const { setModal } = useModal();
|
|
const navigate = useNavigate();
|
|
const wing =
|
|
apartment?.Unit_No.split("-")[0] === "W" ? "West Wing" : "East Wing";
|
|
|
|
const [isFavorite, setIsFavorite] = useState(false);
|
|
const { setFavorites } = useFavorites();
|
|
|
|
const handleOnShowClick = () => {
|
|
setIsActive((prev) => !prev);
|
|
};
|
|
|
|
const handleOnLabelClick = (sphere: ISphere) => {
|
|
setSelectedSphere(sphere);
|
|
};
|
|
|
|
const handleOnBackClick = () => {
|
|
navigate(-1);
|
|
};
|
|
|
|
const handleAboutComplexClick = () => {
|
|
if (!apartment) return;
|
|
navigate(`../search/${apartment?.id}`);
|
|
};
|
|
|
|
const handleOnSendEnquiryClick = () => {
|
|
setModal(<SendEnquiryModal />);
|
|
};
|
|
|
|
const handleOnFavoriteClick = (
|
|
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
|
) => {
|
|
e.stopPropagation();
|
|
console.log("apartment", apartment);
|
|
if (!apartment) return;
|
|
const favorites = localStorage.getItem("Favorites");
|
|
|
|
if (!favorites) {
|
|
setIsFavorite(true);
|
|
const updatedFavorites = JSON.stringify([apartment]);
|
|
|
|
localStorage.setItem("Favorites", updatedFavorites);
|
|
} else {
|
|
const _favorites = JSON.parse(favorites) as IAparmentRes[];
|
|
|
|
if (_favorites.some((apart) => apart.id === apartment.id)) {
|
|
setIsFavorite(false);
|
|
const updatedFavorites = [..._favorites].filter(
|
|
(apart) => apart.id !== apartment.id
|
|
);
|
|
const convertedFavorites = JSON.stringify(updatedFavorites);
|
|
setFavorites(updatedFavorites);
|
|
localStorage.setItem("Favorites", convertedFavorites);
|
|
} else {
|
|
setIsFavorite(true);
|
|
const updatedFavorites = [..._favorites, apartment];
|
|
setFavorites(updatedFavorites);
|
|
const convertedFavorites = JSON.stringify(updatedFavorites);
|
|
localStorage.setItem("Favorites", convertedFavorites);
|
|
}
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!apartment) return;
|
|
const favorites = localStorage.getItem("Favorites");
|
|
if (favorites) {
|
|
const _isFavorite = (JSON.parse(favorites) as IAparmentRes[]).some(
|
|
(apart) => apart.id === apartment.id
|
|
);
|
|
setIsFavorite(_isFavorite);
|
|
}
|
|
}, [apartment, apartment?.id]);
|
|
|
|
return (
|
|
<div className="absolute w-screen h-screen grid z-[99999997] pointer-events-none select-none">
|
|
<div className="h-screen py-[202px] px-3 w-[1012.5px]">
|
|
<div className="bg-white w-full rounded-2xl p-5 flex flex-col relative rounded-ee-none">
|
|
<div className="flex items-center justify-between pb-4 border-b gap-4">
|
|
<Button
|
|
icon={<LeftArrowIcon />}
|
|
buttonType="secondary"
|
|
className="w-fit"
|
|
onClick={handleOnBackClick}
|
|
/>
|
|
{/* <p className="text-[#0D1922] font-semibold leading-6 text-left text-xl"> */}
|
|
<p className="text-[#0D1922] font-semibold text-subheadline-s text-[56.25px] leading-[78.75px] text-left">
|
|
{apartment
|
|
? `${apartment?.Unit_Type}, ${Math.round(
|
|
apartment?.Total_Area_Sqft
|
|
)} Sqft`
|
|
: "1 BR Squared, 609 Sqft"}
|
|
</p>
|
|
</div>
|
|
<div className="pt-3">
|
|
<div className="flex gap-2 items-center">
|
|
<div className="flex flex-col">
|
|
<p className="text-[#00BED7] text-caption-m font-medium">
|
|
{apartment?.Project_Name || "Rove Home Marasi Drive"}
|
|
</p>
|
|
<div className="text-[#73787C] flex gap-2 items-center w-fit pt-1">
|
|
<p className="text-caption-m font-semibold leading-4">
|
|
{wing}
|
|
</p>
|
|
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
|
|
<p className="text-caption-m font-semibold leading-4">
|
|
Floor {apartment?.Floor || 11}
|
|
</p>
|
|
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
|
|
<p className="text-caption-m font-semibold leading-4">
|
|
№ {apartment?.Unit_No || 213}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
className={`transition-all duration-700 ease-in-out ${
|
|
!isActive ? "max-h-0 opacity-0" : "max-h-screen opacity-100"
|
|
}`}
|
|
>
|
|
<div
|
|
className={`${
|
|
isActive ? "my-4" : ""
|
|
} relative flex justify-center`}
|
|
>
|
|
<img src={appartmentSphere?.map} alt="" className="h-[840px]" />
|
|
<div
|
|
className="absolute zoom-280"
|
|
style={{
|
|
top: `${selectedSphere?.mapPosition[1] || 0}px`,
|
|
left: `${selectedSphere?.mapPosition[0] || 0}px`,
|
|
transform: `rotate(${-currentCompassRotate + 90}deg)`,
|
|
}}
|
|
>
|
|
<MapVectorIcon />
|
|
</div>
|
|
</div>
|
|
<div className="pt-4 border-t">
|
|
<div className="flex flex-col gap-3">
|
|
<div className="flex justify-between text-m">
|
|
<p className="text-[#73787C]">Size</p>
|
|
<p className="text-[#0D1922]">
|
|
{apartment?.Total_Area_Sqft || 609} Sqft
|
|
</p>
|
|
</div>
|
|
<div className="flex justify-between text-m">
|
|
<p className="text-[#73787C]">Status</p>
|
|
<p className="text-[#0D1922]">
|
|
{apartment?.Property_Status || "Available"}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col">
|
|
<h2 className="text-subheadline-s font-semibold text-[#00BED7] pt-4">
|
|
Unvailiable
|
|
</h2>
|
|
<div className="flex gap-2 pt-4 ">
|
|
<Button
|
|
icon={<BookingIcon />}
|
|
text="Send Enquiry"
|
|
buttonType="cta"
|
|
className="flex-1 flex items-center justify-center"
|
|
onClick={handleOnSendEnquiryClick}
|
|
/>
|
|
<Button
|
|
icon={<InfoIcon />}
|
|
buttonType="secondary"
|
|
onClick={handleAboutComplexClick}
|
|
/>
|
|
<Button
|
|
icon={<HeartIcon isFilled={isFavorite} />}
|
|
buttonType="secondary"
|
|
onClick={handleOnFavoriteClick}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="h-14 absolute -bottom-14 left-0 w-full flex justify-between">
|
|
<div className="flex gap-1 py-2 items-start flex-wrap pr-[9px]">
|
|
{appartmentSphere &&
|
|
appartmentSphere.spheres.map((sphere) => {
|
|
return (
|
|
<div
|
|
onClick={() => handleOnLabelClick(sphere)}
|
|
className={`font-semibold text-caption-s py-0.5 px-2 w-fit rounded-full cursor-pointer pointer-events-auto select-none text-white ${
|
|
selectedSphere?.id === sphere.id
|
|
? "bg-[#00BED7]"
|
|
: "bg-[#0D192266]"
|
|
}`}
|
|
key={sphere.id}
|
|
>
|
|
{sphere.roomType}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
<div
|
|
onClick={handleOnShowClick}
|
|
className="transition-all duration-300 bg-[#FFFFFFCC] px-4 py-3 w-fit h-12 rounded-ee-lg rounded-es-lg select-none cursor-pointer pointer-events-auto items-start border border-t-[#0D1922B2] active:border-[#00BED7] hover:bg-[#FFFFFF] text-[#0D1922B2] hover:text-[#0D1922]"
|
|
>
|
|
<div className="flex justify-center items-center gap-2">
|
|
<div className="relative text-[45px]">
|
|
<div
|
|
className={`transition-opacity duration-300 ${
|
|
!isActive ? "opacity-100" : "opacity-0"
|
|
}`}
|
|
>
|
|
Show
|
|
</div>
|
|
<div
|
|
className={`transition-opacity duration-300 absolute top-0 ${
|
|
!isActive ? "opacity-0" : "opacity-100"
|
|
}`}
|
|
>
|
|
Hide
|
|
</div>
|
|
</div>
|
|
<ChevronDownIcon
|
|
className={`transition-all duration-300 ${
|
|
!isActive ? "rotate-0" : "rotate-180"
|
|
}`}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default VirtualTourSidebar;
|