updated folder structure

This commit is contained in:
Nalvazhuthi
2025-04-11 18:08:47 +05:30
50 changed files with 4346 additions and 4216 deletions

View File

@@ -0,0 +1,33 @@
import html2canvas from "html2canvas";
export const captureVisualization = async (): Promise<string | null> => {
const container = document.getElementById("real-time-vis-canvas");
if (!container) {
console.error("Container element not found");
return null;
}
try {
// Hide any elements you don't want in the screenshot
const originalVisibility = container.style.visibility;
container.style.visibility = 'visible';
const canvas = await html2canvas(container, {
scale: 2, // Higher scale for better quality
logging: false, // Disable console logging
useCORS: true, // Handle cross-origin images
allowTaint: true, // Allow tainted canvas
backgroundColor: '#ffffff', // Set white background
removeContainer: true // Clean up temporary containers
});
// Restore original visibility
container.style.visibility = originalVisibility;
// Convert to PNG with highest quality
return canvas.toDataURL('image/png', 1.0);
} catch (error) {
console.error("Error capturing visualization:", error);
return null;
}
};

View File

@@ -0,0 +1,77 @@
export function determinePosition(
canvasRect: DOMRect,
relativeX: number,
relativeY: number
): {
top: number | "auto";
left: number | "auto";
right: number | "auto";
bottom: number | "auto";
} {
const centerX = canvasRect.width / 2;
const centerY = canvasRect.height / 2;
// Define a threshold for considering a point as "centered"
const centerThreshold = 10; // Adjust this value as needed
// Check if the point is within the center threshold
const isCenterX = Math.abs(relativeX - centerX) <= centerThreshold;
const isCenterY = Math.abs(relativeY - centerY) <= centerThreshold;
// If the point is centered, return a special "centered" position
if (isCenterX && isCenterY) {
return {
top: "auto",
left: "auto",
right: "auto",
bottom: "auto",
};
}
let position: {
top: number | "auto";
left: number | "auto";
right: number | "auto";
bottom: number | "auto";
};
if (relativeY < centerY) {
if (relativeX < centerX) {
// Top-left quadrant
position = {
top: relativeY - 41.5,
left: relativeX - 125,
right: "auto",
bottom: "auto",
};
} else {
// Top-right quadrant
position = {
top: relativeY - 41.5,
right: canvasRect.width - relativeX - 125,
left: "auto",
bottom: "auto",
};
}
} else {
if (relativeX < centerX) {
// Bottom-left quadrant
position = {
bottom: canvasRect.height - relativeY - 41.5,
left: relativeX - 125,
right: "auto",
top: "auto",
};
} else {
// Bottom-right quadrant
position = {
bottom: canvasRect.height - relativeY - 41.5,
right: canvasRect.width - relativeX - 125,
left: "auto",
top: "auto",
};
}
}
return position;
}

View File

@@ -0,0 +1,11 @@
export function getActiveProperties(position: any): [string, string] {
if (position.top !== "auto" && position.left !== "auto") {
return ["top", "left"]; // Top-left
} else if (position.top !== "auto" && position.right !== "auto") {
return ["top", "right"]; // Top-right
} else if (position.bottom !== "auto" && position.left !== "auto") {
return ["bottom", "left"]; // Bottom-left
} else {
return ["bottom", "right"]; // Bottom-right
}
}

View File

@@ -0,0 +1,97 @@
import { Template } from "../../../store/useTemplateStore";
import { captureVisualization } from "./captureVisualization";
type HandleSaveTemplateProps = {
addTemplate: (template: Template) => void;
floatingWidget: []; // Updated type from `[]` to `any[]` for clarity
widgets3D: []; // Updated type from `[]` to `any[]` for clarity
selectedZone: {
panelOrder: string[];
widgets: any[];
};
templates?: Template[];
visualizationSocket: any;
};
// Generate a unique ID
const generateUniqueId = (): string => {
return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
};
export const handleSaveTemplate = async ({
addTemplate,
floatingWidget,
widgets3D,
selectedZone,
templates = [],
visualizationSocket,
}: HandleSaveTemplateProps): Promise<void> => {
try {
// Check if the selected zone has any widgets
if (!selectedZone.panelOrder || selectedZone.panelOrder.length === 0) {
return;
}
// Check if the template already exists
const isDuplicate = templates.some(
(template) =>
JSON.stringify(template.panelOrder) ===
JSON.stringify(selectedZone.panelOrder) &&
JSON.stringify(template.widgets) ===
JSON.stringify(selectedZone.widgets)
);
if (isDuplicate) {
return;
}
// Capture visualization snapshot
const snapshot = await captureVisualization();
if (!snapshot) {
return;
}
// Create a new template
const newTemplate: Template = {
id: generateUniqueId(),
name: `Template ${new Date().toISOString()}`, // Better name formatting
panelOrder: selectedZone.panelOrder,
widgets: selectedZone.widgets,
snapshot,
floatingWidget,
widgets3D,
};
// Extract organization from email
const email = localStorage.getItem("email") || "";
const organization = email.includes("@")
? email.split("@")[1]?.split(".")[0]
: "";
if (!organization) {
return;
}
let saveTemplate = {
organization: organization,
template: newTemplate,
};
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-template:add", saveTemplate);
}
// Save the template
try {
addTemplate(newTemplate);
// const response = await saveTemplateApi(organization, newTemplate);
//
// Add template only if API call succeeds
} catch (apiError) {
//
}
} catch (error) {
//
}
};

View File

@@ -0,0 +1,20 @@
import { useEffect } from "react";
export const useClickOutside = (
ref: React.RefObject<HTMLElement>,
callback: () => void
) => {
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (ref.current && !event.composedPath().includes(ref.current)) {
callback();
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref, callback]);
};