saveinmed/saveinmed-frontend/src/hooks/useProdutos.ts
Tiago Yamamoto b39caf0fd0 first commit
2025-12-17 13:58:26 -03:00

202 lines
6.1 KiB
TypeScript

import { useState, useCallback, useRef, useEffect } from 'react';
import { Models } from 'appwrite';
import { produtoService, ProdutoData } from '@/services/produtoService';
export type { ProdutoData };
export interface UseProdutosReturn {
produtos: Models.Document[];
loading: boolean;
isChangingPage: boolean;
isCreating: boolean;
error: string | null;
totalProdutos: number;
currentPage: number;
listarProdutos: (page?: number, search?: string) => Promise<void>;
buscarProdutos: (nome: string, page?: number) => Promise<void>;
cadastrarProduto: (data: ProdutoData) => Promise<boolean>;
atualizarProduto: (id: string, data: ProdutoData) => Promise<boolean>;
deletarProduto: (id: string) => Promise<boolean>;
setCurrentPage: (page: number) => void;
searchTerm: string;
setSearchTerm: (term: string) => void;
}
const PAGE_SIZE = 10;
export const useProdutos = (): UseProdutosReturn => {
const [produtos, setProdutos] = useState<Models.Document[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [totalProdutos, setTotalProdutos] = useState(0);
const [currentPage, setCurrentPage] = useState(1);
const [isChangingPage, setIsChangingPage] = useState(false);
const [isCreating, setIsCreating] = useState(false);
const [searchTerm, setSearchTerm] = useState('');
const isInitialMount = useRef(true);
const listarProdutos = useCallback(
async (page = currentPage, search = searchTerm) => {
setIsChangingPage(true);
setLoading(true);
setError(null);
try {
const response = search.trim()
? await produtoService.buscar(search, page, PAGE_SIZE)
: await produtoService.listar(page, PAGE_SIZE);
const docs = search.trim()
? response.documents.filter(produto =>
produto['catalogo-produtos']?.descricao
?.toLowerCase()
.includes(search.toLowerCase()) ||
produto['catalogo-produtos']?.['codigo-interno']
?.toLowerCase()
.includes(search.toLowerCase()) ||
produto.empresas?.['nome-fantasia']
?.toLowerCase()
.includes(search.toLowerCase())
)
: response.documents;
if (response.success) {
setProdutos(docs);
// Corrigir: usar o tamanho da lista filtrada quando há busca
setTotalProdutos(search.trim() ? docs.length : response.total || 0);
setCurrentPage(page);
setSearchTerm(search);
} else {
setError(response.error || 'Erro ao carregar produtos');
}
} catch (err) {
setError('Erro de conexão ao carregar produtos');
} finally {
setLoading(false);
setIsChangingPage(false);
}
},
[] // Removendo dependências circulares
);
const buscarProdutos = useCallback(
async (termo: string, page = 1) => {
setIsChangingPage(true);
setLoading(true);
setError(null);
try {
const response = await produtoService.buscar(termo, page, PAGE_SIZE);
const produtosFiltrados = response.documents.filter(produto =>
produto['catalogo-produtos']?.descricao
?.toLowerCase()
.includes(termo.toLowerCase()) ||
produto['catalogo-produtos']?.['codigo-interno']
?.toLowerCase()
.includes(termo.toLowerCase()) ||
produto.empresas?.['nome-fantasia']
?.toLowerCase()
.includes(termo.toLowerCase())
);
setProdutos(produtosFiltrados);
// Corrigir: usar o tamanho da lista filtrada quando há filtros aplicados
setTotalProdutos(termo.trim() ? produtosFiltrados.length : response.total);
setCurrentPage(page);
setSearchTerm(termo);
} catch (err: any) {
setError(err.message || 'Erro ao buscar produtos');
} finally {
setLoading(false);
setIsChangingPage(false);
}
},
[]
);
const cadastrarProduto = useCallback(async (formData: ProdutoData): Promise<boolean> => {
setIsCreating(true);
setError(null);
try {
const response = await produtoService.criar(formData);
if (response.success) {
await listarProdutos(1, searchTerm);
return true;
} else {
setError(response.error || 'Erro ao cadastrar produto');
return false;
}
} catch (err) {
setError('Erro de conexão ao cadastrar produto');
return false;
} finally {
setIsCreating(false);
}
}, [listarProdutos, searchTerm]);
const atualizarProduto = useCallback(async (id: string, formData: ProdutoData): Promise<boolean> => {
setLoading(true);
setError(null);
try {
const response = await produtoService.atualizar(id, formData);
if (response.success) {
await listarProdutos(currentPage, searchTerm);
return true;
} else {
setError(response.error || 'Erro ao atualizar produto');
return false;
}
} catch (err) {
setError('Erro de conexão ao atualizar produto');
return false;
} finally {
setLoading(false);
}
}, [listarProdutos, currentPage, searchTerm]);
const deletarProduto = useCallback(async (id: string): Promise<boolean> => {
setLoading(true);
setError(null);
try {
const response = await produtoService.deletar(id);
if (response.success) {
await listarProdutos(currentPage, searchTerm);
return true;
} else {
setError(response.error || 'Erro ao deletar produto');
return false;
}
} catch (err) {
setError('Erro de conexão ao deletar produto');
return false;
} finally {
setLoading(false);
}
}, [listarProdutos, currentPage, searchTerm]);
// Remover o useEffect problemático - a inicialização será feita no componente
return {
produtos,
loading,
isChangingPage,
isCreating,
error,
totalProdutos,
currentPage,
listarProdutos,
buscarProdutos,
cadastrarProduto,
atualizarProduto,
deletarProduto,
setCurrentPage,
searchTerm,
setSearchTerm
};
};