/** * Review Submission Modal & Handler * Handles review form display, validation, and submission */ (function() { 'use strict'; let currentProductId = null; let currentOrderId = null; let selectedRating = 0; let uploadedImages = []; // Get CSRF token from meta tag function getCsrfToken() { const metaTag = document.querySelector('meta[name="csrf-token"]'); return metaTag ? metaTag.getAttribute('content') : ''; } // Initialize function init() { createReviewModal(); attachEventListeners(); loadReviewableOrders(); } // Create review modal HTML function createReviewModal() { const modalHTML = `
`; document.body.insertAdjacentHTML('beforeend', modalHTML); } // Attach event listeners function attachEventListeners() { // Modal triggers - event delegation document.addEventListener('click', function(e) { const btn = e.target.closest('.btn-write-review'); if (btn) { e.preventDefault(); openReviewModal( btn.dataset.productId, btn.dataset.orderId, btn.dataset.productName, btn.dataset.productImage, btn.dataset.productSku ); } }); // Close modal setTimeout(() => { const closeBtn = document.getElementById('review-modal-close'); const cancelBtn = document.getElementById('review-cancel'); const overlay = document.getElementById('review-modal-overlay'); if (closeBtn) { closeBtn.addEventListener('click', closeReviewModal); } if (cancelBtn) { cancelBtn.addEventListener('click', closeReviewModal); } if (overlay) { overlay.addEventListener('click', function(e) { if (e.target === overlay) closeReviewModal(); }); } }, 100); // Star rating setTimeout(() => { const starButtons = document.querySelectorAll('.star-btn'); starButtons.forEach(btn => { btn.addEventListener('click', function(e) { e.preventDefault(); const rating = parseInt(this.dataset.rating); setRating(rating); }); }); }, 100); // Character count setTimeout(() => { const textarea = document.getElementById('review-text'); if (textarea) { textarea.addEventListener('input', function() { updateCharCount(); calculatePotentialPoints(); }); } }, 100); // Image upload setTimeout(() => { const uploadTrigger = document.getElementById('upload-trigger'); const fileInput = document.getElementById('review-images'); if (uploadTrigger && fileInput) { uploadTrigger.addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', handleImageSelection); } }, 100); // Form submit setTimeout(() => { const form = document.getElementById('review-form'); if (form) { form.addEventListener('submit', handleSubmit); } }, 100); } // Open review modal function openReviewModal(productId, orderId, productName, productImage, productSku) { const overlay = document.getElementById('review-modal-overlay'); if (!overlay) { console.error('Modal overlay not found!'); return; } currentProductId = productId; currentOrderId = orderId; selectedRating = 0; uploadedImages = []; // Set product info const nameEl = document.getElementById('review-product-name'); const imageEl = document.getElementById('review-product-image'); const skuEl = document.getElementById('review-product-sku'); if (nameEl) nameEl.textContent = productName; if (imageEl) imageEl.src = productImage || '/assets/img/no-image.png'; if (skuEl) skuEl.textContent = 'SKU: ' + productSku; // Update privacy preview with actual user name updatePrivacyPreview(); // Reset form const form = document.getElementById('review-form'); const previewGrid = document.getElementById('image-preview-grid'); const errorEl = document.getElementById('review-form-error'); if (form) form.reset(); if (previewGrid) previewGrid.innerHTML = ''; if (errorEl) errorEl.style.display = 'none'; setRating(0); updateCharCount(); calculatePotentialPoints(); // Show modal overlay.style.display = 'flex'; overlay.classList.add('show'); document.body.style.overflow = 'hidden'; } // Close review modal function closeReviewModal() { const overlay = document.getElementById('review-modal-overlay'); if (overlay) { overlay.classList.remove('show'); setTimeout(() => { overlay.style.display = 'none'; }, 200); // Wait for fade animation } document.body.style.overflow = ''; } // Set star rating function setRating(rating) { selectedRating = rating; const stars = document.querySelectorAll('.star-btn'); const labels = ['', 'Sangat Buruk', 'Buruk', 'Cukup', 'Bagus', 'Sangat Bagus']; stars.forEach((star, index) => { if (index < rating) { star.classList.add('active'); } else { star.classList.remove('active'); } }); document.getElementById('rating-label').textContent = labels[rating] || 'Pilih rating Anda'; } // Update character count function updateCharCount() { const textarea = document.getElementById('review-text'); const count = textarea.value.length; document.getElementById('review-char-count').textContent = count; } // Calculate potential points function calculatePotentialPoints() { const textarea = document.getElementById('review-text'); if (!textarea) return; const charCount = textarea.value.trim().length; const hasImages = uploadedImages.length > 0; let totalPoints = 5000; let longTextActive = charCount >= 100; let imagesActive = hasImages; if (longTextActive) totalPoints += 1000; if (imagesActive) totalPoints += 2000; // Update UI const longTextEl = document.getElementById('pri-long-text'); const imagesEl = document.getElementById('pri-images'); const totalEl = document.getElementById('pri-total-points'); if (longTextEl) longTextEl.style.opacity = longTextActive ? '1' : '0.5'; if (imagesEl) imagesEl.style.opacity = imagesActive ? '1' : '0.5'; if (totalEl) totalEl.textContent = totalPoints.toLocaleString('id-ID') + ' point'; } // Handle image selection function handleImageSelection(e) { const files = Array.from(e.target.files); if (files.length > 5) { showError('Maksimal 5 foto yang dapat diupload'); e.target.value = ''; // Reset input return; } uploadedImages = []; const previewGrid = document.getElementById('image-preview-grid'); previewGrid.innerHTML = ''; files.forEach((file, index) => { // Validate file type if (!file.type.match(/image\/(jpeg|jpg|png|webp)/)) { showError('Format file harus JPG, PNG, atau WebP'); return; } // Validate file size (2MB) if (file.size > 2 * 1024 * 1024) { showError('Ukuran file maksimal 2MB'); return; } uploadedImages.push(file); // Create preview const reader = new FileReader(); reader.onload = function(e) { const previewHTML = `Gagal memuat data. Silakan refresh halaman.
'; empty.style.display = 'block'; } } } // Render reviewable orders function renderReviewableOrders(orders) { const container = document.getElementById('reviewable-orders-list'); if (!container) return; let html = ''; orders.forEach(order => { html += `