feat: add floor selector dropdown to 3D viewer (defaults to Upper Floor with 479 plants)
Some checks are pending
Deploy to Production / deploy (push) Waiting to run
Test / backend-test (push) Waiting to run
Test / frontend-test (push) Waiting to run

This commit is contained in:
fullsizemalt 2025-12-18 12:14:26 -08:00
parent f91fbc2237
commit 71f1e23ff3

View file

@ -51,6 +51,10 @@ export default function Facility3DViewerPage() {
const [timelineDate, setTimelineDate] = useState<Date>(new Date());
const [isTimelinePlaying, setIsTimelinePlaying] = useState(false);
// Floor selection state
const [allFloors, setAllFloors] = useState<{ id: string; name: string; buildingName: string }[]>([]);
const [selectedFloorId, setSelectedFloorId] = useState<string | null>(null);
const [searchParams] = useSearchParams();
const targetedPlantTag = searchParams.get('plant');
@ -58,6 +62,13 @@ export default function Facility3DViewerPage() {
loadData();
}, []);
// Load floor data when selected floor changes
useEffect(() => {
if (selectedFloorId) {
loadFloorData(selectedFloorId);
}
}, [selectedFloorId]);
// Deep link handler
useEffect(() => {
if (floorData && targetedPlantTag) {
@ -83,16 +94,40 @@ export default function Facility3DViewerPage() {
}
}, [floorData, targetedPlantTag]);
async function loadFloorData(floorId: string) {
setStatus('Fetching 3D scene...');
try {
const data = await layoutApi.getFloor3D(floorId);
setFloorData(data);
setStatus('');
} catch (err) {
setStatus('Error: ' + (err as Error).message);
}
}
async function loadData() {
setStatus('Loading layout...');
try {
const props = await layoutApi.getProperties();
if (props[0]?.buildings[0]?.floors[0]) {
const floorId = props[0].buildings[0].floors[0].id;
setStatus('Fetching 3D scene...');
const data = await layoutApi.getFloor3D(floorId);
setFloorData(data);
setStatus('');
if (props[0]?.buildings?.length > 0) {
// Collect all floors from all buildings
const floors: { id: string; name: string; buildingName: string }[] = [];
for (const building of props[0].buildings) {
for (const floor of building.floors || []) {
floors.push({
id: floor.id,
name: floor.name,
buildingName: building.name
});
}
}
setAllFloors(floors);
// Default to second floor if available (Upper Floor has more plants)
if (floors.length > 0) {
const defaultFloor = floors.length > 1 ? floors[1] : floors[0];
setSelectedFloorId(defaultFloor.id);
}
} else {
setStatus('No floor layout found. Set up a facility first.');
}
@ -165,9 +200,28 @@ export default function Facility3DViewerPage() {
Facility 3D
<span className="badge badge-accent text-xs">BETA</span>
</h1>
<p className="text-xs text-slate-400">
{floorData ? `${floorData.floor.name}${floorData.stats.occupiedPositions} Plants` : 'Loading...'}
</p>
<div className="flex items-center gap-2">
{allFloors.length > 1 ? (
<select
value={selectedFloorId || ''}
onChange={(e) => setSelectedFloorId(e.target.value)}
className="select select-xs bg-slate-800 border-slate-600 text-white"
>
{allFloors.map(f => (
<option key={f.id} value={f.id}>
{f.buildingName} - {f.name}
</option>
))}
</select>
) : (
<span className="text-xs text-slate-400">
{floorData?.floor.name || 'Loading...'}
</span>
)}
<span className="text-xs text-slate-400">
{floorData?.stats.occupiedPositions || 0} Plants
</span>
</div>
</div>
</div>