npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@logcomex/log-platform-frontend-lib

v0.2.6

Published

Frontend library for Logcomex platform (ProductSelector, platform auth, shell)

Downloads

169

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-lib

Passo 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-merge

Passo 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. É 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ínimo home (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 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: QueryClientProviderTooltipProvider (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 em sessionStorage para 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 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: platformBaseUrl e getAuthToken obrigató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) — prop supplyPlatformAppBaseUrl para o item “Plataforma Logcomex”.
  • hostAppBaseUrl — URL deste SPA (ex.: import.meta.env.VITE_APP_URL ou window.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-init

Imprime 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-lib

Instalar 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.* |