refactor: improve data handling and UI feedback in LGPD-related components; enhance error handling and consent term display

This commit is contained in:
2025-12-02 14:03:52 -03:00
parent e81054874f
commit ffa4dc5fb2
5 changed files with 254 additions and 64 deletions

View File

@@ -32,10 +32,14 @@
let termoBusca = $state('');
const client = useConvexClient();
const solicitacoes = useQuery(api.lgpd.listarSolicitacoes, {
// Query reativa que atualiza quando os filtros mudam
const solicitacoesQuery = $derived({
status: statusFiltro || undefined,
tipo: tipoFiltro || undefined
});
const solicitacoes = useQuery(api.lgpd.listarSolicitacoes, solicitacoesQuery);
let solicitacaoSelecionada = $state<string | null>(null);
let resposta = $state('');
@@ -85,15 +89,21 @@
}
function filtrarSolicitacoes() {
if (!solicitacoes) return [];
if (!termoBusca) return solicitacoes;
// Verificar se solicitacoes existe e é um array
if (!solicitacoes || !Array.isArray(solicitacoes)) return [];
// Se não há termo de busca, retorna todas as solicitações
if (!termoBusca || termoBusca.trim() === '') return solicitacoes;
const busca = termoBusca.toLowerCase();
// Filtrar por termo de busca
const busca = termoBusca.toLowerCase().trim();
return solicitacoes.filter(
(s) =>
s.usuarioNome.toLowerCase().includes(busca) ||
s.usuarioEmail.toLowerCase().includes(busca) ||
(s.usuarioMatricula?.toLowerCase().includes(busca) ?? false)
(s.usuarioNome?.toLowerCase().includes(busca) ?? false) ||
(s.usuarioEmail?.toLowerCase().includes(busca) ?? false) ||
(s.usuarioMatricula?.toLowerCase().includes(busca) ?? false) ||
(getTipoLabel(s.tipo).toLowerCase().includes(busca)) ||
(getStatusBadge(s.status).label.toLowerCase().includes(busca))
);
}
@@ -193,16 +203,52 @@
<!-- Lista de Solicitações -->
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title text-2xl mb-4">Solicitações</h2>
<div class="flex items-center justify-between mb-4">
<h2 class="card-title text-2xl">Solicitações</h2>
{#if solicitacoes && Array.isArray(solicitacoes)}
<div class="badge badge-outline">
Total: {solicitacoes.length} | Exibindo: {solicitacoesFiltradas.length}
</div>
{/if}
</div>
{#if solicitacoes === undefined}
{#if solicitacoes === undefined || solicitacoes === null}
<div class="flex justify-center items-center py-20">
<span class="loading loading-spinner loading-lg text-primary"></span>
</div>
{:else if solicitacoesFiltradas.length === 0}
{:else if !Array.isArray(solicitacoes) || solicitacoes.length === 0}
<div class="text-center py-10">
<FileText class="h-16 w-16 text-base-content/30 mx-auto mb-4" />
<p class="text-base-content/60">Nenhuma solicitação encontrada</p>
<p class="text-base-content/60">
{#if statusFiltro || tipoFiltro}
Nenhuma solicitação encontrada com os filtros aplicados
{:else}
Nenhuma solicitação encontrada
{/if}
</p>
{#if statusFiltro || tipoFiltro}
<button
onclick={() => {
statusFiltro = null;
tipoFiltro = null;
termoBusca = '';
}}
class="btn btn-sm btn-outline mt-4"
>
Limpar Filtros
</button>
{/if}
</div>
{:else if solicitacoesFiltradas.length === 0 && termoBusca}
<div class="text-center py-10">
<Search class="h-16 w-16 text-base-content/30 mx-auto mb-4" />
<p class="text-base-content/60">Nenhuma solicitação encontrada com o termo "{termoBusca}"</p>
<button
onclick={() => (termoBusca = '')}
class="btn btn-sm btn-outline mt-4"
>
Limpar Busca
</button>
</div>
{:else}
<div class="space-y-4">
@@ -230,6 +276,23 @@
<div>
<span class="font-semibold">E-mail:</span> {solicitacao.usuarioEmail}
</div>
{#if solicitacao.consentimentoTermo}
<div class="flex items-center gap-2">
<span class="font-semibold">Termo de Consentimento:</span>
<span class="badge badge-success badge-sm">Aceito</span>
<span class="text-xs text-base-content/60">
(v.{solicitacao.consentimentoTermo.versao} em{' '}
{format(new Date(solicitacao.consentimentoTermo.aceitoEm), 'dd/MM/yyyy', {
locale: ptBR
})})
</span>
</div>
{:else}
<div class="flex items-center gap-2">
<span class="font-semibold">Termo de Consentimento:</span>
<span class="badge badge-warning badge-sm">Não aceito</span>
</div>
{/if}
<div>
<span class="font-semibold">Criada em:</span>{' '}
{format(new Date(solicitacao.criadoEm), "dd/MM/yyyy 'às' HH:mm", {