Correcao Sidebar Classico e Rail, Correcao Layout, Ajuste de Breakpoint para Tailwind, Ajuste AppTopbar, Ajuste Menu PopOver, Recriado Paleta de Cores, Inserido algumas animações leves, Reajuste Cor items NOVOS da tabela, Drawer Ajuda Corrigido no Logout, Whatsapp, sms, email, recursos extras

This commit is contained in:
Leonardo
2026-03-24 21:26:58 -03:00
parent a89d1f5560
commit 53a4980396
453 changed files with 121427 additions and 174407 deletions
+138 -160
View File
@@ -15,211 +15,189 @@
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, inject } from 'vue'
import { useLayout } from '@/layout/composables/layout'
import { primaryColors, surfaces, presetOptions, applyThemeEngine } from '@/theme/theme.options'
import { computed, inject } from 'vue';
import { useLayout } from '@/layout/composables/layout';
import { primaryColors, surfaces, presetOptions, applyThemeEngine } from '@/theme/theme.options';
const { layoutConfig, isDarkTheme, changeMenuMode, setVariant } = useLayout()
const { layoutConfig, isDarkTheme, changeMenuMode, setVariant } = useLayout();
// ✅ vem do AppTopbar (mesma instância)
const queuePatch = inject('queueUserSettingsPatch', null)
const queuePatch = inject('queueUserSettingsPatch', null);
// menu mode options
const menuModeOptions = [
{ label: 'Static', value: 'static' },
{ label: 'Overlay', value: 'overlay' }
]
{ label: 'Static', value: 'static' },
{ label: 'Overlay', value: 'overlay' }
];
// ✅ v-model sincronizado (sem state local)
const presetModel = computed({
get: () => layoutConfig.preset,
set: (val) => {
if (!val || val === layoutConfig.preset) return
layoutConfig.preset = val
get: () => layoutConfig.preset,
set: (val) => {
if (!val || val === layoutConfig.preset) return;
layoutConfig.preset = val;
applyThemeEngine(layoutConfig)
queuePatch?.({ preset: val })
}
})
applyThemeEngine(layoutConfig);
queuePatch?.({ preset: val });
}
});
const menuModeModel = computed({
get: () => layoutConfig.menuMode,
set: (val) => {
if (!val || val === layoutConfig.menuMode) return
layoutConfig.menuMode = val
get: () => layoutConfig.menuMode,
set: (val) => {
if (!val || val === layoutConfig.menuMode) return;
layoutConfig.menuMode = val;
// ✅ changeMenuMode espera event.value (seu composable usa event.value)
try { changeMenuMode({ value: val }) } catch {}
// ✅ changeMenuMode espera event.value (seu composable usa event.value)
try {
changeMenuMode({ value: val });
} catch {}
queuePatch?.({ menu_mode: val })
}
})
queuePatch?.({ menu_mode: val });
}
});
function updateColors (type, item) {
if (type === 'primary') {
layoutConfig.primary = item.name
applyThemeEngine(layoutConfig)
queuePatch?.({ primary_color: item.name })
return
}
function updateColors(type, item) {
if (type === 'primary') {
layoutConfig.primary = item.name;
applyThemeEngine(layoutConfig);
queuePatch?.({ primary_color: item.name });
return;
}
if (type === 'surface') {
layoutConfig.surface = item.name
applyThemeEngine(layoutConfig)
queuePatch?.({ surface_color: item.name })
}
if (type === 'surface') {
layoutConfig.surface = item.name;
applyThemeEngine(layoutConfig);
queuePatch?.({ surface_color: item.name });
}
}
</script>
<template>
<div
class="config-panel hidden absolute top-[3.25rem] right-0 w-64 p-4 bg-surface-0 dark:bg-surface-900 border border-surface rounded-border origin-top shadow-[0px_3px_5px_rgba(0,0,0,0.02),0px_0px_2px_rgba(0,0,0,0.05),0px_1px_4px_rgba(0,0,0,0.08)]"
>
<div class="flex flex-col gap-4">
<div>
<span class="text-sm text-muted-color font-semibold">Primary</span>
<div class="pt-2 flex gap-2 flex-wrap justify-between">
<button
v-for="c of primaryColors"
:key="c.name"
type="button"
:title="c.name"
@click="updateColors('primary', c)"
:class="[
'border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1',
{ 'outline-primary': layoutConfig.primary === c.name }
]"
:style="{ backgroundColor: `${c.name === 'noir' ? 'var(--text-color)' : c.palette['500']}` }"
/>
<div
class="config-panel hidden absolute top-[3.25rem] right-0 w-64 p-4 bg-surface-0 dark:bg-surface-900 border border-surface rounded-border origin-top shadow-[0px_3px_5px_rgba(0,0,0,0.02),0px_0px_2px_rgba(0,0,0,0.05),0px_1px_4px_rgba(0,0,0,0.08)]"
>
<div class="flex flex-col gap-4">
<div>
<span class="text-sm text-muted-color font-semibold">Primary</span>
<div class="pt-2 flex gap-2 flex-wrap justify-between">
<button
v-for="c of primaryColors"
:key="c.name"
type="button"
:title="c.name"
@click="updateColors('primary', c)"
:class="['border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1', { 'outline-primary': layoutConfig.primary === c.name }]"
:style="{ backgroundColor: `${c.name === 'noir' ? 'var(--text-color)' : c.palette['500']}` }"
/>
</div>
</div>
<div>
<span class="text-sm text-muted-color font-semibold">Surface</span>
<div class="pt-2 flex gap-2 flex-wrap justify-between">
<button
v-for="s of surfaces"
:key="s.name"
type="button"
:title="s.name"
@click="updateColors('surface', s)"
:class="[
'border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1',
{ 'outline-primary': layoutConfig.surface ? layoutConfig.surface === s.name : isDarkTheme ? s.name === 'zinc' : s.name === 'slate' }
]"
:style="{ backgroundColor: `${s.palette['500']}` }"
/>
</div>
</div>
<div class="flex flex-col gap-2">
<span class="text-sm text-muted-color font-semibold">Presets</span>
<SelectButton v-model="presetModel" :options="presetOptions" :allowEmpty="false" />
</div>
<!-- Menu Mode: visível apenas no Layout Clássico -->
<div v-show="layoutConfig.variant === 'classic'" class="flex flex-col gap-2">
<span class="text-sm text-muted-color font-semibold">Menu Mode</span>
<SelectButton v-model="menuModeModel" :options="menuModeOptions" :allowEmpty="false" optionLabel="label" optionValue="value" />
</div>
<div class="flex flex-col gap-2">
<span class="text-sm text-muted-color font-semibold">Layout</span>
<div class="flex flex-col gap-1">
<!-- Layout Rail -->
<button type="button" class="layout-option" :class="{ 'layout-option--active': layoutConfig.variant === 'rail' }" @click="setVariant('rail')">
<i :class="layoutConfig.variant === 'rail' ? 'pi pi-check-circle' : 'pi pi-circle'" class="layout-option__icon" />
<span class="layout-option__label">Layout Rail</span>
<span v-if="layoutConfig.variant === 'rail'" class="layout-option__badge layout-option__badge--default">Padrão</span>
</button>
<!-- Layout Clássico -->
<button type="button" class="layout-option" :class="{ 'layout-option--active': layoutConfig.variant === 'classic' }" @click="setVariant('classic')">
<i :class="layoutConfig.variant === 'classic' ? 'pi pi-check-circle' : 'pi pi-circle'" class="layout-option__icon" />
<span class="layout-option__label">Layout Clássico</span>
</button>
</div>
</div>
</div>
</div>
<div>
<span class="text-sm text-muted-color font-semibold">Surface</span>
<div class="pt-2 flex gap-2 flex-wrap justify-between">
<button
v-for="s of surfaces"
:key="s.name"
type="button"
:title="s.name"
@click="updateColors('surface', s)"
:class="[
'border-none w-5 h-5 rounded-full p-0 cursor-pointer outline-none outline-offset-1',
{ 'outline-primary': layoutConfig.surface ? layoutConfig.surface === s.name : (isDarkTheme ? s.name === 'zinc' : s.name === 'slate') }
]"
:style="{ backgroundColor: `${s.palette['500']}` }"
/>
</div>
</div>
<div class="flex flex-col gap-2">
<span class="text-sm text-muted-color font-semibold">Presets</span>
<SelectButton v-model="presetModel" :options="presetOptions" :allowEmpty="false" />
</div>
<!-- Menu Mode: visível apenas no Layout Clássico -->
<div v-show="layoutConfig.variant === 'classic'" class="flex flex-col gap-2">
<span class="text-sm text-muted-color font-semibold">Menu Mode</span>
<SelectButton
v-model="menuModeModel"
:options="menuModeOptions"
:allowEmpty="false"
optionLabel="label"
optionValue="value"
/>
</div>
<div class="flex flex-col gap-2">
<span class="text-sm text-muted-color font-semibold">Layout</span>
<div class="flex flex-col gap-1">
<!-- Layout Rail -->
<button
type="button"
class="layout-option"
:class="{ 'layout-option--active': layoutConfig.variant === 'rail' }"
@click="setVariant('rail')"
>
<i
:class="layoutConfig.variant === 'rail' ? 'pi pi-check-circle' : 'pi pi-circle'"
class="layout-option__icon"
/>
<span class="layout-option__label">Layout Rail</span>
<span v-if="layoutConfig.variant === 'rail'" class="layout-option__badge layout-option__badge--default">Padrão</span>
</button>
<!-- Layout Clássico -->
<button
type="button"
class="layout-option"
:class="{ 'layout-option--active': layoutConfig.variant === 'classic' }"
@click="setVariant('classic')"
>
<i
:class="layoutConfig.variant === 'classic' ? 'pi pi-check-circle' : 'pi pi-circle'"
class="layout-option__icon"
/>
<span class="layout-option__label">Layout Clássico</span>
</button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.layout-option {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.45rem 0.6rem;
border-radius: var(--border-radius, 6px);
border: 1px solid var(--surface-border);
background: var(--surface-ground);
font-size: 0.8rem;
cursor: pointer;
text-align: left;
transition: border-color 0.15s, background 0.15s;
width: 100%;
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.45rem 0.6rem;
border-radius: var(--border-radius, 6px);
border: 1px solid var(--surface-border);
background: var(--surface-ground);
font-size: 0.8rem;
cursor: pointer;
text-align: left;
transition:
border-color 0.15s,
background 0.15s;
width: 100%;
}
.layout-option:hover {
border-color: var(--primary-color);
border-color: var(--primary-color);
}
.layout-option--active {
border-color: var(--primary-color);
background: color-mix(in srgb, var(--primary-color) 8%, transparent);
border-color: var(--primary-color);
background: color-mix(in srgb, var(--primary-color) 8%, transparent);
}
.layout-option__icon {
font-size: 0.85rem;
color: var(--text-color-secondary);
flex-shrink: 0;
font-size: 0.85rem;
color: var(--text-color-secondary);
flex-shrink: 0;
}
.layout-option--active .layout-option__icon {
color: var(--primary-color);
color: var(--primary-color);
}
.layout-option__label {
flex: 1;
font-weight: 500;
color: var(--text-color);
flex: 1;
font-weight: 500;
color: var(--text-color);
}
.layout-option__badge {
font-size: 0.6rem;
font-weight: 700;
letter-spacing: 0.01em;
padding: 0.1rem 0.45rem;
border-radius: 999px;
white-space: nowrap;
flex-shrink: 0;
font-size: 0.6rem;
font-weight: 700;
letter-spacing: 0.01em;
padding: 0.1rem 0.45rem;
border-radius: 999px;
white-space: nowrap;
flex-shrink: 0;
}
.layout-option__badge--default {
background: var(--primary-color);
color: var(--primary-color-text, #fff);
background: var(--primary-color);
color: var(--primary-color-text, #fff);
}
</style>
</style>