UNPKG

@textback/notification-widget

Version:

TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.

282 lines (230 loc) 10.2 kB
import Component from '../index.js'; import arrowIcon from '../../icons/paper-plane-arrow.svg'; import waIcon from '../../icons/icon_whatsapp_new.svg'; import iconTbLogoLightRu from '../../icons/tb-logo-light-ru.svg' import iconTbLogoLightEn from '../../icons/tb-logo-light-en.svg' import './styles.scss'; const parsePhoneNumber = (phoneString) => phoneString.replace(/[^\d]/g, ''); export default class Wahunter extends Component { constructor() { super(...arguments); } render() { this.lang = this.widgetAPI.config.lang || this.parentElement.getAttribute('lang'); this.logo = (this.lang === 'ru') ? iconTbLogoLightRu : iconTbLogoLightEn || iconTbLogoLightRu; this.showPersonalDataConsent = this.widgetAPI.config.personalDataConsent !== undefined && this.widgetAPI.config.personalDataConsent.enabled; this.showMarketingConsent = this.widgetAPI.config.marketingConsent !== undefined && this.widgetAPI.config.marketingConsent.enabled; super.render(); this.submitFormElem = this.element.querySelector(`.${Wahunter.tagName}__submit-form`); this.marketingCheckbox = this.submitFormElem.querySelector('#marketing-consent'); this.addListeners(); } addListeners() { this.submitFormElem.addEventListener('submit', (e) => { e.preventDefault(); this.submit(); }); this.submitFormElem.phoneNumber.addEventListener('input', (e) => { const target = e.target; let selectionPos = target.selectionStart; let newValue = parsePhoneNumber(target.value); if (['7', '8'].includes(newValue[0]) || newValue.slice(0, 2) === '+7') { newValue = newValue.slice(0, 11); newValue = (newValue + '_'.repeat(11 - newValue.length)).replace(/(.{1})(.{3})(.{3})(.{2})(.{2})/, "+7 ($2) $3-$4-$5"); const indexOfFirstUnderscore = newValue.indexOf('_'); const indexOfLastNumber = newValue.lastIndexOf(newValue.match(/\d/g).pop()); if (target.value[selectionPos] === "_") { selectionPos = indexOfLastNumber + 1; } else { selectionPos = indexOfFirstUnderscore; } target.value = newValue; return target.setSelectionRange(selectionPos, selectionPos); } if (target.value[0] === '+') { newValue = `+${newValue}`; } target.value = newValue; }); this.submitFormElem.tryAgain.addEventListener('click', (e) => { if (this.widgetAPI.config.displayMode !== 'inline') { this.element.querySelector(`.${Wahunter.tagName}__text-content`).style = null; } this.changeSubmitFormState('initial'); }); } getTbBrandBadge({ displayMode }) { const utmMedium = 'hunter'; return ` <a target="_blank" href="//textback.ru/?utm_source=TextBack_tool&utm_medium=${utmMedium}&utm_campaign=${window.location.origin}${window.location.pathname}&utm_content=${displayMode}" id="tb-notification-brand-badge" style="${displayMode === 'inline' ? 'fill:inherit; color: inherit;' : ''}" > ${this.logo} </a> `; } submit() { const phoneNumber = +parsePhoneNumber(this.submitFormElem.phoneNumber.value); if (this.widgetAPI.config.displayMode !== 'inline') { this.element.querySelector(`.${Wahunter.tagName}__text-content`).style.display = 'none'; } this.changeSubmitFormState('pending'); setTimeout(() => { this.widgetAPI.runWahunter(phoneNumber, this.showPersonalDataConsent, this.marketingCheckbox && this.marketingCheckbox.checked) .then(() => this.changeSubmitFormState('success')) .catch((error) => { if (error.status === 400) return this.changeSubmitFormState('notFound'); this.changeSubmitFormState('error'); }); }, 1500); } changeSubmitFormState(stateName) { const submitFormElem = this.submitFormElem; let messageText = ''; let tryAgainText = ''; let emoji = ''; switch (stateName) { case 'pending': { submitFormElem.dataset.state = 'pending'; messageText = this.text('sendMessage'); emoji = '⏳'; break; } case 'success': { submitFormElem.dataset.state = 'success'; messageText = this.text('answerSuccessful'); emoji = '👍'; break; } case 'notFound': { submitFormElem.dataset.state = 'notFound'; messageText = this.text('numberNotFound'); emoji = '🕵️‍♂️'; tryAgainText = this.text('tryAgain'); break; } case 'error': { submitFormElem.dataset.state = 'error'; messageText = this.text('somethingWentWrong'); emoji = '👨‍🔧'; tryAgainText = this.text('errorTryAgain'); break; } default: { submitFormElem.dataset.state = 'initial'; break; } } submitFormElem.querySelector(`.${Wahunter.tagName}__state-report-emoji`).textContent = emoji; submitFormElem.querySelector(`.${Wahunter.tagName}__state-report-message`).innerHTML = messageText; submitFormElem.tryAgain.textContent = tryAgainText; } get template() { const { displayMode, markUp: { image, header, description, }, } = this.widgetAPI.config; if (displayMode === 'inline') return this.submitFormTemplate; if (displayMode === 'popup') { return ` <div class="${Wahunter.tagName}__top-img" style="background-image: url(${image.url})"></div> <div class="${Wahunter.tagName}__img"> <img src="${image.url}"> </div> <div class="${Wahunter.tagName}__main-content"> <div class="${Wahunter.tagName}__text-content"> <div class="${Wahunter.tagName}__headline" style="color:${header.color}"> ${header.value} </div> <div class="${Wahunter.tagName}__description" style="color:${description.color}"> ${description.value} </div> </div> ${this.submitFormTemplate} </div> `; } if (displayMode === 'corner-popup') { return ` <div class="${Wahunter.tagName}__text-content"> <div class="${Wahunter.tagName}__headline" style="color:${header.color}"> ${header.value} </div> </div> ${this.submitFormTemplate} ` } } get submitFormTemplate() { let { displayMode, showWahunterAgreement, personalDataConsent, marketingConsent, markUp: { wahunterButton, header, }, } = this.widgetAPI.config; const landingPlacesUrls = [ 'lp.textback.ru', 'lp.textback.io', 'lp-dev.textback.ru', 'tb-opsrv-dev.textback.io/messaging.html#!/mini-landings', 'my.textback.io/messaging.html#!/mini-landings', 'landings.textback.io', ]; const isTBMiniLanding = landingPlacesUrls.some((url) => location.href.includes(url)); return ` <form class="${Wahunter.tagName}__submit-form" data-state="initial"> <div class="${Wahunter.tagName}__submit-form-controls"> <div class="${Wahunter.tagName}__phone-input-container"> <input type="text" class="${Wahunter.tagName}__phone-input" name="phoneNumber" placeholder="${this.text('enterNumber')}" required> <button class="${Wahunter.tagName}__submit-button" style="color:${wahunterButton.textColor};background-color:${wahunterButton.color}"> ${wahunterButton.text} <div class="${Wahunter.tagName}__submit-button-icon"> ${arrowIcon} </div> </button> </div> <div class="${Wahunter.tagName}__submit-form-footer" style="${showWahunterAgreement && !this.showPersonalDataConsent ? '' : 'display:none'}"> <label class="${Wahunter.tagName}__agreement"> <input type="checkbox" required checked> <span class="${Wahunter.tagName}__agreement-text">${this.text('getAnswer')}<span class="${Wahunter.tagName}__agreement-wa-icon">${waIcon}</span>WhatsApp</span> </label> </div> <div class="${Wahunter.tagName}__submit-form-footer" style="${this.showPersonalDataConsent ? '' : 'display:none'}"> <label class="${Wahunter.tagName}__agreement"> <input type="checkbox" ${this.showPersonalDataConsent ? 'required' : ''}> <span class="${Wahunter.tagName}__agreement-text ${Wahunter.tagName}__agreement-personal-data">${this.showPersonalDataConsent && personalDataConsent.text ? personalDataConsent.text : ''} </label> </div> <div class="${Wahunter.tagName}__submit-form-footer" style="${this.showMarketingConsent ? '' : 'display:none'}"> <label class="${Wahunter.tagName}__agreement "> <input id="marketing-consent" type="checkbox" ${this.showMarketingConsent && marketingConsent.required ? 'required' : ''}> <span class="${Wahunter.tagName}__agreement-text">${this.showMarketingConsent && marketingConsent.text ? marketingConsent.text : ''} </label> </div> </div> <div class="${Wahunter.tagName}__state-report"> <div class="${Wahunter.tagName}__state-report-emoji"></div> <div class="${Wahunter.tagName}__state-report-message-container" style="${displayMode === 'inline' ? ('color:' + header.color + ';' + 'fill:' + header.color) : ''}"> <div class="${Wahunter.tagName}__state-report-message"></div> <button class="${Wahunter.tagName}__try-again-button" type="button" name="tryAgain"></button> ${displayMode === 'inline' && !isTBMiniLanding ? this.getTbBrandBadge(this.widgetAPI.config) : ''} </div> </div> </form> ` } static get tagName() { return 'tb-nw-wahunter'; } };