2026-05-18 17:34:23 -03:00
|
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
|
import { BrandMark } from '../../../shared/components/BrandMark';
|
|
|
|
|
import { clearSession } from '../../auth/services/sessionService';
|
|
|
|
|
|
|
|
|
|
const navigationBySection = {
|
|
|
|
|
supervisor: [
|
2026-05-22 10:51:07 -03:00
|
|
|
{ id: 'dashboard', label: 'Home' },
|
|
|
|
|
{ id: 'templates', label: 'Templates' },
|
2026-05-26 09:08:08 -03:00
|
|
|
{ id: 'knowledge', label: 'Fluxo do Bot' },
|
|
|
|
|
{ id: 'ai-contents', label: 'Conteúdos da IA' },
|
2026-05-22 10:51:07 -03:00
|
|
|
{ id: 'audit', label: 'Auditoria' },
|
|
|
|
|
{ type: 'separator' },
|
|
|
|
|
{ id: 'attendance', label: 'Atendimento' },
|
2026-05-26 09:08:08 -03:00
|
|
|
{ id: 'new-attendance', label: 'Abrir Atendimento' },
|
2026-05-22 10:51:07 -03:00
|
|
|
{ id: 'mass-message', label: 'Disparo em Massa' },
|
|
|
|
|
{ id: 'contacts', label: 'Contatos' },
|
2026-05-18 17:34:23 -03:00
|
|
|
],
|
|
|
|
|
admin: [
|
2026-05-21 15:50:55 -03:00
|
|
|
{ id: 'today', label: 'Operação' },
|
2026-05-21 12:06:30 -03:00
|
|
|
{ type: 'separator' },
|
2026-05-21 15:50:55 -03:00
|
|
|
{ id: 'users-access', label: 'Usuários & Acessos' },
|
2026-05-21 12:06:30 -03:00
|
|
|
{ id: 'templates', label: 'Templates' },
|
2026-05-26 09:08:08 -03:00
|
|
|
{ id: 'knowledge', label: 'Fluxo do Bot' },
|
|
|
|
|
{ id: 'ai-contents', label: 'Conteúdos da IA' },
|
2026-05-21 12:06:30 -03:00
|
|
|
{ id: 'audit', label: 'Auditoria' },
|
2026-05-26 11:33:18 -03:00
|
|
|
{ id: 'channels', label: 'Canais e Integração' },
|
2026-05-21 12:06:30 -03:00
|
|
|
{ type: 'separator' },
|
2026-05-21 15:50:55 -03:00
|
|
|
{ id: 'attendance', label: 'Atendimento' },
|
2026-05-26 09:08:08 -03:00
|
|
|
{ id: 'new-attendance', label: 'Abrir Atendimento' },
|
2026-05-21 12:06:30 -03:00
|
|
|
{ id: 'mass-message', label: 'Disparo em Massa' },
|
|
|
|
|
{ id: 'contacts', label: 'Contatos' },
|
|
|
|
|
{ type: 'separator' },
|
2026-05-21 15:50:55 -03:00
|
|
|
{ id: 'settings', label: 'Configurações' },
|
2026-05-18 17:34:23 -03:00
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const actionLabelBySection = {
|
|
|
|
|
supervisor: '+ Redistribuir atendimento',
|
2026-05-27 09:31:25 -03:00
|
|
|
admin: 'Home',
|
2026-05-18 17:34:23 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function ManagementLayout({
|
|
|
|
|
title,
|
|
|
|
|
subtitle,
|
|
|
|
|
activeSection,
|
|
|
|
|
profileLabel,
|
|
|
|
|
initials,
|
|
|
|
|
children,
|
|
|
|
|
isDesktop,
|
|
|
|
|
isMobile,
|
2026-05-21 12:06:30 -03:00
|
|
|
activeNavItem,
|
|
|
|
|
onNavItemChange,
|
2026-05-18 17:34:23 -03:00
|
|
|
}) {
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const navItems = navigationBySection[activeSection] || navigationBySection.supervisor;
|
2026-05-22 10:51:07 -03:00
|
|
|
const actionLabel = actionLabelBySection[activeSection] || 'Home';
|
2026-05-18 17:34:23 -03:00
|
|
|
|
|
|
|
|
function handleLogout() {
|
|
|
|
|
clearSession();
|
|
|
|
|
navigate('/login', { replace: true });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<main style={{ minHeight: '100vh', padding: '1.5rem' }}>
|
|
|
|
|
<section
|
|
|
|
|
style={{
|
|
|
|
|
width: 'min(1680px, calc(100vw - 3rem))',
|
|
|
|
|
margin: '0 auto',
|
|
|
|
|
background: 'var(--color-surface-strong)',
|
|
|
|
|
borderRadius: '32px',
|
|
|
|
|
boxShadow: 'var(--shadow-lg)',
|
|
|
|
|
padding: '1.5rem',
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gap: '1.5rem',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gridTemplateColumns: isDesktop ? 'minmax(300px, 360px) minmax(0, 1fr)' : '1fr',
|
|
|
|
|
gap: '1.5rem',
|
|
|
|
|
alignItems: 'start',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ display: 'grid', gap: '1.25rem' }}>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
background: '#fff',
|
|
|
|
|
border: '1px solid var(--color-border)',
|
|
|
|
|
borderRadius: '28px',
|
|
|
|
|
padding: '1.5rem',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<BrandMark size="lg" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<aside
|
|
|
|
|
style={{
|
|
|
|
|
background: 'linear-gradient(180deg, rgba(0, 49, 80, 0.98), rgba(7, 64, 98, 0.96))',
|
|
|
|
|
color: '#fff',
|
|
|
|
|
borderRadius: '28px',
|
|
|
|
|
padding: '1.5rem',
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gap: '1.25rem',
|
|
|
|
|
alignContent: 'start',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
2026-05-27 09:31:25 -03:00
|
|
|
onClick={() => {
|
|
|
|
|
if (activeSection === 'admin') {
|
|
|
|
|
onNavItemChange?.('home');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
navigate('/home');
|
|
|
|
|
}}
|
2026-05-18 17:34:23 -03:00
|
|
|
style={{
|
|
|
|
|
border: 'none',
|
|
|
|
|
borderRadius: '20px',
|
|
|
|
|
padding: '1rem 1.15rem',
|
|
|
|
|
background: 'linear-gradient(135deg, var(--color-highlight), #f3b94d)',
|
|
|
|
|
color: '#132534',
|
|
|
|
|
fontWeight: 800,
|
|
|
|
|
textAlign: 'left',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{actionLabel}
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<nav
|
|
|
|
|
style={{
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gap: '0.5rem',
|
|
|
|
|
gridTemplateColumns: isMobile ? 'repeat(auto-fit, minmax(180px, 1fr))' : '1fr',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{navItems.map((item, index) => {
|
2026-05-21 12:06:30 -03:00
|
|
|
if (item.type === 'separator') {
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
key={`separator-${index}`}
|
|
|
|
|
style={{
|
|
|
|
|
height: 1,
|
|
|
|
|
background: 'rgba(255, 255, 255, 0.16)',
|
|
|
|
|
margin: '0.35rem 0',
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isActive = activeNavItem ? item.id === activeNavItem : index === 0;
|
2026-05-18 17:34:23 -03:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
key={item.id}
|
|
|
|
|
type="button"
|
2026-05-21 12:06:30 -03:00
|
|
|
onClick={() => {
|
|
|
|
|
if (item.path) {
|
|
|
|
|
navigate(item.path);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
onNavItemChange?.(item.id);
|
|
|
|
|
}}
|
2026-05-18 17:34:23 -03:00
|
|
|
style={{
|
|
|
|
|
border: 'none',
|
|
|
|
|
borderRadius: '18px',
|
|
|
|
|
padding: '0.9rem 1rem',
|
|
|
|
|
background: isActive ? 'rgba(255, 255, 255, 0.14)' : 'transparent',
|
|
|
|
|
color: '#fff',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
fontWeight: isActive ? 700 : 500,
|
|
|
|
|
width: '100%',
|
|
|
|
|
textAlign: 'left',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<span>{item.label}</span>
|
|
|
|
|
{item.count ? (
|
|
|
|
|
<span
|
|
|
|
|
style={{
|
|
|
|
|
minWidth: 30,
|
|
|
|
|
borderRadius: 999,
|
|
|
|
|
padding: '0.2rem 0.5rem',
|
|
|
|
|
background: 'rgba(255, 255, 255, 0.12)',
|
|
|
|
|
fontSize: '0.82rem',
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{item.count}
|
|
|
|
|
</span>
|
|
|
|
|
) : null}
|
|
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={handleLogout}
|
|
|
|
|
style={{
|
|
|
|
|
border: '1px solid rgba(255, 255, 255, 0.18)',
|
|
|
|
|
borderRadius: '18px',
|
|
|
|
|
padding: '0.9rem 1rem',
|
|
|
|
|
background: 'transparent',
|
2026-05-27 09:31:25 -03:00
|
|
|
color: '#ef4444',
|
2026-05-18 17:34:23 -03:00
|
|
|
fontWeight: 700,
|
|
|
|
|
textAlign: 'left',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Sair
|
|
|
|
|
</button>
|
|
|
|
|
</aside>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div style={{ display: 'grid', gap: '1.25rem', minWidth: 0 }}>
|
|
|
|
|
<header
|
|
|
|
|
style={{
|
|
|
|
|
display: 'grid',
|
|
|
|
|
gridTemplateColumns: isMobile ? '1fr' : 'minmax(0, 1fr) auto',
|
|
|
|
|
gap: '1rem',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
padding: '1.1rem 1.25rem',
|
|
|
|
|
borderRadius: '22px',
|
|
|
|
|
background: '#fff',
|
|
|
|
|
border: '1px solid var(--color-border)',
|
|
|
|
|
minWidth: 0,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<h1 style={{ margin: 0, fontSize: '1.65rem' }}>{title}</h1>
|
|
|
|
|
<p style={{ margin: '0.45rem 0 0', color: 'var(--color-text-soft)' }}>
|
|
|
|
|
{subtitle}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
style={{
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
gap: '0.9rem',
|
|
|
|
|
justifySelf: isMobile ? 'stretch' : 'end',
|
|
|
|
|
justifyContent: isMobile ? 'space-between' : 'flex-end',
|
|
|
|
|
padding: '0.85rem 1rem',
|
|
|
|
|
borderRadius: '22px',
|
|
|
|
|
background: '#fff',
|
|
|
|
|
border: '1px solid var(--color-border)',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ textAlign: 'right' }}>
|
|
|
|
|
<strong style={{ display: 'block' }}>{profileLabel}</strong>
|
|
|
|
|
<span style={{ color: 'var(--color-text-soft)', fontSize: '0.92rem' }}>
|
2026-05-21 15:50:55 -03:00
|
|
|
Ambiente de gestão
|
2026-05-18 17:34:23 -03:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
|
aria-hidden="true"
|
|
|
|
|
style={{
|
|
|
|
|
width: 48,
|
|
|
|
|
height: 48,
|
|
|
|
|
borderRadius: '16px',
|
|
|
|
|
display: 'grid',
|
|
|
|
|
placeItems: 'center',
|
|
|
|
|
background: 'linear-gradient(135deg, var(--color-accent), var(--color-primary))',
|
|
|
|
|
color: '#fff',
|
|
|
|
|
fontWeight: 800,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{initials}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
{children}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
</main>
|
|
|
|
|
);
|
|
|
|
|
}
|