diff --git a/src/layout/melissa/MelissaAgenda.vue b/src/layout/melissa/MelissaAgenda.vue index 04a2b14..31ce1b1 100644 --- a/src/layout/melissa/MelissaAgenda.vue +++ b/src/layout/melissa/MelissaAgenda.vue @@ -115,6 +115,16 @@ const fcRef = ref(null); // Title visível na toolbar (atualizado pelo FC via datesSet) const currentTitle = ref(''); +// Botão "Hoje" fica desabilitado quando o range visível JÁ inclui hoje +// (evita click ruidoso e dá affordance de "está em hoje"). +const refDateIsToday = computed(() => { + const hoje = new Date(); + const inicio = viewStart.value; + const fim = viewEnd.value; + if (!inicio || !fim) return false; + return hoje >= inicio && hoje < fim; +}); + // Range visível atual (passa pro composable que refetcha) const viewStart = ref(new Date()); const viewEnd = ref(new Date()); @@ -149,22 +159,47 @@ function dateKey(date) { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } +// ── Filtro por stat ──────────────────────────────────────────── +// Click num stat do "Hoje" filtra fcEvents + sessoesHoje pelo predicado +// correspondente. Click no stat ativo limpa o filtro. Stats com value=0 +// ficam disabled. Feriados continuam sempre (background events). +const STAT_FILTERS = { + total: () => true, + sessoes: (e) => e.tipo === 'sessao', + realizadas: (e) => /realizad/i.test(e.status), + faltas: (e) => /falt/i.test(e.status) +}; +const STAT_LABELS = { + total: 'Total', sessoes: 'Sessões', realizadas: 'Realizadas', faltas: 'Faltas' +}; +const statFiltroAtivo = ref(null); // null | 'total' | 'sessoes' | 'realizadas' | 'faltas' + +function toggleStatFiltro(key) { + statFiltroAtivo.value = statFiltroAtivo.value === key ? null : key; +} +function statLabel(key) { + return STAT_LABELS[key] || ''; +} + // FC events derivados dos eventos do composable + feriados como background. // feriadoFcEvents vem do useFeriados (display:'background', cor amber suave). // Pattern espelha AgendaTerapeutaPage:601. -const fcEvents = computed(() => [ - ...eventosSemana.value.map((ev) => ({ - id: ev.id, - title: ev.label, - start: ev.inicio_em, - end: ev.fim_em, - backgroundColor: `${ev.color}26`, // ~15% opacity - borderColor: ev.color, - textColor: 'white', - extendedProps: ev - })), - ...feriadoFcEvents.value -]); +const fcEvents = computed(() => { + const pred = statFiltroAtivo.value ? STAT_FILTERS[statFiltroAtivo.value] : () => true; + return [ + ...eventosSemana.value.filter(pred).map((ev) => ({ + id: ev.id, + title: ev.label, + start: ev.inicio_em, + end: ev.fim_em, + backgroundColor: `${ev.color}26`, // ~15% opacity + borderColor: ev.color, + textColor: 'white', + extendedProps: ev + })), + ...feriadoFcEvents.value + ]; +}); function escHtml(s) { return String(s ?? '') @@ -476,23 +511,23 @@ const eventosHojeReal = computed(() => { }); // ── Stats do dia (real) ──────────────────────────────────────── +// Cada stat tem `key` que casa com STAT_FILTERS pra interatividade. const statsHoje = computed(() => { const arr = eventosHojeReal.value; - const total = arr.length; - const sessoes = arr.filter((e) => e.tipo === 'sessao').length; - const realizadas = arr.filter((e) => /realizad/i.test(e.status)).length; - const faltas = arr.filter((e) => /falt/i.test(e.status)).length; return [ - { label: 'Total', value: total, cls: '' }, - { label: 'Sessões', value: sessoes, cls: 'ok' }, - { label: 'Realizadas', value: realizadas, cls: '' }, - { label: 'Faltas', value: faltas, cls: 'warn' } + { key: 'total', label: 'Total', value: arr.length, cls: '' }, + { key: 'sessoes', label: 'Sessões', value: arr.filter(STAT_FILTERS.sessoes).length, cls: 'ok' }, + { key: 'realizadas', label: 'Realizadas', value: arr.filter(STAT_FILTERS.realizadas).length, cls: '' }, + { key: 'faltas', label: 'Faltas', value: arr.filter(STAT_FILTERS.faltas).length, cls: 'warn' } ]; }); // ── Sessões hoje (lista, ordenadas por hora) ────────────────── +// Aplica o mesmo filtro dos stats pra coerência visual: clicar no stat +// "Faltas" mostra só faltas tanto no FC quanto na lista logo abaixo. const sessoesHoje = computed(() => { - return [...eventosHojeReal.value].sort((a, b) => a.startH - b.startH); + const pred = statFiltroAtivo.value ? STAT_FILTERS[statFiltroAtivo.value] : () => true; + return [...eventosHojeReal.value].filter(pred).sort((a, b) => a.startH - b.startH); }); // ── Cadastro de paciente (popover + dialogs) ────────────────── @@ -621,15 +656,18 @@ const kebabItems = computed(() => { {{ sessoesHoje.length }}