256 lines
9.5 KiB
TypeScript
256 lines
9.5 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
|
import InputToggle from "../../../ui/inputs/InputToggle";
|
|
|
|
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
|
|
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
|
import { useVersionContext } from "../../../../modules/builder/version/versionContext";
|
|
import { useParams } from "react-router-dom";
|
|
import { getUserData } from "../../../../functions/getUserData";
|
|
import { useSocketStore } from "../../../../store/builder/store";
|
|
import { materials } from "./FloorProperties";
|
|
|
|
import { upsertFloorApi } from "../../../../services/factoryBuilder/floor/upsertFloorApi";
|
|
|
|
const SelectedFloorProperties = () => {
|
|
const [depth, setDepth] = useState("");
|
|
const [isBeveled, setIsBeveled] = useState(false);
|
|
const [bevelStrength, setBevelStrength] = useState("");
|
|
const { selectedFloor } = useBuilderStore();
|
|
const { floorStore } = useSceneContext();
|
|
const { selectedVersionStore } = useVersionContext();
|
|
const { selectedVersion } = selectedVersionStore();
|
|
const { socket } = useSocketStore();
|
|
const { userId, organization } = getUserData();
|
|
const { projectId } = useParams();
|
|
const { getFloorById, updateFloor } = floorStore();
|
|
|
|
const [activeSurface, setActiveSurface] = useState<"top" | "side">("top");
|
|
|
|
const floor = selectedFloor ? getFloorById(selectedFloor.userData.floorUuid) : null;
|
|
|
|
useEffect(() => {
|
|
if (floor) {
|
|
setDepth(floor.floorDepth.toString());
|
|
setIsBeveled(floor.isBeveled);
|
|
setBevelStrength(floor.bevelStrength.toString());
|
|
}
|
|
}, [floor]);
|
|
|
|
const handleDepthChange = (val: string) => {
|
|
setDepth(val);
|
|
const parsed = parseFloat(val);
|
|
if (!isNaN(parsed) && floor) {
|
|
const updatedFloor = updateFloor(floor.floorUuid, { floorDepth: parsed });
|
|
if (projectId) {
|
|
if (!socket?.connected) {
|
|
|
|
// 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 handleBevelChange = (val: string) => {
|
|
setBevelStrength(val);
|
|
const parsed = parseFloat(val);
|
|
if (!isNaN(parsed) && floor) {
|
|
const updatedFloor = updateFloor(floor.floorUuid, { bevelStrength: parsed });
|
|
if (projectId) {
|
|
if (!socket?.connected) {
|
|
|
|
// 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?.connected) {
|
|
|
|
// 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 handleSelectMaterial = (material: { textureId: string; textureName: string }) => {
|
|
if (!floor) return;
|
|
const key = activeSurface === "top" ? "topMaterial" : "sideMaterial";
|
|
const updatedFloor = updateFloor(floor.floorUuid, { [key]: material.textureId });
|
|
if (projectId) {
|
|
if (!socket?.connected) {
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
if (!floor) return null;
|
|
|
|
const selectedMaterials = {
|
|
top: materials.find((m) => m.textureId === floor.topMaterial) ?? materials[0],
|
|
side: materials.find((m) => m.textureId === floor.sideMaterial) ?? materials[0],
|
|
};
|
|
|
|
return (
|
|
<div className="wall-properties-container">
|
|
<section className="wall-properties-section">
|
|
<div className="header">Floor</div>
|
|
<div className="wall-properties">
|
|
<InputWithDropDown
|
|
label="Depth"
|
|
value={depth}
|
|
min={0.1}
|
|
max={10}
|
|
step={0.1}
|
|
onChange={handleDepthChange}
|
|
/>
|
|
<InputToggle
|
|
label="Beveled"
|
|
inputKey="isBeveled"
|
|
value={isBeveled}
|
|
onClick={handleIsBeveledToggle}
|
|
/>
|
|
<InputWithDropDown
|
|
label="Bevel Strength"
|
|
value={bevelStrength}
|
|
min={1}
|
|
max={10}
|
|
step={1}
|
|
onChange={handleBevelChange}
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<div className="header-wrapper">
|
|
<div className="header">Materials</div>
|
|
</div>
|
|
|
|
<div className="material-preview">
|
|
<div className="sides-wrapper">
|
|
{(["top", "side"] as const).map((surface) => (
|
|
<button
|
|
key={surface}
|
|
className={`side-wrapper ${activeSurface === surface ? "active" : ""}`}
|
|
onClick={() => setActiveSurface(surface)}
|
|
>
|
|
<div className="label">{surface === "top" ? "Top" : "Side"}</div>
|
|
<div className="texture-image">
|
|
<img
|
|
draggable={false}
|
|
src={selectedMaterials[surface].texture}
|
|
alt={selectedMaterials[surface].textureName}
|
|
/>
|
|
</div>
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<div className="preview">
|
|
<img
|
|
draggable={false}
|
|
src={selectedMaterials[activeSurface].texture}
|
|
alt={selectedMaterials[activeSurface].textureName}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="materials">
|
|
<div className="material-container">
|
|
{materials.map((material, index) => {
|
|
const isSelected = selectedMaterials[activeSurface].textureId === material.textureId;
|
|
return (
|
|
<button
|
|
className={`material-wrapper ${isSelected ? "selectedMaterial" : ""}`}
|
|
key={`${material.textureName}_${index}`}
|
|
onClick={() => handleSelectMaterial(material)}
|
|
>
|
|
<div className="material-property">
|
|
<div className="material-image">
|
|
<img
|
|
draggable={false}
|
|
src={material.texture}
|
|
alt={material.textureName}
|
|
/>
|
|
</div>
|
|
<div className="material-name">{material.textureName}</div>
|
|
</div>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SelectedFloorProperties;
|