2026-06-26 10:50:24 +02:00
|
|
|
|
import React from 'react';
|
|
|
|
|
|
import type { PropertiesPanelProps } from '../types/ui.types';
|
|
|
|
|
|
|
|
|
|
|
|
const PropertiesPanel: React.FC<PropertiesPanelProps> = ({ selectedElement, layers, onUpdateProperty }) => {
|
|
|
|
|
|
const el = selectedElement;
|
2026-06-27 14:12:37 +02:00
|
|
|
|
const x = el ? String(el.x) : '0';
|
|
|
|
|
|
const y = el ? String(el.y) : '0';
|
|
|
|
|
|
const w = el ? String(el.width) : '0.5';
|
|
|
|
|
|
const h = el ? String(el.height) : '0.5';
|
|
|
|
|
|
const rot = el ? String(el.properties.rotation ?? 0) : '0';
|
2026-06-26 10:50:24 +02:00
|
|
|
|
const color = (el?.properties.stroke as string) || '#3b82f6';
|
|
|
|
|
|
const blockName = el?.properties.blockId || 'Stuhl-Standard';
|
|
|
|
|
|
const desc = el?.properties.text as string || 'Standard-Konferenzstuhl 0.5×0.5m';
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<div className="panel-section">
|
|
|
|
|
|
<div className="panel-section-title">
|
|
|
|
|
|
<span>Auswahl · 1 Stuhl</span>
|
|
|
|
|
|
<button style={{ color: 'var(--color-text-muted)', fontSize: '11px' }} title="Mehr Optionen">
|
|
|
|
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="panel-section">
|
|
|
|
|
|
<div className="panel-section-title"><span>Geometrie</span></div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Position X</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<input className="prop-input" type="text" value={x} aria-label="Position X" onChange={(e) => onUpdateProperty('x', parseFloat(e.target.value) || 0)} />
|
2026-06-26 10:50:24 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Position Y</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<input className="prop-input" type="text" value={y} aria-label="Position Y" onChange={(e) => onUpdateProperty('y', parseFloat(e.target.value) || 0)} />
|
2026-06-26 10:50:24 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Breite</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<input className="prop-input" type="text" value={w} aria-label="Breite" onChange={(e) => onUpdateProperty('width', parseFloat(e.target.value) || 0)} />
|
2026-06-26 10:50:24 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Tiefe</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<input className="prop-input" type="text" value={h} aria-label="Tiefe" onChange={(e) => onUpdateProperty('height', parseFloat(e.target.value) || 0)} />
|
2026-06-26 10:50:24 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Drehung</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<input className="prop-input" type="text" value={rot} aria-label="Drehung" onChange={(e) => onUpdateProperty('rotation', parseFloat(e.target.value) || 0)} />
|
2026-06-26 10:50:24 +02:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="panel-section">
|
|
|
|
|
|
<div className="panel-section-title"><span>Darstellung</span></div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Farbe</span>
|
|
|
|
|
|
<div className="prop-color-row">
|
|
|
|
|
|
<div className="prop-color-swatch" style={{ background: color }} aria-hidden="true"></div>
|
|
|
|
|
|
<input className="prop-swatch-input" type="color" value={color} aria-label="Stuhlfarbe" onChange={(e) => onUpdateProperty('stroke', e.target.value)} />
|
|
|
|
|
|
<input className="prop-input" type="text" value={color.toUpperCase()} aria-label="Farb-Hex" onChange={(e) => onUpdateProperty('stroke', e.target.value)} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Linientyp</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<select className="prop-select" aria-label="Linientyp" value={el?.properties.lineType || 'solid'} onChange={(e) => onUpdateProperty('lineType', e.target.value)}>
|
2026-06-26 10:50:24 +02:00
|
|
|
|
<option>Solid (durchgehend)</option>
|
|
|
|
|
|
<option>Dashed (gestrichelt)</option>
|
|
|
|
|
|
<option>Dotted (gepunktet)</option>
|
|
|
|
|
|
<option>Dash-Dot</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Stärke</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<select className="prop-select" aria-label="Linienstärke" value={String(el?.properties.strokeWidth ?? '0.18')} onChange={(e) => onUpdateProperty('strokeWidth', e.target.value)}>
|
2026-06-26 10:50:24 +02:00
|
|
|
|
<option>0.18 mm · Normal</option>
|
|
|
|
|
|
<option>0.25 mm · Dick</option>
|
|
|
|
|
|
<option>0.35 mm · Extra</option>
|
|
|
|
|
|
<option>0.50 mm · Max</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Layer</span>
|
2026-06-27 14:12:37 +02:00
|
|
|
|
<select className="prop-select" aria-label="Layer zuweisen" value={el?.layerId || ''} onChange={(e) => onUpdateProperty('layerId', e.target.value)}>
|
2026-06-26 10:50:24 +02:00
|
|
|
|
{layers.length > 0 ? layers.map((l) => (
|
|
|
|
|
|
<option key={l.id} value={l.id}>{l.name}</option>
|
|
|
|
|
|
)) : (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<option>Bestuhlung · Standard</option>
|
|
|
|
|
|
<option>Bestuhlung · VIP</option>
|
|
|
|
|
|
<option>Möbel · Tische</option>
|
|
|
|
|
|
<option>Bühne</option>
|
|
|
|
|
|
</>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="panel-section">
|
|
|
|
|
|
<div className="panel-section-title"><span>Block</span></div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Block-Name</span>
|
|
|
|
|
|
<input className="prop-input" type="text" value={blockName} aria-label="Block-Name" onChange={(e) => onUpdateProperty('blockId', e.target.value)} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="prop-row">
|
|
|
|
|
|
<span className="prop-label">Beschreibung</span>
|
|
|
|
|
|
<input className="prop-input" type="text" value={desc} aria-label="Beschreibung" onChange={(e) => onUpdateProperty('text', e.target.value)} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default PropertiesPanel;
|