/**
* Product Page Enhancements - Interactive Features
* Modern UX improvements for better conversion
*/
(function() {
'use strict';
// ==========================================
// 1. Image Gallery with Zoom
// ==========================================
function initImageGallery() {
const mainImage = document.querySelector('.main-product-image');
const thumbnails = document.querySelectorAll('.thumbnail-item');
if (!mainImage || !thumbnails.length) return;
// Set first thumbnail as active
if (thumbnails[0]) {
thumbnails[0].classList.add('active');
}
// Thumbnail click handler
thumbnails.forEach((thumb, index) => {
thumb.addEventListener('click', function() {
const newSrc = this.dataset.image;
if (newSrc) {
mainImage.src = newSrc;
// Update active state
thumbnails.forEach(t => t.classList.remove('active'));
this.classList.add('active');
}
});
});
// Lightbox on main image click
const mainImageContainer = document.querySelector('.main-image-container');
if (mainImageContainer) {
mainImageContainer.addEventListener('click', function() {
openLightbox(mainImage.src);
});
}
}
// ==========================================
// 2. Lightbox for Image Zoom
// ==========================================
function openLightbox(imageSrc) {
let lightbox = document.querySelector('.lightbox');
if (!lightbox) {
lightbox = createLightbox();
}
const lightboxImage = lightbox.querySelector('.lightbox-image');
lightboxImage.src = imageSrc;
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
}
function createLightbox() {
const lightbox = document.createElement('div');
lightbox.className = 'lightbox';
lightbox.innerHTML = `
×
`;
document.body.appendChild(lightbox);
// Close handlers
lightbox.addEventListener('click', function(e) {
if (e.target === lightbox || e.target.classList.contains('lightbox-close')) {
closeLightbox();
}
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
closeLightbox();
}
});
return lightbox;
}
function closeLightbox() {
const lightbox = document.querySelector('.lightbox');
if (lightbox) {
lightbox.classList.remove('active');
document.body.style.overflow = '';
}
}
// ==========================================
// 3. Quantity Selector
// ==========================================
function initQuantitySelector() {
const qtyInput = document.querySelector('.qty-input');
const qtyMinus = document.querySelector('.qty-minus');
const qtyPlus = document.querySelector('.qty-plus');
if (!qtyInput || !qtyMinus || !qtyPlus) return;
const maxQty = parseInt(qtyInput.dataset.max) || 99;
qtyMinus.addEventListener('click', function() {
let value = parseInt(qtyInput.value) || 1;
if (value > 1) {
qtyInput.value = value - 1;
updateQuantity();
}
});
qtyPlus.addEventListener('click', function() {
let value = parseInt(qtyInput.value) || 1;
if (value < maxQty) {
qtyInput.value = value + 1;
updateQuantity();
}
});
qtyInput.addEventListener('change', function() {
let value = parseInt(this.value) || 1;
if (value < 1) value = 1;
if (value > maxQty) value = maxQty;
this.value = value;
updateQuantity();
});
function updateQuantity() {
const qty = parseInt(qtyInput.value);
qtyMinus.disabled = qty <= 1;
qtyPlus.disabled = qty >= maxQty;
// Update total price if exists
const priceElement = document.querySelector('.product-price');
const totalPriceElement = document.querySelector('.total-price');
if (priceElement && totalPriceElement) {
const unitPrice = parseFloat(priceElement.dataset.price);
const total = unitPrice * qty;
totalPriceElement.textContent = total.toFixed(0);
}
}
}
// ==========================================
// 4. Sticky Add to Cart Bar (Mobile)
// ==========================================
function initStickyCartBar() {
const stickyBar = document.querySelector('.sticky-cart-bar');
const addToCartSection = document.querySelector('.product-actions');
if (!stickyBar || !addToCartSection) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
stickyBar.classList.remove('visible');
} else {
stickyBar.classList.add('visible');
}
},
{ threshold: 0 }
);
observer.observe(addToCartSection);
}
// ==========================================
// 5. Share Functionality
// ==========================================
function initShareButtons() {
const shareButtons = document.querySelectorAll('.share-btn, .share-icon-btn');
shareButtons.forEach(btn => {
btn.addEventListener('click', function() {
const type = this.dataset.share;
const url = window.location.href;
const title = document.querySelector('.product-name')?.textContent || 'منتج رائع';
switch(type) {
case 'whatsapp':
window.open(`https://wa.me/?text=${encodeURIComponent(title + ' - ' + url)}`, '_blank');
showToast('✓ تمت المشاركة عبر WhatsApp');
break;
case 'facebook':
window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`, '_blank', 'width=600,height=400');
showToast('✓ تمت المشاركة عبر Facebook');
break;
case 'twitter':
window.open(`https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}&text=${encodeURIComponent(title)}`, '_blank', 'width=600,height=400');
showToast('✓ تمت المشاركة عبر Twitter');
break;
case 'copy':
copyToClipboard(url);
showToast('✓ تم نسخ الرابط بنجاح');
break;
}
});
});
}
function copyToClipboard(text) {
if (navigator.clipboard) {
navigator.clipboard.writeText(text);
} else {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
}
}
// ==========================================
// 6. Enhanced Add to Cart
// ==========================================
function enhanceAddToCart() {
const addToCartBtns = document.querySelectorAll('.btn-add-to-cart, .sticky-add-btn');
addToCartBtns.forEach(btn => {
btn.addEventListener('click', function(e) {
const qtyInput = document.querySelector('.qty-input');
const quantity = qtyInput ? parseInt(qtyInput.value) : 1;
// Store quantity for the original addToCart function
if (window.addToCart && this.dataset.productId) {
const productId = this.dataset.productId;
addToCartWithQuantity(productId, quantity);
e.stopPropagation();
}
});
});
}
function addToCartWithQuantity(productId, quantity) {
fetch('../api/cart/add.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
},
body: `product_id=${productId}&quantity=${quantity}`
})
.then(r => r.json())
.then(data => {
if (data.success) {
showToast(`✓ تم إضافة ${quantity} قطعة للسلة`);
updateCartBadge(data.cart_count);
// Animation
animateAddToCart();
} else {
showToast('⚠ ' + (data.message || 'حدث خطأ'));
}
})
.catch(err => {
console.error('Error:', err);
showToast('❌ حدث خطأ في الاتصال');
});
}
function animateAddToCart() {
const btn = document.querySelector('.btn-add-to-cart');
if (btn) {
btn.style.transform = 'scale(0.95)';
setTimeout(() => {
btn.style.transform = '';
}, 200);
}
}
function updateCartBadge(count) {
const badges = document.querySelectorAll('.nav-badge, #cartBadge');
badges.forEach(badge => {
if (count > 0) {
badge.textContent = count;
badge.style.display = 'flex';
} else {
badge.style.display = 'none';
}
});
}
// ==========================================
// 7. Toast Notification Helper
// ==========================================
function showToast(message, duration = 3000) {
let toast = document.getElementById('toast');
if (!toast) {
toast = document.createElement('div');
toast.id = 'toast';
toast.className = 'toast-notification hidden';
document.body.appendChild(toast);
}
toast.textContent = message;
toast.classList.remove('hidden');
setTimeout(() => {
toast.classList.add('hidden');
}, duration);
}
// Make showToast global
window.showToast = showToast;
// ==========================================
// 8. Smooth Scroll to Reviews
// ==========================================
function initReviewsScroll() {
const reviewsLink = document.querySelector('[href="#reviews"]');
const reviewsSection = document.querySelector('#reviews');
if (reviewsLink && reviewsSection) {
reviewsLink.addEventListener('click', function(e) {
e.preventDefault();
reviewsSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
}
}
// ==========================================
// 9. Recently Viewed Products
// ==========================================
function saveRecentlyViewed() {
const productId = document.querySelector('[data-product-id]')?.dataset.productId;
if (!productId) return;
let recent = JSON.parse(localStorage.getItem('recentlyViewed') || '[]');
// Remove if already exists
recent = recent.filter(id => id !== productId);
// Add to beginning
recent.unshift(productId);
// Keep only last 10
recent = recent.slice(0, 10);
localStorage.setItem('recentlyViewed', JSON.stringify(recent));
}
// ==========================================
// Initialize Everything
// ==========================================
function init() {
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
return;
}
initImageGallery();
initQuantitySelector();
initStickyCartBar();
initShareButtons();
enhanceAddToCart();
initReviewsScroll();
saveRecentlyViewed();
console.log('✓ Product enhancements initialized');
}
// Start initialization
init();
})();
// ==========================================
// 10. Review Form Functions
// ==========================================
function showReviewForm() {
const modal = document.getElementById('reviewFormModal');
if (modal) {
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
}
}
function hideReviewForm() {
const modal = document.getElementById('reviewFormModal');
if (modal) {
modal.style.display = 'none';
document.body.style.overflow = '';
document.getElementById('reviewForm').reset();
}
}
function submitReview(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
const productId = document.querySelector('[data-product-id]')?.dataset.productId;
if (!productId) {
showToast('❌ خطأ في تحديد المنتج');
return;
}
formData.append('product_id', productId);
// Disable submit button
const submitBtn = form.querySelector('.submit-review-btn');
const originalText = submitBtn.innerHTML;
submitBtn.disabled = true;
submitBtn.innerHTML = ' جاري الإرسال...';
fetch('../api/reviews/submit.php', {
method: 'POST',
body: formData
})
.then(r => r.json())
.then(data => {
if (data.success) {
showToast('✓ تم إرسال تقييمك بنجاح! سيظهر بعد المراجعة');
hideReviewForm();
// Reload page after 2 seconds to show new review
setTimeout(() => {
window.location.reload();
}, 2000);
} else {
showToast('⚠ ' + (data.message || 'حدث خطأ في إرسال التقييم'));
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
}
})
.catch(err => {
console.error('Error:', err);
showToast('❌ حدث خطأ في الاتصال');
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
});
}
// Close modal on outside click
document.addEventListener('click', function(e) {
const modal = document.getElementById('reviewFormModal');
if (modal && e.target === modal) {
hideReviewForm();
}
});
// Close modal on Escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
hideReviewForm();
}
});
// Make functions global
window.showReviewForm = showReviewForm;
window.hideReviewForm = hideReviewForm;
window.submitReview = submitReview;