Files
IRTH-Touch/client/src/components/modals/mobile/WingFloorModal.tsx
T
2024-07-09 13:57:13 +05:00

376 lines
13 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-explicit-any */
import { useSwipeable } from "react-swipeable";
import useModal from "../../../store/useModal";
import { useEffect, useState } from "react";
import MinusIcon from "../../icons/MinusIcon";
import { IAparmentRes } from "../../../types/apartmentsRes";
import { IDesctiptionFloor } from "../../../types/descriptionFloor";
import { apartmentsWithoutVirtualTour } from "../../../consts/apartmentsWithoutVirtualTour";
import EastWingHighlighting from "../../complexWingPage/FloorSidebar/EastWingHighlighting";
import EastWingLayout from "../../complexWingPage/FloorSidebar/EastWingLayout";
import WestWingHighlighting from "../../complexWingPage/FloorSidebar/WestWingHighlighting";
import WestWingLayout from "../../complexWingPage/FloorSidebar/WestWingLayout";
import WestWingTopLevelsHighlighting from "../../complexWingPage/FloorSidebar/WestWingTopLevelsHighlighting";
import WestWingTopLevelsLayout from "../../complexWingPage/FloorSidebar/WestWingTopLevelsLayout";
import { filterCurrentApartment } from "../../../calc/filterCurrentApartment";
import MobileApartmentDescription from "../../complexWingPage/MobileApartmentDescription";
import TransparentSelector from "../../TransparentSelector";
import { IOption } from "../../../types/selectorOption";
const getDefaultApartments = (currentFloor: IDesctiptionFloor | null) => {
if (!currentFloor) return [];
const defaultApartment: IAparmentRes[] = apartmentsWithoutVirtualTour.map(
(aprt, index) => {
const unitNo = `${currentFloor?.wing.slice(0, 1)}-${
currentFloor.floor
}0${index}`;
return {
id: unitNo,
Floor: currentFloor.floor,
Property_Status: "Available",
Unit_Type: aprt.type,
Project_Name: "Rove Home Marasi Drive",
Suite_Area_Sqft: 0,
Balcony_Area_Sqft: 0,
No_Of_Bedrooms: 1,
Unit_No: unitNo,
Total_Area_Sqft: 0,
No_of_Bathrooms: 0,
Property_Name: "-",
Unit_View: "-",
};
}
);
return defaultApartment;
};
interface WingFloorModalProps {
currentFloor: IDesctiptionFloor | null;
floorApartments: IAparmentRes[];
}
const WingFloorModal = ({
currentFloor,
floorApartments,
}: WingFloorModalProps) => {
const { setModal } = useModal();
const [isAnimate, setIsAnimate] = useState(false);
const [apartments, setApartments] = useState<IAparmentRes[]>([]);
const [currentApartmentType, setCurrentApartmentType] = useState<
string | null
>(null);
const [currentApartment, setCurrentApartment] = useState<IAparmentRes | null>(
null
);
const [isDescVisible, setIsDescVisible] = useState(false);
const [mousePos, setMousePos] = useState<number[]>([0, 0]);
const [optionsFloors, setOptionsFloors] = useState<IOption[]>([]);
const wing =
floorApartments.length > 0 &&
floorApartments[0].Unit_No.split("-")[0] === "E"
? "East Wing"
: "West Wing";
const handleOnClose = () => {
if (setIsAnimate) {
setIsAnimate(false);
const timeout = setTimeout(() => {
setModal(null);
clearTimeout(timeout);
}, 300);
}
};
function handleOnApartmentClick(
event: React.MouseEvent<SVGSVGElement, MouseEvent>
) {
const apartmentType = event.currentTarget.dataset.type;
if (!apartmentType) {
return;
}
setCurrentApartmentType(apartmentType);
const apartment = filterCurrentApartment(apartments, apartmentType);
if (!apartment) return;
setCurrentApartment(apartment);
setIsDescVisible(true);
}
const handlers = useSwipeable({
onSwipedDown: () => handleOnClose(),
});
function handleMouseClick(
event: React.MouseEvent<SVGSVGElement, MouseEvent> | any
) {
const isApartmentClicked = event.target.parentElement.dataset.type;
if (!isApartmentClicked) {
setIsDescVisible(false);
} else {
const scrollOffsetY = window.scrollY;
//detect mouse pos
const y = event.clientY - 65 + scrollOffsetY - 650;
const x = event.clientX - 140;
// const x = event.clientX - 50;
setMousePos([x, y]);
}
}
const handleOnFloorOptionClick = (floorId: string) => {
const updatedOptions = [...optionsFloors].map((floor) => {
return { ...floor, isSelected: floor.id === floorId };
});
setOptionsFloors(updatedOptions);
};
useEffect(() => {
if (!currentFloor) return;
const defaultApartment: IAparmentRes[] = getDefaultApartments(currentFloor);
setApartments([...defaultApartment, ...floorApartments]);
}, [currentFloor, currentFloor?.floor, currentFloor?.wing, floorApartments]);
useEffect(() => {
setIsAnimate(true);
}, []);
useEffect(() => {
window.addEventListener("mousemove", handleMouseClick);
return () => {
window.removeEventListener("mousemove", handleMouseClick);
};
}, []);
useEffect(() => {
if (!currentFloor) return;
const { floor: selectedFloor } = currentFloor;
if (selectedFloor === 11) {
const floors = Array.from({ length: 4 }).map((_, index) => {
const floor: IOption = {
isSelected: index + 11 === 11,
value: `${index + 11}`,
id: `${index + 11}`,
};
return floor;
});
setOptionsFloors(floors);
return;
}
if (selectedFloor === 31) {
const floors = Array.from({ length: 4 }).map((_, index) => {
const floor: IOption = {
isSelected: index + 28 === 31,
value: `${index + 28}`,
id: `${index + 28}`,
};
return floor;
});
setOptionsFloors(floors);
return;
}
const floors = Array.from({ length: 4 }).map((_, index) => {
const floorIndex = selectedFloor - 1 + index;
const floor: IOption = {
isSelected: floorIndex === selectedFloor,
value: `${index - 1 + selectedFloor}`,
id: `${index - 1 + selectedFloor}`,
};
return floor;
});
setOptionsFloors(floors);
}, [currentFloor]);
return (
<>
<div
className={`h-[calc(100vh-78.75px)] w-screen pt-[157.5px] absolute z-[99999997] top-0 duration-300 ease-in-out overflow-x-clip`}
>
{isDescVisible && (
<div
className="absolute z-[99999999] w-fit h-fit top-0 left-0"
style={{ top: `${mousePos[1]}px`, left: `${mousePos[0]}px` }}
>
<MobileApartmentDescription
apartment={currentApartment}
apartmentDataType={currentApartmentType}
apartments={apartments}
floor={currentFloor}
/>
</div>
)}
<div
className={`flex flex-col text-white px-4 pb-6 transition-opacity duration-300 ease-in-out h-[405px] pt-[202.5px] ${
isAnimate ? "opacity-100" : "opacity-0"
}`}
>
<p className="text-subheadline-s font-semibold">
Rove Home Marasi Drive
</p>
<p className="text-s">{currentFloor?.floor} floor</p>
</div>
<div
style={{ transform: `translateY(${isAnimate ? 0 : 100}%)` }}
className="bg-[#F3F3F2] h-full p-6 pt-0 flex flex-col gap-6 transition-transform ease-in-out relative"
>
<div
className="w-[calc(100%-135px)] absolute flex justify-center py-3"
{...handlers}
>
<div className="zoom-280">
<MinusIcon />
</div>
</div>
<div className="pt-6 flex justify-between items-center">
<div className="flex flex-col">
<h2 className="font-semibold text-[#0D1922] text-subheadline-m">
{currentFloor?.floor} floor
</h2>
<p className="text-s">{wing}</p>
</div>
<div className="py-[8.44px] px-2 text-white bg-[#00BED7] rounded-full text-caption-m">
{floorApartments.length} units
</div>
</div>
<div className="flex justify-between items-center py-2 px-4 rounded-lg bg-white">
<TransparentSelector
options={optionsFloors}
onClick={handleOnFloorOptionClick}
/>
<div className="flex items-center justify-center gap-6">
<div className="flex gap-2 text-[#0D1922B2] items-center">
<div className="w-[48px] h-[48px] text-caption-m flex items-center bg-[#A19E9E] text-white justify-center rounded-full pt-[1.5px] pb-[2.5px]">
{
floorApartments.filter(
(aprt) => aprt.Unit_Type === "Studio Flex"
).length
}
</div>
<p className="text-caption-m font-semibold">Studio flex</p>
</div>
<div className="flex gap-2 text-[#0D1922B2] items-center">
<div className="w-[48px] h-[48px] text-caption-m flex items-center bg-[#8299AD] text-white justify-center rounded-full pt-[1.5px] pb-[2.5px]">
{
floorApartments.filter(
(aprt) => aprt.Unit_Type === "Studio Squared"
).length
}
</div>
<p className="text-caption-m font-semibold">Studio</p>
</div>
<div className="flex gap-2 text-[#0D1922B2] items-center">
<div className="w-[48px] h-[48px] text-caption-m flex items-center bg-[#BFC9D1] text-white justify-center rounded-full pt-[1.5px] pb-[2.5px]">
{
floorApartments.filter(
(aprt) => aprt.Unit_Type === "1 BR Squared"
).length
}
</div>
<p className="text-caption-m font-semibold">1 Bedroom</p>
</div>
<div className="flex gap-2 text-[#0D1922B2] items-center">
<div className="w-[48px] h-[48px] text-caption-m flex items-center bg-[#878FA3] text-white justify-center rounded-full pt-[1.5px] pb-[2.5px]">
{
floorApartments.filter(
(aprt) => aprt.Unit_Type === "2 BR Squared"
).length
}
</div>
<p className="text-caption-m font-semibold">2 Bedroom</p>
</div>
</div>
</div>
<div className="px-10 bg-white flex gap-6 font-semibold text-caption-m rounded-2xl justify-center items-center py-4 overflow-clip">
{currentFloor?.wing === "West Wing" ? (
currentFloor && currentFloor.floor <= 21 ? (
<svg
className="rotate-[135deg] zoom-280"
xmlns="http://www.w3.org/2000/svg"
width="400"
height="700"
fill="none"
viewBox="0 0 204 600"
>
<WestWingLayout />
<WestWingHighlighting
handleOnApartmentClick={handleOnApartmentClick}
/>
</svg>
) : (
<svg
className="rotate-[135deg] zoom-280"
xmlns="http://www.w3.org/2000/svg"
width="400"
height="700"
fill="none"
viewBox="0 0 204 600"
>
<WestWingTopLevelsLayout />
<WestWingTopLevelsHighlighting
handleOnApartmentClick={handleOnApartmentClick}
/>
</svg>
)
) : (
<svg
className="rotate-[135deg] zoom-280"
xmlns="http://www.w3.org/2000/svg"
fill="none"
width="672"
height="700"
viewBox="0 0 672 280"
>
<EastWingLayout />
<EastWingHighlighting
handleOnApartmentClick={handleOnApartmentClick}
/>
</svg>
)}
</div>
</div>
</div>
</>
);
};
// const TransparentSelector = ({
// options,
// setOptions,
// }: TransparentSelectorProps) => {
// const [isOpened, setIsOpened] = useState(false);
// const handleOnClick = () => {
// setIsOpened((prev) => !prev);
// };
// return (
// <div className="relative">
// <div
// className="text-[#00BED7] text-[38.4px] flex gap-[19.2px] items-center justify-center cursor-pointer select-none"
// onClick={handleOnClick}
// >
// <p>11 floor</p>
// <div
// className={`zoom-280 ease-in-out duration-300 transition-transform ${
// isOpened ? "-rotate-180" : ""
// }`}
// >
// <ChevronDownIcon />
// </div>
// </div>
// {isOpened && (
// <div className="flex flex-col bg-black p-[19.2px] absolute -bottom-[49px]">
// {options.map}
// </div>
// )}
// </div>
// );
// };
export default WingFloorModal;