Convenções e Componentes Compartilhados
Padrões usados em toda a aplicação e o que já existe em src/shared.
Antes de criar um componente novo, vale conferir src/shared/components — a maior parte das telas de
CRUD/listagem reaproveita as mesmas peças:
| Componente | Onde | Uso |
|---|---|---|
ScreenTable | shared/components/ScreenTable | Tabela genérica com loading/erro/empty state; suporta seleção múltipla via checkbox (prop selection, opcional) |
Pagination | shared/components/Pagination | Paginação conectada a IPageResponse<T> |
DeleteModal | shared/components/DeleteModal | AlertDialog de confirmação de exclusão, com trigger customizável |
SearchBar | shared/components/SearchBar | Campo de busca controlado |
FormTabs | shared/components/FormTabs | Abas dentro de um formulário/página |
Hooks de API
useApiQuery e useApiMutation (shared/hooks) são wrappers finos sobre useQuery/useMutation do
TanStack Query, já tipando o erro como AxiosError<IApiError>. Toda chamada de API no app passa por eles —
não use useQuery/useMutation direto do @tanstack/react-query.
Permissões e Sidebar
O menu lateral (shared/components/layout/Sidebar/Sidebar.tsx) é uma lista estática navItems, onde cada
item pode ter permission (string, ex: "client:read") ou role (string, ex: "ADMIN"). A visibilidade é
filtrada em runtime via usePermissions() (shared/hooks/usePermissions.ts), que decodifica o JWT do cookie.
{
title: 'Gerenciamento',
items: [
{ title: 'Usuários', url: '/users', role: 'ADMIN' },
{ title: 'Lixeira', url: '/trash', role: 'ADMIN' },
],
}Isso controla apenas a exibição do menu — a autorização de verdade é sempre feita pelo backend
(@RequiresPermission, ver Permissões no backend).
Erros de API
getApiErrorMessage(error, fallback) (shared/utils/getApiErrorMessage.ts) extrai a mensagem amigável de um
AxiosError<IApiError> para exibir em toast (sonner).