/* |-------------------------------------------------------------------------- | Agência PSI — pagesIndex.js |-------------------------------------------------------------------------- | Índice curado das páginas navegáveis do app. Consumido pelo GlobalSearch | pra dar "ir pra tal página" como resultado da busca. | | Regras: | • `roles` vazio ou ausente → todos logados veem. | • `roles` com valores → apenas esses papéis veem. | • Roles reconhecidos: 'therapist', 'clinic_admin', 'tenant_admin', | 'supervisor', 'saas_admin', 'portal_user'. | | Não duplique aqui o que já está nas STATIC_ACTIONS do GlobalSearch | (Agenda, Pacientes, Financeiro, Documentos, Configurações, etc.). | O foco aqui são *sub-páginas* e telas menos frequentes, que o usuário | raramente lembra onde ficam. |-------------------------------------------------------------------------- */ // Helpers opcionais pra keywords mais ricas const kw = (...arr) => arr.flat().filter(Boolean); export const PAGES = [ // ═══════════════════ THERAPIST (/therapist/*) ═══════════════════ { id: 'p_t_dashboard', label: 'Dashboard', icon: 'pi pi-home', sublabel: 'Visão geral', path: '/therapist', roles: ['therapist'], keywords: kw('home','inicio','painel','dashboard') }, { id: 'p_t_conversas', label: 'Conversas', icon: 'pi pi-comments', sublabel: 'Mensagens com pacientes', path: '/therapist/conversas', roles: ['therapist'], keywords: kw('conversas','chat','mensagens','whatsapp') }, { id: 'p_t_agenda_rec', label: 'Recorrências da agenda', icon: 'pi pi-refresh', sublabel: 'Sessões recorrentes', path: '/therapist/agenda/recorrencias', roles: ['therapist'], keywords: kw('recorrencia','repeticao','semanal','sessao fixa') }, { id: 'p_t_agenda_comp', label: 'Compromissos determinados', icon: 'pi pi-bookmark', sublabel: 'Sessões fixas', path: '/therapist/agenda/compromissos', roles: ['therapist'], keywords: kw('compromissos','determinado','fixo') }, { id: 'p_t_plano', label: 'Meu plano', icon: 'pi pi-crown', sublabel: 'Assinatura e billing', path: '/therapist/meu-plano', roles: ['therapist'], keywords: kw('plano','assinatura','pagamento','mensalidade','billing') }, { id: 'p_t_upgrade', label: 'Upgrade de plano', icon: 'pi pi-arrow-up', sublabel: 'Mudar de plano', path: '/therapist/upgrade', roles: ['therapist'], keywords: kw('upgrade','trocar','mudar plano') }, { id: 'p_t_grupos', label: 'Grupos de pacientes', icon: 'pi pi-users', sublabel: 'Organizar pacientes em grupos', path: '/therapist/patients/grupos', roles: ['therapist'], keywords: kw('grupos','segmentacao','categorias') }, { id: 'p_t_tags', label: 'Tags de pacientes', icon: 'pi pi-tags', sublabel: 'Etiquetas', path: '/therapist/patients/tags', roles: ['therapist'], keywords: kw('tags','etiquetas','marcadores','labels') }, { id: 'p_t_medicos', label: 'Médicos referenciadores', icon: 'pi pi-user-edit', sublabel: 'Médicos que encaminham pacientes', path: '/therapist/patients/medicos', roles: ['therapist'], keywords: kw('medicos','encaminhadores','referenciadores','indicacao') }, { id: 'p_t_link_externo', label: 'Link de cadastro externo', icon: 'pi pi-link', sublabel: 'Link público pra pacientes', path: '/therapist/patients/link-externo', roles: ['therapist'], keywords: kw('link','externo','publico','cadastro paciente','convite') }, { id: 'p_t_cad_recebidos', label: 'Cadastros recebidos', icon: 'pi pi-inbox', sublabel: 'Pacientes aguardando aceite', path: '/therapist/patients/cadastro/recebidos', roles: ['therapist'], keywords: kw('recebidos','pendentes','aceitar','intake','novos') }, { id: 'p_t_doc_templates', label: 'Templates de documentos', icon: 'pi pi-file-edit', sublabel: 'Modelos reutilizáveis', path: '/therapist/documents/templates', roles: ['therapist'], keywords: kw('templates','modelos','contratos','documentos') }, { id: 'p_t_online_sched', label: 'Agendamento online', icon: 'pi pi-globe', sublabel: 'Página pública de agendamento', path: '/therapist/online-scheduling', roles: ['therapist'], keywords: kw('online','publico','agendar','landing','pagina','site') }, { id: 'p_t_ag_recebidos', label: 'Agendamentos recebidos', icon: 'pi pi-calendar-plus',sublabel: 'Solicitações da agenda pública', path: '/therapist/agendamentos-recebidos', roles: ['therapist'], keywords: kw('solicitacoes','recebidos','publico','pedidos') }, { id: 'p_t_fin_lanc', label: 'Lançamentos financeiros', icon: 'pi pi-list', sublabel: 'Entradas e saídas', path: '/therapist/financeiro/lancamentos', roles: ['therapist'], keywords: kw('lancamentos','entradas','saidas','fluxo de caixa','receitas','despesas') }, { id: 'p_t_relatorios', label: 'Relatórios', icon: 'pi pi-chart-bar', sublabel: 'Métricas e análises', path: '/therapist/relatorios', roles: ['therapist'], keywords: kw('relatorios','metricas','dashboards','analytics','indicadores') }, { id: 'p_t_security', label: 'Segurança da conta', icon: 'pi pi-shield', sublabel: 'Senha, 2FA, sessões', path: '/therapist/settings/security', roles: ['therapist'], keywords: kw('seguranca','senha','2fa','autenticacao','mfa') }, { id: 'p_t_notificacoes', label: 'Notificações', icon: 'pi pi-bell', sublabel: 'Histórico completo', path: '/therapist/notificacoes', roles: ['therapist'], keywords: kw('notificacoes','historico','alertas','avisos','inbox') }, // ═══════════════════ CLINIC ADMIN (/admin/*) ═══════════════════ { id: 'p_c_dashboard', label: 'Dashboard (clínica)', icon: 'pi pi-home', sublabel: 'Visão geral da clínica', path: '/admin', roles: ['clinic_admin','tenant_admin'], keywords: kw('dashboard','home','clinica') }, { id: 'p_c_features', label: 'Features da clínica', icon: 'pi pi-th-large', sublabel: 'Recursos habilitados', path: '/admin/clinic/features', roles: ['clinic_admin','tenant_admin'], keywords: kw('features','recursos','modulos','addons') }, { id: 'p_c_professionals', label: 'Profissionais', icon: 'pi pi-user', sublabel: 'Terapeutas da clínica', path: '/admin/clinic/professionals', roles: ['clinic_admin','tenant_admin'], keywords: kw('profissionais','terapeutas','equipe','time') }, { id: 'p_c_agenda_clinica', label: 'Agenda da clínica', icon: 'pi pi-calendar', sublabel: 'Agenda consolidada', path: '/admin/agenda/clinica', roles: ['clinic_admin','tenant_admin'], keywords: kw('agenda','clinica','global','consolidada') }, { id: 'p_c_plano', label: 'Plano da clínica', icon: 'pi pi-crown', sublabel: 'Assinatura', path: '/admin/meu-plano', roles: ['clinic_admin','tenant_admin'], keywords: kw('plano','assinatura','billing','clinica') }, // ═══════════════════ CONFIGURAÇÕES (/configuracoes/*) ═══════════════════ { id: 'p_cfg_agenda', label: 'Config: Agenda', icon: 'pi pi-calendar', sublabel: 'Horário de atendimento, durações', path: '/configuracoes/agenda', keywords: kw('config','agenda','horario','duracao','expediente') }, { id: 'p_cfg_bloqueios', label: 'Config: Bloqueios', icon: 'pi pi-ban', sublabel: 'Feriados e indisponibilidades', path: '/configuracoes/bloqueios', keywords: kw('bloqueios','feriados','ferias','indisponivel','folga') }, { id: 'p_cfg_agendador', label: 'Config: Agendador público', icon: 'pi pi-globe', sublabel: 'Configurações da página pública', path: '/configuracoes/agendador', keywords: kw('agendador','publico','online','booking','configurar') }, { id: 'p_cfg_pagamento', label: 'Config: Formas de pagamento', icon: 'pi pi-wallet', sublabel: 'Métodos aceitos', path: '/configuracoes/pagamento', keywords: kw('pagamento','metodos','pix','cartao','boleto','dinheiro') }, { id: 'p_cfg_descontos', label: 'Config: Descontos', icon: 'pi pi-percentage', sublabel: 'Regras de desconto', path: '/configuracoes/descontos', keywords: kw('descontos','promocao','reducao','abatimento') }, { id: 'p_cfg_excecoes', label: 'Config: Exceções financeiras', icon: 'pi pi-exclamation-triangle', sublabel: 'Casos especiais', path: '/configuracoes/excecoes-financeiras', keywords: kw('excecoes','financeiras','casos especiais','ajustes','manuais') }, { id: 'p_cfg_convenios', label: 'Config: Convênios', icon: 'pi pi-id-card', sublabel: 'Planos de saúde', path: '/configuracoes/convenios', keywords: kw('convenios','planos','saude','insurance','seguro') }, { id: 'p_cfg_email', label: 'Config: Templates de e-mail', icon: 'pi pi-envelope', sublabel: 'Mensagens automáticas', path: '/configuracoes/email-templates', keywords: kw('email','templates','modelos','notificacoes','mensagens') }, { id: 'p_cfg_empresa', label: 'Config: Empresa', icon: 'pi pi-building', sublabel: 'Dados da sua empresa', path: '/configuracoes/empresa', keywords: kw('empresa','dados','cnpj','razao social','fantasia','endereco') }, { id: 'p_cfg_conv_tags', label: 'Config: Tags de Conversa', icon: 'pi pi-tag', sublabel: 'Etiquetas pro CRM de conversas', path: '/configuracoes/conversas-tags', keywords: kw('tags','etiquetas','conversas','crm','whatsapp','kanban') }, { id: 'p_cfg_conv_autoreply', label: 'Config: Auto-reply WhatsApp', icon: 'pi pi-reply', sublabel: 'Resposta fora do horário', path: '/configuracoes/conversas-autoreply', keywords: kw('auto-reply','autoresposta','fora do horario','whatsapp','automatico','bot') }, { id: 'p_cfg_conv_optouts', label: 'Config: Opt-outs (LGPD)', icon: 'pi pi-ban', sublabel: 'Números bloqueados de envios auto', path: '/configuracoes/conversas-optouts', keywords: kw('opt-out','optout','lgpd','parar','bloqueio','cancelar','compliance','anpd') }, { id: 'p_cfg_lembretes', label: 'Config: Lembretes de Sessão', icon: 'pi pi-bell', sublabel: 'WhatsApp 24h e 2h antes', path: '/configuracoes/lembretes-sessao', keywords: kw('lembretes','sessao','whatsapp','automatico','reduzir faltas','avisar') }, { id: 'p_cfg_creditos_wa', label: 'Config: Créditos WhatsApp', icon: 'pi pi-credit-card', sublabel: 'Saldo, pacotes, extrato', path: '/configuracoes/creditos-whatsapp', keywords: kw('creditos','whatsapp','saldo','pacote','pagamento','pix','comprar','asaas') }, { id: 'p_cfg_canais', label: 'Config: Canais de notificação', icon: 'pi pi-bell', sublabel: 'WhatsApp, SMS, e-mail', path: '/configuracoes/canais', keywords: kw('canais','notificacoes','lembretes','whatsapp','sms','email') }, { id: 'p_cfg_whatsapp', label: 'Config: WhatsApp', icon: 'pi pi-whatsapp', sublabel: 'Canal WhatsApp', path: '/configuracoes/whatsapp', keywords: kw('whatsapp','wa','mensageria') }, { id: 'p_cfg_whatsapp_ofc', label: 'Config: WhatsApp Oficial AgenciaPSI', icon: 'pi pi-verified', sublabel: 'Número oficial gerenciado', path: '/configuracoes/whatsapp-oficial', keywords: kw('whatsapp','oficial','agenciapsi','business','api','meta','creditos') }, { id: 'p_cfg_whatsapp_pes', label: 'Config: WhatsApp Pessoal', icon: 'pi pi-mobile', sublabel: 'Conectar via QR code', path: '/configuracoes/whatsapp-pessoal', keywords: kw('whatsapp','pessoal','qr','gratis','evolution','baileys') }, { id: 'p_cfg_sms', label: 'Config: SMS', icon: 'pi pi-mobile', sublabel: 'Canal SMS', path: '/configuracoes/sms', keywords: kw('sms','torpedo','texto') }, { id: 'p_cfg_sms_canal', label: 'Config: Canal SMS', icon: 'pi pi-mobile', sublabel: 'Provedor e número', path: '/configuracoes/sms-canal', keywords: kw('sms','canal','provedor') }, { id: 'p_cfg_extras', label: 'Config: Recursos extras', icon: 'pi pi-plus-circle', sublabel: 'Addons e créditos', path: '/configuracoes/recursos-extras', keywords: kw('recursos','extras','addons','creditos','saldo') }, { id: 'p_cfg_auditoria', label: 'Config: Auditoria', icon: 'pi pi-history', sublabel: 'Log de ações', path: '/configuracoes/auditoria', keywords: kw('auditoria','log','historico','acoes') }, // ═══════════════════ CONTA (/account/*) ═══════════════════ { id: 'p_acc_profile', label: 'Meu perfil', icon: 'pi pi-user', sublabel: 'Dados pessoais', path: '/account/profile', keywords: kw('perfil','profile','meus dados','nome','foto','bio') }, { id: 'p_acc_negocio', label: 'Meu negócio', icon: 'pi pi-briefcase', sublabel: 'Dados profissionais', path: '/account/negocio', keywords: kw('negocio','profissional','crp','atuacao','especialidade') }, { id: 'p_acc_security', label: 'Segurança (conta)', icon: 'pi pi-shield', sublabel: 'Senha e autenticação', path: '/account/security', keywords: kw('seguranca','senha','password','2fa') } ]; /** * Filtra páginas pelo papel ativo do usuário. * @param {string|null} role - 'therapist'|'clinic_admin'|'tenant_admin'|'supervisor'|'saas_admin'|'portal_user' * @returns {Array} */ export function filterPagesForRole(role) { if (!role) return PAGES.filter((p) => !p.roles || p.roles.length === 0); return PAGES.filter((p) => !p.roles || p.roles.length === 0 || p.roles.includes(role)); } /** * Normaliza string pra busca fuzzy simples (remove acento, minúsculo, trim). */ function _norm(s) { return String(s || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase().trim(); } /** * Busca fuzzy em páginas filtradas pelo papel. * @param {string} q * @param {string|null} role * @param {number} limit */ export function searchPages(q, role, limit = 6) { const query = _norm(q); const pool = filterPagesForRole(role); if (!query) return pool.slice(0, limit); // top N quando vazio return pool .filter((p) => { const hay = _norm(p.label + ' ' + p.sublabel + ' ' + (p.keywords || []).join(' ')); return hay.includes(query); }) .slice(0, limit); }