added api fallback for sockets

This commit is contained in:
2025-09-01 17:36:40 +05:30
parent 765f4acb57
commit 8e7c5a1aa0
43 changed files with 2034 additions and 1863 deletions

View File

@@ -39,7 +39,7 @@ const DashboardHome: React.FC = () => {
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
setRecentProjects(projects);
}
} catch (error) {}
} catch (error) { }
};
const handleRecentProjectSearch = async (inputValue: string) => {
@@ -66,7 +66,7 @@ const DashboardHome: React.FC = () => {
// );
//
//socket for delete Project
// SOCKET for delete Project
const deleteProject = {
projectId,
organization,
@@ -90,7 +90,7 @@ const DashboardHome: React.FC = () => {
};
});
setIsSearchActive(false);
} catch (error) {}
} catch (error) { }
};
const handleDuplicateRecentProject = async (
@@ -98,15 +98,18 @@ const DashboardHome: React.FC = () => {
projectName: string,
thumbnail: string
) => {
const duplicateRecentProjectData = {
userId,
thumbnail,
organization,
projectUuid: generateUniqueId(),
refProjectID: projectId,
projectName,
};
projectSocket.emit("v1:project:Duplicate", duplicateRecentProjectData);
if (projectSocket) {
const duplicateRecentProjectData = {
userId,
thumbnail,
organization,
projectUuid: generateUniqueId(),
refProjectID: projectId,
projectName,
};
projectSocket.emit("v1:project:Duplicate", duplicateRecentProjectData);
}
};
const renderProjects = () => {

View File

@@ -60,7 +60,7 @@ const DashboardProjects: React.FC = () => {
if (JSON.stringify(projects) !== JSON.stringify(workspaceProjects)) {
setWorkspaceProjects(projects);
}
} catch (error) {}
} catch (error) { }
};
const handleDeleteProject = async (projectId: any) => {
@@ -77,7 +77,7 @@ const DashboardProjects: React.FC = () => {
userId,
};
//socket for deleting the project
// SOCKET for deleting the project
if (projectSocket) {
projectSocket.emit("v1:project:delete", deleteProjects);
} else {
@@ -95,7 +95,7 @@ const DashboardProjects: React.FC = () => {
};
});
setIsSearchActive(false);
} catch (error) {}
} catch (error) { }
};
const handleDuplicateWorkspaceProject = async (
@@ -110,16 +110,17 @@ const DashboardProjects: React.FC = () => {
// projectName
// );
// console.log("duplicatedProject: ", duplicatedProject);
const duplicateProjectData = {
userId,
thumbnail,
organization,
projectUuid: generateUniqueId(),
refProjectID: projectId,
projectName,
};
projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
if (projectSocket) {
const duplicateProjectData = {
userId,
thumbnail,
organization,
projectUuid: generateUniqueId(),
refProjectID: projectId,
projectName,
};
projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
}
};
const renderProjects = () => {
@@ -166,7 +167,7 @@ const DashboardProjects: React.FC = () => {
try {
const sharedWithMe = await sharedWithMeProjects();
setSharedWithMeProjects(sharedWithMe);
} catch {}
} catch { }
};
useEffect(() => {

View File

@@ -38,12 +38,13 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
const handleCreateNewProject = async () => {
const token = localStorage.getItem("token");
const refreshToken = localStorage.getItem("refreshToken");
console.log("refreshToken: ", refreshToken);
if (!token || !refreshToken) {
console.error('token expired');
return;
}
try {
const projectId = generateProjectId();
useSocketStore
.getState()
.initializeSocket(email, organization, token, refreshToken);
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken);
//API for creating new Project
// const project = await createProject(
@@ -60,7 +61,6 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
projectUuid: projectId,
};
console.log("projectSocket: ", projectSocket);
if (projectSocket) {
const handleResponse = (data: any) => {
if (data.message === "Project created successfully") {
@@ -90,7 +90,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
<div className="user-name">
{userName
? userName.charAt(0).toUpperCase() +
userName.slice(1).toLowerCase()
userName.slice(1).toLowerCase()
: "Anonymous"}
</div>
</div>

View File

@@ -75,7 +75,7 @@ const Assets: React.FC = () => {
return (
<div className="assets-container-main">
<Search onChange={setSearchValue} value={searchValue} />
<Search debounced onChange={setSearchValue} value={searchValue} />
<div className="assets-list-section">
<section>
{isLoading ? (

View File

@@ -282,11 +282,11 @@ const AisleProperties: React.FC = () => {
<button
key={val.id}
title={val.brief || val.id}
className={`aisle-list ${aisleColor === val.color ? "selected" : ""}`}
className={`aisle-list ${aisleColor === val.id ? "selected" : ""}`}
onClick={() => setAisleColor(val.id)}
aria-pressed={aisleColor === val.id}
>
<div
<div
className={`texture-display ${val.id}`}
style={{ background: val.id }}
>

View File

@@ -20,6 +20,8 @@ import { useSocketStore } from "../../../../store/builder/store";
import { getUserData } from "../../../../functions/getUserData";
import { aisleTextureList } from "./AisleProperties";
import { upsertAisleApi } from "../../../../services/factoryBuilder/aisle/upsertAisleApi";
const SelectedAisleProperties: React.FC = () => {
const [collapsePresets, setCollapsePresets] = useState(false);
const [collapseTexture, setCollapseTexture] = useState(true);
@@ -44,23 +46,28 @@ const SelectedAisleProperties: React.FC = () => {
const updateBackend = (updatedAisle: Aisle) => {
if (updatedAisle && projectId) {
// API
if (!socket?.active) {
// upsertAisleApi(updatedAisle.aisleUuid, updatedAisle.points, updatedAisle.type, projectId, selectedVersion?.versionId || '');
// API
// SOCKET
upsertAisleApi(updatedAisle.aisleUuid, updatedAisle.points, updatedAisle.type, projectId, selectedVersion?.versionId || '');
const data = {
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization,
aisleUuid: updatedAisle.aisleUuid,
points: updatedAisle.points,
type: updatedAisle.type
} else {
// SOCKET
const data = {
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization,
aisleUuid: updatedAisle.aisleUuid,
points: updatedAisle.points,
type: updatedAisle.type
}
socket.emit('v1:model-aisle:add', data);
}
socket.emit('v1:model-aisle:add', data);
}
}

View File

@@ -7,8 +7,8 @@ import { useSocketStore } from "../../../../store/builder/store";
import InputRange from "../../../ui/inputs/InputRange";
import { getUserData } from "../../../../functions/getUserData";
// import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi";
// import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";
import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi";
import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";
const SelectedDecalProperties = () => {
const { selectedDecal, setSelectedDecal } = useBuilderStore();
@@ -24,39 +24,45 @@ const SelectedDecalProperties = () => {
const updateBackend = (updatedData: Wall | Floor) => {
if ('wallUuid' in updatedData) {
if (projectId && updatedData) {
// API
if (!socket?.active) {
// API
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedData);
upsertWallApi(projectId, selectedVersion?.versionId || '', updatedData);
} else {
// SOCKET
// SOCKET
const data = {
wallData: updatedData,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
const data = {
wallData: updatedData,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Wall:add', data);
}
socket.emit('v1:model-Wall:add', data);
}
} else if ('floorUuid' in updatedData) {
if (projectId && updatedData) {
// API
if (!socket?.active) {
// API
// upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedData);
upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedData);
} else {
// SOCKET
// SOCKET
const data = {
floorData: updatedData,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
const data = {
floorData: updatedData,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Floor:add', data);
}
socket.emit('v1:model-Floor:add', data);
}
}
}

View File

@@ -10,7 +10,7 @@ import { getUserData } from "../../../../functions/getUserData";
import { useSocketStore } from "../../../../store/builder/store";
import { materials } from "./FloorProperties";
// import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";
import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";
const SelectedFloorProperties = () => {
const [depth, setDepth] = useState("");
@@ -43,22 +43,25 @@ const SelectedFloorProperties = () => {
if (!isNaN(parsed) && floor) {
const updatedFloor = updateFloor(floor.floorUuid, { floorDepth: parsed });
if (projectId) {
if (!socket?.active) {
// API
// API
// upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
} else {
// SOCKET
// SOCKET
const data = {
floorData: updatedFloor,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
const data = {
floorData: updatedFloor,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Floor:add', data);
}
socket.emit('v1:model-Floor:add', data);
}
}
};
@@ -69,10 +72,40 @@ const SelectedFloorProperties = () => {
if (!isNaN(parsed) && floor) {
const updatedFloor = updateFloor(floor.floorUuid, { bevelStrength: parsed });
if (projectId) {
if (!socket?.active) {
// API
upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
} else {
// SOCKET
const data = {
floorData: updatedFloor,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Floor:add', data);
}
}
}
};
const handleIsBeveledToggle = () => {
setIsBeveled(!isBeveled);
if (!floor) return;
const updatedFloor = updateFloor(floor.floorUuid, { isBeveled: !floor.isBeveled });
if (projectId) {
if (!socket?.active) {
// API
// upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
} else {
// SOCKET
@@ -87,30 +120,6 @@ const SelectedFloorProperties = () => {
socket.emit('v1:model-Floor:add', data);
}
}
};
const handleIsBeveledToggle = () => {
setIsBeveled(!isBeveled);
if (!floor) return;
const updatedFloor = updateFloor(floor.floorUuid, { isBeveled: !floor.isBeveled });
if (projectId) {
// API
// upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
// SOCKET
const data = {
floorData: updatedFloor,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Floor:add', data);
}
};
@@ -119,22 +128,25 @@ const SelectedFloorProperties = () => {
const key = activeSurface === "top" ? "topMaterial" : "sideMaterial";
const updatedFloor = updateFloor(floor.floorUuid, { [key]: material.textureId });
if (projectId) {
if (!socket?.active) {
// API
// API
// upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
upsertFloorApi(projectId, selectedVersion?.versionId || '', floor);
} else {
// SOCKET
// SOCKET
const data = {
floorData: updatedFloor,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
const data = {
floorData: updatedFloor,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Floor:add', data);
}
socket.emit('v1:model-Floor:add', data);
}
};

View File

@@ -11,7 +11,7 @@ import { useParams } from "react-router-dom";
import { getUserData } from "../../../../functions/getUserData";
import { useSocketStore } from "../../../../store/builder/store";
// import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi";
import { upsertWallApi } from "../../../../services/factoryBuilder/wall/upsertWallApi";
const SelectedWallProperties = () => {
const [height, setHeight] = useState("");
@@ -47,22 +47,25 @@ const SelectedWallProperties = () => {
if (!isNaN(height) && wall) {
const updatedWall = updateWall(wall.wallUuid, { wallHeight: height });
if (updatedWall && projectId) {
if (!socket?.active) {
// API
// API
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
} else {
// SOCKET
// SOCKET
const data = {
wallData: updatedWall,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
const data = {
wallData: updatedWall,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Wall:add', data);
}
socket.emit('v1:model-Wall:add', data);
}
}
};
@@ -73,10 +76,41 @@ const SelectedWallProperties = () => {
if (!isNaN(thickness) && wall) {
const updatedWall = updateWall(wall.wallUuid, { wallThickness: thickness });
if (updatedWall && projectId) {
if (!socket?.active) {
// API
upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
} else {
// SOCKET
const data = {
wallData: updatedWall,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Wall:add', data);
}
}
}
};
const handleSelectMaterial = (material: { textureId: string; textureName: string }) => {
if (!wall) return;
const updated = (activeSide === "side1" ? { insideMaterial: material.textureId } : { outsideMaterial: material.textureId })
const updatedWall = updateWall(wall.wallUuid, updated);
if (updatedWall && projectId) {
if (!socket?.active) {
// API
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
} else {
// SOCKET
@@ -93,31 +127,6 @@ const SelectedWallProperties = () => {
}
};
const handleSelectMaterial = (material: { textureId: string; textureName: string }) => {
if (!wall) return;
const updated = (activeSide === "side1" ? { insideMaterial: material.textureId } : { outsideMaterial: material.textureId })
const updatedWall = updateWall(wall.wallUuid, updated);
if (updatedWall && projectId) {
// API
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
// SOCKET
const data = {
wallData: updatedWall,
projectId: projectId,
versionId: selectedVersion?.versionId || '',
userId: userId,
organization: organization
}
socket.emit('v1:model-Wall:add', data);
}
};
if (!wall) return null;
const selectedMaterials = {

View File

@@ -65,32 +65,34 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
if (isEditableThread && editedThread) {
try {
// const editThreadTitle = await editThreadTitleApi(projectId, (val as CommentSchema).threadId, value, selectedVersion?.versionId || "")
// if (editThreadTitle.message == "ThreadTitle updated Successfully") {
// const editedThread: CommentSchema = {
// state: 'active',
// threadId: editThreadTitle.data.replyId,
// creatorId: userId,
// createdAt: getRelativeTime(editThreadTitle.data.createdAt),
// threadTitle: value,
// lastUpdatedAt: new Date().toISOString(),
// position: editThreadTitle.data.position,
// rotation: [0, 0, 0],
// comments: [],
// }
// updateComment((val as CommentSchema).threadId, editedThread)
// }
// projectId, userId, threadTitle, organization, threadId
const threadEdit = {
projectId,
userId,
threadTitle: value,
organization,
threadId: (val as CommentSchema).threadId || selectedComment.threadId,
versionId: selectedVersion?.versionId || ""
}
if (!threadSocket?.active) {
const editThreadTitle = await editThreadTitleApi(projectId, (val as CommentSchema).threadId, value, selectedVersion?.versionId || "")
if (editThreadTitle.message == "ThreadTitle updated Successfully") {
const editedThread: CommentSchema = {
state: 'active',
threadId: editThreadTitle.data.replyId,
creatorId: userId,
createdAt: getRelativeTime(editThreadTitle.data.createdAt),
threadTitle: value,
lastUpdatedAt: new Date().toISOString(),
position: editThreadTitle.data.position,
rotation: [0, 0, 0],
comments: [],
}
updateComment((val as CommentSchema).threadId, editedThread)
}
} else {
const threadEdit = {
projectId,
userId,
threadTitle: value,
organization,
threadId: (val as CommentSchema).threadId || selectedComment.threadId,
versionId: selectedVersion?.versionId || ""
}
threadSocket.emit('v1:thread:updateTitle', threadEdit)
threadSocket.emit('v1:thread:updateTitle', threadEdit)
}
} catch {
}
} else {
@@ -277,7 +279,7 @@ const Messages: React.FC<MessageProps> = ({ val, i, setMessages, mode, setIsEdit
<div className="message">
{"comment" in val ? val.comment : val.threadTitle}
</div>
</div>
</div >
)}

View File

@@ -5,12 +5,14 @@ interface SearchProps {
value?: string | null; // The current value of the search input
placeholder?: string; // Placeholder text for the input
onChange: (value: string) => void; // Callback function to handle input changes
debounced?: boolean; // New prop: whether to debounce onChange
}
const Search: React.FC<SearchProps> = ({
value = "",
placeholder = "Search",
onChange,
debounced = false, // Default false
}) => {
// State to track the input value and focus status
const [inputValue, setInputValue] = useState(value);
@@ -19,7 +21,10 @@ const Search: React.FC<SearchProps> = ({
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
const newValue = event.target.value;
setInputValue(newValue);
onChange(newValue); // Call the onChange prop with the new value
if (!debounced) {
onChange(newValue); // Immediate call if not debounced
}
};
useEffect(() => {
@@ -29,26 +34,36 @@ const Search: React.FC<SearchProps> = ({
}
}, [value]);
// Handle debounced effect
useEffect(() => {
if (!debounced) return;
const timer = setTimeout(() => {
onChange(inputValue ?? "");
}, 500);
return () => clearTimeout(timer);
}, [inputValue, debounced, onChange]);
const handleClear = () => {
echo.warn("Search field cleared.");
console.warn("Search field cleared.");
setInputValue("");
onChange(""); // Clear the input value
onChange(""); // Clear immediately
};
const handleFocus = () => {
setIsFocused(true); // Set focus state to true
setIsFocused(true);
};
const handleBlur = () => {
setIsFocused(false); // Set focus state to false
setIsFocused(false);
};
return (
<div className="search-wrapper">
<div
className={`search-container ${
isFocused || inputValue ? "active" : ""
}`}
className={`search-container ${isFocused || inputValue ? "active" : ""
}`}
>
<div className="icon-container">
<SearchIcon />
@@ -76,4 +91,4 @@ const Search: React.FC<SearchProps> = ({
);
};
export default Search;
export default Search;