diff --git a/conversations.php b/conversations.php index 4355631..154c82f 100644 --- a/conversations.php +++ b/conversations.php @@ -360,6 +360,57 @@ 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 { background: #fffacd; border: 1px solid #f0e68c; @@ -596,65 +647,59 @@ } async showNotificationToast(notification) { - // Create toast element + // Create or reuse container const containerId = 'notification-toasts'; let container = document.getElementById(containerId); if (!container) { container = document.createElement('div'); container.id = containerId; - container.style.position = 'fixed'; - container.style.top = '12px'; - container.style.right = '12px'; - container.style.zIndex = 9999; document.body.appendChild(container); } const toast = document.createElement('div'); - toast.className = 'notification-toast'; - toast.style.background = '#fff'; - toast.style.padding = '10px 14px'; - toast.style.border = '1px solid #ddd'; - toast.style.boxShadow = '0 2px 6px rgba(0,0,0,0.12)'; - toast.style.marginTop = '8px'; - toast.style.borderRadius = '6px'; - toast.style.minWidth = '220px'; + // compact by default + toast.className = 'notification-toast small'; + if (notification.cool || notification.type === 'cool') toast.classList.add('cool'); + if (notification.level === 'urgent' || notification.urgent) toast.classList.add('urgent'); + + const iconSpan = document.createElement('span'); + iconSpan.className = 'nt-icon'; + iconSpan.textContent = notification.icon || (notification.cool ? '✨' : (notification.level === 'urgent' ? '⚠️' : '🔔')); + toast.appendChild(iconSpan); const msg = document.createElement('div'); + msg.style.flex = '1'; + msg.style.fontSize = '13px'; + msg.style.lineHeight = '1.2'; msg.textContent = notification.message || 'Nuevo evento'; toast.appendChild(msg); const actions = document.createElement('div'); - actions.style.marginTop = '8px'; - actions.style.display = 'flex'; - actions.style.gap = '8px'; + actions.className = 'nt-actions'; 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.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})}); - // Parse data to get user_id let data = {}; try { data = notification.data ? JSON.parse(notification.data) : {}; } catch(e) {} const userId = data.user_id || notification.user_id; if (userId) { - // find conversation item and open it const conv = this.conversations.find(c => c.user_id == userId); if (conv) { this.openConversation(conv.user_id, conv.name, conv.phone_number); } else { - // fallback: open by fetching user info this.openConversation(userId, 'Usuario', ''); } } - // remove toast toast.remove(); }; const dismiss = document.createElement('button'); - dismiss.className = 'btn btn-sm btn-secondary'; - dismiss.textContent = 'Descartar'; + dismiss.className = 'btn btn-sm btn-outline-secondary'; + dismiss.textContent = '×'; + dismiss.title = 'Descartar'; dismiss.onclick = async () => { await fetch('api/mark_notification_read.php', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id: notification.id})}); toast.remove(); @@ -666,8 +711,9 @@ container.appendChild(toast); - // Auto remove after 18s - setTimeout(() => { if (toast.parentNode) toast.remove(); }, 18000); + // Auto remove (shorter for compact notifications) + const timeout = notification.cool ? 15000 : 8000; + setTimeout(() => { if (toast.parentNode) toast.remove(); }, timeout); } setupEventListeners() {