import React, { useState, useEffect, useRef } from 'react'; import './SidePanel.css'; import LayerPanel from './LayerPanel'; import BlockLibrary from './BlockLibrary'; import PropertiesPanel from './PropertiesPanel/PropertiesPanel'; interface SidePanelProps { canvasRef?: React.RefObject; yjsDoc?: React.RefObject; } const SidePanel: React.FC = ({ canvasRef, yjsDoc }) => { const [activeTab, setActiveTab] = useState('blocks'); const [layers, setLayers] = useState([]); const [activeLayer, setActiveLayer] = useState(''); const localCanvasRef = useRef(null); const localYjsDocRef = useRef(null); // Use props if provided, otherwise fall back to local refs const effectiveCanvasRef = (canvasRef ?? localCanvasRef) as React.RefObject; const effectiveYjsDocRef = (yjsDoc ?? localYjsDocRef) as React.RefObject; const tabs = [ { id: 'blocks', label: 'Blocks', icon: '🧱' }, { id: 'layers', label: 'Layers', icon: '📄' }, { id: 'properties', label: 'Properties', icon: '⚙️' }, { id: 'copilot', label: 'KI Copilot', icon: '🤖' }, ]; // Observe changes in yjsDoc.layers useEffect(() => { const yjsDocInstance = effectiveYjsDocRef?.current as { layers?: { forEach: (cb: (layer: Record, id: string) => void) => void; observe: (cb: () => void) => void; unobserve: (cb: () => void) => void; }; } | null; const yjsLayers = yjsDocInstance?.layers; if (!yjsLayers) return; // Function to update layers from yjsDoc const updateLayers = () => { const layersArray: Array & { id: string }> = []; yjsLayers.forEach((layer, id) => { layersArray.push({ ...layer, id }); }); setLayers(layersArray); // Set active layer if none is set or if current active layer doesn't exist if (!activeLayer || !layersArray.some(layer => layer.id === activeLayer)) { if (layersArray.length > 0) { setActiveLayer(layersArray[0].id); } } }; // Initial update updateLayers(); // Observe changes yjsLayers.observe(updateLayers); // Cleanup observer on unmount return () => { yjsLayers.unobserve(updateLayers); }; }, [activeLayer, effectiveYjsDocRef]); const renderContent = () => { switch (activeTab) { case 'blocks': return ).current} />; case 'layers': return ( ).current} /> ); case 'properties': return ( ); case 'copilot': return
KI Copilot content goes here
; default: return
Select a tab
; } }; return (
{tabs.map((tab) => ( ))}
{renderContent()}
); }; export default SidePanel;