Update conversations.php
This commit is contained in:
+72
-26
@@ -360,6 +360,57 @@
|
|||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notification toasts (compact by default) */
|
||||||
|
#notification-toasts {
|
||||||
|
position: fixed;
|
||||||
|
top: 12px;
|
||||||
|
right: 12px;
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: flex-end;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-toast {
|
||||||
|
pointer-events: auto;
|
||||||
|
background: #fff;
|
||||||
|
color: #222;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
min-width: 160px;
|
||||||
|
max-width: 260px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-toast.small {
|
||||||
|
padding: 6px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
min-width: 140px;
|
||||||
|
max-width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-toast.cool {
|
||||||
|
background: linear-gradient(90deg,#6a11cb,#2575fc);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 6px 16px rgba(37,117,252,0.28);
|
||||||
|
transform-origin: right;
|
||||||
|
animation: pop 320ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pop { from { transform: translateY(-6px) scale(0.98); opacity:0 } to { transform: translateY(0) scale(1); opacity:1 } }
|
||||||
|
|
||||||
|
.notification-toast .nt-icon { font-size: 16px; margin-right: 6px; opacity: 0.95; }
|
||||||
|
.notification-toast .nt-actions { margin-left: auto; display:flex; gap:6px; }
|
||||||
|
.notification-toast .btn { font-size: 12px; padding: 4px 8px; }
|
||||||
|
|
||||||
|
.notification-toast.urgent { border-left: 4px solid #e74c3c; }
|
||||||
|
|
||||||
.message-template {
|
.message-template {
|
||||||
background: #fffacd;
|
background: #fffacd;
|
||||||
border: 1px solid #f0e68c;
|
border: 1px solid #f0e68c;
|
||||||
@@ -596,65 +647,59 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async showNotificationToast(notification) {
|
async showNotificationToast(notification) {
|
||||||
// Create toast element
|
// Create or reuse container
|
||||||
const containerId = 'notification-toasts';
|
const containerId = 'notification-toasts';
|
||||||
let container = document.getElementById(containerId);
|
let container = document.getElementById(containerId);
|
||||||
if (!container) {
|
if (!container) {
|
||||||
container = document.createElement('div');
|
container = document.createElement('div');
|
||||||
container.id = containerId;
|
container.id = containerId;
|
||||||
container.style.position = 'fixed';
|
|
||||||
container.style.top = '12px';
|
|
||||||
container.style.right = '12px';
|
|
||||||
container.style.zIndex = 9999;
|
|
||||||
document.body.appendChild(container);
|
document.body.appendChild(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
const toast = document.createElement('div');
|
const toast = document.createElement('div');
|
||||||
toast.className = 'notification-toast';
|
// compact by default
|
||||||
toast.style.background = '#fff';
|
toast.className = 'notification-toast small';
|
||||||
toast.style.padding = '10px 14px';
|
if (notification.cool || notification.type === 'cool') toast.classList.add('cool');
|
||||||
toast.style.border = '1px solid #ddd';
|
if (notification.level === 'urgent' || notification.urgent) toast.classList.add('urgent');
|
||||||
toast.style.boxShadow = '0 2px 6px rgba(0,0,0,0.12)';
|
|
||||||
toast.style.marginTop = '8px';
|
const iconSpan = document.createElement('span');
|
||||||
toast.style.borderRadius = '6px';
|
iconSpan.className = 'nt-icon';
|
||||||
toast.style.minWidth = '220px';
|
iconSpan.textContent = notification.icon || (notification.cool ? '✨' : (notification.level === 'urgent' ? '⚠️' : '🔔'));
|
||||||
|
toast.appendChild(iconSpan);
|
||||||
|
|
||||||
const msg = document.createElement('div');
|
const msg = document.createElement('div');
|
||||||
|
msg.style.flex = '1';
|
||||||
|
msg.style.fontSize = '13px';
|
||||||
|
msg.style.lineHeight = '1.2';
|
||||||
msg.textContent = notification.message || 'Nuevo evento';
|
msg.textContent = notification.message || 'Nuevo evento';
|
||||||
toast.appendChild(msg);
|
toast.appendChild(msg);
|
||||||
|
|
||||||
const actions = document.createElement('div');
|
const actions = document.createElement('div');
|
||||||
actions.style.marginTop = '8px';
|
actions.className = 'nt-actions';
|
||||||
actions.style.display = 'flex';
|
|
||||||
actions.style.gap = '8px';
|
|
||||||
|
|
||||||
const openBtn = document.createElement('button');
|
const openBtn = document.createElement('button');
|
||||||
openBtn.className = 'btn btn-sm btn-primary';
|
openBtn.className = notification.cool ? 'btn btn-sm btn-light' : 'btn btn-sm btn-primary';
|
||||||
openBtn.textContent = 'Abrir';
|
openBtn.textContent = 'Abrir';
|
||||||
openBtn.onclick = async () => {
|
openBtn.onclick = async () => {
|
||||||
// Mark notification read, then open conversation
|
|
||||||
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
|
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
|
||||||
// Parse data to get user_id
|
|
||||||
let data = {};
|
let data = {};
|
||||||
try { data = notification.data ? JSON.parse(notification.data) : {}; } catch(e) {}
|
try { data = notification.data ? JSON.parse(notification.data) : {}; } catch(e) {}
|
||||||
const userId = data.user_id || notification.user_id;
|
const userId = data.user_id || notification.user_id;
|
||||||
if (userId) {
|
if (userId) {
|
||||||
// find conversation item and open it
|
|
||||||
const conv = this.conversations.find(c => c.user_id == userId);
|
const conv = this.conversations.find(c => c.user_id == userId);
|
||||||
if (conv) {
|
if (conv) {
|
||||||
this.openConversation(conv.user_id, conv.name, conv.phone_number);
|
this.openConversation(conv.user_id, conv.name, conv.phone_number);
|
||||||
} else {
|
} else {
|
||||||
// fallback: open by fetching user info
|
|
||||||
this.openConversation(userId, 'Usuario', '');
|
this.openConversation(userId, 'Usuario', '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remove toast
|
|
||||||
toast.remove();
|
toast.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
const dismiss = document.createElement('button');
|
const dismiss = document.createElement('button');
|
||||||
dismiss.className = 'btn btn-sm btn-secondary';
|
dismiss.className = 'btn btn-sm btn-outline-secondary';
|
||||||
dismiss.textContent = 'Descartar';
|
dismiss.textContent = '×';
|
||||||
|
dismiss.title = 'Descartar';
|
||||||
dismiss.onclick = async () => {
|
dismiss.onclick = async () => {
|
||||||
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
|
await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})});
|
||||||
toast.remove();
|
toast.remove();
|
||||||
@@ -666,8 +711,9 @@
|
|||||||
|
|
||||||
container.appendChild(toast);
|
container.appendChild(toast);
|
||||||
|
|
||||||
// Auto remove after 18s
|
// Auto remove (shorter for compact notifications)
|
||||||
setTimeout(() => { if (toast.parentNode) toast.remove(); }, 18000);
|
const timeout = notification.cool ? 15000 : 8000;
|
||||||
|
setTimeout(() => { if (toast.parentNode) toast.remove(); }, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
setupEventListeners() {
|
setupEventListeners() {
|
||||||
|
|||||||
Reference in New Issue
Block a user