const StepDisplay =['Zipcode','customerStep-9','customerStep-10','Address','Details','Username','Verify','End']; const cssLoad= `.appActive {display: flex;justify-content: center;align-items: center;position: fixed; top:0px; left:0px; width: 100%;height: 100%;background: #fff;z-index: 9999;}.loadingRoofCal{position:relative;margin: auto;top:0;left:0;right:0;bottom:0;background-color:transparent;display:none;justify-content:center;align-items:center;z-index:9999;transition:1s all;}.loadingRoofCal.show{display:flex}.loadingRoofCal .spin{border:3px solid hsla(185,100%,62%,.2);border-top-color:#019720;background-color:transparent!important;border-radius:50%;width:3em;height:3em;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.btnNone{display: none;}.navRoofCal{display: none;}#btnOpenRoofCal {box-sizing: border-box;padding: 5px 8px;color: #555;background-color: #fff;border: 1px solid #ccc;border-radius: 4px;font-size: 16px;font-family: Nunito, sans-serif;}.headRoofCal {position: relative;width: 100%;min-height: 50px;}.sectBtnClose {position: absolute;right: 20px;top: 10px;}button.btnCloseIcon {background-color: transparent;color: #D81E1E;font-size: 32px;font-weight: bold;box-sizing: border-box;border: 1px solid #D81E1E;border-radius: 4px;padding: 0px 12px;cursor: pointer;font-family: Nunito, sans-serif;}#errorReload{display:none;}`; const textBtnMain= `RoofCal Estimate`; const urlLogo= `https://marketeaaccounts.com/media/100582/420/roofcal/`; const imgLogo= ``; const desc_company= ``; const user_id = "100582"; const org_id = "420"; const site = "amazingmetalroofing.com"; const ip = "216.73.216.31"; const ip_info = JSON.parse('{"status":"success","country":"United States","countryCode":"US","region":"OH","regionName":"Ohio","city":"Columbus","zip":"43215","lat":39.96249999999999857891452847979962825775146484375,"lon":-83.00610000000000354702933691442012786865234375,"timezone":"America\/New_York","isp":"Amazon.com","org":"Anthropic, PBC","as":"AS16509 Amazon.com, Inc.","query":"216.73.216.31"}'); const consultaApiIp = "1"; const idsesion = "608263"; const urlSession = "https://marketeaaccounts.com/api/roofcal/sendids/1743917214306"; const urlStep = "https://marketeaaccounts.com/api/roofcal/step"; const allZip = "0"; const cssMain="https://marketeaaccounts.com/api/roofcal/maincss/1743917214306"; const btnIframeCSS="https://marketeaaccounts.com/api/roofcal/btnIframeCSS/1743917214306"; const redirect = "0"; const urlSendcode = "https://marketeaaccounts.com/api/roofcal/sendvalidcode"; const opt = "1"; const uri = ""; const time = "25000"; const zip = ['01757'];// creando html var divBase = document.querySelector("#" + appRoofCal); divBase.classList.add('appRoofCal'); divBase.style.display = 'none'; // btn princial var btnOpenRoofCal = document.createElement('button'); btnOpenRoofCal.type = "button"; btnOpenRoofCal.id = `btnOpenRoofCal`; btnOpenRoofCal.classList.add('btnOpenRoofCal'); var htmlBtn = ` `; htmlBtn += `` + textBtnMain + ``; htmlBtn += ` `; btnOpenRoofCal.innerHTML = htmlBtn; divBase.appendChild(btnOpenRoofCal); // creando iframe con widget var iframeLoad; let iframeReady; // agregando html al iframe var htmlDivMain = `
`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += `Failed to load, try again with reload.`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += `
`; /* htmlDivMain += ``; htmlDivMain += ``; */ function initIframe() { let resolveReady; iframeReady = new Promise(resolve => { resolveReady = resolve; }); var iframeRoof = document.createElement('iframe'); iframeRoof.id = 'iframeRoof'; iframeRoof.classList.add('iframeRoof', 'roofHide'); let divBase = document.querySelector("#" + appRoofCal); if (divBase) { divBase.appendChild(iframeRoof); iframeRoof.onload = function () { iframeLoad = iframeRoof.contentDocument || iframeRoof.contentWindow.document; // Marca que el iframe está listo resolveReady(); }; iframeRoof.src = 'about:blank'; } } // Funciones globales para seleccionar dentro del iframe // qIframe y qAll esperan a que el iframe esté listo function qIframe(selector) { return iframeReady.then(() => iframeLoad.querySelector(selector)); } function qAllIframe(selector) { return iframeReady.then(() => iframeLoad.querySelectorAll(selector)); } function qValue(selector) { if (iframeReady) { return iframeLoad.querySelector(selector); } console.warn(`⚠ qValue("${selector}") llamado antes de que el iframe esté listo. Se devolverá null por ahora.`); return null; // o podrías devolver un objeto vacío si prefieres } // Función para agregar contenido seguro function addToIframe(html) { iframeReady.then(() => { iframeLoad.body.append(html); }); } // Ejemplos de uso (pueden ejecutarse antes o después de onload) // addToIframe(htmlDivMain); // addToIframe("

Contenido posterior

"); // qIframe('#miElemento').then(el => { if (el) el.innerHTML = 'Texto modificado automáticamente'; }); // qAllIframe('.opcion').then(elements => { elements.forEach(el => el.style.color = 'blue'); }); // qIframe('.miElemento').then(el => { if (el) el.classList.add('activo'); }); // qAllIframe('.opcion').then(elements => { elements.forEach(el => el.style.color = 'red');}); // 📌 Obtener info completa del navegador, SO y dispositivo function getSystemInfo() { const ua = navigator.userAgent; const vendor = navigator.vendor || ""; const lowerUA = ua.toLowerCase(); // --- Detectar Sistema Operativo y versión --- let os = "Sistema Operativo desconocido"; let osVersion = "Versión desconocida"; if (/windows nt/i.test(ua)) { os = "Windows"; const match = ua.match(/Windows NT ([0-9.]+)/i); if (match) { const versions = { "10.0": "10 / 11", "6.3": "8.1", "6.2": "8", "6.1": "7", "6.0": "Vista", "5.1": "XP" }; osVersion = versions[match[1]] || match[1]; } } else if (/android/i.test(ua)) { os = "Android"; const match = ua.match(/Android ([0-9.]+)/i); if (match) osVersion = match[1]; } else if (/mac os x/i.test(ua) && !/iphone|ipad|ipod/i.test(ua)) { os = "MacOS"; const match = ua.match(/Mac OS X ([0-9_]+)/i); if (match) osVersion = match[1].replace(/_/g, "."); } else if (/iphone|ipad|ipod/i.test(ua)) { os = "iOS"; const match = ua.match(/OS ([0-9_]+)/i); if (match) osVersion = match[1].replace(/_/g, "."); } else if (/linux/i.test(ua)) { os = "Linux"; } // --- Detectar Navegador y versión --- let browser = "Navegador desconocido"; let browserVersion = "Versión desconocida"; if (/edg/i.test(ua)) { browser = "Edge"; browserVersion = (ua.match(/Edg\/([0-9.]+)/i) || [])[1] || browserVersion; } else if (/opr\//i.test(ua)) { browser = "Opera"; browserVersion = (ua.match(/OPR\/([0-9.]+)/i) || [])[1] || browserVersion; } else if (/chrome|crios/i.test(ua) && /google inc/i.test(vendor)) { browser = "Chrome"; browserVersion = (ua.match(/(?:Chrome|CriOS)\/([0-9.]+)/i) || [])[1] || browserVersion; } else if (/firefox|fxios/i.test(ua)) { browser = "Firefox"; browserVersion = (ua.match(/(?:Firefox|FxiOS)\/([0-9.]+)/i) || [])[1] || browserVersion; } else if (/safari/i.test(ua) && !/chrome|crios|opr\//i.test(ua)) { browser = "Safari"; browserVersion = (ua.match(/Version\/([0-9.]+)/i) || [])[1] || browserVersion; } else if (/trident/i.test(ua) || /msie/i.test(ua)) { browser = "Internet Explorer"; browserVersion = (ua.match(/(?:MSIE |rv:)([0-9.]+)/i) || [])[1] || browserVersion; } // --- Detectar Tipo de Dispositivo --- let device = "Desktop"; if (/android/i.test(lowerUA) && /mobile/i.test(lowerUA)) device = "Mobile"; else if (/android/i.test(lowerUA)) device = "Tablet"; else if (/iphone/i.test(lowerUA)) device = "Mobile"; else if (/ipad|tablet/i.test(lowerUA)) device = "Tablet"; else if (/windows phone/i.test(lowerUA)) device = "Mobile"; return { sistemaOperativo: os, versionSO: osVersion, navegador: browser, versionNavegador: browserVersion, dispositivo: device }; } // Ejemplo de uso // console.log(getSystemInfo()); // Inicializamos initIframe(); var ids = window.localStorage.getItem('idsRoofcal'); if (ids == null || consultaApiIp == 1) { ids = idsesion; window.localStorage.setItem('idsRoofcal', ids) } var iniEst = {}; iniEst.idEst = 0; iniEst.user_id = user_id; iniEst.org_id = org_id; iniEst.site = site; iniEst.title = d.title; iniEst.pathname = d.location.pathname; iniEst.pageVisits = d.location.href; iniEst.referer = (d.referrer != '') ? d.referrer : 'Direct'; iniEst.ip = ip; iniEst.consultaApiIp = consultaApiIp; iniEst.os = getSystemInfo().sistemaOperativo; iniEst.browser = getSystemInfo().navegador; iniEst.device = getSystemInfo().dispositivo; iniEst.ids = window.localStorage.getItem('idsRoofcal'); iniEst.ip_info = ip_info; iniEst.quest = new Array(); var estimate = iniEst; var divIdStep = "step"; var stepCount = 0; var calculator = {}; calculator.step = stepCount; window.localStorage.setItem('calculator', JSON.stringify(calculator)); window.localStorage.removeItem('reload'); var selectedShape; function registerLog() { fetch(urlSession, { method: "POST", mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { "Content-Type": "application/json", "Authentication": "Bearer " + user_id + "-" + org_id + "" }, redirect: 'follow', referrerPolicy: 'no-referrer', body: JSON.stringify(iniEst), }) .then(res => res.json()) .catch(error => { console.error('Error:', error) }) .then(response => { //console.log('Success:', response) }); } function requestFiles(url, typeFile, idDiv) { btnDis('nextRoofCal', 'true'); return new Promise((resolve) => { fetch(url, { method: 'GET', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { "Content-Type": "text/xml", "Authentication": "Bearer " + user_id + "-" + org_id + "" }, redirect: 'follow', referrerPolicy: 'no-referrer', }) .then(response => { response.text().then(function (text) { //console.log('response text', text); if (text.includes('syntax error') || text.includes('Exception')) { window.localStorage.setItem('reload', stepCount); console.log('response text error php'); showLoading(); pantallaStepNone(); showReload(); } else { if (typeFile == 'js') { } else if (typeFile == 'css') { createCssIframe(text, idDiv); } else if (typeFile == 'cssDOM') { createCssDOM(text, idDiv); } else if (typeFile == 'html') { if (window.localStorage.getItem('reload')) { window.localStorage.removeItem('reload'); qIframe('#errorReload').then(el => { if (el) el.classList.remove('showFlex'); }); } createAppHtml(text, idDiv); btnDis('nextRoofCal', 'false'); } } resolve(true) }) }) .catch(error => { console.log('Error:', error); btnDis('nextRoofCal', 'false'); resolve(false); }); }); } function requestFilesPOST(url, typeFile, idDiv, varPost) { var data = JSON.stringify({ data: varPost }) btnDis('nextRoofCal', 'true'); fetch(url, { method: "POST", mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { "Content-Type": "application/json", "Authentication": "Bearer " + user_id + "-" + org_id + "" }, redirect: 'follow', referrerPolicy: 'no-referrer', body: data, }) .then(response => { response.text().then(function (text) { //console.log('response text', text); if (text.includes('syntax error') || text.includes('Exception')) { window.localStorage.setItem('reload', stepCount); console.log('response text error php'); showLoading(); pantallaStepNone(); showReload(); } else { if (typeFile == 'js') { } else if (typeFile == 'css') { createCssIframe(text, idDiv); } else if (typeFile == 'html') { if (window.localStorage.getItem('reload')) { window.localStorage.removeItem('reload'); qIframe('#errorReload').then(el => { if (el) el.classList.remove('showFlex'); }); } createAppHtml(text, idDiv); btnDis('nextRoofCal', 'false'); } } }) }) .catch(error => { console.log('Error:', error); btnDis('nextRoofCal', 'false'); }); }function setLS(obj, val) { window.localStorage.setItem(obj, JSON.stringify(val)); getLS(obj); } function getLS(obj) { var json = window.localStorage.getItem("" + obj + ""); obj = JSON.parse(json); } function btnDis(btn, disabled) { qIframe(".navRoofCal #" + btn).then(el => { if (el) { if (disabled == "true") { el.setAttribute('disabled', disabled); } else { el.removeAttribute('disabled'); } } }); } function fetchStepHTML(estimate) { // console.log('step', StepDisplay[stepCount]); var sentget = JSON.stringify(estimate); var p = urlStep + '/' + StepDisplay[stepCount] + '/' + f.getTime(); requestFilesPOST(p, 'html', StepDisplay[stepCount], sentget); } function llamarHTML(estimate) { fetchStepHTML(estimate); qIframe('.navRoofCal').then(el => { if (el) el.style.display = "flex"; }); } function backRoofCal() { if (stepCount > 0) { stepCount--; } showLoading(); window.localStorage.removeItem('reload'); qIframe('#errorReload').then(el => { if (el) el.classList.remove('showFlex'); }); btnDis('nextRoofCal', 'false'); calculator.step = stepCount; setLS('calculator', calculator); qIframe("#" + StepDisplay[stepCount]).then(el => { if (!el) { // console.log('backRoofCal', el, 'fetchStepHTML'); fetchStepHTML(estimate); } else { // console.log('backRoofCal', el, 'stepActive'); showLoading(); stepActive(); } }); } function nextRoofCal() { showLoading(); // validacion de address antes de cambiar de pantalla if (StepDisplay[stepCount] == 'Address') { var tildes = ['á', 'é', 'í', 'ó', 'ú', 'ä', 'ë', 'ï', 'ö', 'ü', 'Á', 'É', 'Í', 'Ó', 'Ú', 'Ä', 'Ë', 'Ï', 'Ö', 'Ü']; var sintildes = ['a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U', 'A', 'E', 'I', 'O', 'U',]; var addressVal = qValue("#address").value != null ? qValue("#address").value.split('') : []; var addressNew = ''; for (var i in addressVal) { if (addressVal[i]) { for (var e in tildes) { if (addressVal[i].indexOf(tildes[e]) > -1) { addressVal[i] = addressVal[i].replace(tildes[e], sintildes[e]); } } addressNew += addressVal[i]; } } estimate.address = addressNew; } stepCount++; // console.log('nextRoofCal', stepCount, StepDisplay[stepCount]); if (window.localStorage.getItem('reload') == stepCount) { showReload(); } if (StepDisplay[stepCount] == 'Username') { estimate.otherdetails = qValue("#other-details").value || ''; } if (StepDisplay[stepCount] == 'Verify') { estimate.firsname = qValue("#firsname").value || ''; estimate.lastname = qValue("#lastname").value || ''; estimate.phone = qValue("#phone").value || ''; estimate.email = qValue("#email").value || ''; } if (StepDisplay[stepCount] == 'End') { estimate.code = qValue("#code").value || ''; estimate.idEst = qValue("#idEst").value || ''; } setLS('estimate', estimate); calculator.step = stepCount; setLS('calculator', calculator); if (qIframe("#" + StepDisplay[stepCount]) == undefined && StepDisplay[stepCount] != 'End') { llamarHTML(estimate); } else if (StepDisplay[stepCount] == 'Address') { // si fallo antes volver a llamar qIframe("#address").then(el => { qIframe("#" + StepDisplay[stepCount]).then(el => { if (el) el.remove(); }); }); llamarHTML(estimate); } else if (StepDisplay[stepCount] == 'Verify') { var validFinal = validFormUser(); if (validFinal == 'false') { // siempre volver actualizar esta vista qIframe("#" + StepDisplay[stepCount]).then(el => { if (el) el.remove(); }); llamarHTML(estimate); } else { showLoading(); backRoofCal(); } } else if (StepDisplay[stepCount] == 'End') { // si fallo antes volver a llamar qIframe("#codeSMS").then(el => { if (el) el.style.display = "none"; }); var data = { user_id: estimate.user_id, org_id: estimate.org_id, code: estimate.code, idEst: estimate.idEst, }; fetch(urlSendcode + "/" + f.getTime(), { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } }).then(res => res.json()) .catch(error => { console.error('Error:', error); }) .then(response => { // console.log('response', response) //debugger; if (response.respSMS.status) { qIframe("#" + StepDisplay[stepCount]).then(el => { if (el) el.remove(); }); llamarHTML(estimate); if (redirect == 1) { redirection(opt, uri, time); } } else { showLoading(); backRoofCal(); qIframe("#codeSMS").then(el => { if (el) el.style.display = "block"; }); } }); } else { qIframe("#" + StepDisplay[stepCount]).then(el => { if (!el) { llamarHTML(estimate); } else { showLoading(); stepActive(); } }); validations(); validNext(); } } function showLoading() { if (window.localStorage.getItem('reload') == stepCount) { // console.log('cerrando showReload') showReload(); } qIframe('#loadingRoofCal').then(el => { if (el) { // console.log('#loadingRoofCal', el) if (el.classList.length > 1) { // console.log('desactivando loanding', 'step', stepCount); el.classList.remove('show'); stepActive(); qIframe('.headRoofCal').then(st => { if (st) { // console.log('show headRoofCal') if (st.style.display == "none") { st.style.display = "block"; } } }); } else { // console.log('activando loanding', 'step', stepCount, el.classList); el.classList.add('show'); pantallaStepNone(); } } }); } function pantallaStepNone() { // console.log('ocultando pantallaStep', 'step', stepCount); qAllIframe('.pantallaStep').then(elements => { elements.forEach(el => el.style.display = "none"); }); } function stepActive() { // console.log('stepActive', 'step', stepCount); qIframe("#" + StepDisplay[stepCount]).then(el => { if (el) el.style.display = "block"; }); qIframe('.navRoofCal #back').then(el => { if (el) { if (stepCount > 0) { if (el.classList.length > 0) { el.classList.remove('opa0'); } } else { if (el.classList.length == 0) { el.classList.add('opa0'); } } } }); qIframe('.navRoofCal').then(el => { if (el) { if (stepCount > 0) { if (el.style.display == "none") { el.style.display = "flex"; } } else { el.style.display = "none"; } } }); } function closeRoofCal() { qIframe("#contentRoofCal").then(el => { if (el) el.style.display = "none"; }); qIframe(".headRoofCal").then(el => { if (el) el.style.display = "none"; }); document.querySelector('#btnOpenRoofCal').classList.remove('btnNone'); document.querySelector("#" + appRoofCal).classList.remove('appActive'); if (StepDisplay[stepCount] == 'End') { resetPantallas(); } } function newEst() { if (StepDisplay[stepCount] == 'End') { resetPantallas(); } openRoofCal(); } function resetPantallas() { qAllIframe('.pantallaStep').then(elements => { elements.forEach(el => { el.remove(); }); }); window.localStorage.clear(); stepCount = 0; calculator.step = stepCount; setLS('calculator', calculator); var newEst = iniEst; setLS('estimate', newEst); estimate = newEst; } function reloadHTML() { qIframe('#errorReload').then(el => { if (el) el.classList.remove('showFlex'); }); showLoading(); qIframe("#" + StepDisplay[window.localStorage.getItem('reload')]).then(el => { if (el) el.remove(); }); llamarHTML(estimate); } function showReload() { qIframe('#errorReload').then(el => { if (el) { if (el.classList.length == 0 || window.localStorage.getItem('reload') == stepCount) { el.classList.add('showFlex'); } else { window.localStorage.removeItem('reload'); el.classList.remove('showFlex'); qIframe('#loadingRoofCal').then(elem => { if (elem) elem.classList.remove('showFlex'); }); } } }); } function redirection(opt, uri, time) { setTimeout(function () { if (opt == 1) { window.location.href = window.location.origin } else { window.location.href = uri; } }, time); }function createCssDOM(cssText, cssID) { var s = d.createElement("style"); s.type = "text/css"; s.rel = "stylesheet"; s.id = cssID; s.innerHTML = cssText; var wgRoofCalS = document.querySelector("#" + idS); wgRoofCalS.after(s); } function createCssIframe(cssText, cssID) { var s = d.createElement("style"); s.type = "text/css"; s.rel = "stylesheet"; s.id = cssID; s.innerHTML = cssText; iframeLoad.body.append(s); } function createAppsj(urlRoofCal) { var s = d.createElement('script'); s.type = "text/javascript"; s.id = idS; s.defer = !0; s.src = urlRoofCal + '/' + f.getTime(); t.after(s) } function createAppHtml(html, idDiv) { var divCode = d.createElement("div"); idDiv = idDiv == 'Address' ? 'Address-step' : idDiv; divCode.id = idDiv; divCode.classList.add('pantallaStep'); divCode.innerHTML = html; qIframe('.bodyRoofCalContent').then(el => { if (el) el.append(divCode); }); // console.log('createAppHtml', idDiv); //validaciones setTimeout(function () { showLoading(); validations(); validNext(); }, 400); }function formZip(e) { e.preventDefault(); var zipVal = qValue(".zipcode-input").value || ''; if (allZip == 1 && zipVal.length == 5) { qIframe(".form-field-error").then(el => { if (el) el.style.display = "none"; }); estimate.zipcode = zipVal; estimate.idEst = qValue("#idEst").value || ''; setLS('estimate', estimate); nextRoofCal(); } else if (zip.includes(zipVal) && zipVal.length == 5) { qIframe(".form-field-error").then(el => { if (el) el.style.display = "none"; }); estimate.zipcode = zipVal; estimate.idEst = qValue("#idEst").value || ''; setLS('estimate', estimate); nextRoofCal(); } else { qIframe(".form-field-error").then(el => { if (el) el.style.display = "block"; }); } } function validations() { if (StepDisplay[stepCount] == 'Zipcode') { //setTimeout(function(){qIframe("#zipcode").value ='01757';}, 1000); setTimeout(function () { // console.log('Zipcode focus'); qValue("#zipcode")?.focus(); }, 500); // console.log('Zipcode', estimate) } if (stepCount > 0 && StepDisplay[stepCount - 1].indexOf('customerStep-') > -1) { let idQuest = StepDisplay[stepCount - 1].split('-'); let inputName = "input[name='item" + idQuest[1] + "']"; let items = '.item' + idQuest[1]; let multiple = "#multiple" + idQuest[1]; let questElem = "questID" + idQuest[1]; let questName = qValue("#questName" + idQuest[1]).value || ''; let countQuest = stepCount - 2; estimate.quest[countQuest] = { questName: questName, answers: [] }; if (qIframe(inputName)) { estimate.quest[countQuest].answers = [qValue(inputName).value || '']; } else if (qValue(multiple)?.value == 1) { qAllIframe(items).then(elements => { valItems = []; let contItem = 0; elements.forEach(e => { //console.log('check ', e.checked) if (e.checked) { valItems[contItem] = e.value; contItem++; } }); estimate.quest[countQuest].answers = valItems; }); } else { estimate.quest[countQuest].answers = []; } if (estimate.quest[countQuest].answers.length == 0) { alert("You must select one of the options."); backRoofCal(); } else { setLS('estimate', estimate); } } if (StepDisplay[stepCount] == 'Address') { iframeReady.then(() => { // if (!iframeLoad.isActiveInitMap) { console.log('preparando MapPlace...') if (iframeLoad.isAlreadyInitMap()) { iframeLoad.initMapPaceRoofCal(); // Inicializa el mapa y el input de búsqueda } else { iframeLoad.waitForMapAndInput(); // Espera a que el mapa y el input estén listos } // } }); } if (StepDisplay[stepCount] == 'End') { qIframe('.navRoofCal').then(el => { if (el) el.style.display = "none"; }); } } // fin validations function showErrorForm(elem, msj, show) { if (elem) { if (show == 0) { elem.style.display = "none"; } else { elem.innerHTML = msj; elem.style.display = "block"; } } } function validNext() { var stop = 'false'; if (StepDisplay[stepCount] == 'Address') { if (qValue("#address")?.value.trim().length <= 1) { stop = 'true'; } else { // repositionPacContainer(iframeLoad); } } if (StepDisplay[stepCount] == 'Username') { if ( qValue("#firsname")?.value.trim().length == 0 || qValue("#lastname")?.value.trim().length == 0 || qValue("#phone")?.value.trim().length == 0 || qValue("#email")?.value.trim().length == 0 ) { stop = 'true'; } } if (StepDisplay[stepCount] == 'Verify') { if (qValue("#code")?.value.trim().length < 4) { stop = 'true'; } } btnDis('nextRoofCal', stop); } function validFormUser() { var stop = 'false'; var logfirstname = qValue(".error-firstname"); var loglastname = qValue(".error-lastname"); var logphone = qValue(".error-phone"); var logemail = qValue(".error-email"); var msj = ""; showErrorForm(logfirstname, msj, 0); showErrorForm(loglastname, msj, 0); showErrorForm(logphone, msj, 0); showErrorForm(logemail, msj, 0); var emailRegex = /^[-\w.%+]{1,64}@(?:[A-Z0-9-]{1,63}\.){1,125}[A-Z]{2,63}$/i; if (qValue("#firsname")?.value.trim().length == 0) { msj = 'First name is required'; showErrorForm(logfirstname, msj, 1); stop = 'true'; } if (qValue("#firsname")?.value.trim().length < 2) { msj = 'First name is invalid'; showErrorForm(logfirstname, msj, 1); stop = 'true'; } if (qValue("#lastname")?.value.trim().length == 0) { msj = 'Last name is required'; showErrorForm(loglastname, msj, 1); stop = 'true'; } if (qValue("#lastname")?.value.trim().length < 2) { msj = 'Last name is invalid'; showErrorForm(loglastname, msj, 1); stop = 'true'; } if (qValue("#phone")?.value.trim().length == 0) { msj = 'Phone is required'; showErrorForm(logphone, msj, 1); stop = 'true'; } else { var valNroUSA = formatPhone(qValue("#phone").value, "USA"); var valNroCOL = formatPhone(qValue("#phone").value, "COL"); var valNroPEP = formatPhone(qValue("#phone").value, "PEP"); var valNroBRA = formatPhone(qValue("#phone").value, "BRA"); if (!valNroUSA && !valNroCOL && !valNroPEP && !valNroBRA) { msj = 'Phone is invalid'; showErrorForm(logphone, msj, 1); stop = 'true'; } } if (qValue("#email")?.value.trim().length == 0) { msj = 'Email is invalid'; showErrorForm(logemail, msj, 1); stop = 'true'; } if (!emailRegex.test(qValue("#email")?.value)) { msj = 'Email is required'; showErrorForm(logemail, msj, 1); stop = 'true'; } if (msj.length > 0) { stop = 'true'; } btnDis('nextRoofCal', stop); return stop; } function formatPhone(phoneNumber, country) { // var phoneRe = /^[2-9]\d{2}[2-9]\d{2}\d{4}$/; // var digits = value.replace(/\D/g, ""); // return phoneRe.test(digits); const mobilePatterns = { USA: /^(?:\+1)?[2-9]\d{2}[2-9]\d{6}$/, // Solo móviles de EE.UU. COL: /^(?:\+57)?3\d{9}$/, // Solo celulares en Colombia (3XX-XXXXXXX) PEP: /^(?:\+57)?3(2|14|24|10)\d{7}$/, // Celulares en rangos PEP BRA: /^(?:\+55)?(?:[14689][1-9])9\d{8}$/ // Celulares en Brasil (+55 DDD 9XXXX-XXXX) }; const pattern = mobilePatterns[country.toUpperCase()]; if (!pattern) { throw new Error("País no soportado"); } return pattern.test(phoneNumber); } function validFormatPhone() { var nroVal = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+']; var str = qValue("#phone")?.value.trim(); var nro = str.split(''); var nroFormat = ''; var contNro = 0; var valid = false; for (var i in nro) { if (nro[i]) { valid = false; for (var e in nroVal) { if (nro[i] == nroVal[e]) { valid = true; } } if (valid) { contNro++; nroFormat += '' + nro[i]; } } } if (contNro != 10) { return false; } else { qValue("#phone").value = nroFormat; return true; } } setTimeout(function () { registerLog(); }, 1000); // cargar estilos if (!document.querySelector('#btnIframeCSS')) { requestFiles(btnIframeCSS, 'cssDOM', 'btnIframeCSS').then(result => { if (document.querySelector('#btnIframeCSS')) { //console.log('load btnIframeCSS') divBase.removeAttribute('style'); } }); } qIframe('#cssMain').then(cssEl => { if (!cssEl) requestFiles(cssMain, 'css', 'cssMain'); }); // agregando html al iframe var htmlDivMain = ``; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += `Failed to load, try again with reload.`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += `
`; htmlDivMain += ``; htmlDivMain += `
`; htmlDivMain += `
`; var divCode = d.createElement("div"); divCode.id = 'contentRoofCal'; divCode.style.display = 'flex'; divCode.innerHTML = htmlDivMain; iframeReady.then(() => { addToIframe(divCode); // iframeLoad.body.append(divCode); // creando script de gogle map place qIframe("#apiMap").then(apiMAP => { if (!apiMAP) { const keyGooglePlace = "AIzaSyCEA1_kvJc0-Cpqo5_FvFP2wJxWjsPP0Ok"; console.log('create script apiMap') var s = iframeLoad.createElement('script'); s.type = "text/javascript"; s.id = "apiMap"; s.async = !0; s.src = "https://maps.googleapis.com/maps/api/js?key=" + keyGooglePlace + "&libraries=places,drawing,geometry&v=weekly"; //s.src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD4EnKn-u2jXwq0KPQSadqX7YaS4OYDrgw&libraries=places"; s.onload = () => { console.log("Google Maps API cargada dentro del iframe"); console.log(iframeLoad.defaultView.google); // Aquí ya debe estar }; iframeLoad.body.append(s); } }); // init y waitForMap iframeLoad.waitForMapAndInput = function () { const checkInterval = setInterval(() => { const inputAddress = iframeLoad.querySelector('#address'); const mapContainer = iframeLoad.querySelector("#map"); const valAddress = iframeLoad.querySelector("#address") ? iframeLoad.querySelector("#address").value : ''; // Validamos que exista el input, el contenedor y la API de Google if (iframeLoad.isAlreadyInitMap()) { // iframeLoad.google.maps && // iframeLoad.google.maps.places clearInterval(checkInterval); // Detenemos el intervalo iframeLoad.initMapPaceRoofCal(); // Ejecutamos la función principal } else { console.log("esperando map place..."); console.log("inputAddress", inputAddress); console.log("mapContainer", mapContainer); console.log("valAddress", valAddress.length); } }, 1500); // Revisa cada 200ms } iframeLoad.isAlreadyInitMap = function () { const inputAddress = iframeLoad.querySelector('#address'); const mapContainer = iframeLoad.querySelector("#map"); const valAddress = iframeLoad.querySelector("#address") ? iframeLoad.querySelector("#address").value : ''; return ( inputAddress && mapContainer && typeof iframeLoad.defaultView.google !== 'undefined' && valAddress.length <= 4 ); } iframeLoad.isActiveInitMap = false; iframeLoad.initMapPaceRoofCal = function () { const mapElement = iframeLoad.querySelector("#map"); console.log("Cargando Google Maps Places API...", mapElement); const myLatLng = { lat: 42.1630697, lng: -71.5090529 }; if (Object.keys(ip_info).length > 0) { myLatLng.lat = ip_info?.lat; myLatLng.lng = ip_info?.lon; } console.log('lat', myLatLng.lat, 'lng', myLatLng.lng); const map = new iframeLoad.defaultView.google.maps.Map(mapElement, { center: myLatLng, zoom: 18, mapTypeId: "satellite" //"roadmap | satellite", }); // Create the search box and link it to the UI element. const searchInput = iframeLoad.querySelector('#address'); if (!searchInput) { console.error("❌ No se encontró el campo de dirección", searchInput); return; } const searchBox = new iframeLoad.defaultView.google.maps.places.SearchBox(searchInput); //map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); // Bias the SearchBox results towards current map's viewport. map.addListener("bounds_changed", () => { const bounds = map.getBounds(); if (bounds) searchBox.setBounds(bounds); }); let markers = []; // Listen for the event fired when the user selects a prediction and retrieve // more details for that place. searchBox.addListener("places_changed", () => { const places = searchBox.getPlaces(); if (places.length == 0) { return; } // Clear out the old markers. markers.forEach((marker) => { marker.setMap(null); }); markers = []; // For each place, get the icon, name and location. //const bounds = new google.maps.LatLngBounds(); // Llama a la función para geocodificar la dirección y dibujar el polígono let e = searchBox.getPlaces(); if (0 != e.length) { // console.log('getPlaces', e) // geocodeAddress(e[0].formatted_address); } places.forEach((place) => { if (!place.geometry || !place.geometry.location) { console.log("Returned place contains no geometry"); return; } map.panTo(place.geometry.location); map.setZoom(19); const icon = { url: place.icon, size: new iframeLoad.defaultView.google.maps.Size(71, 71), origin: new iframeLoad.defaultView.google.maps.Point(0, 0), anchor: new iframeLoad.defaultView.google.maps.Point(17, 34), scaledSize: new iframeLoad.defaultView.google.maps.Size(25, 25), }; // Create a marker for each place. markers.push( new iframeLoad.defaultView.google.maps.Marker({ map, //icon, title: place.name, position: place.geometry.location, }) ); // if (place.geometry.viewport) { // // Only geocodes have viewport. // bounds.union(place.geometry.viewport); // } else { // bounds.extend(place.geometry.location); // } // Guardar la ubicación seleccionada en el objeto estimate estimate.location = { lat: place.geometry.location.lat(), lng: place.geometry.location.lng() }; console.log('Ubicación seleccionada:', estimate.location); setLS('estimate', estimate); }); //map.fitBounds(bounds); }); iframeLoad.isActiveInitMap = true; } /* function copyGoogleMapsStylesToIframe(iframe) { const iframeHead = iframe.head; var checkStyleMapLoaded = setInterval(function () { qIframe("#GoogleMapsStylesPlace").then(el => { if (!el) { // console.log('buscando estilos de map place') const parentStyles = document.head.querySelectorAll("style"); parentStyles.forEach(style => { if (style.innerHTML.includes(".pac-container")) { // Solo copiar estilos de Google Maps const clonedStyle = document.createElement('style'); clonedStyle.innerHTML = style.innerHTML; clonedStyle.id = 'GoogleMapsStylesPlace'; iframeHead.appendChild(clonedStyle); // console.log('estilos de map place COPIADOS') clearInterval(checkStyleMapLoaded); } }); } }); }, 200); // Verifica cada 200ms } function repositionPacContainer(iframe) { setTimeout(() => { const pacContainer = iframe.querySelector(".pac-container"); const input = iframe.querySelector("#address"); if (pacContainer && input) { const rect = input.getBoundingClientRect(); pacContainer.style.position = "absolute"; pacContainer.style.top = `${rect.bottom}px`; pacContainer.style.left = `${rect.left}px`; pacContainer.style.width = `${rect.width}px`; pacContainer.style.zIndex = "10000"; // console.log('repositionPacContainer', pacContainer) } }, 300); } function geocodeAddress(address) { const geocoder = new google.maps.Geocoder(); geocoder.geocode({'address': address}, function(results, status) { if (status === 'OK') { const location = results[0].geometry.location; map.setCenter(location); // Dibuja un polígono alrededor de la ubicación obtenida drawPolygon(location); } else { alert('Geocode was not successful for the following reason: ' + status); } }); } function drawPolygon(location) { const bounds = [ { lat: location.lat() + 0.0001, lng: location.lng() - 0.0001 }, { lat: location.lat() + 0.0001, lng: location.lng() + 0.0001 }, { lat: location.lat() - 0.0001, lng: location.lng() + 0.0001 }, { lat: location.lat() - 0.0001, lng: location.lng() - 0.0001 } ]; const polygon = new google.maps.Polygon({ paths: bounds, strokeColor: '#FF0000', strokeOpacity: 0.8, strokeWeight: 2, fillColor: '#FF0000', fillOpacity: 0.35, editable: true, draggable: true }); polygon.setMap(map); if (selectedShape) { selectedShape.setMap(null); } selectedShape = polygon; google.maps.event.addListener(polygon.getPath(), 'set_at', calculateArea); google.maps.event.addListener(polygon.getPath(), 'insert_at', calculateArea); calculateArea(); } function calculateArea() { const area = google.maps.geometry.spherical.computeArea(selectedShape.getPath()); alert('Área del techo: ' + area.toFixed(2) + ' metros cuadrados'); }*/}); setLS('estimate', estimate); setLS('calculator', calculator); function openRoofCal() { /* console.log('click openRoofCal') */ // iframeRoof.classList.toggle(); if (imgLogo != '' || desc_company != '') { setTimeout(function () { qIframe('.sectLogo').then(el => { if (el) el.style.display = "flex"; }); }, 2000); } showLoading(); document.querySelector('#btnOpenRoofCal').classList.add('btnNone'); document.querySelector("#" + appRoofCal).classList.add('appActive'); qIframe("#contentRoofCal").then(elemRoof => { if (elemRoof) { if (window.innerWidth > 768) { elemRoof.style.display = "flex"; } else { elemRoof.style.display = "block"; } } }); getLS('calculator'); if (calculator.step > 0) { stepCount = calculator.step showLoading(); } else { stepCount = 0; calculator.step = stepCount; setLS('calculator', calculator); /* console.log("redirect", redirect); */ qIframe("#zipcode").then(zip => { if (!zip) { fetchStepHTML(estimate); } else { showLoading(); } }); } } document.querySelector('#btnOpenRoofCal').addEventListener('click', (event) => { event.preventDefault(); openRoofCal(); });