Layout 100%, Notificações, SetupWizard
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
:style="{ width: '1000px', maxWidth: '96vw' }"
|
||||
:breakpoints="{ '960px': '96vw', '640px': '98vw' }"
|
||||
class="agenda-event-composer"
|
||||
pt:mask:class="backdrop-blur-xs"
|
||||
>
|
||||
<template #header>
|
||||
<div class="w-full flex items-center justify-between gap-3">
|
||||
@@ -24,47 +25,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 shrink-0">
|
||||
<Button
|
||||
v-if="step === 2 && !isEdit && allowBack"
|
||||
label="Voltar"
|
||||
icon="pi pi-arrow-left"
|
||||
severity="secondary"
|
||||
outlined
|
||||
size="small"
|
||||
class="rounded-full"
|
||||
@click="goBack"
|
||||
/>
|
||||
<Button
|
||||
v-if="step === 2 && isEdit && hasSerie"
|
||||
label="Encerrar série"
|
||||
icon="pi pi-trash"
|
||||
severity="danger"
|
||||
outlined
|
||||
size="small"
|
||||
class="rounded-full text-xs h-8"
|
||||
@click="onEncerrarSerie"
|
||||
/>
|
||||
<Button
|
||||
v-if="step === 2 && isEdit && !hasSerie"
|
||||
icon="pi pi-trash"
|
||||
severity="danger"
|
||||
outlined
|
||||
size="small"
|
||||
class="rounded-full h-9 w-9"
|
||||
v-tooltip.bottom="'Remover'"
|
||||
@click="onDelete"
|
||||
/>
|
||||
<Button
|
||||
v-if="step === 2"
|
||||
label="Salvar"
|
||||
icon="pi pi-check"
|
||||
size="small"
|
||||
class="rounded-full"
|
||||
:disabled="!canSave"
|
||||
@click="onSave"
|
||||
/>
|
||||
</div>
|
||||
<!-- actions moved to footer -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -924,7 +885,7 @@
|
||||
:style="{ width: '560px', maxWidth: '96vw' }"
|
||||
:breakpoints="{ '640px': '98vw' }"
|
||||
>
|
||||
<div class="flex flex-col gap-4 p-1">
|
||||
<div class="flex flex-col gap-4">
|
||||
<!-- Data -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-2">Data</label>
|
||||
@@ -1060,6 +1021,53 @@
|
||||
</template>
|
||||
</Dialog>
|
||||
|
||||
|
||||
<!-- Footer -->
|
||||
<template v-if="step === 2" #footer>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
v-if="!isEdit && allowBack"
|
||||
label="Voltar"
|
||||
icon="pi pi-arrow-left"
|
||||
severity="secondary"
|
||||
outlined
|
||||
size="small"
|
||||
class="rounded-full"
|
||||
@click="goBack"
|
||||
/>
|
||||
<Button
|
||||
v-if="isEdit && hasSerie"
|
||||
label="Encerrar série"
|
||||
icon="pi pi-trash"
|
||||
severity="danger"
|
||||
outlined
|
||||
size="small"
|
||||
class="rounded-full text-xs h-8"
|
||||
@click="onEncerrarSerie"
|
||||
/>
|
||||
<Button
|
||||
v-if="isEdit && !hasSerie"
|
||||
icon="pi pi-trash"
|
||||
severity="danger"
|
||||
outlined
|
||||
size="small"
|
||||
class="rounded-full h-9 w-9"
|
||||
v-tooltip.bottom="'Remover'"
|
||||
@click="onDelete"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
label="Salvar"
|
||||
icon="pi pi-check"
|
||||
size="small"
|
||||
class="rounded-full"
|
||||
:disabled="!canSave"
|
||||
@click="onSave"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- ══════════════════════════════════════════════ -->
|
||||
<!-- Cadastro Rápido de Paciente -->
|
||||
<!-- ══════════════════════════════════════════════ -->
|
||||
@@ -2662,7 +2670,7 @@ function statusSeverity (v) {
|
||||
.commitment-card {
|
||||
width: 100%; text-align: left;
|
||||
border: 1px solid var(--surface-border);
|
||||
border-radius: 1.25rem;
|
||||
border-radius: 6px;
|
||||
background: color-mix(in srgb, var(--surface-card), transparent 10%);
|
||||
transition: box-shadow .12s ease, transform .12s ease, border-color .12s;
|
||||
overflow: hidden;
|
||||
@@ -2704,7 +2712,7 @@ function statusSeverity (v) {
|
||||
/* ── paciente hero ──────────────────────────────── */
|
||||
.patient-hero {
|
||||
border: 1.5px solid var(--surface-border);
|
||||
border-radius: 1.25rem;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: color-mix(in srgb, var(--surface-card), transparent 10%);
|
||||
}
|
||||
@@ -2736,7 +2744,7 @@ function statusSeverity (v) {
|
||||
|
||||
/* Card genérico para seções (data/horário, etc.) */
|
||||
.field-card {
|
||||
border-radius: 1rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--surface-border);
|
||||
background: var(--surface-card);
|
||||
overflow: hidden;
|
||||
@@ -2848,7 +2856,7 @@ function statusSeverity (v) {
|
||||
}
|
||||
.side-card {
|
||||
border: 1px solid var(--surface-border);
|
||||
border-radius: 1.25rem;
|
||||
border-radius: 6px;
|
||||
padding: .9rem 1rem;
|
||||
background: color-mix(in srgb, var(--surface-card), transparent 10%);
|
||||
}
|
||||
@@ -2879,7 +2887,7 @@ function statusSeverity (v) {
|
||||
|
||||
/* ── serie banner ───────────────────────────────── */
|
||||
.serie-banner {
|
||||
border-radius: 1rem;
|
||||
border-radius: 6px;
|
||||
padding: .75rem .9rem;
|
||||
background: color-mix(in srgb, var(--blue-500, #3b82f6) 8%, var(--surface-card));
|
||||
border: 1px solid color-mix(in srgb, var(--blue-400, #60a5fa) 30%, transparent);
|
||||
@@ -2922,7 +2930,7 @@ function statusSeverity (v) {
|
||||
.recorrencia-preview {
|
||||
display: flex; align-items: center; gap: .5rem;
|
||||
padding: .5rem .75rem;
|
||||
border-radius: .75rem;
|
||||
border-radius: 6px;
|
||||
background: color-mix(in srgb, var(--p-primary-500) 8%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--p-primary-400) 25%, transparent);
|
||||
}
|
||||
@@ -2994,7 +3002,7 @@ function statusSeverity (v) {
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 16px;
|
||||
border-radius: 0.75rem;
|
||||
border-radius: 6px;
|
||||
background: color-mix(in srgb, var(--primary-500, #6366f1) 8%, var(--surface-card));
|
||||
border: 1px solid color-mix(in srgb, var(--primary-400, #818cf8) 25%, transparent);
|
||||
}
|
||||
@@ -3125,7 +3133,7 @@ function statusSeverity (v) {
|
||||
.rec-startdate-row {
|
||||
display: flex; align-items: center; justify-content: space-between; gap: .5rem;
|
||||
padding: .45rem .65rem;
|
||||
border-radius: .75rem;
|
||||
border-radius: 6px;
|
||||
background: color-mix(in srgb, var(--surface-ground), transparent 30%);
|
||||
border: 1px solid var(--surface-border);
|
||||
}
|
||||
@@ -3177,7 +3185,7 @@ function statusSeverity (v) {
|
||||
/* ── personalizar box ───────────────────────────── */
|
||||
.personalizar-box {
|
||||
border: 1px solid var(--surface-border);
|
||||
border-radius: .85rem;
|
||||
border-radius: 6px;
|
||||
padding: .75rem;
|
||||
background: color-mix(in srgb, var(--surface-ground), transparent 40%);
|
||||
display: flex;
|
||||
@@ -3190,7 +3198,7 @@ function statusSeverity (v) {
|
||||
.patient-item {
|
||||
width: 100%; display: flex; align-items: center; justify-content: space-between;
|
||||
gap: 1rem; text-align: left; padding: .85rem .95rem;
|
||||
border: 1px solid var(--surface-border); border-radius: 1.25rem;
|
||||
border: 1px solid var(--surface-border); border-radius: 6px;
|
||||
background: color-mix(in srgb, var(--surface-card), transparent 10%);
|
||||
transition: box-shadow .12s ease, transform .12s ease;
|
||||
}
|
||||
@@ -3199,7 +3207,7 @@ function statusSeverity (v) {
|
||||
/* ── serie panel (Recorrências Aplicadas) ─────────── */
|
||||
.serie-panel {
|
||||
border: 1px solid var(--surface-border);
|
||||
border-radius: 1.1rem;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.serie-panel__header {
|
||||
@@ -3273,7 +3281,7 @@ function statusSeverity (v) {
|
||||
flex-direction: column;
|
||||
gap: .35rem;
|
||||
border: 1px solid var(--surface-border);
|
||||
border-radius: .5rem;
|
||||
border-radius: 6px;
|
||||
padding: .5rem;
|
||||
}
|
||||
.commitment-item-row {
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
:closable="!saving"
|
||||
:dismissableMask="!saving"
|
||||
class="dc-dialog w-[96vw] max-w-2xl"
|
||||
:pt="{ content: { class: 'p-0' }, header: { class: 'pb-0' } }"
|
||||
:pt="{ content: { class: 'p-0' }, header: { class: 'pb-0' }, footer: { class: 'pt-0' } }"
|
||||
pt:mask:class="backdrop-blur-xs"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex w-full items-center justify-between gap-3 px-1">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<!-- Dot de cor -->
|
||||
<span
|
||||
class="dc-header-dot shrink-0"
|
||||
class="shrink-0 w-3.5 h-3.5 rounded-full border-2 border-white/30 shadow-[0_0_0_3px_rgba(0,0,0,0.08)] transition-colors duration-200"
|
||||
:style="{ backgroundColor: previewBgColor }"
|
||||
/>
|
||||
<div class="min-w-0">
|
||||
@@ -37,33 +38,17 @@
|
||||
v-tooltip.top="'Excluir'"
|
||||
@click="emitDelete"
|
||||
/>
|
||||
<Button
|
||||
label="Cancelar"
|
||||
severity="secondary"
|
||||
outlined
|
||||
class="rounded-full"
|
||||
:disabled="saving"
|
||||
@click="close"
|
||||
/>
|
||||
<Button
|
||||
label="Salvar"
|
||||
icon="pi pi-check"
|
||||
class="rounded-full"
|
||||
:loading="saving"
|
||||
:disabled="!canSubmit"
|
||||
@click="submit"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Banner de preview -->
|
||||
<div
|
||||
class="dc-banner"
|
||||
class="h-[72px] flex items-center justify-center transition-colors duration-[250ms] rounded-[6px]"
|
||||
:style="{ backgroundColor: previewBgColor }"
|
||||
>
|
||||
<span
|
||||
class="dc-banner__pill"
|
||||
class="text-base font-bold tracking-[-0.02em] px-[1.1rem] py-[0.35rem] bg-black/15 rounded-full backdrop-blur-sm transition-colors duration-200"
|
||||
:style="{ color: form.text_color || '#ffffff' }"
|
||||
>
|
||||
{{ form.name || 'Nome do compromisso' }}
|
||||
@@ -71,7 +56,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Corpo -->
|
||||
<div class="flex flex-col gap-4 p-4">
|
||||
<div class="flex flex-col gap-4 mt-4">
|
||||
|
||||
<!-- Nome + Ativo -->
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -91,68 +76,15 @@
|
||||
<label for="cr-nome">Nome *</label>
|
||||
</FloatLabel>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 shrink-0 pt-1">
|
||||
|
||||
<!-- Toggle Ativo -->
|
||||
<div class="shrink-0 flex items-center gap-2">
|
||||
<span class="text-sm font-medium">Ativo</span>
|
||||
<InputSwitch v-model="form.active" :disabled="saving || isActiveLocked" />
|
||||
<ToggleSwitch v-model="form.active" :disabled="saving || isActiveLocked" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Seção Cor -->
|
||||
<div class="dc-section">
|
||||
<div class="dc-section__label">Cor</div>
|
||||
|
||||
<!-- Paleta predefinida -->
|
||||
<div class="dc-palette">
|
||||
<button
|
||||
v-for="p in presetColors"
|
||||
:key="p.bg"
|
||||
class="dc-swatch"
|
||||
:class="{ 'dc-swatch--active': form.bg_color === p.bg }"
|
||||
:style="{ backgroundColor: `#${p.bg}` }"
|
||||
:title="p.name"
|
||||
:disabled="saving || isEditLocked"
|
||||
@click="applyPreset(p)"
|
||||
>
|
||||
<i v-if="form.bg_color === p.bg" class="pi pi-check dc-swatch__check" />
|
||||
</button>
|
||||
|
||||
<!-- Custom ColorPicker -->
|
||||
<div class="dc-swatch dc-swatch--custom" title="Cor personalizada">
|
||||
<ColorPicker
|
||||
v-model="form.bg_color"
|
||||
format="hex"
|
||||
:disabled="saving || isEditLocked"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Texto -->
|
||||
<div class="flex items-center gap-3 mt-2">
|
||||
<span class="text-xs font-medium opacity-60 uppercase tracking-wide">Texto</span>
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
class="dc-text-opt"
|
||||
:class="{ 'dc-text-opt--active': form.text_color === '#ffffff' }"
|
||||
:disabled="saving || isEditLocked"
|
||||
@click="form.text_color = '#ffffff'"
|
||||
>
|
||||
<span class="dc-text-opt__dot" style="background:#ffffff; border: 1px solid #ccc;" />
|
||||
Branco
|
||||
</button>
|
||||
<button
|
||||
class="dc-text-opt"
|
||||
:class="{ 'dc-text-opt--active': form.text_color === '#000000' }"
|
||||
:disabled="saving || isEditLocked"
|
||||
@click="form.text_color = '#000000'"
|
||||
>
|
||||
<span class="dc-text-opt__dot" style="background:#000000;" />
|
||||
Preto
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Descrição -->
|
||||
|
||||
<!-- Descrição -->
|
||||
<FloatLabel variant="on">
|
||||
<Textarea
|
||||
id="cr-descricao"
|
||||
@@ -166,10 +98,83 @@
|
||||
<label for="cr-descricao">Descrição</label>
|
||||
</FloatLabel>
|
||||
|
||||
<!-- Seção Cor -->
|
||||
<div class="border border-[var(--surface-border)] rounded-[6px] bg-[var(--surface-card)] p-4">
|
||||
<div class="text-[1rem] font-bold uppercase tracking-[0.06em] opacity-45 mb-3">Cor</div>
|
||||
|
||||
<!-- Paleta predefinida -->
|
||||
<div class="flex flex-wrap gap-[0.45rem]">
|
||||
<button
|
||||
v-for="p in presetColors"
|
||||
:key="p.bg"
|
||||
class="w-7 h-7 rounded-full grid place-items-center cursor-pointer relative transition-transform duration-[120ms] ease-in-out hover:scale-[1.18] hover:shadow-[0_3px_10px_rgba(0,0,0,0.2)] disabled:cursor-not-allowed"
|
||||
:class="form.bg_color === p.bg ? 'shadow-[0_0_0_2px_var(--text-color)] border-2 border-[var(--surface-0,#fff)]' : 'border-0'"
|
||||
:style="{ backgroundColor: `#${p.bg}` }"
|
||||
:title="p.name"
|
||||
:disabled="saving || isEditLocked"
|
||||
@click="applyPreset(p)"
|
||||
>
|
||||
<i v-if="form.bg_color === p.bg" class="pi pi-check !text-[13px] text-white font-black p-1" />
|
||||
</button>
|
||||
|
||||
<!-- Custom ColorPicker -->
|
||||
<div
|
||||
class="w-7 h-7 rounded-full grid place-items-center cursor-pointer overflow-hidden relative transition-transform duration-[120ms] ease-in-out hover:scale-[1.18] hover:shadow-[0_3px_10px_rgba(0,0,0,0.2)]"
|
||||
:class="isCustomColor ? 'shadow-[0_0_0_2px_var(--text-color)]' : ''"
|
||||
style="background: conic-gradient(red, yellow, lime, cyan, blue, magenta, red);"
|
||||
title="Cor personalizada"
|
||||
>
|
||||
<i
|
||||
v-if="isCustomColor"
|
||||
class="pi pi-check !text-[13px] text-white font-black absolute z-10 pointer-events-none drop-shadow-[0_1px_2px_rgba(0,0,0,0.6)]"
|
||||
/>
|
||||
<ColorPicker
|
||||
v-model="form.bg_color"
|
||||
format="hex"
|
||||
:disabled="saving || isEditLocked"
|
||||
class="absolute inset-0 [&_.p-colorpicker-preview]:w-full [&_.p-colorpicker-preview]:h-full [&_.p-colorpicker-preview]:border-0 [&_.p-colorpicker-preview]:rounded-full [&_.p-colorpicker-preview]:opacity-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Texto -->
|
||||
<div class="flex items-center gap-3 mt-2">
|
||||
<span class="text-xs font-medium opacity-60 uppercase tracking-wide">Texto</span>
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
class="inline-flex items-center gap-[0.4rem] px-3 py-1 rounded-full border text-sm font-medium cursor-pointer transition-colors duration-[120ms] disabled:cursor-not-allowed"
|
||||
:class="
|
||||
form.text_color === '#ffffff'
|
||||
? 'bg-[var(--surface-section,var(--surface-100))] border-[var(--primary-color)] text-[var(--primary-color)] font-bold'
|
||||
: 'bg-transparent border-[var(--surface-border)] text-[var(--text-color)] hover:bg-[var(--surface-hover)]'
|
||||
"
|
||||
:disabled="saving || isEditLocked"
|
||||
@click="form.text_color = '#ffffff'"
|
||||
>
|
||||
<span class="w-2.5 h-2.5 rounded-full inline-block border border-[#ccc]" style="background:#ffffff;" />
|
||||
Branco
|
||||
</button>
|
||||
<button
|
||||
class="inline-flex items-center gap-[0.4rem] px-3 py-1 rounded-full border text-sm font-medium cursor-pointer transition-colors duration-[120ms] disabled:cursor-not-allowed"
|
||||
:class="
|
||||
form.text_color === '#000000'
|
||||
? 'bg-[var(--surface-section,var(--surface-100))] border-[var(--primary-color)] text-[var(--primary-color)] font-bold'
|
||||
: 'bg-transparent border-[var(--surface-border)] text-[var(--text-color)] hover:bg-[var(--surface-hover)]'
|
||||
"
|
||||
:disabled="saving || isEditLocked"
|
||||
@click="form.text_color = '#000000'"
|
||||
>
|
||||
<span class="w-2.5 h-2.5 rounded-full inline-block" style="background:#000000;" />
|
||||
Preto
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Campos adicionais -->
|
||||
<div class="dc-section">
|
||||
<div class="border border-[var(--surface-border)] rounded-[6px] bg-[var(--surface-card)] p-4">
|
||||
<div class="flex items-center justify-between gap-2 mb-3">
|
||||
<div class="dc-section__label mb-0">Campos adicionais</div>
|
||||
<div class="text-[1rem] font-bold uppercase tracking-[0.06em] opacity-45">Campos adicionais</div>
|
||||
<Button
|
||||
label="Adicionar campo"
|
||||
icon="pi pi-plus"
|
||||
@@ -190,7 +195,7 @@
|
||||
<div
|
||||
v-for="(f, idx) in form.fields"
|
||||
:key="f.key"
|
||||
class="grid grid-cols-1 gap-2 rounded-2xl border border-[var(--surface-border)] bg-[var(--surface-0)] p-3 md:grid-cols-12"
|
||||
class="grid grid-cols-1 gap-2 rounded-[6px] border border-[var(--surface-border)] bg-[var(--surface-0)] p-3 md:grid-cols-12"
|
||||
>
|
||||
<div class="md:col-span-6">
|
||||
<FloatLabel variant="on">
|
||||
@@ -233,14 +238,32 @@
|
||||
@click="removeField(idx)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-12 text-xs opacity-40 font-mono">
|
||||
key: {{ f.key }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer com botões Cancelar / Salvar -->
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-end gap-2 pt-2">
|
||||
<Button
|
||||
label="Cancelar"
|
||||
severity="secondary"
|
||||
outlined
|
||||
class="rounded-full"
|
||||
:disabled="saving"
|
||||
@click="close"
|
||||
/>
|
||||
<Button
|
||||
label="Salvar"
|
||||
icon="pi pi-check"
|
||||
class="rounded-full"
|
||||
:loading="saving"
|
||||
:disabled="!canSubmit"
|
||||
@click="submit"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
@@ -249,8 +272,9 @@ import { computed, reactive, watch } from 'vue'
|
||||
|
||||
import Textarea from 'primevue/textarea'
|
||||
import Dropdown from 'primevue/dropdown'
|
||||
import InputSwitch from 'primevue/inputswitch'
|
||||
import ColorPicker from 'primevue/colorpicker'
|
||||
import ToggleSwitch from 'primevue/toggleswitch'
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: Boolean, default: false },
|
||||
@@ -281,6 +305,16 @@ const presetColors = [
|
||||
{ bg: '292524', text: '#ffffff', name: 'Escuro' },
|
||||
]
|
||||
|
||||
// bg_colors dos presets (sem #) para comparação
|
||||
const presetBgValues = presetColors.map(p => p.bg)
|
||||
|
||||
// Verdadeiro quando a cor atual não bate com nenhum preset
|
||||
const isCustomColor = computed(() => {
|
||||
if (!form.bg_color) return false
|
||||
const clean = String(form.bg_color).replace('#', '').toLowerCase()
|
||||
return !presetBgValues.includes(clean)
|
||||
})
|
||||
|
||||
function applyPreset (p) {
|
||||
if (props.saving) return
|
||||
form.bg_color = p.bg
|
||||
@@ -350,9 +384,9 @@ function hydrate () {
|
||||
}
|
||||
}
|
||||
|
||||
const isActiveLocked = computed(() => !!form.locked) // nativo+locked → sempre ativo, nunca pode desativar
|
||||
const isEditLocked = computed(() => false) // edição sempre permitida
|
||||
const isFieldsLocked = computed(() => false) // campos sempre editáveis
|
||||
const isActiveLocked = computed(() => !!form.locked)
|
||||
const isEditLocked = computed(() => false)
|
||||
const isFieldsLocked = computed(() => false)
|
||||
const canDelete = computed(() => !form.native)
|
||||
|
||||
const canSubmit = computed(() => {
|
||||
@@ -408,13 +442,11 @@ function removeField (idx) {
|
||||
}
|
||||
|
||||
function syncKey (field) {
|
||||
// se o user renomear, a key acompanha (sem quebrar: simples por enquanto)
|
||||
const next = makeKey(field.label)
|
||||
field.key = next
|
||||
}
|
||||
|
||||
function makeKey (label) {
|
||||
|
||||
const k = String(label || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
@@ -424,100 +456,4 @@ function makeKey (label) {
|
||||
.replace(/(^_|_$)/g, '') || `field_${Math.random().toString(16).slice(2, 8)}`
|
||||
return k
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* ── Header ─────────────────────────────── */
|
||||
.dc-header-dot {
|
||||
width: 14px; height: 14px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid rgba(255,255,255,0.3);
|
||||
box-shadow: 0 0 0 3px rgba(0,0,0,0.08);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
/* ── Banner de preview ───────────────────── */
|
||||
.dc-banner {
|
||||
height: 72px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: background-color 0.25s ease;
|
||||
}
|
||||
.dc-banner__pill {
|
||||
font-size: 1rem; font-weight: 700; letter-spacing: -0.02em;
|
||||
padding: 0.35rem 1.1rem;
|
||||
background: rgba(0,0,0,0.15);
|
||||
border-radius: 999px;
|
||||
backdrop-filter: blur(4px);
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
/* ── Section ─────────────────────────────── */
|
||||
.dc-section {
|
||||
border: 1px solid var(--surface-border);
|
||||
border-radius: 1.25rem;
|
||||
background: var(--surface-card);
|
||||
padding: 1rem;
|
||||
}
|
||||
.dc-section__label {
|
||||
font-size: 0.7rem; font-weight: 700;
|
||||
text-transform: uppercase; letter-spacing: 0.06em;
|
||||
opacity: 0.45; margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
/* ── Paleta ──────────────────────────────── */
|
||||
.dc-palette {
|
||||
display: flex; flex-wrap: wrap; gap: 0.45rem;
|
||||
}
|
||||
.dc-swatch {
|
||||
width: 28px; height: 28px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid transparent;
|
||||
display: grid; place-items: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
|
||||
position: relative;
|
||||
}
|
||||
.dc-swatch:hover:not(:disabled) {
|
||||
transform: scale(1.18);
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,0.2);
|
||||
}
|
||||
.dc-swatch--active {
|
||||
border-color: var(--surface-0, #fff);
|
||||
box-shadow: 0 0 0 2px var(--text-color);
|
||||
}
|
||||
.dc-swatch__check {
|
||||
font-size: 0.6rem; color: #fff; font-weight: 900;
|
||||
}
|
||||
.dc-swatch--custom {
|
||||
background: conic-gradient(red, yellow, lime, cyan, blue, magenta, red);
|
||||
overflow: hidden;
|
||||
}
|
||||
.dc-swatch--custom :deep(.p-colorpicker-preview) {
|
||||
width: 100%; height: 100%;
|
||||
border: none; border-radius: 50%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* ── Texto toggle ────────────────────────── */
|
||||
.dc-text-opt {
|
||||
display: inline-flex; align-items: center; gap: 0.4rem;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--surface-border);
|
||||
font-size: 0.8rem; font-weight: 500;
|
||||
cursor: pointer;
|
||||
color: var(--text-color);
|
||||
background: transparent;
|
||||
transition: background 0.12s, border-color 0.12s;
|
||||
}
|
||||
.dc-text-opt:hover:not(:disabled) { background: var(--surface-hover); }
|
||||
.dc-text-opt--active {
|
||||
background: var(--surface-section, var(--surface-100));
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
font-weight: 700;
|
||||
}
|
||||
.dc-text-opt__dot {
|
||||
width: 10px; height: 10px; border-radius: 50%; display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</script>
|
||||
Reference in New Issue
Block a user