knxdisplay/web-interface/src/components/SidebarLeft.vue
2026-01-30 17:14:50 +01:00

100 lines
5.7 KiB
Vue

<template>
<aside class="h-full overflow-y-auto p-[18px] flex flex-col gap-4 border-r border-border max-[1100px]:border-r-0 max-[1100px]:border-b">
<section class="bg-gradient-to-b from-white to-[#f6f9fc] border border-border rounded-[14px] p-3.5 shadow-[0_10px_24px_rgba(15,23,42,0.12)]">
<div class="flex items-center justify-between gap-2.5 mb-3">
<h3 class="text-[12px] uppercase tracking-[0.08em] text-[#3a5f88]">Elemente</h3>
<span class="text-[11px] text-muted">Klick zum Hinzufuegen</span>
</div>
<div class="grid grid-cols-2 gap-2.5">
<button class="bg-panel-2 border border-border rounded-xl p-2.5 text-left transition hover:-translate-y-0.5 hover:border-accent" @click="store.addWidget('label')">
<span class="text-[13px] font-semibold">Label</span>
<span class="text-[11px] text-muted mt-0.5 block">Text</span>
</button>
<button class="bg-panel-2 border border-border rounded-xl p-2.5 text-left transition hover:-translate-y-0.5 hover:border-accent" @click="store.addWidget('button')">
<span class="text-[13px] font-semibold">Button</span>
<span class="text-[11px] text-muted mt-0.5 block">Aktion</span>
</button>
<button :class="btnClass" @click="store.addWidget('led')">
<span class="material-symbols-outlined text-[24px]">light_mode</span>
<span class="text-[10px]">LED</span>
</button>
<button :class="btnClass" @click="store.addWidget('clock')">
<span class="material-symbols-outlined text-[24px]">schedule</span>
<span class="text-[10px]">Uhr</span>
</button>
<button :class="btnClass" @click="store.addWidget('icon')">
<span class="material-symbols-outlined text-[24px]">image</span>
<span class="text-[10px]">Icon</span>
</button>
<button class="bg-panel-2 border border-border rounded-xl p-2.5 text-left transition hover:-translate-y-0.5 hover:border-accent" @click="store.addWidget('tabview')">
<span class="text-[13px] font-semibold">Tabs</span>
<span class="text-[11px] text-muted mt-0.5 block">Container</span>
</button>
<button class="bg-panel-2 border border-border rounded-xl p-2.5 text-left transition hover:-translate-y-0.5 hover:border-accent" @click="store.addWidget('powerflow')">
<span class="text-[13px] font-semibold">Power Flow</span>
<span class="text-[11px] text-muted mt-0.5 block">Card</span>
</button>
<button class="bg-panel-2 border border-border rounded-xl p-2.5 text-left transition hover:-translate-y-0.5 hover:border-accent" @click="store.addWidget('powernode')">
<span class="text-[13px] font-semibold">Power Node</span>
<span class="text-[11px] text-muted mt-0.5 block">Element</span>
</button>
<button class="bg-panel-2 border border-border rounded-xl p-2.5 text-left transition hover:-translate-y-0.5 hover:border-accent" @click="store.addWidget('chart')">
<span class="text-[13px] font-semibold">Chart</span>
<span class="text-[11px] text-muted mt-0.5 block">Verlauf</span>
</button>
</div>
</section>
<section class="bg-gradient-to-b from-white to-[#f6f9fc] border border-border rounded-[14px] p-3.5 shadow-[0_10px_24px_rgba(15,23,42,0.12)]">
<div class="flex items-center justify-between gap-2.5 mb-3">
<h3 class="text-[12px] uppercase tracking-[0.08em] text-[#3a5f88]">Baum</h3>
<span class="text-[11px] text-muted">{{ store.activeScreen?.widgets.length || 0 }}</span>
</div>
<div class="flex flex-col gap-2">
<div class="text-[12px] text-muted mb-1">{{ store.activeScreen?.name }}</div>
<div class="flex flex-col gap-1.5">
<div v-if="!store.widgetTree.length" class="text-[12px] text-muted py-1.5">Keine Widgets</div>
<TreeItem
v-else
v-for="node in store.widgetTree"
:key="node.id"
:node="node"
/>
</div>
</div>
</section>
<section class="bg-gradient-to-b from-white to-[#f6f9fc] border border-border rounded-[14px] p-3.5 shadow-[0_10px_24px_rgba(15,23,42,0.12)]">
<div class="flex items-center justify-between gap-2.5 mb-3">
<h3 class="text-[12px] uppercase tracking-[0.08em] text-[#3a5f88]">Canvas</h3>
</div>
<div class="flex items-center justify-between gap-2.5 mb-2.5">
<label class="text-[12px] text-muted">Zoom</label>
<input class="flex-1 accent-[var(--accent)]" type="range" min="0.3" max="1" step="0.05" v-model.number="store.canvasScale">
</div>
<div class="flex items-center justify-between text-[11px] text-muted mb-2">
<span>{{ Math.round(store.canvasScale * 100) }}%</span>
<span>1280x800</span>
</div>
<label class="flex items-center gap-2 text-[12px] text-muted">
<input class="accent-[var(--accent)]" type="checkbox" v-model="store.showGrid">
<span>Grid anzeigen</span>
</label>
<div class="flex items-center justify-between gap-2.5 mt-2 mb-2.5">
<label class="text-[12px] text-muted">Grid Gr.</label>
<input class="flex-1 bg-panel-2 border border-border rounded-lg px-2 py-1.5 text-text text-[12px] focus:outline-none focus:border-accent" type="number" min="5" max="100" v-model.number="store.gridSize">
</div>
<label class="flex items-center gap-2 text-[12px] text-muted">
<input class="accent-[var(--accent)]" type="checkbox" v-model="store.snapToGrid">
<span>Am Grid ausrichten</span>
</label>
</section>
</aside>
</template>
<script setup>
import { useEditorStore } from '../stores/editor';
import TreeItem from './TreeItem.vue';
const store = useEditorStore();
</script>