From 76b58af9a1a558f3840423963668f5329093baef Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 28 Apr 2026 17:45:53 -0300 Subject: [PATCH] Melissa: promove rota oficial + redirect automatico da home Sai do estado "preview/sandbox" e liga o Melissa como layout real ativavel pelo user em Configuracoes -> Profile. Mudancas: - routes.misc.js: /preview/melissa/:secao? -> /melissa/:secao?, nome PreviewMelissa -> Melissa. Sem alias por compat (autorizado). - router/index.js: novo beforeEach apos o supportGuard e antes do applyGuards. Quando to.name e' therapist.dashboard ou admin.dashboard E localStorage.layout_variant === 'melissa' E viewport >= 1280px, redireciona pra { name: 'Melissa' }. Le do localStorage (gravado pelo bootstrapUserSettings + setVariant) pra evitar esperar store do DB e evitar flash do shell antes do redirect. Bypassa mobile pq Melissa nao foi feito pra /melissa. Remove regra CSS .lv-card--wip orfa. Tradeoff aceito: rotas especificas (/therapist/agenda etc.) seguem no shell classico/rail. So a HOME do role e' interceptada pra /melissa. Coerente com o desenho atual do MelissaLayout, que ja abre Agenda / Pacientes / etc. como overlays internos via deep-link /melissa/. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/layout/melissa/MelissaLayout.vue | 9 +++--- .../composables/useMelissaPacientes.js | 4 +-- src/router/index.js | 29 +++++++++++++++++++ src/router/routes.misc.js | 13 +++++---- src/views/pages/account/ProfilePage.vue | 21 ++++---------- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/layout/melissa/MelissaLayout.vue b/src/layout/melissa/MelissaLayout.vue index eafa16c..aaf971c 100644 --- a/src/layout/melissa/MelissaLayout.vue +++ b/src/layout/melissa/MelissaLayout.vue @@ -12,7 +12,8 @@ * * Dados ainda em mock. Próxima fase pluga Supabase. * - * Rota atual (sandbox): /preview/melissa + * Rota: /melissa (com :secao? opcional). User com layout_variant='melissa' + * em user_settings e' redirecionado da home do role pra ca pelo router. */ import { ref, computed, watch, onMounted, onBeforeUnmount, provide } from 'vue'; import { useRouter, useRoute } from 'vue-router'; @@ -93,7 +94,7 @@ const SECOES = { }; // Seção ativa = param `:secao?` da rota. URL é a fonte da verdade pra -// permitir back/forward e deep-link (ex: /preview/melissa/agenda abre o +// permitir back/forward e deep-link (ex: /melissa/agenda abre o // overlay da agenda direto). Se a chave for inválida, vira null. const router = useRouter(); const route = useRoute(); @@ -107,11 +108,11 @@ function abrirSecao(key) { workspaceOpen.value = false; eventoSelecionado.value = null; if (key === secaoAberta.value) return; // no-op, evita push duplicado - router.push({ name: 'PreviewMelissa', params: { secao: key } }); + router.push({ name: 'Melissa', params: { secao: key } }); } function fecharSecao() { if (!secaoAberta.value) return; - router.push({ name: 'PreviewMelissa', params: {} }); + router.push({ name: 'Melissa', params: {} }); } // Prefs de layout/UI (toque, fundo, opacidade, formato hora) diff --git a/src/layout/melissa/composables/useMelissaPacientes.js b/src/layout/melissa/composables/useMelissaPacientes.js index fcff5e6..fb77025 100644 --- a/src/layout/melissa/composables/useMelissaPacientes.js +++ b/src/layout/melissa/composables/useMelissaPacientes.js @@ -6,8 +6,8 @@ * - withTenantFilter (defesa em profundidade — RLS cobre, mas blindamos no client) * - normalizeStatus client-side (DB pode ter 'ativo'/'active'/null/etc.) * - * Sem auth (sem uid ou tenant), retorna vazio sem erro — uso em /preview/melissa - * permite a página renderizar mesmo sem session. + * Sem auth (sem uid ou tenant), retorna vazio sem erro — permite a pagina + * renderizar mesmo sem session (defesa em profundidade). * * Forma normalizada do paciente: * { id, nome, email, telefone, avatar_url, status, last_attended_at, created_at } diff --git a/src/router/index.js b/src/router/index.js index b7a1413..9ea1965 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -105,6 +105,35 @@ router.beforeEach(async (to) => { await supportGuard(to, pinia); }); +// ── Layout Melissa: home do role -> /melissa ───────────────────────── +// Quando o user gravou layout_variant='melissa' em user_settings, qualquer +// entrada na home do role (therapist.dashboard ou admin.dashboard) cai +// direto no layout Melissa. Tomada de decisão via localStorage (espelho +// gravado pelo bootstrapUserSettings + setVariant) — evita esperar a +// store carregar do DB e prevenir flash do shell clássico antes do +// redirect. Bypassa em mobile (<1280px), onde Melissa não foi feito pra +// rodar e o effectiveVariant do layout.js já força 'classic'. +const HOME_ROUTE_NAMES = new Set(['therapist.dashboard', 'admin.dashboard']); +router.beforeEach((to) => { + if (!HOME_ROUTE_NAMES.has(to.name)) return; + + let variant = null; + try { + variant = localStorage.getItem('layout_variant'); + } catch { + // localStorage indisponível (modo privado / SSR) — segue o caminho normal + return; + } + if (variant !== 'melissa') return; + + const isMobile = typeof window !== 'undefined' + && typeof window.matchMedia === 'function' + && window.matchMedia('(max-width: 1279px)').matches; + if (isMobile) return; + + return { name: 'Melissa' }; +}); + applyGuards(router); export default router; diff --git a/src/router/routes.misc.js b/src/router/routes.misc.js index ddae6e7..84d1dc5 100644 --- a/src/router/routes.misc.js +++ b/src/router/routes.misc.js @@ -23,14 +23,17 @@ export default { component: () => import('@/views/pages/Landing.vue') }, - // Sandbox do layout Melissa (Direção B — lockscreen-style) - // Standalone, sem auth, sem AppLayout. Promovido de /preview/dashboard-win11. - // Param `:secao?` opcional reflete a seção aberta na URL (agenda, + // Layout Melissa (Direcao B — lockscreen-style). + // Fullscreen, fora do AppLayout — UI inteira do Melissa vive aqui. + // Quem ativa: user com user_settings.layout_variant = 'melissa' + // (escolhido em /account/profile). O router.beforeEach do + // index.js redireciona automaticamente da home do role pra ca. + // Param `:secao?` opcional reflete a secao aberta na URL (agenda, // pacientes, conversas, etc.) — permite deep-link, back/forward, // refresh preservando estado. { - path: 'preview/melissa/:secao?', - name: 'PreviewMelissa', + path: 'melissa/:secao?', + name: 'Melissa', component: () => import('@/layout/melissa/MelissaLayout.vue') }, diff --git a/src/views/pages/account/ProfilePage.vue b/src/views/pages/account/ProfilePage.vue index 6f7c85f..f822292 100644 --- a/src/views/pages/account/ProfilePage.vue +++ b/src/views/pages/account/ProfilePage.vue @@ -1424,16 +1424,16 @@ onBeforeUnmount(() => { - +