Files
Dwinzo_dev/app/src/components/ui/componets/DroppedFloatingWidgets.tsx

215 lines
6.4 KiB
TypeScript
Raw Normal View History

2025-03-27 12:28:17 +05:30
2025-03-27 18:04:16 +05:30
import { WalletIcon } from "../../icons/3dChartIcons";
import { useEffect, useRef, useState } from "react";
import { Line } from "react-chartjs-2";
import { useDroppedObjectsStore, Zones } from "../../../store/useDroppedObjectsStore";
2025-03-27 12:28:17 +05:30
2025-03-27 18:04:16 +05:30
const DroppedObjects: React.FC = () => {
const zones = useDroppedObjectsStore((state) => state.zones);
const updateObjectPosition = useDroppedObjectsStore((state) => state.updateObjectPosition);
const [draggingIndex, setDraggingIndex] = useState<{ zone: string; index: number } | null>(null);
const [offset, setOffset] = useState<[number, number] | null>(null);
const positionRef = useRef<[number, number] | null>(null);
const animationRef = useRef<number | null>(null);
// useEffect(() => {
// const initialZones: Record<string, Zones> = {
// "Zone 1": {
// zoneName: "Zone 1",
// zoneId: "2e996073-546c-470c-8323-55bd3700c6aa",
// objects: [
// {
// header: "Todays Money",
// value: 53000, // ✅ Converted to number
// per: "+55%",
// className: "floating total-card",
// position: [146, 214], // ✅ No need for 'as' here
// },
// {
// header: "New Clients",
// value: 250, // ✅ Converted to number
// per: "+12%",
// className: "floating total-card",
// position: [344, 295],
// },
// ],
// },
// };
// useDroppedObjectsStore.setState({ zones: initialZones });
// }, []);
const zoneEntries = Object.entries(zones);
if (zoneEntries.length === 0) return null; // No zone, nothing to render
const [zoneName, zone] = zoneEntries[0]; // Only render the first zone
function handlePointerDown(event: React.PointerEvent, index: number) {
const obj = zone.objects[index];
const offsetX = event.clientX - obj.position[1];
const offsetY = event.clientY - obj.position[0];
setDraggingIndex({ zone: zoneName, index });
setOffset([offsetY, offsetX]);
}
function handlePointerMove(event: React.PointerEvent) {
if (!draggingIndex || !offset) return;
const container = document.getElementById("real-time-vis-canvas");
if (!container) return;
const rect = container.getBoundingClientRect();
let newX = event.clientX - offset[1];
let newY = event.clientY - offset[0];
newX = Math.max(0, Math.min(rect.width - 50, newX));
newY = Math.max(0, Math.min(rect.height - 50, newY));
positionRef.current = [newY, newX];
if (!animationRef.current) {
animationRef.current = requestAnimationFrame(() => {
if (positionRef.current) {
updateObjectPosition(zoneName, draggingIndex.index, positionRef.current);
}
animationRef.current = null;
});
}
}
function handlePointerUp() {
setDraggingIndex(null);
setOffset(null);
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
animationRef.current = null;
}
}
2025-03-27 12:28:17 +05:30
2025-03-27 18:04:16 +05:30
return (
<div onPointerMove={handlePointerMove} onPointerUp={handlePointerUp}>
{zone.objects.map((obj, index) => (
<div
key={`${zoneName}-${index}`}
className={obj.className}
style={{
top: obj.position[0] + "px",
left: obj.position[1] + "px",
transition: draggingIndex?.index === index ? "none" : "transform 0.1s ease-out",
}}
onPointerDown={(event) => handlePointerDown(event, index)}
>
{obj.className === "floating total-card" ? (
<div>
<div className="header-wrapper">
<div className="header">{obj.header}</div>
<div className="data-values">
<div className="value">{obj.value}</div>
<div className="per">{obj.per}</div>
</div>
</div>
<div className="icon">
<WalletIcon />
</div>
</div>
) : obj.className === "warehouseThroughput floating" ? (
<div>
<div className="header">
<h2>Warehouse Throughput</h2>
<p>
<span>(+5) more</span> in 2025
</p>
</div>
<div className="lineGraph" style={{ height: "100%" }}>
{/* <Line data={lineGraphData} options={lineGraphOptions} /> */}
</div>
</div>
) : obj.className === "fleetEfficiency floating" ? (
<div>
<h2 className="header">Fleet Efficiency</h2>
<div className="progressContainer">
<div className="progress">
<div className="barOverflow">
<div
className="bar"
style={{ transform: `rotate(${obj.value}deg)` }}
></div>
</div>
</div>
</div>
<div className="scaleLabels">
<span>0%</span>
<div className="centerText">
<div className="percentage">{obj.per}%</div>
<div className="status">Optimal</div>
</div>
<span>100%</span>
</div>
</div>
) : null}
</div>
))}
</div>
);
};
2025-03-27 12:28:17 +05:30
2025-03-27 18:04:16 +05:30
export default DroppedObjects;
2025-03-27 12:28:17 +05:30
2025-03-27 12:28:17 +05:30
2025-03-27 18:04:16 +05:30
// import { Html } from "@react-three/drei";
// import { useDroppedObjectsStore } from "../../../store/store";
// import { CartIcon, DocumentIcon, GlobeIcon, WalletIcon } from "../../icons/3dChartIcons";
// import SimpleCard from "../realTimeVis/floating/SimpleCard";
// const ICON_MAP: Record<string, React.ComponentType<React.SVGProps<SVGSVGElement>>> = {
// WalletIcon,
// GlobeIcon,
// DocumentIcon,
// CartIcon
// };
// const DroppedObjects: React.FC = () => {
// const objects = useDroppedObjectsStore((state) => state.objects); // Get objects from Zustand store
//
// return (
// <>
// {objects.map((obj, index) => {
// const IconComponent = obj.Icon || WalletIcon; // Use obj.Icon directly if it exists
// return (
// <SimpleCard
// key={index}
// position={obj.position}
// header={obj.header}
// icon={IconComponent} // ✅ No need to look it up in ICON_MAP
// value={obj.value}
// per={obj.per}
// />
// );
// })}
// </>
// );
// };
// export default DroppedObjects;