Ajuste em Massa - Paciente, Terapeuta, Clinica e Admin - Inicio agenda
This commit is contained in:
+68
-26
@@ -1,54 +1,96 @@
|
||||
// src/navigation/index.js
|
||||
|
||||
// ======================================================
|
||||
// 📦 Importação dos menus base por área
|
||||
// ======================================================
|
||||
|
||||
import adminMenu from './menus/admin.menu'
|
||||
import therapistMenu from './menus/therapist.menu'
|
||||
import patientMenu from './menus/patient.menu'
|
||||
import portalMenu from './menus/portal.menu'
|
||||
import sakaiDemoMenu from './menus/sakai.demo.menu'
|
||||
import saasMenu from './menus/saas.menu'
|
||||
|
||||
import { useSaasHealthStore } from '@/stores/saasHealthStore'
|
||||
import { useTenantFeaturesStore } from '@/stores/tenantFeaturesStore'
|
||||
|
||||
// ======================================================
|
||||
// 🎭 Mapeamento de role → menu base
|
||||
// ======================================================
|
||||
|
||||
const MENUS = {
|
||||
admin: adminMenu,
|
||||
// ✅ role real do tenant
|
||||
clinic_admin: adminMenu,
|
||||
therapist: therapistMenu,
|
||||
patient: patientMenu
|
||||
patient: portalMenu,
|
||||
|
||||
// ✅ compatibilidade profiles.role
|
||||
admin: adminMenu,
|
||||
|
||||
// ✅ legado
|
||||
tenant_admin: adminMenu
|
||||
}
|
||||
|
||||
// aceita export de menu como ARRAY ou como FUNÇÃO (ctx) => []
|
||||
// ======================================================
|
||||
// 🧠 Função utilitária
|
||||
// Permite que o menu seja:
|
||||
// - Array direto
|
||||
// - ou função (ctx) => Array
|
||||
// ======================================================
|
||||
|
||||
function resolveMenu (builder, ctx) {
|
||||
if (!builder) return []
|
||||
return typeof builder === 'function' ? builder(ctx) : builder
|
||||
}
|
||||
|
||||
/**
|
||||
* role: vem do seu contexto (admin/therapist/patient)
|
||||
* sessionCtx: objeto que tenha { isSaasAdmin: boolean } (ex.: authStore, sessionStore, etc.)
|
||||
*/
|
||||
export function getMenuByRole (role, sessionCtx) {
|
||||
const base = resolveMenu(MENUS[role], sessionCtx)
|
||||
// ======================================================
|
||||
// 🎯 getMenuByRole
|
||||
// ======================================================
|
||||
|
||||
// ✅ badge dinâmica do Health (contador vem do store)
|
||||
// ⚠️ não faz fetch aqui: o AppMenu carrega o store.
|
||||
export function getMenuByRole (role, sessionCtx = {}) {
|
||||
// 🔹 Store de health do SaaS (badge dinâmica)
|
||||
// ⚠️ Não faz fetch aqui. O AppMenu carrega o store.
|
||||
const saasHealthStore = useSaasHealthStore()
|
||||
const mismatchCount = saasHealthStore?.mismatchCount || 0
|
||||
|
||||
// ✅ menu SaaS entra como overlay, não depende de role
|
||||
// passa opts com mismatchCount (saas.menu.js vai usar pra badge)
|
||||
// 🔹 Store de módulos por tenant (tenant_features)
|
||||
// ⚠️ Não faz fetch aqui. O guard/app deve carregar. Aqui só lemos cache.
|
||||
const tenantFeaturesStore = useTenantFeaturesStore()
|
||||
|
||||
// 🔹 SaaS overlay aparece somente para SaaS master
|
||||
const isSaas = sessionCtx?.isSaasAdmin === true
|
||||
|
||||
// ctx que será passado pros menu builders
|
||||
const ctx = {
|
||||
...sessionCtx,
|
||||
mismatchCount,
|
||||
tenantFeaturesStore,
|
||||
tenantFeatureEnabled: (key) => {
|
||||
try { return !!tenantFeaturesStore?.isEnabled?.(key) } catch { return false }
|
||||
}
|
||||
}
|
||||
|
||||
// 🔹 Menu base da role
|
||||
const base = resolveMenu(MENUS[role], ctx)
|
||||
|
||||
// 🔹 Resolve menu SaaS (array ou função)
|
||||
const saas = typeof saasMenu === 'function'
|
||||
? saasMenu(sessionCtx, { mismatchCount })
|
||||
? saasMenu(ctx, { mismatchCount })
|
||||
: saasMenu
|
||||
|
||||
// ✅ mantém demos disponíveis para admin em DEV (não polui prod)
|
||||
if (role === 'admin' && import.meta.env.DEV) {
|
||||
return [
|
||||
...base,
|
||||
...(saas.length ? [{ separator: true }, ...saas] : []),
|
||||
{ separator: true },
|
||||
...sakaiDemoMenu
|
||||
]
|
||||
}
|
||||
// ======================================================
|
||||
// 🚀 Menu final
|
||||
// - base sempre
|
||||
// - overlay SaaS só para SaaS master
|
||||
// - Demo Sakai só para SaaS master em DEV
|
||||
// ======================================================
|
||||
|
||||
return [
|
||||
...base,
|
||||
...(saas.length ? [{ separator: true }, ...saas] : [])
|
||||
|
||||
...(isSaas && saas.length ? [{ separator: true }, ...saas] : []),
|
||||
|
||||
...(isSaas && import.meta.env.DEV
|
||||
? [{ separator: true }, ...sakaiDemoMenu]
|
||||
: [])
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,111 @@
|
||||
export default [
|
||||
{
|
||||
label: 'Admin',
|
||||
// src/navigation/menus/admin.menu.js
|
||||
|
||||
export default function adminMenu (ctx = {}) {
|
||||
const patientsOn = !!ctx?.tenantFeatureEnabled?.('patients')
|
||||
|
||||
const menu = [
|
||||
// =====================================================
|
||||
// 📊 OPERAÇÃO
|
||||
// =====================================================
|
||||
{
|
||||
label: 'Operação',
|
||||
items: [
|
||||
{
|
||||
label: 'Dashboard',
|
||||
icon: 'pi pi-fw pi-home',
|
||||
to: '/admin'
|
||||
},
|
||||
{
|
||||
label: 'Agenda',
|
||||
icon: 'pi pi-fw pi-calendar',
|
||||
to: '/admin/agenda',
|
||||
feature: 'agenda.view'
|
||||
},
|
||||
{
|
||||
label: 'Agenda da Clínica',
|
||||
icon: 'pi pi-fw pi-sitemap',
|
||||
to: '/admin/agenda/clinica',
|
||||
feature: 'agenda.view'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// =====================================================
|
||||
// 👥 PACIENTES (somente se módulo ativo)
|
||||
// =====================================================
|
||||
if (patientsOn) {
|
||||
menu.push({
|
||||
label: 'Pacientes',
|
||||
items: [
|
||||
{
|
||||
label: 'Lista de Pacientes',
|
||||
icon: 'pi pi-fw pi-users',
|
||||
to: '/admin/pacientes'
|
||||
},
|
||||
{
|
||||
label: 'Grupos',
|
||||
icon: 'pi pi-fw pi-users',
|
||||
to: '/admin/pacientes/grupos'
|
||||
},
|
||||
{
|
||||
label: 'Tags',
|
||||
icon: 'pi pi-fw pi-tags',
|
||||
to: '/admin/pacientes/tags'
|
||||
},
|
||||
{
|
||||
label: 'Link Externo',
|
||||
icon: 'pi pi-fw pi-link',
|
||||
to: '/admin/pacientes/link-externo'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// ⚙️ GESTÃO DA CLÍNICA
|
||||
// =====================================================
|
||||
menu.push({
|
||||
label: 'Gestão',
|
||||
items: [
|
||||
{
|
||||
label: 'Dashboard',
|
||||
icon: 'pi pi-fw pi-home',
|
||||
to: '/admin'
|
||||
label: 'Profissionais',
|
||||
icon: 'pi pi-fw pi-id-card',
|
||||
to: '/admin/clinic/professionals'
|
||||
},
|
||||
{
|
||||
label: 'Clínicas',
|
||||
icon: 'pi pi-fw pi-building',
|
||||
to: '/admin/clinics'
|
||||
},
|
||||
{
|
||||
label: 'Usuários',
|
||||
icon: 'pi pi-fw pi-users',
|
||||
to: '/admin/users'
|
||||
label: 'Módulos da Clínica',
|
||||
icon: 'pi pi-fw pi-sliders-h',
|
||||
to: '/admin/clinic/features'
|
||||
},
|
||||
{
|
||||
label: 'Assinatura',
|
||||
icon: 'pi pi-fw pi-credit-card',
|
||||
to: '/admin/billing'
|
||||
},
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 🔒 MÓDULO PRO (exemplo)
|
||||
{
|
||||
label: 'Agendamento Online (PRO)',
|
||||
icon: 'pi pi-fw pi-calendar',
|
||||
to: '/admin/online-scheduling',
|
||||
feature: 'online_scheduling.manage',
|
||||
proBadge: true
|
||||
},
|
||||
|
||||
// ✅ ajustado para bater com sua rota "configuracoes"
|
||||
// =====================================================
|
||||
// 🔒 SISTEMA
|
||||
// =====================================================
|
||||
menu.push({
|
||||
label: 'Sistema',
|
||||
items: [
|
||||
{
|
||||
label: 'Segurança',
|
||||
icon: 'pi pi-fw pi-shield',
|
||||
to: '/admin/configuracoes/seguranca'
|
||||
to: '/admin/settings/security'
|
||||
},
|
||||
{
|
||||
label: 'Agendamento Online (PRO)',
|
||||
icon: 'pi pi-fw pi-calendar-plus',
|
||||
to: '/admin/online-scheduling',
|
||||
feature: 'online_scheduling.manage',
|
||||
proBadge: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Pacientes',
|
||||
items: [
|
||||
{
|
||||
label: 'Meus Pacientes',
|
||||
icon: 'pi pi-list',
|
||||
to: '/admin/pacientes',
|
||||
quickCreate: true,
|
||||
quickCreateFullTo: '/admin/pacientes/novo',
|
||||
quickCreateEntity: 'patient'
|
||||
},
|
||||
{
|
||||
label: 'Grupos de pacientes',
|
||||
icon: 'pi pi-fw pi-users',
|
||||
to: '/admin/pacientes/grupos'
|
||||
},
|
||||
{
|
||||
label: 'Tags',
|
||||
icon: 'pi pi-tags',
|
||||
to: '/admin/pacientes/tags'
|
||||
},
|
||||
{
|
||||
label: 'Link externo (Cadastro)',
|
||||
icon: 'pi pi-link',
|
||||
to: '/admin/pacientes/link-externo'
|
||||
},
|
||||
{
|
||||
label: 'Cadastros Recebidos',
|
||||
icon: 'pi pi-inbox',
|
||||
to: '/admin/pacientes/cadastro/recebidos'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return menu
|
||||
}
|
||||
@@ -5,20 +5,12 @@ export default [
|
||||
// ======================
|
||||
// ✅ Básico (sempre)
|
||||
// ======================
|
||||
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/patient' },
|
||||
|
||||
{ label: 'Consultas', icon: 'pi pi-fw pi-calendar-plus', to: '/patient/appointments' },
|
||||
|
||||
{ label: 'Meu Perfil', icon: 'pi pi-fw pi-user', to: '/patient/profile' },
|
||||
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/portal' },
|
||||
{ label: 'Minha Agenda', icon: 'pi pi-fw pi-calendar-plus', to: '/portal/agenda' },
|
||||
{ label: 'Agendar Sessão', icon: 'pi pi-fw pi-user', to: '/portal/agenda/new' },
|
||||
// ✅ Conta é global, não do portal
|
||||
{ label: 'My Account', icon: 'pi pi-fw pi-user', to: '/account/profile' }
|
||||
|
||||
{
|
||||
label: 'Agendamento online',
|
||||
icon: 'pi pi-fw pi-globe',
|
||||
to: '/patient/online-scheduling',
|
||||
feature: 'online_scheduling.manage',
|
||||
proBadge: true
|
||||
},
|
||||
|
||||
// =====================================================
|
||||
// 🔒 PRO (exemplos futuros no portal do paciente)
|
||||
// =====================================================
|
||||
@@ -32,7 +24,7 @@ export default [
|
||||
// {
|
||||
// label: 'Agendar online',
|
||||
// icon: 'pi pi-fw pi-globe',
|
||||
// to: '/patient/online-scheduling',
|
||||
// to: '/portal/online-scheduling',
|
||||
// feature: 'online_scheduling.public',
|
||||
// proBadge: true
|
||||
// },
|
||||
@@ -41,7 +33,7 @@ export default [
|
||||
// {
|
||||
// label: 'Documentos',
|
||||
// icon: 'pi pi-fw pi-file',
|
||||
// to: '/patient/documents',
|
||||
// to: '/portal/documents',
|
||||
// feature: 'patient_documents',
|
||||
// proBadge: true
|
||||
// },
|
||||
@@ -50,7 +42,7 @@ export default [
|
||||
// {
|
||||
// label: 'Sala de atendimento',
|
||||
// icon: 'pi pi-fw pi-video',
|
||||
// to: '/patient/telehealth',
|
||||
// to: '/portal/telehealth',
|
||||
// feature: 'telehealth',
|
||||
// proBadge: true
|
||||
// }
|
||||
@@ -1,10 +1,15 @@
|
||||
// src/navigation/menus/saas.menu.js
|
||||
|
||||
export default function saasMenu (authStore, opts = {}) {
|
||||
if (!authStore?.isSaasAdmin) return []
|
||||
export default function saasMenu (sessionCtx, opts = {}) {
|
||||
if (!sessionCtx?.isSaasAdmin) return []
|
||||
|
||||
const mismatchCount = Number(opts?.mismatchCount || 0)
|
||||
|
||||
// ✅ helper p/ evitar repetir spread + manter comentários intactos
|
||||
const mismatchBadge = mismatchCount > 0
|
||||
? { badge: String(mismatchCount), badgeClass: 'p-badge p-badge-danger' }
|
||||
: {}
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'SaaS',
|
||||
@@ -16,11 +21,11 @@ export default function saasMenu (authStore, opts = {}) {
|
||||
{
|
||||
label: 'Planos',
|
||||
icon: 'pi pi-star',
|
||||
path: '/plans', // ✅ vira /saas/plans pelo parentPath
|
||||
path: '/saas/plans', // ✅ absoluto (mais confiável p/ active/expand)
|
||||
items: [
|
||||
{ label: 'Listagem de Planos', icon: 'pi pi-list', to: '/saas/plans' },
|
||||
|
||||
// ✅ NOVO: vitrine pública (pricing page)
|
||||
// ✅ vitrine pública (pricing page)
|
||||
{ label: 'Vitrine Pública', icon: 'pi pi-megaphone', to: '/saas/plans-public' },
|
||||
|
||||
{ label: 'Recursos', icon: 'pi pi-bolt', to: '/saas/features' },
|
||||
@@ -31,7 +36,7 @@ export default function saasMenu (authStore, opts = {}) {
|
||||
{
|
||||
label: 'Assinaturas',
|
||||
icon: 'pi pi-credit-card',
|
||||
path: '/subscriptions', // ✅ vira /saas/subscriptions
|
||||
path: '/saas/subscriptions', // ✅ absoluto
|
||||
items: [
|
||||
{ label: 'Listagem de Assinaturas', icon: 'pi pi-list', to: '/saas/subscriptions' },
|
||||
{ label: 'Histórico', icon: 'pi pi-history', to: '/saas/subscription-events' },
|
||||
@@ -39,20 +44,21 @@ export default function saasMenu (authStore, opts = {}) {
|
||||
label: 'Saúde das Assinaturas',
|
||||
icon: 'pi pi-shield',
|
||||
to: '/saas/subscription-health',
|
||||
...(mismatchCount > 0
|
||||
? { badge: String(mismatchCount), badgeClass: 'p-badge p-badge-danger' }
|
||||
...(mismatchBadge
|
||||
? mismatchBadge
|
||||
: {})
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Intenções de Assinatura',
|
||||
icon: 'pi pi-inbox',
|
||||
to: '/saas/subscription-intents'
|
||||
},
|
||||
|
||||
{
|
||||
label: 'Intenções de Assinatura',
|
||||
icon: 'pi pi-inbox',
|
||||
to: '/saas/subscription-intents'
|
||||
},
|
||||
|
||||
{ label: 'Clínicas (Tenants)', icon: 'pi pi-users', to: '/saas/tenants' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,47 @@
|
||||
// src/navigation/menus/therapist.menu.js
|
||||
|
||||
export default [
|
||||
{
|
||||
label: 'Terapeuta',
|
||||
label: 'Therapist',
|
||||
items: [
|
||||
// ======================================================
|
||||
// 📊 DASHBOARD
|
||||
// ======================================================
|
||||
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', to: '/therapist' },
|
||||
|
||||
// ======================================================
|
||||
// 📅 AGENDA
|
||||
// ======================================================
|
||||
{ label: 'Agenda', icon: 'pi pi-fw pi-calendar', to: '/therapist/agenda' },
|
||||
|
||||
// ✅ PRO
|
||||
// ======================================================
|
||||
// 👥 PATIENTS
|
||||
// ======================================================
|
||||
{ label: 'Meus pacientes', icon: 'pi pi-list', to: '/therapist/patients' },
|
||||
|
||||
{ label: 'Grupo de pacientes', icon: 'pi pi-fw pi-users', to: '/therapist/patients/grupos' },
|
||||
|
||||
{ label: 'Tags', icon: 'pi pi-tags', to: '/therapist/patients/tags' },
|
||||
|
||||
{ label: 'Meu link de cadastro', icon: 'pi pi-link', to: '/therapist/patients/link-externo' },
|
||||
|
||||
{ label: 'Cadastros recebidos', icon: 'pi pi-inbox', to: '/therapist/patients/cadastro/recebidos' },
|
||||
|
||||
// ======================================================
|
||||
// 🔒 PRO — Online Scheduling
|
||||
// ======================================================
|
||||
{
|
||||
label: 'Agendamento online',
|
||||
label: 'Online Scheduling',
|
||||
icon: 'pi pi-fw pi-globe',
|
||||
to: '/therapist/online-scheduling',
|
||||
feature: 'online_scheduling.manage',
|
||||
proBadge: true
|
||||
},
|
||||
|
||||
{ label: 'Pacientes', icon: 'pi pi-fw pi-id-card', to: '/therapist/patients' }
|
||||
// ======================================================
|
||||
// 👤 ACCOUNT
|
||||
// ======================================================
|
||||
{ label: 'Meu Perfil', icon: 'pi pi-fw pi-user', to: '/account/profile' }
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
Reference in New Issue
Block a user