Refactor: Remove deprecated API endpoints and implement new zone management features

- Deleted obsolete API files for wall items, layers, lines, and points.
- Introduced new zone management APIs including create, delete, and update functionalities.
- Enhanced zone state management in the store with new properties for height and color.
- Implemented 2D and 3D zone rendering components for better visualization.
- Added asset fetching functionalities for marketplace integration.
- Updated types to accommodate new zone properties and API responses.
This commit is contained in:
2025-06-27 17:51:57 +05:30
parent 812a4f6aef
commit fa6506c0be
46 changed files with 1301 additions and 1301 deletions

View File

@@ -0,0 +1,50 @@
import { useMemo } from 'react';
import { DoubleSide, Shape, Vector2 } from 'three';
import { Extrude } from '@react-three/drei';
import * as Constants from '../../../../../types/world/worldConstants';
function Zone2DInstance({ zone }: { zone: Zone }) {
const savedTheme: string | null = localStorage.getItem("theme");
const shape = useMemo(() => {
const shape = new Shape();
const points = zone.points.map(p => new Vector2(p.position[0], p.position[2]));
if (points.length < 3) return null;
shape.moveTo(points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
shape.lineTo(points[i].x, points[i].y);
}
return shape;
}, [zone]);
if (!shape) return null;
return (
<mesh
castShadow
receiveShadow
name={`Zone-2D-${zone.zoneUuid}`}
rotation={[Math.PI / 2, 0, 0]}
position={[0, 0, 0]}
userData={zone}
>
<Extrude
name={`Zone-${zone.zoneUuid}`}
args={[shape, {
depth: Constants.floorConfig.height,
}]}
userData={zone}
>
<meshBasicMaterial
color={savedTheme === "dark" ? "green" : "green"}
side={DoubleSide}
transparent
opacity={0.4}
depthWrite={false}
/>
</Extrude>
</mesh>
);
}
export default Zone2DInstance;

View File

@@ -0,0 +1,73 @@
import { useMemo } from 'react'
import { Color, DoubleSide, ShaderMaterial } from 'three';
import { Vector3 } from 'three';
function ZoneInstance({ zone }: { zone: Zone }) {
const zoneLayer = zone.points[0].layer;
const zoneMaterial = useMemo(() => {
return new ShaderMaterial({
side: DoubleSide,
vertexShader: `
varying vec2 vUv;
void main(){
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
vUv = uv;
}
`,
fragmentShader: `
varying vec2 vUv;
uniform vec3 uOuterColor;
void main(){
float alpha = 1.0 - vUv.y;
gl_FragColor = vec4(uOuterColor, alpha);
}
`,
uniforms: {
uOuterColor: { value: new Color(zone.zoneColor) },
},
transparent: true,
depthWrite: false,
})
}, []);
return (
<>
<mesh
name={`Zone-${zone.zoneUuid}`}
userData={zone}
>
{zone.points.slice(0, -1).map((point, index: number) => {
const nextPoint = zone.points[index + 1];
const point1 = new Vector3(point.position[0], point.position[1], point.position[2]);
const point2 = new Vector3(nextPoint.position[0], nextPoint.position[1], nextPoint.position[2]);
const planeWidth = point1.distanceTo(point2);
const planeHeight = zone.zoneHeight;
const midpoint = new Vector3((point1.x + point2.x) / 2, zone.zoneHeight / 2 + (zoneLayer - 1) * zone.zoneHeight, (point1.z + point2.z) / 2);
const angle = Math.atan2(point2.z - point1.z, point2.x - point1.x);
return (
<mesh
key={index}
position={midpoint}
rotation={[0, -angle, 0]}
>
<planeGeometry args={[planeWidth, planeHeight]} />
<primitive
object={zoneMaterial.clone()}
attach="material"
/>
</mesh>
);
})}
</ mesh>
</>
)
}
export default ZoneInstance

View File

