refactor: otimização e refatoração do app
- Lazy loading de rotas com React.lazy + Suspense (code-splitting) - main.tsx reduzido de 378 para ~55 linhas (roteamento data-driven) - Novo routeConfig.ts e AppRoutes.tsx para configuração centralizada - 601 console.logs dos componentes core migrados para logger centralizado - Logger aprimorado com nível debug e tipagem melhorada - Imports mal posicionados corrigidos (OptimizedCache, PerformanceMonitor) - process.env.NODE_ENV substituído por import.meta.env.DEV (padrão Vite) - QueryClient com retry backoff exponencial, gcTime e refetchOnWindowFocus - Toaster duplicado removido do Layout.tsx (mantido no main.tsx) - Vite build: chunks adicionais para date-fns, jspdf, lucide-react - Dead code removido em ProtectedRouteByResource (branch unreachable) - Nenhuma lógica de negócios alterada
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
import React, { Suspense, lazy, useMemo } from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import { Layout } from './Layout';
|
||||
import { ProtectedRoute } from './ProtectedRoute';
|
||||
import { ProtectedAdminRoute } from './ProtectedAdminRoute';
|
||||
import { ProtectedRouteByResource } from './ProtectedRouteByResource';
|
||||
import { routeConfig, RouteDefinition } from '@/config/routeConfig';
|
||||
|
||||
// ============================================================================
|
||||
// Fallback de loading para Suspense
|
||||
// ============================================================================
|
||||
|
||||
const PageLoadingFallback = () => (
|
||||
<div className="flex items-center justify-center min-h-screen bg-background">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
|
||||
<span className="text-sm text-muted-foreground">Carregando...</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// Cache de componentes lazy para evitar re-criação a cada render
|
||||
// ============================================================================
|
||||
|
||||
const lazyComponentCache = new Map<string, React.LazyExoticComponent<React.ComponentType<any>>>();
|
||||
|
||||
function getLazyComponent(route: RouteDefinition): React.LazyExoticComponent<React.ComponentType<any>> {
|
||||
const key = route.path;
|
||||
if (!lazyComponentCache.has(key)) {
|
||||
lazyComponentCache.set(key, lazy(route.component));
|
||||
}
|
||||
return lazyComponentCache.get(key)!;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Funções de wrapping por tipo de guard
|
||||
// ============================================================================
|
||||
|
||||
function wrapWithGuard(
|
||||
element: React.ReactNode,
|
||||
guard: RouteDefinition['guard'],
|
||||
resourceKey?: string
|
||||
): React.ReactNode {
|
||||
switch (guard) {
|
||||
case 'public':
|
||||
return element;
|
||||
|
||||
case 'protected':
|
||||
return (
|
||||
<ProtectedRoute>
|
||||
<Layout>{element}</Layout>
|
||||
</ProtectedRoute>
|
||||
);
|
||||
|
||||
case 'admin':
|
||||
return (
|
||||
<ProtectedAdminRoute>
|
||||
<Layout>{element}</Layout>
|
||||
</ProtectedAdminRoute>
|
||||
);
|
||||
|
||||
case 'resource':
|
||||
return (
|
||||
<ProtectedRouteByResource resourceKey={resourceKey!}>
|
||||
<Layout>{element}</Layout>
|
||||
</ProtectedRouteByResource>
|
||||
);
|
||||
|
||||
default:
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Componente principal de rotas
|
||||
// ============================================================================
|
||||
|
||||
export function AppRoutes() {
|
||||
const routes = useMemo(
|
||||
() =>
|
||||
routeConfig.map((route) => {
|
||||
const LazyComponent = getLazyComponent(route);
|
||||
|
||||
const element = wrapWithGuard(
|
||||
<Suspense fallback={<PageLoadingFallback />}>
|
||||
<LazyComponent />
|
||||
</Suspense>,
|
||||
route.guard,
|
||||
route.resourceKey
|
||||
);
|
||||
|
||||
return <Route key={route.path} path={route.path} element={element} />;
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
// Lazy load da página NotFound
|
||||
const LazyNotFound = useMemo(() => lazy(() => import('@/pages/NotFound')), []);
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
{routes}
|
||||
<Route
|
||||
path="*"
|
||||
element={
|
||||
<Suspense fallback={<PageLoadingFallback />}>
|
||||
<LazyNotFound />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user