From cb414f282409247c8ede9db2ded511dbcbda1e68 Mon Sep 17 00:00:00 2001
From: Jerald-Golden-B <jerald@hexrfactory.com>
Date: Wed, 28 May 2025 10:44:19 +0530
Subject: [PATCH] feat: enhance aisle management with new properties and types

---
 .../layout/sidebarRight/SideBarRight.tsx      |  33 +++--
 .../properties/AisleProperties.tsx            | 140 ++++++++++--------
 .../Instances/instance/aisleInstance.tsx      |   5 +
 .../instance/aisleTypes/dashedAisle.tsx       |   4 +-
 .../instance/aisleTypes/dottedAisle.tsx       |  58 ++++++++
 .../instance/aisleTypes/solidAisle.tsx        |   4 +-
 .../aisle/aisleCreator/aisleCreator.tsx       |  55 ++-----
 .../aisle/aisleCreator/referenceAisle.tsx     |  76 ++++++++--
 app/src/store/builder/useAisleStore.ts        |  16 +-
 app/src/store/builder/useBuilderStore.ts      |  42 ++++++
 app/src/types/builderTypes.d.ts               |  11 +-
 11 files changed, 296 insertions(+), 148 deletions(-)
 create mode 100644 app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx
 create mode 100644 app/src/store/builder/useBuilderStore.ts

