testes/src_2/hooks/useGlobalLoading.js

82 lines
2.1 KiB
JavaScript

import { create } from 'zustand';
/**
* Hook global para gerenciar o estado de carregamento da aplicação
* Útil para mostrar overlays de loading durante navegação entre rotas
* ou durante carregamento inicial de dados
*/
export const useGlobalLoading = create((set) => ({
// Estado de carregamento global
isLoading: false,
// Mensagem de loading customizada
loadingMessage: 'Carregando...',
// Contador de operações de loading ativas
// Permite múltiplas operações simultâneas
loadingCount: 0,
/**
* Inicia um estado de loading
* @param {string} message - Mensagem customizada (opcional)
*/
startLoading: (message = 'Carregando...') => set((state) => ({
loadingCount: state.loadingCount + 1,
isLoading: true,
loadingMessage: message
})),
/**
* Finaliza um estado de loading
* Só remove o loading quando todas as operações terminarem
*/
stopLoading: () => set((state) => {
const newCount = Math.max(0, state.loadingCount - 1);
return {
loadingCount: newCount,
isLoading: newCount > 0,
loadingMessage: newCount > 0 ? state.loadingMessage : 'Carregando...'
};
}),
/**
* Força a parada de todos os loadings
* Útil para casos de erro ou reset
*/
forceStopLoading: () => set({
loadingCount: 0,
isLoading: false,
loadingMessage: 'Carregando...'
}),
/**
* Atualiza apenas a mensagem de loading
* @param {string} message - Nova mensagem
*/
setLoadingMessage: (message) => set({ loadingMessage: message })
}));
/**
* Hook helper para executar operações assíncronas com loading automático
* @param {Function} asyncFn - Função assíncrona a ser executada
* @param {string} message - Mensagem de loading (opcional)
* @returns {Promise} - Resultado da função assíncrona
*/
export const useAsyncWithLoading = () => {
const { startLoading, stopLoading } = useGlobalLoading();
return async (asyncFn, message) => {
try {
startLoading(message);
const result = await asyncFn();
return result;
} catch (error) {
throw error;
} finally {
stopLoading();
}
};
};
export default useGlobalLoading;