diff --git a/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx b/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
index c36b656..ab1430c 100644
--- a/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/ZoneProperties.tsx
@@ -62,19 +62,25 @@ const ZoneProperties: React.FC = () => {
: zone
)
);
- }else{
+ } else {
// console.log(response?.message);
}
}
function handleVectorChange(key: "zoneViewPortTarget" | "zoneViewPortPosition", newValue: [number, number, number]) {
setSelectedZone((prev) => ({ ...prev, [key]: newValue }));
}
-
+ const checkZoneNameDuplicate = (name: string) => {
+ return zones.some(
+ (zone: any) =>
+ zone.zoneName.trim().toLowerCase() === name.trim().toLowerCase() &&
+ zone.zoneId !== selectedZone.zoneId
+ );
+ };
return (
-
+
{Edit ? "Cancel" : "Edit"}
diff --git a/app/src/components/ui/inputs/RenameInput.tsx b/app/src/components/ui/inputs/RenameInput.tsx
index d197dd4..593e1f1 100644
--- a/app/src/components/ui/inputs/RenameInput.tsx
+++ b/app/src/components/ui/inputs/RenameInput.tsx
@@ -1,26 +1,42 @@
import React, { useState, useRef, useEffect } from "react";
+// interface RenameInputProps {
+// value: string;
+// onRename?: (newText: string) => void;
+// }
+
interface RenameInputProps {
value: string;
onRename?: (newText: string) => void;
+ checkDuplicate?: (name: string) => boolean;
}
-const RenameInput: React.FC
= ({ value, onRename }) => {
+const RenameInput: React.FC = ({ value, onRename, checkDuplicate }) => {
const [isEditing, setIsEditing] = useState(false);
const [text, setText] = useState(value);
+ const [isDuplicate, setIsDuplicate] = useState(false);
const inputRef = useRef(null);
+
useEffect(() => {
- setText(value); // Ensure state updates when parent value changes
+ setText(value);
}, [value]);
+ useEffect(() => {
+ if (checkDuplicate) {
+ setIsDuplicate(checkDuplicate(text));
+ }
+ }, [text, checkDuplicate]);
+
const handleDoubleClick = () => {
setIsEditing(true);
- setTimeout(() => inputRef.current?.focus(), 0); // Focus the input after rendering
+ setTimeout(() => inputRef.current?.focus(), 0);
};
const handleBlur = () => {
+
+ if(isDuplicate) return
setIsEditing(false);
- if (onRename) {
+ if (onRename && !isDuplicate) {
onRename(text);
}
};
@@ -30,7 +46,7 @@ const RenameInput: React.FC = ({ value, onRename }) => {
};
const handleKeyDown = (e: React.KeyboardEvent) => {
- if (e.key === "Enter") {
+ if (e.key === "Enter" && !isDuplicate) {
setIsEditing(false);
if (onRename) {
onRename(text);
@@ -41,15 +57,18 @@ const RenameInput: React.FC = ({ value, onRename }) => {
return (
<>
{isEditing ? (
-
+ <>
+
+ {/* {isDuplicate && Name already exists!
} */}
+ >
) : (
{text}
@@ -58,5 +77,4 @@ const RenameInput: React.FC = ({ value, onRename }) => {
>
);
};
-
-export default RenameInput;
+export default RenameInput
diff --git a/app/src/components/ui/list/List.tsx b/app/src/components/ui/list/List.tsx
index 06bc129..49e86f4 100644
--- a/app/src/components/ui/list/List.tsx
+++ b/app/src/components/ui/list/List.tsx
@@ -13,7 +13,7 @@ import {
RmoveIcon,
} from "../../icons/ExportCommonIcons";
import { useThree } from "@react-three/fiber";
-import { useFloorItems, useZoneAssetId } from "../../../store/store";
+import { useFloorItems, useZoneAssetId, useZones } from "../../../store/store";
import { zoneCameraUpdate } from "../../../services/realTimeVisulization/zoneData/zoneCameraUpdation";
import { setFloorItemApi } from "../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
@@ -40,7 +40,7 @@ const List: React.FC = ({ items = [], remove }) => {
const { activeModule, setActiveModule } = useModuleStore();
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const { zoneAssetId, setZoneAssetId } = useZoneAssetId();
-
+ const { zones, setZones } = useZones();
const { setSubModule } = useSubModuleStore();
const [expandedZones, setExpandedZones] = useState>(
{}
@@ -100,19 +100,33 @@ const List: React.FC = ({ items = [], remove }) => {
function handleAssetClick(asset: Asset) {
setZoneAssetId(asset)
}
+
async function handleZoneNameChange(newName: string) {
- //zone apiiiiii
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
- let zonesdata = {
+
+ const isDuplicate = zones.some(
+ (zone: any) =>
+ zone.zoneName.trim().toLowerCase() === newName.trim().toLowerCase() &&
+ zone.zoneId !== selectedZone.zoneId
+ );
+
+ if (isDuplicate) {
+ alert("Zone name already exists. Please choose a different name.");
+ return; // DO NOT update state
+ }
+
+ const zonesdata = {
zoneId: selectedZone.zoneId,
- zoneName: newName
+ zoneName: newName,
};
- let response = await zoneCameraUpdate(zonesdata, organization);
+
+ const response = await zoneCameraUpdate(zonesdata, organization);
if (response.message === "updated successfully") {
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
}
}
+
async function handleZoneAssetName(newName: string) {
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0];
@@ -128,10 +142,17 @@ const List: React.FC = ({ items = [], remove }) => {
)
);
}
-
+
console.log('newName: ', newName);
}
+ const checkZoneNameDuplicate = (name: string) => {
+ return zones.some(
+ (zone: any) =>
+ zone.zoneName.trim().toLowerCase() === name.trim().toLowerCase() &&
+ zone.zoneId !== selectedZone.zoneId
+ );
+ };
return (
<>
@@ -146,7 +167,12 @@ const List: React.FC = ({ items = [], remove }) => {
className="value"
onClick={() => handleSelectZone(item.id)}
>
-
+
+
diff --git a/app/src/modules/builder/agv/navMeshCreator.tsx b/app/src/modules/builder/agv/navMeshCreator.tsx
index cdbca45..c0f8808 100644
--- a/app/src/modules/builder/agv/navMeshCreator.tsx
+++ b/app/src/modules/builder/agv/navMeshCreator.tsx
@@ -19,7 +19,7 @@ function NavMeshCreator({ lines }: NavMeshCreatorProps) {
-
+
diff --git a/app/src/modules/visualization/DisplayZone.tsx b/app/src/modules/visualization/DisplayZone.tsx
index dfe68f6..e2f3b2f 100644
--- a/app/src/modules/visualization/DisplayZone.tsx
+++ b/app/src/modules/visualization/DisplayZone.tsx
@@ -104,8 +104,8 @@ const DisplayZone: React.FC = ({
setShowLeftArrow(isOverflowing && canScrollLeft);
setShowRightArrow(isOverflowing && canScrollRight);
- console.log('canScrollRight: ', canScrollRight);
- console.log('isOverflowing: ', isOverflowing);
+ // console.log('canScrollRight: ', canScrollRight);
+ // console.log('isOverflowing: ', isOverflowing);
}
}, []);
diff --git a/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx b/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx
index 243d2ef..cfe29aa 100644
--- a/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx
+++ b/app/src/modules/visualization/widgets/floating/DroppedFloatingWidgets.tsx
@@ -520,37 +520,37 @@ const DroppedObjects: React.FC = () => {
onPointerUp={handlePointerUp}
className="floating-wrapper"
>
- {zone.objects.map((obj, index) => {
+ {zone?.objects?.map((obj, index) => {
const topPosition =
- typeof obj.position.top === "number"
- ? `calc(${obj.position.top}px + ${
- isPlaying && selectedZone.activeSides.includes("top")
+ typeof obj?.position?.top === "number"
+ ? `calc(${obj?.position?.top}px + ${
+ isPlaying && selectedZone?.activeSides?.includes("top")
? `${heightMultiplier - 55}px`
: "0px"
})`
: "auto";
const leftPosition =
- typeof obj.position.left === "number"
- ? `calc(${obj.position.left}px + ${
- isPlaying && selectedZone.activeSides.includes("left")
+ typeof obj?.position?.left === "number"
+ ? `calc(${obj?.position?.left}px + ${
+ isPlaying && selectedZone?.activeSides?.includes("left")
? `${widthMultiplier - 150}px`
: "0px"
})`
: "auto";
const rightPosition =
- typeof obj.position.right === "number"
- ? `calc(${obj.position.right}px + ${
- isPlaying && selectedZone.activeSides.includes("right")
+ typeof obj?.position?.right === "number"
+ ? `calc(${obj?.position?.right}px + ${
+ isPlaying && selectedZone?.activeSides?.includes("right")
? `${widthMultiplier - 150}px`
: "0px"
})`
: "auto";
const bottomPosition =
- typeof obj.position.bottom === "number"
- ? `calc(${obj.position.bottom}px + ${
- isPlaying && selectedZone.activeSides.includes("bottom")
+ typeof obj?.position?.bottom === "number"
+ ? `calc(${obj?.position?.bottom}px + ${
+ isPlaying && selectedZone?.activeSides?.includes("bottom")
? `${heightMultiplier - 55}px`
: "0px"
})`
diff --git a/app/src/styles/components/input.scss b/app/src/styles/components/input.scss
index 0c89cc5..883f6c2 100644
--- a/app/src/styles/components/input.scss
+++ b/app/src/styles/components/input.scss
@@ -56,6 +56,12 @@ input {
padding: 0 8px;
}
+.input-error {
+ border: 1px solid #f65648 !important;
+ outline: none !important;
+ color: #f65648;
+}
+
.toggle-header-container {
@include flex-center;
padding: 6px 12px;
@@ -344,7 +350,6 @@ input {
padding: 10px;
}
-
.loading {
position: absolute;
bottom: 0;
@@ -364,9 +369,7 @@ input {
left: -50%;
height: 100%;
width: 50%;
- background: linear-gradient(to right,
- var(--accent-color),
- transparent);
+ background: linear-gradient(to right, var(--accent-color), transparent);
animation: loadingAnimation 1.2s linear infinite;
border-radius: 4px;
}
@@ -381,8 +384,6 @@ input {
}
}
-
-
.dropdown-item {
display: block;
padding: 5px 10px;
@@ -710,4 +711,4 @@ input {
.multi-email-invite-input.active {
border: 1px solid var(--accent-color);
}
-}
\ No newline at end of file
+}