From 66092158b293a21e516a238b2dd2f8e0008782cf Mon Sep 17 00:00:00 2001
From: Angel <angelsola2004@gmailcom>
Date: Mon, 12 May 2025 20:26:04 +0200
Subject: [PATCH] api dades

---
 app/src/ar_scenes/FloorScene.jsx | 272 +++++++++----------------------
 app/src/styles/ar.css            |  10 +-
 2 files changed, 83 insertions(+), 199 deletions(-)

diff --git a/app/src/ar_scenes/FloorScene.jsx b/app/src/ar_scenes/FloorScene.jsx
index 0a5293f..e57d7eb 100644
--- a/app/src/ar_scenes/FloorScene.jsx
+++ b/app/src/ar_scenes/FloorScene.jsx
@@ -1,208 +1,64 @@
-import React, { Suspense, useState, useRef, useEffect} from "react";
+import React, { useEffect, useState, useRef, Suspense } from "react";
 import { Canvas, useFrame } from "@react-three/fiber";
-import { OrbitControls, useGLTF } from "@react-three/drei";
-import ModelSelector from "./ModelSelector";
-import Model from "./Model";
-
+import { OrbitControls } from "@react-three/drei";
+import * as THREE from "three";
 import Select from "react-select";
-// Conjuntos de modelos
-const modelSets = [
-  [
-    { url: "/nexus/P0B.glb", label: "Base P0" },
-    { url: "/nexus/P0O0.glb", label: "Oficina 0" },
-    { url: "/nexus/P0O1.glb", label: "Oficina 1" },
-    { url: "/nexus/P0O2.glb", label: "Oficina 2" },
-  ],
-  [
-    { url: "/nexus/P1B.glb", label: "Base P1" },
-    { url: "/nexus/P1O0.glb", label: "Oficina 0" },
-    { url: "/nexus/P1O1.glb", label: "Oficina 1" },
-    { url: "/nexus/P1O2.glb", label: "Oficina 2" },
-    { url: "/nexus/P1O3.glb", label: "Oficina 3" },
-    { url: "/nexus/P1O4.glb", label: "Oficina 4" },
-    { url: "/nexus/P1O5.glb", label: "Oficina 5" },
-    { url: "/nexus/P1O6.glb", label: "Oficina 6" },
-    { url: "/nexus/P1O7.glb", label: "Oficina 7" },
-    { url: "/nexus/P1O8.glb", label: "Oficina 8" },
-    { url: "/nexus/P1O9.glb", label: "Oficina 9" },
-    { url: "/nexus/P1O10.glb", label: "Oficina 10" },
-  ],
-];
-
-// Preload modelos
-modelSets.flat().forEach((model) => useGLTF.preload(model.url));
-
-const Model3D = ({ url, position = [0, 0, 0], scale = [5, 5, 5], visible }) => {
-  const gltf = useGLTF(url);
-  return (
-    <primitive
-      object={gltf.scene}
-      position={position}
-      scale={scale}
-      visible={visible}
-    />
-  );
-};
-
-const FloorScene = () => {
-  const [activeSetIndex, setActiveSetIndex] = useState(0);
-  const [modelStates, setModelStates] = useState(
-    modelSets.map((set) =>
-      set.map((model) => ({
-        ...model,
-        position: [0, 0, 0],
-        scale: [5, 5, 5],
-        visible: true,
-      }))
-    )
-  );
-
-  const toggleModelVisibility = (modelIndex) => {
-    setModelStates((prev) =>
-      prev.map((set, i) =>
-        i === activeSetIndex
-          ? set.map((model, j) =>
-              j === modelIndex ? { ...model, visible: !model.visible } : model
-            )
-          : set
-      )
-    );
-  };
-
-  const handleSetChange = (e) => {
-    setActiveSetIndex(Number(e.target.value));
-  };
-
-  return (
-    <>
-      <ModelSelector
-        modelSets={modelSets}
-        activeSetIndex={activeSetIndex}
-        handleSetChange={handleSetChange}
-        modelStates={modelStates}
-        toggleModelVisibility={toggleModelVisibility}
-      />
-
-      <Canvas camera={{ position: [0, 1, 8] }}>
-        <ambientLight />
-        <directionalLight position={[5, 5, 5]} />
-        <Suspense fallback={null}>
-          {modelStates[activeSetIndex].map((model, index) => (
-            <Model
-              key={`${model.url}-${index}`}
-              url={model.url}
-              position={model.position}
-              scale={model.scale}
-              visible={model.visible}
-            />
-          ))}
-        </Suspense>
-        <OrbitControls enableZoom={false} enablePan={false} />
-      </Canvas>
-    </>
-  );
-};
+import Model from "./Model"; 
 
