const APP_BASE_URL = document.querySelector('meta[name="app-url"]')?.content || ''; function initSweetAlerts() { const swalData = document.getElementById('swal-data'); const flashError = document.querySelector('.flash-data-error'); const flashSuccess = document.querySelector('.flash-data-success'); function showSuccess(msg) { Swal.fire({ icon: 'success', title: 'Berhasil!', text: msg, timer: 3000, showConfirmButton: true, confirmButtonText: 'OK', confirmButtonColor: '#10b981' }); } function showError(msg) { Swal.fire({ icon: 'error', title: 'Gagal!', text: msg, confirmButtonColor: '#1e293b', }); } if (swalData) { const successMessage = swalData.getAttribute('data-success'); const errorMessage = swalData.getAttribute('data-error'); const warningMessage = swalData.getAttribute('data-warning'); if (successMessage && successMessage !== '') { showSuccess(successMessage); swalData.setAttribute('data-success', ''); } if (errorMessage && errorMessage !== '') { showError(errorMessage); swalData.setAttribute('data-error', ''); } if (warningMessage && warningMessage !== '') { Swal.fire({ icon: 'warning', title: 'Peringatan', text: warningMessage, confirmButtonColor: '#f59e0b', confirmButtonText: 'OK' }); swalData.setAttribute('data-warning', ''); } const validationErrors = swalData.getAttribute('data-errors'); if (validationErrors) { try { const errors = JSON.parse(validationErrors); if (errors.length > 0) { Swal.fire({ icon: 'error', title: 'Gagal Validasi!', html: ``, confirmButtonColor: '#d33', }); } } catch (e) {} swalData.setAttribute('data-errors', ''); } } if (flashError) { const msg = flashError.getAttribute('data-message'); if (msg && msg !== '') { showError(msg); flashError.setAttribute('data-message', ''); } } if (flashSuccess) { const msg = flashSuccess.getAttribute('data-message'); if (msg && msg !== '') { showSuccess(msg); flashSuccess.setAttribute('data-message', ''); } } } document.addEventListener('turbo:load', initSweetAlerts); document.addEventListener('DOMContentLoaded', initSweetAlerts); // ==== Polling Badge Notifikasi ==== function updateNotifBadge() { const badge = document.getElementById('notif-badge'); if (!badge) return; // User tidak punya akses notifikasi, hentikan tanpa fetch fetch(APP_BASE_URL + '/notifikasi/unread-count', { headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' } }) .then(r => { if (!r.ok) return null; // Tangani 403/redirect dengan aman return r.json(); }) .then(data => { if (!data) return; const count = data.count ?? 0; if (count > 0) { badge.textContent = count > 99 ? '99+' : count; badge.classList.remove('hidden'); } else { badge.classList.add('hidden'); } }) .catch(() => {}); } updateNotifBadge(); setInterval(updateNotifBadge, 30000); // ==== Alpine.js Dropdown Notifikasi ==== function notifDropdown() { return { open: false, items: [], unreadCount: 0, loading: false, toggle() { this.open = !this.open; if (this.open) this.loadRecent(); }, loadRecent() { this.loading = true; fetch(APP_BASE_URL + '/notifikasi/recent', { headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' } }) .then(r => r.json()) .then(data => { this.items = data.data || []; this.unreadCount = this.items.filter(i => !i.is_read).length; this.loading = false; }) .catch(() => { this.loading = false; }); }, readItem(item) { if (!item.is_read) { fetch(APP_BASE_URL + '/notifikasi/' + item.id + '/read', { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' } }).then(() => { item.is_read = true; this.unreadCount = Math.max(0, this.unreadCount - 1); updateBadgeUI(this.unreadCount); }); } }, markAllRead() { fetch(APP_BASE_URL + '/notifikasi/read-all', { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' } }).then(() => { this.items.forEach(i => i.is_read = true); this.unreadCount = 0; updateBadgeUI(0); }); }, getIconClass(tipe) { var map = { 'lembur': 'bg-amber-100 text-amber-600', 'presensi': 'bg-green-100 text-green-600', 'pengumuman': 'bg-blue-100 text-blue-600', 'surat_izin': 'bg-purple-100 text-purple-600', 'izin': 'bg-purple-100 text-purple-600', 'poin': 'bg-rose-100 text-rose-600', }; return map[tipe] || 'bg-slate-100 text-slate-600'; }, getIcon(tipe) { var icons = { 'lembur': '', 'presensi': '', 'pengumuman': '', 'surat_izin': '', 'izin': '', 'poin': '', }; return icons[tipe] || ''; } }; } function updateBadgeUI(count) { var badge = document.getElementById('notif-badge'); if (!badge) return; if (count > 0) { badge.textContent = count > 99 ? '99+' : count; badge.classList.remove('hidden'); } else { badge.classList.add('hidden'); } } function confirmAction(event, formId, message, confirmBtnColor = '#3085d6', confirmBtnText = 'Ya, lanjutkan!') { event.preventDefault(); Swal.fire({ title: 'Konfirmasi Tindakan', text: message, icon: 'question', showCancelButton: true, confirmButtonColor: confirmBtnColor, cancelButtonColor: '#64748b', confirmButtonText: confirmBtnText, cancelButtonText: 'Batal', reverseButtons: true }).then((result) => { if (result.isConfirmed) { const form = document.getElementById(formId); if (form) { form.requestSubmit(); } else { console.error('Form tidak ditemukan:', formId); } } }); }