/** * Dashboard Modal & Multi-step Form Handlers */ jQuery(document).ready(function($) { // Modal elements const $fabButton = $('.mf-floating-action-button'); const $modalOverlay = $('.mf-modal-overlay'); const $modalContainer = $('.mf-modal-container'); const $modalClose = $('.mf-modal-close'); const $backBtn = $('.mf-back-btn'); const $nextBtn = $('.mf-next-btn'); // Step indicators const $stepDots = $('.mf-step-dot'); let $steps = $('.mf-step'); // Selection buttons const $selectionButtons = $('.mf-selection-button'); // Current step and selected type let currentStep = 0; let selectedType = ''; let domainData = { domain: '', isValid: false, usesCloudFlare: false, cloudflareZoneId: '', cloudflareEmail: '', cloudflareKey: '', hasMX: false, configureMailferno: false, emailAccounts: [] }; // Open Modal $fabButton.on('click', function() { resetForm(); $modalOverlay.addClass('active'); }); // Close Modal $modalClose.on('click', closeModal); $modalOverlay.on('click', function(e) { if (e.target === this) { closeModal(); } }); function closeModal() { $modalOverlay.removeClass('active'); resetForm(); } // Reset Form function resetForm() { currentStep = 0; selectedType = ''; domainData = { domain: '', isValid: false, usesCloudFlare: false, cloudflareZoneId: '', cloudflareEmail: '', cloudflareKey: '', hasMX: false, configureMailferno: false, emailAccounts: [] }; $selectionButtons.removeClass('selected'); updateStepIndicators(); showCurrentStep(); $('.mf-validation-error').hide(); $('.mf-success-message, .mf-error-message').remove(); $('.mf-loading').hide(); $('#mf-domain-input').val(''); $('#mf-cloudflare-email').val(''); $('#mf-cloudflare-key').val(''); $('.mf-mx-option').removeClass('selected'); $('.mf-email-row:not(:first)').remove(); $('.mf-email-row input').val(''); } // Selection buttons $selectionButtons.on('click', function() { $selectionButtons.removeClass('selected'); $(this).addClass('selected'); selectedType = $(this).data('type'); $nextBtn.removeClass('disabled'); }); // Navigation buttons $backBtn.on('click', function() { if (currentStep > 0) { currentStep--; updateStepIndicators(); showCurrentStep(); } }); $nextBtn.on('click', function() { if ($(this).hasClass('disabled')) return; // Handle first step (selection) if (currentStep === 0) { if (!selectedType) { alert('Please select an option to continue'); return; } // Set up next steps based on selection setupStepsByType(selectedType); currentStep++; updateStepIndicators(); showCurrentStep(); return; } // Domain specific step handling if (selectedType === 'domain') { const result = handleDomainStep(currentStep); if (!result) return; // If step validation fails, don't proceed } // If we reach here, move to next step currentStep++; updateStepIndicators(); showCurrentStep(); }); // Update step indicators function updateStepIndicators() { $stepDots.removeClass('active completed'); // Update for current setup $stepDots.each(function(index) { if (index < currentStep) { $(this).addClass('completed'); } else if (index === currentStep) { $(this).addClass('active'); } }); // Update back button visibility if (currentStep === 0) { $backBtn.hide(); } else { $backBtn.show(); } // Update next button text const isLastStep = (currentStep === $steps.length - 1); $nextBtn.text(isLastStep ? 'Next' : 'Next'); // When on selection step, disable next until selection made if (currentStep === 0) { $nextBtn.toggleClass('disabled', !selectedType); } else { $nextBtn.removeClass('disabled'); } } // Show current step function showCurrentStep() { $steps.removeClass('active'); $steps.eq(currentStep).addClass('active'); } // Setup steps by selected type function setupStepsByType(type) { // Hide all steps except the first one $steps.not(':first').remove(); // Clear step indicators $('.mf-steps-indicator').empty(); let stepCount = 1; // Selection step if (type === 'domain') { // Step 1: Input domain $('
') .append('

Enter Domain Name

') .append('
Please enter a valid domain name
') .append('') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; // Step 2: CloudFlare verification $('
') .append('

Verify CloudFlare Connection

') .append('
') .append('
') .append('
Please enter valid CloudFlare credentials
') .append('') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; // Step 3: MX Configuration $('
') .append('

Email Server Configuration

') .append('

How would you like to configure email for this domain?

') .append('

Use Mailferno MX Server

Configure this domain to use Mailferno\'s email server. Best if this is a new domain not currently used for email.

Keep Existing Configuration

Keep your current email server configuration. Best if this domain is already being used for email.

') .append('
Please select an MX configuration option
') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; // Step 4: Email accounts $('
') .append('

Add Email Accounts

') .append('

Would you like to create email accounts for this domain now?

') .append('
@'+domainData.domain+'
') .append('') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; // Final step $('
') .append('

Domain Setup Complete

') .append('
Your domain has been successfully added to Mailferno!
') .append('

You can now continue to manage your domain, email accounts, and campaigns from the dashboard.

') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; } else if (type === 'campaign') { // Add campaign specific steps $('
') .append('

Create Campaign

') .append('

Campaign creation functionality will be implemented here.

') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; // Final step $('
') .append('

Campaign Created

') .append('
Your campaign has been successfully created!
') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; } else if (type === 'email') { // Add email account specific steps $('
') .append('

Create Email Account

') .append('

Email account creation functionality will be implemented here.

') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; // Final step $('
') .append('

Email Account Created

') .append('
Your email account has been successfully created!
') .appendTo($modalContainer.find('.mf-modal-body')); stepCount++; } // Create step indicators for (let i = 0; i < stepCount; i++) { $('
') .addClass(i === 0 ? 'completed' : (i === 1 ? 'active' : '')) .appendTo($('.mf-steps-indicator')); } // Make steps accessible $steps = $('.mf-step'); // Setup event handlers for the domain steps if (type === 'domain') { setupDomainStepHandlers(); } } // Domain step specific handlers function setupDomainStepHandlers() { // Step 1: Domain validation $('#mf-domain-input').on('input', function() { // Basic validation const domain = $(this).val().trim(); const isValid = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/.test(domain); if (isValid) { $('#domain-validation-error').hide(); domainData.domain = domain; } else { $('#domain-validation-error').show(); } }); // Step 3: MX Configuration $('.mf-mx-option').on('click', function() { $('.mf-mx-option').removeClass('selected'); $(this).addClass('selected'); domainData.configureMailferno = ($(this).data('option') === 'mailferno'); }); // Step 4: Email accounts $('.mf-add-email-btn').on('click', function() { const $newRow = $('.mf-email-row').first().clone(); $newRow.find('input').val(''); $newRow.insertBefore($(this)); }); // Remove email button $(document).on('click', '.mf-remove-email-btn', function() { if ($('.mf-email-row').length > 1) { $(this).closest('.mf-email-row').remove(); } else { $('.mf-email-row').find('input').val(''); } }); } // Domain step validation and AJAX handling function handleDomainStep(step) { // Adjust step to match domain-specific numbering (after selection) const domainStep = step - 1; switch(domainStep) { case 0: // Domain input validation const domain = $('#mf-domain-input').val().trim(); if (!domain || !/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/.test(domain)) { $('#domain-validation-error').show(); return false; } domainData.domain = domain; // Show loading indicator $steps.eq(currentStep).find('.mf-loading').show(); $nextBtn.addClass('disabled'); // AJAX validation call to check if domain is valid and uses CloudFlare $.ajax({ url: dashboard_modal_vars.ajax_url, type: 'POST', data: { action: 'validate_domain', security: dashboard_modal_vars.nonce, domain: domain }, success: function(response) { $steps.eq(currentStep).find('.mf-loading').hide(); if (response.success) { domainData.isValid = true; domainData.usesCloudFlare = response.data.usesCloudFlare; if (!domainData.usesCloudFlare) { $steps.eq(currentStep).append('
This domain is not using CloudFlare nameservers. Please configure CloudFlare for this domain before continuing.
'); return; } // Update domain text in email step $('.mf-email-row span').text('@' + domain); // Continue to next step $nextBtn.removeClass('disabled'); $nextBtn.trigger('click'); } else { $steps.eq(currentStep).append('
' + response.data.message + '
'); $nextBtn.removeClass('disabled'); } }, error: function() { $steps.eq(currentStep).find('.mf-loading').hide(); $steps.eq(currentStep).append('
Error validating domain. Please try again.
'); $nextBtn.removeClass('disabled'); } }); return false; // Prevent automatic next step - we'll handle it in AJAX callback case 1: // CloudFlare verification const email = $('#mf-cloudflare-email').val().trim(); const key = $('#mf-cloudflare-key').val().trim(); if (!email || !key) { $('#cloudflare-validation-error').show(); return false; } domainData.cloudflareEmail = email; domainData.cloudflareKey = key; // Show loading indicator $steps.eq(currentStep).find('.mf-loading').show(); $nextBtn.addClass('disabled'); // AJAX call to verify CloudFlare credentials $.ajax({ url: dashboard_modal_vars.ajax_url, type: 'POST', data: { action: 'verify_cloudflare', security: dashboard_modal_vars.nonce, domain: domainData.domain, email: email, key: key }, success: function(response) { $steps.eq(currentStep).find('.mf-loading').hide(); if (response.success) { domainData.cloudflareZoneId = response.data.zoneId; domainData.hasMX = response.data.hasMX; // Continue to next step $nextBtn.removeClass('disabled'); $nextBtn.trigger('click'); } else { $steps.eq(currentStep).append('
' + response.data.message + '
'); $nextBtn.removeClass('disabled'); } }, error: function() { $steps.eq(currentStep).find('.mf-loading').hide(); $steps.eq(currentStep).append('
Error verifying CloudFlare credentials. Please try again.
'); $nextBtn.removeClass('disabled'); } }); return false; // Prevent automatic next step - we'll handle it in AJAX callback case 2: // MX Configuration if (!$('.mf-mx-option.selected').length) { $('#mx-validation-error').show(); return false; } domainData.configureMailferno = ($('.mf-mx-option.selected').data('option') === 'mailferno'); return true; case 3: // Email accounts domainData.emailAccounts = []; let allValid = true; $('.mf-email-row').each(function() { const username = $(this).find('.mf-email-local').val().trim(); if (username) { domainData.emailAccounts.push(username + '@' + domainData.domain); } }); if (allValid) { // Create domain via AJAX $nextBtn.addClass('disabled'); $.ajax({ url: dashboard_modal_vars.ajax_url, type: 'POST', data: { action: 'create_domain', security: dashboard_modal_vars.nonce, domainData: JSON.stringify(domainData) }, success: function(response) { if (response.success) { // Update final step $steps.eq(currentStep + 1).find('.mf-success-message').text(response.data.message); // Continue to next step $nextBtn.removeClass('disabled'); $nextBtn.trigger('click'); // Reload page after a short delay to show updated dashboard setTimeout(function() { window.location.reload(); }, 5000); } else { $steps.eq(currentStep).append('
' + response.data.message + '
'); $nextBtn.removeClass('disabled'); } }, error: function() { $steps.eq(currentStep).append('
Error creating domain. Please try again.
'); $nextBtn.removeClass('disabled'); } }); return false; } return allValid; case 4: // Final step - just close modal closeModal(); return true; } return true; } });