import React from 'react'; import { useConfirm } from '../contexts/ConfirmContext.tsx'; import { Users, Calendar as CalendarIcon, LayoutDashboard, DollarSign, RefreshCw, Activity, BookOpen, Award, Megaphone, LogOut, ClipboardList, Bell, Building2, User, BarChart3, Settings, FileText, Puzzle, ScanLine, Monitor, UsersRound, GraduationCap, UserSearch, Briefcase, TrendingUp, Eye, FlaskConical, DoorOpen, Sparkles, FileSignature, Percent, ShieldAlert, ChevronDown } from 'lucide-react'; import { ToothIcon } from './ToothIcon.tsx'; import { HybridBackend } from '../services/backend.ts'; import { getActivePlugins } from '../views/plugins/pluginRegistry.ts'; interface SidebarProps { activeTab: string; setActiveTab: (t: string) => void; } export const Sidebar: React.FC = ({ activeTab, setActiveTab }) => { const currentRole = HybridBackend.getCurrentRole(); const userName = HybridBackend.getCurrentUserName(); const userEmail = HybridBackend.getCurrentUser(); const activeWorkspace = HybridBackend.getActiveWorkspace(); const clinColor = activeWorkspace?.cor || (currentRole === 'superadmin' ? '#dc2626' : '#2563eb'); const activePluginIds = getActivePlugins(); const isTutor = (() => { try { return JSON.parse(localStorage.getItem('SCOREODONTO_USER_DATA') || '{}').is_tutor === true; } catch { return false; } })(); const pluginMenuItems: Array<{ id: string; label: string; icon: any; color: string }> = []; if (activePluginIds.includes('rx-scoreodonto')) { // Radiografias são ODONTOLÓGICAS: só papéis odonto (dentista + donos/funcionário). // Biomédico e protético NÃO veem RX. if (['dentista', 'funcionario', 'admin', 'donoclinica', 'donoconsultorio'].includes(currentRole)) { pluginMenuItems.push({ id: 'rx-radiografias', label: 'RX / RADIOGRAFIAS', icon: ScanLine, color: '#7c3aed' }); } // DISPOSITIVOS RX (config + PCs): admin/donos da clínica e superadmin (gestão global). if (['admin', 'donoclinica', 'donoconsultorio', 'superadmin'].includes(currentRole)) { pluginMenuItems.push({ id: 'rx-config', label: 'DISPOSITIVOS RX', icon: Monitor, color: '#7c3aed' }); } } // Locação de Salas: capability SEMPRE ativa (sem desativar) p/ todos menos superadmin. // Dois menus: administrar as próprias salas (locador) e alugar salas de terceiros (locatário). if (currentRole !== 'superadmin') { pluginMenuItems.push({ id: 'minhas-salas', label: 'MINHAS SALAS', icon: DoorOpen, color: '#0d9488' }); pluginMenuItems.push({ id: 'alugar-salas', label: 'ALUGAR SALAS', icon: Building2, color: '#0d9488' }); } // Marketplace de Profissionais: clínicas contratam, profissionais divulgam perfil/recebem propostas. if (activePluginIds.includes('profissionais-marketplace') && currentRole !== 'superadmin' && currentRole !== 'paciente') { pluginMenuItems.push({ id: 'marketplace-profissionais', label: 'PROFISSIONAIS', icon: UserSearch, color: '#0d9488' }); } // OBS: o catálogo de PLUGINS é EXCLUSIVO do superadmin (gerência/ativação). // Não exibir para nenhum outro papel. const menuItems = [ { id: 'superadmin-overview', label: 'VISÃO GERAL', icon: TrendingUp }, { id: 'superadmin-users', label: 'USUÁRIOS', icon: Users }, { id: 'superadmin-clinicas', label: 'CLÍNICAS', icon: Building2 }, { id: 'superadmin-logs', label: 'ACESSOS', icon: Activity }, { id: 'superadmin-financeiro', label: 'FINANCEIRO', icon: DollarSign }, { id: 'superadmin-notificacoes', label: 'NOTIFICAÇÕES', icon: Bell }, { id: 'sala-home', label: 'PAINEL DA SALA', icon: DoorOpen }, { id: 'dashboard', label: 'VISÃO GERAL', icon: LayoutDashboard }, { id: 'agenda', label: 'AGENDA', icon: CalendarIcon }, { id: 'pacientes', label: 'PACIENTES', icon: Users }, { id: 'lancar-gto', label: 'LANÇAR GTO', icon: ClipboardList }, { id: 'ortodontia', label: 'ORTODONTIA', icon: Activity }, { id: 'financeiro', label: 'FINANCEIRO', icon: DollarSign }, { id: 'relatorios', label: 'RELATÓRIOS', icon: BarChart3 }, { id: 'comissoes', label: 'COMISSÕES', icon: Percent }, { id: 'glosas', label: 'GLOSAS', icon: ShieldAlert }, { id: 'orcamentos', label: 'ORÇAMENTOS', icon: FileText }, { id: 'contratos', label: 'CONTRATOS', icon: FileSignature }, { id: 'leads', label: 'GESTÃO DE LEADS', icon: Megaphone }, { id: 'tratamentos', label: 'MEUS TRATAMENTOS', icon: ClipboardList }, { id: 'clinicas', label: 'MINHAS CLÍNICAS', icon: Building2 }, { id: 'dentistas', label: 'DENTISTAS', icon: ToothIcon }, { id: 'especialidades', label: 'ESPECIALIDADES', icon: Award }, { id: 'procedimentos', label: 'PROCEDIMENTOS', icon: ClipboardList }, { id: 'planos', label: 'PLANOS / CONVÊNIOS', icon: BookOpen }, { id: 'gestao-equipe', label: 'EQUIPE / USUÁRIOS', icon: UsersRound }, { id: 'diretorio-profissionais', label: 'DIRETÓRIO PROF.', icon: UserSearch }, { id: 'admin-gestao-tutores', label: 'GESTÃO TUTORES', icon: GraduationCap }, { id: 'candidatura-tutor', label: 'SER TUTOR ORTO', icon: GraduationCap }, { id: 'tutoria-painel', label: 'PAINEL TUTOR', icon: GraduationCap }, { id: 'notificacoes', label: 'NOTIFICAÇÕES', icon: Bell }, { id: 'plugins', label: 'PLUGINS', icon: Puzzle }, { id: 'configuracoes', label: 'CONFIGURAÇÕES', icon: Settings }, ].filter(item => { // superadmin: itens específicos de administração global if (currentRole === 'superadmin') return ['superadmin-overview', 'superadmin-users', 'superadmin-clinicas', 'superadmin-logs', 'superadmin-financeiro', 'superadmin-notificacoes', 'plugins', 'configuracoes'].includes(item.id); // telas de superadmin são exclusivas do superadmin (não vazam p/ admin/donos) if (item.id.startsWith('superadmin')) return false; // PAINEL DA SALA só existe quando o workspace ativo é uma sala. if (item.id === 'sala-home') return (activeWorkspace as any)?.tipo === 'sala'; // Contexto de SALA (workspace tipo='sala'): isola da clínica — menu base só conta/notificações. // (MINHAS SALAS / ALUGAR SALAS são itens de plugin, mostrados à parte.) if ((activeWorkspace as any)?.tipo === 'sala') return ['sala-home', 'notificacoes', 'configuracoes'].includes(item.id); // plugins e gestão de tutores: exclusivo superadmin if (item.id === 'plugins' || item.id === 'admin-gestao-tutores') return false; // diretório antigo é absorvido pelo plugin Profissionais quando ele está ativo if (item.id === 'diretorio-profissionais' && activePluginIds.includes('profissionais-marketplace')) return false; // painel tutor: só para tutores aprovados if (item.id === 'tutoria-painel') return isTutor; // RBAC por CARGO: membro não-dono com permissões definidas no workspace ativo const wsRole = (activeWorkspace as any)?.role; const wsPerms = (activeWorkspace as any)?.permissoes; const isWsOwner = ['admin', 'donoclinica', 'donoconsultorio'].includes(wsRole || ''); if (!isWsOwner && Array.isArray(wsPerms) && wsPerms.length > 0) { // Navegação/conta sempre visível if (['clinicas', 'configuracoes', 'notificacoes'].includes(item.id)) return true; return wsPerms.includes(item.id); } if (['admin', 'donoclinica', 'donoconsultorio'].includes(currentRole)) return true; // Dono de sala (locador não-clínico): só conta/notificações; salas vêm como itens de plugin. if (currentRole === 'donosala') return ['notificacoes', 'configuracoes'].includes(item.id); if (currentRole === 'paciente') return ['tratamentos', 'notificacoes', 'configuracoes'].includes(item.id); // Dentista: clínico odonto completo (ortodontia, tutoria orto). if (currentRole === 'dentista') return ['dashboard', 'tratamentos', 'agenda', 'ortodontia', 'notificacoes', 'clinicas', 'configuracoes', 'candidatura-tutor', 'diretorio-profissionais'].includes(item.id); // Biomédico(a): seu próprio catálogo (especialidades/procedimentos de biomedicina); // SEM itens odontológicos (ortodontia, RX, tutoria orto). if (currentRole === 'biomedico') return ['dashboard', 'agenda', 'tratamentos', 'especialidades', 'procedimentos', 'notificacoes', 'clinicas', 'configuracoes', 'diretorio-profissionais'].includes(item.id); // Protético: laboratório — agenda própria + GTO; sem ortodontia/RX/pacientes clínicos. if (currentRole === 'protetico') return ['dashboard', 'agenda', 'tratamentos', 'lancar-gto', 'notificacoes', 'clinicas', 'configuracoes', 'diretorio-profissionais'].includes(item.id); if (currentRole === 'funcionario') return ['dashboard', 'leads', 'pacientes', 'tratamentos', 'lancar-gto', 'agenda', 'financeiro', 'relatorios', 'glosas', 'notificacoes', 'clinicas', 'configuracoes', 'orcamentos', 'contratos', 'diretorio-profissionais'].includes(item.id); return false; }); const confirm = useConfirm(); const [wsOpen, setWsOpen] = React.useState(false); const handleLogout = async () => { if (await confirm('TEM CERTEZA QUE DESEJA SAIR DO SISTEMA?')) { HybridBackend.logout(); } }; const workspaceName = activeWorkspace?.nome || 'SCOREODONTO'; const activeIsSala = (activeWorkspace as any)?.tipo === 'sala'; const WorkspaceIcon = activeIsSala ? DoorOpen : currentRole === 'donoconsultorio' ? Briefcase : Building2; // Workspaces para o seletor: clínicas (via vínculo) + salas próprias, agrupados. const allWorkspaces: any[] = HybridBackend.getWorkspaces() || []; const wsClinicas = allWorkspaces.filter(w => w.tipo !== 'sala'); const wsSalas = allWorkspaces.filter(w => w.tipo === 'sala'); const canSwitch = allWorkspaces.length > 1; return (
{wsOpen && canSwitch && ( <>
setWsOpen(false)} />
{wsClinicas.length > 0 &&

Clínicas

} {wsClinicas.map(w => ( ))} {wsSalas.length > 0 &&

Salas

} {wsSalas.map(w => ( ))}
)}
); };