@@ -0,0 +1,132 @@
import React, { useEffect, useMemo } from 'react';
import { Vector3 } from 'three';
import { Html } from '@react-three/drei';
import { useSceneContext } from '../../../scene/sceneContext';
import { useToggleView } from '../../../../store/builder/store';
import Line from '../../line/line';
import Point from '../../point/point';
import ZoneInstance from './Instance/zoneInstance';
import Zone2DInstance from './Instance/zone2DInstance';
function ZoneInstances() {
const { zoneStore } = useSceneContext();
const { zones } = zoneStore();
const { toggleView } = useToggleView();
useEffect(() => {
console.log('zones: ', zones);
}, [zones]);
const allPoints = useMemo(() => {
const points: Point[] = [];
const seenUuids = new Set<string>();
zones.forEach(zone => {
zone.points.forEach(point => {
if (!seenUuids.has(point.pointUuid)) {
seenUuids.add(point.pointUuid);
points.push(point);
}
});
});
return points;
}, [zones]);
const allLines = useMemo(() => {
const lines: { start: Point; end: Point; key: string }[] = [];
const seenUuids = new Set<string>();
zones.forEach((zone) => {
const points = zone.points;
if (points.length < 2) return;
for (let i = 0; i < points.length; i++) {
const current = points[i];
const next = points[(i + 1) % points.length];
const lineKey = `${current.pointUuid}-${next.pointUuid}`;
if (current.pointUuid !== next.pointUuid && !seenUuids.has(lineKey)) {
seenUuids.add(lineKey);
lines.push({
start: current,
end: next,
key: lineKey
});
}
}
});
return lines;
}, [zones]);
return (
<>
{!toggleView && zones.length > 0 && (
<mesh name='Zones-Group'>
{zones.map((zone) => (
<ZoneInstance key={zone.zoneUuid} zone={zone} />
))}
</mesh>
)}
{toggleView && zones.length > 0 && (
<mesh name='Zones-2D-Group'>
{zones.map((zone) => (
<Zone2DInstance key={zone.zoneUuid} zone={zone} />
))}
</mesh>
)}
{toggleView && (
<>
<group name='Zone-Points-Group'>
{allPoints.map((point) => (
<Point key={point.pointUuid} point={point} />
))}
</group>
<group name='Zone-Lines-Group'>
{allLines.map(({ start, end, key }) => (
<Line key={key} points={[start, end]} />
))}
{allLines.map((line) => {
const { start, end, key } = line;
const textPosition = new Vector3().addVectors(new Vector3(...start.position), new Vector3(...end.position)).divideScalar(2);
const distance = new Vector3(...start.position).distanceTo(new Vector3(...end.position));
return (
<React.Fragment key={key}>
{toggleView &&
<Html
key={`${start.pointUuid}_${end.pointUuid}`}
userData={line}
position={[textPosition.x, 1, textPosition.z]}
wrapperClass="distance-text-wrapper"
className="distance-text"
zIndexRange={[1, 0]}
prepend
sprite
>
<div
key={key}
className={`distance ${key}`}
>
{distance.toFixed(2)} m
</div>
</Html>
}
</React.Fragment>
)
})}
</group>
</>
)}
</>
)
}
export default ZoneInstances

View File

@@ -0,0 +1,10 @@
import React from 'react'
function ZoneCreator() {
return (
<>
</>
)
}
export default ZoneCreator

View File

@@ -0,0 +1,54 @@
import { useEffect } from 'react';
import { useToggleView } from '../../../store/builder/store';
import { useBuilderStore } from '../../../store/builder/useBuilderStore';
import { useVersionContext } from '../version/versionContext';
import { useSceneContext } from '../../scene/sceneContext';
import { useParams } from 'react-router-dom';
import useModuleStore from '../../../store/useModuleStore';
import ZoneCreator from './zoneCreator/zoneCreator';
import ZoneInstances from './Instances/zoneInstances';
import { getZonesApi } from '../../../services/factoryBuilder/zone/getZonesApi';
function ZoneGroup() {
const { togglView } = useToggleView();
const { setSelectedZone } = useBuilderStore();
const { activeModule } = useModuleStore();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
const { zoneStore } = useSceneContext();
const { setZones } = zoneStore();
const { projectId } = useParams();
useEffect(() => {
if (togglView || activeModule !== 'builder') {
setSelectedZone(null);
}
}, [togglView, activeModule])
useEffect(() => {
if (projectId && selectedVersion) {
getZonesApi(projectId, selectedVersion?.versionId || '').then((zones) => {
if (zones && zones.length > 0) {
setZones(zones);
} else {
setZones([]);
}
}).catch((err) => {
console.log(err);
})
}
}, [projectId, selectedVersion?.versionId])
return (
<>
<ZoneCreator />
<ZoneInstances />
</>
)
}
export default ZoneGroup