UNPKG

@hhgtech/hhg-components

Version:
1,148 lines (1,124 loc) • 245 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib_es6 = require('./tslib.es6-92cccef3.js'); var React = require('react'); var core = require('@mantine/core'); var dayjs = require('dayjs'); var debounce = require('lodash/debounce'); var form = require('@mantine/form'); var index = require('./index-fa7abbff.js'); var miscCookieHelper = require('./miscCookieHelper.js'); var index$1 = require('./index-c2c283f8.js'); var translationsContext = require('./translationsContext-d63b6d32.js'); var utils$1 = require('./utils-7ba0038a.js'); var index$2 = require('./index-25f2e7a5.js'); var index$3 = require('./index-ae1a5588.js'); var index$5 = require('./index-7cc3b1ef.js'); var index$4 = require('./index-86fd931c.js'); require('./index.styles-6dd86c20.js'); var hooks = require('@mantine/hooks'); require('./useMantineLocale-e946ce4a.js'); var index$9 = require('./index-ad7155cf.js'); require('./index-db44e8cb.js'); var index$7 = require('./index-1ee4ebb8.js'); require('./other-eb0ff2f6.js'); require('./index-9012f1d1.js'); var utils = require('./utils-8a20288d.js'); var dates = require('@mantine/dates'); var usePlacesAutocomplete = require('./usePlacesAutocomplete-c514fa2d.js'); var index$6 = require('./index-b0c1d50a.js'); var translationsProvider = require('./translationsProvider-f3fdeb3e.js'); var Locale = require('./Locale-59ccf941.js'); var uuid = require('uuid'); var PhoneInputBase = require('react-phone-number-input'); var styled = require('@emotion/styled'); var miscTheme = require('./miscTheme.js'); var react = require('@emotion/react'); var togetherComponentGlobalContext = require('./utils-aea77f4a.js'); var index$8 = require('./index-981b4867.js'); var index$b = require('./index-e16696c3.js'); var useScreenSize = require('./useScreenSize-30f50b76.js'); var ReactDOM = require('react-dom'); var index$a = require('./index-b9594844.js'); var InputDate = require('./InputDate-89d470b8.js'); var Close = require('./Close-cc3de432.js'); require('./constantsIsProduction.js'); require('./normalizeLink-4fe5440a.js'); require('./constantsDomainLocales.js'); require('@hhgtech/icons/other'); require('@mantine/carousel'); require('classnames'); require('./useUniqueId-6e2f8c19.js'); require('./constantsSite.js'); require('@hhgtech/icons/core'); require('@mantine/notifications'); require('date-fns/locale'); require('./constantsRiskScreener.js'); require('./i18n-values/en-PH.js'); require('./i18n-values/hi-IN.js'); require('./i18n-values/id-ID.js'); require('./i18n-values/km-KH.js'); require('./i18n-values/ms-MY.js'); require('./i18n-values/my-MM.js'); require('./i18n-values/th-TH.js'); require('./i18n-values/tl-PH.js'); require('./i18n-values/vi-VN.js'); require('./i18n-values/vi-VN_MB.js'); require('./i18n-values/zh-TW.js'); require('./index-3020fcb3.js'); require('slugify'); require('string-format'); require('./togetherApiPaths.js'); require('./constants-bb30dda6.js'); require('vaul'); function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var React__default = /*#__PURE__*/_interopDefault(React); var dayjs__default = /*#__PURE__*/_interopDefault(dayjs); var debounce__default = /*#__PURE__*/_interopDefault(debounce); var styled__default = /*#__PURE__*/_interopDefault(styled); const LeadGenComponentContext = React.createContext({}); const CAMPAIGN_TARGET_TYPE = { LINKS: 1, TAGS: 2 }; let LEAD_API = 'https://dev.leadgen.hellobacsi.com/'; const LEAD_DEVICE_TYPE = { MOBILE: 1, DESKTOP: 2, }; let LEAD_CLASS = ''; if (LEAD_API.includes('localhost')) { LEAD_API = 'https://dev.leadgen.hellobacsi.com/'; } if (location.hostname.includes('marrybaby.vn')) { LEAD_CLASS = 'pink'; } // var LEAD_CURRENT_URL = location.href.toLowerCase(); let LEAD_CURRENT_URL = 'https://' + location.hostname + location.pathname + location.search; LEAD_CURRENT_URL = LEAD_CURRENT_URL.toLowerCase(); // TODO: set inital object if exists if (sessionStorage.getItem('insider_object')) { window.insider_object = JSON.parse(sessionStorage.getItem('insider_object')); } const docLang = document.documentElement.lang; // TODO: country code const LEAD_LOCALE_DATA$1 = { 'vi-VN': { popupLang: 'vi', countryCode: 'vn', countryCodeNumber: 84, }, 'id-ID': { popupLang: 'id', countryCode: 'id', countryCodeNumber: 62, }, 'th-TH': { popupLang: 'th', countryCode: 'th', countryCodeNumber: 66, }, 'ms-MY': { popupLang: 'ms', countryCode: 'my', countryCodeNumber: 60, }, 'zh-TW': { popupLang: 'zh', countryCode: 'tw', countryCodeNumber: 886, }, 'km-KH': { popupLang: 'km', countryCode: 'kh', countryCodeNumber: 855, }, 'my-MM': { popupLang: 'my', countryCode: 'mm', countryCodeNumber: 95, }, 'hi-IN': { popupLang: 'hi', countryCode: 'in', countryCodeNumber: 91, }, }; const LEAD_LOCALE = LEAD_LOCALE_DATA$1[docLang] || LEAD_LOCALE_DATA$1['vi-VN']; function LEAD_RESET_VAR() { // LEAD_CURRENT_URL = location.href.toLowerCase(); LEAD_CURRENT_URL = 'https://' + location.hostname + location.pathname + location.search; } const LEAD_TIMEZONE_DATA = { 1: 'Asia/Ho_Chi_Minh', 10: 'Asia/Ho_Chi_Minh', 11: 'Asia/Ho_Chi_Minh', 12: 'Asia/Ho_Chi_Minh', 2: 'Asia/Jakarta', 3: 'Asia/Bangkok', 4: 'Asia/Phnom_Penh', 5: 'Asia/Kuala_Lumpur', 6: 'Asia/Taipei', 7: 'Asia/Yangon', 8: 'Asia/Kolkata', 9: 'Asia/Manila', // Philippines / Filipinos Site }; const LEADGEN_ACTIONS = { SHOW: 'SHOW', SCROLL: 'SCROLL', TIME: 'TIME', }; const LEADGEN_LAYOUT = { LightBoxA: 'LightBoxA', LightBoxB: 'LightBoxB', SkinA: 'SkinA', SkinB: 'SkinB', Floating: 'Floating', Tab: 'Tab', InlineA: 'InlineA', InlineB: 'InlineB', CenterTab: 'CenterTab', Sidebar: 'Sidebar', Fullscreen: 'Fullscreen', Slider: 'Slider', }; const LEADGEN_BLOCK = { TextBlock: 'TextBlock', NumberBlock: 'NumberBlock', DateBlock: 'DateBlock', EmailBlock: 'EmailBlock', PhoneBlock: 'PhoneBlock', PhoneOtpBlock: 'PhoneOtpBlock', WhatsappOtpBlock: 'WhatsappOtpBlock', ZaloOtpBlock: 'ZaloOtpBlock', LocationBlock: 'LocationBlock', LinkButtonBlock: 'LinkButtonBlock', RadioBlock: 'RadioBlock', DropdownBlock: 'DropdownBlock', CheckboxBlock: 'CheckboxBlock', TncBlock: 'TncBlock', TitleBlock: 'TitleBlock', SubtitleBlock: 'SubtitleBlock', }; const LEADGEN_BLOCK_INPUT = [ LEADGEN_BLOCK.TextBlock, LEADGEN_BLOCK.NumberBlock, LEADGEN_BLOCK.DateBlock, LEADGEN_BLOCK.EmailBlock, LEADGEN_BLOCK.PhoneBlock, LEADGEN_BLOCK.PhoneOtpBlock, LEADGEN_BLOCK.WhatsappOtpBlock, LEADGEN_BLOCK.ZaloOtpBlock, LEADGEN_BLOCK.LocationBlock, LEADGEN_BLOCK.RadioBlock, LEADGEN_BLOCK.DropdownBlock, LEADGEN_BLOCK.CheckboxBlock, LEADGEN_BLOCK.TncBlock, ]; const leadGenFieldNamePhone = (listBlockAdded) => { return listBlockAdded .filter(({ name }) => [ LEADGEN_BLOCK.PhoneBlock, LEADGEN_BLOCK.PhoneOtpBlock, LEADGEN_BLOCK.WhatsappOtpBlock, LEADGEN_BLOCK.ZaloOtpBlock, ].includes(name)) .map(({ data }) => data.value); }; const SSO_MAP_LEAD = ['name', 'email', 'birthday', 'phone', 'gender']; const LEAD_LOCALE_DATA = { 'vi-VN': { popupLang: 'vi', countryCode: 'vn', countryCodeNumber: 84, }, 'id-ID': { popupLang: 'id', countryCode: 'id', countryCodeNumber: 62, }, 'th-TH': { popupLang: 'th', countryCode: 'th', countryCodeNumber: 66, }, 'ms-MY': { popupLang: 'ms', countryCode: 'my', countryCodeNumber: 60, }, 'zh-TW': { popupLang: 'zh', countryCode: 'tw', countryCodeNumber: 886, }, 'km-KH': { popupLang: 'km', countryCode: 'kh', countryCodeNumber: 855, }, 'my-MM': { popupLang: 'my', countryCode: 'mm', countryCodeNumber: 95, }, 'hi-IN': { popupLang: 'hi', countryCode: 'in', countryCodeNumber: 91, }, }; const mappingSSOToLead = (userInfoProps) => { var _a, _b; try { const { id, area_code } = userInfoProps; if (!userInfoProps || !id) { return; } const user = {}; for (const ssoKey of SSO_MAP_LEAD) { if (ssoKey in userInfoProps && typeof (userInfoProps === null || userInfoProps === void 0 ? void 0 : userInfoProps[ssoKey]) !== 'undefined') { const initValue = userInfoProps[ssoKey]; if (ssoKey === 'birthday') { const dob = dayjs__default["default"](initValue, 'YYYY-MM-DD', true); if (dob.isValid()) { user.birthday = dob.toDate(); } } else if (ssoKey === 'gender') { user.gender = initValue.toString(); } else if (ssoKey === 'phone' && typeof area_code !== 'undefined') { user.phone = area_code + initValue; } else { user[ssoKey] = initValue; } } } if (((_a = user === null || user === void 0 ? void 0 : user.email) === null || _a === void 0 ? void 0 : _a.includes('@hhg.com')) || ((_b = user === null || user === void 0 ? void 0 : user.email) === null || _b === void 0 ? void 0 : _b.includes('@facebook.com'))) { delete user.email; } return Object.values(user).length ? user : undefined; } catch (error) { return; } }; const formatCampaignDetail = (campaign) => { if (!campaign) { return {}; } try { const { extra_fields, thank_you_image } = campaign || {}; const { textBlocks: exTextBlocks, imageBlocks: exImageBlocks, listBlockAdded: exListBlockAdded, listBlockThankyou: exListBlockThankyou, actionBlocks: exActionBlocks, } = extra_fields; const textBlocks = JSON.parse(exTextBlocks); const imageBlocks = JSON.parse(exImageBlocks); const listBlockAdded = JSON.parse(exListBlockAdded); const listBlockThankyou = JSON.parse(exListBlockThankyou); const actionBlocks = JSON.parse(exActionBlocks); const ThankYouBlock = { image: { src: thank_you_image }, }; listBlockThankyou.forEach((block) => { const { name, data } = block || {}; const { value: htmlText, align, newtab, url } = data || {}; switch (name) { case LEADGEN_BLOCK.TitleBlock: { ThankYouBlock.title = { htmlText, align }; } case LEADGEN_BLOCK.SubtitleBlock: { ThankYouBlock.description = { htmlText, align }; } case LEADGEN_BLOCK.LinkButtonBlock: { ThankYouBlock.button = { htmlText, newtab, url }; } } }); return Object.assign(Object.assign({}, campaign), { extra_fields: Object.assign(Object.assign({}, extra_fields), { textBlocks, imageBlocks, listBlockAdded, listBlockThankyou, actionBlocks }), ThankYouBlock }); } catch (error) { return {}; } }; class Store { constructor() { this.apiSsoUrl = 'https://staging-id.hellobacsi.com/'; this.apiLeadUrl = 'https://dev.leadgen.hellobacsi.com/'; this.apiSubotUrl = 'https://staging-service-subot.hellohealthgroup.com/'; } } const leadStore = new Store(); const METHOD = { GET: 'get', POST: 'POST', }; const LEADGEN_ERROR_CODE = { UNAUTHORIZED: 'UNAUTHORIZED', }; const LEADGEN_API_PATH = { V2_CAMPAIGN: 'api/v2/campaign', V2_SUBSCRIPTION_LEAD: 'api/v2/subscription-box', V2_SUBSCRIPTION_INFO: 'api/campaign/get-title', }; const SSO_API_PATH = { USER_UPDATE: 'api/user/update', }; const ssoApi = { call(_a) { var { url, data } = _a, config = tslib_es6.__rest(_a, ["url", "data"]); const token = miscCookieHelper.getCookie(index.BEARER_TOKEN_COOKIE); config.body = JSON.stringify(data); config.headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }; if (!token) { return Promise.reject({ code: LEADGEN_ERROR_CODE.UNAUTHORIZED, _data: '', }); } return fetch(`${leadStore.apiSsoUrl}${url}`, config) .then((res) => res.json()) .catch(() => ({})); }, }; const leadApi = { call(_a) { var { url, data = undefined } = _a, config = tslib_es6.__rest(_a, ["url", "data"]); config.body = JSON.stringify(data); config.headers = { 'Content-Type': 'application/json', }; return fetch(`${leadStore.apiLeadUrl}${url}`, config) .then((res) => res.json()) .catch(() => ({})); }, }; const subotApi = { call(_a) { var { url, data } = _a, config = tslib_es6.__rest(_a, ["url", "data"]); config.body = JSON.stringify(data); config.headers = { 'Content-Type': 'application/json', }; return fetch(`${leadStore.apiSubotUrl}${url}`, config) .then((res) => res.json()) .catch(() => ({})); }, }; const campaignGetById = (id) => { return leadApi.call({ url: `api/internal/campaign/${id}`, method: 'get', }); }; const validateEmailOrPhoneOnLeadGen = ({ campaign_id, email, phone, }) => { let phoneToSend = phone; // Remove the '0' part. Logic from Back to check between Subot and Lead with different format if (phoneToSend && phoneToSend.startsWith('0')) { phoneToSend = phoneToSend.substring(1); } return leadApi.call({ url: 'api/subot-campaign/check', method: 'post', data: { campaign_id, email, phone: phoneToSend, }, }); }; const validateEmailOrPhoneOnSubot = ({ bot_id, email, phone, }) => { let phoneToSend = phone; // Remove the '0' part. Logic from Back to check between Subot and Lead with different format if (phoneToSend && phoneToSend.startsWith('0')) { phoneToSend = phoneToSend.substring(1); } return subotApi.call({ url: 'frontend/api/subot-campaign/check', method: 'post', data: { bot_id, email, phone: phoneToSend, }, }); }; const validatePhoneNumberOnLeadGen = ({ campaign_id, phone, }) => { return leadApi.call({ url: 'api/collection/log/check-phone-with-campaign', method: 'post', data: { campaign_id, phone, }, }); }; const LEAD_OTP_API = { whatsapp: 'api/sms/whatsapp_otp', phone: 'api/sms/otp', zalo: 'api/sms/zalo_otp', }; const sendSMSOtpLead = ({ phone, type, }) => { return leadApi.call({ url: LEAD_OTP_API[type], method: 'post', data: { // The type Whatsapp/Zalo do not remove the '+' phone_number: type === 'phone' ? phone.replace('+', '') : phone, }, }); }; const LEAD_VERIFY_OTP_API = { whatsapp: 'api/sms/whatsapp_verify', phone: 'api/sms/verify', zalo: 'api/sms/zalo_verify', }; const verifyOtpLead = ({ phone, otp, type, }) => { return leadApi.call({ url: LEAD_VERIFY_OTP_API[type], method: 'post', data: { // The type Whatsapp/Zalo do not remove the '+' otp_code: otp, phone_number: type === 'phone' ? phone.replace('+', '') : phone, }, }); }; const getCampaignByCode = (campaign_code) => { return leadApi.call({ url: `${LEADGEN_API_PATH.V2_CAMPAIGN}/${campaign_code}`, method: METHOD.GET, }); }; const getSubscriptionBoxInfo = ({ category, site, }) => { return leadApi.call({ url: `${LEADGEN_API_PATH.V2_SUBSCRIPTION_INFO}?category=${category}&site=${site}`, method: METHOD.GET, }); }; const postSubscriptionBoxLead = ({ data }) => { return leadApi.call({ url: LEADGEN_API_PATH.V2_SUBSCRIPTION_LEAD, method: METHOD.POST, data, }); }; const postUserInfoFromLeadGen = ({ name }) => { return ssoApi.call({ url: SSO_API_PATH.USER_UPDATE, method: METHOD.POST, data: { name }, }); }; const campaignPostImpression = ({ code, action, title_article, ga_client_id, cookie_id, extra, url, referrer, }) => { return leadApi.call({ url: `api/campaign/${code}/impression`, method: METHOD.POST, data: { action, title_article, cookie_id, ga_client_id, url, extra, referrer, }, }); }; const Service = { campaignGetById, getCampaignByCode, getSubscriptionBoxInfo, postSubscriptionBoxLead, postUserInfoFromLeadGen, campaignPostImpression, validateEmailOrPhoneOnSubot, validateEmailOrPhoneOnLeadGen, validatePhoneNumberOnLeadGen, sendSMSOtpLead, verifyOtpLead, }; const checkUsedEmailOrPhone = (campaignId, campaign_subot_id, data) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { const key = 'email' in data ? 'email' : 'phone'; const value = 'email' in data ? data.email : data.phone; const errorMsg = 'email' in data ? 'validator.emailUsed' : 'validator.phoneUsed'; /** Check on Leadgen Tool */ const resLeadGen = yield Service.validateEmailOrPhoneOnLeadGen({ campaign_id: [campaignId], [key]: value, // Can be email or phone }); if (resLeadGen._errorCode === 'SubmitLeadWithBotId_ERR_001' || resLeadGen._errorCode === 'SubmitLeadWithBotId_ERR_002') { return errorMsg; } /** Check on Subot */ if (campaign_subot_id.length) { const resSubot = yield Service.validateEmailOrPhoneOnSubot({ bot_id: campaign_subot_id, [key]: value, // Can be email or phone }); if (resSubot._errorCode === 'CheckSuBotLeadTool_ERR_001') { return errorMsg; } } }); const checkUsedPhoneOnly = (campaignId, phone) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { var _a; const resLeadGen = yield Service.validatePhoneNumberOnLeadGen({ campaign_id: campaignId, phone, }); if (((_a = resLeadGen === null || resLeadGen === void 0 ? void 0 : resLeadGen._messages) === null || _a === void 0 ? void 0 : _a[0]) === 'Phone was exist') { return 'validator.phoneUsed'; } }); const validatedCache = { email: {}, phone: {}, phoneOnly: {}, }; const checkUsedEmailOrPhoneWithCache = (campaignId, campaign_subot_id, data) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { const key = 'email' in data ? 'email' : 'phone'; const value = 'email' in data ? data.email : data.phone; const errorMsg = 'email' in data ? 'validator.emailUsed' : 'validator.phoneUsed'; if (validatedCache[key][value]) { if (validatedCache[key][value].value) { return errorMsg; } else if (!validatedCache[key][value].value && validatedCache[key][value].expire > Date.now()) { return ''; } } const res = yield checkUsedEmailOrPhone(campaignId, campaign_subot_id, data); if (res) { validatedCache[key][value] = { value: true, }; } else { validatedCache[key][value] = { value: false, expire: Date.now() + 1000 * 60, }; } return res; }); const checkUsedPhoneOnlyWithCache = (campaignId, phone) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { if (validatedCache.phoneOnly[phone]) { if (validatedCache.phoneOnly[phone].value) { return 'validator.phoneUsed'; } else if (!validatedCache.phoneOnly[phone].value && validatedCache.phoneOnly[phone].expire > Date.now()) { return ''; } } const res = yield checkUsedPhoneOnly(campaignId, phone); if (res) { validatedCache.phoneOnly[phone] = { value: true, }; } else { validatedCache.phoneOnly[phone] = { value: false, expire: Date.now() + 1000 * 60, }; } return res; }); const clearCacheUsedEmailOrPhone = () => { validatedCache.email = {}; validatedCache.phone = {}; validatedCache.phoneOnly = {}; }; // You can give context variables any name const [LeadFormProvider$1, useLeadFormContext$1, useLeadForm$1] = form.createFormContext(); const useLeadFormConfig$1 = ({ listBlockAdded = [], validatingPhoneRef, validatingEmailRef, campaignId, campaign_subot_id = [], userInfo, }) => { const { t } = index$1.useTranslations(); const initialValues = React.useMemo(() => mappingSSOToLead(userInfo), [userInfo === null || userInfo === void 0 ? void 0 : userInfo.id]); React.useEffect(() => { if (!window.intlTelInputUtils) { require('intl-tel-input/build/js/utils'); } }, []); const validateObj = React.useMemo(() => { const InputBlocks = [ 'TextBlock', 'NumberBlock', 'EmailBlock', 'PhoneBlock', 'DateBlock', 'CheckboxBlock', 'RadioBlock', 'DropdownBlock', 'PhoneOtpBlock', 'WhatsappOtpBlock', 'ZaloOtpBlock', 'LocationBlock', 'TncBlock', ]; // ALL are required and can skip if not touched yet const withSharedCheck = (name, cb, // eslint-disable-next-line @typescript-eslint/no-explicit-any block) => { return (value) => { var _a; const isBLockRequired = (_a = block === null || block === void 0 ? void 0 : block.data) === null || _a === void 0 ? void 0 : _a.required; if (!formRef.current.isTouched(name)) return; if (typeof value === 'undefined' || value === '' || (Array.isArray(value) && value.length === 0)) { return isBLockRequired ? t('validator.required') : cb === null || cb === void 0 ? void 0 : cb(value); } return cb === null || cb === void 0 ? void 0 : cb(value); }; }; return listBlockAdded .filter((b) => InputBlocks.includes(b.name)) .reduce((r, b) => { var _a; const isRequired = (_a = b.data.required) !== null && _a !== void 0 ? _a : true; if (b.name === 'NumberBlock') { return Object.assign(Object.assign({}, r), { [b.data.value]: withSharedCheck(b.data.value, (value) => { if (value && isNaN(Number(value))) { return t('validator.number'); } }, b) }); } else if (b.name === 'EmailBlock') { return Object.assign(Object.assign({}, r), { [b.data.value]: withSharedCheck(b.data.value, (value) => { if (value && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) { return t('validator.email'); } if (!value) return; validatingEmailRef.current = true; setTimeout(() => { formRef.current.setFieldError(b.data.value, 'Validating...'); checkUsedEmailOrPhoneWithCache(campaignId, campaign_subot_id, { email: value, }) .then((tKey) => { if (tKey) { formRef.current.setFieldError(b.data.value, t(tKey)); } else { formRef.current.clearFieldError(b.data.value); } validatingEmailRef.current = false; }) .catch((e) => { console.error(e); formRef.current.setFieldError(b.data.value, e.message || 'Something went wrong'); validatingEmailRef.current = false; }); }, 200); }, b) }); } else if (b.name === 'PhoneBlock' || b.name === 'PhoneOtpBlock' || b.name === 'ZaloOtpBlock' || b.name === 'WhatsappOtpBlock') { return Object.assign(Object.assign({}, r), { [b.data.value]: withSharedCheck(b.data.value, (value) => { if (value && window.intlTelInputUtils && !window.intlTelInputUtils.isValidNumber(String(value), LEAD_LOCALE.countryCode)) { return t('validator.phone'); } if (!value) return; validatingPhoneRef.current = true; setTimeout(() => { formRef.current.setFieldError(b.data.value, 'Validating...'); if (b.data.singleSubmission) { checkUsedPhoneOnlyWithCache(campaignId, value) .then((tKey) => { if (tKey) { formRef.current.setFieldError(b.data.value, t(tKey)); } else { formRef.current.clearFieldError(b.data.value); } validatingPhoneRef.current = false; }) .catch((err) => { console.error(err); formRef.current.setFieldError(b.data.value, err.message || 'Something went wrong'); validatingPhoneRef.current = false; }); } else { checkUsedEmailOrPhoneWithCache(campaignId, campaign_subot_id, { phone: value, }) .then((tKey) => { if (tKey) { formRef.current.setFieldError(b.data.value, t(tKey)); } else { formRef.current.clearFieldError(b.data.value); } validatingPhoneRef.current = false; }) .catch((e) => { console.error(e); formRef.current.setFieldError(b.data.value, e.message || 'Something went wrong'); validatingPhoneRef.current = false; }); } }, 200); }, b) }); } else if (b.name === 'DateBlock') { return Object.assign(Object.assign({}, r), { [b.data.value]: withSharedCheck(b.data.value, (value) => { if (value && isNaN(Date.parse(value))) { return t('validator.date'); } }, b) }); } else if (b.name === 'TncBlock') { return Object.assign(Object.assign({}, r), { [`TNC-` + b.id]: withSharedCheck('TNC-' + b.id, (value) => { if (isRequired && !value) { return t('validator.required'); } }, b) }); } else { return Object.assign(Object.assign({}, r), { [b.data.value]: withSharedCheck(b.data.value, undefined, b) }); } }, {}); }, [listBlockAdded.map((b) => b.name).join(',')]); const form = useLeadForm$1({ validateInputOnChange: true, clearInputErrorOnChange: true, validate: validateObj, initialValues, }); const formRef = React.useRef(form); formRef.current = form; return { form, validateObj }; }; const Component = ({ campaign, onClose: onCloseProp, onOtherSubmit, onSubmit, showThankyou, setShowThankyou, locale, children, showEmpty, setShowEmpty, userInfo, }) => { var _a, _b; const extraFields = campaign.extra_fields; const campaignId = campaign.id; const campaign_subot_id = campaign.bot_id || []; const listBlockAdded = JSON.parse(extraFields.listBlockAdded); const actionBlocks = JSON.parse(extraFields.actionBlocks); const textBlocks = JSON.parse(extraFields.textBlocks); const heading = ((_b = (_a = textBlocks === null || textBlocks === void 0 ? void 0 : textBlocks.titleBlock) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.value) || ''; const description = textBlocks.subtitleBlock.data.value; const validatingPhoneRef = React.useRef(false); const validatingEmailRef = React.useRef(false); const leadFormConfig = useLeadFormConfig$1({ listBlockAdded, validatingPhoneRef, validatingEmailRef, campaignId, campaign_subot_id, userInfo, }); const [showOtpPhone, setShowOtpPhone] = React.useState(null); const [formRef, setFormRef] = React.useState(null); const onClose = () => { if (showOtpPhone) { setShowOtpPhone(null); } else { onCloseProp === null || onCloseProp === void 0 ? void 0 : onCloseProp(); } }; React.useEffect(() => { clearCacheUsedEmailOrPhone(); }, []); return campaign ? (React__default["default"].createElement(LeadGenComponentContext.Provider, { value: { campaignId, campaign_subot_id, heading, description, listBlockAdded, textBlocks, actionBlocks, leadFormConfig, validatingEmailRef, validatingPhoneRef, formRef: { current: formRef }, setFormRef, locale, onClose, onOtherSubmit, showOtpPhone, setShowOtpPhone, onSubmit, showThankyou, setShowThankyou, showEmpty, setShowEmpty, } }, children)) : null; }; const Description = (_a) => { var rest = tslib_es6.__rest(_a, []); const { description } = React.useContext(LeadGenComponentContext); return description ? (React__default["default"].createElement(index$2.Text, Object.assign({ size: "p3" }, rest), description)) : null; }; const LeadGenContext$1 = React.createContext({}); var useStyles$2 = core.createStyles(() => { return { control: {}, }; }); const libraries$1 = ['places']; const LocationBlock = ({ name, placeholder, locale, required = true, }) => { var _a; const form = useLeadFormContext$1(); const [searchValue, setSearchValue] = React.useState(''); const [address, setAddress] = React.useState(''); const { predictions } = usePlacesAutocomplete.usePlacesAutocomplete(searchValue, '', locale === 'tl-PH' ? 'en' : (_a = locale === null || locale === void 0 ? void 0 : locale.split('-')) === null || _a === void 0 ? void 0 : _a[0]); const [LoadScript, setLoadScript] = React.useState(null); const [ready, setReady] = React.useState(false); const randRef = React.useRef(Math.random().toString(36).substring(7)); const options = React.useMemo(() => { const _opts = predictions.map((p) => { return { value: p.description, label: p.description, }; }); const isExist = _opts.find((o) => o.value === address); if (!address || isExist) { return _opts; } return [{ value: address, label: address }].concat(_opts); }, [predictions, address]); React.useEffect(() => { var _a, _b, _c; // only load extra google script when not yet loaded if (!((_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.maps) === null || _b === void 0 ? void 0 : _b.places) === null || _c === void 0 ? void 0 : _c.AutocompleteService)) { Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@react-google-maps/api')); }).then((m) => { setLoadScript(() => m.LoadScript); setTimeout(() => { setReady(true); }, 200); }); } else { setReady(true); } }, []); if (!ready) return (React__default["default"].createElement("div", { style: { height: 73, } })); return (React__default["default"].createElement(React__default["default"].Fragment, null, LoadScript && (React__default["default"].createElement(LoadScript, { googleMapsApiKey: usePlacesAutocomplete.GOOGLE_API_KEY, libraries: libraries$1, loadingElement: React__default["default"].createElement(React__default["default"].Fragment, null) })), React__default["default"].createElement("div", { style: { display: 'none' }, "data-extra": true, "data-name": name, "data-control": 'text' }), React__default["default"].createElement(index$3.Select, Object.assign({ className: "lead-modal__form-control", label: placeholder, placeholder: placeholder, withAsterisk: required, name: name, data: options, searchValue: searchValue, onSearchChange: (query) => { setSearchValue(query); }, filter: () => true, clearable: true, searchable: true, onChange: (val) => setAddress(val || ''), icon: React__default["default"].createElement("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none" }, React__default["default"].createElement("path", { d: "M10 9.792q.605 0 1.032-.427.426-.428.426-1.032 0-.603-.426-1.031A1.4 1.4 0 0 0 10 6.875q-.604 0-1.032.427a1.4 1.4 0 0 0-.426 1.031q0 .604.426 1.032.428.426 1.032.427m0 8.083q-.145 0-.292-.042a.7.7 0 0 1-.27-.145Q6.478 15 5.01 12.708 3.54 10.418 3.54 8.5q0-3.021 1.949-4.823T10 1.875t4.51 1.802q1.95 1.802 1.949 4.823 0 1.917-1.468 4.208-1.47 2.292-4.427 4.98a.7.7 0 0 1-.271.145 1 1 0 0 1-.292.042", fill: "#8C8C8C" })), autoComplete: 'no-auto-complete-' + randRef.current, rightSection: React__default["default"].createElement(React__default["default"].Fragment, null) }, form.getInputProps(name))))); }; const SubtitleBlock$1 = ({ children, align, }) => (React__default["default"].createElement("p", { className: `lead-modal__description ${'le-text-align-' + (align || '')} ${LEAD_CLASS}` }, children)); const TitleBlock$1 = ({ children, align, }) => (React__default["default"].createElement("h2", { className: `lead-modal__title ${'le-text-align-' + (align || '')} ${LEAD_CLASS}` }, children)); const Fields = ({ listBlockAdded, popupId, locale, onClose, onOtherSubmit, styles, classNames, popoverProps, }) => { const { primaryColor } = React.useContext(LeadGenContext$1); const { classes, cx } = useStyles$2(undefined, { name: 'LeadGen__Field', styles, classNames, }); const form = useLeadFormContext$1(); return (React__default["default"].createElement(React__default["default"].Fragment, null, listBlockAdded.map((b, index) => { var _a; const { name = '', data = {} } = b || {}; const { placeholder, value, align, listQuestion, isSendMailChimp = false, newtab, url, } = data; const required = (_a = data.required) !== null && _a !== void 0 ? _a : true; switch (name) { case 'TitleBlock': return (React__default["default"].createElement(TitleBlock$1, { key: index, align: align }, value)); case 'SubtitleBlock': return (React__default["default"].createElement(SubtitleBlock$1, { key: index, align: align }, value)); case 'TextBlock': return (React__default["default"].createElement(index$3.Input, Object.assign({ key: index, withAsterisk: required, spellCheck: false, type: "text", placeholder: placeholder, className: cx('leadgen-control', classes.control), // onChangeRaw={(e) => inputOnChange('text', e)} label: placeholder, "data-control": "text", name: value }, form.getInputProps(value)))); case 'NumberBlock': return (React__default["default"].createElement(index$3.NumberInput, Object.assign({ key: index, withAsterisk: required, spellCheck: false, type: "number", placeholder: placeholder, className: cx('leadgen-control', classes.control), // onChange={(e) => inputOnChange('number', e)} label: placeholder, "data-control": "number", name: value }, form.getInputProps(value)))); case 'EmailBlock': return (React__default["default"].createElement(index$3.Input, Object.assign({ key: index, withAsterisk: required, spellCheck: false, // type="email" placeholder: placeholder, className: cx('leadgen-control', classes.control), label: placeholder, "data-control": "email", name: value }, form.getInputProps(value)))); case 'PhoneOtpBlock': case 'WhatsappOtpBlock': case 'ZaloOtpBlock': case 'PhoneBlock': { const id = popupId + '-' + value + '-' + index; return (React__default["default"].createElement(index$3.Input.Wrapper, Object.assign({ size: "md", withAsterisk: required, key: index, label: placeholder, // error={errorField.phone} className: cx('leadgen-control', classes.control), labelProps: { htmlFor: id, } }, form.getInputProps(value)), React__default["default"].createElement(index$3.Phone, { name: value, spellCheck: false, type: "tel", placeholder: placeholder, value: form.getInputProps(value).value, onChange: (v) => { form.setFieldValue(value, v); }, // onBlur={(e) => inputOnBlur('tel', e)} id: id, defaultCountry: (locale ? utils.MAPPED_LOCALE[locale] || 'VN' : 'VN'), "data-control": "tel" }))); } case 'LocationBlock': { return (React__default["default"].createElement(LocationBlock, { key: index, name: value, placeholder: placeholder, locale: locale, required: required })); } case 'DateBlock': return (React__default["default"].createElement(React__default["default"].Fragment, null, React__default["default"].createElement(index$5.DatePicker, Object.assign({ withAsterisk: required, key: index, type: "default", name: value, placeholder: placeholder, className: cx('leadgen-control', classes.control), label: placeholder, "data-control": "date", popoverProps: popoverProps }, form.getInputProps(value))), React__default["default"].createElement("input", { type: "hidden", name: value, "data-control": "date" }))); case 'LinkButtonBlock': return (React__default["default"].createElement("div", { key: index }, React__default["default"].createElement("a", { target: newtab ? 'blank' : 'parrent', href: url, style: { textDecoration: 'none' } }, React__default["default"].createElement(index$4.Button, { type: "button", size: "md", color: primaryColor, className: `lead-modal__btn ${LEAD_CLASS}`, onClick: () => { onClose === null || onClose === void 0 ? void 0 : onClose(); onOtherSubmit === null || onOtherSubmit === void 0 ? void 0 : onOtherSubmit(); } }, value)))); case 'CheckboxBlock': return (React__default["default"].createElement(React__default["default"].Fragment, null, isSendMailChimp && (React__default["default"].createElement("div", { style: { display: 'none', }, "data-name": value + '-mailchimp' })), React__default["default"].createElement(index$3.Checkbox.Group, Object.assign({ withAsterisk: required, className: cx('leadgen-control', classes.control), key: index, label: placeholder, size: "md", sx: { display: 'flex', flexDirection: 'column', gap: 8, } }, form.getInputProps(value)), listQuestion.map((l, _index) => (React__default["default"].createElement(index$3.Checkbox, { name: value, key: _index, value: l.value, label: l.placeholder, "data-control": "checkbox" })))))); case 'RadioBlock': return (React__default["default"].createElement(React__default["default"].Fragment, null, isSendMailChimp && (React__default["default"].createElement(index$3.Input, { type: "hidden", name: value + '-mailchimp', value: isSendMailChimp })), React__default["default"].createElement(index$3.Radio.Group, Object.assign({ withAsterisk: required, className: cx('leadgen-control', classes.control), key: index, label: placeholder, size: "md" }, form.getInputProps(value)), listQuestion.map((l, _index) => (React__default["default"].createElement(index$3.Radio, { name: value, key: _index, value: l.value, label: l.placeholder, "data-control": "radio" })))))); case 'DropdownBlock': return (React__default["default"].createElement(React__default["default"].Fragment, null, React__default["default"].createElement("div", { style: { display: 'none' }, "data-extra": true, "data-name": value, "data-control": 'dropdown' }), React__default["default"].createElement(index$3.Select, Object.assign({ key: index, className: cx('leadgen-control', classes.control), label: placeholder, withAsterisk: required, name: value, data: listQuestion.map((l) => ({ value: l.value, label: l.placeholder, })) }, form.getInputProps(value))))); case 'TncBlock': const tncInputProps = form.getInputProps('TNC-' + b.id); return (React__default["default"].createElement(React__default["default"].Fragment, null, React__default["default"].createElement(index$3.Checkbox, Object.assign({ name: 'TNC-' + b.id, key: b.id, label: React__default["default"].createElement("p", { className: "lead-modal__tnc-link", dangerouslySetInnerHTML: { __html: data.valueHTML } }), className: "tnc-block", "data-control": "checkbox" }, tncInputProps, { error: tncInputProps.error ? tncInputProps.error : undefined })))); } return null; }))); }; var useStyles$1 = core.createStyles((theme) => { return { root: {}, header: {}, heading: {}, description: {}, term: { a: { color: theme.fn.primaryColor(), }, }, controlList: {}, control: {}, submitBtn: {}, submitBtnWrapper: {}, }; }); const Heading = (_a) => { var rest = tslib_es6.__rest(_a, []); const { heading } = React.useContext(LeadGenComponentContext); return heading ? (React__default["default"].createElement(index$2.Text, Object.assign({ size: "h3" }, rest), heading)) : null; }; const FormComponent = ({ styles, className, classNames, fillInfo, popoverProps, submitProps, }) => { var _a; const { primaryColor } = React.useContext(LeadGenContext$1); const { listBlockAdded, leadFormConfig: { form, validateObj }, validatingEmailRef, validatingPhoneRef, formRef, setFormRef, onClose, onOtherSubmit, actionBlocks, locale, setShowOtpPhone, onSubmit, } = React.useContext(LeadGenComponentContext); const { classes, cx } = useStyles$1(undefined, { name: 'LeadGen__FormComponent', styles, classNames, }); const [isSubmitLoading, setIsSubmitLoading] = React.useState(false); const popUpSubmitText = actionBlocks.submitBlock.data.value; const middlewareOnSubmit = (e) => { e.preventDefault(); // mark all as touched to allow validation form.setTouched(Object.keys(validateObj).reduce((acc, cur) => { acc[cur] = true; return acc; }, {})); if (validatingEmailRef.current || validatingPhoneRef.current) { return; } setTimeout(() => { form.onSubmit((v) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j; if (Object.keys(form.errors).length) return; let newShowOtpPhone = null; if (listBlockAdded.findIndex((x) => x.name === 'PhoneOtpBlock') > -1) { // not submit yet, open otp const fieldName = (_b = (_a = listBlockAdded.find((x) => x.name === 'PhoneOtpBlock')) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.value; if ((_c = v[fieldName]) === null || _c === void 0 ? void 0 : _c.startsWith('+')) { newShowOtpPhone = { phone: v[fieldName], type: 'phone', }; } } if (listBlockAdded.findIndex((x) => x.name === 'WhatsappOtpBlock') > -1) { // not submit yet, open otp const fieldName = (_e = (_d = listBlockAdded.find((x) => x.name === 'WhatsappOtpBlock')) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.value; if ((_f = v[fieldName]) === null || _f === void 0 ? void 0 : _f.startsWith('+')) { newShowOtpPhone = { phone: v[fieldName], type: 'whatsapp', }; } } if (listBlockAdded.findIndex((x) => x.name === 'ZaloOtpBlock') > -1) { // not submit yet, open otp const fieldName = (_h = (_g = listBlockAdded.find((x) => x.name === 'ZaloOtpBlock')) === null || _g === void 0 ? void 0 : _g.data) === null || _h === void 0 ? void 0 : _h.value; if ((_j = v[fieldName]) === null || _j === void 0 ? void 0 : _j.startsWith('+')) { newShowOtpPhone = { phone: v[fieldName], type: 'zalo', }; } } if (newShowOtpPhone) { setIsSubmitLoading(true); Service.sendSMSOtpLead(newShowOtpPhone) .then((res) => { var _a; const respMessage = (_a = res === null || res === void 0 ? void 0 : res._messages) === null || _a === void 0 ? void 0 : _a[0];