140 lines
5.1 KiB
JavaScript
140 lines
5.1 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
document.querySelectorAll('[data-auto-toast]').forEach((element) => {
|
|
const toast = new bootstrap.Toast(element, { delay: 3200 });
|
|
toast.show();
|
|
});
|
|
|
|
document.querySelectorAll('[data-copy-text]').forEach((button) => {
|
|
button.addEventListener('click', async () => {
|
|
const text = button.getAttribute('data-copy-text') || '';
|
|
try {
|
|
await navigator.clipboard.writeText(text);
|
|
const original = button.textContent;
|
|
button.textContent = document.documentElement.lang === 'ar' ? 'تم النسخ' : 'Copied';
|
|
setTimeout(() => {
|
|
button.textContent = original;
|
|
}, 1200);
|
|
} catch (error) {
|
|
console.error('Copy failed', error);
|
|
}
|
|
});
|
|
});
|
|
|
|
const searchInput = document.querySelector('[data-subject-search]');
|
|
if (searchInput) {
|
|
const items = Array.from(document.querySelectorAll('.subject-grid-item'));
|
|
const emptyState = document.querySelector('[data-empty-state]');
|
|
|
|
const applyFilter = () => {
|
|
const query = searchInput.value.trim().toLowerCase();
|
|
let visible = 0;
|
|
items.forEach((item) => {
|
|
const text = item.getAttribute('data-filter-text') || '';
|
|
const match = text.includes(query);
|
|
item.classList.toggle('d-none', !match);
|
|
if (match) visible += 1;
|
|
});
|
|
if (emptyState) {
|
|
emptyState.classList.toggle('d-none', visible !== 0);
|
|
}
|
|
};
|
|
|
|
searchInput.addEventListener('input', applyFilter);
|
|
}
|
|
|
|
// Convert SweetAlert2 popups
|
|
if (typeof Swal !== 'undefined') {
|
|
|
|
// 1. Convert Flash Alerts (success, danger, warning)
|
|
const validAlerts = [];
|
|
document.querySelectorAll('.alert').forEach(alertEl => {
|
|
// Must be one of the flash message types
|
|
if (!alertEl.classList.contains('alert-success') &&
|
|
!alertEl.classList.contains('alert-danger') &&
|
|
!alertEl.classList.contains('alert-warning')) {
|
|
return;
|
|
}
|
|
|
|
// Skip if it contains interactive elements
|
|
if (alertEl.querySelector('form, ul, .btn, .alert-heading, a')) return;
|
|
|
|
const text = alertEl.innerText.trim();
|
|
if (!text) return;
|
|
|
|
let type = 'info';
|
|
let titleStr = document.documentElement.lang === 'ar' ? 'ملاحظة' : 'Note';
|
|
|
|
if (alertEl.classList.contains('alert-success')) {
|
|
type = 'success';
|
|
titleStr = document.documentElement.lang === 'ar' ? 'نجاح' : 'Success';
|
|
} else if (alertEl.classList.contains('alert-danger')) {
|
|
type = 'error';
|
|
titleStr = document.documentElement.lang === 'ar' ? 'خطأ' : 'Error';
|
|
} else if (alertEl.classList.contains('alert-warning')) {
|
|
type = 'warning';
|
|
titleStr = document.documentElement.lang === 'ar' ? 'تنبيه' : 'Warning';
|
|
}
|
|
|
|
// Hide immediately to prevent flash
|
|
alertEl.style.display = 'none';
|
|
|
|
validAlerts.push({ type, titleStr, text });
|
|
});
|
|
|
|
// Process alerts sequentially so they don't overlap
|
|
(async function() {
|
|
for (const alertData of validAlerts) {
|
|
await Swal.fire({
|
|
icon: alertData.type,
|
|
title: alertData.titleStr,
|
|
text: alertData.text,
|
|
confirmButtonText: document.documentElement.lang === 'ar' ? 'حسنًا' : 'OK',
|
|
confirmButtonColor: '#0d6efd'
|
|
});
|
|
}
|
|
})();
|
|
|
|
// 2. Convert standard browser confirm() dialogs (Forms & Links)
|
|
const interceptConfirms = (selector, eventType, triggerAction) => {
|
|
document.querySelectorAll(selector).forEach(el => {
|
|
const jsAttr = el.getAttribute('on' + eventType);
|
|
if (jsAttr && jsAttr.includes('confirm(')) {
|
|
// Extract text from inside confirm('...')
|
|
const match = jsAttr.match(/confirm\(\s*['"](.*?)['"]\s*\)/);
|
|
const confirmText = match ? match[1] : (document.documentElement.lang === 'ar' ? 'هل أنت متأكد؟' : 'Are you sure?');
|
|
|
|
// Remove native confirm
|
|
el.removeAttribute('on' + eventType);
|
|
|
|
el.addEventListener(eventType, function(e) {
|
|
e.preventDefault();
|
|
Swal.fire({
|
|
title: document.documentElement.lang === 'ar' ? 'تأكيد' : 'Confirmation',
|
|
text: confirmText,
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#dc3545',
|
|
cancelButtonColor: '#6c757d',
|
|
confirmButtonText: document.documentElement.lang === 'ar' ? 'نعم، متأكد' : 'Yes, I am sure',
|
|
cancelButtonText: document.documentElement.lang === 'ar' ? 'إلغاء' : 'Cancel'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
triggerAction(el);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
// Forms
|
|
interceptConfirms('form[onsubmit*="confirm"]', 'submit', (form) => {
|
|
HTMLFormElement.prototype.submit.call(form);
|
|
});
|
|
|
|
// Links (a tags)
|
|
interceptConfirms('a[onclick*="confirm"]', 'click', (link) => {
|
|
window.location.href = link.getAttribute('href');
|
|
});
|
|
}
|
|
}); |