Files
fabrikanabytok/apps/fabrikanabytok/components/planner/planner-editor-3d.tsx
2025-11-28 20:48:15 +01:00

185 lines
6.0 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
import { useSocket } from '@/components/providers/socket-provider'
import type { Design } from '@/lib/types/planner.types'
import { EnhancedPlannerCanvas } from './enhanced-planner-canvas'
import { PlannerToolbar } from './planner-toolbar'
import { PlannerSidebar } from './planner-sidebar'
import { AdvancedObjectInspector } from './advanced-object-inspector'
import { AdvancedToolsPanel } from './advanced-tools-panel'
import { PerformanceMonitorUI } from './performance-monitor-ui'
import { GLBOnboarding } from './glb-onboarding'
import { usePlannerStore } from '@/lib/store/planner-store'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Layers, Eye, Activity, Zap, Sparkles } from 'lucide-react'
interface PlannerEditor3DProps {
design: Design
userId: string
userName: string
}
export function PlannerEditor3D({ design, userId, userName }: PlannerEditor3DProps) {
const { socket, isConnected } = useSocket()
const [isInitialized, setIsInitialized] = useState(false)
const [showLeftPanel, setShowLeftPanel] = useState(true)
const [showRightPanel, setShowRightPanel] = useState(true)
const [showPerformance, setShowPerformance] = useState(false)
const [advancedMode, setAdvancedMode] = useState(true)
const {
selectedObjectId,
placedObjects,
renderSettings,
updateRenderSettings
} = usePlannerStore()
// Initialize planner store with design data
useEffect(() => {
if (!isInitialized && design) {
const store = usePlannerStore.getState()
// Clear existing objects first
store.placedObjects.forEach(obj => store.removeObject(obj.id))
// Load design data into store
if (design.placedObjects && design.placedObjects.length > 0) {
design.placedObjects.forEach(obj => {
store.addObject(obj)
})
}
// Load settings
if (design.snapSettings) {
store.updateSnapSettings(design.snapSettings)
}
if (design.renderSettings) {
store.updateRenderSettings(design.renderSettings)
}
setIsInitialized(true)
}
}, [design, isInitialized])
return (
<div className="h-screen flex flex-col bg-background">
{/* Collaboration Status */}
{socket && !isConnected && (
<div className="absolute top-4 right-4 z-50 bg-yellow-100 border border-yellow-400 text-yellow-800 px-4 py-2 rounded-lg text-sm shadow-lg">
🔄 Reconnecting to collaboration server...
</div>
)}
{socket && isConnected && (
<div className="absolute top-4 right-4 z-50 bg-green-100 border border-green-400 text-green-800 px-4 py-2 rounded-lg text-sm shadow-lg">
Connected - Real-time collaboration active
</div>
)}
{/* Toolbar */}
<PlannerToolbar design={design} />
{/* Status Bar */}
<div className="px-4 py-2 border-b bg-muted/30 flex items-center justify-between">
<div className="flex items-center gap-2">
<Badge variant="default" className="gap-1">
<Zap className="w-3 h-3" />
Advanced Mode
</Badge>
<Badge variant="outline" className="gap-1">
<Layers className="w-3 h-3" />
{placedObjects.length} Objects
</Badge>
<Badge variant="outline" className="gap-1">
<Activity className="w-3 h-3" />
{renderSettings?.quality?.toUpperCase()}
</Badge>
</div>
<div className="flex items-center gap-2">
<Button
variant="ghost"
size="sm"
onClick={() => setShowPerformance(!showPerformance)}
>
<Activity className="w-4 h-4" />
</Button>
</div>
</div>
{/* Main Content */}
<div className="flex-1 flex overflow-hidden relative">
{/* Left Panel */}
{showLeftPanel && (
advancedMode ? (
<AdvancedToolsPanel />
) : (
<PlannerSidebar designId={design.id} />
)
)}
{/* 3D Canvas */}
<div className="flex-1 relative">
<EnhancedPlannerCanvas
design={design}
enablePhysics={advancedMode}
enableWebXR={true}
enablePerformanceMonitor={showPerformance}
qualityPreset={renderSettings?.quality}
/>
{/* Toggle Buttons */}
<div className="absolute top-4 left-4 z-40 flex flex-col gap-2">
<Button
variant="outline"
size="sm"
onClick={() => setShowLeftPanel(!showLeftPanel)}
className="bg-background/90 backdrop-blur-sm"
>
<Layers className="w-4 h-4" />
</Button>
<Button
variant={advancedMode ? 'default' : 'outline'}
size="sm"
onClick={() => setAdvancedMode(!advancedMode)}
className="gap-2 bg-background/90 backdrop-blur-sm"
>
<Sparkles className="w-4 h-4" />
</Button>
</div>
<div className="absolute top-4 right-4 z-40">
<Button
variant="outline"
size="sm"
onClick={() => setShowRightPanel(!showRightPanel)}
className="bg-background/90 backdrop-blur-sm"
>
<Eye className="w-4 h-4" />
</Button>
</div>
{/* Performance Monitor */}
{showPerformance && <PerformanceMonitorUI visible={true} />}
</div>
{/* Right Panel - Object Inspector */}
{showRightPanel && (
<div className="w-80 border-l bg-card">
<AdvancedObjectInspector objectId={selectedObjectId} />
</div>
)}
</div>
{/* GLB Onboarding */}
<GLBOnboarding />
</div>
)
}