refactor: improve data handling and UI feedback in LGPD-related components; enhance error handling and consent term display
This commit is contained in:
@@ -30,7 +30,17 @@ let observacoes = $state('');
|
||||
let carregando = $state(false);
|
||||
|
||||
const client = useConvexClient();
|
||||
const minhasSolicitacoes = useQuery(api.lgpd.listarMinhasSolicitacoes, {});
|
||||
const minhasSolicitacoesQuery = useQuery(api.lgpd.listarMinhasSolicitacoes, {});
|
||||
|
||||
// Garantir que sempre seja um array ou undefined
|
||||
const minhasSolicitacoes = $derived(
|
||||
minhasSolicitacoesQuery === undefined || minhasSolicitacoesQuery === null
|
||||
? undefined
|
||||
: Array.isArray(minhasSolicitacoesQuery)
|
||||
? minhasSolicitacoesQuery
|
||||
: []
|
||||
);
|
||||
|
||||
const exportarDados = useQuery(api.lgpd.exportarDadosUsuario, {});
|
||||
|
||||
const tiposSolicitacao: Array<{ valor: TipoSolicitacao; label: string; descricao: string }> = [
|
||||
@@ -241,16 +251,26 @@ let carregando = $state(false);
|
||||
<!-- Minhas Solicitações -->
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl mb-4">Minhas Solicitações</h2>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="card-title text-2xl">Minhas Solicitações</h2>
|
||||
{#if minhasSolicitacoes && Array.isArray(minhasSolicitacoes)}
|
||||
<div class="badge badge-outline">
|
||||
{minhasSolicitacoes.length} solicitação{minhasSolicitacoes.length !== 1 ? 'ões' : ''}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if minhasSolicitacoes === undefined}
|
||||
{#if minhasSolicitacoes === undefined || minhasSolicitacoes === null}
|
||||
<div class="flex justify-center items-center py-10">
|
||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
||||
</div>
|
||||
{:else if minhasSolicitacoes.length === 0}
|
||||
{:else if !Array.isArray(minhasSolicitacoes) || minhasSolicitacoes.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-xs text-base-content/40 mt-2">
|
||||
Suas solicitações aparecerão aqui após serem criadas
|
||||
</p>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-4">
|
||||
|
||||
@@ -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", {
|
||||
|
||||
Reference in New Issue
Block a user