Melissa: deep-link via URL + Pacientes (WIP) + cronometro reset

Roteamento por URL (substitui o ref local secaoAberta):
- routes.misc.js: rota vira /preview/melissa/:secao? — param opcional
- MelissaLayout.vue: secaoAberta agora e computed do route.params.secao,
  validado contra SECOES (chave invalida -> null). abrirSecao/fecharSecao
  fazem router.push em vez de mutar ref. Habilita back/forward, refresh
  e deep-link tipo /preview/melissa/agenda.

Pagina Pacientes (WIP, ainda nao wireada no slot do Layout):
- src/layout/melissa/MelissaPacientes.vue (novo, ~? linhas) — fullscreen
  3-col espelhando MelissaAgenda: aside esquerda com filtros (status /
  grupos / tags), lista central com cards + busca, quick view direita
  com KPIs do paciente selecionado + acoes.
- Carrega pacientes (todos os status), grupos/tags do tenant, vinculos
  patient_groups + patient_tags + session counts em paralelo.
- Integra PatientProntuario (overlay), PatientCadastroDialog,
  PatientCreatePopover + ComponentCadastroRapido, e
  conversationDrawerStore (acao WhatsApp da quick view).

useMelissaPacientes ganha opcao { onlyActive }:
- default true (compat com cards do resumo / cronometro / eventos hoje
  — so faz sentido com ativos)
- false retorna Ativo + Inativo + Arquivado, pra uso na pagina nova
- select agora inclui data_nascimento (necessario pros KPIs da quick view)

Cronometro: zera ao parar — terminou a sessao, fica pronto pra proxima
sem precisar reabrir o popover.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-04-28 17:12:15 -03:00
parent 7b67bd083a
commit 06bce11e1c
5 changed files with 1755 additions and 8 deletions
+14 -3
View File
@@ -15,6 +15,7 @@
* Rota atual (sandbox): /preview/melissa
*/
import { ref, computed, watch, onMounted, onBeforeUnmount, provide } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import { useLayout } from '@/layout/composables/layout';
import { applyThemeEngine } from '@/theme/theme.options';
@@ -91,16 +92,26 @@ const SECOES = {
medicos: { label: 'Médicos e referências', icon: 'pi pi-user-edit', descricao: 'Profissionais que encaminham ou recebem pacientes.' }
};
const secaoAberta = ref(null); // chave em SECOES, ou null
// 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
// overlay da agenda direto). Se a chave for inválida, vira null.
const router = useRouter();
const route = useRoute();
const secaoAberta = computed(() => {
const s = route.params?.secao;
return s && SECOES[s] ? s : null;
});
function abrirSecao(key) {
// Fecha overlays paralelos pra evitar empilhamento
workspaceOpen.value = false;
eventoSelecionado.value = null;
secaoAberta.value = key;
if (key === secaoAberta.value) return; // no-op, evita push duplicado
router.push({ name: 'PreviewMelissa', params: { secao: key } });
}
function fecharSecao() {
secaoAberta.value = null;
if (!secaoAberta.value) return;
router.push({ name: 'PreviewMelissa', params: {} });
}
// Prefs de layout/UI (toque, fundo, opacidade, formato hora)