Files
IRTH/client/src/components/complexWingPage/SequenceWing/SequenceWing.tsx
T
2024-07-10 18:09:53 +05:00

465 lines
14 KiB
TypeScript

/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { MouseEvent, useEffect, useState } from "react";
import FloorDescription from "../FloorDescription";
import { IDesctiptionFloor } from "../../../types/descriptionFloor";
import SkygardenDescription from "../SkygardenDescription";
import FloorSidebar from "../FloorSidebar/FloorSidebar";
import SkygardenSidebar from "../SkygardenSidebar/SkygardenSidebar";
import useWingSidebar from "../../../store/useWingSidebar";
import useModal from "../../../store/useModal";
import {
laptopWidth,
mobileWidht,
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 { useDebounce } from "@uidotdev/usehooks";
import { getFilteredApartments } from "../../../calc/getFilteredApartments";
import LoaderModal from "../../modals/LoaderModal";
import FloorNumbers from "./FloorNumbers";
import WingSignatures from "./WingSignatures";
import { isMobile } from "react-device-detect";
import FloorsHighlighting from "./FloorsHighlighting";
import MobileFloorDescription from "./MobileFloorDescription";
import WingFloorModal from "../../modals/mobile/WingFloorModal";
import MobileSkygardenDescription from "./MobileSkygardenDescription";
const skyGardenFloor = 22;
const SequenceWing = () => {
const [width, setWidth] = useState<number>(0);
const [top, setTop] = useState<number>(0);
const [left, setLeft] = useState<number>(0);
const { isSidebar, setIsSidebar } = useWingSidebar();
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 [isWrapperHovered, setIsWrapperHovered] = useState(false);
const [isSkygardenSidebar, setIsSkygardenSidebar] = useState(false);
const [isFloorSidebar, setIsFloorSidebar] = useState(false);
const { setModal } = useModal();
const [apartments, setApartments] = useState<IAparmentRes[]>([]);
const [currentHoveredApartments, setCurrentHoveredApartments] = useState<
IAparmentRes[]
>([]);
const [selectedApartments, setSelectedApartments] = useState<IAparmentRes[]>(
[]
);
const [isLeft, setIsLeft] = 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 = () => {
if (!currentHoveredFloor && !currentHoveredApartments) return;
setCurrentFloor(currentHoveredFloor);
setSelectedApartments(currentHoveredApartments);
const screenWidth = window.innerWidth;
const isMobile = screenWidth <= mobileWidht;
if (isMobile) return;
// <640
setIsFloorSidebar(true);
setIsSkygardenSidebar(false);
setIsSidebar(true);
};
const handleOnSkygardenClick = () => {
if (!isMobile) {
setIsSkygardenSidebar(true);
setIsFloorSidebar(false);
setIsSidebar(true);
} else {
// setModal(<WingFloorModal />);
}
};
const handleMouseMove = (
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
) => {
const screenWidth = window.innerWidth;
const _isLeft = e.clientX > screenWidth / 2;
setIsLeft(_isLeft);
// <640
if (screenWidth <= mobileWidht) return;
// const _top = screenHeight / 16;
if (screenWidth > laptopWidth) {
const x = _isLeft ? e.clientX - 795 : e.clientX - 384;
setMousePos([x, e.clientY + top - 25]);
} else {
// 640-1072
if (screenWidth > mobileWidht) {
const x = _isLeft ? e.clientX + left - 800 : e.clientX - 385 + left;
setMousePos([x, e.clientY + top - 25]);
}
}
};
const handleOnMouseDown = (
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
) => {
const isFloorClicked = Boolean(e.target.dataset.id);
if (!isFloorClicked) return;
const screenWidth = window.innerWidth;
const _isLeft = e.clientX > screenWidth / 2;
setIsLeft(_isLeft);
if (screenWidth > mobileWidht) return;
// <640
const x = _isLeft ? e.clientX - 724 + left : e.clientX - 444 + left;
setMousePos([x, e.clientY + Math.abs(top) + 20]);
};
// function handleOnMouseDown(e: MouseEvent | any) {
// 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]);
// // setMousePos([e.clientX - 444 + _left, e.clientY + Math.abs(_top) + 30]);
// // <640
// } else {
// const _top = screenHeight / 2.5;
// const _left = laptopWidth - screenWidth;
// setMousePos([e.clientX - 440 + _left, e.clientY + Math.abs(_top) + 20]);
// }
// }
// }
function handleResize() {
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
if (screenWidth > laptopWidth) {
setWidth(screenWidth);
setTop(screenWidth / 2 - screenHeight / 2);
setLeft(0);
} else {
if (screenWidth > mobileWidht) {
const _top = screenHeight / 16;
setTop(_top);
} else {
const _top = screenHeight / 5.5;
setTop(_top);
}
const _left = (laptopWidth - screenWidth) * 1.1;
const _width = screenWidth + _left * 1.9;
setWidth(_width);
setLeft(_left);
}
}
const handleOnExploreFloorClick = (
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
) => {
e.stopPropagation();
// if (!currentHoveredFloor) return;
setModal(
<WingFloorModal
currentFloor={currentHoveredFloor}
floorApartments={currentHoveredApartments}
/>
);
};
const handleOnExploreSkygardenClick = (
e: MouseEvent<Element, MouseEvent<Element, MouseEvent>> | any
) => {
e.stopPropagation();
// if (!currentHoveredFloor) return;
setModal(
<WingFloorModal
currentFloor={currentHoveredFloor}
floorApartments={currentHoveredApartments}
/>
);
};
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);
};
}, [handleMouseMove]);
useEffect(() => {
if (!isSidebar) {
setIsFloorSidebar(false);
setIsSkygardenSidebar(false);
}
}, [isSidebar]);
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 h-[calc(100vh-56px)] right-0 w-1/2 duration-300 transition-all sm:block hidden"
style={{ right: `${isFloorSidebar ? "0" : "-50%"}` }}
>
<FloorSidebar
floorApartments={selectedApartments}
currentFloor={currentFloor}
onMouseEnter={handleOnWingWrapperMouseLeave}
/>
</div>
<div
className=" absolute h-[calc(100vh-56px)] right-0 w-1/2 duration-300 transition-all sm:block hidden"
style={{ right: `${isSkygardenSidebar ? "0" : "-50%"}` }}
>
<SkygardenSidebar onMouseEnter={handleOnWingWrapperMouseLeave} />
</div>
<div
className="absolute left-0 transition-[left]"
style={{
width: `${width}px`,
height: `${width}px`,
top: `-${top}px`,
left: `${
isSkygardenSidebar || isFloorSidebar ? "-25%" : `-${left}px`
}`,
}}
>
<div
className={`absolute z-40 top-0 left-0 transition-opacity duration-300 ease-in-out sm:flex hidden ${
currentHoveredFloor?.floor === skyGardenFloor && isWrapperHovered
? "opacity-100"
: "opacity-0"
}`}
style={{
top: mousePos[1] - 25,
left: `${
isSkygardenSidebar || isFloorSidebar
? `calc(${mousePos[0]}px + 25%)`
: `${mousePos[0]}px`
}`,
}}
>
<SkygardenDescription isLeft={isLeft} />
</div>
<div
className={`absolute z-40 top-0 left-0 transition-opacity duration-300 ease-in-out sm:flex hidden ${
currentHoveredFloor?.floor !== skyGardenFloor &&
currentHoveredFloor &&
isWrapperHovered
? "opacity-100"
: "opacity-0"
}`}
style={{
top: mousePos[1],
left: `${
isSkygardenSidebar || isFloorSidebar
? `calc(${mousePos[0]}px + 25%)`
: `${mousePos[0]}px`
}`,
}}
>
<FloorDescription
isLeft={isLeft}
descriptionFloor={currentHoveredFloor}
floorApartments={currentHoveredApartments}
/>
</div>
<div
className={`absolute z-40 top-0 left-0 transition-opacity duration-300 ease-in-out sm:hidden flex ${
currentHoveredFloor?.floor !== skyGardenFloor &&
currentHoveredFloor &&
isWrapperHovered
? "flex"
: "hidden"
}`}
style={{
top: mousePos[1],
left: `${mousePos[0]}px`,
}}
>
<MobileFloorDescription
isLeft={isLeft}
onClick={handleOnExploreFloorClick}
descriptionFloor={currentHoveredFloor}
floorApartments={currentHoveredApartments}
/>
</div>
<div
className={`absolute z-40 top-0 left-0 transition-opacity duration-300 ease-in-out sm:hidden flex ${
currentHoveredFloor?.floor === skyGardenFloor &&
currentHoveredFloor &&
isWrapperHovered
? "flex"
: "hidden"
}`}
style={{
top: mousePos[1],
left: `${mousePos[0]}px`,
}}
>
<MobileSkygardenDescription
onClick={handleOnExploreSkygardenClick}
isLeft={isLeft}
/>
</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;