ligbox-ops-platform/specs/019-ops-console-active-operations/deploy/frontend/src/layouts/AdminShell.jsx
Ligbox Spec Hub c1881f58e6 chore: sync Console SSO, DNS viewer, specs e infra docs pendentes
Inclui console handoff Desk↔Console (Spec 019), melhorias DNS Viewer (037),
OpenPanel/Nextcloud/VM116 deploy notes, contracts stack e sidebar actualizado.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 20:10:17 +00:00

111 lines
2.8 KiB
JavaScript

import { useEffect, useState } from 'react'
import { NavLink, Outlet } from 'react-router-dom'
import AdminLoginGate from '../components/AdminLoginGate'
import {
bootstrapAuthFromUrl,
clearSession,
getUser,
isLoggedIn,
} from '../lib/auth'
const adminNav = [
{ to: '/admin', label: 'Início', end: true },
{ to: '/admin/dominio', label: 'Domínio & DNS' },
]
const STAFF_ROLES = new Set([
'super_admin',
'ops_lead',
'technician',
'noc',
'seo',
'devops',
'developer',
'sales_admin',
'sales_support',
])
export default function AdminShell() {
const [authReady, setAuthReady] = useState(false)
const [authed, setAuthed] = useState(isLoggedIn())
const user = getUser()
const subtitle = user && STAFF_ROLES.has(user.role) ? 'Staff · suporte Ligbox' : 'Gerente de domínio'
useEffect(() => {
let cancelled = false
bootstrapAuthFromUrl().then((ok) => {
if (!cancelled) {
setAuthed(ok)
setAuthReady(true)
}
})
return () => {
cancelled = true
}
}, [])
function handleLoginSuccess() {
setAuthed(true)
}
function handleLogout() {
clearSession()
setAuthed(false)
}
return (
<div className="shell">
<aside className="sidebar sidebar-admin">
<div className="sidebar-brand">
<div className="sidebar-logo" aria-hidden="true">LB</div>
<div>
<h1>Ligbox Console</h1>
<p className="sidebar-sub">{subtitle}</p>
</div>
</div>
<p className="nav-section-label">Administração</p>
<nav>
{adminNav.map((item) => (
<NavLink
key={item.to}
to={item.to}
end={item.end}
className={({ isActive }) => `nav-link${isActive ? ' active' : ''}`}
>
{item.label}
</NavLink>
))}
</nav>
<p className="nav-section-label">Staff</p>
<nav>
<NavLink to="/" className="nav-link"> Console Ops</NavLink>
</nav>
{authed && user ? (
<p className="status-pill" style={{ marginTop: '1.5rem' }}>
{user.display_name || user.username}
{user.role ? ` · ${user.role}` : ''}
</p>
) : null}
{authed ? (
<button
type="button"
className="btn btn-ghost btn-sm"
style={{ marginTop: '0.5rem' }}
onClick={handleLogout}
>
Sair
</button>
) : null}
</aside>
<main className="main">
{!authReady ? (
<p className="loading">A validar sessão</p>
) : !authed ? (
<AdminLoginGate onSuccess={handleLoginSuccess} />
) : (
<Outlet />
)}
</main>
</div>
)
}