'use strict'; declare var jivo_init: any; declare var jivo_destroy: any; declare var jivo_api: any; declare var IMask: any; class CallbackWidget { constructor({ primaryColor = '#2f495e', fontFamily = 'Montserrat', logoPath, privacyURL, whatsappPhone, whatsappMessage, supportPhone, token, telegram, max }) { // set primary widget color if (primaryColor) { if (primaryColor.startsWith('#')) { primaryColor = `rgba(${hexToRgb(primaryColor)}, var(--cw-alpha, 1))`; } document.documentElement.style.setProperty('--cw-primary-color', primaryColor); } // upload font family this.uploadCurrentFontFamily(fontFamily); // render markup this.render({ logoPath, privacyURL, whatsappPhone, whatsappMessage, supportPhone, token, telegram, max, }); // add event listeners this.addListeners(); } uploadCurrentFontFamily(fontFamily) { if (!fontFamily) return; const head = document.getElementsByTagName('head')[0]; const link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = `https://unpkg.com/callback-widget@latest/dist/assets/fonts/${fontFamily.toLowerCase()}.css`; head.appendChild(link); document.documentElement.style.setProperty('--cw-font-family', fontFamily); } render(data) { const markupToRender = `
Есть дополнительные вопросы?
Оставьте свои контакты, мы перезвоним:

Нажимая на кнопку, вы даете согласие на обработку своих персональных данных

Мы всегда рады помочь по телефону
${data.supportPhone}
${data.telegram ? ` ` : ''} ${data.max ? ` ` : ''}
`; document.body.insertAdjacentHTML('beforeend', markupToRender); // add phone mask const maskInput = document.querySelector('[data-phone-mask]'); if (typeof IMask !== 'undefined' && maskInput) { const phoneMask = IMask(maskInput, { mask: '+{7} (000) 000-00-00', }); } } addListeners() { const widget = document.querySelector('.chat'); /** * Open Rounded Controls */ widget.addEventListener('click', (e: MouseEvent) => { const target: HTMLElement = e.target as HTMLElement; const chatTrigger: HTMLElement | null = target.closest('[data-trigger="controls"]'); if (!chatTrigger) return; cw_onOpen(); // GTM event: open widget const parent: HTMLElement | null = chatTrigger.closest('.chat'); const body: HTMLElement | null = document.body; if (parent?.classList.contains('is-active')) { parent.classList.remove('is-active', 'is-callback-active', 'is-chat-active'); // body.style.overflow = ''; // document.documentElement.style.removeProperty('--cw-scroll-width'); document.querySelector('.chat-overlay')?.remove(); } else { parent.classList.add('is-active'); // body.style.overflow = 'hidden'; body.insertAdjacentHTML('beforeend', '
'); } }); /** * Open Chat/Callback area */ widget.addEventListener('click', (e: MouseEvent) => { const target: HTMLElement = e.target as HTMLElement; const chatTrigger: HTMLElement | null = target.closest('[data-trigger]'); if (!chatTrigger) return; const behaviour: string | undefined = chatTrigger.dataset.trigger; const parent: HTMLElement | null = chatTrigger.closest('.chat'); switch (behaviour) { case 'chat': // GTM Event: open Jivo chat cw_chatOpen(); jivo_init(); document.querySelector('.chat').classList.remove('is-active', 'is-callback-active', 'is-chat-active'); // document.body.style.overflow = ''; document.querySelector('.chat-overlay').remove(); break; case 'callback': // GTM Event: callback form clicked cw_onCallbackOpen(); parent.classList.remove('is-chat-active'); parent.classList.add('is-callback-active'); break; case 'whatsapp': // GTM Event: whatsapp clicked cw_onWhatsapp(); break; } }); /** * Close */ widget.addEventListener('click', (e: MouseEvent) => { const target: HTMLElement = e.target as HTMLElement; const closeChat: HTMLElement | null = target.closest('[data-controls-close]'); const overlay: HTMLElement | null = target.closest('.chat-overlay'); const chat = document.querySelector('.chat'); if ( closeChat || overlay && !(chat.classList.contains('is-callback-active') || chat.classList.contains('is-chat-active')) ) { chat.classList.remove('is-active', 'is-callback-active', 'is-chat-active'); // document.body.style.overflow = ''; // document.documentElement.style.removeProperty('--cw-scroll-width'); document.querySelector('.chat-overlay').remove(); } }); /** * Form Submit */ const callbackForm: HTMLFormElement | null = document.querySelector('[data-callback-form]'); callbackForm.addEventListener('submit', (e: Event) => { e.preventDefault(); const form: HTMLFormElement = e.target as HTMLFormElement; const parent: HTMLElement | null = form.closest('[data-panel="callback"]'); const nameField: HTMLInputElement = form.querySelector('input[name="name"]'); const phoneField: HTMLInputElement = form.querySelector('input[name="tel"]'); const name: string = nameField.value; const phone: string = phoneField.value; nameField.style.borderColor = ''; phoneField.style.borderColor = ''; if (!name) { nameField.style.borderColor = '#f00'; } if (!phone) { phoneField.style.borderColor = '#f00'; } if (name && phone) { // submit callback form // GTM Event: callback form cw_onCallbackSubmit(); const url = 'https://crm-gateway.globaldrive.ru/deal/add/'; const sendButton: HTMLButtonElement = form.send; const utmData = getUTMParams(); //const utm = new URLSearchParams(utmData as any).toString(); sendButton.disabled = true; // collect data const token = form.dataset.token; if (!token) { throw new Error('Token is missed'); } const form_name = form.getAttribute('name'); const client_name = name; // const phone = phone; const site = window.location.hostname; /*const data = encodeURIComponent(` token=${token}&form_name=${form_name}&client_name=${client_name}&phone=${phone}&site=${site}&${utm}` );*/ const data = new FormData(); data.append('token', token); data.append('form_name', form_name); data.append('client_name', client_name); data.append('phone', phone); data.append('site', site); for (let key in utmData) { data.append(key.toUpperCase(), utmData[key]); } // yandex metrica ID const getCookie = (name: string) => { const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`)); return match ? match[2] : ""; }; const ymUid = getCookie('_ym_uid') || ''; data.append('ya_metrika_client_id', ymUid); // /yandex metrica ID const options = { method: 'POST', headers: { revision: '2023-10-15', 'content-type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams(data as any), }; // sending fetch(url, options) .then((response) => response.text()) .then((response) => { sendButton.disabled = false; const callbackArea: HTMLElement | null = parent.querySelector('[data-panel-main]'); const callbackSuccess: HTMLElement | null = parent.querySelector('[data-panel-success]'); callbackArea.hidden = true; callbackSuccess.hidden = false; }) .catch((err) => { console.error(err); }); } }); } } /** * Jivo Chat OnLoad Callback */ let isFirstLoadedCallback = true; function jivo_onLoadCallback() { if (isFirstLoadedCallback) { // destroy widget by default on first initialization jivo_destroy(); isFirstLoadedCallback = false; // show chat trigger when jivo initialized const chatPanelTrigger: HTMLElement = document.querySelector('[data-trigger="chat"]'); if (chatPanelTrigger) { chatPanelTrigger.hidden = false; } } else { // when we init it, after chat button clicked const params = { start: 'chat' }; let apiResult = jivo_api.open(params); if (apiResult.result === 'fail') { console.log('Widget failed to open'); } else { console.log('Widget open successfully'); } } } /** * Jivo Chat Close Callback */ function jivo_onClose() { // destroy widget jivo_destroy(); document.querySelector('.chat').classList.remove('is-active', 'is-callback-active', 'is-chat-active'); document.querySelector('.chat-overlay').remove(); } /** * Utils */ function hexToRgb(hex) { return hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (m, r, g, b) => '#' + r + r + g + g + b + b) .substring(1).match(/.{2}/g) .map(x => parseInt(x, 16)); } interface utmData { utm_source?: string, utm_medium?: string, utm_campaign?: string, utm_term?: string, utm_content?: string, } function getUTMParams() { // Get the UTM parameters from the URL const search = window.location.search; const params = new URLSearchParams(search); const result: utmData = {}; // Keep track of if an event has already been logged let eventLogged = false; // Loop through each UTM parameter for (var [key, value] of params.entries()) { // Check if the parameter is "utm_source", "utm_medium", "utm_campaign", "utm_term", or "utm_content" if (['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'].indexOf(key) !== -1) { // Check if an event has not yet been logged if (!eventLogged) { params.get('utm_source') ? result.utm_source = params.get('utm_source') : ''; params.get('utm_medium') ? result.utm_medium = params.get('utm_medium') : ''; params.get('utm_campaign') ? result.utm_campaign = params.get('utm_campaign') : ''; params.get('utm_term') ? result.utm_term = params.get('utm_term') : ''; params.get('utm_content') ? result.utm_content = params.get('utm_content') : ''; // Set eventLogged to true so the event is not logged again eventLogged = true; } } } return result; } /** * GTM Events */ // @ts-ignore window.dataLayer = window.dataLayer || []; // open widget function cw_onOpen() { // @ts-ignore dataLayer.push({'event': 'cw_open'}); } // whatsapp clicked function cw_onWhatsapp() { // @ts-ignore dataLayer.push({'event': 'cw_whatsapp'}); } // callback form clicked function cw_onCallbackOpen() { // @ts-ignore dataLayer.push({'event': 'cw_callback_open'}); } // submit callback form function cw_onCallbackSubmit() { // @ts-ignore dataLayer.push({'event': 'cw_callback_submit'}); } // open Jivo chat function cw_chatOpen() { // @ts-ignore dataLayer.push({'event': 'cw_chat_open'}); }