diff --git a/apps/web/src/routes/(dashboard)/licitacoes/empresas/+page.svelte b/apps/web/src/routes/(dashboard)/licitacoes/empresas/+page.svelte index 33871b0..9f0bc4b 100644 --- a/apps/web/src/routes/(dashboard)/licitacoes/empresas/+page.svelte +++ b/apps/web/src/routes/(dashboard)/licitacoes/empresas/+page.svelte @@ -7,7 +7,16 @@ import { maskCEP, maskCNPJ, maskPhone, maskUF, onlyDigits } from '$lib/utils/masks'; const client = useConvexClient(); - const empresasQuery = useQuery(api.empresas.list, {}); + let filtroEmpresa = $state(''); + + const empresasTotalQuery = useQuery(api.empresas.list, {}); + const empresasQuery = useQuery(api.empresas.list, () => ({ + query: filtroEmpresa.trim() || undefined + })); + + function limparFiltroEmpresa() { + filtroEmpresa = ''; + } let modalAberto = $state(false); @@ -425,6 +434,32 @@ +
+
+
+
+ + +
+ +
+
+ {empresasQuery.data?.length ?? 0} de {empresasTotalQuery.data?.length ?? 0} +
+ +
+
+
+
+
{#if empresasQuery.isLoading} @@ -437,11 +472,21 @@
{:else if empresasQuery.data && empresasQuery.data.length === 0}
-

Nenhuma empresa cadastrada ainda.

- + {#if (empresasTotalQuery.data?.length ?? 0) === 0} +

Nenhuma empresa cadastrada ainda.

+ + {:else} +

Nenhum resultado encontrado.

+

+ Ajuste ou limpe o filtro para ver empresas. +

+ + {/if}
{:else if empresasQuery.data}
diff --git a/packages/backend/convex/empresas.ts b/packages/backend/convex/empresas.ts index 68963e2..511ed9c 100644 --- a/packages/backend/convex/empresas.ts +++ b/packages/backend/convex/empresas.ts @@ -5,15 +5,37 @@ import { getCurrentUserFunction } from './auth'; import type { Id } from './_generated/dataModel'; export const list = query({ - args: {}, - handler: async (ctx) => { + args: { + query: v.optional(v.string()) + }, + handler: async (ctx, args) => { await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { recurso: 'empresas', acao: 'listar' }); const empresas = await ctx.db.query('empresas').collect(); - return empresas; + const term = args.query?.trim(); + if (!term) return empresas; + + const termLower = term.toLowerCase(); + const termDigits = term.replace(/\D/g, ''); + + return empresas.filter((empresa) => { + const razao = (empresa.razao_social || '').toLowerCase(); + const fantasia = (empresa.nome_fantasia || '').toLowerCase(); + + const cnpjRaw = empresa.cnpj || ''; + const cnpjLower = cnpjRaw.toLowerCase(); + const cnpjDigits = cnpjRaw.replace(/\D/g, ''); + + const matchNome = razao.includes(termLower) || fantasia.includes(termLower); + const matchCnpj = termDigits + ? cnpjDigits.includes(termDigits) + : cnpjLower.includes(termLower); + + return matchNome || matchCnpj; + }); } });