-
-const Floor = ({ activeOffice, setActiveOffice }) => {
+const Floor = ({ floorData, activeOffice, setActiveOffice }) => {
   const groupRef = useRef();
-
   useFrame(() => {
     if (groupRef.current) {
       groupRef.current.rotation.y += 0.003;
     }
   });
 
-  return (
-    <group ref={groupRef}>
-      <Model
-        path="/baseMT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={1}
-      />
-
-      <Model
-        path="/oficina1MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 1 ? 0.9 : 0.2}
-        onClick={() => setActiveOffice(1)}
-      />
-
-      <Model
-        path="/oficina2MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 2 ? 0.9 : 0.2}
-        onClick={() => setActiveOffice(2)}
-      />
-
-      <Model
-        path="/oficina3MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 3 ? 0.9 : 0.2}
-        onClick={() => setActiveOffice(3)}
-      />
-
-      <Model
-        path="/oficina4MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 4 ? 0.9 : 0.2}
-        onClick={() => setActiveOffice(4)}
-      />
-
-      <Model
-        path="/oficina5MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 5 ? 0.9 : 0.2}
-        onClick={() => setActiveOffice(5)}
-      />
+  if (!floorData) return null;
 
-      <Model
-        path="/oficina6MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 6? 0.9 : 0.2}
-        onClick={() => setActiveOffice(6)}
-      />
+  const [base, ...offices] = floorData.urlModelos;
+  const scale = Array(3).fill(Number(floorData.scale) || 1); 
 
-      <Model
-        path="/oficina7MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 7 ? 0.9 : 0.2}
-        onClick={() => setActiveOffice(7)}
-      />
-
-      <Model
-        path="/oficina8MT.glb"
-        scale={[1, 1, 1]}
-        position={[0, 0, 0]}
-        opacity={activeOffice === 8? 0.9 : 0.2}
-        onClick={() => setActiveOffice(8)}
-      />
+  return (
+    <group ref={groupRef}>
+      <Model path={base} scale={scale} position={[0, 0, 0]} opacity={1} />
+
+      {offices.map((path, index) => {
+        const officeIndex = index + 1;
+        return (
+          <Model
+            key={path}
+            path={path}
+            scale={scale}
+            position={[0, 0, 0]}
+            opacity={activeOffice === officeIndex ? 0.9 : 0.2}
+            onClick={() => setActiveOffice(officeIndex)}
+          />
+        );
+      })}
     </group>
   );
 };
 
 const App = () => {
+  const [floors, setFloors] = useState([]);
+  const [activeFloorIndex, setActiveFloorIndex] = useState(0);
   const [activeOffice, setActiveOffice] = useState(null);
 
-  const options = [
-    { value: null, label: "Eliga su oficina" },
-    { value: 1, label: "Oficina 1" },
-    { value: 2, label: "Oficina 2" },
-    { value: 3, label: "Oficina 3" },
-    { value: 4, label: "Oficina 4" },
-    { value: 5, label: "Oficina 5" },
-    { value: 6, label: "Oficina 6" },
-    { value: 7, label: "Oficina 7" },
-    { value: 8, label: "Oficina 8" },
-  ];
+  useEffect(() => {
+    fetch("https://serverm3d.onrender.com/floors/building/1")
+      .then((res) => res.json())
+      .then((data) => setFloors(data))
+      .catch((err) => console.error("Error fetching floors:", err));
+  }, []);
+
+  const options = [{ value: null, label: "Eliga su oficina" }];
+  const currentFloor = floors[activeFloorIndex];
+  if (currentFloor) {
+    const officeOptions = currentFloor.urlModelos
+      .slice(1)
+      .map((_, i) => ({ value: i + 1, label: `Oficina ${i + 1}` }));
+    options.push(...officeOptions);
+  }
 
   const selectedOption = options.find((opt) => opt.value === activeOffice);
 
@@ -214,7 +70,7 @@ const App = () => {
           bottom: 30,
           left: "50%",
           transform: "translateX(-50%)",
-          width: "260px", 
+          width: "260px",
           zIndex: 1000,
           display: "flex",
           flexDirection: "column",
@@ -230,7 +86,7 @@ const App = () => {
           placeholder="Seleccionar oficina"
           menuPlacement="top"
           menuPortalTarget={document.body}
-          styles={{
+          styles={{ 
             control: (base, state) => ({
               ...base,
               backgroundColor: "#2b2b2b",
@@ -288,14 +144,14 @@ const App = () => {
               fontWeight: isSelected ? "bold" : 400,
               transition: "background 0.2s ease, color 0.2s ease",
             }),
-          }}
+           }}
         />
 
         {activeOffice !== null && (
           <button
             onClick={() => setActiveOffice(null)}
             style={{
-              width: "100%", 
+              width: "100%",
               padding: "10px 0",
               fontSize: "15px",
               borderRadius: "10px",
@@ -303,22 +159,50 @@ const App = () => {
               color: "white",
               border: "none",
               cursor: "pointer",
-              transition: "background 0.3s ease",
               fontWeight: "bold",
             }}
-            onMouseOver={(e) => (e.currentTarget.style.backgroundColor = "#cc0000")}
-            onMouseOut={(e) => (e.currentTarget.style.backgroundColor = "red")}
           >
             Ocultar oficina
           </button>
         )}
+
+        {floors.length > 1 && (
+          <div style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
+            {floors.map((floor, index) => (
+              <button
+                key={floor.id}
+                onClick={() => {
+                  setActiveFloorIndex(index);
+                  setActiveOffice(null); // reset
+                }}
+                style={{
+                  padding: "6px 12px",
+                  backgroundColor: index === activeFloorIndex ? "red" : "#2b2b2b",
+                  color: "white",
+                  border: "1px solid #444",
+                  borderRadius: "8px",
+                  cursor: "pointer",
+                  fontWeight: "bold",
+                }}
+              >
+                {floor.nombre}
+              </button>
+            ))}
+          </div>
+        )}
       </div>
 
       <Canvas camera={{ position: [0, 30, 30], fov: 50 }}>
         <ambientLight intensity={0.5} />
         <directionalLight position={[10, 10, 5]} castShadow />
         <OrbitControls target={[0, 0, 0]} />
-        <Floor activeOffice={activeOffice} setActiveOffice={setActiveOffice} />
+        <Suspense fallback={null}>
+          <Floor
+            floorData={currentFloor}
+            activeOffice={activeOffice}
+            setActiveOffice={setActiveOffice}
+          />
+        </Suspense>
       </Canvas>
     </div>
   );
diff --git a/app/src/styles/ar.css b/app/src/styles/ar.css
index a8937bd..c9548bc 100644
--- a/app/src/styles/ar.css
+++ b/app/src/styles/ar.css
@@ -127,7 +127,7 @@
 .popup-form input:focus,
 .popup-form textarea:focus {
   outline: none;
-  border-color: #4f46e5;
+  border-color: "red";
   box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
 }
 
@@ -156,12 +156,12 @@
 }
 
 .form-actions button[type="submit"] {
-  background-color: #4f46e5;
+  background-color: #e12c2c;
   color: white;
 }
 
 .form-actions button[type="submit"]:hover {
-  background-color: #4338ca;
+  background-color: #38ca42;
 }
 
 .form-actions button[type="button"] {
@@ -178,7 +178,7 @@
   padding: 0.8rem 2rem;
   font-size: 1.1rem;
   font-weight: 600;
-  background-color: #4f46e5;
+  background-color: #e12c2c;
   color: white;
   border: none;
   border-radius: 10px;
@@ -188,6 +188,6 @@
 }
 
 .form-button:hover {
-  background-color: #4338ca;
+  background-color: #38ca42;
   transform: scale(1.02);
 }
-- 
GitLab