182 lines
6.3 KiB
JavaScript
182 lines
6.3 KiB
JavaScript
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 =>
|
|
`<div class="file-item">${file.name} (${(file.size / 1024).toFixed(1)} KB)</div>`
|
|
).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...';
|
|
|
|
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 });
|
|
|