feat: implement filtering and document management features in dashboard components, enhancing user experience with improved query capabilities and UI for managing documents in pedidos and compras

This commit is contained in:
2025-12-15 14:29:30 -03:00
parent f3288b9639
commit a5ad843b3e
7 changed files with 1135 additions and 34 deletions

View File

@@ -8,7 +8,21 @@
const client = useConvexClient();
// Reactive queries
const atasQuery = useQuery(api.atas.list, {});
// Filtros (listagem)
let filtroPeriodoInicio = $state('');
let filtroPeriodoFim = $state('');
let filtroNumero = $state('');
let filtroNumeroSei = $state('');
const atasTotalQuery = useQuery(api.atas.list, {});
let atasTotal = $derived(atasTotalQuery.data || []);
const atasQuery = useQuery(api.atas.list, () => ({
periodoInicio: filtroPeriodoInicio || undefined,
periodoFim: filtroPeriodoFim || undefined,
numero: filtroNumero.trim() || undefined,
numeroSei: filtroNumeroSei.trim() || undefined
}));
let atas = $derived(atasQuery.data || []);
let loadingAtas = $derived(atasQuery.isLoading);
let errorAtas = $derived(atasQuery.error?.message || null);
@@ -188,6 +202,13 @@
attachmentFiles = Array.from(input.files);
}
}
function limparFiltros() {
filtroPeriodoInicio = '';
filtroPeriodoFim = '';
filtroNumero = '';
filtroNumeroSei = '';
}
</script>
<main class="container mx-auto flex max-w-7xl flex-col px-4 py-4">
@@ -220,6 +241,71 @@
</div>
</div>
<div class="card bg-base-100/90 border-base-300 mb-6 border shadow-xl backdrop-blur-sm">
<div class="card-body">
<div class="grid gap-4 sm:grid-cols-[1fr_auto] sm:items-end">
<div class="grid grid-cols-1 gap-4 md:grid-cols-4">
<div class="form-control w-full">
<label class="label" for="filtro_numero">
<span class="label-text font-semibold">Número</span>
</label>
<input
id="filtro_numero"
class="input input-bordered focus:input-primary w-full"
type="text"
placeholder="Ex.: 12/2025"
bind:value={filtroNumero}
/>
</div>
<div class="form-control w-full">
<label class="label" for="filtro_numeroSei">
<span class="label-text font-semibold">Número SEI</span>
</label>
<input
id="filtro_numeroSei"
class="input input-bordered focus:input-primary w-full"
type="text"
placeholder="Ex.: 12345.000000/2025-00"
bind:value={filtroNumeroSei}
/>
</div>
<div class="form-control w-full">
<label class="label" for="filtro_inicio">
<span class="label-text font-semibold">Período (início)</span>
</label>
<input
id="filtro_inicio"
class="input input-bordered focus:input-primary w-full"
type="date"
bind:value={filtroPeriodoInicio}
/>
</div>
<div class="form-control w-full">
<label class="label" for="filtro_fim">
<span class="label-text font-semibold">Período (fim)</span>
</label>
<input
id="filtro_fim"
class="input input-bordered focus:input-primary w-full"
type="date"
bind:value={filtroPeriodoFim}
/>
</div>
</div>
<div class="flex items-center justify-between gap-3 sm:min-w-max sm:justify-end">
<div class="text-base-content/70 text-sm">
{atas.length} de {atasTotal.length}
</div>
<button type="button" class="btn btn-ghost" onclick={limparFiltros}>Limpar</button>
</div>
</div>
</div>
</div>
{#if loadingAtas}
<div class="flex items-center justify-center py-10">
<span class="loading loading-spinner loading-lg"></span>
@@ -258,8 +344,13 @@
<tr>
<td colspan="5" class="py-12 text-center">
<div class="text-base-content/60 flex flex-col items-center gap-2">
<p class="text-lg font-semibold">Nenhuma ata cadastrada</p>
<p class="text-sm">Clique em “Nova Ata” para cadastrar.</p>
{#if atasTotal.length === 0}
<p class="text-lg font-semibold">Nenhuma ata cadastrada</p>
<p class="text-sm">Clique em “Nova Ata” para cadastrar.</p>
{:else}
<p class="text-lg font-semibold">Nenhum resultado encontrado</p>
<p class="text-sm">Ajuste ou limpe os filtros para ver resultados.</p>
{/if}
</div>
</td>
</tr>