carousel, agenda arquivados, agenda cor, agenda arquivados, grupos pacientes, pacientes arquivados - desativados, sessoes verificadas, ajuste notificações, Prontuario, Agenda Animation, Menu Profile, bagdes Profile, Offline

This commit is contained in:
Leonardo
2026-03-18 09:26:09 -03:00
parent 66f67cd40f
commit d6d2fe29d1
55 changed files with 3655 additions and 1512 deletions
+40 -10
View File
@@ -164,6 +164,10 @@
@click="gotoResult(r)"
>
<div class="font-medium truncate">{{ r.titulo || 'Sem título' }}</div>
<span
v-if="r.patients?.status === 'Inativo' || r.patients?.status === 'Arquivado'"
class="inline-block text-[0.6rem] bg-orange-500 text-white px-1.5 py-px rounded font-bold uppercase tracking-wide mt-0.5"
>{{ r.patients?.status === 'Arquivado' ? 'paciente arquivado' : 'paciente desativado' }}</span>
<div class="mt-1 flex items-center justify-between gap-2 text-xs opacity-70">
<span class="truncate">{{ fmtDateTime(r.inicio_em) }}</span>
@@ -304,6 +308,10 @@
<div class="font-semibold text-sm truncate">
{{ r.paciente_nome || r.patient_name || r.titulo || 'Sem título' }}
</div>
<span
v-if="r.paciente_status === 'Inativo' || r.paciente_status === 'Arquivado'"
class="inline-block text-[0.6rem] bg-orange-500 text-white px-1.5 py-px rounded font-bold uppercase tracking-wide mt-0.5"
>{{ r.paciente_status === 'Arquivado' ? 'paciente arquivado' : 'paciente desativado' }}</span>
<!-- Linha 3: título (se paciente diferente de título) -->
<div
@@ -623,7 +631,18 @@ const timeModeOptions = [
{ label: 'Meu Horário', value: 'my' }
]
const mosaicMode = computed(() => timeMode.value === '24' ? 'full_24h' : 'work_hours')
const mosaicMode = ref('work_hours')
const mosaicModeOptions = [
{ label: 'Horas de Trabalho', value: 'work_hours' },
{ label: 'Grade Completa', value: 'full_24h' }
]
// Sincroniza mosaicMode com timeMode: '24h' força grade completa
watch(timeMode, (v) => {
if (v === '24') mosaicMode.value = 'full_24h'
else if (mosaicMode.value === 'full_24h') mosaicMode.value = 'work_hours'
})
function settingsFallbackStart () {
const s = settings.value
@@ -936,15 +955,26 @@ const baseRows = computed(() => {
})
if (!onlySessions.value) return refined
return refined.filter(r => {
const tipo = normalizeEventoTipo(r.tipo, EVENTO_TIPO.SESSAO)
return tipo === EVENTO_TIPO.SESSAO || r.masked === true
})
// Filtrar por patient_id — filtro por tipo não funciona pois o enum do banco
// usa 'sessao' para todos os compromissos não-bloqueio (Análise, Leitura, etc.)
return refined.filter(r => !!(r.patient_id || r.masked))
})
const allEvents = computed(() => {
// Mapa id → cores para injetar em ocorrências virtuais (que não têm o join determined_commitments)
const colorMap = new Map(
(commitmentOptionsNormalized.value || [])
.filter(c => c.id)
.map(c => [c.id, { bg_color: c.bg_color || null, text_color: c.text_color || null }])
)
function withCommitmentColors (r) {
if (r.determined_commitments || !r.determined_commitment_id) return r
const colors = colorMap.get(r.determined_commitment_id)
return colors ? { ...r, determined_commitments: colors } : r
}
// eventos reais (sem ocorrências virtuais para evitar duplicatas)
const realRows = (baseRows.value || []).filter(r => !r.is_occurrence)
const realRows = (baseRows.value || []).filter(r => !r.is_occurrence).map(withCommitmentColors)
const base = mapAgendaEventosToCalendarEvents(realRows)
// ocorrências virtuais das séries
@@ -953,8 +983,8 @@ const allEvents = computed(() => {
const tipo = normalizeEventoTipo(r.tipo, EVENTO_TIPO.SESSAO)
const dc = r.determined_commitment_id
if (tipo === EVENTO_TIPO.SESSAO && dc && !isSessionCommitmentId(dc)) return maskPrivateRow(r)
if (onlySessions.value && tipo !== EVENTO_TIPO.SESSAO) return null
return r
if (onlySessions.value && !(r.patient_id || r.masked)) return null
return withCommitmentColors(r)
}).filter(Boolean)
const occEvents = mapAgendaEventosToCalendarEvents(occRows)
@@ -2059,7 +2089,7 @@ async function _reloadRange () {
// Expande recorrências para cada terapeuta no range
const allMerged = []
for (const ownId of ownerIds.value) {
const merged = await loadAndExpand(ownId, start, end, rows.value.filter(r => r.owner_id === ownId))
const merged = await loadAndExpand(ownId, start, end, rows.value.filter(r => r.owner_id === ownId), tenantId.value)
allMerged.push(...merged.filter(r => r.is_occurrence))
}
_occurrenceRows.value = allMerged
@@ -2536,7 +2566,7 @@ function goRecorrencias () { router.push({ name: 'admin-agenda-recorrencias' })
width: 5px;
height: 5px;
border-radius: 50%;
background: greenyellow;
background: var(--primary-color, #6366f1);
}
/* Badge numérico no header */