feat: enhance LGPD request handling with email notifications and response templates; update frontend filters for improved user experience
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
} from '$lib/utils/chamados';
|
||||
import { useConvexWithAuth } from '$lib/hooks/useConvexWithAuth';
|
||||
import type { Doc } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import { temasDisponiveis, aplicarTema, type Tema } from '$lib/utils/temas';
|
||||
import { temasDisponiveis, aplicarTema } from '$lib/utils/temas';
|
||||
|
||||
const client = useConvexClient();
|
||||
// @ts-expect-error - Convex types issue with getCurrentUser
|
||||
@@ -128,6 +128,9 @@
|
||||
const funcionarioIdDisponivel = $derived(currentUser?.data?.funcionarioId ?? null);
|
||||
const gestorIdDisponivel = $derived(currentUser?.data?._id ?? null);
|
||||
|
||||
// Qualquer usuário com funcionarioId é considerado funcionário
|
||||
const isFuncionario = $derived(!!funcionarioIdDisponivel);
|
||||
|
||||
// Verificar autenticação antes de executar queries
|
||||
const usuarioAutenticado = $derived(
|
||||
currentUser?.data !== null && currentUser?.data !== undefined
|
||||
@@ -818,8 +821,8 @@
|
||||
<FileCheck class="h-5 w-5" strokeWidth={2} />
|
||||
Meus Chamados
|
||||
</button>
|
||||
|
||||
{#if ehGestor}
|
||||
{#if isFuncionario}
|
||||
<!-- Funcionário: solicitar férias -->
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
@@ -830,6 +833,7 @@
|
||||
Minhas Férias
|
||||
</button>
|
||||
|
||||
<!-- Funcionário: solicitar ausências -->
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
@@ -839,41 +843,42 @@
|
||||
<Clock class="h-5 w-5" strokeWidth={2} />
|
||||
Minhas Ausências
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if ehGestor}
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'aprovar-ferias' ? 'tab-active scale-105 bg-gradient-to-r from-green-600 to-emerald-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
|
||||
onclick={() => (abaAtiva = 'aprovar-ferias')}
|
||||
>
|
||||
<CheckCircle2 class="h-5 w-5" strokeWidth={2} />
|
||||
Aprovar Férias
|
||||
{#if (solicitacoesSubordinados || []).filter((s) => s.status === 'aguardando_aprovacao').length > 0}
|
||||
<span class="badge badge-error badge-sm ml-1 animate-pulse">
|
||||
{(solicitacoesSubordinados || []).filter(
|
||||
(s) => s.status === 'aguardando_aprovacao'
|
||||
).length}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{#if ehGestor}
|
||||
<!-- Gestor: aprovar férias -->
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'aprovar-ferias' ? 'tab-active scale-105 bg-gradient-to-r from-green-600 to-emerald-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
|
||||
onclick={() => (abaAtiva = 'aprovar-ferias')}
|
||||
>
|
||||
<CheckCircle2 class="h-5 w-5" strokeWidth={2} />
|
||||
Aprovar Férias
|
||||
{#if (solicitacoesSubordinados || []).filter((s) => s.status === 'aguardando_aprovacao').length > 0}
|
||||
<span class="badge badge-error badge-sm ml-1 animate-pulse">
|
||||
{(solicitacoesSubordinados || []).filter((s) => s.status === 'aguardando_aprovacao')
|
||||
.length}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'aprovar-ausencias' ? 'tab-active scale-105 bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
|
||||
onclick={() => (abaAtiva = 'aprovar-ausencias')}
|
||||
>
|
||||
<Clock class="h-5 w-5" strokeWidth={2} />
|
||||
Aprovar Ausências
|
||||
{#if (ausenciasSubordinados || []).filter((a) => a.status === 'aguardando_aprovacao').length > 0}
|
||||
<span class="badge badge-error badge-sm ml-1 animate-pulse">
|
||||
{(ausenciasSubordinados || []).filter((a) => a.status === 'aguardando_aprovacao')
|
||||
.length}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
<!-- Gestor: aprovar ausências -->
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
class={`tab tab-lg gap-2 font-semibold transition-all duration-300 ${abaAtiva === 'aprovar-ausencias' ? 'tab-active scale-105 bg-gradient-to-r from-orange-600 to-amber-600 text-white shadow-lg' : 'hover:bg-base-100'}`}
|
||||
onclick={() => (abaAtiva = 'aprovar-ausencias')}
|
||||
>
|
||||
<Clock class="h-5 w-5" strokeWidth={2} />
|
||||
Aprovar Ausências
|
||||
{#if (ausenciasSubordinados || []).filter((a) => a.status === 'aguardando_aprovacao').length > 0}
|
||||
<span class="badge badge-error badge-sm ml-1 animate-pulse">
|
||||
{(ausenciasSubordinados || []).filter((a) => a.status === 'aguardando_aprovacao')
|
||||
.length}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
@@ -1217,7 +1222,7 @@
|
||||
>
|
||||
{#if setoresQuery?.data && setoresQuery.data.length > 0}
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
{#each setoresQuery.data as setor}
|
||||
{#each setoresQuery.data as setor (setor._id)}
|
||||
<div
|
||||
class="badge badge-lg font-semibold shadow-sm"
|
||||
style="background-color: rgba(20, 184, 166, 0.1); border-color: rgba(20, 184, 166, 0.3); color: rgb(15, 118, 110);"
|
||||
@@ -1229,8 +1234,6 @@
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else if setoresQuery?.isLoading}
|
||||
<p class="text-base-content/50 mt-1 text-sm">Carregando...</p>
|
||||
{:else}
|
||||
<p class="text-base-content/50 mt-1 text-sm">Nenhum setor atribuído</p>
|
||||
{/if}
|
||||
|
||||
@@ -22,18 +22,19 @@
|
||||
import { ptBR } from 'date-fns/locale';
|
||||
import { toast } from 'svelte-sonner';
|
||||
|
||||
type StatusFiltro = 'pendente' | 'em_analise' | 'concluida' | 'rejeitada' | null;
|
||||
type StatusFiltro = '' | 'pendente' | 'em_analise' | 'concluida' | 'rejeitada';
|
||||
type TipoFiltro =
|
||||
| ''
|
||||
| 'acesso'
|
||||
| 'correcao'
|
||||
| 'exclusao'
|
||||
| 'portabilidade'
|
||||
| 'revogacao_consentimento'
|
||||
| 'informacao_compartilhamento'
|
||||
| null;
|
||||
| 'informacao_compartilhamento';
|
||||
|
||||
let statusFiltro = $state<StatusFiltro>(null);
|
||||
let tipoFiltro = $state<TipoFiltro>(null);
|
||||
// '' = Todos (sem filtro)
|
||||
let statusFiltro = $state<StatusFiltro>('');
|
||||
let tipoFiltro = $state<TipoFiltro>('');
|
||||
let termoBusca = $state('');
|
||||
|
||||
const client = useConvexClient();
|
||||
@@ -221,7 +222,7 @@
|
||||
<span class="label-text font-semibold">Status</span>
|
||||
</label>
|
||||
<select bind:value={statusFiltro} class="select select-bordered">
|
||||
<option value={null}>Todos</option>
|
||||
<option value="">Todos</option>
|
||||
<option value="pendente">Pendente</option>
|
||||
<option value="em_analise">Em Análise</option>
|
||||
<option value="concluida">Concluída</option>
|
||||
@@ -234,7 +235,7 @@
|
||||
<span class="label-text font-semibold">Tipo</span>
|
||||
</label>
|
||||
<select bind:value={tipoFiltro} class="select select-bordered">
|
||||
<option value={null}>Todos</option>
|
||||
<option value="">Todos</option>
|
||||
<option value="acesso">Acesso</option>
|
||||
<option value="correcao">Correção</option>
|
||||
<option value="exclusao">Exclusão</option>
|
||||
|
||||
Reference in New Issue
Block a user