PageSourceSearch

https://mera.work/wp-content/plugins/onboarding%20by%20asj/js/signup-wizard.js?ver=1790230267

js mera.work collected 2026-09-24 13:43:57 UTC 40,170 bytes, 963 lines download raw bytes

1jQuery(document).ready(function ($) {
2    // Define ajaxurl locally if it's not defined globally
3    const ajaxurl = window.ajaxurl || (typeof onboarding_ajax_object !== 'undefined' ? onboarding_ajax_object.ajax_url : '');
4    const ajax_nonce = typeof onboarding_ajax_object !== 'undefined' ? onboarding_ajax_object.nonce : '';
5
6    // Initialize Swiper (if swiper container is present on the page)
7    if ($('.mera-swiper').length > 0 && typeof Swiper !== 'undefined') {
8        var swiper = new Swiper(".mera-swiper", {
9            loop: true,
10            autoplay: { delay: 3500 },
11            pagination: { el: ".swiper-pagination", clickable: true },
12            effect: "slide",
13            speed: 900
14        });
15    }
16
17    // Step state tracking
18    // 0 = Email Step (.sec0)
19    // 1 = OTP Step (.sec1)
20    // 2 = Company/Profile Wizard (.sec2)
21    // 3 = Set Password (.sec6)
22    let currentStep = 0;
23    
24    // Sub-steps inside Step 2 (Wizard panes 1, 2, 3, 4, 5)
25    let activePane = 1; 
26    const maxPane = 5;
27
28    // Cookie Utilities
29    function setCookie(name, value, days) {
30        if (!value) return;
31        const d = new Date();
32        d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
33        document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + d.toUTCString() + ";path=/";
34    }
35
36    function getCookie(name) {
37        let nameEQ = name + "=";
38        let ca = document.cookie.split(';');
39        for (let i = 0; i < ca.length; i++) {
40            let c = ca[i].trim();
41            if (c.indexOf(nameEQ) == 0) return decodeURIComponent(c.substring(nameEQ.length));
42        }
43        return null;
44    }
45
46    function deleteCookie(name) {
47        document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
48    }
49
50    // Safe Storage Utilities
51    function getOnboardingEmail() {
52        let email = '';
53        try {
54            email = localStorage.getItem('onboarding_email') || '';
55        } catch (e) {}
56        if (!email) {
57            email = getCookie('onboarding_email') || '';
58        }
59        return email;
60    }
61
62    function setOnboardingEmail(email) {
63        try {
64            localStorage.setItem('onboarding_email', email);
65        } catch (e) {}
66        setCookie('onboarding_email', email, 30);
67    }
68
69    function removeOnboardingEmail() {
70        try {
71            localStorage.removeItem('onboarding_email');
72        } catch (e) {}
73        deleteCookie('onboarding_email');
74    }
75
76    // Parse URL parameter
77    function getURLParameter(name) {
78        let params = new URLSearchParams(window.location.search);
79        return params.get(name);
80    }
81
82    // Handle Campaign Cookies
83    const hostname = window.location.hostname;
84    if (hostname.includes('mera.work') || hostname.includes('meramonitor.com') || hostname.includes('localhost') || hostname.includes('127.0.0.1')) {
85        let utmSource = getURLParameter('utmSource') || getURLParameter('utm_source');
86        let utmMedium = getURLParameter('utmMedium') || getURLParameter('utm_medium');
87        let partnerCode = getURLParameter('partnerCode') || getURLParameter('partner_code');
88
89        if (partnerCode) setCookie('campPartnerCode', partnerCode, 30);
90        if (utmSource) setCookie('campUtmSource', utmSource, 30);
91        if (utmMedium) setCookie('campUtmMedium', utmMedium, 30);
92
93        // Fallback default
94        if (!utmSource && !getCookie('campUtmSource')) {
95            setCookie('campUtmSource', 'SEO', 2);
96        }
97    }
98
99    // Populate hidden source fields for all forms
100    let storedSource = getCookie('campUtmSource') || getCookie('utm_source');
101    if (storedSource) {
102        $('[id="utm_source"]').val(storedSource);
103    }
104
105    // Restore email from safe storage for all forms
106    var savedEmail = getOnboardingEmail();
107    if (savedEmail) {
108        $('[id="emailaddress"]').text(savedEmail);
109        $('[id="emailsignup"]').val(savedEmail);
110    }
111
112    // Restore wizard state for all forms
113    try {
114        if (localStorage.getItem('wizard-company')) $('[id="company"]').val(localStorage.getItem('wizard-company'));
115        if (localStorage.getItem('wizard-name')) $('[id="fullname"]').val(localStorage.getItem('wizard-name'));
116        if (localStorage.getItem('wizard-phone')) $('[id="phone"]').val(localStorage.getItem('wizard-phone'));
117        if (localStorage.getItem('wizard-country')) $('[id="country"]').val(localStorage.getItem('wizard-country'));
118    } catch (e) {}
119
120    // STEP TRANSITION UTILITY
121    function showFormStep(stepIdx, context) {
122        currentStep = stepIdx;
123        const parent = context || $('.onboarding-container');
124        
125        // Hide all major wrappers inside this container
126        parent.find('.sec0, .sec1, .sec2, .sec6').removeClass('active-step').hide();
127
128        // Dynamically hide/show any independent SSO widgets/divs on the page when moving past Step 0
129        if (stepIdx > 0) {
130            $('.sso-only-wrapper, .sso-divider, .google-micro').hide();
131        } else {
132            $('.sso-only-wrapper, .sso-divider, .google-micro').show();
133        }
134
135        // Dynamically handle column and widget layouts (Elementor, Gutenberg, etc.) to make Step 1+ full screen
136        const widget = parent.closest('.elementor-widget, .wp-block, [class*="widget"]');
137        const column = parent.closest('.elementor-column, .wp-block-column, .vc_column_container, [class*="column"], [class*="col-"]');
138        
139        if (stepIdx > 0) {
140            if (widget.length) {
141                // Find the top-most column to clean up the entire layout
142                const topColumns = parent.parents('.elementor-column, .wp-block-column');
143                const mainColumn = topColumns.length ? $(topColumns[topColumns.length - 1]) : column;
144                
145                mainColumn.find('.elementor-widget, .elementor-inner-section, .wp-block-heading, .wp-block-paragraph').each(function() {
146                    // Hide if it does not contain our form and is not the widget itself
147                    if (!$.contains(this, parent[0]) && this !== widget[0]) {
148                        $(this).addClass('onboarding-hidden-step').hide();
149                    }
150                });
151                widget.css({
152                    'background': 'transparent',
153                    'background-color': 'transparent',
154                    'box-shadow': 'none',
155                    'border': 'none',
156                    'padding': '0'
157                });
158            }
159            if (column.length) {
160                column.siblings().hide();
161                column.css({
162                    'width': '100%',
163                    'max-width': '100%',
164                    'flex': '0 0 100%',
165                    'background': 'transparent',
166                    'background-color': 'transparent',
167                    'box-shadow': 'none',
168                    'border': 'none',
169                    'padding': '0'
170                });
171            }
172            parent.find('.onboarding-logo-wrapper').show();
173            parent.addClass('onboarding-card-layout');
174        } else {
175            if (widget.length) {
176                const topColumns = parent.parents('.elementor-column, .wp-block-column');
177                const mainColumn = topColumns.length ? $(topColumns[topColumns.length - 1]) : column;
178                
179                mainColumn.find('.onboarding-hidden-step').removeClass('onboarding-hidden-step').show();
180                widget.css({
181                    'background': '',
182                    'background-color': '',
183                    'box-shadow': '',
184                    'border': '',
185                    'padding': ''
186                });
187            }
188            if (column.length) {
189                column.siblings().show();
190                column.css({
191                    'width': '',
192                    'max-width': '',
193                    'flex': '',
194                    'background': '',
195                    'background-color': '',
196                    'box-shadow': '',
197                    'border': '',
198                    'padding': ''
199                });
200            }
201            parent.find('.onboarding-logo-wrapper').hide();
202            parent.removeClass('onboarding-card-layout');
203        }
204
205        if (stepIdx === 0) {
206            parent.find('.sec0').addClass('active-step').show();
207        } else if (stepIdx === 1) {
208            parent.find('.sec1').addClass('active-step').show();
209        } else if (stepIdx === 2) {
210            parent.find('.sec2').addClass('active-step').show();
211            showWizardPane(activePane, parent);
212        } else if (stepIdx === 3) {
213            parent.find('.sec6').addClass('active-step').show();
214        }
215    }
216
217    // WIZARD PANES HANDLING (INSIDE STEP 2 / .sec2)
218    function showWizardPane(n, context) {
219        activePane = n;
220        const parent = context || $('.onboarding-container');
221
222        // Hide all panes
223        parent.find('.onboarding-pane, .pane').addClass('hidden').removeClass('show').attr('aria-hidden', 'true');
224
225        // Show pane
226        const targetPane = parent.find('#onboarding-step-' + n).length ? parent.find('#onboarding-step-' + n) : parent.find('#step-' + n);
227        targetPane.removeClass('hidden').addClass('show').attr('aria-hidden', 'false');
228
229        // Update progress bar width and indicators
230        updateOnboardingProgress(n, parent);
231
232        // Actions visibility
233        if (n === 1) {
234            parent.find('#backBtn').hide();
235        } else {
236            parent.find('#backBtn').show();
237        }
238
239        const topProgress = parent.find('.top-progress, #progress-bar-container');
240        if (n === 4 || n === 5) {
241            topProgress.hide();
242            parent.find('.actions').hide();
243        } else {
244            topProgress.show();
245            parent.find('.actions').show();
246        }
247
248        if (n === 4) {
249            parent.find('#nextBtn').text('Finish');
250        } else {
251            parent.find('#nextBtn').text('Continue');
252        }
253
254        validateCurrentPane(parent);
255        focusFirstField(parent);
256    }
257
258    function updateOnboardingProgress(paneIdx, parent) {
259        const parentContainer = parent || $('.onboarding-container');
260        const progressBar = parentContainer.find('#progress-bar')[0];
261        if (!progressBar) return;
262
263        // Pane 1 = 25%, Pane 2 = 50%, Pane 3 = 75%, Pane 4 = 100%
264        const widthPercent = Math.min((paneIdx / 4) * 100, 100);
265        progressBar.style.width = widthPercent + '%';
266
267        for (let i = 1; i <= 4; i++) {
268            const indicator = parentContainer.find('#dot-' + i);
269            if (indicator.length) {
270                indicator.removeClass('active completed');
271                if (i < paneIdx) {
272                    indicator.addClass('completed');
273                } else if (i === paneIdx) {
274                    indicator.addClass('active');
275                }
276            }
277        }
278    }
279
280    function focusFirstField(parent) {
281        const parentContainer = parent || $('.onboarding-container');
282        setTimeout(() => {
283            if (activePane === 1) parentContainer.find('#company').focus();
284            if (activePane === 2) parentContainer.find('#fullname').focus();
285            if (activePane === 3) parentContainer.find('#phone').focus();
286        }, 120);
287    }
288
289    function validateCurrentPane(parent) {
290        const parentContainer = parent || $('.onboarding-container');
291        let isValid = false;
292        if (activePane === 1) {
293            isValid = parentContainer.find('#company').val().trim().length > 0;
294        } else if (activePane === 2) {
295            isValid = parentContainer.find('#fullname').val().trim().length > 0;
296        } else if (activePane === 3) {
297            const phoneVal = parentContainer.find('#phone').val().replace(/\D/g, '');
298            const cc = parentContainer.find('#country').val();
299            let minLen = 6;
300            if (cc === '+91' || cc === '+1' || cc === '+44') minLen = 10;
301            if (cc === '+61') minLen = 9;
302            isValid = phoneVal.length >= minLen;
303        } else if (activePane === 4 || activePane === 5) {
304            isValid = true;
305        }
306        
307        toggleNextBtn(isValid, parentContainer);
308    }
309
310    function toggleNextBtn(enable, parent) {
311        const parentContainer = parent || $('.onboarding-container');
312        const nextBtn = parentContainer.find('#nextBtn');
313        if (enable) {
314            nextBtn.removeClass('disabled').removeAttr('aria-disabled').prop('disabled', false);
315        } else {
316            nextBtn.addClass('disabled').attr('aria-disabled', 'true').prop('disabled', true);
317        }
318    }
319
320    // Real-time wizard input tracking
321    $(document).on('input change', '#company, #fullname, #phone, #country', function () {
322        const onboardingContainer = $(this).closest('.onboarding-container');
323        try {
324            localStorage.setItem('wizard-company', onboardingContainer.find('#company').val());
325            localStorage.setItem('wizard-name', onboardingContainer.find('#fullname').val());
326            localStorage.setItem('wizard-phone', onboardingContainer.find('#phone').val());
327            localStorage.setItem('wizard-country', onboardingContainer.find('#country').val());
328        } catch (e) {}
329        validateCurrentPane(onboardingContainer);
330    });
331
332    // Format Phone input formatting (groups of digits)
333    $(document).on('input', '#phone', function (e) {
334        const onboardingContainer = $(this).closest('.onboarding-container');
335        const raw = e.target.value.replace(/[^\d]/g, '');
336        if (raw.length <= 3) {
337            e.target.value = raw;
338        } else if (raw.length <= 6) {
339            e.target.value = raw.slice(0, 3) + ' ' + raw.slice(3);
340        } else if (raw.length <= 10) {
341            e.target.value = raw.slice(0, 3) + ' ' + raw.slice(3, 6) + '-' + raw.slice(6);
342        } else {
343            e.target.value = raw;
344        }
345        validateCurrentPane(onboardingContainer);
346    });
347
348    // STEP 0: EMAIL SIGNUP ACTION
349    function validateEmail(emailVal) {
350        const trimmed = emailVal.trim();
351        if (trimmed === '') return 'Email is required.';
352        const pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
353        if (!pattern.test(trimmed)) return 'Please enter a valid email address.';
354        return null;
355    }
356
357    $(document).on('click', '#email_submit', function (e) {
358        e.preventDefault();
359        const onboardingContainer = $(this).closest('.onboarding-container');
360        const emailInput = onboardingContainer.find('#emailsignup');
361        const emailErr = validateEmail(emailInput.val());
362
363        if (emailErr !== null) {
364            emailInput.focus().css('border-color', '#e04444');
365            onboardingContainer.find("#invalid_message").html(emailErr).css('display', 'block');
366            return false;
367        }
368
369        if (!onboardingContainer.find('#acceptCheckbox').is(':checked')) {
370            onboardingContainer.find('#acceptCheckbox').focus();
371            onboardingContainer.find("#invalid_message").html('Please accept the Terms & Conditions before submitting.').css('display', 'block');
372            return false;
373        }
374
375        // Set email immediately in UI and storage to prevent dummy email display
376        setOnboardingEmail(emailInput.val());
377        $('[id="emailaddress"]').text(emailInput.val());
378
379        emailInput.css('border-color', '#28a745');
380        onboardingContainer.find("#invalid_message").css('display', 'none');
381
382        // Show spinner inside button
383        const submitBtn = $(this);
384        const origText = submitBtn.html();
385        submitBtn.prop('disabled', true).html('Processing... <span class="spinner-icon"></span>');
386
387        $.ajax({
388            type: 'POST',
389            url: ajaxurl,
390            data: {
391                action: 'onboarding_verify_email',
392                email: emailInput.val(),
393                utm_source: onboardingContainer.find('#utm_source').val() || 'SEO',
394                to_email_ids: onboardingContainer.find('#toEmailiIds').val() || '[email protected],[email protected]',
395                security: ajax_nonce
396            },
397            success: function (response) {
398                if (typeof response === 'string') {
399                    try { response = JSON.parse(response); } catch(e) {}
400                }
401                if (response && response.success === false) {
402                    submitBtn.prop('disabled', false).html(origText);
403                    let errMsg = response.data;
404                    if (response.appendCheck === true) {
405                        errMsg += '&nbsp;<a href="https://app.mera.work/">Click Here</a> to log in.';
406                    }
407                    onboardingContainer.find("#invalid_message").html(errMsg).css('display', 'block');
408                } else if (response && response.success === true) {
409                    setOnboardingEmail(emailInput.val());
410                    $('[id="emailaddress"]').text(emailInput.val());
411                    
412                    // Proceed to OTP Verify
413                    showFormStep(1, onboardingContainer);
414                } else {
415                    // Fallback
416                    setOnboardingEmail(emailInput.val());
417                    $('[id="emailaddress"]').text(emailInput.val());
418                    showFormStep(1, onboardingContainer);
419                }
420            },
421            error: function () {
422                submitBtn.prop('disabled', false).html(origText);
423                onboardingContainer.find("#invalid_message").html('Unable to verify email. Please try again.').css('display', 'block');
424            }
425        });
426    });
427
428    // Click on Edit Email to return to Step 0
429    $(document).on('click', '.edit-email-btn', function (e) {
430        e.preventDefault();
431        const onboardingContainer = $(this).closest('.onboarding-container');
432        showFormStep(0, onboardingContainer);
433        onboardingContainer.find('#emailsignup').focus();
434    });
435
436    // STEP 1: OTP CODE ACTION
437    $('.email-otp-input').removeAttr('min').removeAttr('max');
438
439    // Handle shift focus on typing code
440    $(document).on('input', '.email-otp-input', function () {
441        const $this = $(this);
442        let val = $this.val();
443        
444        if (val.length > 1) {
445            $this.val(val.slice(0, 1));
446        }
447
448        if ($this.val().length === 1) {
449            $this.closest('span').nextAll().find('.email-otp-input').first().focus();
450        }
451
452        // Validate all filled
453        let allFilled = true;
454        const container = $this.closest('.twostep');
455        container.find('.email-otp-input').each(function () {
456            if ($(this).val() === '') {
457                allFilled = false;
458                return false;
459            }
460        });
461
462        if (allFilled) {
463            container.find('#errormessage1').html('');
464            // Trigger automatic submit when final digit entered
465            container.find('#otp-submit').trigger('click');
466        }
467    });
468
469    // Backspace OTP
470    $(document).on('keydown', '.email-otp-input', function (e) {
471        if (e.key === 'Backspace') {
472            const $this = $(this);
473            const prevInput = $this.closest('span').prevAll().find('.email-otp-input').first();
474
475            if ($this.val() === '') {
476                if (prevInput.length > 0) {
477                    prevInput.focus().val('');
478                }
479            } else {
480                $this.val('');
481                if (prevInput.length > 0) {
482                    prevInput.focus();
483                }
484                e.preventDefault();
485            }
486        }
487    });
488
489    // Submit OTP Code
490    $(document).on('click', '#otp-submit', function (e) {
491        e.preventDefault();
492        let otpCode = '';
493        let allFilled = true;
494        
495        const container = $(this).closest('.twostep');
496        const onboardingContainer = $(this).closest('.onboarding-container');
497        const inputs = container.find('.email-otp-input');
498
499        inputs.each(function () {
500            if ($(this).val().length === 0) {
501                allFilled = false;
502                return false;
503            }
504            otpCode += $(this).val();
505        });
506
507        if (!allFilled) {
508            container.find('#errormessage1').html('Please enter all four digits of the OTP.');
509            return;
510        }
511
512        container.find('#errormessage1').html('');
513        const submitBtn = $(this);
514        submitBtn.prop('disabled', true).text('Verifying...');
515        const email = onboardingContainer.find('#emailsignup').val()?.trim() || getOnboardingEmail().trim() || '';
516
517        $.ajax({
518            url: ajaxurl,
519            type: 'POST',
520            data: {
521                action: 'onboarding_verify_code',
522                otp_code: otpCode,
523                email: email,
524                security: ajax_nonce
525            },
526            success: function (response) {
527                if (typeof response === 'string') {
528                    try { response = JSON.parse(response); } catch(e) {}
529                }
530                submitBtn.prop('disabled', false).text('Submit');
531                if (response && response.success && response.data && response.data.trim() === 'Valid Code') {
532                    // Pre-populate fields derived from email safely
533                    if (email && email.indexOf('@') !== -1) {
534                        const parts = email.split('@');
535                        const namePart = parts[0].replace(/[0-9]/g, '');
536                        const domain = parts[1] || '';
537                        const companyName = domain.split('.')[0] || '';
538                        
539                        onboardingContainer.find('#company').val(companyName).trigger('input');
540                        onboardingContainer.find('#fullname').val(namePart).trigger('input');
541                    }
542
543                    // Proceed to Profile Wizard (Step 2, Pane 1)
544                    showFormStep(2, onboardingContainer);
545                } else {
546                    const errMsg = response ? (response.data || 'Invalid Verification Code.') : 'Invalid Verification Code.';
547                    container.find('#errormessage1').html(errMsg);
548                }
549            },
550            error: function () {
551                submitBtn.prop('disabled', false).text('Submit');
552                container.find('#errormessage1').html('An error occurred. Please try again.');
553            }
554        });
555    });
556
557    // Resend OTP Code via Mail
558    $(document).on('click', '#resend-verification-otp-2', function (e) {
559        e.preventDefault();
560        const container = $(this).closest('.twostep');
561        const onboardingContainer = $(this).closest('.onboarding-container');
562        container.find('#errormessage1').html('');
563        container.find('.email-otp-input').val('');
564
565        const email = onboardingContainer.find('#emailsignup').val()?.trim() || getOnboardingEmail().trim() || '';
566
567        $.ajax({
568            url: ajaxurl,
569            type: 'POST',
570            dataType: 'json',
571            data: {
572                action: 'resend_verification_email',
573                email: email,
574                security: ajax_nonce
575            },
576            success: function (response) {
577                if (typeof response === 'string') {
578                    try { response = JSON.parse(response); } catch(e) {}
579                }
580                if (response && response.success) {
581                    container.find('#errormessage1').html('<span style="color:green;">OTP sent successfully.</span>');
582                } else {
583                    const errMsg = response ? (response.data || 'Failed to resend verification email.') : 'Failed to resend verification email.';
584                    container.find('#errormessage1').html(errMsg);
585                }
586            },
587            error: function () {
588                container.find('#errormessage1').html('An error occurred. Please try again.');
589            }
590        });
591    });
592
593    // STEP 2: PROFILE WIZARD ACTION (NEXT & BACK)
594    $(document).on('click', '#backBtn', function () {
595        const onboardingContainer = $(this).closest('.onboarding-container');
596        if (activePane <= 1) {
597            showFormStep(1, onboardingContainer); // Go back to OTP verification
598        } else {
599            showWizardPane(activePane - 1, onboardingContainer);
600        }
601    });
602
603    $(document).on('click', '#nextBtn', function (e) {
604        e.preventDefault();
605        if ($(this).hasClass('disabled') || $(this).prop('disabled')) return;
606        const onboardingContainer = $(this).closest('.onboarding-container');
607
608        if (activePane === 1) {
609            // Check Organization Existence securely via Server-Side AJAX
610            const companyName = onboardingContainer.find('#company').val().trim();
611            const checkBtn = $(this);
612            const origText = checkBtn.text();
613            
614            checkBtn.prop('disabled', true).addClass('disabled').text('Checking...');
615
616            $.ajax({
617                type: 'POST',
618                url: ajaxurl,
619                dataType: 'json',
620                data: {
621                    action: 'onboarding_check_company_existence',
622                    company_name: companyName,
623                    security: ajax_nonce
624                },
625                success: function (response) {
626                    if (typeof response === 'string') {
627                        try { response = JSON.parse(response); } catch(e) {}
628                    }
629                    checkBtn.prop('disabled', false).removeClass('disabled').text(origText);
630                    if (response && response.success === true && response.data && response.data.exists === true) {
631                        onboardingContainer.find("#team_invalid").html('Organization name already exists!').css('display', 'block');
632                    } else {
633                        onboardingContainer.find("#team_invalid").css('display', 'none');
634                        showWizardPane(2, onboardingContainer);
635                    }
636                },
637                error: function () {
638                    checkBtn.prop('disabled', false).removeClass('disabled').text(origText);
639                    // Fail-safe: let user proceed if API validation is down
640                    showWizardPane(2, onboardingContainer);
641                }
642            });
643
644        } else if (activePane === 2) {
645            showWizardPane(3, onboardingContainer);
646        } else if (activePane === 3) {
647            // Transition to loading step (Pane 4) and run submission
648            showWizardPane(4, onboardingContainer);
649            submitCompanyRegistration(onboardingContainer);
650        }
651    });
652
653    // Keyboard navigation (Enter key triggers wizard navigation)
654    document.addEventListener('keydown', (e) => {
655        if (e.key === 'Enter' && currentStep === 2) {
656            const nextBtn = document.getElementById('nextBtn');
657            if (nextBtn && !nextBtn.disabled && $('.actions').is(':visible')) {
658                nextBtn.click();
659            }
660        }
661    });
662
663    // Account Creation Submission Action
664    function submitCompanyRegistration(parent) {
665        const onboardingContainer = parent || $('.onboarding-container');
666        const companyName = onboardingContainer.find('#company').val().trim();
667        const fullname = onboardingContainer.find('#fullname').val().trim();
668        const phone = onboardingContainer.find('#phone').val().trim();
669        const email = onboardingContainer.find('#emailsignup').val()?.trim() || getOnboardingEmail().trim() || '';
670        const toEmailiIds = onboardingContainer.find('#toEmailiIds').val();
671        const utm_source = onboardingContainer.find('#utm_source').val();
672        const subject = onboardingContainer.find('#subject').val();
673
674        // Run simulation animation
675        let progress = 0;
676        const progressFill = onboardingContainer.find('#setupProgress')[0];
677        if (progressFill) progressFill.style.width = '0%';
678        
679        const simInterval = setInterval(() => {
680            const jump = Math.random() * 12 + 6;
681            progress = Math.min(95, progress + jump); // cap at 95% until AJAX response
682            if (progressFill) progressFill.style.width = progress + '%';
683        }, 300);
684
685        $.ajax({
686            type: 'POST',
687            url: ajaxurl,
688            data: {
689                action: 'onboarding_company',
690                email: email,
691                name: fullname,
692                orgName: companyName,
693                to_email_ids: toEmailiIds,
694                subject: subject,
695                utm_source: utm_source,
696                phoneno: phone,
697                security: ajax_nonce
698            },
699            success: function (response) {
700                if (typeof response === 'string') {
701                    try { response = JSON.parse(response); } catch(e) {}
702                }
703                clearInterval(simInterval);
704                if (response && response.success === false) {
705                    // Send back to Pane 1 to display error
706                    showWizardPane(1, onboardingContainer);
707                    let err = response.data;
708                    if (response.appendCheck === true) {
709                        err += '&nbsp;<a href="https://app.mera.work/">Click Here</a> to log in.';
710                    }
711                    onboardingContainer.find("#team_invalid").html(err).
711css('display', 'block');
712                } else if (response && response.success === true) {
713                    // Complete progress bar immediately
714                    if (progressFill) progressFill.style.width = '100%';
715                    setTimeout(() => {
716                        // Go directly to Password Set (Step 3) instead of welcome screen
717                        showFormStep(3, onboardingContainer);
718                        validatePasswordUI(onboardingContainer.find('.password-set'));
719                    }, 500);
720                } else {
721                    // Fallback success
722                    if (progressFill) progressFill.style.width = '100%';
723                    setTimeout(() => {
724                        showFormStep(3, onboardingContainer);
725                        validatePasswordUI(onboardingContainer.find('.password-set'));
726                    }, 500);
727                }
728            },
729            error: function () {
730                clearInterval(simInterval);
731                showWizardPane(1, onboardingContainer);
732                onboardingContainer.find("#team_invalid").html('An error occurred during setup. Please try again.').css('display', 'block');
733            }
734        });
735    }
736
737    // Step 5 (Welcome) -> Click "Let's Begin" to transition to Password Set Step (Step 3)
738    $(document).on('click', '#getStarted', function (e) {
739        e.preventDefault();
740        const onboardingContainer = $(this).closest('.onboarding-container');
741        showFormStep(3, onboardingContainer);
742        validatePasswordUI(onboardingContainer.find('.password-set'));
743    });
744
745    // STEP 3: SET PASSWORD ACTION
746    const hasNumber = s => /\d/.test(s);
747    const hasSpecial = s => /[^A-Za-z0-9]/.test(s);
748    const minLen = s => s.length >= 8;
749
750    let pwTouched = false;
751    let confirmTouched = false;
752
753    function validatePasswordUI(container) {
754        const pwInput = container.find('#password');
755        const submitBtn = container.find('#submitBtn');
756        const confirmError = container.find('#confirmError');
757        
758        const ruleLength = container.find('#rule-length');
759        const ruleNumber = container.find('#rule-number');
760        const ruleSpecial = container.find('#rule-special');
761
762        if (pwInput.length === 0) return;
763        const val = pwInput.val() || '';
764        
765        const okLen = minLen(val);
766        const okNum = hasNumber(val);
767        const okSpec = hasSpecial(val);
768
769        if (okLen) ruleLength.addClass('valid'); else ruleLength.removeClass('valid');
770        if (okNum) ruleNumber.addClass('valid'); else ruleNumber.removeClass('valid');
771        if (okSpec) ruleSpecial.addClass('valid'); else ruleSpecial.removeClass('valid');
772
773        if (val === '') {
774            pwInput.removeClass('input-invalid').addClass('input-default');
775        } else {
776            if (okLen && okNum && okSpec) {
777                pwInput.removeClass('input-invalid').addClass('input-default');
778            } else if (pwTouched) {
779                pwInput.addClass('input-invalid').removeClass('input-default');
780            }
781        }
782
783        if (okLen && okNum && okSpec) {
784            submitBtn.prop('disabled', false).removeAttr('disabled');
785        } else {
786            submitBtn.prop('disabled', true).attr('disabled', 'disabled');
787        }
788
789        checkConfirmPassword(container);
790    }
791
792    function checkConfirmPassword(container) {
793        const pwInput = container.find('#password');
794        const confirmInput = container.find('#confirm');
795        const confirmError = container.find('#confirmError');
796
797        if (confirmInput.length === 0 || pwInput.length === 0) return;
798        const p = pwInput.val() || '';
799        const c = confirmInput.val() || '';
800        
801        const mainGood = minLen(p) && hasNumber(p) && hasSpecial(p);
802
803        if (c === '') {
804            confirmInput.removeClass('input-invalid').addClass('input-default');
805            confirmError.hide();
806            return;
807        }
808
809        if (mainGood && c !== p) {
810            confirmInput.addClass('input-invalid').removeClass('input-default');
811            confirmError.show();
812        } else {
813            confirmInput.removeClass('input-invalid').addClass('input-default');
814            confirmError.hide();
815        }
816    }
817
818    // Bind event handlers dynamically using document delegation
819    $(document).on('input', '#password', function () {
820        const container = $(this).closest('.password-set');
821        validatePasswordUI(container);
822    });
823
824    $(document).on('blur', '#password', function () {
825        pwTouched = true;
826        const container = $(this).closest('.password-set');
827        validatePasswordUI(container);
828    });
829
830    $(document).on('input', '#confirm', function () {
831        confirmTouched = true;
832        const container = $(this).closest('.password-set');
833        checkConfirmPassword(container);
834    });
835
836    $(document).on('blur', '#confirm', function () {
837        confirmTouched = true;
838        const container = $(this).closest('.password-set');
839        checkConfirmPassword(container);
840    });
841
842    // Password Show/Hide Toggle
843    $(document).on('click', '#togglePwd', function () {
844        const container = $(this).closest('.password-set');
845        const input = container.find('#password');
846        const type = input.attr('type') === 'password' ? 'text' : 'password';
847        input.attr('type', type);
848        $(this).attr('aria-pressed', type === 'text');
849    });
850
851    $(document).on('click', '#toggleConfirm', function () {
852        const container = $(this).closest('.password-set');
853        const input = container.find('#confirm');
854        const type = input.attr('type') === 'password' ? 'text' : 'password';
855        input.attr('type', type);
856        $(this).attr('aria-pressed', type === 'text');
857    });
858
859    // Submit Set Password Form
860    $(document).on('click', '#submitBtn', function (e) {
861        e.preventDefault();
862        console.log("Set Password button clicked");
863        const container = $(this).closest('.password-set');
864        const onboardingContainer = $(this).closest('.onboarding-container');
865        validatePasswordUI(container);
866
867        const pass = container.find('#password').val();
868        const cpass = container.find('#confirm').val();
869        const email = ((onboardingContainer.find('#emailsignup').val() || '').trim()) || (getOnboardingEmail().trim());
870
871        console.log("Submit password fields extracted:", { has_pass: !!pass, has_cpass: !!cpass, email: email });
872
873        if (pass !== cpass) {
874            console.log("Passwords do not match error");
875            container.find('#pass_invalid').show().html('Passwords do not match');
876            return;
877        }
878
879        const valid = minLen(pass) && hasNumber(pass) && hasSpecial(pass);
880        console.log("Password valid state:", valid);
881        if (!valid) return;
882
883        console.log("Triggering onboarding_send_pass AJAX request to:", ajaxurl);
884
885        $.ajax({
886            type: 'POST',
887            url: ajaxurl,
888            data: {
889                action: 'onboarding_send_pass',
890                pass: pass,
891                cpass: cpass,
892                email: email,
893                security: ajax_nonce
894            },
895            beforeSend: function () {
896                console.log("AJAX request beforeSend started");
897                container.find('#submitBtn').prop('disabled', true).text('⏳ Processing... Please wait');
898            },
899            success: function (response) {
900                if (typeof response === 'string') {
901                    try { response = JSON.parse(response); } catch(e) {}
902                }
903                console.log("AJAX request success. Response received:", response);
904                if (response && response.success === false) {
905                    container.find('#submitBtn').prop('disabled', false).text('Set Password & Go to Dashboard');
906                    const errStr = (response.data || 'Failed to register.') + '&nbsp;<a href="https://app.mera.work/">Click Here</a> to log in.';
907                    container.find('#confirmError').show();
908                    container.find('#confirmError span:first').hide();
909                    container.find('#pass_invalid').show().html(errStr);
910                } else if (response && response.success === true) {
911                    container.find('#submitBtn').prop('disabled', true).text('🚀 Hold on... Redirecting to dashboard');
912                    
913                    // Show final loader animation pane
914                    showFormStep(2, onboardingContainer);
915                    showWizardPane(4, onboardingContainer);
916                    
917                    // Tracker
918                    console.log("Email:", email);
919                    try {
920                        gr('track', 'conversion', { email: email });
921                    } catch(e) {}
922                    
923                    setTimeout(function () {
924                        // Clear storage variables
925                        removeOnboardingEmail();
926                        try {
927                            localStorage.removeItem('wizard-company');
928                            localStorage.removeItem('wizard-name');
929                            localStorage.removeItem('wizard-phone');
930                            localStorage.removeItem('wizard-country');
931                        } catch (e) {}
932
933                        // Redirect to the dashboard auto-login URL
934                        window.location.href = response.data;
935                    }, 1200);
936                } else {
937                    container.find('#submitBtn').prop('disabled', false).text('Set Password & Go to Dashboard');
938                    container.find('#pass_invalid').show().html('Something went wrong. Please try again.');
939                }
940            },
941            error: function (xhr, status, error) {
942                console.log("AJAX request failed:", { status: status, error: error, response: xhr.responseText });
943                container.find('#submitBtn').prop('disabled', false).text('Set Password & Go to Dashboard');
944                container.find('#confirmError').show();
945                container.find('#pass_invalid').show().html('Something went wrong. Please try again.');
946            }
947        });
948    });
949
950    // SSO LOGIN BUTTONS TRIGGER
951    $(document).on('click', '.g-btn', function () {
952        window.location.href = ajaxurl + '?action=google_login';
953    });
954
955    $(document).on('click', '.m-btn', function () {
956        window.location.href = ajaxurl + '?action=microsoft_login';
957    });
958
959    // INITIAL SHOW FOR ALL CONTAINERS
960    $('.onboarding-container').each(function() {
961        showFormStep(0, $(this));
962    });
963});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.