japhub-shared
v1.0.2
Published
Biblioteca compartilhada para o sistema JAPHub
Downloads
283
Maintainers
Readme
@japhub/shared
Biblioteca compartilhada para o sistema JAPHub, fornecendo componentes, hooks e utilitários padronizados para todas as aplicações.
🚀 Instalação
# No diretório de cada aplicação
npm install ../shared📦 Componentes
ErrorBoundary
Captura erros React e exibe uma tela de erro amigável.
import { ErrorBoundary } from '@japhub/shared';
function App() {
return (
<ErrorBoundary>
<YourApp />
</ErrorBoundary>
);
}LoadingSpinner
Componente de loading padronizado.
import { LoadingSpinner, LoadingCard, LoadingTable } from '@japhub/shared';
// Spinner simples
<LoadingSpinner size="lg" text="Carregando..." />
// Loading de tela cheia
<LoadingSpinner fullScreen text="Carregando aplicação..." />
// Skeleton para cards
<LoadingCard />
// Skeleton para tabelas
<LoadingTable rows={5} columns={4} />ErrorToast
Sistema de toast para erros.
import { ErrorToast, useErrorToast } from '@japhub/shared';
function MyComponent() {
const { error, showError, dismissError } = useErrorToast();
return (
<>
<button onClick={() => showError(someApiError)}>
Mostrar Erro
</button>
<ErrorToast error={error} onDismiss={dismissError} />
</>
);
}🎣 Hooks
useApi
Hook para chamadas de API com estados de loading e erro.
import { useApi, useGet, usePost } from '@japhub/shared';
// Hook genérico
function MyComponent() {
const { data, loading, error, execute, retry } = useApi(
(apiClient) => apiClient.get('/api/forms'),
{ immediate: true }
);
if (loading.isLoading) return <LoadingSpinner />;
if (error.hasError) return <div>Erro: {error.error?.userMessage}</div>;
return <div>{JSON.stringify(data)}</div>;
}
// Hook específico para GET
function FormsList() {
const { data: forms, loading, error } = useGet('/api/forms', {
immediate: true,
onSuccess: (data) => console.log('Formulários carregados:', data),
onError: (error) => console.error('Erro ao carregar:', error)
});
return (
<div>
{loading.isLoading && <LoadingSpinner />}
{error.hasError && <div>Erro: {error.error?.userMessage}</div>}
{forms && forms.map(form => <div key={form.id}>{form.title}</div>)}
</div>
);
}🔧 Serviços
ApiClient
Cliente HTTP unificado com retry automático e tratamento de erros.
import { ApiClient } from '@japhub/shared';
const apiClient = new ApiClient({
baseURL: 'http://localhost:3001',
timeout: 10000,
retries: 3
});
// Uso direto
const forms = await apiClient.get('/api/forms');
const newForm = await apiClient.post('/api/forms', formData);ErrorHandler
Sistema centralizado de tratamento de erros.
import { ErrorHandler } from '@japhub/shared';
const errorHandler = ErrorHandler.getInstance();
try {
await someApiCall();
} catch (error) {
const apiError = errorHandler.handle(error, '/api/endpoint');
// apiError contém informações padronizadas sobre o erro
}📝 Tipos
ApiError
import { ApiError, ErrorType } from '@japhub/shared';
const error = new ApiError({
type: ErrorType.NETWORK_ERROR,
message: 'Failed to fetch',
userMessage: 'Erro de conexão. Verifique sua internet.',
statusCode: 0,
timestamp: new Date().toISOString()
});ApiResponse
import { ApiResponse } from '@japhub/shared';
const response: ApiResponse<Form[]> = {
success: true,
data: forms,
message: 'Formulários carregados com sucesso',
metadata: {
timestamp: '2024-01-01T00:00:00Z',
version: '1.0.0'
}
};🛠️ Utilitários
Helpers
import {
formatDate,
formatRelativeDate,
isValidEmail,
debounce,
generateId
} from '@japhub/shared';
// Formatação de datas
const formatted = formatDate(new Date());
const relative = formatRelativeDate('2024-01-01T00:00:00Z');
// Validação
const isValid = isValidEmail('[email protected]');
// Debounce
const debouncedSearch = debounce(searchFunction, 300);
// ID único
const id = generateId('form');Constantes
import { API_ENDPOINTS, ERROR_MESSAGES } from '@japhub/shared';
// Endpoints padronizados
const formsUrl = API_ENDPOINTS.FORMS.LIST;
const formUrl = API_ENDPOINTS.FORMS.GET('123');
// Mensagens de erro
const networkError = ERROR_MESSAGES.NETWORK_ERROR;🔄 Migração
Antes (sem padronização)
// Cada app tinha seu próprio tratamento
try {
const response = await fetch('/api/forms');
const data = await response.json();
setForms(data);
} catch (error) {
console.error('Erro:', error);
toast.error('Erro ao carregar formulários');
}Depois (com padronização)
// Uso padronizado em todos os apps
const { data: forms, loading, error } = useGet('/api/forms', {
immediate: true,
onError: (error) => showError(error)
});
if (loading.isLoading) return <LoadingSpinner />;
if (error.hasError) return <ErrorToast error={error.error} />;📊 Benefícios
- ✅ Consistência: Mesma experiência em todas as aplicações
- ✅ Reutilização: Código compartilhado e manutenível
- ✅ Padronização: Tratamento de erros unificado
- ✅ Produtividade: Hooks e componentes prontos para uso
- ✅ Debugging: Logs estruturados e informativos
- ✅ TypeScript: Tipagem completa e intellisense
