Layout 100%, Notificações, SetupWizard

This commit is contained in:
Leonardo
2026-03-17 21:08:14 -03:00
parent 84d65e49c0
commit 66f67cd40f
77 changed files with 35823 additions and 15023 deletions
+70 -54
View File
@@ -240,17 +240,29 @@ function sessionStatusLabel (session) {
</script>
<template>
<div class="saas-support p-4 md:p-6">
<Toast />
<Toast />
<!-- Cabeçalho -->
<div class="flex items-center gap-3 mb-5">
<div class="flex items-center justify-center w-10 h-10 rounded-xl bg-orange-100 dark:bg-orange-900/30">
<i class="pi pi-headphones text-orange-600 dark:text-orange-400 text-lg" />
</div>
<div class="flex-1">
<h1 class="text-xl font-bold m-0">Suporte Técnico</h1>
<p class="text-sm text-surface-500 m-0">Gere e gerencie links seguros de acesso em modo debug</p>
<!-- Sentinel -->
<div class="h-px" />
<!-- Hero sticky -->
<div
class="sticky mx-3 md:mx-4 mb-4 z-20 overflow-hidden rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-5"
:style="{ top: 'var(--layout-sticky-top, 56px)' }"
>
<div class="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden="true">
<div class="absolute rounded-full blur-[70px] w-72 h-72 -top-16 -right-20 bg-orange-400/10" />
<div class="absolute rounded-full blur-[70px] w-80 h-80 top-10 -left-24 bg-fuchsia-400/10" />
</div>
<div class="relative z-10 flex items-center justify-between gap-3 flex-wrap">
<div class="flex items-center gap-3 min-w-0">
<div class="flex items-center justify-center w-10 h-10 rounded-md border border-[var(--surface-border)] bg-[var(--surface-ground)] flex-shrink-0">
<i class="pi pi-headphones text-[var(--text-color)]" />
</div>
<div class="min-w-0">
<div class="text-[1rem] font-bold tracking-tight text-[var(--text-color)]">Suporte Técnico</div>
<div class="text-[1rem] text-[var(--text-color-secondary)] mt-0.5">Gere e gerencie links seguros de acesso em modo debug</div>
</div>
</div>
<Tag
v-if="activeSessionCount > 0"
@@ -258,6 +270,10 @@ function sessionStatusLabel (session) {
severity="warning"
/>
</div>
</div>
<!-- content -->
<div class="px-3 md:px-4 pb-8 flex flex-col gap-4">
<!-- Tabs -->
<TabView @tab-change="onTabChange">
@@ -267,15 +283,15 @@ function sessionStatusLabel (session) {
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5 pt-2">
<!-- Formulário -->
<div class="card">
<h2 class="text-base font-semibold flex items-center gap-2 m-0 mb-4">
<i class="pi pi-plus-circle text-primary" />
<div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-5">
<div class="text-[1rem] font-semibold flex items-center gap-2 mb-4">
<i class="pi pi-plus-circle text-[var(--primary-color)]" />
Configurar acesso de suporte
</h2>
</div>
<div class="flex flex-col gap-4">
<div class="flex flex-col gap-1">
<label class="text-sm font-medium">Selecionar Cliente (Tenant)</label>
<label class="text-[1rem] font-medium">Selecionar Cliente (Tenant)</label>
<Select
v-model="selectedTenantId"
:options="tenants"
@@ -290,7 +306,7 @@ function sessionStatusLabel (session) {
</div>
<div class="flex flex-col gap-1">
<label class="text-sm font-medium">Duração do Acesso</label>
<label class="text-[1rem] font-medium">Duração do Acesso</label>
<Select
v-model="ttlMinutes"
:options="ttlOptions"
@@ -301,9 +317,9 @@ function sessionStatusLabel (session) {
</div>
<div class="flex flex-col gap-1">
<label class="text-sm font-medium">
<label class="text-[1rem] font-medium">
Nota / Motivo
<span class="text-surface-400 font-normal">(opcional)</span>
<span class="text-[var(--text-color-secondary)] font-normal">(opcional)</span>
</label>
<InputText
v-model="sessionNote"
@@ -325,45 +341,45 @@ function sessionStatusLabel (session) {
</div>
<!-- URL Gerada -->
<div class="card">
<h2 class="text-base font-semibold flex items-center gap-2 m-0 mb-4">
<i class="pi pi-link text-primary" />
<div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-5">
<div class="text-[1rem] font-semibold flex items-center gap-2 mb-4">
<i class="pi pi-link text-[var(--primary-color)]" />
URL Gerada
</h2>
</div>
<div v-if="generatedUrl" class="flex flex-col gap-4">
<div class="flex flex-col gap-1">
<label class="text-sm font-medium">Link de Acesso</label>
<label class="text-[1rem] font-medium">Link de Acesso</label>
<div class="flex gap-2">
<InputText :value="generatedUrl" readonly class="flex-1 font-mono text-xs" />
<InputText :value="generatedUrl" readonly class="flex-1 font-mono text-[1rem]" />
<Button icon="pi pi-copy" severity="secondary" outlined v-tooltip.top="'Copiar URL'" @click="copyUrl(generatedUrl)" />
</div>
</div>
<div class="flex items-center gap-2 text-sm">
<div class="flex items-center gap-2 text-[1rem]">
<i class="pi pi-clock text-orange-500" />
<span class="text-surface-500">Expira em:</span>
<span class="text-[var(--text-color-secondary)]">Expira em:</span>
<strong>{{ expiresLabel }}</strong>
</div>
<div class="flex items-center gap-2 text-xs text-surface-400 font-mono">
<div class="flex items-center gap-2 text-[1rem] text-[var(--text-color-secondary)] font-mono">
<i class="pi pi-key" />
<span>{{ tokenPreview }}</span>
</div>
<div v-if="sessionNote" class="flex items-start gap-2 text-sm text-surface-500">
<div v-if="sessionNote" class="flex items-start gap-2 text-[1rem] text-[var(--text-color-secondary)]">
<i class="pi pi-comment mt-0.5 flex-shrink-0" />
<span class="italic">{{ sessionNote }}</span>
</div>
<Message severity="info" :closable="false" class="text-sm">
Envie este link ao terapeuta ou acesse diretamente para monitorar os logs da agenda em tempo real.
<Message severity="info" :closable="false">
<div class="text-[1rem]">Envie este link ao terapeuta ou acesse diretamente para monitorar os logs da agenda em tempo real.</div>
</Message>
</div>
<div v-else class="flex flex-col items-center justify-center py-12 text-surface-400 gap-3">
<div v-else class="flex flex-col items-center justify-center py-12 text-[var(--text-color-secondary)] gap-3">
<i class="pi pi-shield text-4xl opacity-25" />
<span class="text-sm">Nenhuma sessão gerada ainda</span>
<div class="text-[1rem]">Nenhuma sessão gerada ainda</div>
</div>
</div>
</div>
@@ -378,12 +394,12 @@ function sessionStatusLabel (session) {
</span>
</template>
<div class="card mt-2">
<div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-5 mt-2">
<div class="flex items-center justify-between mb-4">
<h2 class="text-base font-semibold flex items-center gap-2 m-0">
<i class="pi pi-circle-fill text-green-500 text-xs" />
<div class="text-[1rem] font-semibold flex items-center gap-2">
<i class="pi pi-circle-fill text-green-500" />
Sessões em vigor
</h2>
</div>
<Button
icon="pi pi-refresh"
severity="secondary"
@@ -405,15 +421,15 @@ function sessionStatusLabel (session) {
<Column header="Tenant" style="min-width: 200px">
<template #body="{ data }">
<div class="flex flex-col gap-0.5">
<span class="font-medium text-sm">{{ tenantName(data.tenant_id) }}</span>
<span class="font-mono text-xs text-surface-400">{{ data.tenant_id }}</span>
<span class="font-medium text-[1rem]">{{ tenantName(data.tenant_id) }}</span>
<span class="font-mono text-[1rem] text-[var(--text-color-secondary)]">{{ data.tenant_id }}</span>
</div>
</template>
</Column>
<Column header="Token">
<template #body="{ data }">
<span class="font-mono text-xs text-surface-400">{{ data.token.slice(0, 12) }}</span>
<span class="font-mono text-[1rem] text-[var(--text-color-secondary)]">{{ data.token.slice(0, 12) }}</span>
</template>
</Column>
@@ -427,14 +443,14 @@ function sessionStatusLabel (session) {
<Column header="Criada em">
<template #body="{ data }">
<span class="text-sm text-surface-500">{{ formatDate(data.created_at) }}</span>
<span class="text-[1rem] text-[var(--text-color-secondary)]">{{ formatDate(data.created_at) }}</span>
</template>
</Column>
<Column header="Nota">
<template #body="{ data }">
<span v-if="data._note" class="text-xs italic text-surface-500">{{ data._note }}</span>
<span v-else class="text-xs text-surface-300"></span>
<span v-if="data._note" class="text-[1rem] italic text-[var(--text-color-secondary)]">{{ data._note }}</span>
<span v-else class="text-[1rem] text-[var(--text-color-secondary)]"></span>
</template>
</Column>
@@ -452,12 +468,12 @@ function sessionStatusLabel (session) {
<!-- Tab 2: Histórico -->
<TabPanel header="Histórico">
<div class="card mt-2">
<div class="rounded-md border border-[var(--surface-border)] bg-[var(--surface-card)] p-5 mt-2">
<div class="flex items-center justify-between mb-4">
<h2 class="text-base font-semibold flex items-center gap-2 m-0">
<i class="pi pi-history text-primary" />
<div class="text-[1rem] font-semibold flex items-center gap-2">
<i class="pi pi-history text-[var(--primary-color)]" />
Últimas 100 sessões
</h2>
</div>
<Button
icon="pi pi-refresh"
severity="secondary"
@@ -480,41 +496,41 @@ function sessionStatusLabel (session) {
>
<Column header="Status" style="width: 110px">
<template #body="{ data }">
<Tag :value="sessionStatusLabel(data)" :severity="sessionStatusSeverity(data)" class="text-xs" />
<Tag :value="sessionStatusLabel(data)" :severity="sessionStatusSeverity(data)" />
</template>
</Column>
<Column header="Tenant" style="min-width: 180px">
<template #body="{ data }">
<div class="flex flex-col gap-0.5">
<span class="font-medium text-sm">{{ tenantName(data.tenant_id) }}</span>
<span class="font-mono text-xs text-surface-400">{{ data.tenant_id }}</span>
<span class="font-medium text-[1rem]">{{ tenantName(data.tenant_id) }}</span>
<span class="font-mono text-[1rem] text-[var(--text-color-secondary)]">{{ data.tenant_id }}</span>
</div>
</template>
</Column>
<Column header="Token">
<template #body="{ data }">
<span class="font-mono text-xs text-surface-400">{{ data.token.slice(0, 12) }}</span>
<span class="font-mono text-[1rem] text-[var(--text-color-secondary)]">{{ data.token.slice(0, 12) }}</span>
</template>
</Column>
<Column header="Criada em" sortable field="created_at">
<template #body="{ data }">
<span class="text-sm text-surface-500">{{ formatDate(data.created_at) }}</span>
<span class="text-[1rem] text-[var(--text-color-secondary)]">{{ formatDate(data.created_at) }}</span>
</template>
</Column>
<Column header="Expirava em">
<template #body="{ data }">
<span class="text-sm text-surface-500">{{ formatDate(data.expires_at) }}</span>
<span class="text-[1rem] text-[var(--text-color-secondary)]">{{ formatDate(data.expires_at) }}</span>
</template>
</Column>
<Column header="Nota">
<template #body="{ data }">
<span v-if="data._note" class="text-xs italic text-surface-500">{{ data._note }}</span>
<span v-else class="text-xs text-surface-300"></span>
<span v-if="data._note" class="text-[1rem] italic text-[var(--text-color-secondary)]">{{ data._note }}</span>
<span v-else class="text-[1rem] text-[var(--text-color-secondary)]"></span>
</template>
</Column>