167e864b8a
Duas tabs entregues numa sessao — sao mais leves porque reusam
DocumentsListPage e PatientConversationsTab existentes (testados em
producao no PatientProntuario legacy) com KPIs Melissa por cima.
EXTENSAO src/features/patients/utils/patientFormatters.js
- fmtSize(bytes): legivel B/KB/MB/GB
- DOC_TYPE_LABEL map: atestado/receita/laudo/encaminhamento/termo/etc
- chConvLabel(c): whatsapp -> WhatsApp / sms -> SMS / email -> E-mail
EXTENSAO src/features/patients/composables/usePatientDocuments.js
- topType computed: { tipo, count, label } do tipo mais comum
- pendentes computed: count status_revisao === 'pendente'
- sizeTotalFormatted computed: fmtSize(totalBytes)
EXTENSAO src/features/patients/composables/usePatientMessages.js
- primeiraMensagem computed (mais antiga)
- canais computed: Set de m.channel unicos
MELISSAPACIENTE.VUE — Tab Documentos
- 4 KPIs adaptativos (so renderizam com dados):
Total + sizeTotalFormatted / Mais comum / Ultimo / Revisao pendente
- DocumentsListPage embedded no card Melissa (mpa-embed wrapper).
Reusa upload/preview/listagem testados.
MELISSAPACIENTE.VUE — Tab Conversas
- 4 KPIs: Mensagens com canais / Recebidas % / Enviadas % / Ultima
- CTA "Abrir conversa no drawer" estilo WhatsApp pill verde #25d366
que emite open-whatsapp pro parent (Fase 8 integra com
conversationDrawerStore.openForPatient)
- PatientConversationsTab embedded — thread completa com filter/media
CSS: ~50L novos (mpa-conv-cta + mpa-embed wrapper).
Removido kpiDocumentos nao usado (substituido por documentsHook.total
direto).
ESLint: 0 errors da minha mudanca.
PROXIMA: Fase 8 wire-up final (Dialog -> router.push em MelissaPacientes/
MelissaAgenda; decisao sobre TherapistDashboard + PatientsListPage).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
77 lines
2.5 KiB
JavaScript
77 lines
2.5 KiB
JavaScript
/*
|
|
|--------------------------------------------------------------------------
|
|
| Agência PSI
|
|
|--------------------------------------------------------------------------
|
|
| Arquivo: src/features/patients/composables/usePatientMessages.js
|
|
|
|
|
| Mensagens de conversa do paciente. Carrega 200 mais recentes (in+out)
|
|
| pra alimentar o card "Ultimas mensagens" (Visao Geral, top 4) e os
|
|
| KPIs da aba Conversas. Conversa completa fica no PatientConversationsTab.
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
import { ref, computed } from 'vue';
|
|
import { supabase } from '@/lib/supabase/client';
|
|
|
|
export function usePatientMessages() {
|
|
const messages = ref([]);
|
|
const loading = ref(false);
|
|
const error = ref('');
|
|
|
|
async function load(patientId) {
|
|
if (!patientId) {
|
|
messages.value = [];
|
|
return;
|
|
}
|
|
loading.value = true;
|
|
error.value = '';
|
|
messages.value = [];
|
|
try {
|
|
const { data, error: err } = await supabase
|
|
.from('conversation_messages')
|
|
.select('id, body, direction, created_at, channel, kanban_status')
|
|
.eq('patient_id', patientId)
|
|
.order('created_at', { ascending: false })
|
|
.limit(200);
|
|
if (err) throw err;
|
|
messages.value = data || [];
|
|
} catch (e) {
|
|
error.value = e?.message || 'Falha ao carregar mensagens.';
|
|
messages.value = [];
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
const recentes = computed(() => messages.value.slice(0, 4));
|
|
const totalIn = computed(() =>
|
|
messages.value.filter((m) => m.direction === 'in' || m.direction === 'inbound').length
|
|
);
|
|
const totalOut = computed(() =>
|
|
messages.value.filter((m) => m.direction === 'out' || m.direction === 'outbound').length
|
|
);
|
|
const ultimaMensagem = computed(() => messages.value[0] || null);
|
|
const primeiraMensagem = computed(() => messages.value[messages.value.length - 1] || null);
|
|
|
|
/**
|
|
* Canais unicos usados nas mensagens (whatsapp, sms, email).
|
|
*/
|
|
const canais = computed(() => {
|
|
const set = new Set();
|
|
for (const m of messages.value) if (m.channel) set.add(m.channel);
|
|
return [...set];
|
|
});
|
|
|
|
return {
|
|
messages,
|
|
loading,
|
|
error,
|
|
load,
|
|
recentes,
|
|
totalIn,
|
|
totalOut,
|
|
ultimaMensagem,
|
|
primeiraMensagem,
|
|
canais
|
|
};
|
|
}
|