368 lines
12 KiB
TypeScript
368 lines
12 KiB
TypeScript
/* eslint-disable react-hooks/exhaustive-deps */
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import { MouseEvent, useEffect, useState } from "react";
|
|
import { useDebounce } from "@uidotdev/usehooks";
|
|
import { IDesctiptionFloor } from "../../../types/descriptionFloor";
|
|
import useModal from "../../../store/useModal";
|
|
import { descriptions } from "../../../consts/masterplan";
|
|
import { updateAccessToken } from "../../../api/updateAccessToken";
|
|
import { IAparmentRes } from "../../../types/apartmentsRes";
|
|
import useMasterplanFilters from "../../../store/useMasterplanFilters";
|
|
import { initialRoveHomeCheckboxes } from "../../../consts/initialMasterplanFilters";
|
|
import { pageInitial } from "../../../consts/initialMasterplanFilters";
|
|
import { getFilteredApartments } from "../../../calc/getFilteredApartments";
|
|
import FloorNumbers from "./FloorNumbers";
|
|
import WingSignatures from "./WingSignatures";
|
|
import FloorsHighlighting from "./FloorsHighlighting";
|
|
import MobileFloorDescription from "./MobileFloorDescription";
|
|
import WingFloorModal from "../../modals/mobile/WingFloorModal";
|
|
import MobileSkygardenDescription from "./MobileSkygardenDescription";
|
|
import SkygardenModal from "../../modals/mobile/SkygardenModal";
|
|
import LoaderModal from "../../modals/LoaderModal";
|
|
|
|
// const skyGardenFloor = 22;
|
|
|
|
const SequenceWing = () => {
|
|
const [width, setWidth] = useState<number>(0);
|
|
const [top, setTop] = useState<number>(0);
|
|
const [left, setLeft] = useState<number>(0);
|
|
const [isLeft, setIsLeft] = useState(false);
|
|
const [mousePos, setMousePos] = useState<[number, number]>([0, 0]);
|
|
const [currentHoveredFloor, setHoverCurrentFloor] =
|
|
useState<null | IDesctiptionFloor>(null);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [currentFloor, setCurrentFloor] = useState<IDesctiptionFloor | null>(
|
|
null
|
|
);
|
|
const [, setIsWrapperHovered] = useState(false);
|
|
const [isSkygardenSidebar] = useState(false);
|
|
const [isFloorSidebar] = useState(false);
|
|
const { setModal } = useModal();
|
|
const [apartments, setApartments] = useState<IAparmentRes[]>([]);
|
|
const [currentHoveredApartments, setCurrentHoveredApartments] = useState<
|
|
IAparmentRes[]
|
|
>([]);
|
|
|
|
const [isDescriptionFloorMobile, setIsDescriptionFloorMobile] =
|
|
useState(false);
|
|
const [isDescriptionSkygarden, setIsDescriptionSkygarden] = useState(false);
|
|
|
|
const {
|
|
apartmentTypeCheckboxes,
|
|
switchers,
|
|
multirangeSliders,
|
|
viewCheckboxes,
|
|
sortList,
|
|
} = useMasterplanFilters();
|
|
const debouncedSliders = useDebounce(multirangeSliders, 300);
|
|
|
|
const handleOnFloorMouseEnter = (
|
|
e: React.MouseEvent<SVGPathElement, MouseEvent>
|
|
) => {
|
|
e.stopPropagation();
|
|
const id = e.currentTarget.dataset.id;
|
|
if (!id) return;
|
|
const _currentFloor = descriptions.find((desc) => desc.id === id);
|
|
if (!_currentFloor) return;
|
|
setHoverCurrentFloor(_currentFloor);
|
|
const _currentHoveredApartments = apartments.filter((apartment) => {
|
|
const wing =
|
|
apartment.Unit_No.split("-")[0] === "E" ? "East Wing" : "West Wing";
|
|
return (
|
|
apartment.Floor === _currentFloor.floor && wing === _currentFloor.wing
|
|
);
|
|
});
|
|
setIsWrapperHovered(true);
|
|
setCurrentHoveredApartments(_currentHoveredApartments);
|
|
};
|
|
|
|
const handleOnWingWrapperMouseEnter = (
|
|
e: React.MouseEvent<SVGSVGElement>
|
|
) => {
|
|
(e as unknown as Event).stopPropagation();
|
|
setIsWrapperHovered(true);
|
|
};
|
|
const handleOnWingWrapperMouseLeave = () => {
|
|
setIsWrapperHovered(false);
|
|
};
|
|
|
|
const handleOnFloorClick = () => {
|
|
setIsDescriptionSkygarden(false);
|
|
//detect currentFloor
|
|
if (!currentHoveredFloor && !currentHoveredApartments) return;
|
|
setCurrentFloor(currentHoveredFloor);
|
|
};
|
|
|
|
const handleOnSkygardenClick = () => {
|
|
setCurrentFloor(null);
|
|
setIsDescriptionFloorMobile(false);
|
|
setIsDescriptionSkygarden(true);
|
|
};
|
|
|
|
function handleMouseMove(
|
|
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
|
|
) {
|
|
const isFloorClicked = Boolean(e.target.dataset.id);
|
|
if (isFloorClicked) {
|
|
setMousePos([e.clientX - 364, e.clientY + Math.abs(top) - 20]);
|
|
} else {
|
|
setIsDescriptionFloorMobile(false);
|
|
}
|
|
}
|
|
|
|
function handleOnMouseDown(e: MouseEvent | any) {
|
|
const isFloorClicked = Boolean(e.target.dataset.id);
|
|
if (isFloorClicked) {
|
|
const _isLeft = e.clientX > 1400;
|
|
setIsLeft(_isLeft);
|
|
const descPosX = _isLeft ? e.clientX + 524 : e.clientX + 1184;
|
|
|
|
// detect mouse pos
|
|
const screenWidth = window.innerWidth;
|
|
const screenHeight = window.innerHeight;
|
|
const _top = screenWidth / 2 - screenHeight / 2;
|
|
setMousePos([descPosX, e.clientY + Math.abs(_top) + 50]);
|
|
|
|
//detect currentFloor, current sidebar and apartment on floor
|
|
if (!currentHoveredFloor && !currentHoveredApartments) return;
|
|
setCurrentFloor(currentHoveredFloor);
|
|
setIsDescriptionFloorMobile(true);
|
|
setCurrentFloor(null);
|
|
}
|
|
}
|
|
// function handleOnMouseDown(e: MouseEvent | any) {
|
|
// const isFloorClicked = Boolean(e.target.dataset.id);
|
|
// if (isFloorClicked) {
|
|
// // detect mouse pos
|
|
// const screenWidth = window.innerWidth;
|
|
// const screenHeight = window.innerHeight;
|
|
// // >1072
|
|
// if (screenWidth > laptopWidth) {
|
|
// const _top = screenWidth / 2 - screenHeight / 2;
|
|
// setMousePos([e.clientX - 384, e.clientY + Math.abs(_top) - 20]);
|
|
// } else {
|
|
// // 640-1072
|
|
// if (screenWidth > mobileWidht) {
|
|
// const _top = screenHeight / 4;
|
|
// const _left = laptopWidth - screenWidth;
|
|
// setMousePos([
|
|
// e.clientX - 440 + _left,
|
|
// e.clientY + Math.abs(_top) + 20,
|
|
// ]);
|
|
// // <640
|
|
// } else {
|
|
// const _top = screenHeight / 2.5;
|
|
// const _left = laptopWidth - screenWidth;
|
|
// setMousePos([
|
|
// e.clientX - 440 + _left,
|
|
// e.clientY + Math.abs(_top) + 20,
|
|
// ]);
|
|
// }
|
|
// }
|
|
|
|
// //detect currentFloor, current sidebar and apartment on floor
|
|
// if (!currentHoveredFloor && !currentHoveredApartments) return;
|
|
// setCurrentFloor(currentHoveredFloor);
|
|
// if (!isMobile) {
|
|
// setIsFloorSidebar(true);
|
|
// setIsSkygardenSidebar(false);
|
|
// setIsSidebar(true);
|
|
// } else {
|
|
// setIsDescriptionFloorMobile(true);
|
|
// setCurrentFloor(null);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
function handleResize() {
|
|
const screenWidth = window.innerWidth;
|
|
const screenHeight = window.innerHeight;
|
|
const _top = screenHeight / 4.5;
|
|
setTop(_top);
|
|
const _left = screenHeight - screenWidth;
|
|
const _width = screenHeight + _left;
|
|
|
|
setWidth(_width);
|
|
setLeft(_left);
|
|
}
|
|
|
|
const handleOnExploreFloorClick = (
|
|
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
|
|
) => {
|
|
e.stopPropagation();
|
|
if (!currentHoveredFloor) return;
|
|
setModal(
|
|
<WingFloorModal
|
|
currentFloor={currentHoveredFloor}
|
|
floorApartments={currentHoveredApartments}
|
|
/>
|
|
);
|
|
setIsDescriptionFloorMobile(false);
|
|
};
|
|
|
|
const handleOnExploreSkygardenClick = (
|
|
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
|
|
) => {
|
|
e.stopPropagation();
|
|
setIsDescriptionSkygarden(false);
|
|
setModal(<SkygardenModal />);
|
|
setIsDescriptionFloorMobile(false);
|
|
};
|
|
|
|
useEffect(() => {
|
|
handleResize();
|
|
window.addEventListener("resize", handleResize);
|
|
window.addEventListener("mousemove", handleMouseMove);
|
|
window.addEventListener("mousedown", handleOnMouseDown);
|
|
return () => {
|
|
window.removeEventListener("resize", handleResize);
|
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
window.removeEventListener("mousedown", handleOnMouseDown);
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const localStorageToken = `${localStorage.getItem("ACCESS_TOKEN")}`;
|
|
const perPage = 1000;
|
|
const getApartments = (token: string) =>
|
|
getFilteredApartments(
|
|
token,
|
|
setApartments,
|
|
initialRoveHomeCheckboxes,
|
|
apartmentTypeCheckboxes,
|
|
debouncedSliders,
|
|
switchers,
|
|
viewCheckboxes,
|
|
sortList,
|
|
pageInitial,
|
|
perPage
|
|
);
|
|
|
|
setIsLoading(true);
|
|
|
|
getApartments(localStorageToken)
|
|
.then(() => {
|
|
setIsLoading(false);
|
|
})
|
|
.catch((error) => {
|
|
const errorStatus = error.response.status;
|
|
|
|
if (errorStatus === 401) {
|
|
updateAccessToken()
|
|
.then((token) => {
|
|
if (token) {
|
|
getApartments(token).then(() => {
|
|
setIsLoading(false);
|
|
});
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
setIsLoading(false);
|
|
console.error("error", error);
|
|
});
|
|
} else {
|
|
setIsLoading(false);
|
|
console.error("error", error);
|
|
}
|
|
});
|
|
}, [
|
|
setApartments,
|
|
apartmentTypeCheckboxes,
|
|
debouncedSliders,
|
|
switchers,
|
|
viewCheckboxes,
|
|
sortList,
|
|
]);
|
|
|
|
useEffect(() => {
|
|
if (isLoading) {
|
|
setModal(<LoaderModal />);
|
|
} else {
|
|
setModal(null);
|
|
}
|
|
}, [isLoading, setModal]);
|
|
|
|
return (
|
|
<div className="absolute left-0 overflow-hidden h-screen w-screen select-none ">
|
|
<div
|
|
className="absolute left-0 transition-[left]"
|
|
style={{
|
|
width: `${width}px`,
|
|
height: `${width}px`,
|
|
top: `-${top}px`,
|
|
left: `-${left}px`,
|
|
}}
|
|
>
|
|
{/* */}
|
|
<div
|
|
className={`absolute z-40 top-0 left-0 transition-opacity duration-300 ease-in-out ${
|
|
isDescriptionSkygarden ? "" : "hidden"
|
|
}`}
|
|
style={{
|
|
top: `${mousePos[1]}px`,
|
|
left: `${mousePos[0]}px`,
|
|
}}
|
|
>
|
|
<MobileSkygardenDescription
|
|
isLeft={isLeft}
|
|
onClick={handleOnExploreSkygardenClick}
|
|
/>
|
|
</div>
|
|
<div
|
|
className={`absolute z-40 top-0 left-0 transition-opacity duration-300 ease-in-out ${
|
|
isDescriptionFloorMobile ? "" : "hidden"
|
|
}`}
|
|
style={{
|
|
top: `${mousePos[1]}px`,
|
|
left: `${mousePos[0]}px`,
|
|
}}
|
|
>
|
|
<MobileFloorDescription
|
|
isLeft={isLeft}
|
|
onClick={handleOnExploreFloorClick}
|
|
descriptionFloor={currentHoveredFloor}
|
|
floorApartments={currentHoveredApartments}
|
|
/>
|
|
</div>
|
|
|
|
<img
|
|
width={`${width}px`}
|
|
height={`${width}px`}
|
|
src="/images/sequenceWing.jpg"
|
|
className={`absolute z-10 duration-300 transition-opacity ease-in-out opacity-100 select-none`}
|
|
alt=""
|
|
/>
|
|
<svg
|
|
width="1920"
|
|
height="1920"
|
|
viewBox="0 0 1920 1920"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className={`absolute top-0 left-0 duration-300 transition-opacity ease-in-out w-full h-full opacity-100 z-10 `}
|
|
onMouseOver={handleOnWingWrapperMouseLeave}
|
|
>
|
|
{/* Подписи Крылья */}
|
|
<WingSignatures />
|
|
|
|
{/* Цифры этажи */}
|
|
<FloorNumbers />
|
|
|
|
{/* Этажи */}
|
|
<FloorsHighlighting
|
|
handleOnFloorClick={handleOnFloorClick}
|
|
handleOnSkygardenClick={handleOnSkygardenClick}
|
|
handleOnWingWrapperMouseEnter={handleOnWingWrapperMouseEnter}
|
|
handleOnFloorMouseEnter={handleOnFloorMouseEnter}
|
|
handleOnWingWrapperMouseLeave={handleOnWingWrapperMouseLeave}
|
|
currentFloor={currentFloor}
|
|
isFloorSidebar={isFloorSidebar}
|
|
isSkygardenSidebar={isSkygardenSidebar}
|
|
/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SequenceWing;
|