shubraVeil/js/reviews.js
2024-12-25 13:05:50 +02:00

279 lines
10 KiB
JavaScript

class ReviewSystem {
constructor() {
this.reviewForm = document.getElementById('review-form');
this.reviewsContainer = document.getElementById('reviews-container');
this.ratingInput = document.getElementById('rating-input');
this.initializeReviews();
}
initializeReviews() {
// تهيئة نظام التقييم بالنجوم
this.initializeStarRating();
// معالجة إرسال المراجعة
this.reviewForm?.addEventListener('submit', (e) => this.handleReviewSubmit(e));
// تهيئة فلترة المراجعات
this.initializeReviewFilters();
// تحميل المراجعات الحالية
this.loadReviews();
}
initializeStarRating() {
const ratingStars = document.querySelectorAll('.rating-stars i');
ratingStars.forEach((star, index) => {
star.addEventListener('mouseover', () => {
this.updateStars(ratingStars, index);
});
star.addEventListener('click', () => {
this.ratingInput.value = index + 1;
star.classList.add('selected');
});
});
// إعادة تعيين النجوم عند إزالة المؤشر
document.querySelector('.rating-stars')?.addEventListener('mouseleave', () => {
this.updateStars(ratingStars, this.ratingInput.value - 1);
});
}
updateStars(stars, activeIndex) {
stars.forEach((star, index) => {
star.classList.toggle('active', index <= activeIndex);
});
}
async handleReviewSubmit(e) {
e.preventDefault();
const formData = new FormData(e.target);
try {
const response = await fetch('/api/reviews.php', {
method: 'POST',
body: formData
});
if (!response.ok) throw new Error('فشل إرسال المراجعة');
const review = await response.json();
this.addReviewToDOM(review);
this.showNotification('تم إضافة مراجعتك بنجاح');
e.target.reset();
this.updateStars(document.querySelectorAll('.rating-stars i'), -1);
} catch (error) {
console.error('Review submission error:', error);
this.showNotification('حدث خطأ أثناء إرسال المراجعة', 'error');
}
}
initializeReviewFilters() {
const filterButtons = document.querySelectorAll('.review-filter');
filterButtons.forEach(button => {
button.addEventListener('click', () => {
filterButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
this.filterReviews(button.dataset.rating);
});
});
// تهيئة الترتيب
document.getElementById('review-sort')?.addEventListener('change', (e) => {
this.sortReviews(e.target.value);
});
}
async loadReviews() {
try {
const productId = this.reviewsContainer?.dataset.productId;
const response = await fetch(`/api/reviews.php?product_id=${productId}`);
if (!response.ok) throw new Error('فشل تحميل المراجعات');
const reviews = await response.json();
this.displayReviews(reviews);
} catch (error) {
console.error('Reviews loading error:', error);
this.showNotification('حدث خطأ أثناء تحميل المراجعات', 'error');
}
}
displayReviews(reviews) {
if (!this.reviewsContainer) return;
if (reviews.length === 0) {
this.reviewsContainer.innerHTML = '<p class="no-reviews">لا توجد مراجعات بعد</p>';
return;
}
this.reviewsContainer.innerHTML = reviews.map(review => `
<div class="review-card" data-rating="${review.rating}">
<div class="review-header">
<div class="reviewer-info">
<img src="${review.userAvatar}" alt="${review.userName}" class="reviewer-avatar">
<div>
<h4>${review.userName}</h4>
<div class="review-rating">
${this.generateStars(review.rating)}
</div>
<span class="review-date">${review.date}</span>
</div>
</div>
<div class="review-verification">
${review.verified ? '<span class="verified-badge"><i class="fas fa-check-circle"></i> شراء موثق</span>' : ''}
</div>
</div>
<div class="review-content">
<p>${review.content}</p>
${review.images ? this.generateImageGallery(review.images) : ''}
</div>
<div class="review-actions">
<button class="helpful-btn" onclick="reviewSystem.markHelpful('${review.id}')">
<i class="far fa-thumbs-up"></i>
<span class="helpful-count">${review.helpfulCount}</span>
</button>
<button class="report-btn" onclick="reviewSystem.reportReview('${review.id}')">
<i class="far fa-flag"></i>
</button>
</div>
</div>
`).join('');
}
generateStars(rating) {
return Array(5).fill().map((_, index) => `
<i class="fas fa-star ${index < rating ? 'filled' : ''}"></i>
`).join('');
}
generateImageGallery(images) {
return `
<div class="review-images">
${images.map(image => `
<img src="${image}" alt="صورة المراجعة" onclick="reviewSystem.showImageModal('${image}')">
`).join('')}
</div>
`;
}
filterReviews(rating) {
const reviews = document.querySelectorAll('.review-card');
reviews.forEach(review => {
if (rating === 'all' || review.dataset.rating === rating) {
review.style.display = 'block';
} else {
review.style.display = 'none';
}
});
}
sortReviews(criteria) {
const reviews = Array.from(document.querySelectorAll('.review-card'));
const container = this.reviewsContainer;
if (!container) return;
reviews.sort((a, b) => {
switch (criteria) {
case 'newest':
return new Date(b.querySelector('.review-date').textContent) -
new Date(a.querySelector('.review-date').textContent);
case 'highest':
return b.dataset.rating - a.dataset.rating;
case 'lowest':
return a.dataset.rating - b.dataset.rating;
case 'helpful':
return parseInt(b.querySelector('.helpful-count').textContent) -
parseInt(a.querySelector('.helpful-count').textContent);
default:
return 0;
}
});
reviews.forEach(review => container.appendChild(review));
}
async markHelpful(reviewId) {
try {
const response = await fetch('/api/helpful-review.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ reviewId })
});
if (!response.ok) throw new Error('فشل تسجيل المساعدة');
const data = await response.json();
document.querySelector(`[data-review-id="${reviewId}"] .helpful-count`).textContent = data.helpfulCount;
this.showNotification('شكراً لتقييمك');
} catch (error) {
console.error('Helpful marking error:', error);
}
}
reportReview(reviewId) {
const reason = prompt('يرجى ذكر سبب الإبلاغ عن هذه المراجعة:');
if (!reason) return;
fetch('/api/report-review.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ reviewId, reason })
})
.then(response => {
if (response.ok) {
this.showNotification('شكراً لإبلاغك. سنراجع المحتوى.');
}
})
.catch(error => {
console.error('Review report error:', error);
this.showNotification('حدث خطأ أثناء الإبلاغ', 'error');
});
}
showImageModal(imageSrc) {
const modal = document.createElement('div');
modal.className = 'image-modal';
modal.innerHTML = `
<div class="modal-content">
<img src="${imageSrc}" alt="صورة المراجعة">
<button class="close-modal">&times;</button>
</div>
`;
document.body.appendChild(modal);
modal.querySelector('.close-modal').addEventListener('click', () => modal.remove());
modal.addEventListener('click', (e) => {
if (e.target === modal) modal.remove();
});
}
showNotification(message, type = 'success') {
const notification = document.createElement('div');
notification.className = `review-notification ${type}`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.classList.add('show');
}, 100);
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => notification.remove(), 300);
}, 2000);
}
}
// تهيئة نظام المراجعات
const reviewSystem = new ReviewSystem();