82 lines
2.1 KiB
JavaScript
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;
|