From 98f7252dcd728b776b4a1c3ffb85e3e4e54e1a18 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 6 May 2026 09:14:35 -0300 Subject: [PATCH] Melissa: 6 Pages aplicando blueprint + dialogs unificados + Conversa estilo WhatsApp Sprint F (05-06). Blueprint tabular aplicado nas 6 paginas restantes; dialogs harmonizados (FloatLabel + IconField + variant=filled + section dividers, espelhando PatientsCadastroPage Identidade); ConversationDrawer repaginado pra visual estilo WhatsApp. Pages refatoradas (cada uma com subheader, sidebar __scroll + __footer fixo "Limpar filtros", Xs inline pra zerar filtro individual, mobile drawer com sticky footer): - MelissaCompromissos: blueprint mantendo row design original (color stripe + name + badges + descricao + meta inline). Filtros Status (Ativos/Inativos) + Tipo (Nativos/Meus). Coluna Acoes frozen 140px com toggle+pencil+trash. - MelissaGrupos / MelissaTags: pattern completo + dialog "Pacientes do grupo/tag" com lista vinculada via patient_group_patient / patient_patient_tag. Avatar primary nos pacientes, header colorido com cor da entidade, X de fechar igual .mc-close. Dialog de criar/editar com FloatLabel + section dividers. - MelissaMedicos: blueprint + dialog "Pacientes encaminhados" usando cor primary do tema (medicos nao tem cor propria); dialog de criar/editar com 4 secoes (Identificacao/Contato/Localizacao/Obs) espelhando PatientsCadastroPage. Service ja tinha fetchPatientsByMedicoNome (ILIKE em encaminhado_por). - MelissaConversas: subheader, sidebar com bg-soft + border-right e cards com sombra (mw-w--side), Limpar filtros global no footer fixo (fix bug: filters era ref({...}) e eu lia filters.search direto, agora usa .value), alerta de unlinked movido pro topo, kanban mobile com min-height nas colunas pra mostrar mensagens. - MelissaRecorrencias: subheader, button list de status (Ativas verde/ Encerradas vermelho/Todas) substitui SelectButton, busca por nome do paciente, footer Limpar filtros, X inline no filtro Status. ConversationDrawer redesign (WhatsApp-style): - Header com avatar circular primary + iniciais + numero formatado - Container de mensagens com bg "papel de parede" (color-mix com bege esverdeado WA + radial-gradient pattern) - Bolhas com cantos certos (top-left ou top-right zerado simulando tail), sombra sutil, cores autenticas (#d9fdd3 light/#005c4b dark outbound; #fff/#202c33 inbound), detecao dark via :global - Time HH:MM + status overlay no canto inferior direito DENTRO do balao; checks azuis quando lida (#53bdeb) - Compose pill rounded-full + botao Send circular verde #00a884 - Removido fmtDateTime obsoleto (substituido por fmtTimeOnly) Co-Authored-By: Claude Opus 4.7 (1M context) --- .../conversations/ConversationDrawer.vue | 333 ++- src/layout/melissa/MelissaCompromissos.vue | 1598 +++++++++--- src/layout/melissa/MelissaConversas.vue | 481 +++- src/layout/melissa/MelissaGrupos.vue | 2068 ++++++++++++++-- src/layout/melissa/MelissaMedicos.vue | 2202 +++++++++++++++-- src/layout/melissa/MelissaRecorrencias.vue | 546 +++- src/layout/melissa/MelissaTags.vue | 2048 +++++++++++++-- 7 files changed, 7844 insertions(+), 1432 deletions(-) diff --git a/src/components/conversations/ConversationDrawer.vue b/src/components/conversations/ConversationDrawer.vue index d8a0389..472d653 100644 --- a/src/components/conversations/ConversationDrawer.vue +++ b/src/components/conversations/ConversationDrawer.vue @@ -336,12 +336,19 @@ const KANBAN_COLUMNS = [ ]; // ── Formatters ───────────────────────────────────────────── -function fmtDateTime(iso) { +// HH:MM curto pra exibir dentro da bolha (estilo WhatsApp). +function fmtTimeOnly(iso) { if (!iso) return ''; - return new Date(iso).toLocaleString('pt-BR', { - day: '2-digit', month: '2-digit', year: 'numeric', - hour: '2-digit', minute: '2-digit' - }); + return new Date(iso).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }); +} + +// Iniciais pro avatar circular do header. +function iniciaisChat(name) { + if (!name) return '?'; + const parts = String(name).trim().split(/\s+/).filter(Boolean); + if (!parts.length) return '?'; + if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase(); + return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase(); } function channelIcon(ch) { @@ -699,11 +706,16 @@ function insertEmoji(emoji) { @@ -1030,8 +1042,8 @@ function insertEmoji(emoji) { - -
+ +
Carregando mensagens...
@@ -1042,12 +1054,12 @@ function insertEmoji(emoji) {
-
{{ m.body }}
-
-
- {{ fmtDateTime(m.created_at) }} - - - - - - - · número não vinculado +
{{ m.body }}
+ +
+ {{ fmtTimeOnly(m.created_at) }} + + + + + + +
+ não vinculado
@@ -1142,34 +1155,48 @@ function insertEmoji(emoji) {
- -
-
+ +
+
+ +