2026-07-04 16:43:55 +02:00
|
|
|
import React, { useState, useCallback } from 'react';
|
2026-06-26 10:50:24 +02:00
|
|
|
import type { LeftSidebarProps } from '../types/ui.types';
|
|
|
|
|
import { SEATING_TEMPLATES } from '../services/seatingService';
|
|
|
|
|
|
|
|
|
|
interface ToolDef {
|
|
|
|
|
tool: string;
|
|
|
|
|
title: string;
|
|
|
|
|
label: string;
|
|
|
|
|
kbd: string;
|
|
|
|
|
svg: React.ReactNode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sectionAuswahlen: ToolDef[] = [
|
2026-07-04 16:43:55 +02:00
|
|
|
{ tool: 'select', title: 'Auswählen (V)', label: 'Auswahl', kbd: 'V', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round"><path d="m3 3 7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="m13 13 6 6"/></svg> },
|
|
|
|
|
{ tool: 'pan', title: 'Pan (P / Leertaste)', label: 'Pan', kbd: 'P', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round"><path d="M18 11V6a2 2 0 0 0-2-2 2 2 0 0 0-2 2"/><path d="M14 10V4a2 2 0 0 0-2-2 2 2 0 0 0-2 2v2"/><path d="M10 10.5V6a2 2 0 0 0-2-2 2 2 0 0 0-2 2v8"/><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"/></svg> },
|
|
|
|
|
{ tool: 'measure', title: 'Messen', label: 'Messen', kbd: 'M', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21.3 8.7 8.7 21.3a1 1 0 0 1-1.4 0L2.7 16.7a1 1 0 0 1 0-1.4L15.3 2.7a1 1 0 0 1 1.4 0l4.6 4.6a1 1 0 0 1 0 1.4z"/><path d="m7.5 10.5 2 2"/><path d="m10.5 7.5 2 2"/></svg> },
|
2026-06-26 10:50:24 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const sectionZeichnen: ToolDef[] = [
|
2026-07-04 16:43:55 +02:00
|
|
|
{ tool: 'line', title: 'Linie (L)', label: 'Linie', kbd: 'L', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="19" x2="19" y2="5"/></svg> },
|
|
|
|
|
{ tool: 'polyline', title: 'Polylinie (PL)', label: 'Polylinie', kbd: 'PL', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="4 17 10 11 14 15 20 7"/></svg> },
|
|
|
|
|
{ tool: 'rect', title: 'Rechteck (REC)', label: 'Rechteck', kbd: 'REC', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="1"/></svg> },
|
|
|
|
|
{ tool: 'circle', title: 'Kreis (C)', label: 'Kreis', kbd: 'C', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/></svg> },
|
|
|
|
|
{ tool: 'arc', title: 'Bogen (A)', label: 'Bogen', kbd: 'A', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0z"/><path d="M3 12a9 9 0 0 1 9-9"/></svg> },
|
2026-07-27 01:17:18 +02:00
|
|
|
{ tool: 'polygon', title: 'Polygon (POL)', label: 'Polygon', kbd: 'POL', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="12 2 22 8.5 18 22 6 22 2 8.5"/></svg> },
|
|
|
|
|
{ tool: 'chair', title: 'Stuhl (CH)', label: 'Stuhl', kbd: 'CH', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="6" y="10" width="12" height="8" rx="1"/><path d="M6 10V6a3 3 0 0 1 3-3h6a3 3 0 0 1 3 3v4"/></svg> },
|
2026-07-04 16:43:55 +02:00
|
|
|
{ tool: 'text', title: 'Text (T)', label: 'Text', kbd: 'T', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" y1="20" x2="15" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/></svg> },
|
|
|
|
|
{ tool: 'dimension', title: 'Bemaßung (DIM)', label: 'Bemaßung', kbd: 'DIM', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 3H3l3 18 3-9 6 9 3-9 3 9 3-18z"/><line x1="3" y1="3" x2="21" y2="21"/></svg> },
|
|
|
|
|
{ tool: 'hatch', title: 'Schraffur (H)', label: 'Schraffur', kbd: 'H', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="0"/><line x1="3" y1="9" x2="9" y2="3"/><line x1="9" y1="21" x2="21" y2="9"/><line x1="15" y1="21" x2="21" y2="15"/></svg> },
|
|
|
|
|
{ tool: 'leader', title: 'Hinweislinie (LD)', label: 'Hinweis', kbd: 'LD', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 21 12 12"/><path d="M12 12 18 6"/><polyline points="18 3 18 6 21 6"/><line x1="18" y1="6" x2="21" y2="3"/></svg> },
|
|
|
|
|
{ tool: 'revcloud', title: 'Revisionswolke (REV)', label: 'RevCloud', kbd: 'REV', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 18c-1-3 1-5 3-4 0-3 3-4 5-2 1-3 5-3 6 0 2-1 5 1 4 4 1 2-2 4-4 3-1 2-4 2-5 0-2 1-5-1-4-3-2-1-3-4-1-5z"/></svg> },
|
2026-06-26 10:50:24 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const sectionBearbeiten: ToolDef[] = [
|
2026-07-04 16:43:55 +02:00
|
|
|
{ tool: 'move', title: 'Verschieben (M)', label: 'Move', kbd: 'M', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="5 9 2 12 5 15"/><polyline points="9 5 12 2 15 5"/><polyline points="15 19 12 22 9 19"/><polyline points="19 9 22 12 19 15"/><line x1="2" y1="12" x2="22" y2="12"/><line x1="12" y1="2" x2="12" y2="22"/></svg> },
|
|
|
|
|
{ tool: 'copy', title: 'Kopieren (CO)', label: 'Copy', kbd: 'CO', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg> },
|
|
|
|
|
{ tool: 'rotate', title: 'Rotieren (RO)', label: 'Rotate', kbd: 'RO', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg> },
|
|
|
|
|
{ tool: 'scale', title: 'Skalieren (SC)', label: 'Scale', kbd: 'SC', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg> },
|
|
|
|
|
{ tool: 'mirror', title: 'Spiegeln (MI)', label: 'Mirror', kbd: 'MI', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v18"/><path d="M5 8l5-5 5 5"/><path d="M5 16l5 5 5-5"/></svg> },
|
|
|
|
|
{ tool: 'trim', title: 'Trimmen (TR)', label: 'Trim', kbd: 'TR', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><line x1="20" y1="4" x2="8.12" y2="15.88"/><line x1="14.47" y1="14.48" x2="20" y2="20"/><line x1="8.12" y1="8.12" x2="12" y2="12"/></svg> },
|
2026-07-27 01:17:18 +02:00
|
|
|
{ tool: 'extend', title: 'Verlängern (EX)', label: 'Extend', kbd: 'EX', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="4 12 20 12"/><polyline points="14 6 20 12 14 18"/></svg> },
|
|
|
|
|
{ tool: 'fillet', title: 'Verrunden (F)', label: 'Fillet', kbd: 'F', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 22V12a10 10 0 0 1 10-10h10"/></svg> },
|
2026-07-04 16:43:55 +02:00
|
|
|
{ tool: 'offset', title: 'Versatz (O)', label: 'Offset', kbd: 'O', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h12"/><path d="M3 12h18"/><path d="M3 18h12"/><path d="M21 6v12"/></svg> },
|
|
|
|
|
{ tool: 'delete', title: 'Löschen (E)', label: 'Löschen', kbd: 'E', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg> },
|
2026-06-26 10:50:24 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const sectionBestuhlung: ToolDef[] = [
|
2026-07-04 16:43:55 +02:00
|
|
|
{ tool: 'seating-row', title: 'Reihen-Bestuhlung', label: 'Reihe', kbd: 'R', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="4" height="3" rx="0.5"/><rect x="10" y="5" width="4" height="3" rx="0.5"/><rect x="17" y="5" width="4" height="3" rx="0.5"/><rect x="3" y="11" width="4" height="3" rx="0.5"/><rect x="10" y="11" width="4" height="3" rx="0.5"/><rect x="17" y="11" width="4" height="3" rx="0.5"/><rect x="3" y="17" width="4" height="3" rx="0.5"/><rect x="10" y="17" width="4" height="3" rx="0.5"/><rect x="17" y="17" width="4" height="3" rx="0.5"/></svg> },
|
|
|
|
|
{ tool: 'seating-block', title: 'Block-Bestuhlung', label: 'Block', kbd: 'B', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="1"/><rect x="6" y="6" width="3" height="3"/><rect x="10.5" y="6" width="3" height="3"/><rect x="15" y="6" width="3" height="3"/><rect x="6" y="10.5" width="3" height="3"/><rect x="10.5" y="10.5" width="3" height="3"/><rect x="15" y="10.5" width="3" height="3"/><rect x="6" y="15" width="3" height="3"/><rect x="10.5" y="15" width="3" height="3"/><rect x="15" y="15" width="3" height="3"/></svg> },
|
|
|
|
|
{ tool: 'table', title: 'Tisch (TAB)', label: 'Tisch', kbd: 'TAB', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="4" y="9" width="16" height="6" rx="1"/><line x1="6" y1="15" x2="6" y2="19"/><line x1="18" y1="15" x2="18" y2="19"/></svg> },
|
|
|
|
|
{ tool: 'stage', title: 'Bühne', label: 'Bühne', kbd: 'S', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 17h20v3H2z"/><path d="M5 14V8h14v6"/><path d="M9 14v-3"/><path d="M15 14v-3"/></svg> },
|
|
|
|
|
{ tool: 'seating-template', title: 'Vorlagen', label: 'Vorlagen', kbd: 'TPL', svg: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg> },
|
2026-06-26 10:50:24 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const sections: Array<{ label: string; tools: ToolDef[] }> = [
|
|
|
|
|
{ label: 'Auswählen / Anzeigen', tools: sectionAuswahlen },
|
|
|
|
|
{ label: 'Zeichnen', tools: sectionZeichnen },
|
|
|
|
|
{ label: 'Bearbeiten', tools: sectionBearbeiten },
|
|
|
|
|
{ label: 'Bestuhlung', tools: sectionBestuhlung },
|
|
|
|
|
];
|
|
|
|
|
|
2026-07-04 16:43:55 +02:00
|
|
|
const MIN_LEFTBAR_WIDTH = 140;
|
|
|
|
|
const MAX_LEFTBAR_WIDTH = 400;
|
|
|
|
|
|
|
|
|
|
const LeftSidebar: React.FC<LeftSidebarProps> = ({ activeTool, onToolChange, selectedTemplate, onTemplateSelect, onCollapse, className, collapsed, onToggleCollapse, onGroup, onUngroup, leftbarWidth = 200, onWidthChange }) => {
|
|
|
|
|
const [collapsedSections, setCollapsedSections] = useState<Record<string, boolean>>({});
|
|
|
|
|
|
|
|
|
|
const toggleSection = useCallback((label: string) => {
|
|
|
|
|
setCollapsedSections((prev) => ({ ...prev, [label]: !prev[label] }));
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const handleResizeMouseDown = useCallback((e: React.MouseEvent) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
const startClientX = e.clientX;
|
|
|
|
|
const startWidth = leftbarWidth;
|
|
|
|
|
|
|
|
|
|
const handleMouseMove = (ev: MouseEvent) => {
|
|
|
|
|
const delta = ev.clientX - startClientX;
|
|
|
|
|
const newWidth = Math.min(MAX_LEFTBAR_WIDTH, Math.max(MIN_LEFTBAR_WIDTH, startWidth + delta));
|
|
|
|
|
document.documentElement.style.setProperty('--leftbar-w', newWidth + 'px');
|
|
|
|
|
if (onWidthChange) {
|
|
|
|
|
onWidthChange(newWidth);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleMouseUp = () => {
|
|
|
|
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
|
|
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
|
|
|
document.body.style.cursor = '';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.body.style.cursor = 'col-resize';
|
|
|
|
|
document.addEventListener('mousemove', handleMouseMove);
|
|
|
|
|
document.addEventListener('mouseup', handleMouseUp);
|
|
|
|
|
}, [leftbarWidth, onWidthChange]);
|
|
|
|
|
|
|
|
|
|
const renderSectionLabel = (label: string, sectionKey: string) => (
|
|
|
|
|
<div
|
|
|
|
|
className="tool-section-label"
|
|
|
|
|
onClick={() => toggleSection(sectionKey)}
|
|
|
|
|
style={{ cursor: 'pointer', userSelect: 'none', display: 'flex', alignItems: 'center', gap: '4px' }}
|
|
|
|
|
>
|
|
|
|
|
<span className="tool-section-chevron">{collapsedSections[sectionKey] ? '▶' : '▼'}</span>
|
|
|
|
|
{label}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
|
2026-06-26 10:50:24 +02:00
|
|
|
return (
|
2026-07-04 16:08:51 +02:00
|
|
|
<aside className={`leftbar${className ? ' ' + className : ''}${collapsed ? ' leftbar-collapsed' : ''}`} aria-label="Werkzeugpalette">
|
2026-06-26 10:50:24 +02:00
|
|
|
<div className="leftbar-header">
|
|
|
|
|
<span className="leftbar-title">Werkzeuge</span>
|
2026-07-04 16:43:55 +02:00
|
|
|
<button className="leftbar-toggle" aria-label="Linke Leiste ein-/ausklappen" onClick={collapsed ? onToggleCollapse : onCollapse} title="Linke Leiste ein-/ausklappen">
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
|
2026-06-26 10:50:24 +02:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-07-04 16:43:55 +02:00
|
|
|
<div className="leftbar-content">
|
|
|
|
|
|
2026-06-26 10:50:24 +02:00
|
|
|
{sections.map((section) => (
|
|
|
|
|
<div className="tool-section" key={section.label}>
|
2026-07-04 16:43:55 +02:00
|
|
|
{renderSectionLabel(section.label, section.label)}
|
|
|
|
|
<div className="tool-grid" style={collapsedSections[section.label] ? { display: 'none' } : undefined}>
|
2026-06-26 10:50:24 +02:00
|
|
|
{section.tools.map((t) => (
|
|
|
|
|
<button
|
|
|
|
|
key={t.tool}
|
|
|
|
|
className={`tool-btn${activeTool === t.tool ? ' active' : ''}`}
|
|
|
|
|
data-tool={t.tool}
|
|
|
|
|
title={t.title}
|
|
|
|
|
onClick={() => onToolChange(t.tool)}
|
|
|
|
|
>
|
|
|
|
|
{t.svg}
|
|
|
|
|
<span className="tool-btn-label">{t.label}</span>
|
|
|
|
|
<span className="tool-btn-kbd">{t.kbd}</span>
|
|
|
|
|
</button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
|
2026-07-04 16:43:55 +02:00
|
|
|
{(onGroup || onUngroup) && (
|
|
|
|
|
<div className="tool-section" key="grouping">
|
|
|
|
|
{renderSectionLabel("Gruppierung", "grouping")}
|
|
|
|
|
<div className="tool-grid" style={collapsedSections["grouping"] ? { display: "none" } : undefined}>
|
|
|
|
|
{onGroup && (
|
|
|
|
|
<button
|
|
|
|
|
className="tool-btn"
|
|
|
|
|
title="Gruppieren (G)"
|
|
|
|
|
onClick={onGroup}
|
|
|
|
|
>
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/><path d="M10 10l4 4"/></svg>
|
|
|
|
|
<span className="tool-btn-label">Gruppieren</span>
|
|
|
|
|
<span className="tool-btn-kbd">G</span>
|
|
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
{onUngroup && (
|
|
|
|
|
<button
|
|
|
|
|
className="tool-btn"
|
|
|
|
|
title="Degruppieren (Strg+G)"
|
|
|
|
|
onClick={onUngroup}
|
|
|
|
|
>
|
|
|
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1" strokeDasharray="2 2"/><rect x="14" y="14" width="7" height="7" rx="1" strokeDasharray="2 2"/><path d="M10 10l4 4" strokeDasharray="2 2"/></svg>
|
|
|
|
|
<span className="tool-btn-label">Degrupp.</span>
|
|
|
|
|
<span className="tool-btn-kbd">Strg+G</span>
|
|
|
|
|
</button>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
2026-06-26 10:50:24 +02:00
|
|
|
{activeTool === 'seating-template' && onTemplateSelect && (
|
|
|
|
|
<div className="tool-section" key="templates">
|
2026-07-04 16:43:55 +02:00
|
|
|
{renderSectionLabel("Vorlagen", "templates")}
|
2026-06-26 10:50:24 +02:00
|
|
|
<select
|
|
|
|
|
className="template-dropdown"
|
|
|
|
|
value={selectedTemplate ?? ''}
|
|
|
|
|
onChange={(e) => onTemplateSelect(e.target.value || null)}
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
padding: '6px 8px',
|
|
|
|
|
borderRadius: '4px',
|
|
|
|
|
border: '1px solid var(--color-border)',
|
|
|
|
|
background: 'var(--color-bg-secondary)',
|
|
|
|
|
color: 'var(--color-text)',
|
|
|
|
|
fontSize: '13px',
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<option value="">— Vorlage wählen —</option>
|
|
|
|
|
{SEATING_TEMPLATES.map((t) => (
|
|
|
|
|
<option key={t.name} value={t.name}>
|
|
|
|
|
{t.name} ({t.description})
|
|
|
|
|
</option>
|
|
|
|
|
))}
|
|
|
|
|
</select>
|
|
|
|
|
{selectedTemplate && (
|
|
|
|
|
<div style={{ marginTop: '6px', fontSize: '12px', color: 'var(--color-text-faint)' }}>
|
|
|
|
|
Klicken Sie auf die Zeichenfläche, um die Vorlage zu platzieren.
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-07-04 16:43:55 +02:00
|
|
|
</div>
|
2026-06-26 10:50:24 +02:00
|
|
|
|
2026-07-04 16:43:55 +02:00
|
|
|
<div className="leftbar-resize-handle" onMouseDown={handleResizeMouseDown} />
|
2026-07-04 16:08:51 +02:00
|
|
|
|
2026-06-26 10:50:24 +02:00
|
|
|
</aside>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default LeftSidebar;
|