bmc_hub/static/js/message-ui.js

24 lines
3.4 KiB
JavaScript
Raw Permalink Normal View History

/* Presentational helpers shared by the internal inbox. No network or mutations. */
window.BmcMessageUI = (() => {
const escape = value => String(value ?? '').replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const initials = name => String(name || '?').trim().split(/\s+/).slice(0,2).map(p=>p[0]).join('').toUpperCase();
const time = value => { const d=new Date(value); return value && !Number.isNaN(d.getTime()) ? d.toLocaleTimeString('da-DK',{hour:'2-digit',minute:'2-digit'}) : ''; };
function message(m) {
const own=!!m.is_own, phone=m.message_kind==='phone';
const number=String(m.callback_phone || '').replace(/[^+0-9*#,;]/g,'');
const person=m.caller_name || m.contact_name || 'Telefonbesked';
const contact=Number(m.contact_id)>0?`<a class="msg-contact" href="/contacts/${Number(m.contact_id)}"><i class="bi bi-person"></i> ${escape(m.contact_name || 'Åbn kontakt')}</a>`:'';
const replyId=own?Number(m.recipient_user_id):Number(m.sender_user_id);
const stamp=time(m.created_at);
const status=own?(m.is_acknowledged?'Bekræftet læst':m.is_read?'Læst':'Sendt'):'';
const phoneCard=phone?`<div class="msg-call"><span class="msg-call-icon"><i class="bi bi-telephone"></i></span><div><small>TELEFONBESKED</small><strong>${escape(person)}</strong>${m.callback_phone?`<span>${escape(m.callback_phone)}</span>`:''}</div>${number?`<a class="msg-call-action" href="tel:${escape(number)}" aria-label="Ring tilbage til ${escape(person)}"><i class="bi bi-telephone-outbound"></i> Ring tilbage</a>`:''}</div>`:'';
return `<article class="msg-message ${own?'is-own':''} ${phone?'is-phone':''}"><div class="msg-byline"><span>${own?'Dig':escape(m.from || 'Kollega')}</span>${stamp?`<time datetime="${escape(m.created_at)}" title="${escape(new Date(m.created_at).toLocaleString('da-DK'))}">${stamp}</time>`:''}${m.is_unread?'<span class="msg-new-dot" title="Ulæst" aria-label="Ulæst"></span>':''}</div><div class="msg-bubble">${phoneCard}<div class="msg-text">${escape(m.text)}</div>${contact}</div><div class="msg-message-actions">${status?`<span class="msg-delivery"><i class="bi bi-check2${m.is_read || m.is_acknowledged?'-all':''}"></i> ${status}</span>`:''}${m.requires_manual_ack && !m.is_acknowledged?'<span class="msg-ack-hint">Læsebekræftelse ønskes</span>':''}${!own && m.requires_manual_ack && !m.is_acknowledged?`<button type="button" class="msg-ack" data-bb-ack-message="${Number(m.id)}"><i class="bi bi-check2-circle"></i> Bekræft læst</button>`:''}${replyId>0?`<button type="button" class="msg-reply" data-bb-reply-message="${Number(m.id)}"><i class="bi bi-reply"></i> Svar</button>`:''}</div></article>`;
}
function thread(t, active) {
const last=t.items?.[t.items.length-1];
const preview=last?`${last.message_kind==='phone'?'Telefonbesked · ':''}${last.text || ''}`:'Start en samtale';
return `<span class="msg-avatar ${t.partnerUserId?'':'is-group'}">${t.partnerUserId?escape(initials(t.label)):'<i class="bi bi-people"></i>'}</span><span class="msg-thread-copy"><span class="msg-thread-top"><strong>${escape(t.label)}</strong><time>${time(t.lastCreatedAt)}</time></span><span class="msg-thread-preview">${escape(preview)}</span></span>${t.unread?`<span class="bb-message-thread-count">${Number(t.unread)}</span>`:''}`;
}
return {message,thread,escape,initials};
})();