Files
sar/apps/web/src/lib/router.tsx
julian 400fcb3360 feat(web+api): ficha do cliente — contatos, CTR, NF-e, pedidos e produtos
- Contatos: grid de cards 3 colunas, botão "Novo Contato" no topo da página
- Sync ERP↔SAR corrigido: vw_contatos aceita formato COR#<id>, trigger normaliza id_empresa (9001→1)
- CTR + NF-e: layout 50/50 — lista de títulos abertos com badge vencido/a vencer e lista de notas com botão copiar chave NF-e
- Histórico de pedidos: UNION SAR+ERP, top 5 + modal "Ver todos"
- Produtos mais comprados: top 5 com último preço + modal "Ver todos"
- Novos endpoints: ctr-list, notas, orders-history, top-produtos
- AppShell: overflow-x travado, sem scroll horizontal na aplicação

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 14:13:21 +00:00

168 lines
4.0 KiB
TypeScript

import {
createRouter,
createRootRoute,
createRoute,
Outlet,
notFound,
} from '@tanstack/react-router';
import { Typography } from 'antd';
import { AppShell } from '../components/layout/AppShell';
import { RepPainel } from '../cockpits/rep/RepPainel';
import { ClientsPage } from '../cockpits/rep/ClientsPage';
import { ClientDetailPage } from '../cockpits/rep/ClientDetailPage';
import { OrdersPage } from '../cockpits/rep/OrdersPage';
import { OrderDetailPage } from '../cockpits/rep/OrderDetailPage';
import { OrderPrintPage } from '../cockpits/rep/OrderPrintPage';
import { NewClientPage } from '../cockpits/rep/NewClientPage';
import { NewOrderPage } from '../cockpits/rep/NewOrderPage';
import { CatalogPage } from '../cockpits/rep/CatalogPage';
import { OrdersErpPage } from '../cockpits/rep/OrdersErpPage';
import { RelatoriosPage } from '../cockpits/rep/RelatoriosPage';
import { ApprovalQueuePage } from '../cockpits/supervisor/ApprovalQueuePage';
import { SupervisorPainel } from '../cockpits/supervisor/SupervisorPainel';
import { authStore } from './auth-store';
function getRoleFromToken(): string {
const token = authStore.get();
if (!token) return 'rep';
try {
const payload = JSON.parse(atob(token.split('.')[1] ?? ''));
return (payload.role as string) ?? 'rep';
} catch {
return 'rep';
}
}
function HomeRoute() {
const role = getRoleFromToken();
return role === 'supervisor' || role === 'manager' ? <SupervisorPainel /> : <RepPainel />;
}
function NotFoundPage() {
return (
<div style={{ padding: 48, textAlign: 'center' }}>
<Typography.Title level={3} type="secondary">
Página não encontrada
</Typography.Title>
</div>
);
}
// Suprime aviso de notFound não utilizado — usado via throw notFound() em loaders futuros.
void notFound;
const rootRoute = createRootRoute({
component: () => (
<AppShell>
<Outlet />
</AppShell>
),
notFoundComponent: NotFoundPage,
});
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: HomeRoute,
});
const rafaelRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/rep',
component: RepPainel,
});
const clientesRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/clientes',
component: ClientsPage,
});
const novoClienteRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/clientes/novo',
component: NewClientPage,
});
const clienteDetailRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/clientes/$id',
component: ClientDetailPage,
});
const pedidosRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/pedidos',
component: OrdersPage,
});
const novoOrderRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/pedidos/novo',
component: NewOrderPage,
});
const pedidoDetailRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/pedidos/$id',
component: OrderDetailPage,
});
const pedidoPrintRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/pedidos/$id/imprimir',
component: OrderPrintPage,
});
const catalogoRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/catalogo',
component: CatalogPage,
});
const pedidosErpRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/pedidos-erp',
component: OrdersErpPage,
});
const relatoriosRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/relatorios',
component: RelatoriosPage,
});
const aprovacoes = createRoute({
getParentRoute: () => rootRoute,
path: '/aprovacoes',
component: ApprovalQueuePage,
});
const routeTree = rootRoute.addChildren([
indexRoute,
rafaelRoute,
clientesRoute,
novoClienteRoute,
clienteDetailRoute,
pedidosRoute,
novoOrderRoute,
pedidoDetailRoute,
pedidoPrintRoute,
catalogoRoute,
pedidosErpRoute,
relatoriosRoute,
aprovacoes,
]);
export const router = createRouter({
routeTree,
defaultPreload: 'intent',
defaultPreloadStaleTime: 0,
});
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}