// === AI Cartoon Generator - Complete File === // Utility function to show/hide elements function toggleElement(el, show) { if (el) el.style.display = show ? 'block' : 'none'; } // === Image Preview Handler === (function imagePreviewInit() { const form = document.querySelector('form'); if (!form) return; const inputs = form.querySelectorAll('input[name="pet_images[]"]'); const previewContainer = document.getElementById('image-preview-container'); if (!previewContainer) return; inputs.forEach(input => { input.addEventListener('change', function(e) { const files = e.target.files; if (!files || files.length === 0) return; previewContainer.innerHTML = ''; Array.from(files).forEach(file => { if (!file.type.startsWith('image/')) return; const reader = new FileReader(); reader.onload = function(e) { const div = document.createElement('div'); div.className = 'image-preview-item'; div.innerHTML = ` Pet preview ${file.name} `; previewContainer.appendChild(div); }; reader.readAsDataURL(file); }); }); }); })(); // === Style Selection Handler === (function styleSelectionInit() { const form = document.querySelector('form'); if (!form) return; const styleRadios = form.querySelectorAll('input[name="style"]'); const styleCards = document.querySelectorAll('.style-card'); styleRadios.forEach(radio => { radio.addEventListener('change', function() { styleCards.forEach(card => { card.classList.remove('selected'); }); const selectedCard = this.closest('.style-card'); if (selectedCard) { selectedCard.classList.add('selected'); } }); }); })(); // === Generate Cartoon via OpenAI (server-side) === (function cartoonGenerateInit() { const generateBtn = document.getElementById('ai-generate-btn'); const preview = document.getElementById('ai-generated-preview'); const hidden = document.getElementById('ai-generated-url'); const mockupSection = document.getElementById('mockup-preview-section'); const mockupContainer = document.getElementById('mockup-preview-container'); if (!generateBtn || !preview || !hidden) return; generateBtn.addEventListener('click', async () => { // Find the form - adjust selector based on your HTML structure const form = generateBtn.closest('form') || document.querySelector('form'); if (!form) { alert('Form not found.'); return; } // Pick first image from pet_images[] const inputs = form.querySelectorAll('input[name="pet_images[]"]'); let file = null; for (const inp of inputs) { if (inp.files && inp.files.length > 0) { file = inp.files[0]; break; } } if (!file) { alert('Please upload a pet image first.'); return; } // Get selected style from radio buttons const selectedStyle = form.querySelector('input[name="style"]:checked'); if (!selectedStyle) { alert('Please select a cartoon style.'); return; } const old = generateBtn.textContent; generateBtn.disabled = true; generateBtn.textContent = '🎨 Generating...'; preview.innerHTML = '
'; if (mockupSection) { mockupSection.style.display = 'none'; } try { const fd = new FormData(); fd.append('action', 'ai_cartoon_generate'); fd.append('nonce', aiCartoonData.nonce); fd.append('pet_image', file); fd.append('style', selectedStyle.value); const res = await fetch(aiCartoonData.ajax_url, { method: 'POST', body: fd }); const json = await res.json(); if (!json?.success || !json?.data?.url) { throw new Error(json?.data || 'Failed to generate image'); } hidden.value = json.data.url; preview.innerHTML = `

Your Pet Cartoon

Cartoonized pet
`; // Show mockup if available if (json.data.mockup_url && mockupContainer && mockupSection) { mockupContainer.innerHTML = `

Product Mockup Preview

Product mockup

This is how your design will look on our products!

`; mockupSection.style.display = 'block'; } } catch (e) { preview.innerHTML = `

${e.message}

`; } finally { generateBtn.disabled = false; generateBtn.textContent = old; } }); })(); // === Form Validation === (function formValidationInit() { const form = document.querySelector('form'); if (!form) return; form.addEventListener('submit', function(e) { const hiddenUrl = document.getElementById('ai-generated-url'); if (!hiddenUrl || !hiddenUrl.value) { e.preventDefault(); alert('Please generate a cartoon first before submitting.'); return false; } // Additional validation can be added here const style = form.querySelector('input[name="style"]:checked'); if (!style) { e.preventDefault(); alert('Please select a cartoon style.'); return false; } }); })(); // === Loading Spinner CSS (inject if not in stylesheet) === (function injectStyles() { const styles = ` .loading-spinner { border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 20px auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .error-message { color: #d32f2f; padding: 15px; background: #ffebee; border-radius: 8px; margin: 10px 0; } .cartoon-result, .mockup-result { text-align: center; padding: 20px; background: #f9f9f9; border-radius: 12px; margin: 20px 0; } .cartoon-result h3, .mockup-result h3 { margin-bottom: 15px; color: #333; } .image-preview-container { display: flex; flex-wrap: wrap; gap: 15px; margin: 15px 0; } .image-preview-item { position: relative; width: 150px; } .image-preview-item img { width: 100%; height: 150px; object-fit: cover; border-radius: 8px; border: 2px solid #ddd; } .image-name { display: block; font-size: 12px; color: #666; margin-top: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .style-card { cursor: pointer; transition: all 0.3s ease; border: 2px solid #ddd; padding: 15px; border-radius: 8px; } .style-card:hover { border-color: #3498db; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); } .style-card.selected { border-color: #3498db; background-color: #e3f2fd; } `; const styleSheet = document.createElement('style'); styleSheet.textContent = styles; document.head.appendChild(styleSheet); })(); console.log('AI Cartoon Generator initialized');