feat(frontend): app do tenant, dashboard ao vivo, fluxo de login multi-tenant
Corrige um gap real: o login sempre mandava pra /platform mesmo pra usuarios sem role de plataforma, sem nunca chamar /auth/tenants ou select-tenant. Agora POST /api/post-login decide o destino server-side (plataforma / tenant unico / seletor com >1 tenant) antes de redirecionar, trocando o access token quando necessario sem nunca expor token ao client. Adiciona GET /reports/dashboard (secao 162) e a tela /app correspondente — chamadas/agentes/TME/TMA/rates ao vivo, "consumo do plano" e "valor estimado" seguindo a mesma disciplina de honestidade (null > numero inventado) do dashboard de plataforma. Shell (sidebar/topbar/drawer mobile) extraido pra components/shell, compartilhado entre os menus Platform e Tenant (secao 168-169) via wrappers client-only por area — corrige de quebra um erro real de serializacao RSC (passar NavSection[] com icones como prop de Server Component pra Client Component quebra: "Functions cannot be passed directly to Client Components"). Testado ponta a ponta com um tenant semeado (Acme Call Center): login → /app direto, platform admin barrado de /app e vice-versa, dashboard com numeros reais (zeros honestos), drawer mobile, dark mode. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EWHKmcVJtstQFErbZ1AanY
This commit is contained in:
@@ -2,6 +2,18 @@ export function formatInt(n: number): string {
|
||||
return new Intl.NumberFormat("pt-BR").format(Math.round(n));
|
||||
}
|
||||
|
||||
/** mm:ss a partir de segundos — usado por TME/TMA (agente.md secao 162). */
|
||||
export function formatDuration(seconds: number): string {
|
||||
const total = Math.round(seconds);
|
||||
const mm = Math.floor(total / 60);
|
||||
const ss = total % 60;
|
||||
return `${mm}:${String(ss).padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
export function formatPercent(ratio: number): string {
|
||||
return new Intl.NumberFormat("pt-BR", { style: "percent", maximumFractionDigits: 1 }).format(ratio);
|
||||
}
|
||||
|
||||
export function formatBytes(bytes: number): { value: string; unit: string } {
|
||||
if (bytes === 0) return { value: "0", unit: "B" };
|
||||
const units = ["B", "KB", "MB", "GB", "TB"];
|
||||
|
||||
Reference in New Issue
Block a user