PageSourceSearch

https://www.espm.br/wp-content/plugins/espminscricoes/assets/js/aviseme.js?ver=1.2.1

js espm.br collected 2026-09-24 08:53:14 UTC 9,626 bytes, 237 lines download raw bytes

1/**
2 * ESPM Avise-me — Modal único (extensão → API EC; graduação/tecnólogo/pós → HubSpot, decidido no servidor)
3 * 
4 * Substitui os popups Elementor/HubSpot por formulário inline que
5 * envia dados diretamente para a API EC via REST endpoint do WordPress.
6 * 
7 * Expõe: window.abrirModalAviseMe() — chamado por todos os módulos
8 * Requer: ESPM_AVISEME (injetado via wp_localize_script)
9 */
10(function() {
11    'use strict';
12
13    // Configuração injetada pelo PHP
14    var CONFIG = (typeof ESPM_AVISEME !== 'undefined') ? ESPM_AVISEME : {};
15    var modalAberto = false;
16
17    /**
18     * Aplica máscara de telefone: (DD) 99999-9999
19     */
20    function mascaraTelefone(valor) {
21        var nums = valor.replace(/\D/g, '').substring(0, 11);
22        if (nums.length === 0) return '';
23        if (nums.length <= 2) return '(' + nums;
24        if (nums.length <= 7) return '(' + nums.substring(0, 2) + ') ' + nums.substring(2);
25        return '(' + nums.substring(0, 2) + ') ' + nums.substring(2, 7) + '-' + nums.substring(7);
26    }
27
28    /**
29     * Remove máscara — retorna só dígitos
30     */
31    function limparTelefone(valor) {
32        return valor.replace(/\D/g, '');
33    }
34
35    /**
36     * Valida formato de e-mail
37     */
38    function validarEmail(email) {
39        return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
40    }
41
42    /**
43     * Cria e exibe o modal do Avise-me
44     * @param {string|number} [oferecidoId] - SKU da variação (oferecido_id na API EC). Se omitido, usa CONFIG.oferecidoId.
45     */
46    function abrirModalAviseMe(oferecidoId) {
47        if (modalAberto) return;
48        modalAberto = true;
49
50        // oferecido_id: parâmetro dinâmico (SKU) > config PHP
51        var idFinal = oferecidoId || CONFIG.oferecidoId || '';
52
53        // Remove modal anterior se existir
54        var existente = document.getElementById('espm-aviseme-modal');
55        if (existente) existente.remove();
56
57        var modal = document.createElement('div');
58        modal.id = 'espm-aviseme-modal';
59        modal.className = 'espm-aviseme-overlay';
60        modal.innerHTML =
61            '<div class="espm-aviseme-container">' +
62                '<button type="button" class="espm-aviseme-fechar" aria-label="Fechar">&times;</button>' +
63                '<h3 class="espm-aviseme-titulo">Avise-me quando abrir</h3>' +
64                '<p class="espm-aviseme-subtitulo">' + (CONFIG.nomeProduto || 'Este curso') + '</p>' +
65                '<form id="espm-aviseme-form" class="espm-aviseme-form">' +
66                    '<input type="hidden" name="oferecido_id" value="' + idFinal + '">' +
67                    '<input type="hidden" name="produto_id" value="' + (CONFIG.produtoId || '') + '">' +
68                    '<input type="hidden" name="url" value="' + window.location.href + '">' +
69                    '<div class="espm-aviseme-campo">' +
70                        '<input type="text" name="nome" placeholder="Nome *" required autocomplete="given-name">' +
71                    '</div>' +
72                    '<div class="espm-aviseme-campo">' +
73                        '<input type="text" name="sobrenome" placeholder="Sobrenome *" required autocomplete="family-name">' +
74                    '</div>' +
75                    '<div class="espm-aviseme-campo">' +
76                        '<input type="email" name="email" placeholder="E-mail *" required autocomplete="email">' +
77                    '</div>' +
78                    '<div class="espm-aviseme-campo">' +
79                        '<input type="tel" name="telefone" placeholder="Telefone (opcional)" autocomplete="tel">' +
80                    '</div>' +
81                    '<button type="submit" class="espm-aviseme-enviar">Quero ser avisado</button>' +
82                    '<div id="espm-aviseme-msg" class="espm-aviseme-msg" style="display:none;"></div>' +
83                '</form>' +
84            '</div>';
85
86        document.body.appendChild(modal);
87
88        // Fechar ao clicar no X
89        modal.querySelector('.espm-aviseme-fechar').addEventListener('click', fecharModalAviseMe);
90
91        // Fechar ao clicar no overlay
92        modal.addEventListener('click', function(e) {
93            if (e.target === modal) fecharModalAviseMe();
94        });
95
96        // Fechar com ESC
97        function escHandler(e) {
98            if (e.key === 'Escape') {
99                fecharModalAviseMe();
100                document.removeEventListener('keydown', escHandler);
101            }
102        }
103        document.addEventListener('keydown', escHandler);
104
105        // Máscara de telefone
106        var telInput = modal.querySelector('input[name="telefone"]');
107        telInput.addEventListener('input', function() {
108            var pos = this.selectionStart;
109            var antes = this.value.length;
110            this.value = mascaraTelefone(this.value);
111            var depois = this.value.length;
112            this.setSelectionRange(pos + (depois - antes), pos + (depois - antes));
113        });
114
115        // Submit do formulário
116        modal.querySelector('#espm-aviseme-form').addEventListener('submit', function(e) {
117            e.preventDefault();
118            enviarFormularioAviseMe(this);
119        });
120
121        // Animação de entrada
122        requestAnimationFrame(function() {
123            modal.classList.add('espm-aviseme-visivel');
124        });
125
126        // console.log('[ESPM AVISE-ME] Modal aberto | oferecido_id:', idFinal, '| produto:', CONFIG.nomeProduto);
127    }
128
129    /**
130     * Fecha o modal com animação
131     */
132    function fecharModalAviseMe() {
133        var modal = document.getElementById('espm-aviseme-modal');
134        if (modal) {
135            modal.classList.remove('espm-aviseme-visivel');
136            setTimeout(function() {
137                modal.remove();
138                modalAberto = false;
139            }, 300);
140        } else {
141            modalAberto = false;
142        }
143    }
144
145    /**
146     * Envia o formulário para o REST endpoint
147     */
148    function enviarFormularioAviseMe(form) {
149        var btn = form.querySelector('.espm-aviseme-enviar');
150        var msgEl = form.querySelector('#espm-aviseme-msg');
151        var textoOriginal = btn.textContent;
152
153        // Validação de e-mail
154        var emailInput = form.querySelector('input[name="email"]');
155        if (!validarEmail(emailInput.value)) {
156            msgEl.className = 'espm-aviseme-msg espm-aviseme-erro';
157            msgEl.textContent = 'Por favor, informe um e-mail válido.';
158            msgEl.style.display = 'block';
159            emailInput.focus();
160            return;
161        }
162
163        btn.textContent = 'Enviando...';
164        btn.disabled = true;
165        msgEl.style.display = 'none';
166
167        // Coleta dados do formulário
168        var dados = {};
169        var inputs = form.querySelectorAll('input');
170        for (var i = 0; i < inputs.length; i++) {
171            if (inputs[i].name) {
172                dados[inputs[i].name] = inputs[i].value;
173            }
174        }
175
176        // Variação escolhida no form do Woo (campus/período/formato são lidos dela no servidor).
177        // O template repete o form (desktop/mobile/flutuante): vale o primeiro com variação escolhida.
178        var variacoes = document.querySelectorAll('form.variations_form input[name="variation_id"]');
179        for (var v = 0; v < variacoes.length; v++) {
180            if (variacoes[v].value && variacoes[v].value !== '0') {
181                dados.variacao_id = variacoes[v].value;
182                break;
183            }
184        }
185
186        // Remove máscara do telefone antes de enviar
187        if (dados.telefone) {
188            dados.telefone = limparTelefone(dados.telefone);
189        }
190
191        // console.group('[ESPM AVISE-ME] Enviando formulário');
192        // console.log('Endpoint:', CONFIG.restUrl);
193        // console.log('Dados:', dados);
194
195        fetch(CONFIG.restUrl, {
196            method: 'POST',
197            credentials: 'same-origin',
198            headers: { 'Content-Type': 'application/json' },
199            body: JSON.stringify(dados)
200        })
201        .then(function(res) { return res.json(); })
202        .then(function(data) {
203            // console.log('Resposta:', data);
204            // console.groupEnd();
205
206            if (data.sucesso) {
207                msgEl.className = 'espm-aviseme-msg espm-aviseme-sucesso';
208                msgEl.textContent = data.mensagem || 'Cadastro realizado com sucesso!';
209                msgEl.style.display = 'block';
210
211                // Fecha modal após 2.5s
212                setTimeout(fecharModalAviseMe, 2500);
213            } else {
214                msgEl.className = 'espm-aviseme-msg espm-aviseme-erro';
215                msgEl.textContent = data.mensagem || 'Erro ao enviar. Tente novamente.';
216                msgEl.style.display = 'block';
217                btn.textContent = textoOriginal;
218                btn.disabled = false;
219            }
220        })
221        .catch(function(err) {
222            // console.error('[ESPM AVISE-ME] Erro:', err);
223            // console.groupEnd();
224
225            msgEl.className = 'espm-aviseme-msg espm-aviseme-erro';
226            msgEl.textContent = 'Erro de conexão. Tente novamente.';
227            msgEl.style.display = 'block';
228            btn.textContent = textoOriginal;
229            btn.disabled = false;
230        });
231    }
232
233    // Expõe globalmente para todos os módulos
234    window.abrirModalAviseMe = abrirModalAviseMe;
235    window.fecharModalAviseMe = fecharModalAviseMe;
236
237})();

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.