202 lines
6.1 KiB
TypeScript
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
|
|
};
|
|
};
|