import React, { useRef, useState } from 'react'; import { useStudioStore, SceneObject } from '../store/useStudioStore'; import './LeftPanel.css'; const LeftPanel: React.FC = () => { const { objects, selectedId, setSelectedId, addObject, removeObject } = useStudioStore(); const fileInputRef = useRef(null); const [dragging, setDragging] = useState(false); const handleFiles = (files: FileList | null) => { if (!files) return; Array.from(files).forEach((file) => { if (!file.name.endsWith('.glb') && !file.name.endsWith('.gltf')) { alert('Please upload .glb or .gltf files only'); return; } const url = URL.createObjectURL(file); const newObj: SceneObject = { id: Math.random().toString(36).slice(2), name: file.name.replace(/\.(glb|gltf)$/, ''), url, file, position: [0, 0, 0], rotation: [0, 0, 0], scale: [1, 1, 1], color: '#ffffff', metalness: 0.2, roughness: 0.8, envMapIntensity: 1, animations: [], selectedAnimIndex: 0, animPlaying: false, animSpeed: 1, animLoop: true, }; addObject(newObj); }); }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); setDragging(false); handleFiles(e.dataTransfer.files); }; return (
ASSETS
{ e.preventDefault(); setDragging(true); }} onDragLeave={() => setDragging(false)} onClick={() => fileInputRef.current?.click()} >
Drop .GLB / .GLTF
or click to browse
handleFiles(e.target.files)} />
SCENE OBJECTS
{objects.length === 0 && (
No models loaded
)} {objects.map((obj) => (
setSelectedId(obj.id)} > {obj.name} {obj.animations.length > 0 && ( {obj.animations.length}A )}
))}
); }; export default LeftPanel;