@hhgtech/hhg-components
Version:
Hello Health Group common components
990 lines (970 loc) • 89.5 kB
JavaScript
import React__default, { createContext, useContext, useMemo, useCallback, useState, useEffect, forwardRef, useRef } from 'react';
import { rem, Container, createStyles, Box, Stack, Flex, AspectRatio, ScrollArea, Chip, Group, Badge, MultiSelect, Stepper } from '@mantine/core';
import { C as CommonGAssets } from './index-ebe66e27.js';
import { b as callApiWithAuth, d as getApiPath, T as TogetherComponentGlobalContext, e as getPremiumApiPath, f as getWebsiteUrlApi, h as getSsoApiPath } from './utils-40e61585.js';
import { G as GA_TOKEN_COOKIE } from './index-5e947517.js';
import { H as HEALTH_TOOL_TYPE, a as HEALTH_TOOL_DEFAULT_IMG } from './healthTools-84f2ddc1.js';
import { RISK_SCREENER_NAME, RISK_SCREENER_SLUG } from './constantsRiskScreener.js';
import { _ as __rest, a as __awaiter } from './tslib.es6-ea4dfe68.js';
import { u as useSSOV2Store, I as IS_SSOV2_ENABLED } from './store-994a3f4d.js';
import { I as ImageWrap } from './useScreenSize-981e5b51.js';
import { g as getCurrentBaseUrl, a as getCurrentSsoUrl } from './normalizeLink-593b397a.js';
import { u as useTranslations } from './index-9d21b711.js';
import { useForm, isNotEmpty } from '@mantine/form';
import { d as Checkbox, e as ChipButton, I as Input, t as themeColors, b as AspectRatio$1 } from './index-5d405c0d.js';
import '@mantine/dates';
import './index-90813715.js';
import './useMantineLocale-0c6bea99.js';
import { T as Text } from './index-9f5659e8.js';
import { B as Button } from './index-c68a0fa7.js';
import './index.styles-770020ac.js';
import { useViewportSize } from '@mantine/hooks';
import './utils-cb7242c7.js';
import './other-4ccb5568.js';
import './index-c2190f6e.js';
import { PATHS as PATHS$2 } from './togetherApiPaths.js';
import './translationsContext-3a9e3453.js';
import { H as Heading } from './index-dcc517ff.js';
import { u as useHealthToolsCache } from './useHealthToolCache-bf165bb8.js';
import { I as Icon } from './index-5d841202.js';
import { domainLocales } from './constantsDomainLocales.js';
import { isProduction } from './constantsIsProduction.js';
import { Close, Plus } from '@hhgtech/icons/core';
import { i as isVideo } from './index-a7fca99f.js';
import { M as Modal } from './index-5d32e000.js';
import Cookies from 'js-cookie';
import flatten from 'lodash/flatten';
import uniqBy from 'lodash/uniqBy';
import { L as LOCALE } from './Locale-f270bd9d.js';
const PREFER_TOPICS = [
{
title: 'Health News & Current Affairs',
description: 'Covering the latest happenings in the health field, including medical breakthroughs, policies, and disease outbreaks',
icon: CommonGAssets.getAssetPath('newsletter-prefer/newsletter-health.svg'),
checked: false,
id: 1,
},
{
title: 'Educational Medical Hello Bacsi Content',
description: 'Covering the latest happenings in the health field, including medical breakthroughs, policies, and disease outbreaks',
icon: CommonGAssets.getAssetPath('newsletter-prefer/newsletter-education.svg'),
checked: false,
id: 2,
},
{
title: 'Hello Health Community Feed',
description: 'Covering the latest happenings in the health field, including medical breakthroughs, policies, and disease outbreaks',
icon: CommonGAssets.getAssetPath('newsletter-prefer/newsletter-community.svg'),
checked: false,
id: 3,
},
];
var BannerCategory;
(function (BannerCategory) {
BannerCategory["Pregnant"] = "pregnant";
BannerCategory["Parenting"] = "parenting";
})(BannerCategory || (BannerCategory = {}));
var BannerType;
(function (BannerType) {
BannerType["Option"] = "option";
})(BannerType || (BannerType = {}));
var OptionBannerStyleType;
(function (OptionBannerStyleType) {
OptionBannerStyleType["Button"] = "button";
OptionBannerStyleType["Checkbox"] = "checkbox";
})(OptionBannerStyleType || (OptionBannerStyleType = {}));
var BannerAction;
(function (BannerAction) {
BannerAction["ShowTool"] = "showTool";
BannerAction["ShowPremiumModal"] = "showPremiumModal";
BannerAction["ShowOptionBanner"] = "showOptionBanner";
BannerAction["Hide"] = "hide";
})(BannerAction || (BannerAction = {}));
const MAPPING_CATEGORY_PREMIUM_TYPE = {
pregnancy: BannerCategory.Pregnant,
parenting: BannerCategory.Parenting,
};
const MAPPING_CATEGORY_PREMIUM_API_TYPE = {
[BannerCategory.Pregnant]: 'pregnant',
[BannerCategory.Parenting]: 'parent',
};
const FLOW = (t, currentUrl) => ({
[BannerCategory.Pregnant]: {
action: BannerAction.ShowOptionBanner,
props: {
heading: t('pnBanner.pregnancy.heading'),
description: t('pnBanner.pregnancy.desc'),
styleType: OptionBannerStyleType.Button,
thumbnail: {
desktop: CommonGAssets.getAssetPath(`newsletter/banner-option-pregnancy-desktop.png`),
mobile: CommonGAssets.getAssetPath(`newsletter/banner-option-pregnancy-mobile.png`),
},
buttonProps: {
variant: 'white',
styles: (theme) => ({
minWidth: rem(80),
[theme.fn.largerThan('sm')]: {
minWidth: rem(120),
},
}),
},
items: [
{
label: t('switchBtn.yes'),
value: 'yes',
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'Are you navigating the world of pregnancy - Yes Click',
dataEventLabel: currentUrl,
},
},
{
label: t('switchBtn.no'),
value: 'no',
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'Are you navigating the world of pregnancy - No Click',
dataEventLabel: currentUrl,
},
},
],
},
submitHandler: {
yes: {
action: BannerAction.ShowTool,
props: {
value: HEALTH_TOOL_TYPE.DUE_DATE,
},
},
no: {
action: BannerAction.ShowPremiumModal,
},
},
},
[BannerCategory.Parenting]: {
action: BannerAction.ShowOptionBanner,
props: {
heading: t('pnBanner.parenting.heading'),
description: t('pnBanner.parenting.desc'),
thumbnail: {
desktop: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-desktop.png`),
mobile: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-mobile.png`),
},
hideDescOnMobile: true,
styleType: OptionBannerStyleType.Checkbox,
items: [
{
label: t('pnBanner.toddlers'),
value: 'todders',
},
{
label: t('pnBanner.teenager'),
value: 'teenager',
},
],
submitBtnTracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'What is the age range of your kids Click',
dataEventLabel: currentUrl,
},
},
submitHandler: {
todders: {
action: BannerAction.ShowTool,
props: {
value: HEALTH_TOOL_TYPE.BABY_VACCINE,
},
},
teenager: {
action: BannerAction.ShowOptionBanner,
props: {
styleType: OptionBannerStyleType.Button,
heading: t('pnBanner.teenager.heading'),
description: t('pnBanner.parenting.desc'),
thumbnail: {
desktop: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-desktop.png`),
mobile: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-mobile.png`),
},
buttonProps: {
variant: 'white',
},
items: [
{
label: t('childCard.boy'),
value: 'teenager.boy',
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'What is the gender of your kids - Boy Click',
dataEventLabel: currentUrl,
},
},
{
label: t('childCard.girl'),
value: 'teenager.girl',
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'What is the gender of your kids - Girl Click',
dataEventLabel: currentUrl,
},
},
],
},
},
'teenager.boy': {
action: BannerAction.ShowPremiumModal,
},
'teenager.girl': {
action: BannerAction.ShowTool,
activeTool: RISK_SCREENER_NAME.HPV,
props: {
value: RISK_SCREENER_NAME.HPV,
},
},
'todders|teenager': {
action: BannerAction.ShowOptionBanner,
props: {
styleType: OptionBannerStyleType.Button,
heading: t('pnBanner.both.heading'),
description: t('pnBanner.both.desc'),
thumbnail: {
desktop: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-desktop.png`),
mobile: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-mobile.png`),
},
hideDescOnMobile: true,
buttonProps: {
variant: 'secondary',
},
styles: (theme) => ({
wrapper: {
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
},
},
button: {
background: theme.colors.blue[0],
},
}),
items: [
{
label: t('pnBanner.vaccine.btnLabel'),
activeTool: HEALTH_TOOL_TYPE.BABY_VACCINE,
isLink: true,
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'Experience our tools for parent - Baby Vaccine Click',
dataEventLabel: currentUrl,
},
},
{
label: t('pnBanner.pn.btnLabel'),
value: 'todders|teenager.showPN',
isPNBtn: true,
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'Experience our tools for parent - Premium Newsletter Click',
dataEventLabel: currentUrl,
},
},
],
},
},
'todders|teenager.showPN': {
action: BannerAction.ShowOptionBanner,
props: {
styleType: OptionBannerStyleType.Button,
heading: t('pnBanner.both.heading'),
description: t('pnBanner.both.desc'),
thumbnail: {
desktop: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-desktop.png`),
mobile: CommonGAssets.getAssetPath(`newsletter/banner-option-parenting-mobile.png`),
},
hideDescOnMobile: true,
buttonProps: {
variant: 'secondary',
},
styles: (theme) => ({
wrapper: {
[theme.fn.smallerThan('sm')]: {
flexDirection: 'column',
},
},
button: {
background: theme.colors.blue[0],
},
}),
items: [
{
label: t('pnBanner.vaccine.btnLabel'),
activeTool: HEALTH_TOOL_TYPE.BABY_VACCINE,
isLink: true,
tracking: {
dataEventCategory: 'Focused Audience',
dataEventAction: 'Experience our tools for parent - Baby Vaccine Click',
dataEventLabel: currentUrl,
},
},
],
},
},
},
},
});
const TOOL_BANNERS_PROPS = (t) => ({
[HEALTH_TOOL_TYPE.DUE_DATE]: {
heading: t('pnBanner.dueDateTool.heading'),
description: t('pnBanner.dueDateTool.desc'),
btnLabel: t('pnBanner.caclNow'),
value: HEALTH_TOOL_TYPE.DUE_DATE,
dataEventAction: 'Try our Due Date Calculator Click',
},
[HEALTH_TOOL_TYPE.BABY_VACCINE]: {
heading: t('pnBanner.vaccination.heading'),
description: t('pnBanner.vaccination.desc'),
btnLabel: t('pnBanner.caclNow'),
value: HEALTH_TOOL_TYPE.BABY_VACCINE,
dataEventAction: 'Try our Baby Vaccine Scheduler Click',
},
[HEALTH_TOOL_TYPE.BABY_GROWTH]: {
heading: 'Baby Growth',
description: t('pnBanner.vaccination.desc'),
btnLabel: t('pnBanner.caclNow'),
value: HEALTH_TOOL_TYPE.BABY_GROWTH,
},
[RISK_SCREENER_NAME.HPV]: {
heading: t('pnBanner.hpv.heading'),
description: t('pnBanner.hpv.desc'),
thumbnail: {
desktop: CommonGAssets.getAssetPath(`newsletter/banner-option-hpv-desktop.png`),
mobile: CommonGAssets.getAssetPath(`newsletter/banner-option-hpv-mobile.png`),
},
isRiskScreener: true,
btnLabel: t('pnBanner.checkNow'),
value: RISK_SCREENER_NAME.HPV,
hideDescOnMobile: true,
dataEventAction: 'Keep safe from HPV virus Click',
},
});
const SurveyOrPremiumBannerContext = createContext({});
const PnBannerEle = (_a) => {
var rest = __rest(_a, []);
const { locale } = useTranslations();
const { type, isMobile, currentUrl, isMarketing, isLoggedIn, setShouldAcquisitionModalOpen, } = useContext(SurveyOrPremiumBannerContext);
const { triggerLogin } = useSSOV2Store();
const bannerClick = () => __awaiter(void 0, void 0, void 0, function* () {
const url = isMarketing
? getCurrentBaseUrl(locale) + '/dang-ky-nhan-tin/'
: `${window.location.href}?source=acquisition`;
if (isLoggedIn) {
setShouldAcquisitionModalOpen === null || setShouldAcquisitionModalOpen === void 0 ? void 0 : setShouldAcquisitionModalOpen();
}
else {
if (IS_SSOV2_ENABLED(locale)) {
triggerLogin({
returnUrl: isMarketing ? url : undefined,
source: !isMarketing ? 'acquisition' : undefined,
});
}
else {
window.location.href = `${getCurrentSsoUrl(locale)}/?returnUrl=${encodeURIComponent(url)}`;
}
}
});
return (React__default.createElement(Container, Object.assign({ mih: { base: 144, md: 160 }, fluid: true, p: 0, sx: {
borderRadius: 4,
cursor: 'pointer',
}, onClick: bannerClick, "data-event-category": "Newsletter", "data-event-action": "Banner Click", "data-event-label": currentUrl, className: "pointer-event-child-none" }, rest),
React__default.createElement(ImageWrap, { src: isMarketing
? CommonGAssets.getAssetPath(`newsletter/${isMobile ? 'Mobile' : 'Desktop'}_Marketing.png`)
: CommonGAssets.getAssetPath(`newsletter/${isMobile ? 'Mobile' : 'Desktop'}_${type}.png`), style: { maxWidth: '100%' }, alt: "newsletter banner" })));
};
const PATHS$1 = {
GET_SUGGESTED_TOPIC: 'api/v1/categories?external_id={externalId}&site={website_url}',
GET_NEWSLETTER_CATEGORIES: 'api/v1/categories?site={website_url}',
POST_SUBSCRIPTION: 'api/v1/subscription?site={website_url}',
TEMP_POST_SUBSCRIPTION: 'api/v1/subscription/temporary?site={website_url}',
TEMP_POST_SUBSCRIPTION_OFFICIAL: 'api/v1/subscription/official?site={website_url}',
TEMP_GET_NEWSLETTER_CATEGORIES: 'api/v1/categories/temporary?site={website_url}',
GET_SUBSCRIPTION_CATEGORIES: 'api/v1/categories?site={website_url}',
};
var useStyles = createStyles((theme) => {
return {
root: {},
wrapper: {
[theme.fn.smallerThan('sm')]: {
width: '70%',
},
},
button: {
[theme.fn.smallerThan('sm')]: {
height: 'auto',
minHeight: rem(32),
padding: `${rem(6)} ${rem(16)}`,
textAlign: 'center',
width: '100%',
},
},
buttonLabel: {
whiteSpace: 'normal',
},
};
});
const BannerLayout = ({ heading, description, thumbnail = {
desktop: '',
mobile: '',
}, hideDescOnMobile, children, }) => {
const { isMobile, minHeight } = useContext(SurveyOrPremiumBannerContext);
return (React__default.createElement(Box, { sx: () => ({
borderRadius: rem(8),
background: 'linear-gradient(180deg, #FAFDFF 0%, #E3F2FF 100%)',
}) },
React__default.createElement(Box, { sx: (theme) => ({
minHeight: rem(minHeight),
borderRadius: 'inherit',
background: `url(${isMobile ? thumbnail.mobile : thumbnail.desktop})`,
backgroundPosition: 'center right',
backgroundRepeat: 'no-repeat',
backgroundSize: 'contain',
padding: `${rem(24)} ${rem(16)}`,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
[theme.fn.largerThan('sm')]: {
padding: `${rem(22)} ${rem(32)}`,
},
}) },
React__default.createElement(Stack, { spacing: rem(16) },
React__default.createElement(Stack, { spacing: rem(4), sx: (theme) => ({
maxWidth: '60%',
[theme.fn.largerThan('sm')]: {
maxWidth: '70%',
},
}) },
heading && React__default.createElement(Heading, { tag: "h4" }, heading),
!(hideDescOnMobile && isMobile) && description && (React__default.createElement(Text, { size: "p4" }, description))),
React__default.createElement(Box, null, children)))));
};
const BannerWithOptions = (props) => {
const { styleType = OptionBannerStyleType.Button, items: itemsProp = [], buttonProps, styles, submitBtnTracking, } = props;
const { classes } = useStyles(undefined, {
name: 'PremiumBannerWithOptions',
styles,
});
const { t, locale } = useTranslations();
const { surveyType, articleId, handleClickOption, hasPremiumBanner, source, isMobile, setShowPNModal, } = useContext(SurveyOrPremiumBannerContext);
const items = useMemo(() => !hasPremiumBanner
? itemsProp.filter((i) => !Boolean(i.isPNBtn)).filter(Boolean)
: itemsProp, [itemsProp]);
const { getHealthToolLink } = useHealthToolsCache(locale);
const form = useForm({
initialValues: {
bannerOptions: [],
},
});
const saveStep = (value) => __awaiter(void 0, void 0, void 0, function* () {
return yield callApiWithAuth(getApiPath(PATHS$2.HEALTH_TOOL.CREATE, {
_locale: locale,
type: MAPPING_CATEGORY_PREMIUM_API_TYPE[surveyType],
}), 'POST', {
headers: {
'Content-Type': 'application/json',
},
data: {
value,
article: articleId,
source,
},
});
});
const renderButtonChoice = useCallback(() => (React__default.createElement(Flex, { gap: rem(8), className: classes.wrapper }, items.map((i, idx) => (React__default.createElement(Box, { key: String(idx), component: i.isLink ? 'a' : 'div', href: i.isRiskScreener
? `https://${domainLocales[locale]}/bot/${RISK_SCREENER_SLUG[locale][i.activeTool]}/`
: i.isLink
? getHealthToolLink(i.activeTool)
: undefined },
React__default.createElement(Button, Object.assign({ className: classes.button, classNames: {
label: classes.buttonLabel,
}, size: "sm" }, i.tracking, buttonProps, { onClick: () => {
if (!i.isLink) {
if (i.isPNBtn) {
setShowPNModal(true);
}
saveStep(i.value);
handleClickOption(i.value);
}
} }), i.label)))))), [items, form]);
const renderCheckboxChoice = useCallback(() => (React__default.createElement(Flex, null,
React__default.createElement(Flex, { align: 'center', gap: rem(24), sx: (theme) => ({
background: 'white',
borderRadius: rem(8),
padding: rem(4),
[theme.fn.largerThan('sm')]: {
paddingLeft: rem(16),
},
}) },
React__default.createElement(Checkbox.Group, Object.assign({}, form.getInputProps('bannerOptions', { type: 'checkbox' })),
React__default.createElement(Flex, { gap: rem(16) }, items.map((i, idx) => (React__default.createElement(Checkbox, { key: String(idx), value: i.value, label: i.label, styles: {
label: {
cursor: 'pointer',
},
} }))))),
React__default.createElement(Button, Object.assign({ size: "sm" }, submitBtnTracking, buttonProps, { disabled: form.getInputProps('bannerOptions').value.length === 0, leftIcon: isMobile ? (React__default.createElement(Icon.ArrowRightTail, { size: 18, useCurrentColor: true })) : undefined, onClick: () => {
const curValues = form.getInputProps('bannerOptions').value;
saveStep(curValues.join('|'));
handleClickOption(curValues.join('|'));
}, styles: (theme) => ({
root: {
[theme.fn.smallerThan('sm')]: {
width: rem(38),
minWidth: 'auto',
padding: 0,
},
},
}) }), !isMobile && t('pnBanner.submit'))))), [items, form]);
return (React__default.createElement(BannerLayout, Object.assign({}, props), styleType === OptionBannerStyleType.Button
? renderButtonChoice()
: styleType === OptionBannerStyleType.Checkbox
? renderCheckboxChoice()
: null));
};
const ToolBanner = (props) => {
var _a, _b;
const { t } = useTranslations();
const { heading, description, thumbnail, btnLabel, value, isRiskScreener, hideDescOnMobile, dataEventAction, } = props;
const { locale } = useTranslations();
const { isMobile } = useContext(SurveyOrPremiumBannerContext);
const { getHealthToolLink, allTools } = useHealthToolsCache(locale);
const layout = isRiskScreener ? 'mainBanner' : 'toolBanner';
const btnEle = useMemo(() => {
const toolUrl = isRiskScreener
? `https://${!isProduction ? 'discover.' : ''}${domainLocales[locale]}/bot/${RISK_SCREENER_SLUG[locale][value]}`
: getHealthToolLink(value);
return (React__default.createElement("a", { href: toolUrl },
React__default.createElement(Button, { size: "sm", "data-event-category": "Focused Audience", "data-event-action": dataEventAction, "data-event-label": toolUrl }, btnLabel || t('pnBanner.caclNow'))));
}, [allTools]);
return layout === 'mainBanner' ? (React__default.createElement(BannerLayout, Object.assign({}, Object.assign(Object.assign({}, props), { thumbnail: props.thumbnail })), btnEle)) : (React__default.createElement(Flex, { gap: rem(7), align: 'center', justify: 'space-between', sx: (theme) => ({
borderRadius: rem(8),
background: theme.colors.blue[0],
minHeight: rem(180),
padding: `${rem(24)} ${rem(16)}`,
[theme.fn.largerThan('sm')]: {
padding: `${rem(34)} ${rem(32)}`,
},
}) },
React__default.createElement(Stack, { spacing: rem(12) },
React__default.createElement(Stack, { spacing: rem(4) },
heading && React__default.createElement(Heading, { tag: "h4" }, heading),
!(isMobile && hideDescOnMobile) && description && (React__default.createElement(Text, { size: "p4" }, description))),
React__default.createElement(Flex, { gap: rem(8), sx: {
button: {
minWidth: rem(120),
},
} }, btnEle)),
React__default.createElement(Flex, { align: 'center', justify: 'center', sx: (theme) => ({
width: rem(96),
height: rem(96),
borderRadius: '50%',
background: 'white',
flexShrink: 0,
[theme.fn.largerThan('sm')]: {
width: rem(112),
height: rem(112),
},
img: {
maxWidth: rem(64),
[theme.fn.largerThan('sm')]: {
maxWidth: rem(73),
},
},
}) },
React__default.createElement("img", { alt: "health-tool-icon", src: thumbnail ||
((_b = (_a = allTools.filter((i) => i.template === value)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.icon) ||
HEALTH_TOOL_DEFAULT_IMG[value] ||
'', loading: "lazy" }))));
};
const HandlerBanner = () => {
var _a, _b, _c;
const { t } = useTranslations();
const { state, Outside } = useContext(SurveyOrPremiumBannerContext);
return (state === null || state === void 0 ? void 0 : state.action) === BannerAction.ShowTool ? (React__default.createElement(Outside, null, TOOL_BANNERS_PROPS(t)[(_a = state === null || state === void 0 ? void 0 : state.props) === null || _a === void 0 ? void 0 : _a.value] ? (React__default.createElement(ToolBanner, Object.assign({}, TOOL_BANNERS_PROPS(t)[(_b = state === null || state === void 0 ? void 0 : state.props) === null || _b === void 0 ? void 0 : _b.value], { value: (_c = state === null || state === void 0 ? void 0 : state.props) === null || _c === void 0 ? void 0 : _c.value }))) : null)) : (state === null || state === void 0 ? void 0 : state.action) === BannerAction.ShowOptionBanner ? (React__default.createElement(Outside, null,
React__default.createElement(BannerWithOptions, Object.assign({}, state === null || state === void 0 ? void 0 : state.props)))) : null;
};
const SideBannerModal = (_a) => {
var { isMobile, children, desktopBanner = CommonGAssets.getAssetPath('friso/onboarding-banner.jpg'), mobileBanner = CommonGAssets.getAssetPath('friso/onboarding-banner-mobile.jpg'), modalRatio = {
width: 937,
height: 536,
}, mobileBannerRatio = {
width: 750,
height: 480,
}, desktopBannerRatio = {
width: 420,
height: 536,
}, closeProps } = _a, modalProps = __rest(_a, ["isMobile", "children", "desktopBanner", "mobileBanner", "modalRatio", "mobileBannerRatio", "desktopBannerRatio", "closeProps"]);
const { width: viewportWidth, height: viewportHeight } = useViewportSize();
const curBannerHeight = (viewportWidth * mobileBannerRatio.height) / mobileBannerRatio.width;
const minHeightNha = (viewportHeight <= 667 ? 190 : 265) + curBannerHeight + 74;
const [isFullScreen, setIsFullScreen] = useState(false);
return (React__default.createElement(Modal, Object.assign({ styles: (theme) => ({
header: {
display: 'none',
},
content: {
flex: 'auto',
background: 'transparent',
[theme.fn.smallerThan('sm')]: {
maxHeight: '100%',
height: '100%',
position: 'relative',
borderRadius: 0,
},
[theme.fn.largerThan('sm')]: {
maxWidth: rem(modalRatio.width),
width: '100%',
height: '100%',
maxHeight: rem(modalRatio.height),
boxShadow: 'none',
},
},
body: {
padding: 0,
width: '100%',
height: '100%',
[theme.fn.largerThan('sm')]: {
display: 'flex',
alignItems: 'center',
},
},
inner: {
padding: 0,
[theme.fn.smallerThan('sm')]: {
display: 'flex',
alignItems: 'flex-end',
},
},
}) }, modalProps), isMobile ? (React__default.createElement(Box, { sx: {
position: 'relative',
width: '100%',
height: '100%',
}, onTouchStart: () => setIsFullScreen(true) },
React__default.createElement(Box, { className: "mobile-template", sx: {
position: 'absolute',
height: `${(isFullScreen ? 1 : minHeightNha / viewportHeight) * 100}%`,
left: 0,
bottom: 0,
right: 0,
transition: 'height 0.4s ease',
} },
React__default.createElement(Box, { className: "mobile-template-wrapper", sx: {
height: '100%',
backgroundColor: 'white',
borderTopLeftRadius: isFullScreen ? 0 : rem(12),
borderTopRightRadius: isFullScreen ? 0 : rem(12),
} },
React__default.createElement(Box, { sx: {
// height: 'calc(100% - 74px)',
height: '100%',
background: `url(${mobileBanner})`,
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'top center',
overflowY: 'auto',
borderRadius: 'inherit',
} },
isVideo(mobileBanner) && (React__default.createElement("video", { loop: true, muted: true, autoPlay: true, style: {
width: '100%',
position: 'absolute',
top: 0,
left: 0,
} },
React__default.createElement("source", { src: mobileBanner }))),
React__default.createElement(Button, Object.assign({ variant: "white", leftIcon: React__default.createElement(Close, null), sx: {
position: 'absolute',
right: 0,
top: 0,
zIndex: 1,
padding: rem(10),
// backgroundColor: 'transparent',
} }, closeProps, { onClick: () => modalProps === null || modalProps === void 0 ? void 0 : modalProps.onClose() })),
React__default.createElement(AspectRatio, { ratio: (mobileBannerRatio === null || mobileBannerRatio === void 0 ? void 0 : mobileBannerRatio.width) / (mobileBannerRatio === null || mobileBannerRatio === void 0 ? void 0 : mobileBannerRatio.height), w: "100%" }),
React__default.createElement(Box, { className: "inner", sx: {
padding: `${rem(28)} ${rem(16)} ${rem(16)}`,
background: 'white',
position: 'relative',
} }, children)))))) : (React__default.createElement(AspectRatio, { className: "desktop-template", ratio: modalRatio.width / modalRatio.height, w: "100%", sx: {
position: 'relative',
'& > div': {
justifyContent: 'flex-end',
},
} },
React__default.createElement(Box, { sx: {
width: '100%',
height: '100%',
justifyContent: 'flex-end',
alignItems: 'stretch',
borderRadius: rem(8),
background: 'white',
boxShadow: '0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05) 0 2.25rem 1.75rem -0.4375rem, rgba(0, 0, 0, 0.04) 0 1.0625rem 1.0625rem -0.4375rem',
} },
isVideo(desktopBanner) ? (React__default.createElement("video", { loop: true, muted: true, autoPlay: true, style: {
borderTopLeftRadius: rem(8),
borderBottomLeftRadius: rem(8),
height: '100%',
display: 'block',
} },
React__default.createElement("source", { src: desktopBanner }))) : (React__default.createElement("img", { alt: "", src: desktopBanner, loading: "lazy", style: {
borderTopLeftRadius: rem(8),
borderBottomLeftRadius: rem(8),
height: '100%',
display: 'block',
} })),
React__default.createElement(Box, { sx: {
position: 'relative',
height: '100%',
width: `${((modalRatio.width - desktopBannerRatio.width) /
modalRatio.width) *
100}%`,
} },
React__default.createElement(Button, Object.assign({ variant: "white", leftIcon: React__default.createElement(Close, null) }, closeProps, { onClick: () => modalProps === null || modalProps === void 0 ? void 0 : modalProps.onClose(), sx: {
position: 'absolute',
right: 0,
top: 0,
backgroundColor: 'transparent',
} })),
React__default.createElement(Box, { className: "side-banner-modal-container", sx: {
height: '100%',
padding: `${rem(40)} ${rem(24)} 0`,
} }, children)))))));
};
const PATHS = {
UPDATE_SUBSCRIPTION: 'user/subscription',
};
const PremiumNewsletterModalContext = createContext({});
const _NormalTopic = (_a) => {
var { value, name } = _a, rest = __rest(_a, ["value", "name"]);
return (React__default.createElement(ChipButton, Object.assign({ value: value, withIcon: true }, rest, { buttonProps: {
styles: () => ({
leftIcon: {
marginRight: rem(6),
},
root: {
paddingLeft: rem(10),
paddingRight: rem(10),
},
}),
} }), name));
};
const TopicSection = ({ topicsGroup, onTopicChange, isBlock = false, selectedTopics = [], inputProps, labelProps, maxSelect = 5, hasScroll, readonly, }) => {
const { action: { pushNotifications }, } = useContext(TogetherComponentGlobalContext);
const topics = flatten(topicsGroup.map((i) => i.topics || []));
const { t } = useTranslations();
const [value, setValue] = useState([]);
useEffect(() => {
setValue(selectedTopics);
}, [selectedTopics.length]);
useEffect(() => {
onTopicChange === null || onTopicChange === void 0 ? void 0 : onTopicChange(value);
}, [value]);
const onValueChange = (v) => {
if (v.length > 5) {
pushNotifications({
type: 'danger',
title: t('pnTopicSection.maxSelectError.title', {
maxSelect,
}),
message: t('pnTopicSection.maxSelectError.desc'),
});
return;
}
else {
!readonly &&
setValue(() => {
return topics.filter((topicObj) => v.some((tValue) => topicObj.catId === tValue));
});
}
};
return (React__default.createElement(Stack, { spacing: 12 }, topicsGroup.map((i, idx) => (React__default.createElement(Stack, { key: String(idx), spacing: 12 },
i.label && (React__default.createElement(Text, Object.assign({ size: "s5", color: "gray.4", weight: "semiBold" }, labelProps), i.label)),
hasScroll ? (React__default.createElement(ScrollArea, { w: "100%", offsetScrollbars: true, scrollbarSize: 4, p: 16, m: -16, styles: {
viewport: {
margin: -16,
padding: 16,
},
} },
React__default.createElement(Box, { w: 800 },
React__default.createElement(Chip.Group, Object.assign({ value: value.map((v) => v.catId), multiple: true }, inputProps, { onChange: onValueChange }),
React__default.createElement(Flex, { gap: 8, wrap: "wrap" }, i.topics.map((v) => (React__default.createElement(_NormalTopic, Object.assign({ key: v.catId, value: v.catId, name: v.localName, isBlock: isBlock }, i.tracking))))))))) : (React__default.createElement(Chip.Group, Object.assign({ value: value.map((v) => v.catId), multiple: true }, inputProps, { onChange: onValueChange }),
React__default.createElement(Flex, { gap: 8, wrap: "wrap" }, i.topics.map((v) => v.catId ? (React__default.createElement(_NormalTopic, Object.assign({ key: v.catId, value: v.catId, name: v.localName, isBlock: isBlock }, i.tracking))) : React__default.isValidElement(v.component) ? (v.component) : null)))))))));
};
const Layout = (_a) => {
var { heading, children, stickyActions } = _a, scrollAreaProps = __rest(_a, ["heading", "children", "stickyActions"]);
const { isMobile } = useContext(PremiumNewsletterModalContext);
const content = (React__default.createElement(Stack, { spacing: rem(24), sx: { height: '100%' } },
React__default.createElement(Heading, { tag: "h4", style: {
textAlign: 'center',
} }, heading),
React__default.createElement(Box, null, children)));
return (React__default.createElement(Box, { sx: (theme) => ({
[theme.fn.largerThan('sm')]: {
position: 'relative',
height: '100%',
},
}) },
isMobile ? (content) : (React__default.createElement(ScrollArea, Object.assign({ className: "layout-body", h: stickyActions ? 'calc(100% - 90px)' : '100%' }, scrollAreaProps), content)),
stickyActions && (React__default.createElement(Flex, { gap: rem(8), sx: (theme) => ({
position: 'absolute',
left: 0,
right: 0,
bottom: 0,
padding: rem(16),
button: {
flexGrow: 1,
},
justifyContent: 'center',
[theme.fn.largerThan('sm')]: {
padding: `${rem(24)} 0`,
},
}) }, stickyActions))));
};
const MainForm = () => {
const { t, locale } = useTranslations();
const { data: { userInfo }, action: { pushNotifications }, } = useContext(TogetherComponentGlobalContext);
const isLoggedIn = userInfo === null || userInfo === void 0 ? void 0 : userInfo.id;
const { currentUrl, isMobile, pnSuggestCategory = [], nextStep, formValues, setFormValues, onSubmit: _onSubmit, submitLoading, selectCategory, setCategoryLibs, setSelectCategory, maxSelectCategory, } = useContext(PremiumNewsletterModalContext);
const pnSuggestCategoryIds = pnSuggestCategory.map((i) => i.catId);
const form = useForm({
validate: {
name: isNotEmpty(t('healthToolPNModal.mainForm.requireName')),
},
initialValues: Object.assign(Object.assign({}, formValues), { fitnessTopics: pnSuggestCategoryIds }),
});
const [fitnessTopics, setFitnessTopics] = useState([]);
const [interestedTopics, setInterestedTopics] = useState([]);
useEffect(() => {
(() => __awaiter(void 0, void 0, void 0, function* () {
var _a;
try {
const interestedRes = yield callApiWithAuth(getPremiumApiPath(PATHS$1.GET_SUBSCRIPTION_CATEGORIES, {
_locale: locale,
}), 'get');
const interestedList = (((_a = interestedRes === null || interestedRes === void 0 ? void 0 : interestedRes.data) === null || _a === void 0 ? void 0 : _a.subscription) || []).filter((i) => !pnSuggestCategoryIds.includes(i.catId));
setFitnessTopics(pnSuggestCategory);
setInterestedTopics(interestedList);
setCategoryLibs([...pnSuggestCategory, ...interestedList]);
}
catch (err) {
console.log(err);
}
}))();
}, []);
useEffect(() => {
isLoggedIn && form.setFieldValue('name', (userInfo === null || userInfo === void 0 ? void 0 : userInfo.name) || '');
}, [isLoggedIn]);
const onMore = () => {
if (form.getInputProps('name').value !== '') {
setFormValues(form.getTransformedValues());
nextStep();
}
else {
form.validateField('name');
}
};
const onSubmit = (formValues) => {
if (selectCategory.length === 0) {
pushNotifications({
type: 'danger',
title: t('newsletter.error.minTitle'),
message: t('newsletter.error.minCotennt'),
});
return false;
}
setFormValues(formValues);
_onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(formValues.name);
};
const MoreButton = useMemo(() => (React__default.createElement(Button, { variant: "tertiary", dataEventCategory: "Newsletter", dataEventAction: "More Category Click", dataEventLabel: currentUrl, leftIcon: React__default.createElement(Plus, { size: 16, color: 'currentColor' }), onClick: onMore, styles: (theme) => ({
root: {
borderRadius: rem(6),
padding: '2px 15px',
height: rem(40),
},
label: {
fontSize: rem(14),
fontWeight: 400,
[theme.fn.smallerThan('sm')]: {
fontSize: rem(12),
lineHeight: rem(16),
height: rem(40),
},
},
leftIcon: {
marginRight: '5px',
},
}) },
React__default.createElement(Text, { size: isMobile ? 'p3' : 'p4' }, t('home.seeMore')))), [form]);
useEffect(() => {
form.setFieldValue('fitnessTopics', selectCategory.map((i) => i.catId));
}, [selectCategory]);
return (React__default.createElement("form", { style: { height: '100%' }, onSubmit: form.onSubmit(onSubmit) },
React__default.createElement(Layout, { heading: t('healthToolPNModal.heading'), stickyActions: React__default.createElement(React__default.Fragment, null,
React__default.createElement(Button, { fullWidth: true, type: "submit", dataEventCategory: "Newsletter", dataEventAction: "Register Click", dataEventLabel: currentUrl, loading: submitLoading, sx: { maxWidth: rem(240) } }, t('healthToolPNModal.register'))) },
React__default.createElement(Stack, { spacing: rem(16) },
React__default.createElement(Input, Object.assign({ label: t('newsletter.welcome.description') }, form.getInputProps('name'))),
React__default.createElement(TopicSection, { topicsGroup: [
...(pnSuggestCategory.length === 0 &&
interestedTopics.length === 0
? [
{
topics: [
{
component: MoreButton,
},
],
},
]
: []),
...(pnSuggestCategory.length > 0
? [
{
label: t('healthToolPNModal.mainForm.tailorTopicsHeading'),
topics: [
...pnSuggestCategory,
...(interestedTopics.length === 0
? [
{
component: MoreButton,
},
]
: []),
],
},
]
: []),
...(interestedTopics.length > 0
? [
{
label: t('healthToolPNModal.findMore.chooseFav'),
topics: [
...interestedTopics,
...(interestedTopics.length > 0
? [
{
component: MoreButton,
},
]
: []),
],
},
]
: []),
], selectedTopics: [...fitnessTopics], labelProps: {
size: isMobile ? 'p3' : 'p4',
color: 'gray.6',
}, onTopicChange: setSelectCategory, maxSelect: maxSelectCategory })))));
};
const _SuggestedTopic = forwardRef(function SuggestedTopic(_a, ref) {
var { label } = _a, others = __rest(_a, ["label"]);
return (React__default.createElement("div", Object.assign({ ref: ref }, others),
React__default.createElement(Group, { noWrap: true },
React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" },
React__default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.97887 8.15493C2.97887 5.29627 5.29627 2.97887 8.15493 2.97887C11.0136 2.97887 13.331 5.29627 13.331 8.15493C13.331 11.0136 11.0136 13.331 8.15493 13.331C5.29627 13.331 2.97887 11.0136 2.97887 8.15493ZM8.15493 1.5C4.47951 1.5 1.5 4.47951 1.5 8.15493C1.5 11.8303 4.47951 14.8099 8.15493 14.8099C9.72615 14.8099 11.1702 14.2653 12.3086 13.3547L15.2376 16.2837C15.5264 16.5725 15.9946 16.5725 16.2833 16.2837C16.5721 15.9949 16.5721 15.5267 16.2833 15.238L13.3544 12.3091C14.2652 11.1705 14.8099 9.72634 14.8099 8.15493C14.8099 4.47951 11.8303 1.5 8.15493 1.5Z", fill: "#8C8C8C" })),
React__default.createElement(Text, { size: "p3" }, label))));
});
const _Topic = forwardRef(function Baby(_a, ref) {
var { label