UNPKG

@hhgtech/hhg-components

Version:
1,023 lines (995 loc) 291 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var index$2 = require('./index-ad7155cf.js'); var tslib_es6 = require('./tslib.es6-92cccef3.js'); var index$3 = require('./index-1ee4ebb8.js'); var Cookies = require('js-cookie'); var fd = require('fastdom'); var fastdomPromised = require('fastdom/extensions/fastdom-promised'); var togetherComponentGlobalContext = require('./utils-aea77f4a.js'); var formatString = require('string-format'); var index$1 = require('./index-224bb98e.js'); var dayjs = require('dayjs'); var constantsDomainLocales = require('./constantsDomainLocales.js'); var cn = require('classnames'); var index$b = require('./index-9e79d4c7.js'); var index$a = require('./index-caa8a8c1.js'); var framerMotion = require('framer-motion'); var styled = require('@emotion/styled'); var utils = require('./utils-7ba0038a.js'); var index$4 = require('./index-86fd931c.js'); var remarkable = require('remarkable'); var other = require('@hhgtech/icons/other'); var reactIntersectionObserver = require('react-intersection-observer'); var core = require('@mantine/core'); var index$5 = require('./index-db44e8cb.js'); var isSameOrBefore = require('dayjs/plugin/isSameOrBefore'); var constants = require('./constants-bb30dda6.js'); var uuid = require('uuid'); var index$6 = require('./index-25f2e7a5.js'); var miscTheme = require('./miscTheme.js'); var constantsIsProduction = require('./constantsIsProduction.js'); var index$7 = require('./index-ae1a5588.js'); require('@mantine/dates'); require('./useMantineLocale-e946ce4a.js'); require('./index.styles-6dd86c20.js'); require('./translationsContext-d63b6d32.js'); require('@mantine/hooks'); require('./other-eb0ff2f6.js'); require('./index-9012f1d1.js'); var isEmpty = require('lodash/isEmpty'); var reactHookForm = require('react-hook-form'); var PhoneInputBase = require('react-phone-number-input'); var api = require('@react-google-maps/api'); var usePlacesAutocomplete = require('./usePlacesAutocomplete-c514fa2d.js'); var miscDefaultClassWrapper = require('./miscDefaultClassWrapper.js'); var Locale = require('./Locale-59ccf941.js'); var InputDate = require('./InputDate-89d470b8.js'); var index$8 = require('./index-b9594844.js'); var index$9 = require('./index-e12fe769.js'); var store = require('./store-c7185440.js'); var utils$1 = require('./utils-084e965a.js'); require('date-fns/locale'); require('./constantsSite.js'); require('./constantsRiskScreener.js'); require('./index-3020fcb3.js'); require('./miscCookieHelper.js'); require('slugify'); require('./togetherApiPaths.js'); require('./index-e4e2220d.js'); require('./WhatsApp-931de57c.js'); require('./Spinner-af067a8f.js'); require('./index-c2c283f8.js'); require('./useScreenSize-30f50b76.js'); require('@mantine/carousel'); require('./useUniqueId-6e2f8c19.js'); require('@hhgtech/icons/core'); require('@mantine/notifications'); require('@emotion/react'); require('zustand'); require('./index-fa7abbff.js'); require('./normalizeLink-4fe5440a.js'); require('./healthTools-66a8dc09.js'); function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefault(React); var Cookies__default = /*#__PURE__*/_interopDefault(Cookies); var fd__default = /*#__PURE__*/_interopDefault(fd); var fastdomPromised__default = /*#__PURE__*/_interopDefault(fastdomPromised); var formatString__default = /*#__PURE__*/_interopDefault(formatString); var dayjs__default = /*#__PURE__*/_interopDefault(dayjs); var cn__default = /*#__PURE__*/_interopDefault(cn); var styled__default = /*#__PURE__*/_interopDefault(styled); var isSameOrBefore__default = /*#__PURE__*/_interopDefault(isSameOrBefore); var isEmpty__default = /*#__PURE__*/_interopDefault(isEmpty); var PhoneInputBase__default = /*#__PURE__*/_interopDefault(PhoneInputBase); // extend fastdom const fastdom = fd__default["default"].extend(fastdomPromised__default["default"]); const PATHS$1 = { POST_VERIFY_SMS_OTP: 'sms/update-phone', POST_SEND_OTP: 'sms/otp', POST_SEND_OTP_WHATSAPP: 'whatsapp/otp', POST_VERIFY_OTP: 'sms/verify', POST_VERIFY_OTP_WHATSAPP: 'sms/verify-whatsapp', GET_LANDING_PAGE_FIRST_NODE: 'landing_page/bot', GET_LANDING_PAGE_NEXT_NODE: 'landing_page/messages', POST_LANDING_PAGE_IMPRESSION: 'landing_page/impressions', POST_LANDING_PAGE_CLICK: 'landing_page/clicks', GET_INLINE_FIRST_NODE: 'bots', GET_INLINE_MESSAGE: 'inline/messages', GET_INLINE_IMPRESSION: 'inline/impressions', GET_INLINE_CLICK: 'inline/clicks', GET_SUBOT_LOG: 'log/bot/{botId}/{cookieId}/{accountId}?type={type}', POST_SUBOT_CREATE_LOG: 'log/bot', FETCH_URL_DATA: 'preview', GET_VOUCHER_QUANTITY: 'vouchers/total_quantity?search={search}&client_id={clientId}', }; const TIMEOUT = 30 * 60 * 1000; const WAITING_FIRST_RESP = 'waitingTheFirstResponse'; const CachedSystem = { // eslint-disable-next-line @typescript-eslint/no-explicit-any cached: {}, clearCached: (prefix) => { console.log(CachedSystem.cached); Object.keys(CachedSystem.cached) .filter((k) => k.startsWith(prefix)) .forEach((key) => { console.log(key); CachedSystem.cached[key] = undefined; }); }, withCached: (key, fnResponse) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { if (CachedSystem.cached[key] === WAITING_FIRST_RESP) { return new Promise((resolve) => { const startDate = new Date().getTime(); const intervalId = setInterval(() => { const currentDate = new Date().getTime(); if (currentDate - startDate > 3000) { clearInterval(intervalId); } if (typeof CachedSystem.cached[key] === 'object') { resolve(CachedSystem.cached[key]); clearInterval(intervalId); } }, 100); }); } if (typeof CachedSystem.cached[key] === 'object') { return CachedSystem.cached[key]; } CachedSystem.cached[key] = 'waitingTheFirstResponse'; try { const result = yield fnResponse(); CachedSystem.cached[key] = result; setTimeout(() => { CachedSystem.cached[key] = undefined; }, TIMEOUT); return result; } catch (err) { CachedSystem.cached[key] = undefined; return Promise.reject(err); } }), }; const getSubotApiPath = (path, params) => { const { subotApiUrl } = togetherComponentGlobalContext.GlobalData === null || togetherComponentGlobalContext.GlobalData === void 0 ? void 0 : togetherComponentGlobalContext.GlobalData.env; const apiUrl = subotApiUrl.endsWith('frontend/api/') ? subotApiUrl : subotApiUrl + 'frontend/api/'; return apiUrl + formatString__default["default"](path, Object.assign({}, params)); }; /** inline message */ const subotInlineMessage = (data) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { try { return yield togetherComponentGlobalContext.callApi(getSubotApiPath(PATHS$1.GET_INLINE_MESSAGE), 'POST', { data, }); } catch (error) { } }); const computeExtraSettingsForBot = (data) => { var _a; if ((data === null || data === void 0 ? void 0 : data._status) === 1 && ((_a = data === null || data === void 0 ? void 0 : data._data) === null || _a === void 0 ? void 0 : _a.extra_settings)) { try { const extraSettingsObj = JSON.parse(data._data.extra_settings); if (typeof extraSettingsObj === 'object') { data._data.extra_settings = extraSettingsObj; } else { data._data.extra_settings = { sync_data_friso_campaign: false, }; } } catch (err) { data._data.extra_settings = { sync_data_friso_campaign: false, }; } } return data; }; /** inline first node */ const subotInlineFirstNode = (id) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { try { const data = yield CachedSystem.withCached('SubotInlineFirstNode/' + id, () => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { const response = yield togetherComponentGlobalContext.callApi(getSubotApiPath(PATHS$1.GET_INLINE_FIRST_NODE) + `/${id}`, 'GET'); computeExtraSettingsForBot(response); return response; })); return data; } catch (error) { return null; } }); /** inline click */ const subotInlineClick = (data) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { try { return yield togetherComponentGlobalContext.callApi(getSubotApiPath(PATHS$1.GET_INLINE_CLICK), 'POST', { data, }); } catch (error) { } }); /** inline impression */ const subotInlineImpression = (data) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { try { return yield togetherComponentGlobalContext.callApi(getSubotApiPath(PATHS$1.GET_INLINE_IMPRESSION), 'POST', { data, }); } catch (error) { } }); const calcAge = (value) => { const birthDate = dayjs__default["default"](value); const today = dayjs__default["default"](); return { birthDate, today, age: today.diff(birthDate, 'year'), }; }; /** * Temporary hard the range of age from 1 -> 6 for Durgo Campaign at this time * Ticket: https://hhgdev.atlassian.net/browse/HTO-1327 */ const validateAge = (value, errMsg, conditions) => { const { birthDate, today } = calcAge(value); if (!conditions || !conditions.length) { return true; } const diff = today.diff(birthDate, 'M') / 12; /** * No body in future can validate */ if (diff < 0 || (diff === 0 && today.date() < birthDate.date())) { return errMsg; } /** * from, to * if from === null then compare 0 - to * if to === null then compare from - infinity */ let isValid = false; if (Array.isArray(conditions)) { for (const cond of conditions) { const { from, to } = cond || {}; if (!from && !to) { break; } if ((from <= diff && diff <= to) || (from <= diff && to === null) || (from === null && to <= diff)) { isValid = true; break; } } } if (typeof localStorage !== 'undefined' && localStorage.getItem('hhg_debug') === 'true') { console.log('Log __DOB__ : ', { conditions, isValid, diff }); } return isValid || errMsg; }; const getDynamicScore = (node) => { try { return node.dynamic_score || {}; } catch (err) { return {}; } }; const getCurrentTotalDynamicScore = (listNodes, activeId, nextActionId, _formSubmitMeta) => { const dynamicScoreHash = getDynamicScore(listNodes[0]); // const isDynamicScoreMode = Object.keys(dynamicScoreHash).length > 0 if (!activeId) { return {}; } const currentIdx = listNodes.findIndex((n) => n.id == activeId); // console.log('[LogDynamicScore] currentIdx', currentIdx) // console.log('[LogDynamicScore] listNodes', listNodes) // console.log('[LogDynamicScore] activeId', activeId) const current_total_dynamic_score = listNodes.reduce((totalScore, _node, idx) => { var _a, _b; if (idx > currentIdx) { return totalScore; } const node = _node; // 1. Chưa chọn action nào trước đó. Chọn Action mới. Không có "node._message" // 2. Đã chọn một action trước đó rồi giờ edit lại. Có "node._message" // 3. Nếu có truyền "nextActionId" tính luôn cả action tiếp theo chuẩn bị chọn // Giả lập object _message sau khi đã chọn. const nodeMessage = nextActionId && node.id === activeId ? { action_id: nextActionId } : node._message; let acc = 0; // Calculate normal action score const currentSelectedAction = (_a = node.actions) === null || _a === void 0 ? void 0 : _a.find((act) => act.id === (nodeMessage === null || nodeMessage === void 0 ? void 0 : nodeMessage.action_id)); acc = acc + ((currentSelectedAction === null || currentSelectedAction === void 0 ? void 0 : currentSelectedAction.score) || 0); // Calculate dynamic action score. const isNodeWithDynamicScore = typeof dynamicScoreHash[node.id] !== 'undefined'; const formSubmitMeta = nextActionId && node.id === activeId ? _formSubmitMeta : nodeMessage === null || nodeMessage === void 0 ? void 0 : nodeMessage.form_submit_meta; if (isNodeWithDynamicScore && node.type === index$2.NodeType.FORM && formSubmitMeta) { // debugger // NodeId hiện tại có trong object "dynamic_score" // Lấy ra action // Kết hợp với action id đã chọn const actionIdsDynamicScore = dynamicScoreHash[node.id].action_ids.map((i) => i.id); const actionVarsDynamicScore = dynamicScoreHash[node.id].action_ids.map((i) => i.variableName); const formula = dynamicScoreHash[node.id].formula; const foundActions = (_b = node.actions) === null || _b === void 0 ? void 0 : _b.filter((act) => actionIdsDynamicScore.includes(act.id)); const foundFormMetas = formSubmitMeta.filter((f) => foundActions.find((a) => a.key === f.key) && (f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_NUMBER] || f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_DOB])); const formulaWithVariable = actionVarsDynamicScore .map((variableName, idx) => { const variableMapToActionId = actionIdsDynamicScore[idx]; const variableMapToAction = foundActions.find((act) => act.id === variableMapToActionId); const formValue = foundFormMetas.find((f) => (variableMapToAction === null || variableMapToAction === void 0 ? void 0 : variableMapToAction.key) === f.key && (f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_NUMBER] || f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_DOB])); if (!formValue) return ''; if (formValue.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_DOB]) { const { age } = calcAge(dayjs__default["default"](formValue.value).toDate()); return `var ${variableName} = ${age};`; } return `var ${variableName} = ${formValue.value};`; }) .join(''); try { const computedValue = new Function(`${formulaWithVariable} return ${formula}`)(); if (!isNaN(computedValue)) { acc = acc + Math.round(computedValue); } } catch (err) { } } return totalScore + acc; }, 0); return { current_total_dynamic_score }; }; const replaceTextWithVariables = (label, listNodes) => { const dynamicScoreHash = getDynamicScore(listNodes[0]); try { const listFormNodes = listNodes.filter((node) => node.type === index$2.NodeType.FORM); /** Apply for dynamic score */ Object.keys(dynamicScoreHash).forEach((nodeId) => { var _a, _b, _c; const foundNode = listFormNodes.find((node) => node.id === nodeId); const actionIdsDynamicScore = dynamicScoreHash[nodeId].action_ids.map((i) => i.id); const actionVarsDynamicScore = dynamicScoreHash[nodeId].action_ids.map((i) => i.variableName); const formula = dynamicScoreHash[nodeId].formula; const foundActions = (_a = foundNode === null || foundNode === void 0 ? void 0 : foundNode.actions) === null || _a === void 0 ? void 0 : _a.filter((act) => actionIdsDynamicScore.includes(act.id)); const foundFormMetas = (_c = (_b = foundNode === null || foundNode === void 0 ? void 0 : foundNode._message) === null || _b === void 0 ? void 0 : _b.form_submit_meta) === null || _c === void 0 ? void 0 : _c.filter((f) => foundActions.find((a) => a.key === f.key) && (f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_NUMBER] || f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_DOB])); if (dynamicScoreHash[nodeId].formula && dynamicScoreHash[nodeId].formula_result_name && (foundFormMetas === null || foundFormMetas === void 0 ? void 0 : foundFormMetas.length)) { const formulaWithVariable = actionVarsDynamicScore .map((variableName, idx) => { const variableMapToActionId = actionIdsDynamicScore[idx]; const variableMapToAction = foundActions.find((act) => act.id === variableMapToActionId); const formValue = foundFormMetas.find((f) => (variableMapToAction === null || variableMapToAction === void 0 ? void 0 : variableMapToAction.key) === f.key && (f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_NUMBER] || f.control === index$2.ELEMENT_CONTROL_INPUT_TYPE[index$2.NodeActionType.USER_SUBMIT_DOB])); if (!formValue) return ''; return `var ${variableName} = ${formValue.value};`; }) .join(''); const computedValue = new Function(`${formulaWithVariable} return ${formula}`)(); const formKey = dynamicScoreHash[nodeId].formula_result_name; if (!isNaN(computedValue) && label.includes(`{{var:${formKey}}}`)) { const regex = new RegExp(`{{var:${formKey}}}`, 'g'); label = label.replace(regex, String(Math.floor(computedValue * 100) / 100)); } } }); /** Apply for normal field in form */ listFormNodes.map((formNode) => { var _a, _b; (_b = (_a = formNode._message) === null || _a === void 0 ? void 0 : _a.form_submit_meta) === null || _b === void 0 ? void 0 : _b.map((formMeta) => { const formKey = formMeta.key; const formValue = formMeta.value; const regex = new RegExp(`{{var:${formKey}}}`, 'g'); label = label.replace(regex, formValue); }); }); } catch (err) { console.log('[replaceTextWithVariables]', err); } return label; }; const KEY_OF_TEXT_CHOICE_WITH_OTHER_FIELD = 'other'; const STATE_SUBOT_INLINE_KEY = 'stateInlineSSO'; /** Clone from this package https://github.com/sindresorhus/hex-rgb/blob/main/index.js */ /* eslint-disable no-redeclare */ /** Convert HEX color to RGBA. @param hex - The color in HEX format. Leading `#` is optional. @example ``` import hexRgb from 'hex-rgb'; hexRgb('4183c4'); //=> {red: 65, green: 131, blue: 196, alpha: 1} hexRgb('#4183c4'); //=> {red: 65, green: 131, blue: 196, alpha: 1} hexRgb('#fff'); //=> {red: 255, green: 255, blue: 255, alpha: 1} hexRgb('#22222299'); //=> {red: 34, green: 34, blue: 34, alpha: 0.6} hexRgb('#0006'); //=> {red: 0, green: 0, blue: 0, alpha: 0.4} hexRgb('#cd2222cc'); //=> {red: 205, green: 34, blue: 34, alpha: 0.8} hexRgb('#cd2222cc', {format: 'array'}); //=> [205, 34, 34, 0.8] hexRgb('#cd2222cc', {format: 'css'}); //=> 'rgb(205 34 34 / 80%)' hexRgb('#000', {format: 'css'}); //=> 'rgb(0 0 0)' hexRgb('#22222299', {alpha: 1}); //=> {red: 34, green: 34, blue: 34, alpha: 1} hexRgb('#fff', {alpha: 0.5}); //=> {red: 255, green: 255, blue: 255, alpha: 0.5} ``` */ const hexCharacters = 'a-f\\d'; const match3or4Hex = `#?[${hexCharacters}]{3}[${hexCharacters}]?`; const match6or8Hex = `#?[${hexCharacters}]{6}([${hexCharacters}]{2})?`; const nonHexChars = new RegExp(`[^#${hexCharacters}]`, 'gi'); const validHexSize = new RegExp(`^${match3or4Hex}$|^${match6or8Hex}$`, 'i'); function hexRgb(hex, options) { if (typeof hex !== 'string' || nonHexChars.test(hex) || !validHexSize.test(hex)) { throw new TypeError('Expected a valid hex string'); } hex = hex.replace(/^#/, ''); let alphaFromHex = 1; if (hex.length === 8) { alphaFromHex = Number.parseInt(hex.slice(6, 8), 16) / 255; hex = hex.slice(0, 6); } if (hex.length === 4) { alphaFromHex = Number.parseInt(hex.slice(3, 4).repeat(2), 16) / 255; hex = hex.slice(0, 3); } if (hex.length === 3) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; } const number = Number.parseInt(hex, 16); const red = number >> 16; const green = (number >> 8) & 255; const blue = number & 255; const alpha = typeof options.alpha === 'number' ? options.alpha : alphaFromHex; return [red, green, blue, alpha]; } const getPreviousStateFromStorage = (botId, { getParams }) => { try { if (!index$1.getUserIdFromCookie()) return null; const json = JSON.parse(localStorage.getItem(STATE_SUBOT_INLINE_KEY) || ''); const timeToExist = 30 * 60 * 1000; // 30 minutes if ((json === null || json === void 0 ? void 0 : json.botId) === botId && json.listNodes && json.activeId && json.createdAt + timeToExist > Date.now()) { localStorage.removeItem(STATE_SUBOT_INLINE_KEY); const isSSOAtLast = json.listNodes.slice(-1)[0].position === index$2.NodePosition.SSO; if (isSSOAtLast) { return { listNodes: json.listNodes, activeId: json.activeId, params: Object.assign(Object.assign(Object.assign({}, getParams()), json.params), { account_id: index$1.getUserIdFromCookie() || null, cookie_id: index$1.getSubotCookieId(json.params.cookie_id) }), }; } } return null; } catch (err) { return null; } }; const getSubotInlineLogs = (botItem) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { var _a, _b; try { if (!botItem) return null; const response = yield togetherComponentGlobalContext.callApi(getSubotApiPath(PATHS$1.GET_SUBOT_LOG, { botId: botItem.id, cookieId: index$1.getSubotCookieId(), accountId: index$1.getUserIdFromCookie() || '', type: 'inline', }), 'GET'); if (!((_a = response === null || response === void 0 ? void 0 : response._data) === null || _a === void 0 ? void 0 : _a.data) || ((_b = response === null || response === void 0 ? void 0 : response._data) === null || _b === void 0 ? void 0 : _b.type) !== 'inline') return null; const subotLogsJson = JSON.parse(response._data.data); const nodesLogs = subotLogsJson.nodes; const isInprogress = response._data.status === 'in_progress'; const isComplete = response._data.status === 'complete'; if (isInprogress || isComplete) { return { nodes: [botItem, ...nodesLogs], activeId: subotLogsJson.activeId, params: Object.assign(Object.assign({}, subotLogsJson.params), { account_id: index$1.getUserIdFromCookie() || subotLogsJson.params.account_id || null }), }; } return null; } catch (err) { return null; } }); const getExtraLogsWithCarePath = () => { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const nextInstance = window.next; const pageProps = nextInstance.router.components['/[...slug]'].props.pageProps; const isCarePath = pageProps.template === 'services-connection'; if (!isCarePath) return {}; return { project_id: 'care-path', user_funnel: pageProps.spotlight.additionalSlugActive || '', audience_name: pageProps.spotlight.groupIdActive || '', }; } catch (err) { return {}; } }; const extractUnifiedAnswers = (nodes) => { // console.log('nodes', nodes) const subotNodesMessage = nodes.filter((n) => n.name === 'Unified Questions'); const finalUnifiedAnswers = subotNodesMessage.reduce((result, nodeMessage) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w; if (nodeMessage.actions && ((_a = nodeMessage._message) === null || _a === void 0 ? void 0 : _a.action_id) && ((_b = nodeMessage._message) === null || _b === void 0 ? void 0 : _b.action_value)) { const key = nodeMessage._message.action_value; // submit if (nodeMessage.type === index$2.NodeType.FORM) { const addressControl = ['address', 'province', 'district', 'commune']; const formMetaExceptAddress = (((_c = nodeMessage._message) === null || _c === void 0 ? void 0 : _c.form_submit_meta) || []).filter((formMeta) => !addressControl.includes(formMeta.control)); /** For address field */ const formAddressMultipleFieldMap = (((_d = nodeMessage._message) === null || _d === void 0 ? void 0 : _d.form_submit_meta) || []) .filter((formMeta) => addressControl.includes(formMeta.control)) .reduce((result, formMetaItem) => { result[formMetaItem.control] = formMetaItem; return result; }, {}); const address = [ (_e = formAddressMultipleFieldMap.address) === null || _e === void 0 ? void 0 : _e.value, (_f = formAddressMultipleFieldMap.commune) === null || _f === void 0 ? void 0 : _f.value, (_g = formAddressMultipleFieldMap.district) === null || _g === void 0 ? void 0 : _g.value, (_h = formAddressMultipleFieldMap.province) === null || _h === void 0 ? void 0 : _h.value, ] .filter(Boolean) .join(', '); if (address && formAddressMultipleFieldMap.address) { result.push({ attribute: formAddressMultipleFieldMap.address.key, value: address, label_question: ((_k = (_j = nodeMessage.intents) === null || _j === void 0 ? void 0 : _j[0]) === null || _k === void 0 ? void 0 : _k.label) || '', }); } else { formMetaExceptAddress.forEach((formNormalMeta) => { var _a, _b; result.push({ attribute: formNormalMeta.key, value: formNormalMeta.value, label_question: ((_b = (_a = nodeMessage.intents) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.label) || '', }); }); } } if (nodeMessage.type === index$2.NodeType.TEXT) { if (nodeMessage.is_multi_select) { const actionIds = Object.keys(nodeMessage._message.selected_actions || {}); const actionLabel = nodeMessage.actions .filter((act) => act.label && actionIds.includes(act.id)) .map((act) => act.label); actionIds.length && result.push({ attribute: nodeMessage.actions[0].key || '', value: actionLabel, label_question: ((_m = (_l = nodeMessage.intents) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.label) || '', }); } else { const actionId = nodeMessage._message.action_id; const action = nodeMessage.actions.find((a) => a.id === actionId); const actionLabel = action === null || action === void 0 ? void 0 : action.label; // Select "Other, please provide more detail" -> There is an input below the option is stored in form_submit_meta const otherText = (_q = (_p = (_o = nodeMessage._message) === null || _o === void 0 ? void 0 : _o.form_submit_meta) === null || _p === void 0 ? void 0 : _p.find((f) => f.key === KEY_OF_TEXT_CHOICE_WITH_OTHER_FIELD)) === null || _q === void 0 ? void 0 : _q.value; const isSelectedOther = (action === null || action === void 0 ? void 0 : action.type) === index$2.NodeActionType.USER_CHOICE_TEXT_BY_INPUT; if (actionLabel && actionId) { result.push({ attribute: key, value: isSelectedOther && otherText ? otherText : actionLabel, label_question: ((_s = (_r = nodeMessage.intents) === null || _r === void 0 ? void 0 : _r[0]) === null || _s === void 0 ? void 0 : _s.label) || '', }); } } } if (nodeMessage.type === index$2.NodeType.POLL) { const nodeId = nodeMessage.id; const actionIds = ((_u = (_t = nodeMessage._message) === null || _t === void 0 ? void 0 : _t.current_polls) === null || _u === void 0 ? void 0 : _u[nodeId]) || []; const actionLabel = nodeMessage.actions .filter((act) => act.label && actionIds.includes(act.id)) .map((act) => act.label); actionIds.length && result.push({ attribute: nodeMessage.actions[0].key || '', value: actionLabel, label_question: ((_w = (_v = nodeMessage.intents) === null || _v === void 0 ? void 0 : _v[0]) === null || _w === void 0 ? void 0 : _w.label) || '', }); } } return result; }, []); // console.log('finalUnifiedAnswers', finalUnifiedAnswers) return finalUnifiedAnswers; }; const extractVoucherAnswers = (nodes, botItem) => { var _a; try { if (((_a = botItem.extra_settings) === null || _a === void 0 ? void 0 : _a.subot_type) !== 'ACUVUE') { return; } let voucherProduct = ''; // Select let voucherColor = ''; // Select let voucherSize = ''; // Dropdown let voucherLocation = ''; // Dropdown let phone = ''; const anotherFields = {}; let emailSubmitted = index$1.getUserInfoFromCookie().email; const nodesWithMessage = (nodes || []); nodesWithMessage.forEach((nodeMessage) => { var _a, _b, _c, _d, _e, _f, _g, _h; const submitMessage = nodeMessage._message; if (!submitMessage) return; const selectedAction = (_a = nodeMessage.actions) === null || _a === void 0 ? void 0 : _a.find((act) => act.id === submitMessage.action_id); if (submitMessage.action_value === 'voucher_product') { voucherProduct = (selectedAction === null || selectedAction === void 0 ? void 0 : selectedAction.label) || ''; } else if (submitMessage.action_value === 'voucher_color') { voucherColor = (selectedAction === null || selectedAction === void 0 ? void 0 : selectedAction.label) || ''; } if (nodeMessage.type === index$2.NodeType.FORM) { const logicFind = (key) => (formMeta) => { return formMeta.key === key; }; const formMetaVoucherSize = (_b = submitMessage.form_submit_meta) === null || _b === void 0 ? void 0 : _b.find(logicFind('voucher_size')); const formMetaVoucherLocation = (_c = submitMessage.form_submit_meta) === null || _c === void 0 ? void 0 : _c.find(logicFind('voucher_location')); const formMetaVoucherProduct = (_d = submitMessage.form_submit_meta) === null || _d === void 0 ? void 0 : _d.find(logicFind('voucher_product')); const formMetaVoucherColor = (_e = submitMessage.form_submit_meta) === null || _e === void 0 ? void 0 : _e.find(logicFind('voucher_color')); const formMetaEmail = (_f = submitMessage.form_submit_meta) === null || _f === void 0 ? void 0 : _f.find((formMeta) => { return formMeta.control === 'email'; }); const formMetaPhone = (_g = submitMessage.form_submit_meta) === null || _g === void 0 ? void 0 : _g.find((formMeta) => { return formMeta.control === 'tel'; }); if (formMetaVoucherSize) { voucherSize = formMetaVoucherSize.value; } if (formMetaVoucherLocation) { voucherLocation = formMetaVoucherLocation.value; } if (formMetaVoucherProduct) { voucherProduct = formMetaVoucherProduct.value; } if (formMetaVoucherColor) { voucherColor = formMetaVoucherColor.value; } if (formMetaEmail) { emailSubmitted = formMetaEmail.value; } if (formMetaPhone) { phone = formMetaPhone.value; } (_h = submitMessage.form_submit_meta) === null || _h === void 0 ? void 0 : _h.filter((formMeta) => { return ![ 'voucher_size', 'voucher_location', 'voucher_product', 'voucher_color', 'email', 'tel', ].includes(formMeta.control); }).forEach((formMeta) => { anotherFields[formMeta.key] = formMeta.value; }); } }); /** Doc: https://docs.google.com/spreadsheets/d/1WxA84tyzTyUQyloFdmzV7_Cffz7XYIc3ZJ2mVYQNgs4/edit#gid=0 */ /** https://docs.google.com/spreadsheets/d/1WxA84tyzTyUQyloFdmzV7_Cffz7XYIc3ZJ2mVYQNgs4/edit?gid=1287925107#gid=1287925107 */ if (emailSubmitted) { return Object.assign(Object.assign({}, anotherFields), { email: emailSubmitted, voucherName: voucherProduct === 'ACUVUE® OASYS (1-DAY) WITH HYDRALUXE®' ? voucherProduct : voucherProduct && voucherColor && voucherSize ? `${voucherProduct}|${voucherColor}|${voucherSize}` : 'N/A', voucher_product: voucherProduct || 'N/A', voucher_location: voucherLocation, voucher_size: voucherSize || 'N/A', voucher_color: voucherColor || 'N/A', phone }); } } catch (err) { console.log('ExtractVoucherAnswer', err); } }; const saveSubotInlineLogs = ({ nodes, activeId, params, accountIdFromLogs, }) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { try { let statusFlowBot = 'in_progress'; const lastNode = nodes[nodes.length - 1]; // Saving data with status COMPLETE when chatbot go to final node if ((lastNode === null || lastNode === void 0 ? void 0 : lastNode.type) && index$2.NodeFinalTypes.includes(lastNode.type)) { statusFlowBot = 'complete'; } /** Remove the first node and push it later in data fetching step to make sure data is latest */ const dataNodes = nodes.slice(1); const data = { activeId, params, nodes: dataNodes, tracking: Object.assign(Object.assign({}, getExtraLogsWithCarePath()), { full_url: window.location.href }), unifiedAnswers: extractUnifiedAnswers(dataNodes), voucherAnswers: extractVoucherAnswers(dataNodes, nodes[0]), }; console.log('data.voucherAnswers', data.voucherAnswers); const payload = { cookie_id: index$1.getSubotCookieId(), account_id: accountIdFromLogs || index$1.getUserIdFromCookie() || null, bot_id: nodes[0].id, flow_uuid: nodes[0].flow_uuid, data: JSON.stringify(data), status: statusFlowBot, type: 'inline', market: constantsDomainLocales.MAP_DOMAIN_BY_LOCALE[togetherComponentGlobalContext.locale], }; yield togetherComponentGlobalContext.callApi(getSubotApiPath(PATHS$1.POST_SUBOT_CREATE_LOG), 'POST', { data: payload, }); } catch (err) { // } }); const getColorWithOpacity = (color, opacity) => { try { const [r, g, b] = hexRgb(color, { format: 'array' }); return `rgba(${r}, ${g}, ${b}, ${opacity})`; } catch (err) { return undefined; } }; const detectToSkipNodeStart = (botItem, currentActiveId, currentListNodes) => { if (!(botItem === null || botItem === void 0 ? void 0 : botItem.subot_field_type)) { return [currentActiveId, currentListNodes]; } const foundNode = currentListNodes.find((nodeItem) => nodeItem.id == currentActiveId); const isActiveAtFirstNode = foundNode && foundNode.hasOwnProperty('first_node'); if (isActiveAtFirstNode && currentListNodes.length > 1) { return [currentListNodes[1].id, currentListNodes]; } return [currentActiveId, currentListNodes]; }; const SubotInlineContext = React.createContext({ activeId: '', params: {}, listNodes: [], loading: true, getParams: () => ({}), onNext: () => null, onPrev: () => null, onSubmit: () => null, onStartOver: () => null, onChange: () => null, isShowFooter: false, setIsShowFooter: () => null, setLoading: () => null, userInfo: null, }); const SubotInlineProvider = ({ children, articleLink, subotId, isFullContainer, bgColor: _bgColor, primaryColor: _primaryColor, textColor, textButtonColor, bgContentColor, bgImgFullContainer, isDisabledAnimationOnMobile, onCloseMobile, userInfo, }) => { const { formatMessage: f, action: { pushNotifications }, } = React.useContext(togetherComponentGlobalContext.TogetherComponentGlobalContext); const ref = React.useRef(null); // const { formatMessage: f } = useIntl() const refAccountIdFromLogs = React.useRef(null); const [loading, setLoading] = React.useState(true); const [activeId, setActiveId] = React.useState(''); const [listNodes, setListNodes] = React.useState([]); const [isShowFooter, setIsShowFooter] = React.useState(false); const [params, setParams] = React.useState({}); React.useEffect(() => { const bgColor = _bgColor || '#e3f2ff'; const primaryColor = _primaryColor || '#2d87f3'; const startTime = new Date().getTime(); const intervalId = setInterval(() => { const element = ref.current; const endTime = new Date().getTime(); if (element) { fastdom.mutate(() => { element.style.setProperty('--subot-inline-bg-color', bgColor); element.style.setProperty('--subot-inline-primary-color', primaryColor); element.style.setProperty('--subot-inline-primary-color-hover', getColorWithOpacity(primaryColor, 0.9) || primaryColor); element.style.setProperty('--subot-inline-primary-color-100', getColorWithOpacity(primaryColor, 0.1) || '#e3f2ff'); element.style.setProperty('--subot-inline-primary-color-300', getColorWithOpacity(primaryColor, 0.3) || '#bcdeff'); if (textColor) { element.style.setProperty('--subot-inline-text-color', textColor); } if (textButtonColor) { element.style.setProperty('--subot-inline-text-button-color', textButtonColor); } if (bgContentColor) { element.style.setProperty('--subot-inline-bg-content-color', bgContentColor); } }); clearInterval(intervalId); } if (endTime - startTime > 3 * 60 * 1000) { clearInterval(intervalId); } }, 100); return () => { clearInterval(intervalId); }; }, [_bgColor, _primaryColor, textColor, textButtonColor, bgContentColor]); /** Get Params */ const getParams = React.useCallback(() => { const gaData = window.gaData; const url = window.location.origin + index$3.basePath + ((togetherComponentGlobalContext.GlobalData === null || togetherComponentGlobalContext.GlobalData === void 0 ? void 0 : togetherComponentGlobalContext.GlobalData.locale) === 'tl-PH' ? articleLink.replace('fil/', '') : articleLink); const params = { bot_id: subotId, account_id: index$1.getUserIdFromCookie() || null, action_id: '', action_value: '', cookie_id: index$1.getSubotCookieId(), current_score: 0, current_keys: [], current_selected: [], form_submit_meta: [], gtm_id: gaData ? Object.keys(gaData)[0] : '', ga_client_id: Cookies__default["default"].get('_ga') || '', is_new: false, mode: 'inline', node_id: '', selected_actions: {}, title_url: document.title || '', // url, // Keep this commnent line to test on local url: url .replace('http://localhost:6006', 'https://discover.hellobacsi.com') // Storybook .replace('http://localhost', 'https://discover.hellobacsi.com') .replace('dev.', 'discover.') .replace('staging.hellohealthgroup.com', 'discover.hellodoctor.com.ph') // Stagign .replace('https://hellohealthgroup.com', 'https://hellodoctor.com.ph'), window_id: index$1.getWindowId(), }; return index$1.overrideParamsByQuery(params, togetherComponentGlobalContext.GlobalData === null || togetherComponentGlobalContext.GlobalData === void 0 ? void 0 : togetherComponentGlobalContext.GlobalData.router.query); }, []); const elementScrollIntoView = React.useCallback(() => { var _a; (_a = ref.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'center', }); }, []); const getFirstNode = React.useCallback((params, useSubotLog = true) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { var _a; if (!params || !params.url || !params.bot_id) { return; } let newActiveId = ''; let nodes = []; setLoading(true); const resFirst = yield subotInlineFirstNode(params.bot_id); if ((resFirst === null || resFirst === void 0 ? void 0 : resFirst._status) === 1) { newActiveId = resFirst === null || resFirst === void 0 ? void 0 : resFirst._data.id.toString(); nodes.push(resFirst === null || resFirst === void 0 ? void 0 : resFirst._data, resFirst === null || resFirst === void 0 ? void 0 : resFirst._data.first_node); } const subotLogs = useSubotLog ? yield getSubotInlineLogs(nodes[0]) : null; if (subotLogs) { nodes = subotLogs.nodes; newActiveId = subotLogs.activeId; refAccountIdFromLogs.current = ((_a = subotLogs.params) === null || _a === void 0 ? void 0 : _a.account_id) || 0; } /** [Subot Inline] Show result page after redirect from SSO */ const previousState = getPreviousStateFromStorage(params.bot_id, { getParams, }); if (previousState && previousState.params.action_id && previousState.params.action_value) { const resResultInline = yield subotInlineMessage(previousState.params); if ((resResultInline === null || resResultInline === void 0 ? void 0 : resResultInline._status) === 1 && (resResultInline === null || resResultInline === void 0 ? void 0 : resResultInline._data.node)) { newActiveId = resResultInline === null || resResultInline === void 0 ? void 0 : resResultInline._data.node.id; nodes = previousState.listNodes; nodes[nodes.length - 1] = resResultInline === null || resResultInline === void 0 ? void 0 : resResultInline._data.node; saveSubotInlineLogs({ nodes, activeId: newActiveId, params: previousState.params, accountIdFromLogs: refAccountIdFromLogs.current, }); setTimeout(() => { elementScrollIntoView(); }, 100); } } const newParams = (previousState === null || previousState === void 0 ? void 0 : previousState.params) || (subotLogs === null || subotLogs === void 0 ? void 0 : subotLogs.params) || params; const [computedActiveId, computedNodes] = detectToSkipNodeStart(nodes[0], newActiveId, nodes); setLoading(false); setActiveId(computedActiveId); setListNodes(computedNodes); setParams(Object.assign(Object.assign({}, params), newParams)); }), []); const onSubmit = React.useCallback((nextNode, message) => { // Bot Event Submission const botEvtSubmissionBtnEl = document.querySelector(`.si-revamp-event-submission[data-bot-id="${subotId}"]`); if (botEvtSubmissionBtnEl) { botEvtSubmissionBtnEl.click(); } let newActiveId = activeId; let newListNodes = [...listNodes]; if (message === null || message === void 0 ? void 0 : message.node_id) { const updateNodeIndex = newListNodes.findIndex(({ id }) => id == message.node_id); if (updateNodeIndex !== -1) { newListNodes[updateNodeIndex]._message = Object.assign(Object.assign({}, newListNodes[updateNodeIndex]._message), message); newListNodes = [...newListNodes.slice(0, updateNodeIndex + 1)]; } } setLoading(true); if (nextNode) { const nextNodeFindIndex = newListNodes.findIndex(({ id }) => id == (nextNode === null || nextNode === void 0 ? void 0 : nextNode.id)); if (nextNodeFindIndex === -1) { newListNodes = [...newListNodes, Object.assign({}, nextNode)]; } else { const tmpNode = Object.assign(Object.assign(Object.assign({}, newListNodes[nextNodeFindIndex]), nextNode), { _message: Object.assign(Object.assign({}, newListNodes[nextNodeFindIndex]._message), nextNode === null || nextNode === void 0 ? void 0 : nextNode._message) }); newListNodes = [ ...newListNodes.slice(0, nextNodeFindIndex), Object.assign({}, tmpNode), ...newListNodes.slice(nextNodeFindIndex + 1), ]; } newActiveId = nextNode.id; } setTimeout(() => { setListNodes(newListNodes); setActiveId(newActiveId); setLoading(false); saveSubotInlineLogs({ nodes: newListNodes, activeId: newActiveId, params, accountIdFromLogs: refAccountIdFromLogs.current, }); }, 250); }, [listNodes, activeId]); const onNext = React.useCallback((messageParams) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () { if (messageParams === null || messageParams === void 0 ? void 0 : messageParams.node_id) { const newMessage = Object.assign(Object.assign({}, messageParams), getCurrentTotalDynamicScore(listNodes, activeId