diff --git a/frontend/src/app/api/debug-registro/route.ts b/frontend/src/app/api/debug-registro/route.ts index f3aa88e..d2b758c 100644 --- a/frontend/src/app/api/debug-registro/route.ts +++ b/frontend/src/app/api/debug-registro/route.ts @@ -1,56 +1,63 @@ -// @ts-nocheck -import { NextRequest, NextResponse } from "next/server"; -import { databases } from "@/lib/appwrite"; -import { Query } from "@/lib/appwrite"; +import { NextRequest, NextResponse } from 'next/server'; +import { Client, Databases, Query } from 'node-appwrite'; -export const runtime = "edge"; +export const runtime = 'edge'; + +const createDatabasesClient = () => { + const apiKey = process.env.APPWRITE_API_KEY; + const endpoint = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT; + const projectId = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID; + + if (!apiKey || !endpoint || !projectId) { + throw new Error('Configurao do Appwrite ausente'); + } + + const client = new Client().setEndpoint(endpoint).setProject(projectId).setKey(apiKey); + return new Databases(client); +}; export async function GET(request: NextRequest) { - console.log("🔍 [API] Debug registro usuario..."); + console.log('[API] Debug registro usuario...'); try { const { searchParams } = new URL(request.url); - const userId = searchParams.get("userId"); + const userId = searchParams.get('userId'); if (!userId) { return NextResponse.json( - { success: false, error: "userId é obrigatório" }, + { success: false, error: 'userId obrigatrio' }, { status: 400 } ); } const databaseId = process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID!; - const collectionId = - process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_USUARIOS_ID!; + const collectionId = process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_USUARIOS_ID!; + const databases = createDatabasesClient(); - console.log("🔍 [API] Buscando usuário com auth-id-appwrite:", userId); + console.log('[API] Buscando usurio com auth-id-appwrite:', userId); - // Buscar usuário pelo auth-id-appwrite const response = await databases.listDocuments(databaseId, collectionId, [ - Query.equal("auth-id-appwrite", userId), + Query.equal('auth-id-appwrite', userId), Query.limit(1), ]); if (response.documents.length === 0) { - console.log("❌ [API] Usuário não encontrado"); + console.log('[API] Usurio no encontrado'); return NextResponse.json({ success: true, found: false, - message: "Usuário não encontrado na base de dados", + message: 'Usurio no encontrado na base de dados', }); } - const usuario = response.documents[0]; + const usuario = response.documents[0] as Record; - console.log("✅ [API] Usuário encontrado:", usuario.$id); - - // Análise detalhada dos dados const analise = { id: usuario.$id, - "auth-id-appwrite": usuario["auth-id-appwrite"], - "nome-civil": { - valor: usuario["nome-civil"], - preenchido: !!usuario["nome-civil"], + 'auth-id-appwrite': usuario['auth-id-appwrite'], + 'nome-civil': { + valor: usuario['nome-civil'], + preenchido: !!usuario['nome-civil'], }, cpf: { valor: usuario.cpf, @@ -64,9 +71,7 @@ export async function GET(request: NextRequest) { valido: Array.isArray(usuario.enderecos) && usuario.enderecos.length > 0 && - usuario.enderecos.some( - (endereco) => endereco && endereco.trim() !== "" - ), + usuario.enderecos.some((endereco: string) => endereco && endereco.trim() !== ''), }, empresas_array: { valor: usuario.empresas_array, @@ -80,29 +85,22 @@ export async function GET(request: NextRequest) { }, }; - const dadosFaltantes = []; + const dadosFaltantes: string[] = []; - // Verificar cada campo - if (!analise["nome-civil"].preenchido || !analise.cpf.preenchido) { - dadosFaltantes.push("Dados pessoais"); + if (!analise['nome-civil'].preenchido || !analise.cpf.preenchido) { + dadosFaltantes.push('Dados pessoais'); } if (!analise.enderecos.valido) { - dadosFaltantes.push("Endereço"); + dadosFaltantes.push('Endereo'); } if (!analise.empresas_array.valido) { - dadosFaltantes.push("Empresa"); + dadosFaltantes.push('Empresa'); } const isCompleto = dadosFaltantes.length === 0; - console.log("📋 [API] Análise completa:", { - isCompleto, - dadosFaltantes, - analise, - }); - return NextResponse.json({ success: true, found: true, @@ -112,11 +110,10 @@ export async function GET(request: NextRequest) { dadosCompletos: usuario, }); } catch (error) { - console.error("❌ [API] Erro ao debugar registro:", error); + console.error('[API] Erro ao debugar registro:', error); return NextResponse.json( - { success: false, error: "Erro ao verificar registro" }, + { success: false, error: 'Erro ao verificar registro' }, { status: 500 } ); } } - diff --git a/frontend/src/app/api/relacionar-categorias/route.ts b/frontend/src/app/api/relacionar-categorias/route.ts index dd7ac52..3075022 100644 --- a/frontend/src/app/api/relacionar-categorias/route.ts +++ b/frontend/src/app/api/relacionar-categorias/route.ts @@ -1,85 +1,74 @@ -// @ts-nocheck -import { NextRequest, NextResponse } from "next/server"; -import { databases, Query } from "@/lib/appwrite"; +// @ts-nocheck +import { NextRequest, NextResponse } from 'next/server'; +import { Client, Databases, Query } from 'node-appwrite'; -// Runtime edge para melhor performance -export const runtime = "edge"; +export const runtime = 'edge'; const DATABASE_ID = process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID!; -const COLLECTION_CATALOGO = - process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_CATALOGO_PRODUTOS_ID!; -const COLLECTION_CATEGORIAS = - process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_CATEGORIAS_ID!; +const COLLECTION_CATALOGO = process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_CATALOGO_PRODUTOS_ID!; +const COLLECTION_CATEGORIAS = process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_CATEGORIAS_ID!; + +const createDatabasesClient = () => { + const apiKey = process.env.APPWRITE_API_KEY; + const endpoint = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT; + const projectId = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID; + + if (!apiKey || !endpoint || !projectId) { + throw new Error('Configurao do Appwrite ausente'); + } + + const client = new Client().setEndpoint(endpoint).setProject(projectId).setKey(apiKey); + return new Databases(client); +}; -// Mapeamento de produtos para categorias const mapeamentoCategorias: { [key: string]: string } = { - dipirona: "RX", - cetaphil: "Dermo", - sabonete: "Dermo", - dermo: "Dermo", - vitamina: "Nutrição", - suplemento: "Nutrição", - generico: "Genérico", - diabetes: "Diabetes", - insulina: "Diabetes", - medicamento: "RX", - remedio: "RX", + dipirona: 'RX', + cetaphil: 'Dermo', + sabonete: 'Dermo', + dermo: 'Dermo', + vitamina: 'Nutrio', + suplemento: 'Nutrio', + generico: 'Genrico', + diabetes: 'Diabetes', + insulina: 'Diabetes', + medicamento: 'RX', + remedio: 'RX', }; export async function POST(request: NextRequest) { try { - console.log("🔗 [API] Iniciando relacionamento de categorias..."); + const databases = createDatabasesClient(); - // 1. Buscar todas as categorias const categoriasResponse = await databases.listDocuments( DATABASE_ID, COLLECTION_CATEGORIAS, [Query.limit(100)] ); - console.log( - `📋 [API] Encontradas ${categoriasResponse.documents.length} categorias` - ); - const categorias = categoriasResponse.documents; const categoriasPorNome: { [key: string]: string } = {}; - categorias.forEach((cat) => { - categoriasPorNome[cat.nome.toLowerCase()] = cat.$id; + categorias.forEach((cat: any) => { + categoriasPorNome[String(cat.nome).toLowerCase()] = cat.$id; }); - console.log( - "📋 [API] Categorias disponíveis:", - Object.keys(categoriasPorNome) - ); - - // 2. Buscar todos os produtos do catálogo const produtosResponse = await databases.listDocuments( DATABASE_ID, COLLECTION_CATALOGO, [Query.limit(100)] ); - console.log( - `📦 [API] Encontrados ${produtosResponse.documents.length} produtos` - ); - const produtos = produtosResponse.documents; const resultados = []; - // 3. Para cada produto, determinar e atribuir categoria - for (const produto of produtos) { - const descricao = produto.descricao.toLowerCase(); + for (const produto of produtos as any[]) { + const descricao = String(produto.descricao || '').toLowerCase(); let categoriaEncontrada = null; - let nomeCategoria = ""; + let nomeCategoria = ''; - // Tentar encontrar categoria por palavra-chave - for (const [palavra, nomeCategoriaMapeada] of Object.entries( - mapeamentoCategorias - )) { + for (const [palavra, nomeCategoriaMapeada] of Object.entries(mapeamentoCategorias)) { if (descricao.includes(palavra)) { - const categoriaId = - categoriasPorNome[nomeCategoriaMapeada.toLowerCase()]; + const categoriaId = categoriasPorNome[nomeCategoriaMapeada.toLowerCase()]; if (categoriaId) { categoriaEncontrada = categoriaId; nomeCategoria = nomeCategoriaMapeada; @@ -88,26 +77,17 @@ export async function POST(request: NextRequest) { } } - // Se não encontrou, usar RX como padrão if (!categoriaEncontrada) { - categoriaEncontrada = - categoriasPorNome["rx"] || categoriasPorNome["medicamento"]; - nomeCategoria = "RX"; + categoriaEncontrada = categoriasPorNome['rx'] || categoriasPorNome['medicamento']; + nomeCategoria = 'RX'; } - console.log( - `📦 [API] Produto: ${produto.descricao} → Categoria: ${nomeCategoria}` - ); - try { - // Atualizar produto com categoria await databases.updateDocument( DATABASE_ID, COLLECTION_CATALOGO, produto.$id, - { - categorias: categoriaEncontrada, - } + { categorias: categoriaEncontrada } ); resultados.push({ @@ -116,63 +96,47 @@ export async function POST(request: NextRequest) { categoria: nomeCategoria, sucesso: true, }); - - console.log( - `✅ [API] Produto ${produto.$id} atualizado com categoria ${nomeCategoria}` - ); } catch (updateError) { - console.error( - `❌ [API] Erro ao atualizar produto ${produto.$id}:`, - updateError - ); - resultados.push({ produtoId: produto.$id, descricao: produto.descricao, categoria: nomeCategoria, sucesso: false, - erro: - updateError instanceof Error - ? updateError.message - : String(updateError), + erro: updateError instanceof Error ? updateError.message : String(updateError), }); } - // Pequena pausa para não sobrecarregar await new Promise((resolve) => setTimeout(resolve, 100)); } - console.log("✅ [API] Processo de relacionamento concluído!"); - return NextResponse.json({ sucesso: true, - mensagem: "Relacionamento de categorias concluído", + mensagem: 'Relacionamento de categorias concludo', totalProdutos: produtos.length, - resultados: resultados, + resultados, categoriasDisponiveis: Object.keys(categoriasPorNome), }); } catch (error) { - console.error("❌ [API] Erro no relacionamento:", error); + console.error('[API] Erro no relacionamento:', error); return NextResponse.json( { sucesso: false, erro: error instanceof Error ? error.message : String(error), - mensagem: "Erro ao relacionar categorias", + mensagem: 'Erro ao relacionar categorias', }, { status: 500 } ); } } -export async function GET(request: NextRequest) { +export async function GET(_request: NextRequest) { return NextResponse.json({ - mensagem: "Use POST para executar o relacionamento de categorias", + mensagem: 'Use POST para executar o relacionamento de categorias', instrucoes: [ - "1. Faça uma requisição POST para esta rota", - "2. O sistema irá relacionar automaticamente produtos com categorias", - "3. Após a execução, vá em /produtos para verificar", + '1. Faa uma requisio POST para esta rota', + '2. O sistema ir relacionar automaticamente produtos com categorias', + '3. Aps a execuo, v em /produtos para verificar', ], }); } - diff --git a/frontend/src/app/api/relacionar-produto/route.ts b/frontend/src/app/api/relacionar-produto/route.ts index 8cc9e14..35dc16c 100644 --- a/frontend/src/app/api/relacionar-produto/route.ts +++ b/frontend/src/app/api/relacionar-produto/route.ts @@ -1,35 +1,36 @@ -import { NextRequest, NextResponse } from "next/server"; -import { databases } from "@/lib/appwrite"; +import { NextRequest, NextResponse } from 'next/server'; +import { Client, Databases } from 'node-appwrite'; -// Runtime edge para melhor performance -export const runtime = "edge"; +export const runtime = 'edge'; const DATABASE_ID = process.env.NEXT_PUBLIC_APPWRITE_DATABASE_ID!; -const COLLECTION_CATALOGO = - process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_CATALOGO_PRODUTOS_ID!; +const COLLECTION_CATALOGO = process.env.NEXT_PUBLIC_APPWRITE_COLLECTION_CATALOGO_PRODUTOS_ID!; + +const createDatabasesClient = () => { + const apiKey = process.env.APPWRITE_API_KEY; + const endpoint = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT; + const projectId = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID; + + if (!apiKey || !endpoint || !projectId) { + throw new Error('Configurao do Appwrite ausente'); + } + + const client = new Client().setEndpoint(endpoint).setProject(projectId).setKey(apiKey); + return new Databases(client); +}; export async function POST(request: NextRequest) { try { const { produtoId, categoriaId, subcategoriaId } = await request.json(); - console.log("🔗 [API] Relacionando produto com categoria:", { - produtoId, - categoriaId, - subcategoriaId, - }); - if (!produtoId?.trim()) { return NextResponse.json( - { - sucesso: false, - erro: "ID do produto é obrigatório", - }, + { sucesso: false, erro: 'ID do produto obrigatrio' }, { status: 400 } ); } - // Preparar dados para atualização - const updateData: any = {}; + const updateData: Record = {}; if (categoriaId?.trim()) { updateData.categoria = categoriaId.trim(); @@ -41,15 +42,12 @@ export async function POST(request: NextRequest) { if (Object.keys(updateData).length === 0) { return NextResponse.json( - { - sucesso: false, - erro: "Pelo menos uma categoria ou subcategoria deve ser fornecida", - }, + { sucesso: false, erro: 'Pelo menos uma categoria ou subcategoria deve ser fornecida' }, { status: 400 } ); } - // Atualizar produto no catálogo + const databases = createDatabasesClient(); const produtoAtualizado = await databases.updateDocument( DATABASE_ID, COLLECTION_CATALOGO, @@ -57,24 +55,19 @@ export async function POST(request: NextRequest) { updateData ); - console.log( - "✅ [API] Produto relacionado com sucesso:", - produtoAtualizado.$id - ); - return NextResponse.json({ sucesso: true, produto: produtoAtualizado, - mensagem: "Produto relacionado com categoria/subcategoria com sucesso!", + mensagem: 'Produto relacionado com categoria/subcategoria com sucesso!', }); } catch (error) { - console.error("❌ [API] Erro ao relacionar produto:", error); + console.error('[API] Erro ao relacionar produto:', error); return NextResponse.json( { sucesso: false, - erro: error instanceof Error ? error.message : "Erro desconhecido", - mensagem: "Erro ao relacionar produto com categoria", + erro: error instanceof Error ? error.message : 'Erro desconhecido', + mensagem: 'Erro ao relacionar produto com categoria', }, { status: 500 } ); diff --git a/frontend/src/components/CatalogoComCarrinho.tsx b/frontend/src/components/CatalogoComCarrinho.tsx index fec29e0..1b39f69 100644 --- a/frontend/src/components/CatalogoComCarrinho.tsx +++ b/frontend/src/components/CatalogoComCarrinho.tsx @@ -1,11 +1,11 @@ -// @ts-nocheck +// @ts-nocheck import React, { useState, useEffect } from 'react'; -import { Models } from '@/lib/appwrite'; import { ShoppingCartIcon, MinusIcon } from '@heroicons/react/24/outline'; import { useCatalogoProdutos } from '@/hooks/useCatalogoProdutos'; +import { CatalogoProdutoDocument } from '@/types/legacyEntities'; interface ItemCarrinho { - produto: Models.Document; + produto: CatalogoProdutoDocument; quantidade: number; } @@ -14,22 +14,22 @@ interface CatalogoComCarrinhoProps { } const CatalogoComCarrinho: React.FC = ({ onAdicionarAoCarrinho }) => { - const { catalogoProdutos, loading, listarCatalogo, totalCatalogoProdutos, currentPage } = useCatalogoProdutos(); + const { catalogoProdutos, loading, listarCatalogo, totalCatalogoProdutos } = useCatalogoProdutos(); const [carrinho, setCarrinho] = useState([]); const [termoBusca, setTermoBusca] = useState(''); const [quantidades, setQuantidades] = useState>({}); useEffect(() => { listarCatalogo(1, termoBusca); - }, [termoBusca]); + }, [termoBusca, listarCatalogo]); - const adicionarAoCarrinho = (produto: Models.Document) => { + const adicionarAoCarrinho = (produto: CatalogoProdutoDocument) => { const quantidade = quantidades[produto.$id] || 1; const itemExistente = carrinho.find(item => item.produto.$id === produto.$id); - + if (itemExistente) { - const novoCarrinho = carrinho.map(item => - item.produto.$id === produto.$id + const novoCarrinho = carrinho.map(item => + item.produto.$id === produto.$id ? { ...item, quantidade: item.quantidade + quantidade } : item ); @@ -38,17 +38,14 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo const novoItem: ItemCarrinho = { produto, quantidade }; setCarrinho([...carrinho, novoItem]); } - - // Reset quantidade para 1 após adicionar + setQuantidades(prev => ({ ...prev, [produto.$id]: 1 })); - + if (onAdicionarAoCarrinho) { onAdicionarAoCarrinho({ produto, quantidade }); } }; - - const removerDoCarrinho = (produtoId: string) => { setCarrinho(carrinho.filter(item => item.produto.$id !== produtoId)); }; @@ -60,12 +57,10 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo }, 0); }; - const formatarPreco = (preco: number) => { - return new Intl.NumberFormat('pt-BR', { - style: 'currency', - currency: 'BRL' - }).format(preco); - }; + const formatarPreco = (preco: number) => new Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL' + }).format(preco); if (loading) { return ( @@ -77,7 +72,6 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo return (
- {/* Barra de Busca */}
= ({ onAdicionarAo
- {/* Lista de Produtos */}
-

Catálogo de Produtos

+

Catlogo de Produtos

{totalCatalogoProdutos} produtos encontrados

- +
{catalogoProdutos.map((produto) => { const preco = produto.pmc || produto['preco-fabrica'] || 0; const quantidade = quantidades[produto.$id] || 1; - + return (
-

- {produto.descricao} -

+

{produto.descricao}

- Código: {produto['codigo-interno']} - {produto['codigo-ean'] && ( - EAN: {produto['codigo-ean']} - )} + Cdigo: {produto['codigo-interno']} + {produto['codigo-ean'] && EAN: {produto['codigo-ean']}} {produto.laboratorios?.length > 0 ? ( Lab: {produto.laboratorios[0].nome || produto.laboratorios[0]} ) : produto.laboratorio && ( @@ -131,29 +120,21 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo )}
- - {formatarPreco(preco)} - + {formatarPreco(preco)} {produto['preco-fabrica'] && produto.pmc && produto['preco-fabrica'] !== produto.pmc && ( - - {formatarPreco(produto['preco-fabrica'])} - + {formatarPreco(produto['preco-fabrica'])} )} {produto['desconto-comercial'] && produto['desconto-comercial'] > 0 && ( -
- Desconto: {formatarPreco(produto['desconto-comercial'])} -
+
Desconto: {formatarPreco(produto['desconto-comercial'])}
)}
- +
- {/* Quantidade */}
Qtd: {quantidade}
- - {/* Botão Adicionar ao Carrinho */} +
- {/* Carrinho */}
@@ -179,7 +159,7 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo Carrinho ({carrinho.length})
- +
{carrinho.length === 0 ? (

Carrinho vazio

@@ -190,17 +170,11 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo return (
-

- {item.produto.descricao} -

-

- {formatarPreco(preco)} x {item.quantidade} -

+

{item.produto.descricao}

+

{formatarPreco(preco)} x {item.quantidade}

- - {formatarPreco(preco * item.quantidade)} - + {formatarPreco(preco * item.quantidade)}
); })} - +
Total: - - {formatarPreco(calcularTotal())} - + {formatarPreco(calcularTotal())}
- + @@ -235,4 +207,3 @@ const CatalogoComCarrinho: React.FC = ({ onAdicionarAo }; export default CatalogoComCarrinho; - diff --git a/frontend/src/components/CatalogoProdutosCompras.tsx b/frontend/src/components/CatalogoProdutosCompras.tsx index 3e8cc2e..518290a 100644 --- a/frontend/src/components/CatalogoProdutosCompras.tsx +++ b/frontend/src/components/CatalogoProdutosCompras.tsx @@ -1,12 +1,12 @@ -// @ts-nocheck +// @ts-nocheck 'use client'; import React, { useState } from 'react'; -import { Models } from '@/lib/appwrite'; import { useCarrinho } from '@/contexts/CarrinhoContext'; -import { ShoppingCartIcon, PlusIcon, CheckIcon } from '@heroicons/react/24/outline'; +import { ShoppingCartIcon, CheckIcon } from '@heroicons/react/24/outline'; +import { CatalogoProdutoDocument } from '@/types/legacyEntities'; interface CatalogoProdutosComprasProps { - produtos: Models.Document[]; + produtos: CatalogoProdutoDocument[]; loading: boolean; isChangingPage?: boolean; totalProdutos: number; @@ -14,7 +14,7 @@ interface CatalogoProdutosComprasProps { pageSize: number; onPrevPage: () => void; onNextPage: () => void; - onRowClick?: (produto: Models.Document) => void; + onRowClick?: (produto: CatalogoProdutoDocument) => void; } const CatalogoProdutosCompras: React.FC = ({ @@ -31,27 +31,23 @@ const CatalogoProdutosCompras: React.FC = ({ const { adicionarItem } = useCarrinho(); const [produtosAdicionados, setProdutosAdicionados] = useState>(new Set()); - const formatarPreco = (preco: number) => { - return new Intl.NumberFormat('pt-BR', { - style: 'currency', - currency: 'BRL' - }).format(preco); - }; + const formatarPreco = (preco: number) => new Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL' + }).format(preco); - const obterPreco = (produto: Models.Document) => { + const obterPreco = (produto: CatalogoProdutoDocument) => { return produto['preco-unitario'] || produto['preco-fabrica'] || produto.pmc || 0; }; - const obterQuantidadeDisponivel = (produto: Models.Document) => { - // Usar quantidade real do produto ou retornar 0 se não informado - return (produto as any).quantidade || (produto as any).estoque || 0; + const obterQuantidadeDisponivel = (produto: CatalogoProdutoDocument) => { + return produto.quantidade || produto.estoque || 0; }; - const handleAdicionarAoCarrinho = (produto: Models.Document, event: React.MouseEvent) => { - event.stopPropagation(); // Evita que o clique no botão dispare o onRowClick - adicionarItem(produto, 1); - - // Adicionar feedback visual temporário + const handleAdicionarAoCarrinho = (produto: CatalogoProdutoDocument, event: React.MouseEvent) => { + event.stopPropagation(); + adicionarItem(produto as any, 1); + setProdutosAdicionados(prev => new Set(prev).add(produto.$id)); setTimeout(() => { setProdutosAdicionados(prev => { @@ -79,7 +75,6 @@ const CatalogoProdutosCompras: React.FC = ({ return (
- {/* Grid de Produtos */}
{produtos.map(produto => { @@ -87,20 +82,19 @@ const CatalogoProdutosCompras: React.FC = ({ const quantidadeDisponivel = obterQuantidadeDisponivel(produto); const foiAdicionado = produtosAdicionados.has(produto.$id); const estoqueStatus = quantidadeDisponivel > 20 ? 'alto' : quantidadeDisponivel > 5 ? 'medio' : 'baixo'; - + return (
onRowClick && onRowClick(produto)} > - {/* Indicador de Estoque Baixo */} {estoqueStatus === 'baixo' && (
@@ -111,36 +105,25 @@ const CatalogoProdutosCompras: React.FC = ({ {estoqueStatus === 'medio' && (
- Estoque Médio + Estoque Mdio
)} - {/* Header do Card */}
-

- {produto.descricao} -

-

- Código: {produto['codigo-interno']} -

+

{produto.descricao}

+

Cdigo: {produto['codigo-interno']}

- {/* Informações do Produto */}
- {produto['codigo-ean'] && ( -

- EAN: {produto['codigo-ean']} -

- )} - - {/* Laboratório */} + {produto['codigo-ean'] &&

EAN: {produto['codigo-ean']}

} + {produto.laboratorios?.length > 0 ? (
- {produto.laboratorios.slice(0, 2).map((lab: any) => ( - - {lab.nome} + {produto.laboratorios.slice(0, 2).map((lab: any, index: number) => ( + + {lab.nome || lab} ))} {produto.laboratorios.length > 2 && ( @@ -148,24 +131,22 @@ const CatalogoProdutosCompras: React.FC = ({ )}
) : ( - Sem laboratório + Sem laboratrio )} - {/* Categoria */} {produto.categorias && ( {produto.categorias.nome} )} - {/* Quantidade Disponível */}
- Disponível: + Disponvel: {quantidadeDisponivel} unidades @@ -173,44 +154,32 @@ const CatalogoProdutosCompras: React.FC = ({
- {/* Seção de Preços */}
- {/* Preço Principal */}
- Preço: + Preo: {preco > 0 ? ( - - {formatarPreco(preco)} - + {formatarPreco(preco)} ) : ( - - Não informado - + No informado )}
- {/* Preços Adicionais */}
{produto['preco-fabrica'] && produto['preco-fabrica'] !== preco && (
- Fábrica - - {formatarPreco(produto['preco-fabrica'])} - + Fbrica + {formatarPreco(produto['preco-fabrica'])}
)} {produto.pmc && produto.pmc !== preco && (
PMC - - {formatarPreco(produto.pmc)} - + {formatarPreco(produto.pmc)}
)}
- {/* Botão de Ação */}
- {/* Mensagem quando não há produtos */} {produtos.length === 0 && (

Nenhum produto encontrado

-

Tente ajustar os filtros de busca ou verifique se há produtos cadastrados.

+

Tente ajustar os filtros de busca ou verifique se h produtos cadastrados.

)}
- {/* Paginação */} {produtos.length > 0 && (
@@ -263,15 +230,13 @@ const CatalogoProdutosCompras: React.FC = ({ > Anterior - - Página {currentPage} de {totalPages} - + Pgina {currentPage} de {totalPages}
diff --git a/frontend/src/services/catalogoProdutoService.ts b/frontend/src/services/catalogoProdutoService.ts index 28367ec..657f9ee 100644 --- a/frontend/src/services/catalogoProdutoService.ts +++ b/frontend/src/services/catalogoProdutoService.ts @@ -1,18 +1,8 @@ -import { Models } from "@/lib/appwrite"; +import { CatalogoProdutoDocument } from '@/types/legacyEntities'; -export interface CatalogoProdutoData extends Models.Document { - descricao: string; - nome?: string; - "codigo-interno"?: string; - "codigo-ean"?: string; - "preco-original"?: number; - "preco-atual"?: number; - "preco-fabrica"?: number; - pmc?: number; - quantidade?: number; - laboratorio?: string; - categoria?: string; - subcategoria?: string; +export interface CatalogoProdutoData extends CatalogoProdutoDocument { + 'preco-original'?: number; + 'preco-atual'?: number; } export interface ApiResponse { @@ -28,14 +18,14 @@ export interface PaginatedResponse extends ApiResponse { } class CatalogoProdutoService { - private readonly baseUrl = "/api/catalogo-produtos"; + private readonly baseUrl = '/api/catalogo-produtos'; private async parseResponse(response: Response): Promise { const data = await response.json().catch(() => ({})); if (!response.ok) { const message = - typeof data?.error === "string" + typeof data?.error === 'string' ? data.error : `Erro HTTP ${response.status}`; throw new Error(message); @@ -44,36 +34,36 @@ class CatalogoProdutoService { return data as T; } - async listar(page = 1, limit = 10, termo = ""): Promise> { + async listar(page = 1, limit = 10, termo = ''): Promise> { const params = new URLSearchParams({ page: String(page), limit: String(limit), }); if (termo.trim()) { - params.set("q", termo.trim()); + params.set('q', termo.trim()); } const response = await fetch(`${this.baseUrl}?${params.toString()}`, { - method: "GET", - cache: "no-store", + method: 'GET', + cache: 'no-store', }); const data = await this.parseResponse>>(response); const documents = Array.isArray(data.documents) ? data.documents : []; const filteredDocuments = termo.trim() - ? documents.filter((produto) => { + ? documents.filter(produto => { const values = [ produto.descricao, produto.nome, - produto["codigo-interno"], - produto["codigo-ean"], + produto['codigo-interno'], + produto['codigo-ean'], ] .filter(Boolean) - .map((value) => String(value).toLowerCase()); + .map(value => String(value).toLowerCase()); - return values.some((value) => value.includes(termo.trim().toLowerCase())); + return values.some(value => value.includes(termo.trim().toLowerCase())); }) : documents; @@ -90,8 +80,8 @@ class CatalogoProdutoService { async obterPorId(id: string): Promise> { const response = await fetch(`${this.baseUrl}/${id}`, { - method: "GET", - cache: "no-store", + method: 'GET', + cache: 'no-store', }); const data = await this.parseResponse>(response); @@ -103,9 +93,9 @@ class CatalogoProdutoService { async criar(produtoData: Partial): Promise> { const response = await fetch(this.baseUrl, { - method: "POST", + method: 'POST', headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify(produtoData), }); @@ -119,9 +109,9 @@ class CatalogoProdutoService { async atualizar(id: string, produtoData: Partial): Promise> { const response = await fetch(`${this.baseUrl}/${id}`, { - method: "PATCH", + method: 'PATCH', headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, body: JSON.stringify(produtoData), }); @@ -135,7 +125,7 @@ class CatalogoProdutoService { async deletar(id: string): Promise> { const response = await fetch(`${this.baseUrl}/${id}`, { - method: "DELETE", + method: 'DELETE', }); await this.parseResponse>(response); @@ -145,4 +135,3 @@ class CatalogoProdutoService { export const catalogoProdutoService = new CatalogoProdutoService(); export type ProdutoData = CatalogoProdutoData; -