diff --git a/modules/turnero/views/chat.php b/modules/turnero/views/chat.php
index be38f4f..8c16ae4 100644
--- a/modules/turnero/views/chat.php
+++ b/modules/turnero/views/chat.php
@@ -152,6 +152,11 @@ html, body { height: 100%; overflow: hidden; font-family: -apple-system, BlinkMa
.msg-time {
font-size: .68rem; color: #aaa; text-align: right; margin-top: 3px;
}
+.date-sep {
+ align-self: center; background: #e9ecef; color: #6c757d;
+ font-size: .73rem; font-weight: 600; padding: 3px 12px;
+ border-radius: 99px; margin: 10px 0; user-select: none;
+}
.msg-type-badge {
font-size: .7rem; color: #888; font-style: italic;
}
@@ -743,6 +748,8 @@ async function pollMessages() {
}
// ── Render mensajes ───────────────────────────────────────────────────────────
+let _lastRenderedDay = null;
+
function renderMessages(msgs, prepend) {
const area = document.getElementById('messagesArea');
area.innerHTML = '';
@@ -755,7 +762,16 @@ function renderMessages(msgs, prepend) {
loadBtn.innerHTML = ' Ver mensajes anteriores';
area.appendChild(loadBtn);
- msgs.forEach(m => area.appendChild(buildBubble(m)));
+ let lastDay = null;
+ msgs.forEach(m => {
+ const day = m.created_at ? msgDay(m.created_at) : null;
+ if (day && day !== lastDay) {
+ area.appendChild(buildDateSep(dateLabel(m.created_at)));
+ lastDay = day;
+ }
+ area.appendChild(buildBubble(m));
+ });
+ _lastRenderedDay = lastDay;
area.scrollTop = area.scrollHeight;
}
@@ -763,15 +779,39 @@ function prependMessages(msgs) {
const area = document.getElementById('messagesArea');
const oldTop = area.scrollHeight - area.scrollTop;
const loadBtn = document.getElementById('loadMoreBtn');
- msgs.forEach(m => area.insertBefore(buildBubble(m), loadBtn.nextSibling));
+ // Día del primer mensaje que ya estaba en pantalla (para no duplicar separador)
+ const firstBubble = loadBtn.nextSibling;
+ const firstExistingDay = firstBubble?.dataset?.msgId
+ ? msgDay(msgs[msgs.length - 1]?.created_at || '') // comparar con el último del lote nuevo
+ : null;
+ let lastDay = null;
+ let insertRef = loadBtn.nextSibling;
+ msgs.forEach(m => {
+ const day = m.created_at ? msgDay(m.created_at) : null;
+ if (day && day !== lastDay) {
+ area.insertBefore(buildDateSep(dateLabel(m.created_at)), insertRef);
+ lastDay = day;
+ }
+ area.insertBefore(buildBubble(m), insertRef);
+ insertRef = area.querySelector(`[data-msg-id="${m.id}"]`)?.nextSibling || insertRef;
+ });
+ // Eliminar separador duplicado si el último día del lote coincide con el primero ya visible
+ const seps = area.querySelectorAll('.date-sep');
+ for (let i = 0; i < seps.length - 1; i++) {
+ if (seps[i].textContent === seps[i+1].textContent) seps[i+1].remove();
+ }
if (!state.hasMore) loadBtn.style.display = 'none';
area.scrollTop = area.scrollHeight - oldTop;
}
function appendMessage(msg) {
- const area = document.getElementById('messagesArea');
- const bubble = buildBubble(msg);
- area.appendChild(bubble);
+ const area = document.getElementById('messagesArea');
+ const day = msg.created_at ? msgDay(msg.created_at) : null;
+ if (day && day !== _lastRenderedDay) {
+ area.appendChild(buildDateSep(dateLabel(msg.created_at)));
+ _lastRenderedDay = day;
+ }
+ area.appendChild(buildBubble(msg));
area.scrollTop = area.scrollHeight;
}
@@ -1415,6 +1455,22 @@ function escHtml(str) {
return String(str ?? '').replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"');
}
function nl2br(str) { return str.replace(/\n/g, '
'); }
+function dateLabel(ts) {
+ const d = new Date(ts.replace(' ', 'T'));
+ const now = new Date();
+ const yesterday = new Date(now); yesterday.setDate(now.getDate() - 1);
+ if (d.toDateString() === now.toDateString()) return 'Hoy';
+ if (d.toDateString() === yesterday.toDateString()) return 'Ayer';
+ return d.toLocaleDateString('es-CO', { weekday:'short', day:'2-digit', month:'short' });
+}
+function buildDateSep(label) {
+ const el = document.createElement('div');
+ el.className = 'date-sep';
+ el.textContent = label;
+ return el;
+}
+function msgDay(ts) { return new Date(ts.replace(' ', 'T')).toDateString(); }
+
function formatTime(ts) {
const d = new Date(ts.replace(' ', 'T'));
const now = new Date();
@@ -1425,9 +1481,7 @@ function formatTime(ts) {
}
function formatTimeFull(ts) {
const d = new Date(ts.replace(' ', 'T'));
- const t = d.toLocaleTimeString('es-CO', { hour: '2-digit', minute: '2-digit' });
- if (d.toDateString() === new Date().toDateString()) return t;
- return d.toLocaleDateString('es-CO', { day: '2-digit', month: '2-digit' }) + ' ' + t;
+ return d.toLocaleTimeString('es-CO', { hour: '2-digit', minute: '2-digit' });
}