2026-02-17 23:03:48 -05:00

205 lines
6.2 KiB
JavaScript

// ═══════════════════════════════════════════════
// A2P Compliance Wizard - Form Handler
// ═══════════════════════════════════════════════
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('wizardForm');
const submitBtn = document.getElementById('submitBtn');
const overlay = document.getElementById('loadingOverlay');
const errorBanner = document.getElementById('errorBanner');
const logoInput = document.getElementById('logoInput');
const logoUpload = document.querySelector('.logo-upload');
const logoPreview = document.getElementById('logoPreview');
const logoUploadText = document.querySelector('.logo-upload-text');
// Logo upload preview
logoUpload.addEventListener('click', () => logoInput.click());
logoUpload.addEventListener('dragover', (e) => {
e.preventDefault();
logoUpload.style.borderColor = '#2563EB';
logoUpload.style.background = '#EFF6FF';
});
logoUpload.addEventListener('dragleave', () => {
logoUpload.style.borderColor = '';
logoUpload.style.background = '';
});
logoUpload.addEventListener('drop', (e) => {
e.preventDefault();
logoUpload.style.borderColor = '';
logoUpload.style.background = '';
if (e.dataTransfer.files.length) {
logoInput.files = e.dataTransfer.files;
handleLogoSelect();
}
});
logoInput.addEventListener('change', handleLogoSelect);
function handleLogoSelect() {
const file = logoInput.files[0];
if (!file) return;
if (!file.type.startsWith('image/')) {
showError('Please upload an image file (PNG, JPG, SVG, WebP)');
return;
}
if (file.size > 5 * 1024 * 1024) {
showError('Logo must be under 5MB');
return;
}
const reader = new FileReader();
reader.onload = (e) => {
logoPreview.src = e.target.result;
logoPreview.style.display = 'block';
logoUpload.classList.add('has-file');
logoUploadText.textContent = file.name;
};
reader.readAsDataURL(file);
}
// Form submission
form.addEventListener('submit', async (e) => {
e.preventDefault();
hideError();
// Validate
if (!validateForm()) return;
// Show loading
overlay.classList.add('active');
submitBtn.disabled = true;
updateProgress(0, 'Preparing your request...');
try {
const formData = new FormData(form);
// Simulate progress during generation
const progressInterval = simulateProgress();
const response = await fetch('/api/generate', {
method: 'POST',
body: formData,
});
clearInterval(progressInterval);
const result = await response.json();
if (!result.success) {
throw new Error(result.error || 'Generation failed');
}
// Show completion
updateProgress(100, 'Complete!');
setStepDone(0);
setStepDone(1);
setStepDone(2);
setStepDone(3);
// Redirect to results
setTimeout(() => {
window.location.href = result.resultsUrl;
}, 800);
} catch (err) {
overlay.classList.remove('active');
submitBtn.disabled = false;
showError(err.message || 'Something went wrong. Please try again.');
}
});
function validateForm() {
const required = ['agencyName', 'agencyEmail', 'businessName', 'businessAddress', 'businessEmail', 'businessPhone', 'businessDescription'];
for (const field of required) {
const input = form.querySelector(`[name="${field}"]`);
if (!input || !input.value.trim()) {
showError(`Please fill in all required fields`);
input?.focus();
return false;
}
}
// Validate email
const email = form.querySelector('[name="agencyEmail"]').value;
if (!email.includes('@') || !email.includes('.')) {
showError('Please enter a valid email address');
return false;
}
// Validate checkbox
const checkbox = form.querySelector('[name="tcpaConsent"]');
if (!checkbox || !checkbox.checked) {
showError('Please confirm TCPA compliance to continue');
return false;
}
return true;
}
function simulateProgress() {
let progress = 0;
const steps = [
{ at: 10, msg: 'Generating AI content...' },
{ at: 45, msg: 'Building website pages...' },
{ at: 65, msg: 'Taking screenshots...' },
{ at: 85, msg: 'Assembling compliance packet...' },
];
let stepIndex = 0;
return setInterval(() => {
if (progress < 90) {
progress += Math.random() * 3 + 0.5;
progress = Math.min(progress, 92);
updateProgress(progress);
if (stepIndex < steps.length && progress >= steps[stepIndex].at) {
setStepActive(stepIndex);
if (stepIndex > 0) setStepDone(stepIndex - 1);
document.querySelector('.loading-message').textContent = steps[stepIndex].msg;
stepIndex++;
}
}
}, 500);
}
function updateProgress(pct, msg) {
const fill = document.querySelector('.progress-fill');
if (fill) fill.style.width = `${pct}%`;
if (msg) {
const el = document.querySelector('.loading-message');
if (el) el.textContent = msg;
}
}
function setStepActive(index) {
const steps = document.querySelectorAll('.progress-step');
if (steps[index]) {
steps[index].classList.remove('done');
steps[index].classList.add('active');
}
}
function setStepDone(index) {
const steps = document.querySelectorAll('.progress-step');
if (steps[index]) {
steps[index].classList.remove('active');
steps[index].classList.add('done');
const icon = steps[index].querySelector('.progress-step-icon');
if (icon) icon.innerHTML = '<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>';
}
}
function showError(msg) {
errorBanner.textContent = msg;
errorBanner.classList.add('visible');
errorBanner.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
function hideError() {
errorBanner.classList.remove('visible');
}
});