feat: ViaCEP em todos os forms de endereço + menus por papel + fix preview de plugins

ViaCEP (auto-preenche endereço ao completar 8 dígitos):
- novo util services/viacep.ts (buscarCep), reutilizado
- ligado em Pacientes, Salas, Profissionais(perfil); Configurações migrada p/ o util
- filtro 'CEP (região)' do marketplace mantido como busca (sem auto-fill)

Menus por papel:
- biomédico: sem Ortodontia, RX e 'Ser Tutor Orto' (não são escopo)
- protético: passa a ver Dashboard/Agenda/Tratamentos/Lançar GTO (antes não via nada)
- RX/Radiografias: só papéis odonto (dentista + donos/funcionário)
- bottom nav mobile ajustado (biomédico/protético)

Fix 'Visualizar como':
- getActivePlugins é preview-aware (todos os plugins ativos enquanto houver PREVIEW_ROLE),
  imune ao timing de hydrate/cache; enterPreview/exitPreview simplificados

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Builder
2026-06-13 20:14:31 +02:00
parent ca7eba4531
commit cb00d9f383
9 changed files with 81 additions and 40 deletions
+9 -3
View File
@@ -26,8 +26,9 @@ export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) =>
const pluginMenuItems: Array<{ id: string; label: string; icon: any; color: string }> = [];
if (activePluginIds.includes('rx-scoreodonto')) {
// Visualização operacional de radiografias: papéis de clínica (não o superadmin).
if (currentRole !== 'superadmin') {
// 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).
@@ -106,7 +107,12 @@ export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) =>
if (['admin', 'donoclinica', 'donoconsultorio'].includes(currentRole)) return true;
if (currentRole === 'paciente') return ['tratamentos', 'notificacoes', 'configuracoes'].includes(item.id);
if (currentRole === 'dentista' || currentRole === 'biomedico') return ['dashboard', 'tratamentos', 'agenda', 'ortodontia', 'notificacoes', 'clinicas', 'configuracoes', 'candidatura-tutor', 'diretorio-profissionais'].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): SEM itens odontológicos (ortodontia, RX, tutoria orto).
if (currentRole === 'biomedico') return ['dashboard', 'agenda', 'tratamentos', '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', 'notificacoes', 'clinicas', 'configuracoes', 'contratos', 'diretorio-profissionais'].includes(item.id);
return false;
});