// UI Enhancements and Utilities
// Loading Overlay
class LoadingOverlay {
constructor() {
this.overlay = null;
}
show(message = 'جاري التحميل...') {
if (this.overlay) return;
this.overlay = document.createElement('div');
this.overlay.className = 'loading-overlay';
this.overlay.innerHTML = `
`;
document.body.appendChild(this.overlay);
document.body.style.overflow = 'hidden';
// Add styles if not exists
if (!document.getElementById('loading-overlay-styles')) {
const style = document.createElement('style');
style.id = 'loading-overlay-styles';
style.textContent = `
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(4px);
display: flex;
align-items: center;
justify-content: center;
z-index: 99999;
animation: fadeIn 0.3s ease;
}
.loading-content {
text-align: center;
color: white;
}
.loading-message {
margin-top: 16px;
font-size: 16px;
font-weight: 500;
}
`;
document.head.appendChild(style);
}
}
hide() {
if (this.overlay) {
this.overlay.style.animation = 'fadeOut 0.3s ease';
setTimeout(() => {
this.overlay?.remove();
this.overlay = null;
document.body.style.overflow = '';
}, 300);
}
}
updateMessage(message) {
if (this.overlay) {
const messageEl = this.overlay.querySelector('.loading-message');
if (messageEl) {
messageEl.textContent = message;
}
}
}
}
// Initialize global loading overlay
window.loading = new LoadingOverlay();
// Confirm Dialog
window.confirmDialog = function(message, onConfirm, onCancel) {
const backdrop = document.createElement('div');
backdrop.className = 'modal-backdrop';
const modal = document.createElement('div');
modal.className = 'modal';
modal.innerHTML = `
`;
document.body.appendChild(backdrop);
document.body.appendChild(modal);
const close = () => {
backdrop.remove();
modal.remove();
};
modal.querySelector('.btn-cancel').addEventListener('click', () => {
close();
if (onCancel) onCancel();
});
modal.querySelector('.btn-confirm').addEventListener('click', () => {
close();
if (onConfirm) onConfirm();
});
backdrop.addEventListener('click', () => {
close();
if (onCancel) onCancel();
});
};
// Add ripple effect to buttons
document.addEventListener('DOMContentLoaded', () => {
// Add ripple to all buttons
document.querySelectorAll('button, .btn, a[class*="btn"]').forEach(button => {
if (!button.classList.contains('no-ripple')) {
button.classList.add('btn-ripple');
}
});
// Add hover glow to cards
document.querySelectorAll('.card').forEach(card => {
if (!card.classList.contains('no-glow')) {
card.classList.add('glow-on-hover');
}
});
// Animate elements on scroll
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-fade-in');
observer.unobserve(entry.target);
}
});
}, observerOptions);
document.querySelectorAll('.card, .section-card').forEach(el => {
observer.observe(el);
});
});
// Smooth scroll to element
window.scrollToElement = function(element, offset = 0) {
const targetPosition = element.getBoundingClientRect().top + window.pageYOffset - offset;
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
};
// Copy to clipboard with feedback
window.copyToClipboard = function(text, successMessage = 'تم النسخ!') {
navigator.clipboard.writeText(text).then(() => {
showSuccess(successMessage);
}).catch(() => {
showError('فشل النسخ');
});
};
// Format number with animation
window.animateNumber = function(element, target, duration = 1000) {
const start = 0;
const increment = target / (duration / 16);
let current = start;
const timer = setInterval(() => {
current += increment;
if (current >= target) {
element.textContent = Math.round(target);
clearInterval(timer);
} else {
element.textContent = Math.round(current);
}
}, 16);
};
// Debounce function
window.debounce = function(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
// Throttle function
window.throttle = function(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
};
// Add loading state to buttons
window.setButtonLoading = function(button, loading = true) {
if (loading) {
button.disabled = true;
button.dataset.originalText = button.innerHTML;
button.innerHTML = `
`;
} else {
button.disabled = false;
button.innerHTML = button.dataset.originalText || button.innerHTML;
}
};
// Form validation helper
window.validateForm = function(formElement) {
const inputs = formElement.querySelectorAll('input[required], textarea[required], select[required]');
let isValid = true;
inputs.forEach(input => {
if (!input.value.trim()) {
isValid = false;
input.classList.add('error');
input.addEventListener('input', function() {
this.classList.remove('error');
}, { once: true });
}
});
if (!isValid) {
showError('الرجاء ملء جميع الحقول المطلوبة');
}
return isValid;
};
// Auto-save indicator
window.showAutoSaveIndicator = function(status = 'saving') {
let indicator = document.getElementById('autosave-indicator');
if (!indicator) {
indicator = document.createElement('div');
indicator.id = 'autosave-indicator';
indicator.style.cssText = `
position: fixed;
bottom: 20px;
left: 20px;
padding: 8px 16px;
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
font-size: 13px;
z-index: 9999;
display: flex;
align-items: center;
gap: 8px;
animation: slideInBottom 0.3s ease;
`;
document.body.appendChild(indicator);
}
const messages = {
saving: ' جاري الحفظ...',
saved: ' تم الحفظ',
error: ' فشل الحفظ'
};
indicator.innerHTML = messages[status] || messages.saving;
if (status === 'saved' || status === 'error') {
setTimeout(() => {
indicator.style.animation = 'slideOutBottom 0.3s ease';
setTimeout(() => indicator.remove(), 300);
}, 2000);
}
};
// Initialize tooltips
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-tooltip]').forEach(el => {
el.classList.add('tooltip');
});
});
console.log('✨ UI Enhancements loaded successfully!');