@hhgtech/hhg-components
Version:
Hello Health Group common components
1,035 lines (995 loc) • 57.7 kB
JavaScript
import React__default, { createContext, forwardRef, useContext, useImperativeHandle, useState, useRef, useEffect, useMemo, Fragment } from 'react';
import { Box, Input, Grid, Title, Container, Flex, rem, Stack, AspectRatio } from '@mantine/core';
import { P as Phone, I as Input$1, R as Radio, O as OTP, d as Checkbox } from './index-bd44bcb2.js';
import '@mantine/dates';
import { L as LOCALE_SPECS } from './index-8c40504a.js';
import './index-fe4471f4.js';
import { C as CommonGAssets } from './index-7adf994c.js';
import './index-3f09210d.js';
import { T as Text } from './index-0b67696c.js';
import { B as Button } from './index-2d25b0f0.js';
import './index-17c85f76.js';
import './index.styles-3adef5f6.js';
import './translationsContext-18f7b7e0.js';
import { useInterval, useCounter } from '@mantine/hooks';
import { M as MediaQueries, a as getPopupWrapperDom } from './utils-538169b3.js';
import './index-04505e35.js';
import { M as MAPPED_LOCALE, h as hiddenEmailChar } from './utils-2d973164.js';
export { M as MAPPED_LOCALE } from './utils-2d973164.js';
import { createFormContext, yupResolver } from '@mantine/form';
import styled from '@emotion/styled';
import { _ as __rest, a as __awaiter } from './tslib.es6-00ab44b2.js';
import { u as useTranslations } from './index-09d9e570.js';
import * as yup from 'yup';
import { D as DatePicker } from './index-0861b084.js';
import { A as AddressInput } from './index-48d7f133.js';
import { V as Visible } from './Visible-95cdc6e2.js';
import { H as Heading } from './index-e348d0b2.js';
import { createPortal } from 'react-dom';
import { theme } from './miscTheme.js';
import { u as useScreenSize } from './index-50aea2c8.js';
import { L as LogoIcon } from './logoIcon-b515c32f.js';
import { I as Icon } from './index-a22d54f1.js';
import throttle from 'lodash/throttle';
import { T as Text$1 } from './index-546ca9b5.js';
import { B as Button$1 } from './index-67429eb2.js';
import { format } from 'date-fns';
import flattenChildren from 'react-keyed-flatten-children';
import '@hhgtech/icons/other';
import '@mantine/carousel';
import './shared-b07d1eb2.js';
import 'classnames';
import 'uuid';
import './useUniqueId-38cdf062.js';
import './constantsSite.js';
import './Locale-dc1237b9.js';
import '@emotion/react';
import '@hhgtech/icons/core';
import 'date-fns/locale';
import './constantsDomainLocales.js';
import './constantsRiskScreener.js';
import './constantsIsProduction.js';
import 'dayjs';
import '@mantine/notifications';
import './WhatsApp-6a0c0a12.js';
import './Spinner-589f30ad.js';
// define shared context
const OnboardingContext = createContext({
currentStep: 0,
setCurrentStep: () => false,
setMaxStep: () => false,
nextStep: () => false,
prevStep: () => false,
isMarryBaby: false,
siteType: 'helloSites',
sharedData: {},
setSharedData: () => false,
});
const [FormProvider, useFormContext, useForm] = createFormContext();
const StyledDynamicForm = styled(Box) `
.phone-input {
width: 100%;
margin-bottom: 32px;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
.PhoneInput {
margin-bottom: 16px;
}
.PhoneInputCountry {
border-radius: 4px 0 0 4px;
}
.PhoneInputInput {
border-radius: 0 4px 4px 0;
}
}
`;
const DynamicForm = (_a) => {
var { inputOrder = ['phone'], withSimilac = false, customTerms = '', formContext } = _a, rest = __rest(_a, ["inputOrder", "withSimilac", "customTerms", "formContext"]);
const { t } = useTranslations();
const form = formContext || useFormContext();
const Phone$1 = (_a) => {
var { label, name = 'phone' } = _a, phoneProps = __rest(_a, ["label", "name"]);
return (React__default.createElement(Input.Wrapper, { className: withSimilac ? 'input-control' : 'phone-input', withAsterisk: true, label: label || withSimilac ? (React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.similac.input.phone'))) : undefined },
React__default.createElement(Phone, Object.assign({ defaultCountry: MAPPED_LOCALE[process.env.UNIFY_LOCALE] || 'VN' }, form.getInputProps(name), phoneProps)),
React__default.createElement(Input.Error, { size: "md" }, form.errors.phone)));
};
const FullName = (_a) => {
var { label, name = 'name' } = _a, rest = __rest(_a, ["label", "name"]);
return (React__default.createElement(Input$1, Object.assign({ label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.formEmail.yourName')), withAsterisk: true }, form.getInputProps(name), rest)));
};
const Email = (_a) => {
var { label, name = 'email' } = _a, rest = __rest(_a, ["label", "name"]);
return (React__default.createElement(Input$1, Object.assign({ label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.formEmail.yourEmail')), withAsterisk: true }, form.getInputProps(name), rest)));
};
const Dob = (_a) => {
var { label, name = 'dob' } = _a, rest = __rest(_a, ["label", "name"]);
return (React__default.createElement(DatePicker, Object.assign({ label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.formEmail.yourBirthday')), placeholder: "DD/MM/YYYY" }, form.getInputProps(name), rest)));
};
const Gender = (_a) => {
var { label, name = 'gender' } = _a, radioProps = __rest(_a, ["label", "name"]);
return (React__default.createElement(Radio.Group, Object.assign({ className: "radio-group", label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('tools.selectGender')) }, form.getInputProps(name), radioProps),
React__default.createElement(Radio, { value: "0", label: t('onboarding.formEmail.genderMale') }),
React__default.createElement(Radio, { value: "1", label: t('onboarding.formEmail.genderFemale') })));
};
const Otp = ({ name = 'otp' }) => (React__default.createElement("div", { className: "otp-input" },
React__default.createElement(OTP, Object.assign({ enterKeyHint: undefined, nonce: undefined }, form.getInputProps(name))),
React__default.createElement(Input.Error, null, form.errors.otp)));
const Password = ({ label, name = 'password' }) => (React__default.createElement(Input$1.Password, Object.assign({ label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.updatePassword.password')), withAsterisk: true, rightSection: React__default.createElement(Visible, null) }, form.getInputProps(name))));
const Term = ({ name = 'term', className = '' }) => customTerms ? (React__default.createElement("div", { style: { marginBottom: 16 }, className: className },
React__default.createElement(Checkbox, Object.assign({ label: React__default.createElement(Text, { size: "p4", as: "span", sx: {
a: {
color: '#2d87f3',
fontWeight: 'bold',
letterSpacing: 0,
},
} }, customTerms) }, form.getInputProps(name, { type: 'checkbox' }), { error: null })),
React__default.createElement(Input.Error, { size: "md" }, form.getInputProps('term', { type: 'checkbox' }).error))) : null;
const Address = (_a) => {
var { label, className = '', name = 'address' } = _a, rest = __rest(_a, ["label", "className", "name"]);
return (React__default.createElement(AddressInput, Object.assign({ className: `${className} input-control`, label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.similac.input.address')) }, form.getInputProps(name), rest)));
};
const ConfirmPassword = ({ label, name = 'confirmPassword', }) => (React__default.createElement(Input$1.Password, Object.assign({ label: React__default.createElement(Text, { size: "s4", weight: "semiBold", as: "span" }, label || t('onboarding.updatePassword.confirmPassword')), withAsterisk: true, rightSection: React__default.createElement(Visible, null) }, form.getInputProps(name))));
const elements = {
phone: Phone$1,
full_name: FullName,
email: Email,
dob: Dob,
gender: Gender,
otp: Otp,
password: Password,
confirm_password: ConfirmPassword,
term: Term,
address: Address,
};
const content = inputOrder.map((part) => {
var _a;
const curProps = typeof part === 'string' ? { inputType: part } : part;
return (_a = elements[curProps.inputType]) === null || _a === void 0 ? void 0 : _a.call(elements, curProps);
});
return React__default.createElement(StyledDynamicForm, Object.assign({}, rest), content);
};
const frisoOnboardingSchema = (t) => yup.object().shape({
phone: yup.string().required(t('onboarding.updatePhone.error')).default(''),
name: yup.string().required(t('onboarding.errorMessage.requiredName')),
email: yup
.string()
.required(t('onboarding.errorMessage.requiredEmail'))
.email(t('onboarding.errorMessage.invalidEmail'))
.default(''),
address: yup.mixed().required(t('onboarding.similac.address.error')),
term: yup.bool().oneOf([true], t('validation.error.requiredField')),
});
const FrisoOnboardingForm = (_a, ref) => {
var { inputOrder, onSubmit: _onSubmit, validateSchema, defaultValues, isActive, customTerms, customFormTexts } = _a, rest = __rest(_a, ["inputOrder", "onSubmit", "validateSchema", "defaultValues", "isActive", "customTerms", "customFormTexts"]);
const { nextStep, setSharedData, sharedData } = useContext(OnboardingContext);
const { t } = useTranslations();
const form = useForm({
initialValues: {
term: false,
phone: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.phone) || (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.phone) || '',
email: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.email) || (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.email) || '',
name: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.name) || (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.name) || '',
},
validate: validateSchema || yupResolver(frisoOnboardingSchema(t)),
});
const onSubmit = (values) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield (_onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(values));
setSharedData((d) => (Object.assign(Object.assign({}, d), { phone: values.phone, email: values.email, name: values.name })));
nextStep();
}
catch (err) {
console.error(err);
}
});
const onError = (fieldErrors) => {
console.log(fieldErrors);
};
const handleSubmitForm = () => { var _a; return (_a = form.onSubmit(onSubmit, onError)) === null || _a === void 0 ? void 0 : _a(); };
useImperativeHandle(ref, () => ({
submitForm: handleSubmitForm,
}));
return (React__default.createElement(Box, Object.assign({ "data-active": isActive }, rest),
React__default.createElement(Box, { sx: (theme) => ({
display: 'flex',
flexDirection: 'column',
gap: '16px',
[theme.fn.largerThan('md')]: {
gap: '24px',
},
}) },
React__default.createElement(Box, { sx: { textAlign: 'center' } },
React__default.createElement(Heading, { tag: "h4", as: "h2" }, customFormTexts === null || customFormTexts === void 0 ? void 0 : customFormTexts.heading),
React__default.createElement(Text, { size: "p3" }, customFormTexts === null || customFormTexts === void 0 ? void 0 : customFormTexts.description)),
React__default.createElement(FormProvider, { form: form },
React__default.createElement("form", { className: "friso-form", style: {
width: '100%',
}, onSubmit: form.onSubmit(onSubmit, onError) },
React__default.createElement(Box, { sx: {
'.friso-form': {
display: 'flex',
flexWrap: 'wrap',
gap: '8px',
'.input-control': {
width: '100%',
marginBottom: 0,
},
'.phone-input': {
marginBottom: '0 !important',
'.PhoneInput': {
marginBottom: '0 !important',
},
},
},
} },
React__default.createElement(DynamicForm, { inputOrder: inputOrder, customTerms: customTerms, className: "friso-form" })))))));
};
var FrisoOnboardingForm$1 = forwardRef(FrisoOnboardingForm);
const StyledOnboardingModal = styled.div `
position: fixed;
inset: 0;
z-index: 1000;
background: white;
overflow-y: auto;
`;
const StyledContainer = styled.div `
height: 100%;
${MediaQueries.lgPcUp} {
display: table;
width: 100%;
height: calc(100% - 25px);
}
`;
const StyledContent = styled.div `
padding: 16px;
${MediaQueries.mbUp} {
padding: 48px 24px 24px;
}
&[data-similac='true'][data-has-banner='true'] {
${MediaQueries.mbDown} {
background: white;
border-top-left-radius: 1rem;
border-top-right-radius: 1rem;
margin-top: -1rem;
}
}
`;
const StyledBannerCol = styled.div `
width: 640px;
padding: 16px 16px 0 16px;
display: none;
${MediaQueries.mbUp} {
width: 640px;
display: table-cell;
}
`;
const StyledBannerInner = styled.div `
background-color: ${theme.colors.primary50};
border-radius: 12px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
&[data-is-marry-baby='true'] {
background-color: ${theme.mbColors.tonePink};
}
`;
const StyledIntro = styled.div `
margin-top: 40px;
padding: 24px 40px;
`;
const StyledBannerImgWrapper = styled.div `
width: 100%;
display: block;
img {
width: 100%;
height: auto;
}
&.similac {
min-width: 1px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
${MediaQueries.mbUp} {
position: sticky;
top: 0;
height: 100vh;
}
}
`;
const OnboardingModal = (_a) => {
var { children, withSimilac, banner, withPortal } = _a, rest = __rest(_a, ["children", "withSimilac", "banner", "withPortal"]);
const { isMobile } = useScreenSize();
const { isMarryBaby } = useContext(OnboardingContext);
const { t } = useTranslations();
if (withPortal && typeof window === 'undefined')
return null;
const MainContent = (React__default.createElement(StyledOnboardingModal, Object.assign({}, rest),
React__default.createElement(StyledContainer, null,
React__default.createElement(Grid, { sx: {
[MediaQueries.mbDown]: {
margin: 0,
},
'.mantine-Grid-col': {
[MediaQueries.mbDown]: {
padding: 0,
},
},
} },
React__default.createElement(Grid.Col, { span: (typeof banner === 'object' || withSimilac) && !isMobile ? 6 : 12, order: withSimilac ? 2 : 1, orderMd: withSimilac ? 1 : 2, sx: {
zIndex: withSimilac ? 99 : undefined,
} },
React__default.createElement(StyledContent, { "data-similac": withSimilac, "data-has-banner": typeof banner === 'object' }, children)),
banner && typeof banner === 'object' && !withSimilac && (React__default.createElement(Grid.Col, { span: !isMobile ? 6 : 12, order: 1, orderMd: 2 },
React__default.createElement(StyledBannerCol, null,
React__default.createElement(StyledBannerInner, { "data-is-marry-baby": isMarryBaby },
React__default.createElement(StyledIntro, null,
banner.heading && (React__default.createElement(Title, { order: 1, mb: 24 }, banner.heading)),
banner.description && (React__default.createElement(Text, { size: "p1", color: theme.colors.gray800 }, t('onboarding.welcomeScreen.content')))),
React__default.createElement(StyledBannerImgWrapper, null, banner.imgSrc ? (React__default.createElement("img", { src: banner.imgSrc, loading: "lazy" })) : banner.imgComponent ? (banner.imgComponent) : null))))),
banner &&
typeof banner === 'object' &&
withSimilac &&
(banner.imgSrc || banner.imgComponent) && (React__default.createElement(Grid.Col, { span: 'auto', order: 1, orderMd: 2 },
React__default.createElement(StyledBannerImgWrapper, { className: "similac" }, banner.imgSrc ? (React__default.createElement("img", { src: banner.imgSrc, loading: "lazy" })) : banner.imgComponent ? (banner.imgComponent) : null)))))));
if (withPortal) {
return createPortal(MainContent, getPopupWrapperDom());
}
return MainContent;
};
const StyledFormInner$1 = styled.div `
margin-top: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&.similac {
margin-top: 16px;
}
`;
const StyledOnboarding$1 = styled(Container) `
&.hhg-comp-onboarding-container.hhg-comp-onboarding-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
width: 100%;
max-width: 520px;
}
.header {
margin-bottom: 32px;
text-align: center;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
}
.input-control {
width: 100%;
}
.radio-group,
.input-control {
margin-bottom: 16px;
}
.form {
width: 100%;
}
/* .form-error {
margin-top: 32px;
font-size: 14px;
}
.field-error {
margin-top: 10px;
font-size: 14px;
} */
.form-button {
width: 100%;
}
`;
const StyledThumb$1 = styled.img `
margin-bottom: 38px;
`;
const Onboarding$1 = (_a) => {
var _b;
var { heading, description, children, className, imgSrc, hiddenLogo = false } = _a, rest = __rest(_a, ["heading", "description", "children", "className", "imgSrc", "hiddenLogo"]);
const { isMarryBaby, siteType } = useContext(OnboardingContext);
return (React__default.createElement(StyledOnboarding$1, Object.assign({}, rest, { className: `hhg-comp-onboarding-container ${className}`, size: "sm" }),
!hiddenLogo && (React__default.createElement(LogoIcon, { type: isMarryBaby
? siteType
: (((_b = LOCALE_SPECS[process.env.UNIFY_LOCALE]) === null || _b === void 0 ? void 0 : _b.LOGO_TYPE) ||
'hellobacsi') })),
React__default.createElement(StyledFormInner$1, { className: hiddenLogo ? 'similac' : '' },
imgSrc && React__default.createElement(StyledThumb$1, { src: imgSrc, loading: "lazy" }),
(heading || description) && (React__default.createElement("div", { className: "header" },
heading && React__default.createElement(Title, { order: 3 }, heading),
description && (React__default.createElement(Text, { size: "p3", mt: 8, color: theme.colors.gray600 }, description)))),
children)));
};
const StyledOnboardingForm$2 = styled(Onboarding$1) `
.phone-input {
width: 100%;
margin-bottom: 32px;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
.PhoneInput {
margin-bottom: 16px;
}
.PhoneInputCountry {
border-radius: 4px 0 0 4px;
}
.PhoneInputInput {
border-radius: 0 4px 4px 0;
}
}
&:not([data-active='true']) {
display: none !important;
}
`;
const onboardingSchema = (t) => yup.object().shape({
phone: yup.string().required(t('onboarding.updatePhone.error')).default(''),
});
const DefaultOnboardingForm = ({ onClose, onSubmit: _onSubmit, canSkip = true, customFormTexts, isActive, submitProps, submitLabel, skipProps, isWhatsApp, }) => {
const { t } = useTranslations();
const { sharedData, setSharedData, nextStep } = useContext(OnboardingContext);
const form = useForm({
initialValues: {
phone: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.phone) || '',
},
validate: yupResolver(onboardingSchema(t)),
});
const onSubmit = (values) => __awaiter(void 0, void 0, void 0, function* () {
try {
setSharedData((p) => (Object.assign(Object.assign({}, p), { phone: values.phone })));
const error = yield (_onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(values.phone));
!error && nextStep();
}
catch (err) {
console.error(err);
}
});
const onError = (fieldErrors) => {
console.log(fieldErrors);
};
return (React__default.createElement(StyledOnboardingForm$2, { heading: (customFormTexts === null || customFormTexts === void 0 ? void 0 : customFormTexts.heading) || t('onboarding.updatePhone.heading'), description: (customFormTexts === null || customFormTexts === void 0 ? void 0 : customFormTexts.description) ||
(isWhatsApp
? t('onboarding.updateWhatsapp.description')
: t('onboarding.updatePhone.description')), "data-active": isActive },
React__default.createElement(FormProvider, { form: form },
React__default.createElement("form", { onSubmit: form.onSubmit(onSubmit, onError) },
React__default.createElement(DynamicForm, { inputOrder: ['phone'] }),
React__default.createElement(Button, Object.assign({ variant: "primary", fullWidth: true, size: "lg" }, (isWhatsApp && {
leftIcon: React__default.createElement(Icon.WhatsApp, { size: 18, useCurrentColor: true }),
}), submitProps, { type: "submit", "data-event-category": isWhatsApp ? 'OTP' : 'Sign Up', "data-event-action": isWhatsApp
? 'Whatsapp - Fill phone and continue Click'
: 'Update Phone Number', "data-event-label": typeof window !== 'undefined' ? window.location.href : '', className: "pointer-event-child-none" }), submitLabel ||
(isWhatsApp
? t('onboarding.updateWhatsapp.submitLabel')
: t('onboarding.button.continue'))),
canSkip && (React__default.createElement(Button, Object.assign({ variant: "ghost", fullWidth: true, size: "lg" }, (isWhatsApp && {
dataEventCategory: 'OTP',
dataEventAction: 'Whatsapp - Skip fill phone Click',
dataEventLabel: typeof window !== 'undefined' ? window.location.href : '',
}), skipProps, { onClick: onClose, type: "button" }), t('onboarding.button.skip')))))));
};
const StyledOtpForm = styled(Onboarding$1) `
.otp-input {
margin-bottom: 36px;
${MediaQueries.mbDown} {
margin-bottom: 20px;
}
.otpContainer {
margin-bottom: 16px;
}
}
.resend {
display: flex;
gap: 6px;
margin-bottom: 32px;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
a {
text-decoration: underline;
cursor: pointer;
}
}
.phone-description {
margin-left: 2px;
margin-top: 2px;
}
.otp-description-edit-icon {
cursor: pointer;
vertical-align: bottom;
/* height: 100%; */
margin-bottom: 3px;
margin-left: 3px;
}
`;
// export const StyledOtpForm = styled(Container)`
// &.hhg-comp-onboarding-container.hhg-comp-onboarding-container {
// display: flex;
// flex-direction: column;
// align-items: center;
// height: 100%;
// width: 100%;
// text-align: center;
// max-width: 520px;
// }
// .header {
// margin-top: 70px;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
// gap: 8px;
// margin-bottom: 32px;
// ${MediaQueries.mbDown} {
// margin-bottom: 16px;
// }
// }
// .otpContainer {
// margin-bottom: 36px;
// ${MediaQueries.mbDown} {
// margin-bottom: 20px;
// }
// }
// .resend {
// display: flex;
// gap: 6px;
// margin-bottom: 32px;
// ${MediaQueries.mbDown} {
// margin-bottom: 16px;
// }
// a {
// text-decoration: underline;
// cursor: pointer;
// }
// }
// `
const otpSchema = (t) => yup.object().shape({
otp: yup
.string()
.required(t('onboarding.otpForm.error'))
.length(6, t('onboarding.otpForm.error'))
.default(''),
});
const EmailOtpForm = ({ onSubmit: _onSubmit, email: emailProp, onResendCode, otpError, onClose, loading,
// onBack,
canSkip: canSkipInit, }) => {
const { sharedData: { email: emailContext, retryEmailCount }, setSharedData, prevStep, siteType, isMarryBaby, nextStep, } = useContext(OnboardingContext);
const email = emailProp || emailContext || '';
const [seconds, setSeconds] = useState(30);
const interval = useInterval(() => setSeconds((s) => s - 1), 1000);
const [canSkip, handlers] = useCounter(0, { min: 0, max: 3 });
const preventClickRef = useRef(true);
const { t } = useTranslations();
useEffect(() => {
interval.start();
return interval.stop;
}, []);
useEffect(() => {
if (seconds === 0) {
interval.stop();
preventClickRef.current = false;
}
}, [seconds]);
const form = useForm({
initialValues: {
otp: '',
},
validate: yupResolver(otpSchema(t)),
});
useEffect(() => {
if (otpError)
form.setFieldError('otp', otpError);
}, [otpError]);
const onSubmit = (values) => __awaiter(void 0, void 0, void 0, function* () {
try {
handlers.increment();
const error = yield (_onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(values.otp));
!error && nextStep();
}
catch (err) {
console.error(err);
}
});
const onError = (fieldErrors) => {
console.log(fieldErrors);
};
const throttleResendCode = useMemo(() => {
return throttle(() => {
if (preventClickRef.current)
return;
handlers.increment();
setSeconds(30);
onResendCode === null || onResendCode === void 0 ? void 0 : onResendCode(email);
interval.start();
preventClickRef.current = true;
}, 1000, { trailing: false });
}, [email, onResendCode, interval]);
const onBack = () => {
if (retryEmailCount >= 2)
return;
setSharedData((d) => (Object.assign(Object.assign({}, d), { retryEmailCount: d.retryEmailCount + 1 })));
prevStep();
};
const outOfEdit = retryEmailCount >= 2;
return (React__default.createElement(StyledOtpForm, { heading: t('onboarding.otpForm.heading'), description: React__default.createElement(React__default.Fragment, null,
React__default.createElement("span", { dangerouslySetInnerHTML: {
__html: t('onboarding.otpForm.descriptionEmail', {
email: `<b style="color:${theme.colors.gray800}">${hiddenEmailChar(email)}</b>`,
}),
} }),
!outOfEdit && (React__default.createElement("svg", { onClick: onBack, width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "otp-description-edit-icon" },
React__default.createElement("path", { d: "M12.7812 1.33337C12.2987 1.33337 11.8162 1.51712 11.4479 1.88546L10.6667 2.66671L13.3333 5.33337L14.1146 4.55212C14.8506 3.81612 14.8506 2.62212 14.1146 1.88546C13.7463 1.51712 13.2638 1.33337 12.7812 1.33337ZM9.66667 3.66671L2 11.3334V14H4.66667L12.3333 6.33337L9.66667 3.66671Z", fill: "#ADB3BC" })))) },
React__default.createElement(FormProvider, { form: form },
React__default.createElement("form", { onSubmit: form.onSubmit(onSubmit, onError) },
React__default.createElement(DynamicForm, { inputOrder: ['otp'] }),
React__default.createElement("div", { className: "resend" },
React__default.createElement(Text$1, { size: "p4", color: theme.colors.gray400 }, t('onboarding.otpForm.notReceiveOTP')),
React__default.createElement(Text$1, { as: "a", size: "p4", color: isMarryBaby ? theme.mbColors.pink : theme.colors.primaryBase, onClick: throttleResendCode }, seconds === 0
? t('onboarding.otpForm.resendCode')
: t('onboarding.otpForm.resendCodeWithSeconds', { seconds }))),
React__default.createElement(Button$1, { theme: siteType, color: "primary", isBlock: true, size: "lg", type: "submit", isLoading: loading, disabled: loading, "data-event-category": "Sign Up", "data-event-action": "Confirm Phone Number", "data-event-label": typeof window !== 'undefined' ? window.location.href : '', className: "pointer-event-child-none" }, t('onboarding.button.continue')),
canSkipInit && canSkip >= 3 && (React__default.createElement(Button$1, { theme: siteType, color: "ghost", isBlock: true, size: "lg", onClick: onClose, type: "button" }, t('onboarding.button.skip')))))));
};
const PhoneOtpForm = ({ onSubmit: _onSubmit, phone: phoneProp, onResendCode, otpError, onClose, loading,
// onBack,
canSkip: canSkipInit, isWhatsApp, }) => {
const { sharedData: { phone: phoneContext, retryPhoneCount }, setSharedData, prevStep, siteType, isMarryBaby, nextStep, } = useContext(OnboardingContext);
const phone = phoneProp || phoneContext || '';
const [seconds, setSeconds] = useState(30);
const interval = useInterval(() => setSeconds((s) => s - 1), 1000);
const [canSkip, handlers] = useCounter(0, { min: 0, max: 3 });
const preventClickRef = useRef(true);
const { t } = useTranslations();
useEffect(() => {
interval.start();
return interval.stop;
}, []);
useEffect(() => {
if (seconds === 0) {
interval.stop();
preventClickRef.current = false;
}
}, [seconds]);
const form = useForm({
initialValues: {
otp: '',
},
validate: yupResolver(otpSchema(t)),
});
useEffect(() => {
if (otpError)
form.setFieldError('otp', otpError);
}, [otpError]);
const onSubmit = (values) => __awaiter(void 0, void 0, void 0, function* () {
try {
handlers.increment();
const error = yield (_onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(values.otp));
!error && nextStep();
}
catch (err) {
console.error(err);
}
});
const onError = (fieldErrors) => {
console.log(fieldErrors);
};
const throttleResendCode = useMemo(() => {
return throttle(() => {
if (preventClickRef.current)
return;
handlers.increment();
setSeconds(30);
onResendCode === null || onResendCode === void 0 ? void 0 : onResendCode(phone);
interval.start();
preventClickRef.current = true;
}, 1000, { trailing: false });
}, [phone, onResendCode, interval]);
const onBack = () => {
if (retryPhoneCount >= 2)
return;
setSharedData((d) => (Object.assign(Object.assign({}, d), { retryPhoneCount: d.retryPhoneCount + 1 })));
prevStep();
};
const outOfEdit = retryPhoneCount >= 2;
const phoneEleStr = `<b style="color:${theme.colors.gray800}">${phone
.slice(0, -3)
.replace(/./g, 'x')
.concat(phone.slice(-3))}</b>`;
return (React__default.createElement(StyledOtpForm, { heading: isWhatsApp ? (React__default.createElement(Flex, { align: 'center', justify: 'center', gap: rem(8) },
React__default.createElement("img", { style: { width: rem(24) }, loading: "lazy", src: CommonGAssets.getAssetPath('whatsapp.svg'), alt: "whatsapp" }),
React__default.createElement("span", null, t('onboarding.otpWhatsapps.heading')))) : (t('onboarding.otpForm.heading')), description: React__default.createElement(React__default.Fragment, null,
React__default.createElement("span", { dangerouslySetInnerHTML: {
__html: t(isWhatsApp
? 'onboarding.otpWhatsapps.description'
: 'onboarding.otpForm.description', {
phone: phoneEleStr,
}),
} }),
!outOfEdit && (React__default.createElement("svg", { onClick: onBack, width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "otp-description-edit-icon" },
React__default.createElement("path", { d: "M12.7812 1.33337C12.2987 1.33337 11.8162 1.51712 11.4479 1.88546L10.6667 2.66671L13.3333 5.33337L14.1146 4.55212C14.8506 3.81612 14.8506 2.62212 14.1146 1.88546C13.7463 1.51712 13.2638 1.33337 12.7812 1.33337ZM9.66667 3.66671L2 11.3334V14H4.66667L12.3333 6.33337L9.66667 3.66671Z", fill: "#ADB3BC" })))) },
React__default.createElement(FormProvider, { form: form },
React__default.createElement("form", { onSubmit: form.onSubmit(onSubmit, onError) },
React__default.createElement(DynamicForm, { inputOrder: ['otp'] }),
React__default.createElement("div", { className: "resend" },
React__default.createElement(Text, { size: "p4", color: theme.colors.gray400 }, t('onboarding.otpForm.notReceiveOTP')),
React__default.createElement(Text, { as: "a", size: "p4", color: isMarryBaby ? theme.mbColors.pink : theme.colors.primaryBase, onClick: throttleResendCode }, seconds === 0
? t('onboarding.otpForm.resendCode')
: t('onboarding.otpForm.resendCodeWithSeconds', { seconds }))),
React__default.createElement(Button$1, { theme: siteType, color: "primary", isBlock: true, size: "lg", type: "submit", isLoading: loading, disabled: loading, "data-event-category": isWhatsApp ? 'OTP' : 'Sign Up', "data-event-action": isWhatsApp
? 'Whatsapp - OTP verified Click'
: 'Confirm Phone Number', "data-event-label": typeof window !== 'undefined' ? window.location.href : '', className: "pointer-event-child-none" }, t('onboarding.button.continue')),
canSkipInit && canSkip >= 3 && (React__default.createElement(Button$1, { theme: siteType, color: "ghost", isBlock: true, size: "lg", onClick: onClose, type: "button" }, t('onboarding.button.skip')))))));
};
const onboardingEmailSchema = (t) => yup.object().shape({
email: yup
.string()
.required(t('onboarding.errorMessage.requiredEmail'))
.email(t('onboarding.errorMessage.invalidEmail'))
.default(''),
name: yup.string().required(t('onboarding.errorMessage.requiredName')),
});
const StyledFormInner = styled.div `
margin-top: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&.similac {
margin-top: 16px;
}
`;
const StyledOnboarding = styled(Container) `
&.hhg-comp-onboarding-container.hhg-comp-onboarding-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
width: 100%;
max-width: 520px;
}
.header {
margin-bottom: 32px;
text-align: center;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
}
.input-control {
width: 100%;
}
.radio-group,
.input-control {
margin-bottom: 16px;
}
.form {
width: 100%;
}
/* .form-error {
margin-top: 32px;
font-size: 14px;
}
.field-error {
margin-top: 10px;
font-size: 14px;
} */
.form-button {
width: 100%;
}
`;
const StyledThumb = styled.img `
margin-bottom: 38px;
`;
const OnboardingUI = (_a) => {
var _b;
var { heading, description, children, className, imgSrc, hiddenLogo = false } = _a, rest = __rest(_a, ["heading", "description", "children", "className", "imgSrc", "hiddenLogo"]);
const { isMarryBaby, siteType } = useContext(OnboardingContext);
return (React__default.createElement(StyledOnboarding, Object.assign({}, rest, { className: `hhg-comp-onboarding-container ${className}`, size: "sm" }),
!hiddenLogo && (React__default.createElement(LogoIcon, { type: isMarryBaby
? siteType
: (((_b = LOCALE_SPECS[process.env.UNIFY_LOCALE]) === null || _b === void 0 ? void 0 : _b.LOGO_TYPE) ||
'hellobacsi') })),
React__default.createElement(StyledFormInner, { className: hiddenLogo ? 'similac' : '' },
imgSrc && React__default.createElement(StyledThumb, { src: imgSrc, loading: "lazy" }),
React__default.createElement("div", { className: "header" },
React__default.createElement(Title, { order: 3 }, heading),
React__default.createElement(Text, { size: "p3", mt: 8, color: theme.colors.gray600 }, description)),
children)));
};
const PersonalInfoForm = ({ onClose, onSubmit, canSkip, loading, errorMessage, initialData, }) => {
const { t, locale } = useTranslations();
const { siteType, isMarryBaby, setSharedData, nextStep } = useContext(OnboardingContext);
const form = useForm({
validate: yupResolver(onboardingEmailSchema(t)),
});
const onError = (fieldErrors) => {
console.log({ fieldErrors });
};
useEffect(() => {
form.setValues(Object.assign(Object.assign({ gender: '0' }, initialData), ((initialData === null || initialData === void 0 ? void 0 : initialData.birthday) && {
birthday: new Date(initialData.birthday),
})));
}, [initialData]);
useEffect(() => {
if (errorMessage)
form.setFieldError('email', errorMessage);
}, [errorMessage]);
return (React__default.createElement(OnboardingUI, { heading: t('onboarding.formEmail.heading'), description: t('onboarding.formEmail.description', {
site: isMarryBaby
? 'Marry Baby'
: LOCALE_SPECS[locale].SITE_NAME_FORMATTED,
}) },
React__default.createElement(FormProvider, { form: form },
React__default.createElement("form", { className: "form", onSubmit: form.onSubmit((values) => __awaiter(void 0, void 0, void 0, function* () {
setSharedData((d) => (Object.assign(Object.assign({}, d), values)));
const error = yield (onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(Object.assign(Object.assign({}, values), { birthday: values.birthday && format(values.birthday, 'yyyy-MM-dd') })));
!error && nextStep();
}), onError) },
React__default.createElement(DynamicForm, { inputOrder: ['full_name', 'email', 'dob', 'gender'] }),
React__default.createElement(Button$1, { color: "primary", isBlock: true, size: "lg", type: "submit", theme: siteType, isLoading: loading, disabled: loading }, t('onboarding.button.continue')),
canSkip && (React__default.createElement(Button$1, { theme: siteType, color: "ghost", isBlock: true, size: "lg", onClick: onClose, type: "button" }, t('onboarding.button.skip')))))));
};
const OnboardingProvider = ({ children, siteType, setSharedData: _setSharedData, }) => {
const [currentStep, setCurrentStep] = useState(0);
const [maxStep, setMaxStep] = useState(0);
const [sharedData, setSharedData] = useState({});
const nextStep = () => currentStep + 1 <= maxStep && setCurrentStep(currentStep + 1);
const prevStep = () => currentStep - 1 >= 0 && setCurrentStep(currentStep - 1);
useEffect(() => {
_setSharedData === null || _setSharedData === void 0 ? void 0 : _setSharedData(sharedData);
}, [sharedData, _setSharedData]);
return (React__default.createElement(OnboardingContext.Provider, { value: {
currentStep,
setCurrentStep,
setMaxStep,
nextStep,
prevStep,
siteType,
isMarryBaby: siteType === 'marryBaby',
sharedData,
setSharedData,
} }, children));
};
const ResultScreen = (_a) => {
var { onClose } = _a, rest = __rest(_a, ["onClose"]);
const { t } = useTranslations();
const { siteType } = useContext(OnboardingContext);
return (React__default.createElement(OnboardingUI, Object.assign({}, rest),
React__default.createElement(Button$1, { theme: siteType, size: "lg", onClick: onClose, className: "form-button" }, t('onboarding.button.continue'))));
};
const StyledOnboardingForm$1 = styled(Onboarding$1) `
.phone-input {
width: 100%;
margin-bottom: 32px;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
.PhoneInput {
margin-bottom: 16px;
}
.PhoneInputCountry {
border-radius: 4px 0 0 4px;
}
.PhoneInputInput {
border-radius: 0 4px 4px 0;
}
}
&:not([data-active='true']) {
display: none !important;
}
`;
const similacOnboardingSchema = (t, optionalTerm) => yup.object().shape({
phone: yup.string().required(t('onboarding.updatePhone.error')).default(''),
name: yup.string().required(t('onboarding.errorMessage.requiredName')),
email: yup
.string()
.required(t('onboarding.errorMessage.requiredEmail'))
.email(t('onboarding.errorMessage.invalidEmail'))
.default(''),
address: yup.mixed().required(t('onboarding.similac.address.error')),
term: optionalTerm
? yup.bool()
: yup.bool().oneOf([true], t('validation.error.requiredField')),
});
const SimilacOnboardingForm = (_a) => {
var { onClose, onSubmit: _onSubmit, canSkip = true, customFormTexts, customTerms, defaultValues, isActive } = _a, rest = __rest(_a, ["onClose", "onSubmit", "canSkip", "customFormTexts", "customTerms", "defaultValues", "isActive"]);
const { t } = useTranslations();
const { nextStep, setSharedData, sharedData } = useContext(OnboardingContext);
const { isMobile } = useScreenSize();
const form = useForm({
initialValues: {
term: false,
phone: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.phone) || (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.phone) || '',
email: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.email) || (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.email) || '',
name: (sharedData === null || sharedData === void 0 ? void 0 : sharedData.name) || (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.name) || '',
},
validate: yupResolver(similacOnboardingSchema(t, !customTerms)),
});
const onSubmit = (values) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield (_onSubmit === null || _onSubmit === void 0 ? void 0 : _onSubmit(values));
setSharedData((d) => (Object.assign(Object.assign({}, d), { phone: values.phone, email: values.email, name: values.name })));
nextStep();
}
catch (err) {
console.error(err);
}
});
const onError = (fieldErrors) => {
console.log(fieldErrors);
};
const inputOrder = (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.email)
? ['full_name', 'phone', 'address', 'term']
: ['full_name', 'email', 'phone', 'address', 'term'];
return (React__default.createElement(StyledOnboardingForm$1, Object.assign({ heading: (customFormTexts === null || customFormTexts === void 0 ? void 0 : customFormTexts.heading) || t('onboarding.updatePhone.heading'), description: (customFormTexts === null || customFormTexts === void 0 ? void 0 : customFormTexts.description) || t('onboarding.updatePhone.description'), hiddenLogo: isMobile, "data-active": isActive }, rest),
React__default.createElement(FormProvider, { form: form },
React__default.createElement("form", { style: {
width: '100%',
}, onSubmit: form.onSubmit(onSubmit, onError) },
React__default.createElement(DynamicForm, { inputOrder: inputOrder, withSimilac: true, customTerms: customTerms }),
React__default.createElement(Button, { fullWidth: true, size: "lg", type: "submit", "data-event-category": "Sign Up", "data-event-action": "Update Phone Number", "data-event-label": typeof window !== 'undefined' ? window.location.href : '', className: "pointer-event-child-none" }, t('onboarding.button.continue')),
canSkip && (React__default.createElement(Button, { variant: "ghost", fullWidth: true, size: "lg", onClick: onClose, type: "button" }, t('onboarding.button.skip')))))));
};
const OnboardingStepRenderer = ({ children, onStepChange }) => {
const { currentStep, setMaxStep } = useContext(OnboardingContext);
const childrenCount = React__default.Children.count(children);
useEffect(() => {
onStepChange === null || onStepChange === void 0 ? void 0 : onStepChange(currentStep);
}, [currentStep]);
useEffect(() => {
setMaxStep(childrenCount - 1);
}, [childrenCount]);
return (React__default.createElement(React__default.Fragment, null, flattenChildren(children).map((element, idx) => {
const active = idx === currentStep;
return (React__default.createElement(Fragment, { key: idx }, !React__default.isValidElement(element)
? active
? element
: null
: element.props.alwaysRender || active
? React__default.cloneElement(element, {
isActive: idx === currentStep,
stepIndex: idx,
})
: null));
})));
};
const StyledOnboardingForm = styled(Onboarding$1) `
.phone-input {
width: 100%;
margin-bottom: 32px;
${MediaQueries.mbDown} {
margin-bottom: 16px;
}
.PhoneInput {
margin-bottom: 16px;
}
.PhoneInputCountry {
border-radius: 4px 0 0 4px;
}
.PhoneInputInput {
border-radius: 0 4px 4px 0;
}
}
&:not([data-active='true']) {
display: none !important;
}
`;
const ThankYouStepRenderer = (_a) => {
var { onClose, thanksPageInfo, isActive } = _a, rest = __rest(_a, ["onClose", "thanksPageInfo", "isActive"]);
const { t } = useTranslations();
const { isMobile } = useScreenSize();
return (React__default.createElement(StyledOnboardingForm, Object.assign({ heading: '', description: '', hiddenLogo: isMobile, "data-active": isActive }, rest),
React__default.createElement(Container, { fluid: true },
React__default.createElement(Stack, { align: "center", spacing: 8, w: "100%", ta: "center" },
React__default.createElement(AspectRatio, { ratio: 1, w: { base: 120, md: 160 } },
React__default.createElement("svg", { width: "160", height: "160", viewBox: "0 0 160 160", fill: "none" },
React__default.createElement("mask", { id: "mask0_4580_96805", maskUnits: "userSpaceOnUse", x: "0", y: "0", width: "160", height: "160" },
React__default.createElement("circle", { cx: "80", cy: "80", r: "80", fill: "url(#paint0_radial_4580_96805)" })),
React__default.createElement("g", { mask: "url(#mask0_4580_96805)", fill: "#E0F8EE" },
React__default.createElement("path", { d: "m71.594.46 5.382 37.677c.035 0 .106 0 .141-.035l5.242 36.901 5.207-36.936h.07l5.207-37.043A81 81 0 0 0 80.002 0c-2.85 0-5.664.141-8.408.46m59.556 18.08a79.7 79.7 0 0 0-17.977-11.336L97.87 41.068c.035 0 .07.036.07.036L82.46 75.286z" }),
React__default.createElement("path", { d: "M46.439 64.833 82.11 75.321h-.14l.352.106h.035l.035-.035.035.035h-.035l.035.035h.035l.14.071-.105-.07 35.849 10.523c0 .035 0 .035-.035.07l39.789 11.76a81.6 81.6 0 0 0 1.9-17.48c0-1.66-.071-3.355-.141-4.98h-40.035v.071l-37.362.035v-.035l.176-.035-.14.07.316-.106h-.176l72.858-21.717a81 81 0 0 0-9.885-19.35L82.639 75.285h-.14l.07-.07-.106.07.035-.212-.07.141v