@hhgtech/hhg-components
Version:
Hello Health Group common components
1,015 lines (991 loc) • 277 kB
JavaScript
import React__default, { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo, forwardRef, useImperativeHandle, memo } from 'react';
import { d as NodeType, E as ELEMENT_CONTROL_INPUT_TYPE, f as NodeActionType, c as NodePosition, e as NodeFinalTypes, g as NodeMultipleOptions, N as NodeIntentType, F as FULL_KEY_ADDRESS, C as COMMON_DATE_TRANSLATE_KEY } from './index-90813715.js';
import { a as __awaiter, _ as __rest } from './tslib.es6-ea4dfe68.js';
import { f as basePath, G as GA_TOKEN_COOKIE, A as API_DATE_FORMAT, I as ISO_FORMAT, g as SSO_URL } from './index-5e947517.js';
import Cookies from 'js-cookie';
import fd from 'fastdom';
import fastdomPromised from 'fastdom/extensions/fastdom-promised';
import { G as GlobalData, c as callApi, u as locale, T as TogetherComponentGlobalContext } from './utils-40e61585.js';
import formatString from 'string-format';
import { a as getUserIdFromCookie, b as getSubotCookieId, c as getUserInfoFromCookie, d as getWindowId, o as overrideParamsByQuery, e as checkUntilFinished, g as getHelloSitesUrl, f as checkMobile, h as clickAndOpenInNewTab, i as formatUrlWithEncrypedGa, T as TIME_RESET_RESEND_OTP, j as isFakeEmail, s as ssoIntents, k as getHhgIdFromCookie } from './index-8b24c2ec.js';
export { T as TIME_RESET_RESEND_OTP, f as checkMobile, e as checkUntilFinished, h as clickAndOpenInNewTab, i as formatUrlWithEncrypedGa, g as getHelloSitesUrl, k as getHhgIdFromCookie, b as getSubotCookieId, a as getUserIdFromCookie, c as getUserInfoFromCookie, d as getWindowId, j as isFakeEmail, o as overrideParamsByQuery, s as ssoIntents } from './index-8b24c2ec.js';
import dayjs from 'dayjs';
import { MAP_DOMAIN_BY_LOCALE } from './constantsDomainLocales.js';
import cn from 'classnames';
import { C as Container$w } from './index-3a8ea352.js';
import { L as Loading } from './index-07d56b7b.js';
import { motion } from 'framer-motion';
import styled from '@emotion/styled';
import { M as MediaQueries } from './utils-cb7242c7.js';
import { B as Button } from './index-c68a0fa7.js';
import { Remarkable } from 'remarkable';
import { ArrowRight } from '@hhgtech/icons/other';
import { useInView } from 'react-intersection-observer';
import { Box, Textarea } from '@mantine/core';
import { C as CommonGAssets } from './index-ebe66e27.js';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import { d as LEAD_TOKEN_COOKIE } from './constants-f4091ce6.js';
import { v4 } from 'uuid';
import { T as Text } from './index-9f5659e8.js';
import { theme } from './miscTheme.js';
import { isProduction } from './constantsIsProduction.js';
import { S as Select } from './index-5d405c0d.js';
import '@mantine/dates';
import './useMantineLocale-0c6bea99.js';
import './index.styles-770020ac.js';
import './translationsContext-3a9e3453.js';
import '@mantine/hooks';
import './other-4ccb5568.js';
import './index-c2190f6e.js';
import isEmpty from 'lodash/isEmpty';
import { Controller, useForm } from 'react-hook-form';
import PhoneInputBase, { getCountryCallingCode, isPossiblePhoneNumber, parsePhoneNumber } from 'react-phone-number-input';
import { LoadScript } from '@react-google-maps/api';
import { u as usePlacesAutocomplete, G as GOOGLE_API_KEY, a as GOOGLE_API_LANGUAGE } from './usePlacesAutocomplete-b017462a.js';
import { setDefaultClass } from './miscDefaultClassWrapper.js';
import { L as LOCALE } from './Locale-f270bd9d.js';
import { I as InputDate } from './InputDate-13f91afd.js';
import { B as Button$1 } from './index-6351bdee.js';
import { D as Dropdown } from './index-a2183fa7.js';
import { u as useSSOV2Store, I as IS_SSOV2_ENABLED } from './store-994a3f4d.js';
import { g as getURLwithSSOTracking } from './utils-757f12af.js';
import 'date-fns/locale';
import './constantsSite.js';
import './constantsRiskScreener.js';
import './index-963a1701.js';
import './miscCookieHelper.js';
import 'slugify';
import './togetherApiPaths.js';
import './index-5d841202.js';
import './WhatsApp-f7a93c46.js';
import './Spinner-2d43eb3a.js';
import './index-9d21b711.js';
import './useScreenSize-981e5b51.js';
import '@mantine/carousel';
import './useUniqueId-4305c9aa.js';
import '@hhgtech/icons/core';
import '@mantine/notifications';
import '@emotion/react';
import 'zustand';
import './index-235eabf2.js';
import './normalizeLink-593b397a.js';
import './healthTools-84f2ddc1.js';
// extend fastdom
const fastdom = fd.extend(fastdomPromised);
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) => __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 } = GlobalData === null || GlobalData === void 0 ? void 0 : GlobalData.env;
const apiUrl = subotApiUrl.endsWith('frontend/api/')
? subotApiUrl
: subotApiUrl + 'frontend/api/';
return apiUrl + formatString(path, Object.assign({}, params));
};
/** inline message */
const subotInlineMessage = (data) => __awaiter(void 0, void 0, void 0, function* () {
try {
return yield 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) => __awaiter(void 0, void 0, void 0, function* () {
try {
const data = yield CachedSystem.withCached('SubotInlineFirstNode/' + id, () => __awaiter(void 0, void 0, void 0, function* () {
const response = yield 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) => __awaiter(void 0, void 0, void 0, function* () {
try {
return yield callApi(getSubotApiPath(PATHS$1.GET_INLINE_CLICK), 'POST', {
data,
});
}
catch (error) { }
});
/** inline impression */
const subotInlineImpression = (data) => __awaiter(void 0, void 0, void 0, function* () {
try {
return yield callApi(getSubotApiPath(PATHS$1.GET_INLINE_IMPRESSION), 'POST', {
data,
});
}
catch (error) { }
});
const calcAge = (value) => {
const birthDate = dayjs(value);
const today = dayjs();
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 === 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 ===
ELEMENT_CONTROL_INPUT_TYPE[NodeActionType.USER_SUBMIT_NUMBER] ||
f.control ===
ELEMENT_CONTROL_INPUT_TYPE[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 ===
ELEMENT_CONTROL_INPUT_TYPE[NodeActionType.USER_SUBMIT_NUMBER] ||
f.control ===
ELEMENT_CONTROL_INPUT_TYPE[NodeActionType.USER_SUBMIT_DOB]));
if (!formValue)
return '';
if (formValue.control ===
ELEMENT_CONTROL_INPUT_TYPE[NodeActionType.USER_SUBMIT_DOB]) {
const { age } = calcAge(dayjs(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 === 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 ===
ELEMENT_CONTROL_INPUT_TYPE[NodeActionType.USER_SUBMIT_NUMBER] ||
f.control ===
ELEMENT_CONTROL_INPUT_TYPE[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 ===
ELEMENT_CONTROL_INPUT_TYPE[NodeActionType.USER_SUBMIT_NUMBER] ||
f.control ===
ELEMENT_CONTROL_INPUT_TYPE[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 (!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 === NodePosition.SSO;
if (isSSOAtLast) {
return {
listNodes: json.listNodes,
activeId: json.activeId,
params: Object.assign(Object.assign(Object.assign({}, getParams()), json.params), { account_id: getUserIdFromCookie() || null, cookie_id: getSubotCookieId(json.params.cookie_id) }),
};
}
}
return null;
}
catch (err) {
return null;
}
};
const getSubotInlineLogs = (botItem) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
try {
if (!botItem)
return null;
const response = yield callApi(getSubotApiPath(PATHS$1.GET_SUBOT_LOG, {
botId: botItem.id,
cookieId: getSubotCookieId(),
accountId: 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: 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 === 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 === 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) === 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 === 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 = 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 === 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, }) => __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) && 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: getSubotCookieId(),
account_id: accountIdFromLogs || getUserIdFromCookie() || null,
bot_id: nodes[0].id,
flow_uuid: nodes[0].flow_uuid,
data: JSON.stringify(data),
status: statusFlowBot,
type: 'inline',
market: MAP_DOMAIN_BY_LOCALE[locale],
};
yield 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 = 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 }, } = useContext(TogetherComponentGlobalContext);
const ref = useRef(null);
// const { formatMessage: f } = useIntl()
const refAccountIdFromLogs = useRef(null);
const [loading, setLoading] = useState(true);
const [activeId, setActiveId] = useState('');
const [listNodes, setListNodes] = useState([]);
const [isShowFooter, setIsShowFooter] = useState(false);
const [params, setParams] = useState({});
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 = useCallback(() => {
const gaData = window.gaData;
const url = window.location.origin +
basePath +
((GlobalData === null || GlobalData === void 0 ? void 0 : GlobalData.locale) === 'tl-PH'
? articleLink.replace('fil/', '')
: articleLink);
const params = {
bot_id: subotId,
account_id: getUserIdFromCookie() || null,
action_id: '',
action_value: '',
cookie_id: getSubotCookieId(),
current_score: 0,
current_keys: [],
current_selected: [],
form_submit_meta: [],
gtm_id: gaData ? Object.keys(gaData)[0] : '',
ga_client_id: Cookies.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: getWindowId(),
};
return overrideParamsByQuery(params, GlobalData === null || GlobalData === void 0 ? void 0 : GlobalData.router.query);
}, []);
const elementScrollIntoView = useCallback(() => {
var _a;
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'center',
});
}, []);
const getFirstNode = useCallback((params, useSubotLog = true) => __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 = 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 = useCallback((messageParams) => __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, messageParams.action_id));
const res = yield subotInlineMessage(newMessage);
setLoading(false);
if ((res === null || res === void 0 ? void 0 : res._status) === 1) {
const _b = res === null || res === void 0 ? void 0 : res._data, { node } = _b, restData = __rest(_b, ["node"]);
const nextNode = Object.assign(Object.assign({}, node), { _message: Object.assign(Object.assign({}, restData), { node_id: node.id }) });
const foundIdxOfNextNode = listNodes.findIndex((nodeItem) => nodeItem.id === nextNode.id);
const isFound = foundIdxOfNextNode !== -1;
if (isFound) {
// onSubmi