Melissa polish + Prontuario Visao Geral + agenda historico

Sprints B (05-03) e C (05-04) acumulados:

- NotificationDrawer/Item redesign (visual mais limpo, ações inline)
- Dock pins compose (useMelissaDockPins) + cache store global (melissaCacheStore)
- MelissaAgenda: timeline FullCalendar parity + cards resumo, histórico
  card com useMelissaAgendaHistorico, MelissaEventoPanel ajustado
- useFeriados: cache opt-in pra evitar fetch redundante de feriados
- PatientProntuario: aba Visão Geral nova; PatientConversationsTab polish
- AgendaClinicMosaic / AgendaTerapeutaPage / useAgendaSettings: ajustes
  de paridade com Melissa
- DocumentsListPage: pequenos ajustes
- DB migration 20260504000001: fix do trigger pra status 'excluido' nas
  cancel_notifications

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-05-06 09:11:55 -03:00
parent 86311ef305
commit 957e912a7f
19 changed files with 5203 additions and 285 deletions
+51 -3
View File
@@ -18,8 +18,15 @@
import { ref, computed } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { getFeriadosNacionais } from '@/utils/feriadosBR';
import { useMelissaCacheStore, MELISSA_CACHE_TTL } from '@/stores/melissaCacheStore';
// opts.cache (opt-in): habilita stale-while-revalidate via melissaCacheStore.
// Default false pra preservar comportamento em páginas SaaS/admin que
// editam feriados (esperam invalidação imediata após criar/remover).
export function useFeriados(opts = {}) {
const useCache = !!opts.cache;
const cache = useCache ? useMelissaCacheStore() : null;
export function useFeriados() {
const ano = ref(new Date().getFullYear());
const loading = ref(false);
const municipais = ref([]); // linhas da tabela `feriados`
@@ -51,14 +58,53 @@ export function useFeriados() {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}
async function _doFetch(tenantId, cacheKey) {
const { data, error } = await supabase
.from('feriados')
.select('*')
.or(`tenant_id.eq.${tenantId},tenant_id.is.null`)
.gte('data', `${ano.value}-01-01`)
.lte('data', `${ano.value}-12-31`)
.order('data');
if (error) throw error;
const rows = data || [];
if (cache && cacheKey) cache.set('feriados', rows, cacheKey);
municipais.value = rows;
return rows;
}
// ── Load municipais do Supabase ───────────────────────────
async function load(tenantId, year) {
if (year) ano.value = year;
if (!tenantId) return;
if (cache) {
const cacheKey = `${tenantId}:${ano.value}`;
const cached = cache.get('feriados', cacheKey, MELISSA_CACHE_TTL.feriados);
if (cached) {
municipais.value = cached;
_doFetch(tenantId, cacheKey).catch((e) => {
// eslint-disable-next-line no-console
console.warn('[useFeriados] revalidate', e);
});
return;
}
loading.value = true;
try { await _doFetch(tenantId, cacheKey); }
finally { loading.value = false; }
return;
}
// Comportamento legado (sem cache) — páginas de admin que editam.
loading.value = true;
try {
// Busca feriados do tenant + feriados globais (tenant_id null, cadastrados pelo SAAS)
const { data, error } = await supabase.from('feriados').select('*').or(`tenant_id.eq.${tenantId},tenant_id.is.null`).gte('data', `${ano.value}-01-01`).lte('data', `${ano.value}-12-31`).order('data');
const { data, error } = await supabase
.from('feriados')
.select('*')
.or(`tenant_id.eq.${tenantId},tenant_id.is.null`)
.gte('data', `${ano.value}-01-01`)
.lte('data', `${ano.value}-12-31`)
.order('data');
if (error) throw error;
municipais.value = data || [];
} finally {
@@ -71,6 +117,7 @@ export function useFeriados() {
const { data, error } = await supabase.from('feriados').insert(payload).select().single();
if (error) throw error;
municipais.value = [...municipais.value, data].sort((a, b) => a.data.localeCompare(b.data));
if (cache) cache.invalidate('feriados');
return data;
}
@@ -79,6 +126,7 @@ export function useFeriados() {
const { error } = await supabase.from('feriados').delete().eq('id', id);
if (error) throw error;
municipais.value = municipais.value.filter((f) => f.id !== id);
if (cache) cache.invalidate('feriados');
}
// ── Verificar duplicata ───────────────────────────────────