159 lines
6.1 KiB
PHP
159 lines
6.1 KiB
PHP
<style>
|
|
/* ===== NOTIFIKASI STYLE FACEBOOK ===== */
|
|
|
|
.message-body {
|
|
max-height: 360px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* item notif */
|
|
.message-body .dropdown-item {
|
|
padding: 8px 12px;
|
|
font-size: 13px;
|
|
line-height: 1.35;
|
|
white-space: normal;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
/* jarak antar notif */
|
|
.message-body .dropdown-item + .dropdown-item {
|
|
margin-top: 2px;
|
|
}
|
|
|
|
/* judul teks */
|
|
.message-body .notif-text {
|
|
color: #212529;
|
|
}
|
|
|
|
/* waktu */
|
|
.message-body .notif-time {
|
|
font-size: 11px;
|
|
color: #6c757d;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
/* hover ala Facebook */
|
|
.message-body .dropdown-item:hover {
|
|
background-color: #f0f2f5;
|
|
}
|
|
</style>
|
|
|
|
<header class="app-header">
|
|
<nav class="navbar navbar-expand-lg navbar-light">
|
|
<ul class="navbar-nav">
|
|
<li class="nav-item d-block d-xl-none">
|
|
<a class="nav-link sidebartoggler " id="headerCollapse" href="javascript:void(0)">
|
|
<i class="ti ti-menu-2"></i>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<div class="navbar-collapse justify-content-end px-0" id="navbarNav">
|
|
<ul class="navbar-nav flex-row ms-auto align-items-center justify-content-end">
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link position-relative" href="javascript:void(0)" id="drop1" data-bs-toggle="dropdown" aria-expanded="false">
|
|
<span class="d-inline-flex align-items-center justify-content-center rounded-circle bg-light" style="width:46px;height:46px;">
|
|
<i class="ti ti-bell text-primary"></i>
|
|
</span>
|
|
<span id="notifCountBadge" class="position-absolute top-0 start-50 badge rounded-pill bg-danger d-none">
|
|
0
|
|
</span>
|
|
</a>
|
|
<div class="dropdown-menu dropdown-menu-end dropdown-menu-animate-up shadow" aria-labelledby="drop1" style="min-width: 320px;">
|
|
<div class="d-flex align-items-center justify-content-between px-3 border-bottom">
|
|
<span class="fw-semibold">Notifikasi</span>
|
|
<span class="small text-muted" id="notifCountText">0 baru</span>
|
|
</div>
|
|
<div class="message-body" id="notifList">
|
|
<div class="dropdown-item text-muted small">Memuat...</div>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link " href="javascript:void(0)" id="drop2" data-bs-toggle="dropdown"
|
|
aria-expanded="false">
|
|
<img src="./assets/images/profile/user-1.jpg" alt="" width="35" height="35" class="rounded-circle">
|
|
</a>
|
|
<div class="dropdown-menu dropdown-menu-end dropdown-menu-animate-up" aria-labelledby="drop2">
|
|
<div class="message-body">
|
|
<a href="javascript:void(0)" class="d-flex align-items-center gap-2 dropdown-item">
|
|
<i class="ti ti-user fs-6"></i>
|
|
<p class="mb-0 fs-3">{{ auth()->user()->namauser ?? 'admin' }}</p>
|
|
</a>
|
|
<form action="/logout" method="POST">
|
|
@csrf
|
|
<button type="submit" class="btn btn-outline-primary mx-3 mt-2 d-block">Logout</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const listEl = document.getElementById('notifList');
|
|
const countTextEl = document.getElementById('notifCountText');
|
|
const badgeEl = document.getElementById('notifCountBadge');
|
|
|
|
function setList(items) {
|
|
if (!listEl) return;
|
|
if (!items.length) {
|
|
listEl.innerHTML = '<div class="dropdown-item text-muted small">Tidak ada notifikasi</div>';
|
|
return;
|
|
}
|
|
listEl.innerHTML = items.map(item => `
|
|
<a href="${item.url || '#'}" class="dropdown-item d-flex align-items-start gap-2">
|
|
<span class="badge ${item.is_read ? 'bg-secondary' : 'bg-primary'} rounded-circle" style="width:10px;height:10px;margin-top:6px;"></span>
|
|
<div>
|
|
<div class="fw-semibold">${item.text_notifikasi || '-'}</div>
|
|
<div class="small text-muted">${item.created_at || ''}</div>
|
|
</div>
|
|
</a>
|
|
`).join('');
|
|
}
|
|
|
|
fetch('/data/notifications')
|
|
.then(r => r.json())
|
|
.then(res => {
|
|
const unread = res?.status ? Number(res.unread || 0) : 0;
|
|
const items = res?.status ? (res.data || []) : [];
|
|
|
|
if (countTextEl) countTextEl.textContent = `${unread} baru`;
|
|
if (badgeEl) {
|
|
if (unread > 0) {
|
|
badgeEl.classList.remove('d-none');
|
|
badgeEl.textContent = unread;
|
|
} else {
|
|
badgeEl.classList.add('d-none');
|
|
}
|
|
}
|
|
|
|
setList(items);
|
|
})
|
|
.catch(() => {
|
|
if (listEl) listEl.innerHTML = '<div class="dropdown-item text-muted small">Gagal memuat notifikasi</div>';
|
|
});
|
|
|
|
const notifToggle = document.getElementById('drop1');
|
|
if (notifToggle) {
|
|
notifToggle.addEventListener('show.bs.dropdown', () => {
|
|
const unread = Number(badgeEl?.textContent || 0);
|
|
if (unread > 0) {
|
|
fetch('/data/notifications/read', {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content || '',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
}).then(() => {
|
|
if (countTextEl) countTextEl.textContent = '0 baru';
|
|
if (badgeEl) badgeEl.classList.add('d-none');
|
|
}).catch(() => {});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|