const dropArea = document.getElementById('dropArea'); const fileInput = document.getElementById('fileInput'); const fileList = document.getElementById('fileList'); const submitBtn = document.getElementById('submitBtn'); const emailInput = document.getElementById('emailInput'); const notesInput = document.getElementById('notesInput'); let selectedFiles = []; function checkCanSubmit() { const hasEmail = emailInput.value.trim().length > 0; const hasNotes = notesInput.value.trim().length > 0; const hasFiles = selectedFiles.length > 0; submitBtn.disabled = !(hasEmail || hasNotes || hasFiles); } emailInput.addEventListener('input', checkCanSubmit); notesInput.addEventListener('input', checkCanSubmit); dropArea.addEventListener('click', () => fileInput.click()); dropArea.addEventListener('dragover', (e) => { e.preventDefault(); dropArea.classList.add('dragover'); }); dropArea.addEventListener('dragleave', () => { dropArea.classList.remove('dragover'); }); dropArea.addEventListener('drop', (e) => { e.preventDefault(); dropArea.classList.remove('dragover'); handleFiles(e.dataTransfer.files); }); fileInput.addEventListener('change', (e) => { handleFiles(e.target.files); }); function handleFiles(files) { selectedFiles = Array.from(files); displayFiles(); checkCanSubmit(); } function displayFiles() { if (selectedFiles.length === 0) { fileList.classList.remove('show'); return; } fileList.classList.add('show'); fileList.innerHTML = selectedFiles.map(file => `
${file.name} (${(file.size / 1024).toFixed(1)} KB)
` ).join(''); } submitBtn.addEventListener('click', async () => { const email = emailInput.value.trim(); const notes = notesInput.value.trim(); // Validate at least one field if (!email && !notes && selectedFiles.length === 0) { return; } // Disable form during submission submitBtn.disabled = true; emailInput.disabled = true; notesInput.disabled = true; fileInput.disabled = true; dropArea.style.pointerEvents = 'none'; dropArea.classList.add('disabled'); // Show progress bar const progressContainer = document.getElementById('progressContainer'); const progressFill = document.getElementById('progressFill'); const progressMessage = document.getElementById('progressMessage'); progressContainer.style.display = 'block'; progressFill.style.width = '0%'; progressMessage.textContent = 'Starting...'; // Scroll to progress bar so it's visible (for Google Pages iframe compatibility) setTimeout(() => { progressContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }, 100); try { // Create FormData const formData = new FormData(); if (email) formData.append('email', email); if (notes) formData.append('notes', notes); selectedFiles.forEach(file => { formData.append('files', file); }); // Submit and read streaming response const response = await fetch('/submit-quote/', { method: 'POST', body: formData }); if (!response.ok) { throw new Error(`Server error: ${response.status}`); } const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop() || ''; // Keep incomplete line in buffer for (const line of lines) { if (line.trim()) { try { const update = JSON.parse(line); progressFill.style.width = update.progress + '%'; progressMessage.textContent = update.message; if (update.step === 5 || update.step === 'error') { // Complete or error if (update.step === 5) { setTimeout(() => { // Reset form after success emailInput.value = ''; notesInput.value = ''; selectedFiles = []; displayFiles(); checkCanSubmit(); // Re-enable form (but keep progress bar visible) emailInput.disabled = false; notesInput.disabled = false; fileInput.disabled = false; dropArea.style.pointerEvents = 'auto'; dropArea.classList.remove('disabled'); }, 2000); } else { // Error - re-enable form emailInput.disabled = false; notesInput.disabled = false; fileInput.disabled = false; dropArea.style.pointerEvents = 'auto'; dropArea.classList.remove('disabled'); submitBtn.disabled = false; } } } catch (e) { console.error('Error parsing progress update:', e); } } } } } catch (error) { progressMessage.textContent = `Error: ${error.message}`; progressFill.style.width = '0%'; // Re-enable form emailInput.disabled = false; notesInput.disabled = false; fileInput.disabled = false; dropArea.style.pointerEvents = 'auto'; dropArea.classList.remove('disabled'); submitBtn.disabled = false; } }); // Attempt to auto-resize the iframe height (if parent allows) function postHeight() { const height = document.documentElement.scrollHeight; try { parent.postMessage({ type: 'sedutto-ifr-height', height }, '*'); } catch (e) { // ignore if cross-origin restrictions apply } } window.addEventListener('load', postHeight); window.addEventListener('resize', postHeight); const mo = new MutationObserver(postHeight); mo.observe(document.body, { childList: true, subtree: true });