Dwinzo_dev/app/src/components/ui/componets/DisplayZone.tsx

214 lines
6.2 KiB
TypeScript
Raw Normal View History

2025-03-27 05:24:40 +00:00
import React, { useEffect, useRef, useState, useCallback } from "react";
2025-03-25 12:04:20 +00:00
import { Widget } from "../../../store/useWidgetStore";
2025-03-27 12:40:49 +00:00
import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
import { InfoIcon } from "../../icons/ExportCommonIcons";
import { useDroppedObjectsStore } from "../../../store/useDroppedObjectsStore";
import { getSelect2dZoneData } from "../../../services/realTimeVisulization/zoneData/getSelect2dZoneData";
2025-03-25 12:04:20 +00:00
// Define the type for `Side`
type Side = "top" | "bottom" | "left" | "right";
interface DisplayZoneProps {
zonesData: {
[key: string]: {
activeSides: Side[];
panelOrder: Side[];
2025-03-25 12:04:20 +00:00
lockedPanels: Side[];
widgets: Widget[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
2025-03-25 12:04:20 +00:00
};
};
selectedZone: {
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
2025-03-25 12:04:20 +00:00
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
2025-03-25 12:04:20 +00:00
widgets: {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}[];
};
setSelectedZone: React.Dispatch<
React.SetStateAction<{
zoneName: string;
activeSides: Side[];
panelOrder: Side[];
2025-03-25 12:04:20 +00:00
lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
2025-03-25 12:04:20 +00:00
widgets: {
id: string;
type: string;
title: string;
panel: Side;
data: any;
}[];
}>
>;
}
const DisplayZone: React.FC<DisplayZoneProps> = ({
zonesData,
selectedZone,
setSelectedZone,
}) => {
2025-03-25 12:04:20 +00:00
// Ref for the container element
const containerRef = useRef<HTMLDivElement | null>(null);
2025-03-27 12:40:49 +00:00
// State to track overflow visibility
const [showLeftArrow, setShowLeftArrow] = useState(false);
const [showRightArrow, setShowRightArrow] = useState(false);
2025-03-25 12:04:20 +00:00
2025-03-27 12:40:49 +00:00
// Function to calculate overflow state
const updateOverflowState = useCallback(() => {
2025-03-25 12:04:20 +00:00
const container = containerRef.current;
2025-03-27 05:24:40 +00:00
if (container) {
const isOverflowing = container.scrollWidth > container.clientWidth;
const canScrollLeft = container.scrollLeft > 0;
const canScrollRight =
container.scrollLeft + container.clientWidth < container.scrollWidth;
2025-03-25 12:04:20 +00:00
2025-03-27 05:24:40 +00:00
setShowLeftArrow(isOverflowing && canScrollLeft);
setShowRightArrow(isOverflowing && canScrollRight);
2025-03-25 12:04:20 +00:00
}
2025-03-27 05:24:40 +00:00
}, []);
2025-03-25 12:04:20 +00:00
useEffect(() => {
const container = containerRef.current;
2025-03-27 05:24:40 +00:00
if (container) {
// Initial calculation after the DOM has been rendered
const handleInitialRender = () => {
requestAnimationFrame(updateOverflowState);
};
handleInitialRender();
// Update on window resize or scroll
const handleResize = () => updateOverflowState();
const handleScroll = () => updateOverflowState();
// Add mouse wheel listener for horizontal scrolling
const handleWheel = (event: WheelEvent) => {
event.preventDefault(); // Prevent default vertical scrolling
if (container) {
container.scrollBy({
left: event.deltaY * 2, // Translate vertical scroll to horizontal scroll
behavior: "smooth",
});
}
};
2025-03-25 12:04:20 +00:00
2025-03-27 05:24:40 +00:00
container.addEventListener("scroll", handleScroll);
window.addEventListener("resize", handleResize);
container.addEventListener("wheel", handleWheel, { passive: false });
2025-03-25 12:04:20 +00:00
2025-03-27 05:24:40 +00:00
return () => {
container.removeEventListener("scroll", handleScroll);
window.removeEventListener("resize", handleResize);
container.removeEventListener("wheel", handleWheel);
};
}
}, [updateOverflowState]);
2025-03-25 12:04:20 +00:00
2025-03-27 05:24:40 +00:00
// Handle scrolling with navigation arrows
const handleScrollLeft = () => {
const container = containerRef.current;
2025-03-25 12:04:20 +00:00
if (container) {
2025-03-27 05:24:40 +00:00
container.scrollBy({
left: -200, // Scroll left by 200px
behavior: "smooth",
});
2025-03-25 12:04:20 +00:00
}
2025-03-27 05:24:40 +00:00
};
2025-03-25 12:04:20 +00:00
2025-03-27 05:24:40 +00:00
const handleScrollRight = () => {
const container = containerRef.current;
if (container) {
container.scrollBy({
left: 200, // Scroll right by 200px
behavior: "smooth",
});
}
2025-03-25 12:04:20 +00:00
};
async function handleSelect2dZoneData(zoneId: string, zoneName: string) {
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
let response = await getSelect2dZoneData(zoneId, organization)
setSelectedZone({
zoneName,
activeSides: response.activeSides,
panelOrder: response.panelOrder,
lockedPanels: response.lockedPanels,
widgets: response.widgets,
zoneId: zoneId,
zoneViewPortTarget:
response.viewPortCenter,
zoneViewPortPosition:
response.viewPortposition,
});
}
2025-03-25 12:04:20 +00:00
return (
<div
className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom"
}`}
2025-03-25 12:04:20 +00:00
>
2025-03-27 05:24:40 +00:00
{/* Left Arrow */}
{showLeftArrow && (
<button className="arrow left-arrow" onClick={handleScrollLeft}>
<MoveArrowLeft />
2025-03-27 05:24:40 +00:00
</button>
)}
{/* Zones Wrapper */}
{Object.keys(zonesData).length !== 0 ? (
<div ref={containerRef} className="zones-wrapper">
{Object.keys(zonesData).map((zoneName, index) => (
<div
key={index}
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
}`}
onClick={() => {
2025-03-27 12:40:49 +00:00
useDroppedObjectsStore.getState().setZone(zoneName, zonesData[zoneName]?.zoneId);
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
}}
>
{zoneName}
</div>
))}
</div>
) : (
<div className="no-zone">
<InfoIcon />
No zones? Create one!
2025-03-25 12:04:20 +00:00
</div>
)}
2025-03-27 05:24:40 +00:00
{/* Right Arrow */}
{showRightArrow && (
<button className="arrow right-arrow" onClick={handleScrollRight}>
<MoveArrowRight />
2025-03-27 05:24:40 +00:00
</button>
)}
2025-03-25 12:04:20 +00:00
</div>
);
};
export default DisplayZone;