diff --git a/app/src/components/layout/sidebarRight/SideBarRight.tsx b/app/src/components/layout/sidebarRight/SideBarRight.tsx
index 10de581..44199bc 100644
--- a/app/src/components/layout/sidebarRight/SideBarRight.tsx
+++ b/app/src/components/layout/sidebarRight/SideBarRight.tsx
@@ -16,6 +16,7 @@ import Simulations from "./simulation/Simulations";
 import useVersionHistoryStore, {
   useSaveVersion,
   useSelectedFloorItem,
+  useToolMode,
 } from "../../../store/builder/store";
 import {
   useSelectedEventData,
@@ -26,10 +27,12 @@ import AsstePropertiies from "./properties/AssetProperties";
 import ZoneProperties from "./properties/ZoneProperties";
 import EventProperties from "./properties/eventProperties/EventProperties";
 import VersionHistory from "./versionHisory/VersionHistory";
+import AisleProperties from "./properties/AisleProperties";
 
 const SideBarRight: React.FC = () => {
   const { activeModule } = useModuleStore();
   const { toggleUIRight } = useToggleStore();
+  const { toolMode } = useToolMode();
   const { subModule, setSubModule } = useSubModuleStore();
   const { selectedFloorItem } = useSelectedFloorItem();
   const { selectedEventData } = useSelectedEventData();
@@ -62,9 +65,8 @@ const SideBarRight: React.FC = () => {
 
   return (
     <div
-      className={`sidebar-right-wrapper ${
-        toggleUIRight && !isVersionSaved ? "open" : "closed"
-      }`}
+      className={`sidebar-right-wrapper ${toggleUIRight && !isVersionSaved ? "open" : "closed"
+        }`}
     >
       <Header />
       {toggleUIRight && (
@@ -74,9 +76,8 @@ const SideBarRight: React.FC = () => {
               {activeModule !== "simulation" && (
                 <button
                   id="sidebar-action-list-properties"
-                  className={`sidebar-action-list ${
-                    subModule === "properties" ? "active" : ""
-                  }`}
+                  className={`sidebar-action-list ${subModule === "properties" ? "active" : ""
+                    }`}
                   onClick={() => {
                     setSubModule("properties");
                     setVersionHistory(false);
@@ -90,9 +91,8 @@ const SideBarRight: React.FC = () => {
                 <>
                   <button
                     id="sidebar-action-list-simulation"
-                    className={`sidebar-action-list ${
-                      subModule === "simulations" ? "active" : ""
-                    }`}
+                    className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""
+                      }`}
                     onClick={() => {
                       setSubModule("simulations");
                       setVersionHistory(false);
@@ -103,9 +103,8 @@ const SideBarRight: React.FC = () => {
                   </button>
                   <button
                     id="sidebar-action-list-mechanics"
-                    className={`sidebar-action-list ${
-                      subModule === "mechanics" ? "active" : ""
-                    }`}
+                    className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""
+                      }`}
                     onClick={() => {
                       setSubModule("mechanics");
                       setVersionHistory(false);
@@ -116,9 +115,8 @@ const SideBarRight: React.FC = () => {
                   </button>
                   <button
                     id="sidebar-action-list-analysis"
-                    className={`sidebar-action-list ${
-                      subModule === "analysis" ? "active" : ""
-                    }`}
+                    className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""
+                      }`}
                     onClick={() => {
                       setSubModule("analysis");
                       setVersionHistory(false);
@@ -147,7 +145,10 @@ const SideBarRight: React.FC = () => {
             !selectedFloorItem && (
               <div className="sidebar-right-container">
                 <div className="sidebar-right-content-container">
-                  <GlobalProperties />
+                  {toolMode === "Aisle" ? (
+                    <AisleProperties />) : (
+                    <GlobalProperties />
+                  )}
                 </div>
               </div>
             )}
diff --git a/app/src/components/layout/sidebarRight/properties/AisleProperties.tsx b/app/src/components/layout/sidebarRight/properties/AisleProperties.tsx
index eaab9f6..db58c7a 100644
--- a/app/src/components/layout/sidebarRight/properties/AisleProperties.tsx
+++ b/app/src/components/layout/sidebarRight/properties/AisleProperties.tsx
@@ -11,9 +11,10 @@ import Dashed from "../../../../assets/image/aisleTypes/Dashed.png";
 import Directional from "../../../../assets/image/aisleTypes/Directional.png";
 import Dotted from "../../../../assets/image/aisleTypes/Dotted.png";
 import Solid from "../../../../assets/image/aisleTypes/Solid.png";
+import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
 
 interface TextureItem {
-  color: string;
+  color: AisleColors;
   id: string;
   brief: string;
   texture: string;
@@ -22,10 +23,7 @@ interface TextureItem {
 const AisleProperties: React.FC = () => {
   const [collapsePresets, setCollapsePresets] = useState(false);
   const [collapseTexture, setCollapseTexture] = useState(true);
-  const [selectedTexture, setSelectedTexture] = useState<string | null>(
-    "yellow1"
-  );
-  const [selectedType, setSelectedType] = useState<string | null>("Solid");
+  const { aisleType, aisleWidth, aisleColor, setAisleType, setAisleColor, setAisleWidth } = useBuilderStore();
 
   const aisleTextureList: TextureItem[] = [
     { color: "gray", id: "gray", brief: "basic", texture: "" },
@@ -60,58 +58,82 @@ const AisleProperties: React.FC = () => {
     },
   ];
 
-  const aisleTypes = [
-    {
-      name: "Solid",
-      id: "1",
-      thumbnail: Solid,
-    },
-    {
-      name: "Dotted",
-      id: "2",
-      thumbnail: Dotted,
-    },
-    {
-      name: "Dashed",
-      id: "3",
-      thumbnail: Dashed,
-    },
-    {
-      name: "Arrow",
-      id: "4",
-      thumbnail: Arrow,
-    },
-    {
-      name: "Contiuous Arrows",
-      id: "5",
-      thumbnail: Arrows,
-    },
-    {
-      name: "Directional",
-      id: "6",
-      thumbnail: Directional,
-    },
-    {
-      name: "Arc",
-      id: "7",
-      thumbnail: Arc,
-    },
-    {
-      name: "Circle",
-      id: "8",
-      thumbnail: Circle,
-    },
-  ];
+  const aisleTypes: {
+    name: string;
+    type: AisleTypes;
+    id: string;
+    thumbnail: string;
+  }[] = [
+      {
+        name: "Solid",
+        type: "solid-aisle",
+        id: "1",
+        thumbnail: Solid,
+      },
+      {
+        name: "Dotted",
+        type: "dotted-aisle",
+        id: "2",
+        thumbnail: Dotted,
+      },
+      {
+        name: "Dashed",
+        type: "dashed-aisle",
+        id: "3",
+        thumbnail: Dashed,
+      },
+      {
+        name: "Arrow",
+        type: "arrow-aisle",
+        id: "4",
+        thumbnail: Arrow,
+      },
+      {
+        name: "Contiuous Arrows",
+        type: "arrows-aisle",
+        id: "5",
+        thumbnail: Arrows,
+      },
+      {
+        name: "Directional",
+        type: "junction-aisle",
+        id: "6",
+        thumbnail: Directional,
+      },
+      {
+        name: "Arc",
+        type: "arc-aisle",
+        id: "7",
+        thumbnail: Arc,
+      },
+      {
+        name: "Circle",
+        type: "circle-aisle",
+        id: "8",
+        thumbnail: Circle,
+      },
+    ];
+
+  const handleAisleWidthChange = (value: string) => {
+    const width = parseFloat(value);
+    if (isNaN(width)) {
+      return;
+    }
+    setAisleWidth(width);
+  }
 
   return (
     <div className="aisle-properties-container">
       <div className="header">Properties</div>
       <section>
         <InputWithDropDown
-          label="Width"
-          value="1"
-          editableLabel
-          onChange={() => {}}
+          label="Aisle Width"
+          value={`${aisleWidth}`}
+          min={0.1}
+          step={0.1}
+          max={2}
+          defaultValue="0.1"
+          onChange={handleAisleWidthChange}
         />
       </section>
 
@@ -132,12 +154,11 @@ const AisleProperties: React.FC = () => {
             {aisleTypes.map((val) => (
               <div className="preset-list" key={val.id}>
                 <button
-                  className={`thumbnail ${
-                    selectedType === val.name ? "selected" : ""
-                  }`}
+                  className={`thumbnail ${aisleType === val.type ? "selected" : ""
+                    }`}
                   title={val.name}
                   onClick={() => {
-                    setSelectedType(val.name);
+                    setAisleType(val.type);
                   }}
                 >
                   <img src={val.thumbnail} alt="" />
@@ -170,11 +191,10 @@ const AisleProperties: React.FC = () => {
               <button
                 key={val.id}
                 title={val.brief || val.id}
-                className={`aisle-list ${
-                  selectedTexture === val.id ? "selected" : ""
-                }`}
-                onClick={() => setSelectedTexture(val.id)}
-                aria-pressed={selectedTexture === val.id}
+                className={`aisle-list ${aisleColor === val.color ? "selected" : ""
+                  }`}
+                onClick={() => setAisleColor(val.color)}
+                aria-pressed={aisleColor === val.id}
               >
                 <div className="texture-display">{val.texture}</div>
                 <div className="aisle-color">{val.color}</div>
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx
index beada6f..8ab9c5f 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleInstance.tsx
@@ -1,4 +1,5 @@
 import DashedAisle from './aisleTypes/dashedAisle';
+import DottedAisle from './aisleTypes/dottedAisle';
 import SolidAisle from './aisleTypes/solidAisle';
 
 function AisleInstance({ aisle }: { readonly aisle: Aisle }) {
@@ -12,6 +13,10 @@ function AisleInstance({ aisle }: { readonly aisle: Aisle }) {
             {aisle.type.aisleType === 'dashed-aisle' && (
                 <DashedAisle aisle={aisle} />
             )}
+
+            {aisle.type.aisleType === 'dotted-aisle' && (
+                <DottedAisle aisle={aisle} />
+            )}
         </>
     );
 }
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
index 5774fcd..7103479 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dashedAisle.tsx
@@ -9,7 +9,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
 
         const start = new THREE.Vector3(...aisle.points[0].position);
         const end = new THREE.Vector3(...aisle.points[1].position);
-        const width = aisle.type.width || 0.1;
+        const width = aisle.type.aisleWidth || 0.1;
         const dashLength = 0.5;
         const gapLength = 0.3;
 
@@ -59,7 +59,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
                     castShadow
                 >
                     <meshStandardMaterial
-                        color={aisle.type.color || '#ffffff'}
+                        color={aisle.type.aisleColor || '#ffffff'}
                         side={THREE.DoubleSide}
                     />
                 </Extrude>
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx
new file mode 100644
index 0000000..09a3c65
--- /dev/null
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/dottedAisle.tsx
@@ -0,0 +1,58 @@
+import * as THREE from 'three';
+import { useMemo } from 'react';
+import { Extrude } from '@react-three/drei';
+import * as Constants from '../../../../../../types/world/worldConstants';
+
+function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
+    const shapes = useMemo(() => {
+        if (aisle.points.length < 2) return [];
+
+        const start = new THREE.Vector3(...aisle.points[0].position);
+        const end = new THREE.Vector3(...aisle.points[1].position);
+        const width = aisle.type.aisleWidth || 0.1;
+        const dotSpacing = 0.5;
+        const dotRadius = width * 0.4;
+
+        const totalLength = new THREE.Vector3().subVectors(end, start).length();
+        const dotCount = Math.floor(totalLength / dotSpacing);
+
+        const shapes = [];
+        const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();
+
+        for (let i = 0; i < dotCount; i++) {
+            const dotCenter = new THREE.Vector3().copy(start).addScaledVector(directionNormalized, i * dotSpacing + dotSpacing / 2);
+
+            const shape = new THREE.Shape();
+            shape.absarc(dotCenter.x, dotCenter.z, dotRadius, 0, Math.PI * 2, false);
+
+            shapes.push(shape);
+        }
+
+        return shapes;
+    }, [aisle]);
+
+    if (shapes.length === 0) return null;
+
+    return (
+        <group
+            position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
+            rotation={[Math.PI / 2, 0, 0]}
+        >
+            {shapes.map((shape, index) => (
+                <Extrude
+                    key={index}
+                    args={[shape, { depth: 0.01, bevelEnabled: false }]}
+                    receiveShadow
+                    castShadow
+                >
+                    <meshStandardMaterial
+                        color={aisle.type.aisleColor || '#ffffff'}
+                        side={THREE.DoubleSide}
+                    />
+                </Extrude>
+            ))}
+        </group>
+    );
+}
+
+export default DottedAisle;
\ No newline at end of file
diff --git a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
index c2bfdab..f4fb3ff 100644
--- a/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
+++ b/app/src/modules/builder/aisle/Instances/instance/aisleTypes/solidAisle.tsx
@@ -9,7 +9,7 @@ function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
 
         const start = new THREE.Vector3(...aisle.points[0].position);
         const end = new THREE.Vector3(...aisle.points[1].position);
-        const width = aisle.type.width || 0.1;
+        const width = aisle.type.aisleWidth || 0.1;
 
         const direction = new THREE.Vector3().subVectors(end, start).normalize();
         const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
@@ -42,7 +42,7 @@ function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
                 castShadow
             >
                 <meshStandardMaterial
-                    color={aisle.type.color || '#ffffff'}
+                    color={aisle.type.aisleColor || '#ffffff'}
                     side={THREE.DoubleSide}
                 />
             </Extrude>
diff --git a/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx b/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx
index 593c437..f21224a 100644
--- a/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx
+++ b/app/src/modules/builder/aisle/aisleCreator/aisleCreator.tsx
@@ -3,8 +3,8 @@ import { useEffect, useMemo, useState } from 'react'
 import { useThree } from '@react-three/fiber';
 import { useActiveLayer, useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
 import { useAisleStore } from '../../../../store/builder/useAisleStore';
-import * as Constants from '../../../../types/world/worldConstants';
 import ReferenceAisle from './referenceAisle';
+import { useBuilderStore } from '../../../../store/builder/useBuilderStore';
 
 function AisleCreator() {
     const { scene, camera, raycaster, gl, pointer } = useThree();
@@ -17,14 +17,14 @@ function AisleCreator() {
 
     const [tempPoints, setTempPoints] = useState<Point[]>([]);
     const [isCreating, setIsCreating] = useState(false);
-    const [aisleType, setAisleType] = useState<'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle' | 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle'>('dashed-aisle');
+    const { aisleType, aisleWidth, aisleColor } = useBuilderStore();
 
-    useEffect(() => {
-        if (tempPoints.length > 0) {
-            setTempPoints([]);
-            setIsCreating(false);
-        }
-    }, [aisleType]);
+    // useEffect(() => {
+    //     if (tempPoints.length > 0) {
+    //         setTempPoints([]);
+    //         setIsCreating(false);
+    //     }
+    // }, [aisleType]);
 
     const allPoints = useMemo(() => {
         const points: Point[] = [];
@@ -102,10 +102,9 @@ function AisleCreator() {
                         points: [tempPoints[0], newPoint],
                         type: {
                             typeName: 'Aisle',
-                            material: 'default',
                             aisleType: aisleType,
-                            color: Constants.aisleConfig.defaultColor,
-                            width: Constants.aisleConfig.width
+                            aisleColor: aisleColor,
+                            aisleWidth: aisleWidth
                         }
                     };
 
@@ -114,33 +113,7 @@ function AisleCreator() {
                     setTempPoints([newPoint]);
                 }
             } else if (['arc-aisle', 'circle-aisle', 'arrow-aisle', 'junction-aisle'].includes(aisleType)) {
-                const newPoint: Point = {
-                    uuid: THREE.MathUtils.generateUUID(),
-                    position: [point.x, point.y, point.z],
-                    layer: activeLayer
-                };
-
-                if (tempPoints.length === 0) {
-                    setTempPoints([newPoint]);
-                    setIsCreating(true);
-                } else {
-                    const aisle: Aisle = {
-                        uuid: THREE.MathUtils.generateUUID(),
-                        points: [tempPoints[0], newPoint],
-                        type: {
-                            typeName: 'Aisle',
-                            material: 'default',
-                            aisleType: aisleType,
-                            color: Constants.aisleConfig.defaultColor,
-                            width: Constants.aisleConfig.width
-                        }
-                    };
-
-                    addAisle(aisle);
-
-                    setTempPoints([]);
-                    setIsCreating(false);
-                }
+                console.log();
             }
         };
 
@@ -170,7 +143,7 @@ function AisleCreator() {
             canvasElement.removeEventListener("click", onMouseClick);
             canvasElement.removeEventListener("contextmenu", onContext);
         };
-    }, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addAisle, aisleType]);
+    }, [gl, camera, scene, raycaster, pointer, plane, toggleView, toolMode, activeLayer, socket, tempPoints, isCreating, addAisle, aisleType, aisleColor, aisleWidth]);
 
     return (
         <>
@@ -187,8 +160,8 @@ function AisleCreator() {
                     </mesh>
                 ))}
             </group>
-            
-            <ReferenceAisle tempPoints={tempPoints} aisleType={aisleType} />
+
+            <ReferenceAisle tempPoints={tempPoints} aisleType={aisleType} aisleWidth={aisleWidth} aisleColor={aisleColor} />
         </>
     );
 }
diff --git a/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx b/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx
index 437337a..74d5e1f 100644
--- a/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx
+++ b/app/src/modules/builder/aisle/aisleCreator/referenceAisle.tsx
@@ -7,10 +7,12 @@ import { Extrude } from '@react-three/drei';
 
 interface ReferenceAisleProps {
     tempPoints: Point[];
-    aisleType: 'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle' | 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle';
+    aisleType: AisleTypes;
+    aisleWidth: number;
+    aisleColor: AisleColors;
 }
 
-function ReferenceAisle({ tempPoints, aisleType }: Readonly<ReferenceAisleProps>) {
+function ReferenceAisle({ tempPoints, aisleType, aisleWidth, aisleColor }: Readonly<ReferenceAisleProps>) {
     const { pointer, raycaster, camera } = useThree();
     const { toolMode } = useToolMode();
     const { toggleView } = useToggleView();
@@ -41,10 +43,9 @@ function ReferenceAisle({ tempPoints, aisleType }: Readonly<ReferenceAisleProps>
                     ],
                     type: {
                         typeName: 'Aisle',
-                        material: 'default',
                         aisleType: aisleType,
-                        color: Constants.aisleConfig.defaultColor,
-                        width: Constants.aisleConfig.width
+                        aisleColor: aisleColor,
+                        aisleWidth: aisleWidth
                     }
                 });
             }
@@ -55,7 +56,7 @@ function ReferenceAisle({ tempPoints, aisleType }: Readonly<ReferenceAisleProps>
 
     useEffect(() => {
         setTempAisle(null);
-    }, [toolMode, toggleView, tempPoints.length, aisleType]);
+    }, [toolMode, toggleView, tempPoints.length, aisleType, aisleWidth, aisleColor]);
 
     if (!tempAisle) return null;
 
@@ -65,6 +66,8 @@ function ReferenceAisle({ tempPoints, aisleType }: Readonly<ReferenceAisleProps>
                 return <SolidAisle aisle={tempAisle} />;
             case 'dashed-aisle':
                 return <DashedAisle aisle={tempAisle} />;
+            case 'dotted-aisle':
+                return <DottedAisle aisle={tempAisle} />;
             default:
                 return null;
         }
@@ -79,14 +82,13 @@ function ReferenceAisle({ tempPoints, aisleType }: Readonly<ReferenceAisleProps>
 
 export default ReferenceAisle;
 
-
 function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
     const shape = useMemo(() => {
         if (aisle.points.length < 2) return null;
 
         const start = new THREE.Vector3(...aisle.points[0].position);
         const end = new THREE.Vector3(...aisle.points[1].position);
-        const width = aisle.type.width || 0.1;
+        const width = aisle.type.aisleWidth || 0.1;
 
         const direction = new THREE.Vector3().subVectors(end, start).normalize();
         const perp = new THREE.Vector3(-direction.z, 0, direction.x).normalize();
@@ -119,7 +121,7 @@ function SolidAisle({ aisle }: { readonly aisle: Aisle }) {
                 castShadow
             >
                 <meshStandardMaterial
-                    color={aisle.type.color || '#ffffff'}
+                    color={aisle.type.aisleColor || '#ffffff'}
                     side={THREE.DoubleSide}
                 />
             </Extrude>
@@ -133,7 +135,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
 
         const start = new THREE.Vector3(...aisle.points[0].position);
         const end = new THREE.Vector3(...aisle.points[1].position);
-        const width = aisle.type.width || 0.1;
+        const width = aisle.type.aisleWidth || 0.1;
         const dashLength = 0.5;
         const gapLength = 0.3;
 
@@ -183,7 +185,7 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
                     castShadow
                 >
                     <meshStandardMaterial
-                        color={aisle.type.color || '#ffffff'}
+                        color={aisle.type.aisleColor || '#ffffff'}
                         side={THREE.DoubleSide}
                     />
                 </Extrude>
@@ -191,3 +193,55 @@ function DashedAisle({ aisle }: { readonly aisle: Aisle }) {
         </group>
     );
 }
+
+function DottedAisle({ aisle }: { readonly aisle: Aisle }) {
+    const shapes = useMemo(() => {
+        if (aisle.points.length < 2) return [];
+
+        const start = new THREE.Vector3(...aisle.points[0].position);
+        const end = new THREE.Vector3(...aisle.points[1].position);
+        const width = aisle.type.aisleWidth || 0.1;
+        const dotSpacing = 0.5;
+        const dotRadius = width * 0.4;
+
+        const totalLength = new THREE.Vector3().subVectors(end, start).length();
+        const dotCount = Math.floor(totalLength / dotSpacing);
+
+        const shapes = [];
+        const directionNormalized = new THREE.Vector3().subVectors(end, start).normalize();
+
+        for (let i = 0; i < dotCount; i++) {
+            const dotCenter = new THREE.Vector3().copy(start).addScaledVector(directionNormalized, i * dotSpacing + dotSpacing / 2);
+
+            const shape = new THREE.Shape();
+            shape.absarc(dotCenter.x, dotCenter.z, dotRadius, 0, Math.PI * 2, false);
+
+            shapes.push(shape);
+        }
+
+        return shapes;
+    }, [aisle]);
+
+    if (shapes.length === 0) return null;
+
+    return (
+        <group
+            position={[0, (aisle.points[0].layer - 1) * Constants.wallConfig.height + 0.01, 0]}
+            rotation={[Math.PI / 2, 0, 0]}
+        >
+            {shapes.map((shape, index) => (
+                <Extrude
+                    key={index}
+                    args={[shape, { depth: 0.01, bevelEnabled: false }]}
+                    receiveShadow
+                    castShadow
+                >
+                    <meshStandardMaterial
+                        color={aisle.type.aisleColor || '#ffffff'}
+                        side={THREE.DoubleSide}
+                    />
+                </Extrude>
+            ))}
+        </group>
+    );
+}
\ No newline at end of file
diff --git a/app/src/store/builder/useAisleStore.ts b/app/src/store/builder/useAisleStore.ts
index 22bdbd3..17f16f7 100644
--- a/app/src/store/builder/useAisleStore.ts
+++ b/app/src/store/builder/useAisleStore.ts
@@ -9,8 +9,7 @@ interface AisleStore {
     removeAisle: (uuid: string) => void;
     setPosition: (pointUuid: string, position: [number, number, number]) => void;
     setLayer: (pointUuid: string, layer: number) => void;
-    setMaterial: (aisleUuid: string, material: string) => void;
-    setColor: (aisleUuid: string, color: string) => void;
+    setColor: (aisleUuid: string, color: AisleColors) => void;
     setWidth: (aisleUuid: string, width: number) => void;
     getAisleById: (uuid: string) => Aisle | undefined;
 }
@@ -58,24 +57,17 @@ export const useAisleStore = create<AisleStore>()(
             }
         }),
 
-        setMaterial: (aisleUuid: string, material: string) => set((state) => {
+        setColor: (aisleUuid: string, color: AisleColors) => set((state) => {
             const aisle = state.aisles.find(a => a.uuid === aisleUuid);
             if (aisle) {
-                aisle.type.material = material;
-            }
-        }),
-
-        setColor: (aisleUuid: string, color: string) => set((state) => {
-            const aisle = state.aisles.find(a => a.uuid === aisleUuid);
-            if (aisle) {
-                aisle.type.color = color;
+                aisle.type.aisleColor = color;
             }
         }),
 
         setWidth: (aisleUuid: string, width: number) => set((state) => {
             const aisle = state.aisles.find(a => a.uuid === aisleUuid);
             if (aisle) {
-                aisle.type.width = width;
+                aisle.type.aisleWidth = width;
             }
         }),
 
diff --git a/app/src/store/builder/useBuilderStore.ts b/app/src/store/builder/useBuilderStore.ts
new file mode 100644
index 0000000..fa2b596
--- /dev/null
+++ b/app/src/store/builder/useBuilderStore.ts
@@ -0,0 +1,42 @@
+import { create } from 'zustand';
+import { immer } from 'zustand/middleware/immer';
+
+interface BuilderState {
+    aisleType: AisleTypes;
+    aisleWidth: number;
+    aisleColor: AisleColors;
+    setAisleType: (type: AisleTypes) => void;
+    setAisleWidth: (width: number) => void;
+    setAisleColor: (color: AisleColors) => void;
+    setAisleProperties: (type: AisleTypes, width: number, color: AisleColors) => void;
+}
+
+export const useBuilderStore = create<BuilderState>()(
+    immer((set) => ({
+        aisleType: 'solid-aisle',
+        aisleWidth: 0.1,
+        aisleColor: 'gray',
+        setAisleType: (type) => {
+            set((state) => {
+                state.aisleType = type;
+            });
+        },
+        setAisleWidth: (width) => {
+            set((state) => {
+                state.aisleWidth = width;
+            });
+        },
+        setAisleColor: (color) => {
+            set((state) => {
+                state.aisleColor = color;
+            });
+        },
+        setAisleProperties: (type, width, color) => {
+            set((state) => {
+                state.aisleType = type;
+                state.aisleWidth = width;
+                state.aisleColor = color;
+            });
+        }
+    }))
+);
\ No newline at end of file
diff --git a/app/src/types/builderTypes.d.ts b/app/src/types/builderTypes.d.ts
index b2409a0..c361f8e 100644
--- a/app/src/types/builderTypes.d.ts
+++ b/app/src/types/builderTypes.d.ts
@@ -37,12 +37,15 @@ interface Point {
     layer: number;
 }
 
+type AisleTypes = | 'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle' | 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle';
+
+type AisleColors = | 'gray' | 'yellow' | 'green' | 'orange' | 'blue' | 'purple' | 'red' | 'bright green' | 'yellow-black' | 'white-black'
+
 interface AisleType {
     typeName: 'Aisle';
-    material: string;
-    aisleType: 'solid-aisle' | 'dashed-aisle' | 'stripped-aisle' | 'dotted-aisle' | 'arrow-aisle'| 'arrows-aisle' | 'arc-aisle' | 'circle-aisle' | 'junction-aisle';
-    color: string;
-    width: number;
+    aisleType: AisleTypes;
+    aisleColor: AisleColors;
+    aisleWidth: number;
 }
 
 interface Aisle {