@logcomex/log-platform-frontend-lib
v0.2.6
Published
Frontend library for Logcomex platform (ProductSelector, platform auth, shell)
Downloads
169
Maintainers
Keywords
Readme
@logcomex/log-platform-frontend-lib — Guia passo a passo
Biblioteca React para integração com a Plataforma Logcomex / Supply: SSO (validate-auth), ProductSelector, modal de escolha de conta para system admin.
Backend: as rotas HTTP vivem na log-platform-backend-lib (validate-auth, user-products, accounts-to-join, join-account, …). Configura o Laravel desse pacote antes de testar o front.
Alterações entre versões: CHANGELOG.md.
Parte 1 — Instalar o pacote e dependências
Passo 1. Na raiz do teu projeto front, instala a lib:
npm install @logcomex/log-platform-frontend-libPasso 2. Garante que o package.json do app tem as peer dependencies (versões compatíveis com as da lib). Se faltar alguma, instala por exemplo:
npm install react react-dom react-router-dom @tanstack/react-query react-i18next i18next @radix-ui/react-tooltip @radix-ui/react-dropdown-menu @radix-ui/react-dialog lucide-react clsx tailwind-mergePasso 3. Usa sempre o import da raiz do pacote (não existem subpaths como /platform-auth):
import {
LogPlatformAppShell,
LogPlatformAuthProvider,
useLogPlatformAuthRoutes,
ProductSelector,
registerLogPlatformI18n,
SelectAccountModal,
useLogPlatformAuth,
} from "@logcomex/log-platform-frontend-lib";(Importa só o que precisares em cada ficheiro.)
Parte 2 — Configurar o Tailwind CSS
Sem isto, os componentes da lib aparecem sem estilos.
Passo 1. Abre o tailwind.config.js ou tailwind.config.ts do teu app (não o da lib).
Passo 2. Adiciona os ficheiros compilados da lib ao array content.
Se o config for CommonJS:
const logPlatformContent = require("@logcomex/log-platform-frontend-lib/tailwind-content");
module.exports = {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}", ...logPlatformContent],
// theme, plugins…
};Se for ESM (tailwind.config.ts), o export da lib é CJS — usa createRequire:
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
const logPlatformContent = require("@logcomex/log-platform-frontend-lib/tailwind-content");
export default {
content: ["./index.html", "./src/**/*.{tsx,ts,jsx,js}", ...logPlatformContent],
};Passo 3. Reinicia o servidor de desenvolvimento (ex.: Vite) para o Tailwind voltar a analisar o content.
Parte 3 — Configurar traduções (i18n)
As strings da lib ficam sob translation.logPlatform.* para não colidir com as chaves sidebar / common do teu produto.
Passo 1. Mantém o teu fluxo atual de i18next + initReactI18next (ficheiro tipo src/i18n.ts / i18n.js).
Passo 2. Depois de i18n.init({ ... }), regista as traduções da lib:
import { registerLogPlatformI18n } from "@logcomex/log-platform-frontend-lib";
registerLogPlatformI18n(i18n);Opcional: registerLogPlatformI18n(i18n, { lngs: ["pt", "en"], ns: "translation" }).
Passo 3. No entry da app (main.tsx / main.jsx), importa o i18n antes do App:
import "./i18n";
import App from "./App";Parte 4 — Configurar as rotas de autenticação (SSO / callback)
A Plataforma redireciona para algo como /auth/platform-callback?token=.... A lib regista essa rota e trata o validate-auth.
Tens duas formas: com shell (recomendado) ou manual.
Opção A — Com LogPlatformAppShell
Passo 1. Abre o ficheiro onde definiste o componente raiz que contém o <Routes> do React Router — em projetos Vite + React é habitualmente src/App.tsx ou src/App.jsx. É aí que deves colocar o LogPlatformAppShell: envolve o retorno desse componente (ou substitui a pilha antiga de BrowserRouter + providers por este shell). O main.tsx / main.jsx costuma ficar só com createRoot(...).render(<App />); não é obrigatório mudar o main se o router já vive no App.
Passo 2. Envolve a árvore onde precisas de router + auth com LogPlatformAppShell, passando auth com pelo menos:
apiBaseUrl— URL base da API onde está o prefixo da lib (ex.:https://api.teudominio.com, igual ao que usas para outras chamadas).getToken/setToken— ler e gravar o token do produto após o login (ex.:localStorage).paths— no mínimohome(ex.:"/") e, se quiseres outro path,platformCallback(default:"/auth/platform-callback").
Passo 3. Usa filho em forma de função para receber platformRoutes e coloca-o dentro de <Routes> como irmã das tuas rotas (no mesmo ficheiro ou num componente filho importado pelo App, desde que continue a ser filho direto do shell):
import { LogPlatformAppShell } from "@logcomex/log-platform-frontend-lib";
import { Routes, Route } from "react-router-dom";
export function App() {
return (
<LogPlatformAppShell
auth={{
apiBaseUrl: import.meta.env.VITE_API_URL ?? "",
getToken: () => localStorage.getItem("supply_product_token"),
setToken: (t) => localStorage.setItem("supply_product_token", t),
paths: { home: "/" },
}}
>
{({ platformRoutes }) => (
<Routes>
{platformRoutes}
<Route path="/" element={<Home />} />
{/* …outras rotas */}
</Routes>
)}
</LogPlatformAppShell>
);
}Passo 4. Confirma no Laravel que o prefixo (default platform-supply-lib) coincide com supplyLibBasePath se usares um path custom.
Passo 5. Se o teu app já tem QueryClientProvider, TooltipProvider ou BrowserRouter por cima, passa wrapQueryClient={false}, wrapTooltipProvider={false} e/ou wrapBrowserRouter={false} e mantém LogPlatformAppShell dentro dessa ordem (Router por fora do provider de auth da lib se desativares o router do shell).
Opção B — Integração manual (sem shell)
Passo 1. No mesmo sítio onde montas a app com router — de novo, em geral src/App.tsx / src/App.jsx (ou um ficheiro dedicado tipo src/routes/AppRoutes.tsx que o App importa) — aplica a pilha abaixo.
Passo 2. Por fora para dentro: QueryClientProvider → TooltipProvider (Radix) → BrowserRouter.
Passo 3. Dentro do router, envolve com LogPlatformAuthProvider com as mesmas props auth descritas na Opção A.
Passo 4. Cria um componente filho que chama useLogPlatformAuthRoutes() só dentro do provider e, no JSX, dentro de <Routes>, renderiza {platformRoutes} junto com as tuas <Route />.
Passo 5. O React Router só aceita <Route> ou fragmento como filhos diretos de <Routes> — não substituas isto por um wrapper que não devolva rotas válidas.
Parte 5 — Configurar o modal de troca de conta (system admin)
Serve para o administrador da plataforma escolher em que conta cliente quer atuar depois do login.
Passo 1. No LogPlatformAuthProvider (ou no objeto auth do LogPlatformAppShell), define selectAccountPresentation:
"none"— após o login, vai direto àhome; podes abrir o modal só quando quiseres (modo controlado)."modal"— após o login como system admin, a lib marca um flag emsessionStoragepara o modal poder abrir na primeira página autenticada.
Passo 2. Coloca <SelectAccountModal /> num layout que já tenha token válido e que seja renderizado quando o utilizador está autenticado (ex.: layout da área logada, não na página de login).
Passo 3. Se usaste selectAccountPresentation="modal", garante que esse layout é montado depois do redirect do callback (a home ou rota inicial autenticada).
Passo 4. Modo controlado (opcional): para um botão “Trocar empresa”, usa estado local e passa open + onOpenChange ao SelectAccountModal; podes combinar com useLogPlatformAuth() para isSystemAdmin. Por defeito, após join-account bem-sucedido o modal dispara window.location.reload() (reloadAfterJoin, default true) para evitar dados da conta anterior em cache; usa reloadAfterJoin={false} se precisares do comportamento só-SPA.
Passo 5. Para obter o fluxo de contas (join-account, etc.), o backend já expõe as rotas da log-platform-backend-lib; o modal usa o cliente HTTP interno do contexto.
Banner de impersonação: coloca <SystemAdminImpersonationBanner /> no topo do layout autenticado e passa currentAccountId (ex.: user.account_id) e, opcionalmente, currentAccountLabel. O backend só envia system_admin_account em accounts-to-join quando o token tem viewing_as (já noutra conta); na conta própria vem null. Por isso o provider aceita getFallbackSystemAdminHomeAccountId (ex.: devolver user.account_id do /me enquanto o admin está na conta agregadora) e persiste o ID em sessionStorage para o banner comparar antes/depois do join. Usa authRevision que mude com token e account_id do utilizador (ex.: após getMe) para voltar a sincronizar. isSystemAdminFromProduct continua necessário para login por email sem SSO.
Parte 6 — Configurar o ProductSelector
Menu (geralmente na sidebar) para mudar de produto e, para system admin, ir ao hub da Plataforma.
Passo 1. O selector usa React Query — tem de estar dentro de QueryClientProvider (o LogPlatformAppShell já inclui um por defeito).
Passo 2. Coloca o ProductSelector dentro da árvore onde já existe LogPlatformAuthProvider (ou dentro do shell), para poderes omitir platformBaseUrl e getAuthToken (a lib usa apiBaseUrl e o token do contexto).
Passo 3. Passa no mínimo:
collapsed— se a sidebar está colapsada (afeta tooltip vs texto completo).- Se não estiveres dentro do provider:
platformBaseUrlegetAuthTokenobrigatórios.
Passo 4. Configura variáveis de ambiente conforme o teu cenário:
- URL pública do hub da Plataforma Supply (ex.:
VITE_SUPPLY_PLATFORM_APP_URL) — propsupplyPlatformAppBaseUrlpara o item “Plataforma Logcomex”. hostAppBaseUrl— URL deste SPA (ex.:import.meta.env.VITE_APP_URLouwindow.location.origin) para alinhar seleção com o produto atual.
Passo 5. O pedido de lista de produtos é um GET para {apiBaseUrl}/{prefixo}/user-products (prefixo default platform-supply-lib), com Authorization: Bearer do token do produto. Se a tua API usar outro path, usa userProductsListPath ou supplyLibBasePath.
Passo 6. Implementa onSelectInvalidUrl para feedback quando um produto não tem URL ou falta token da plataforma para saltar de produto.
Passo 7. Garante que o fluxo SSO (Parte 4) grava o token da plataforma em localStorage após o callback — o selector usa isso para montar .../auth/platform-callback?token=... ao mudar de produto.
Exemplo mínimo com provider:
<ProductSelector
collapsed={sidebarCollapsed}
hostAppBaseUrl={import.meta.env.VITE_APP_URL ?? window.location.origin}
supplyPlatformAppBaseUrl={import.meta.env.VITE_SUPPLY_PLATFORM_APP_URL}
onSelectInvalidUrl={() => toast.error("Não foi possível abrir o produto")}
/>Parte 7 — Logout (limpar sessão da lib)
Passo 1. Remove o token do produto (o mesmo que getToken lê / setToken grava).
Passo 2. Chama clearPlatformToken() de useLogPlatformAuth() (ou os helpers exportados que limpam o token da plataforma no localStorage).
Passo 3. Chama setIsSystemAdmin(false) e, se usaste o modal automático, remove a chave de sessionStorage associada ao “pending select account” (constante exportada PENDING_SELECT_ACCOUNT_MODAL_KEY).
Apêndice A — CLI de dicas
npx log-platform-frontend-initImprime lembretes (Tailwind, i18n, shell); não modifica ficheiros.
Apêndice B — Desenvolvimento local da lib
cd log-platform-frontend-lib
npm run build
npm link
# no app consumidor:
npm link @logcomex/log-platform-frontend-libInstalar a partir do Git: npm install github:ORG/log-platform-frontend-lib#main.
Apêndice C — Prefixos das chaves i18n
| Área | Prefixo das chaves |
|------|---------------------|
| Selector | logPlatform.productSelector.* |
| Página de callback SSO | logPlatform.platformAuth.callback.* |
| Modal / painel de contas | logPlatform.platformAuth.selectAccount.* |
