42 lines
1.2 KiB
JavaScript
42 lines
1.2 KiB
JavaScript
(function () {
|
|
const meta = document.querySelector('meta[name="csrf-token"]');
|
|
const csrfToken = meta ? meta.content : '';
|
|
|
|
document.addEventListener('click', async (e) => {
|
|
const btn = e.target.closest('[data-social-action]');
|
|
if (!btn) return;
|
|
|
|
// Guest: redirect to login
|
|
if (btn.hasAttribute('data-require-login')) {
|
|
window.location.href = '/login';
|
|
return;
|
|
}
|
|
|
|
// Prevent card <a> from navigating when button is inside one
|
|
e.stopPropagation();
|
|
|
|
const { socialAction, socialType, socialId } = btn.dataset;
|
|
const url = `/api/${socialType}s/${socialId}/${socialAction}`;
|
|
|
|
btn.disabled = true;
|
|
try {
|
|
const res = await fetch(url, {
|
|
method: 'POST',
|
|
headers: { 'X-CSRF-Token': csrfToken },
|
|
});
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
const data = await res.json();
|
|
|
|
const isOn = data.liked ?? data.favorited;
|
|
btn.classList.toggle('active', isOn);
|
|
btn.setAttribute('aria-pressed', String(isOn));
|
|
const countEl = btn.querySelector('.social-count');
|
|
if (countEl) countEl.textContent = data.count;
|
|
} catch (err) {
|
|
console.error('[social] toggle failed:', err);
|
|
} finally {
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
})();
|