/* AAU CRM — Unified Inbox (3 columns, interactive) */ const INBOX_LABELS = [ { id: 'hot', label: 'Hot', color: '#ef4444' }, { id: 'proposal', label: 'Chờ proposal', color: '#f59e0b' }, { id: 'callback', label: 'Hẹn gọi lại', color: '#3b82f6' }, { id: 'franchise', label: 'Nhượng quyền', color: '#8b5cf6' }, { id: 'care', label: 'Cần CSKH', color: '#0a9e6e' }, { id: 'spam', label: 'Rác / Spam', color: '#9ca3af' }, ]; const labelById = (id) => INBOX_LABELS.find(l => l.id === id); const SENTIMENT = { cv1: 'pos', cv2: 'neu', cv3: 'neg', cv4: 'pos', cv5: 'neu', cv6: 'neg', cv7: 'neu', cv8: 'pos' }; const SENT_META = { pos: { l: 'Thiện chí', c: '#0a9e6e' }, neu: { l: 'Trung lập', c: '#8a8a8a' }, neg: { l: 'Do dự', c: '#c4320a' } }; const DUPES = { L1: 'Khoa BBQ — hồ sơ cũ (T9/2025)' }; const ME_ID = 'u5'; // người đang trực inbox (demo) // media tự host trên backend (/media/..). Same-origin LIVE → URL tương đối chạy // thẳng; dev static (:5500) → ghép API.base. http/data URL giữ nguyên. function mediaSrc(u) { if (!u) return u; if (/^(https?:|data:|blob:)/.test(u)) return u; const b = (window.API && window.API.base) || ''; return b + u; } function fmtBytes(n) { n = Number(n) || 0; if (!n) return ''; if (n < 1024) return n + ' B'; if (n < 1048576) return (n / 1024).toFixed(0) + ' KB'; return (n / 1048576).toFixed(1) + ' MB'; } // nhãn ngắn cho danh sách hội thoại khi tin cuối là media function attShortLabel(a) { return ({ image: '🖼 Hình ảnh', video: '🎬 Video', audio: '🎤 Tin thoại', sticker: '😀 Sticker' })[a.type] || ('📎 ' + (a.name || 'Tệp')); } // Attachment — 1 bong bóng media (ảnh/video/voice/tệp) cho cả tin nhận & gửi. function Attachment({ a, dir }) { const src = mediaSrc(a.url); const out = dir === 'out'; if (a.type === 'image') return ( {a.name ); if (a.type === 'video') return