@hhgtech/hhg-components
Version:
Hello Health Group common components
314 lines (307 loc) • 12.8 kB
JavaScript
;
var tslib_es6 = require('./tslib.es6-92cccef3.js');
var React = require('react');
var miscCookieHelper = require('./miscCookieHelper.js');
var useUniqueId = require('./useUniqueId-6e2f8c19.js');
require('./index-ad7155cf.js');
var index = require('./index-c2c283f8.js');
var Locale = require('./Locale-59ccf941.js');
function normalizeAndHash(string) {
const utf8 = new TextEncoder().encode(string.trim().toLowerCase());
return crypto.subtle.digest('SHA-256', utf8).then((hashBuffer) => {
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray
.map((bytes) => bytes.toString(16).padStart(2, '0'))
.join('');
return hashHex;
});
}
const FbDataLayerStoreKey = 'fbDataLayer_userInfo';
const IPStoreKey = 'fbClientIp';
const useFbDataLayer = (userInfo) => {
const savedIpRef = React.useRef('');
React.useEffect(() => {
(() => tslib_es6.__awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
if (!savedIpRef.current) {
let userIp = yield fetch('https://api.ipify.org').then((res) => res.text());
if (!userIp) {
userIp = yield fetch('https://icanhazip.com').then((res) => res.text());
}
savedIpRef.current = userIp;
}
(_b = (_a = window.localStorage) === null || _a === void 0 ? void 0 : _a.setItem) === null || _b === void 0 ? void 0 : _b.call(_a, IPStoreKey, JSON.stringify({
client_ip_address: ((_c = savedIpRef.current) === null || _c === void 0 ? void 0 : _c.replace('\n', '')) || '',
client_user_agent: navigator.userAgent || '',
}));
if (userInfo === null || userInfo === void 0 ? void 0 : userInfo.id) {
const [em, ph, db, ge, ct, fn] = yield Promise.all([
userInfo.email ? normalizeAndHash(userInfo.email) : null,
userInfo.phone ? normalizeAndHash(userInfo.phone) : null,
userInfo.birthday
? normalizeAndHash(userInfo.birthday.split('-').join(''))
: null,
userInfo.gender ? 'm' : 'f',
userInfo.city_name
? normalizeAndHash(userInfo.city_name).then((n) => n.replace(/\s/g, ''))
: null,
userInfo.name ? normalizeAndHash(userInfo.name) : null,
]);
({
fbc: miscCookieHelper.getCookie('_fbc') || '',
fbp: miscCookieHelper.getCookie('_fbp') || '',
});
const localData = {
user_id: userInfo.id,
};
if (fn) {
localData['fn'] = fn;
}
if (em) {
localData['em'] = em;
}
if (ph) {
localData['ph'] = ph;
}
if (db) {
localData['db'] = db;
}
if (ct) {
localData['ct'] = ct;
}
(_e = (_d = window.localStorage) === null || _d === void 0 ? void 0 : _d.setItem) === null || _e === void 0 ? void 0 : _e.call(_d, FbDataLayerStoreKey, JSON.stringify(localData));
// ;(async function waitFbq() {
// // check for the generic script
// // easiest check to prevent race condition
// if (window.fbq) {
// window.fbq('trackCustom', 'FB Conversion', {
// action_source: 'website',
// event_source_url: window.location.href,
// user_data: [userData],
// })
// } else {
// timeout = setTimeout(waitFbq, 1000)
// }
// })()
}
}))();
return () => {
};
}, [userInfo]);
};
/** src: https://www.benmvp.com/blog/8-helpful-custom-react-hooks/
* know the PREVIOUS + DIFFERENT value of props or state. */
const usePrevious = (value) => {
// use refs to keep track of both the previous &
// current values
const prevRef = React.useRef();
const curRef = React.useRef(value);
const isInitialMount = useUniqueId.useInitialMount();
// after the initial render, if the value passed in
// differs from the `curRef`, then we know that the
// value we're tracking actually changed. we can
// update the refs. otherwise if the `curRef` &
// value are the same, something else caused the
// re-render and we should *not* update `prevRef`.
if (!isInitialMount && curRef.current !== value) {
prevRef.current = curRef.current;
curRef.current = value;
}
return prevRef.current;
};
/** src: https://www.benmvp.com/blog/8-helpful-custom-react-hooks/
* delay State update till next animation frame. Similar to debounce but shorter */
const useRafState = (initialState) => {
// this is the actual state
const [state, setState] = React.useState(initialState);
// keep track of the `requestAnimationFrame` request ID
// across renders and successive calls to `useRafState`
const requestId = React.useRef(0);
// the actual state setter we'll return.
// using `useCallback` so that it's memoized
// just like `setState`
const setRafState = React.useCallback((value) => {
// cancel active request before making next one.
// this is debouncing.
cancelAnimationFrame(requestId.current);
// create new request to set state on animation frame
requestId.current = requestAnimationFrame(() => {
setState(value);
});
}, []);
// cancel any active request when component unmounts
React.useEffect(() => {
return () => cancelAnimationFrame(requestId.current);
});
return [state, setRafState];
};
const PREGNANCY_SLUG = {
'vi-VN': 'mang-thai',
'id-ID': 'kehamilan',
'ms-MY': 'kehamilan',
'km-KH': 'ពពោះ',
'en-PH': 'pregnancy',
'tl-PH': 'pregnancy',
'th-TH': 'การตั้งครรภ์',
'my-MM': 'pregnancy',
'zh-TW': 'pregnancy',
'hi-IN': 'pregnancy',
'zh-CN': 'pregnancy',
};
// NOTE: this is temporary mapping on 13/02/2023, can be outdated due to changes from content team in the future
const MAPPED_CATEGORY_SLUGS = {
[Locale.LOCALE.Vietnam]: {
sexualWellness: 'suc-khoe-tinh-duc',
health: 'suc-khoe',
healthyEating: 'an-uong-lanh-manh',
skinHealth: 'da-lieu',
healthyHabit: 'thoi-quen-lanh-manh',
drug: 'thuoc',
womensHealth: 'suc-khoe-phu-nu',
fitness: 'the-duc-the-thao',
pregnancy: 'mang-thai',
parenting: 'nuoi-day-con',
diabetes: 'tieu-duong-dai-thao-duong',
healthyMind: 'tam-ly-tam-than',
},
[Locale.LOCALE.Indonesia]: {
pregnancy: 'kehamilan',
parenting: 'parenting',
health: 'sehat',
diabetes: 'diabetes',
womensHealth: 'wanita',
drug: 'obat-suplemen',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.Malaysia]: {
pregnancy: 'kehamilan',
parenting: 'keibubapaan',
health: 'kesihatan',
diabetes: 'kencing-manis',
womensHealth: 'kesihatan-wanita',
drug: 'ubat',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.Cambodia]: {
pregnancy: '%e1%9e%96%e1%9e%96%e1%9f%84%e1%9f%87',
parenting: '%e1%9e%85%e1%9e%b7%e1%9e%89%e1%9f%92%e1%9e%85%e1%9e%b9%e1%9e%98%e1%9e%80%e1%9e%bc%e1%9e%93',
health: '%e1%9e%9f%e1%9e%bb%e1%9e%81%e1%9e%97%e1%9e%b6%e1%9e%96%e1%9e%91%e1%9e%bc%e1%9e%91%e1%9f%85',
diabetes: '%e1%9e%87%e1%9f%86%e1%9e%84%e1%9e%ba%e1%9e%91%e1%9e%b9%e1%9e%80%e1%9e%93%e1%9f%84%e1%9e%98%e1%9e%95%e1%9f%92%e1%9e%a2%e1%9f%82%e1%9e%98',
womensHealth: '%e1%9e%9f%e1%9e%bb%e1%9e%81%e1%9e%97%e1%9e%b6%e1%9e%96%e1%9e%9f%e1%9f%92%e1%9e%8f%e1%9f%92%e1%9e%9a%e1%9e%b8',
drug: '%e1%9e%b1%e1%9e%9f%e1%9e%90%e1%9e%93%e1%9e%b7%e1%9e%84%e1%9e%a2%e1%9e%b6%e1%9e%a0%e1%9e%b6%e1%9e%9a%e1%9e%94%e1%9f%86%e1%9e%94%e1%9f%89%e1%9e%93',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.PhilippinesEnglish]: {
pregnancy: 'pregnancy',
parenting: 'parenting',
health: 'health',
diabetes: 'diabetes',
womensHealth: 'womens-health',
drug: 'drugs-supplements',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.PhilippinesTagalog]: {
pregnancy: 'pagbubuntis',
parenting: 'pagiging-magulang',
health: 'kalusugan',
diabetes: 'diabetes-fil',
womensHealth: 'kalusugan-kababaihan',
drug: 'drugs-at-supplements',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.Thailand]: {
pregnancy: '%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b8%95%e0%b8%b1%e0%b9%89%e0%b8%87%e0%b8%84%e0%b8%a3%e0%b8%a3%e0%b8%a0%e0%b9%8c',
parenting: '%e0%b8%9e%e0%b9%88%e0%b8%ad%e0%b9%81%e0%b8%a1%e0%b9%88%e0%b9%80%e0%b8%a5%e0%b8%b5%e0%b9%89%e0%b8%a2%e0%b8%87%e0%b8%a5%e0%b8%b9%e0%b8%81',
health: '%e0%b8%aa%e0%b8%b8%e0%b8%82%e0%b8%a0%e0%b8%b2%e0%b8%9e',
diabetes: '%e0%b9%82%e0%b8%a3%e0%b8%84%e0%b9%80%e0%b8%9a%e0%b8%b2%e0%b8%ab%e0%b8%a7%e0%b8%b2%e0%b8%99',
womensHealth: '%e0%b8%aa%e0%b8%b8%e0%b8%82%e0%b8%a0%e0%b8%b2%e0%b8%9e%e0%b8%ab%e0%b8%8d%e0%b8%b4%e0%b8%87',
drug: '%e0%b8%a2%e0%b8%b2%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%ad%e0%b8%b2%e0%b8%ab%e0%b8%b2%e0%b8%a3%e0%b9%80%e0%b8%aa%e0%b8%a3%e0%b8%b4%e0%b8%a1',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.Myanmar]: {
pregnancy: 'pregnancy',
parenting: 'parenting',
health: 'health',
diabetes: 'diabetes',
womensHealth: 'womens-health',
drug: 'drugs-az',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.Taiwan]: {
pregnancy: 'pregnancy',
parenting: 'parenting',
health: 'health',
diabetes: 'diabetes',
womensHealth: 'womens-health',
drug: 'drugs-supplement',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
// TODO: Update label
[Locale.LOCALE.China]: {
pregnancy: 'pregnancy',
parenting: 'parenting',
health: 'health',
diabetes: 'diabetes',
womensHealth: 'womens-health',
drug: 'drugs-supplement',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
[Locale.LOCALE.India]: {
pregnancy: 'pregnancy',
parenting: 'parenting',
health: 'health',
diabetes: 'diabetes',
womensHealth: 'womens-health',
diabetesEn: 'en-diabetes',
drug: 'dawaai',
sexualWellness: '',
healthyEating: '',
skinHealth: '',
},
};
function getCategoryFromURL(url, categories) {
const urlParts = url.split('/');
for (const key in categories) {
const keyword = categories[key];
if (urlParts.includes(keyword)) {
return key;
}
}
return null; // Return null if no matching key is found
}
const useCategory = (asPath) => {
const { locale } = index.useTranslations();
const isPregnancy = React.useMemo(() => decodeURI(asPath.replace(/\//gi, '')).includes(PREGNANCY_SLUG[locale]), []);
const isParenting = React.useMemo(() => {
var _a;
return decodeURI(asPath.replace(/\//gi, '')).includes((_a = MAPPED_CATEGORY_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.parenting);
}, []);
const type = React.useMemo(() => {
return getCategoryFromURL(asPath, MAPPED_CATEGORY_SLUGS[locale]);
}, [asPath, locale]);
return { isPregnancy, isParenting, type };
};
exports.MAPPED_CATEGORY_SLUGS = MAPPED_CATEGORY_SLUGS;
exports.PREGNANCY_SLUG = PREGNANCY_SLUG;
exports.useCategory = useCategory;
exports.useFbDataLayer = useFbDataLayer;
exports.usePrevious = usePrevious;
exports.useRafState = useRafState;