Files
BetiX/resources/js/components/AppearanceTabs.vue
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

97 lines
4.2 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { ref, watch } from 'vue';
import { usePrimaryColor } from '@/composables/usePrimaryColor';
const active = ref<'appearance'|'theme'|'layout'>('appearance');
// Accent color state using global composable
const { primaryColor, updatePrimaryColor } = usePrimaryColor();
// Local hex input model to allow free typing without instantly rejecting partial values
const hexInput = ref<string>(primaryColor.value || '#ff007a');
watch(primaryColor, (val) => {
if (val && val.toLowerCase() !== hexInput.value.toLowerCase()) {
hexInput.value = val;
}
});
function onPickColor(e: Event) {
const value = (e.target as HTMLInputElement).value;
hexInput.value = value;
updatePrimaryColor(value);
}
function onHexInput(e: Event) {
const value = (e.target as HTMLInputElement).value.trim();
hexInput.value = value;
}
function applyHex() {
// Accept #RGB or #RRGGBB; auto-add leading # if missing
let v = hexInput.value.trim();
if (!v.startsWith('#')) v = `#${v}`;
const isValid = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v);
if (isValid) {
hexInput.value = v.toLowerCase();
updatePrimaryColor(hexInput.value);
}
}
function resetToDefault() {
const def = '#ff007a';
hexInput.value = def;
updatePrimaryColor(def);
}
</script>
<template>
<div class="appearance-tabs">
<div class="tabs">
<button :class="{active: active==='appearance'}" @click="active='appearance'">Appearance</button>
<button :class="{active: active==='theme'}" @click="active='theme'">Theme</button>
<button :class="{active: active==='layout'}" @click="active='layout'">Layout</button>
</div>
<div class="panel">
<div v-if="active==='appearance'" class="section">
<div class="row">
<div class="label"><i data-lucide="palette"></i> Accent color</div>
<div class="controls">
<input class="color" type="color" :value="primaryColor" @input="onPickColor" />
<input class="hex" type="text" v-model="hexInput" @input="onHexInput" placeholder="#ff007a" />
<button class="apply" @click="applyHex">Apply</button>
<button class="reset" @click="resetToDefault">Reset</button>
</div>
</div>
<div class="hint">Tipp: Du kannst entweder den Farbwähler benutzen oder einen HEXWert eingeben (z. B. #00aaff).</div>
<div class="preview">
<div class="swatch" :style="{ background: primaryColor }"></div>
<span class="code">{{ primaryColor }}</span>
</div>
</div>
<p v-else-if="active==='theme'">Theme settings coming soon.</p>
<p v-else>Layout settings coming soon.</p>
</div>
</div>
</template>
<style scoped>
.appearance-tabs { background:#0a0a0a; border:1px solid #151515; border-radius:12px; padding:12px; }
.tabs { display:flex; gap:8px; margin-bottom:10px; }
.tabs button { background:#0a0a0a; border:1px solid #1a1a1a; color:#fff; padding:8px 10px; border-radius:10px; font-size:12px; font-weight:900; cursor:pointer; }
.tabs button.active { background:#121212; border-color:#333; }
.panel { color:#aaa; font-size:12px; }
.section { display:flex; flex-direction:column; gap:10px; }
.row { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.label { display:flex; align-items:center; gap:8px; color:#fff; font-weight:800; font-size:13px; }
.controls { display:flex; align-items:center; gap:8px; }
.color { width: 34px; height: 24px; border:1px solid #222; background:#111; border-radius:6px; padding:0; cursor:pointer; }
.hex { width:120px; background:#0a0a0a; border:1px solid #1a1a1a; color:#fff; padding:6px 8px; border-radius:8px; font-size:12px; font-weight:700; }
.apply, .reset { background:#0a0a0a; border:1px solid #1a1a1a; color:#fff; padding:6px 10px; border-radius:8px; font-size:12px; font-weight:800; cursor:pointer; }
.apply:hover, .reset:hover { border-color:#333; }
.hint { font-size:12px; color:#888; }
.preview { display:flex; align-items:center; gap:10px; }
.swatch { width:28px; height:18px; border-radius:6px; border:1px solid #222; }
.code { font-size:12px; color:#ccc; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; }
</style>