@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
JavaScript
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';
}
};