213 lines
8.6 KiB
JavaScript
213 lines
8.6 KiB
JavaScript
/* ============================================================
|
|
js/pesan.js — Media komunikasi pengurus v2.2
|
|
============================================================ */
|
|
|
|
window.labelJenisPesan = {
|
|
permintaan_bantuan: 'Permintaan Bantuan',
|
|
koordinasi: 'Koordinasi',
|
|
pengumuman: 'Pengumuman'
|
|
};
|
|
|
|
var _jenisEmoji = {
|
|
permintaan_bantuan: '🆘',
|
|
koordinasi: '📋',
|
|
pengumuman: '📢'
|
|
};
|
|
|
|
/* ─────────────────────────────────────────────────────
|
|
Floating detail box
|
|
───────────────────────────────────────────────────── */
|
|
window.openPesanDetail = async function (p) {
|
|
var fl = document.getElementById('pesan-detail-float');
|
|
if (!fl) return;
|
|
|
|
var jenis = p.jenis || 'koordinasi';
|
|
var emoji = _jenisEmoji[jenis] || '💬';
|
|
var jenisLabel = window.labelJenisPesan[jenis] || jenis;
|
|
var isBroadcast = !p.penerima_id;
|
|
var roleLabel = p.role_pengirim === 'pimpinan_daerah' ? '<i class="fa-solid fa-crown"></i> Pimpinan Daerah' : '<i class="fa-solid fa-mosque"></i> Pengurus Masjid';
|
|
|
|
/* Accent bar */
|
|
document.getElementById('pdf-accent-bar').className = 'pdf-accent-bar ' + jenis;
|
|
|
|
/* Icon */
|
|
var icon = document.getElementById('pdf-icon');
|
|
icon.textContent = emoji;
|
|
icon.className = 'pdf-icon ' + jenis;
|
|
|
|
/* Title (judul pesan) + subtitle (jenis) */
|
|
document.getElementById('pdf-title').textContent = p.judul || 'Pesan';
|
|
document.getElementById('pdf-subtitle').textContent = jenisLabel;
|
|
|
|
/* Isi */
|
|
document.getElementById('pdf-isi').textContent = p.isi || '(tidak ada isi)';
|
|
|
|
/* Info rows */
|
|
document.getElementById('pdf-pengirim').textContent = p.nama_pengirim || '-';
|
|
document.getElementById('pdf-role').innerHTML = roleLabel;
|
|
document.getElementById('pdf-jenis-label').textContent = emoji + ' ' + jenisLabel;
|
|
document.getElementById('pdf-waktu').textContent = p.created_fmt || '-';
|
|
|
|
/* Broadcast badge */
|
|
document.getElementById('pdf-row-broadcast').style.display = isBroadcast ? '' : 'none';
|
|
|
|
/* Baru badge */
|
|
document.getElementById('pdf-row-baru').style.display = (p.status === 'baru') ? '' : 'none';
|
|
|
|
/* Close */
|
|
document.getElementById('pdf-close').onclick = window.closePesanDetail;
|
|
|
|
/* Show */
|
|
fl.style.display = 'flex';
|
|
|
|
/* Mark as read if it is new and we are not the sender */
|
|
if (p.status === 'baru' && p.pengirim_id != window.appAuth.id) {
|
|
try {
|
|
var formData = new FormData();
|
|
formData.append('id', p.id);
|
|
formData.append('status', 'dibaca');
|
|
await fetch('php/update_pesan_status.php', { method: 'POST', body: formData });
|
|
|
|
p.status = 'dibaca';
|
|
|
|
// Remove 'baru' indicator from card visually
|
|
var cardEl = document.querySelector('.p-card[data-id="' + p.id + '"]');
|
|
if (cardEl) {
|
|
cardEl.classList.remove('baru');
|
|
var dot = cardEl.querySelector('.p-new');
|
|
if (dot) dot.remove();
|
|
}
|
|
|
|
// Immediately update the notification badge
|
|
if (window.pollPesanNotification) window.pollPesanNotification();
|
|
} catch (e) {
|
|
console.error('Failed to update message status', e);
|
|
}
|
|
}
|
|
};
|
|
|
|
window.closePesanDetail = function () {
|
|
var fl = document.getElementById('pesan-detail-float');
|
|
if (fl) fl.style.display = 'none';
|
|
};
|
|
|
|
/* ── Panel open/close ── */
|
|
window.openPesanPanel = async function () {
|
|
var panel = document.getElementById('panel-pesan');
|
|
if (panel) {
|
|
var sidebar = document.getElementById('sidebar');
|
|
if (sidebar) sidebar.style.display = 'none';
|
|
var lap = document.getElementById('panel-laporan');
|
|
if (lap) lap.style.display = 'none';
|
|
panel.style.display = 'flex';
|
|
await window.loadPesan();
|
|
}
|
|
};
|
|
window.closePesanPanel = function () {
|
|
var p = document.getElementById('panel-pesan');
|
|
if (p) p.style.display = 'none';
|
|
window.closePesanDetail();
|
|
|
|
// Auto-open sidebar
|
|
var sidebar = document.getElementById('sidebar');
|
|
if (sidebar) sidebar.style.display = 'flex';
|
|
};
|
|
|
|
/* ── Load & render pesan ── */
|
|
window.loadPesan = async function () {
|
|
var container = document.getElementById('pesan-list-container');
|
|
if (!container) return;
|
|
container.innerHTML = '<div class="loading">Memuat pesan...</div>';
|
|
var data = await window.fetchJson('php/read_pesan.php', []);
|
|
container.innerHTML = '';
|
|
|
|
if (!data.length) {
|
|
container.innerHTML = '<div class="empty">Belum ada pesan. Mulai komunikasi di bawah.</div>';
|
|
return;
|
|
}
|
|
|
|
data.forEach(function (p) {
|
|
var jenisClass = { permintaan_bantuan:'bantuan', koordinasi:'', pengumuman:'pengumuman' }[p.jenis] || '';
|
|
var chipColors = { permintaan_bantuan:'chip-red', koordinasi:'chip-blue', pengumuman:'chip-amber' };
|
|
var isBroadcast = !p.penerima_id;
|
|
var emoji = _jenisEmoji[p.jenis] || '💬';
|
|
|
|
var card = document.createElement('div');
|
|
card.className = 'p-card' + (jenisClass ? ' ' + jenisClass : '') + (p.status === 'baru' ? ' baru' : '');
|
|
card.title = 'Klik untuk detail lengkap';
|
|
card.dataset.id = p.id;
|
|
|
|
card.innerHTML =
|
|
'<div class="p-head">' +
|
|
'<span class="chip ' + (chipColors[p.jenis]||'chip-gray') + '">' + emoji + ' ' + (window.labelJenisPesan[p.jenis]||p.jenis) + '</span>' +
|
|
(isBroadcast ? '<span class="chip chip-purple">📡 Broadcast</span>' : '') +
|
|
(p.status === 'baru' ? '<span class="p-new">●</span>' : '') +
|
|
'</div>' +
|
|
'<div class="p-judul">' + window.escapeHtml(p.judul) + '</div>' +
|
|
'<div class="p-isi">' + window.escapeHtml(p.isi) + '</div>' +
|
|
'<div class="p-meta">👤 ' + window.escapeHtml(p.nama_pengirim) +
|
|
' (' + (p.role_pengirim === 'pimpinan_daerah' ? 'Pimpinan' : 'Pengurus') + ')' +
|
|
' · 🕐 ' + p.created_fmt + '</div>';
|
|
|
|
/* Klik kartu → buka floating detail */
|
|
card.addEventListener('click', function () {
|
|
window.openPesanDetail(p);
|
|
});
|
|
|
|
container.appendChild(card);
|
|
});
|
|
};
|
|
|
|
/* ── Submit kirim pesan ── */
|
|
window.submitPesan = async function (e) {
|
|
e.preventDefault();
|
|
if (!window.appAuth.loggedIn) { window.showToast('Login diperlukan.', 'error'); return; }
|
|
|
|
var btn = document.getElementById('btn-submit-pesan');
|
|
var judul = document.getElementById('pesan-judul').value.trim();
|
|
var isi = document.getElementById('pesan-isi').value.trim();
|
|
var jenis = document.getElementById('pesan-jenis').value;
|
|
|
|
if (!judul || !isi) { window.showToast('Judul dan isi wajib diisi.', 'error'); return; }
|
|
btn.disabled = true; btn.textContent = 'Mengirim...';
|
|
|
|
try {
|
|
await window.postForm('php/send_pesan.php', { judul, isi, jenis });
|
|
document.getElementById('pesan-judul').value = '';
|
|
document.getElementById('pesan-isi').value = '';
|
|
window.showToast('Pesan terkirim.', 'success');
|
|
await window.loadPesan();
|
|
} catch (err) { window.showToast('Gagal: ' + err.message, 'error'); }
|
|
finally { btn.disabled = false; btn.textContent = 'Kirim Pesan'; }
|
|
};
|
|
|
|
/* Polling for Pesan Notification */
|
|
window.pollPesanNotification = async function() {
|
|
if (!window.appAuth) return;
|
|
try {
|
|
var res = await fetch('php/read_pesan.php');
|
|
var text = await res.text();
|
|
var data = JSON.parse(text);
|
|
if(Array.isArray(data)) {
|
|
// Count messages from OTHER users that are considered "baru"
|
|
// Since we don't have a read-status per user in this simple app, we can just count messages from others in the last 24 hours, or just count 'baru'
|
|
var pendingCount = data.filter(function(m) {
|
|
return m.status === 'baru' && m.pengirim_id != window.appAuth.id;
|
|
}).length;
|
|
|
|
var badge = document.getElementById('nav-badge-pesan');
|
|
if(badge) {
|
|
if(pendingCount > 0) {
|
|
badge.style.display = 'inline-flex';
|
|
badge.textContent = pendingCount;
|
|
} else {
|
|
badge.style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
} catch(e) {}
|
|
};
|
|
|
|
// Start polling every 15 seconds
|
|
setInterval(window.pollPesanNotification, 15000);
|