+ Menu Hover no Layout Rail, Twilio, Sms, Email, Templates, LNovo Layout Configurações

This commit is contained in:
Leonardo
2026-03-25 08:39:45 -03:00
parent 53a4980396
commit 3f1786c9bf
59 changed files with 2553 additions and 1106 deletions
@@ -2326,10 +2326,10 @@ onMounted(async () => {
<div class="absolute w-64 h-64 -top-16 -right-8 rounded-full blur-[60px] bg-indigo-500/10" />
<div class="absolute w-72 h-72 top-0 -left-16 rounded-full blur-[60px] bg-emerald-400/[0.07]" />
</div>
<div class="relative z-[1] flex items-center gap-3">
<div class="relative z-1 flex items-center gap-3">
<!-- Brand -->
<div class="flex items-center gap-2 flex-shrink-0">
<div class="grid place-items-center w-9 h-9 rounded-md flex-shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-calendar text-base" /></div>
<div class="flex items-center gap-2 shrink-0">
<div class="grid place-items-center w-9 h-9 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-calendar text-base" /></div>
<div class="min-w-0 hidden lg:block">
<div class="text-base font-bold tracking-tight text-[var(--text-color)]">Agenda</div>
<div class="text-xs text-[var(--text-color-secondary)]">{{ subtitleText }}</div>
@@ -2523,7 +2523,7 @@ onMounted(async () => {
agPanelOpen = false;
"
>
<div class="flex flex-col items-end min-w-[36px] flex-shrink-0">
<div class="flex flex-col items-end min-w-[36px] shrink-0">
<span class="text-xs font-bold text-[var(--text-color)]">{{ fmtHoraEvento(ev.inicio_em) }}</span>
<span class="text-[0.65rem] text-[var(--text-color-secondary)]">{{ fmtDuracao(ev.inicio_em, ev.fim_em) }}</span>
</div>
@@ -2539,13 +2539,13 @@ onMounted(async () => {
</div>
<button
v-if="ev.patient_id || ev.paciente_id"
class="w-6 h-6 rounded-full flex items-center justify-center border-none bg-transparent text-[var(--text-color-secondary)] hover:bg-[var(--surface-border)] hover:text-[var(--primary-color,#6366f1)] transition-colors duration-100 cursor-pointer flex-shrink-0"
class="w-6 h-6 rounded-full flex items-center justify-center border-none bg-transparent text-[var(--text-color-secondary)] hover:bg-[var(--surface-border)] hover:text-[var(--primary-color,#6366f1)] transition-colors duration-100 cursor-pointer shrink-0"
title="Opções"
@click.stop="openTodayEvMenu($event, ev)"
>
<i class="pi pi-ellipsis-v text-[0.7rem]" />
</button>
<i v-else class="text-xs text-[var(--text-color-secondary)] flex-shrink-0" :class="statusIcon(ev.status)" />
<i v-else class="text-xs text-[var(--text-color-secondary)] shrink-0" :class="statusIcon(ev.status)" />
</div>
</div>
</div>
@@ -2587,23 +2587,23 @@ onMounted(async () => {
class="flex items-center gap-2.5 px-2.5 py-2 rounded-md border-none bg-transparent cursor-pointer w-full text-left transition-colors duration-100 hover:bg-[var(--surface-hover)]"
@click="router.push('/therapist/patients')"
>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] flex-shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-list" /></div>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-list" /></div>
<div class="flex-1 min-w-0 flex flex-col gap-px">
<span class="text-[1rem] font-semibold text-[var(--text-color)] truncate">Lista de pacientes</span>
<span class="text-[0.68rem] text-[var(--text-color-secondary)] truncate">Todos os cadastros ativos</span>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 shrink-0" />
</button>
<button
class="flex items-center gap-2.5 px-2.5 py-2 rounded-md border-none bg-transparent cursor-pointer w-full text-left transition-colors duration-100 hover:bg-[var(--surface-hover)]"
@click="router.push('/therapist/patients/cadastro')"
>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] flex-shrink-0 bg-green-500/10 text-green-600"><i class="pi pi-user-plus" /></div>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] shrink-0 bg-green-500/10 text-green-600"><i class="pi pi-user-plus" /></div>
<div class="flex-1 min-w-0 flex flex-col gap-px">
<span class="text-[1rem] font-semibold text-[var(--text-color)] truncate">Novo paciente</span>
<span class="text-[0.68rem] text-[var(--text-color-secondary)] truncate">Cadastrar manualmente</span>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 shrink-0" />
</button>
<!-- Link de cadastro externo -->
<div v-if="cadastroExternoLink" class="flex flex-col gap-1 px-2.5 py-2 rounded-md bg-[var(--surface-ground)] border border-[var(--surface-border)] mt-1">
@@ -2616,7 +2616,7 @@ onMounted(async () => {
@click="$event.target.select()"
/>
<button
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs flex-shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
@click="copyLink(cadastroExternoLink)"
v-tooltip.top="'Copiar link'"
>
@@ -2637,12 +2637,12 @@ onMounted(async () => {
class="flex items-center gap-2.5 px-2.5 py-2 rounded-md border-none bg-transparent cursor-pointer w-full text-left transition-colors duration-100 hover:bg-[var(--surface-hover)]"
@click="router.push('/therapist/agendador/solicitacoes')"
>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] flex-shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-inbox" /></div>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-inbox" /></div>
<div class="flex-1 min-w-0 flex flex-col gap-px">
<span class="text-[1rem] font-semibold text-[var(--text-color)] truncate">Solicitações</span>
<span class="text-[0.68rem] text-[var(--text-color-secondary)] truncate">Pedidos de agendamento</span>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 shrink-0" />
</button>
<!-- Link do agendador -->
<div v-if="agendadorLink" class="flex flex-col gap-1 px-2.5 py-2 rounded-md bg-[var(--surface-ground)] border border-[var(--surface-border)] mt-1">
@@ -2650,7 +2650,7 @@ onMounted(async () => {
<div class="flex items-center gap-1.5">
<input readonly :value="agendadorLink" class="flex-1 min-w-0 text-[0.72rem] text-[var(--primary-color,#6366f1)] bg-transparent border-none outline-none truncate cursor-text font-mono" @click="$event.target.select()" />
<button
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs flex-shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
@click="copyLink(agendadorLink)"
v-tooltip.top="'Copiar link'"
>
@@ -2714,7 +2714,7 @@ onMounted(async () => {
<div class="flex items-center gap-2 min-w-0">
<i class="pi pi-calendar-clock text-[var(--primary-color,#6366f1)]" />
<span class="truncate">Calendário · Sessões de hoje</span>
<span v-if="todayEvents.length" class="inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-[var(--primary-color,#6366f1)] text-white text-[0.68rem] font-bold flex-shrink-0">{{
<span v-if="todayEvents.length" class="inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-[var(--primary-color,#6366f1)] text-white text-[0.68rem] font-bold shrink-0">{{
todayEvents.length
}}</span>
</div>
@@ -2804,7 +2804,7 @@ onMounted(async () => {
}"
@click="onEventRowClick(ev)"
>
<div class="flex flex-col items-end min-w-[36px] flex-shrink-0">
<div class="flex flex-col items-end min-w-[36px] shrink-0">
<span class="text-xs font-bold text-[var(--text-color)]">{{ fmtHoraEvento(ev.inicio_em) }}</span>
<span class="text-[0.65rem] text-[var(--text-color-secondary)]">{{ fmtDuracao(ev.inicio_em, ev.fim_em) }}</span>
</div>
@@ -2820,13 +2820,13 @@ onMounted(async () => {
</div>
<button
v-if="ev.patient_id || ev.paciente_id"
class="w-6 h-6 rounded-full flex items-center justify-center border-none bg-transparent text-[var(--text-color-secondary)] hover:bg-[var(--surface-border)] hover:text-[var(--primary-color,#6366f1)] transition-colors duration-100 cursor-pointer flex-shrink-0"
class="w-6 h-6 rounded-full flex items-center justify-center border-none bg-transparent text-[var(--text-color-secondary)] hover:bg-[var(--surface-border)] hover:text-[var(--primary-color,#6366f1)] transition-colors duration-100 cursor-pointer shrink-0"
title="Opções"
@click.stop="openTodayEvMenu($event, ev)"
>
<i class="pi pi-ellipsis-v text-[0.7rem]" />
</button>
<i v-else class="text-xs text-[var(--text-color-secondary)] flex-shrink-0" :class="statusIcon(ev.status)" />
<i v-else class="text-xs text-[var(--text-color-secondary)] shrink-0" :class="statusIcon(ev.status)" />
</div>
</div>
</div>
@@ -2860,23 +2860,23 @@ onMounted(async () => {
class="flex items-center gap-2.5 px-2.5 py-2 rounded-md border-none bg-transparent cursor-pointer w-full text-left transition-colors duration-100 hover:bg-[var(--surface-hover)]"
@click="router.push('/therapist/patients')"
>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] flex-shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-list" /></div>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-list" /></div>
<div class="flex-1 min-w-0 flex flex-col gap-px">
<span class="text-[1rem] font-semibold text-[var(--text-color)] truncate">Lista de pacientes</span>
<span class="text-[0.68rem] text-[var(--text-color-secondary)] truncate">Todos os cadastros ativos</span>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 shrink-0" />
</button>
<button
class="flex items-center gap-2.5 px-2.5 py-2 rounded-md border-none bg-transparent cursor-pointer w-full text-left transition-colors duration-100 hover:bg-[var(--surface-hover)]"
@click="router.push('/therapist/patients/cadastro')"
>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] flex-shrink-0 bg-green-500/10 text-green-600"><i class="pi pi-user-plus" /></div>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] shrink-0 bg-green-500/10 text-green-600"><i class="pi pi-user-plus" /></div>
<div class="flex-1 min-w-0 flex flex-col gap-px">
<span class="text-[1rem] font-semibold text-[var(--text-color)] truncate">Novo paciente</span>
<span class="text-[0.68rem] text-[var(--text-color-secondary)] truncate">Cadastrar manualmente</span>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 shrink-0" />
</button>
<!-- Link de cadastro externo -->
<div v-if="cadastroExternoLink" class="flex flex-col gap-1 px-2.5 py-2 rounded-md bg-[var(--surface-ground)] border border-[var(--surface-border)] mt-1">
@@ -2889,7 +2889,7 @@ onMounted(async () => {
@click="$event.target.select()"
/>
<button
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs flex-shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
@click="copyLink(cadastroExternoLink)"
v-tooltip.top="'Copiar link'"
>
@@ -2910,12 +2910,12 @@ onMounted(async () => {
class="flex items-center gap-2.5 px-2.5 py-2 rounded-md border-none bg-transparent cursor-pointer w-full text-left transition-colors duration-100 hover:bg-[var(--surface-hover)]"
@click="router.push('/therapist/agendador/solicitacoes')"
>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] flex-shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-inbox" /></div>
<div class="w-[30px] h-[30px] rounded-md grid place-items-center text-[0.8rem] shrink-0 bg-indigo-500/10 text-indigo-500"><i class="pi pi-inbox" /></div>
<div class="flex-1 min-w-0 flex flex-col gap-px">
<span class="text-[1rem] font-semibold text-[var(--text-color)] truncate">Solicitações</span>
<span class="text-[0.68rem] text-[var(--text-color-secondary)] truncate">Pedidos de agendamento</span>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-40 shrink-0" />
</button>
<!-- Link do agendador -->
<div v-if="agendadorLink" class="flex flex-col gap-1 px-2.5 py-2 rounded-md bg-[var(--surface-ground)] border border-[var(--surface-border)] mt-1">
@@ -2923,7 +2923,7 @@ onMounted(async () => {
<div class="flex items-center gap-1.5">
<input readonly :value="agendadorLink" class="flex-1 min-w-0 text-[0.72rem] text-[var(--primary-color,#6366f1)] bg-transparent border-none outline-none truncate cursor-text font-mono" @click="$event.target.select()" />
<button
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs flex-shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
class="grid place-items-center w-[26px] h-[26px] rounded border border-[var(--surface-border)] bg-[var(--surface-card)] text-[var(--text-color-secondary)] cursor-pointer text-xs shrink-0 transition-colors duration-100 hover:bg-[var(--primary-color,#6366f1)] hover:text-white hover:border-[var(--primary-color)]"
@click="copyLink(agendadorLink)"
v-tooltip.top="'Copiar link'"
>
@@ -3144,11 +3144,11 @@ onMounted(async () => {
<!-- Body: split panel -->
<div v-if="desativadoSelected" class="flex flex-col lg:flex-row flex-1 min-h-0 overflow-hidden">
<!-- Sidebar esquerda: lista de sessões -->
<div class="w-full lg:w-[340px] lg:flex-shrink-0 flex flex-col border-b lg:border-b-0 lg:border-r border-[var(--surface-border)]">
<div class="w-full lg:w-[340px] lg:shrink-0 flex flex-col border-b lg:border-b-0 lg:border-r border-[var(--surface-border)]">
<!-- Patient info -->
<div class="px-4 py-3 border-b border-[var(--surface-border)] bg-orange-500/5">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold text-sm flex-shrink-0" style="background: #f97316">
<div class="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold text-sm shrink-0" style="background: #f97316">
{{ (desativadoSelected.nome_completo || '?').charAt(0).toUpperCase() }}
</div>
<div class="min-w-0">
@@ -3157,7 +3157,7 @@ onMounted(async () => {
{{ desativadoSelected.status === 'Arquivado' ? 'arquivado' : 'desativado' }}
</span>
</div>
<div class="ml-auto text-right flex-shrink-0">
<div class="ml-auto text-right shrink-0">
<div class="text-lg font-bold text-orange-500">{{ desativadoSelected.sessions.length }}</div>
<div class="text-[0.65rem] text-[var(--text-color-secondary)]">sessão(ões)</div>
</div>
@@ -360,12 +360,12 @@ const emptySub = computed(() => {
<div class="absolute w-56 h-56 -bottom-8 right-1/4 rounded-full blur-[55px] bg-orange-400/[0.07]" />
</div>
<div class="relative z-[1] flex flex-col gap-2.5">
<div class="relative z-1 flex flex-col gap-2.5">
<!-- Linha 1: brand + busca + refresh -->
<div class="flex items-center gap-3 flex-wrap">
<!-- Brand -->
<div class="flex items-center gap-2 flex-shrink-0">
<div class="grid place-items-center w-9 h-9 rounded-md flex-shrink-0 bg-indigo-500/10 text-indigo-500">
<div class="flex items-center gap-2 shrink-0">
<div class="grid place-items-center w-9 h-9 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
<i class="pi pi-inbox text-base" />
</div>
<div class="min-w-0 hidden sm:block">
@@ -386,7 +386,7 @@ const emptySub = computed(() => {
</div>
<!-- Refresh -->
<Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full flex-shrink-0" :loading="loading" title="Atualizar" @click="load" />
<Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full shrink-0" :loading="loading" title="Atualizar" @click="load" />
</div>
<!-- Linha 2: chips de status -->
@@ -425,7 +425,7 @@ const emptySub = computed(() => {
@click="filtroStatus = 'autorizado'"
>
<!-- Ícone pulsante -->
<div class="relative flex-shrink-0">
<div class="relative shrink-0">
<div class="grid place-items-center w-8 h-8 rounded-md bg-amber-400/20 text-amber-600">
<i class="pi pi-calendar-plus text-[0.95rem]" />
</div>
@@ -444,7 +444,7 @@ const emptySub = computed(() => {
</div>
<!-- Badge + seta -->
<div class="flex items-center gap-2 flex-shrink-0">
<div class="flex items-center gap-2 shrink-0">
<span class="inline-flex items-center justify-center min-w-[22px] h-[22px] px-1.5 rounded-full bg-amber-500 text-white text-[1rem] font-bold">
{{ totalAutorizados }}
</span>
@@ -460,7 +460,7 @@ const emptySub = computed(() => {
<!-- Loading skeleton -->
<div v-if="loading" class="flex flex-col gap-3">
<div v-for="n in 4" :key="n" class="flex items-center gap-4 p-4 rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)]">
<div class="w-10 h-10 rounded-full flex-shrink-0 bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
<div class="w-10 h-10 rounded-full shrink-0 bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
<div class="flex flex-col gap-2 flex-1">
<div class="h-3.5 w-3/5 rounded-md bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
<div class="h-2.5 w-2/5 rounded-md bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
@@ -512,7 +512,7 @@ const emptySub = computed(() => {
<!-- Linha principal clicável -->
<div class="flex items-center gap-3 px-4 py-3.5 cursor-pointer hover:bg-[var(--surface-ground,#f8fafc)] transition-colors duration-100" @click="toggleExpand(s.id)">
<!-- Avatar inicial -->
<div class="grid place-items-center w-10 h-10 rounded-full flex-shrink-0 font-bold text-[0.95rem] bg-indigo-500/10 text-indigo-600">
<div class="grid place-items-center w-10 h-10 rounded-full shrink-0 font-bold text-[0.95rem] bg-indigo-500/10 text-indigo-600">
{{ initials(s) }}
</div>
@@ -532,24 +532,24 @@ const emptySub = computed(() => {
</div>
<!-- Ações rápidas pendente -->
<div v-if="s.status === 'pendente'" class="hidden sm:flex items-center gap-1.5 flex-shrink-0" @click.stop>
<div v-if="s.status === 'pendente'" class="hidden sm:flex items-center gap-1.5 shrink-0" @click.stop>
<Button label="Aprovar" icon="pi pi-check" size="small" severity="success" class="rounded-full" :loading="aprovando === s.id" @click="aprovar(s)" />
<Button label="Recusar" icon="pi pi-times" size="small" severity="danger" outlined class="rounded-full" @click="abrirRecusa(s)" />
<Button label="Converter" icon="pi pi-calendar-plus" size="small" severity="info" outlined class="rounded-full" :loading="convertendoId === s.id" @click="converterEmSessao(s)" />
</div>
<!-- Ações autorizado -->
<div v-else-if="s.status === 'autorizado'" class="hidden sm:flex items-center flex-shrink-0" @click.stop>
<div v-else-if="s.status === 'autorizado'" class="hidden sm:flex items-center shrink-0" @click.stop>
<Button label="Converter em sessão" icon="pi pi-calendar-plus" size="small" severity="info" outlined class="rounded-full" :loading="convertendoId === s.id" @click="converterEmSessao(s)" />
</div>
<!-- Ações convertido -->
<div v-else-if="s.status === 'convertido'" class="hidden sm:flex items-center flex-shrink-0" @click.stop>
<div v-else-if="s.status === 'convertido'" class="hidden sm:flex items-center shrink-0" @click.stop>
<Button label="Ver na agenda" icon="pi pi-calendar" size="small" severity="secondary" outlined class="rounded-full" @click="irParaAgenda(s)" />
</div>
<!-- Chevron -->
<i class="pi flex-shrink-0 text-[1rem] text-[var(--text-color-secondary)] transition-transform duration-200" :class="expandedId === s.id ? 'pi-chevron-up' : 'pi-chevron-down'" />
<i class="pi shrink-0 text-[1rem] text-[var(--text-color-secondary)] transition-transform duration-200" :class="expandedId === s.id ? 'pi-chevron-up' : 'pi-chevron-down'" />
</div>
<!-- Ações mobile (visíveis quando expandido, em telas pequenas) -->
@@ -382,25 +382,25 @@ function isRecent(row) {
-->
<div
ref="headerEl"
class="sticky mx-3 md:mx-4 mb-3 z-20 overflow-hidden rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] px-3 py-2.5 transition-[border-radius] duration-200"
class="sticky mx-3 md:mx-4 mb-3 z-20 overflow-hidden rounded-md border border-(--surface-border,#e2e8f0) bg-(--surface-card,#fff) px-3 py-2.5 transition-[border-radius] duration-200"
:class="{ 'rounded-tl-none rounded-tr-none': headerStuck }"
:style="{ top: 'var(--layout-sticky-top, 56px)' }"
>
<!-- Blobs decorativos -->
<div class="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden="true">
<div class="absolute w-64 h-64 -top-16 -right-8 rounded-full blur-[60px] bg-emerald-400/10" />
<div class="absolute w-72 h-72 top-0 -left-16 rounded-full blur-[60px] bg-indigo-500/[0.09]" />
<div class="absolute w-72 h-72 top-0 -left-16 rounded-full blur-[60px] bg-indigo-500/9" />
</div>
<div class="relative z-[1] flex items-center gap-3">
<div class="relative z-1 flex items-center gap-3">
<!-- Brand -->
<div class="flex items-center gap-2 flex-shrink-0">
<div class="grid place-items-center w-9 h-9 rounded-md flex-shrink-0 bg-indigo-500/10 text-indigo-500">
<div class="flex items-center gap-2 shrink-0">
<div class="grid place-items-center w-9 h-9 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
<i class="pi pi-list text-base" />
</div>
<div class="min-w-0 hidden lg:block">
<div class="text-[1rem] font-bold tracking-tight text-[var(--text-color)]">Compromissos</div>
<div class="text-[0.75rem] text-[var(--text-color-secondary)]">Configure tipos de compromissos e campos adicionais</div>
<div class="text-[1rem] font-bold tracking-tight text-(--text-color)">Compromissos</div>
<div class="text-[0.75rem] text-(--text-color-secondary)">Configure tipos de compromissos e campos adicionais</div>
</div>
</div>
@@ -419,13 +419,13 @@ function isRecent(row) {
</div>
<!-- Ações desktop -->
<div class="hidden xl:flex items-center gap-1 flex-shrink-0">
<div class="hidden xl:flex items-center gap-1 shrink-0">
<Button label="Novo" icon="pi pi-plus" class="rounded-full" :disabled="loading" @click="openCreate()" />
<Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full" :loading="loading" @click="fetchAll()" />
</div>
<!-- Mobile -->
<div class="flex xl:hidden items-center gap-1 flex-shrink-0 ml-auto">
<div class="flex xl:hidden items-center gap-1 shrink-0 ml-auto">
<Button icon="pi pi-search" severity="secondary" outlined class="h-9 w-9 rounded-full" @click="searchDlgOpen = true" />
<Button icon="pi pi-plus" class="h-9 w-9 rounded-full" @click="openCreate()" />
<Button label="Ações" icon="pi pi-ellipsis-v" severity="secondary" size="small" class="rounded-full" @click="(e) => mobileMenuRef.toggle(e)" />
@@ -506,7 +506,7 @@ function isRecent(row) {
<Column field="name" header="Nome" sortable style="min-width: 14rem">
<template #body="{ data }">
<div class="flex items-center gap-2">
<div v-if="data.bg_color" class="w-3 h-3 rounded-full flex-shrink-0" :style="{ background: `#${data.bg_color}` }" />
<div v-if="data.bg_color" class="w-3 h-3 rounded-full shrink-0" :style="{ background: `#${data.bg_color}` }" />
<span class="font-semibold text-sm">{{ data.name }}</span>
<Tag v-if="data.is_native" value="Nativo" severity="info" class="text-xs" />
</div>
@@ -561,11 +561,11 @@ function isRecent(row) {
<!-- fim coluna principal -->
<!-- PAINEL LATERAL: tipos de compromisso -->
<div class="w-full xl:w-[272px] xl:flex-shrink-0">
<div class="w-full xl:w-[272px] xl:shrink-0">
<div class="rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] overflow-hidden">
<!-- Header do painel -->
<div class="flex items-center gap-2.5 px-3.5 pt-3 pb-2.5 border-b border-[var(--surface-border,#f1f5f9)]">
<div class="w-8 h-8 rounded-md flex items-center justify-center flex-shrink-0 bg-indigo-500/10 text-indigo-500">
<div class="w-8 h-8 rounded-md flex items-center justify-center shrink-0 bg-indigo-500/10 text-indigo-500">
<i class="pi pi-chart-bar text-[0.9rem]" />
</div>
<div class="flex-1 min-w-0">
@@ -596,14 +596,14 @@ function isRecent(row) {
@click="openStatsInfo(c)"
>
<!-- Dot cor -->
<div class="w-2.5 h-2.5 rounded-full flex-shrink-0" :style="c.bg_color ? { background: `#${c.bg_color}` } : { background: 'var(--surface-border)' }" />
<div class="w-2.5 h-2.5 rounded-full shrink-0" :style="c.bg_color ? { background: `#${c.bg_color}` } : { background: 'var(--surface-border)' }" />
<div class="flex-1 min-w-0">
<div class="font-semibold text-[0.8rem] truncate text-[var(--text-color)]">{{ c.name }}</div>
<div class="text-[0.72rem] text-[var(--text-color-secondary)]">
{{ formatMinutes(getTotalMinutes(c.id)) }}
</div>
</div>
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-30 group-hover:opacity-100 group-hover:text-[var(--primary-color,#6366f1)] transition-all duration-150 flex-shrink-0" />
<i class="pi pi-chevron-right text-[0.6rem] text-[var(--text-color-secondary)] opacity-30 group-hover:opacity-100 group-hover:text-[var(--primary-color,#6366f1)] transition-all duration-150 shrink-0" />
</button>
</div>