Frontend
Roteamento
React Router, rotas protegidas e lazy loading
React Router
O app usa createBrowserRouter do React Router com lazy loading via React.lazy.
Estrutura de rotas
Rotas públicas:
/login
/esqueci-senha
/redefinir-senha
/auth/callback
/termos, /privacidade
/p/:token ← proposta pública (sem login)
Rotas protegidas (AppLayout):
/dashboard
/primeiros-passos ← onboarding tour
/negocios
/negocios/:id ← hub do negócio
/contatos, /contatos/:id
/empresas, /empresas/:id
/atividades
/importar ← wizard de importação CSV/XLSX
/propostas
/propostas/:id
/propostas/:id/preview
/propostas/:id/wizard ← wizard de edição (25 passos)
/base-de-clientes
/base-de-clientes/nova
/base-de-clientes/:baseId ← análise (8 abas por slug)
/admin/workspaces ← painel super admin (apenas super admins)
/settings/empresa, /settings/equipe, /settings/metas
/settings/segmentos, /settings/pipelines, /settings/produtos
/settings/tipos-negocio, /settings/origens, /settings/atividades
/settings/motivos-perda, /settings/qualificacao
/settings/qualificacao/new, /settings/qualificacao/new/blank
/settings/qualificacao/:id/edit
/settings/campos, /settings/propostas, /settings/perfilProtectedRoute
Wrapper que verifica autenticação antes de renderizar rotas protegidas. Redireciona para /login se o usuário não estiver autenticado.
Lazy loading
Todas as pages são carregadas com React.lazy e envolvidas em SuspenseWrapper:
const DealsPage = lazy(() => import("@/features/deals/DealsPage"));
// Na rota:
element: (
<SuspenseWrapper>
<DealsPage />
</SuspenseWrapper>
)Constantes de rotas
As URLs são definidas em src/lib/constants.ts via ROUTES:
import { ROUTES } from "@/lib/constants";
navigate(ROUTES.deals);
navigate(ROUTES.settings.pipelines);