@homefile/components-v2 2.63.0 → 2.63.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/onboarding/CardFooter.js +2 -1
  2. package/dist/components/onboarding/pages/ActivateAccount.js +3 -3
  3. package/dist/components/onboarding/pages/AuthHeader.js +2 -2
  4. package/dist/components/onboarding/pages/BasePageWrapper.d.ts +32 -1
  5. package/dist/components/onboarding/pages/BasePageWrapper.js +23 -3
  6. package/dist/components/onboarding/pages/EmailValidation.js +2 -2
  7. package/dist/components/onboarding/pages/MessagePage.js +3 -3
  8. package/dist/components/onboarding/pages/NewPassword.js +3 -3
  9. package/dist/components/onboarding/pages/ResendResetPassword.js +2 -2
  10. package/dist/components/onboarding/pages/ResetPassword.js +3 -3
  11. package/dist/components/onboarding/pages/SignIn.js +3 -3
  12. package/dist/components/onboarding/pages/SignUp.js +3 -3
  13. package/dist/components/onboarding/pages/TwoFactor.d.ts +1 -1
  14. package/dist/components/onboarding/pages/TwoFactor.js +13 -4
  15. package/dist/components/onboarding/pages/Welcome.js +2 -2
  16. package/dist/interfaces/pages/TwoFactor.interface.d.ts +2 -1
  17. package/dist/stories/onboarding/CardFooter.stories.d.ts +2 -1
  18. package/dist/stories/onboarding/CardFooter.stories.js +24 -0
  19. package/dist/stories/onboarding/pages/ActivateAccount.stories.d.ts +3 -1
  20. package/dist/stories/onboarding/pages/ActivateAccount.stories.js +41 -0
  21. package/dist/stories/onboarding/pages/EmailValidation.stories.d.ts +3 -1
  22. package/dist/stories/onboarding/pages/EmailValidation.stories.js +43 -0
  23. package/dist/stories/onboarding/pages/MessagePage.stories.js +10 -2
  24. package/dist/stories/onboarding/pages/NewPassword.stories.d.ts +3 -1
  25. package/dist/stories/onboarding/pages/NewPassword.stories.js +44 -0
  26. package/dist/stories/onboarding/pages/ResendResetPassword.stories.d.ts +3 -1
  27. package/dist/stories/onboarding/pages/ResendResetPassword.stories.js +47 -0
  28. package/dist/stories/onboarding/pages/ResetPassword.stories.d.ts +3 -1
  29. package/dist/stories/onboarding/pages/ResetPassword.stories.js +45 -0
  30. package/dist/stories/onboarding/pages/SignIn.stories.d.ts +2 -0
  31. package/dist/stories/onboarding/pages/SignIn.stories.js +52 -0
  32. package/dist/stories/onboarding/pages/SignUp.stories.d.ts +2 -1
  33. package/dist/stories/onboarding/pages/SignUp.stories.js +34 -0
  34. package/dist/stories/onboarding/pages/TwoFactor.stories.d.ts +3 -1
  35. package/dist/stories/onboarding/pages/TwoFactor.stories.js +68 -11
  36. package/dist/stories/onboarding/pages/Welcome.stories.d.ts +2 -1
  37. package/dist/stories/onboarding/pages/Welcome.stories.js +29 -0
  38. package/dist/stories/onboarding/phoneLayout.d.ts +20 -0
  39. package/dist/stories/onboarding/phoneLayout.js +89 -0
  40. package/package.json +1 -1
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Container, Text } from '@chakra-ui/react';
3
+ import { ONBOARDING_PAGE_PX } from '../../components';
3
4
  export const CardFooter = ({ title = '', buttonLabel, handleButtonClick, children, }) => {
4
- return (_jsx(Container, { variant: "secondary", centerContent: true, w: "full", flex: { base: 1, md: 'initial' }, children: _jsxs(Box, { w: "full", px: ['container.sm', 'container.md', 'container.lg'],
5
+ return (_jsx(Container, { variant: "secondary", centerContent: true, w: "full", flex: { base: 1, md: 'initial' }, children: _jsxs(Box, { w: "full", px: ONBOARDING_PAGE_PX,
5
6
  // Mobile: keep the footer text pinned at the top of the (grown) green
6
7
  // area instead of vertically centering it. Desktop: centered as before.
7
8
  my: { base: 0, md: 'auto' }, py: "2rem", children: [_jsxs(Text, { textAlign: "center", variant: "body", children: [title, ' ', _jsx(Box, { as: "button", type: "button", display: "inline", color: "link.default", fontWeight: "medium", onClick: handleButtonClick, _hover: { textDecoration: 'underline' }, _focusVisible: {
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { Box, Container, Text, Center, Button } from '@chakra-ui/react';
4
- import { Logo, WelcomeHeader, ButtonLoader, BasePageWrapper, } from '../../../components';
4
+ import { Logo, WelcomeHeader, ButtonLoader, BasePageWrapper, ONBOARDING_PHONE_PX, onboardingCardProps, } from '../../../components';
5
5
  import { useWindowDimensions } from '../../../hooks';
6
6
  export const ActivateAccount = ({ name, isLoading = false, handleActivateBt, }) => {
7
7
  const { windowDimensions: { width }, } = useWindowDimensions();
8
- return (_jsx(BasePageWrapper, { children: _jsxs(Container, { size: "validation", boxShadow: "lg", children: [_jsx(Container, { variant: "secondary", children: _jsx(Logo, {}) }), _jsxs(Box, { px: ['container.sm', 'container.lg'], children: [_jsx(WelcomeHeader, { description: t('registration.instruction'), greeting: t('welcome.greeting'), name: name }), _jsx(Center, { children: _jsx(Button, { onClick: handleActivateBt, isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), size: "onboarding", children: width < 400
8
+ return (_jsx(BasePageWrapper, { flushMobile: true, flushBelow: "sm", children: _jsxs(Container, Object.assign({ size: "validation" }, onboardingCardProps({ below: 'sm', maxW: 'container.lg' }), { children: [_jsx(Container, { variant: "secondary", children: _jsx(Logo, {}) }), _jsxs(Box, { px: [ONBOARDING_PHONE_PX, 'container.lg'], children: [_jsx(WelcomeHeader, { description: t('registration.instruction'), greeting: t('welcome.greeting'), name: name }), _jsx(Center, { children: _jsx(Button, { onClick: handleActivateBt, isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), size: "onboarding", children: width < 400
9
9
  ? t('registration.activateBtShort')
10
- : t('registration.activateBt') }) }), _jsx(Text, { variant: "info", mt: "8", children: t('welcome.signature') })] }), _jsx(Container, { variant: "tertiary", mt: "8", children: _jsx(Center, { h: "12", px: "4", children: _jsx(Text, { variant: "label", children: t('registration.notReply') }) }) })] }) }));
10
+ : t('registration.activateBt') }) }), _jsx(Text, { variant: "info", mt: "8", children: t('welcome.signature') })] }), _jsx(Container, { variant: "tertiary", mt: "8", children: _jsx(Center, { h: "12", px: "4", children: _jsx(Text, { variant: "label", children: t('registration.notReply') }) }) })] })) }));
11
11
  };
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { Flex, Text, Box, Image } from '@chakra-ui/react';
4
- import { Logo } from '../../../components';
4
+ import { Logo, ONBOARDING_PAGE_PX } from '../../../components';
5
5
  import { HomefileUpdate } from '../../../assets/images';
6
6
  export const AuthHeader = ({ isPartner = false }) => {
7
7
  if (!isPartner)
8
8
  return _jsx(Logo, {});
9
- return (_jsxs(Flex, { align: "center", justify: "space-between", w: "full", h: "container.xxs", px: ['container.sm', 'container.md', 'container.lg'], children: [_jsx(Image, { src: HomefileUpdate, alt: "Homefile", h: "image.logo" }), _jsx(Box, { pl: "base", borderLeft: "1px solid", borderColor: "gray.200", children: _jsx(Text, { fontSize: "lg", fontWeight: "medium", children: t('partner.admin') }) })] }));
9
+ return (_jsxs(Flex, { align: "center", justify: "space-between", w: "full", h: "container.xxs", px: ONBOARDING_PAGE_PX, children: [_jsx(Image, { src: HomefileUpdate, alt: "Homefile", h: "image.logo" }), _jsx(Box, { pl: "base", borderLeft: "1px solid", borderColor: "gray.200", children: _jsx(Text, { fontSize: "lg", fontWeight: "medium", children: t('partner.admin') }) })] }));
10
10
  };
@@ -1,6 +1,37 @@
1
1
  import { PropsWithChildren } from 'react';
2
+ export declare const ONBOARDING_PHONE_PX = "base";
3
+ export declare const ONBOARDING_PAGE_PX: string[];
4
+ export type FlushBelow = 'sm' | 'md';
5
+ export declare const onboardingCardProps: ({ below, shadow, maxW, }?: {
6
+ below?: FlushBelow;
7
+ shadow?: string;
8
+ maxW?: string;
9
+ }) => {
10
+ boxShadow: {
11
+ [x: string]: string;
12
+ base: string;
13
+ };
14
+ borderRadius: {
15
+ [x: string]: string | number;
16
+ base: number;
17
+ };
18
+ maxW: {
19
+ [x: string]: string;
20
+ base: string;
21
+ };
22
+ flex: {
23
+ [x: string]: string | number;
24
+ base: number;
25
+ };
26
+ display: {
27
+ [x: string]: string;
28
+ base: string;
29
+ };
30
+ flexDirection: "column";
31
+ };
2
32
  interface BasePageWrapperProps {
3
33
  flushMobile?: boolean;
34
+ flushBelow?: FlushBelow;
4
35
  }
5
- export declare const BasePageWrapper: ({ children, flushMobile, }: PropsWithChildren<BasePageWrapperProps>) => import("react/jsx-runtime").JSX.Element;
36
+ export declare const BasePageWrapper: ({ children, flushMobile, flushBelow, }: PropsWithChildren<BasePageWrapperProps>) => import("react/jsx-runtime").JSX.Element;
6
37
  export {};
@@ -1,9 +1,29 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box } from '@chakra-ui/react';
3
- export const BasePageWrapper = ({ children, flushMobile, }) => {
4
- return (_jsx(Box, { w: "container.full", zIndex: "2", position: "relative", mt: flushMobile ? { base: '0', md: 'onboarding.top' } : 'onboarding.top',
3
+ // The side padding of every onboarding page on a phone: 13px ('base', Matt
4
+ // 2026-10-07). The one place that says it.
5
+ export const ONBOARDING_PHONE_PX = 'base';
6
+ // The side padding of the sign-in family of onboarding pages (sign in, the code
7
+ // step, sign up, reset and new password, the message pages, the Sign-up box and
8
+ // the partner header): the phone value, 32px from 480px and 48px from 768px.
9
+ // One value, so the pages can't drift apart.
10
+ export const ONBOARDING_PAGE_PX = [ONBOARDING_PHONE_PX, 'container.md', 'container.lg'];
11
+ // Sign in's card on a phone, the one copy every onboarding page uses: below
12
+ // `below` the card is the whole page (no shadow, square corners, full width)
13
+ // and grows so the copyright sits at the bottom of the screen. From `below` up
14
+ // it is a card again, with the page's own shadow and width.
15
+ export const onboardingCardProps = ({ below = 'md', shadow = 'lg', maxW = 'container.md', } = {}) => ({
16
+ boxShadow: { base: 'none', [below]: shadow },
17
+ borderRadius: { base: 0, [below]: 'sm' },
18
+ maxW: { base: '100%', [below]: maxW },
19
+ flex: { base: 1, [below]: 'initial' },
20
+ display: { base: 'flex', [below]: 'block' },
21
+ flexDirection: 'column',
22
+ });
23
+ export const BasePageWrapper = ({ children, flushMobile, flushBelow = 'md', }) => {
24
+ return (_jsx(Box, { w: "container.full", zIndex: "2", position: "relative", mt: flushMobile ? { base: '0', [flushBelow]: 'onboarding.top' } : 'onboarding.top',
5
25
  // Mobile full-screen: this wrapper is the full-height flex column holding
6
26
  // the card + the copyright footer, so the card can flex to fill the space
7
27
  // above the copyright (which stays pinned at the bottom) with NO overflow.
8
- minH: flushMobile ? { base: '100vh', md: 'auto' } : undefined, display: flushMobile ? { base: 'flex', md: 'block' } : undefined, flexDirection: flushMobile ? 'column' : undefined, children: children }));
28
+ minH: flushMobile ? { base: '100vh', [flushBelow]: 'auto' } : undefined, display: flushMobile ? { base: 'flex', [flushBelow]: 'block' } : undefined, flexDirection: flushMobile ? 'column' : undefined, children: children }));
9
29
  };
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { chakra, Container, Text, Image, Center, Button, } from '@chakra-ui/react';
4
- import { Logo, ButtonLoader, BasePageWrapper } from '../../../components';
4
+ import { Logo, ButtonLoader, BasePageWrapper, ONBOARDING_PHONE_PX, onboardingCardProps, } from '../../../components';
5
5
  import { Confirmation } from '../../../assets/images';
6
6
  export const EmailValidation = ({ email, isLoading = false, handleResendBt, }) => {
7
- return (_jsx(BasePageWrapper, { children: _jsxs(Container, { size: "validation", boxShadow: "lg", children: [_jsxs(Container, { variant: "secondary", children: [_jsx(Logo, {}), _jsxs(Text, { variant: "title", textAlign: "center", px: ['container.sm', 'container.xl'], pb: 6, minH: "6rem", children: [_jsx(chakra.span, { color: "gray.3", children: t('validation.title1') }), _jsx(chakra.span, { color: "gray.3", children: email }), _jsx(chakra.span, { color: "gray.3", children: t('validation.title2') })] }), _jsx(Center, { children: _jsx(Image, { src: Confirmation, alt: "Activate account", h: ['100px', '145px'], w: "auto" }) })] }), _jsx(Text, { variant: "info", px: ['container.md', 'container.lg'], py: "2rem", textAlign: "center", children: t('validation.alert1') }), _jsx(Center, { children: _jsx(Button, { mb: 10, mx: 4, variant: "secondary", onClick: handleResendBt, isLoading: isLoading, spinner: _jsx(ButtonLoader, { isOutlined: true }), size: "onboarding", children: t('validation.resendBt') }) })] }) }));
7
+ return (_jsx(BasePageWrapper, { flushMobile: true, flushBelow: "sm", children: _jsxs(Container, Object.assign({ size: "validation" }, onboardingCardProps({ below: 'sm', maxW: 'container.lg' }), { children: [_jsxs(Container, { variant: "secondary", children: [_jsx(Logo, {}), _jsxs(Text, { variant: "title", textAlign: "center", px: [ONBOARDING_PHONE_PX, 'container.xl'], pb: 6, minH: "6rem", children: [_jsx(chakra.span, { color: "gray.3", children: t('validation.title1') }), _jsx(chakra.span, { color: "gray.3", children: email }), _jsx(chakra.span, { color: "gray.3", children: t('validation.title2') })] }), _jsx(Center, { children: _jsx(Image, { src: Confirmation, alt: "Activate account", h: ['100px', '145px'], w: "auto" }) })] }), _jsx(Text, { variant: "info", px: ['container.md', 'container.lg'], py: "2rem", textAlign: "center", children: t('validation.alert1') }), _jsx(Center, { children: _jsx(Button, { mb: 10, mx: [ONBOARDING_PHONE_PX, 4], variant: "secondary", onClick: handleResendBt, isLoading: isLoading, spinner: _jsx(ButtonLoader, { isOutlined: true }), size: "onboarding", children: t('validation.resendBt') }) })] })) }));
8
8
  };
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Button, Container, Stack, Text } from '@chakra-ui/react';
3
- import { Footer, BasePageWrapper, AuthHeader } from '../../../components';
3
+ import { Footer, BasePageWrapper, ONBOARDING_PAGE_PX, onboardingCardProps, AuthHeader, } from '../../../components';
4
4
  // A page with only a message: a title, a line under it and, optionally, one link
5
5
  // button (e.g. "Back to my texts" opening the texting app).
6
6
  export const MessagePage = ({ title, description, actionLabel, actionHref, }) => {
7
7
  const showAction = Boolean(actionLabel && actionHref);
8
- return (_jsxs(BasePageWrapper, { flushMobile: true, children: [_jsxs(Container, { size: "onboarding", bg: "neutral.white", boxShadow: { base: 'none', md: 'lg' }, borderRadius: { base: 0, md: 'sm' }, maxW: { base: '100%', md: 'container.md' }, flex: { base: 1, md: 'initial' }, display: { base: 'flex', md: 'block' }, flexDirection: "column", children: [_jsx(AuthHeader, {}), _jsxs(Stack, { my: "6", children: [_jsx(Text, { variant: "title", textAlign: "center", px: "10", children: title }), _jsx(Text, { fontFamily: "secondary", textAlign: "center", px: ['10', '20'],
8
+ return (_jsxs(BasePageWrapper, { flushMobile: true, children: [_jsxs(Container, Object.assign({ size: "onboarding", bg: "neutral.white" }, onboardingCardProps(), { children: [_jsx(AuthHeader, {}), _jsxs(Stack, { my: "6", children: [_jsx(Text, { variant: "title", textAlign: "center", px: "10", children: title }), _jsx(Text, { fontFamily: "secondary", textAlign: "center", px: ['10', '20'],
9
9
  // Centred text wraps into even lines (no widows).
10
- sx: { textWrap: 'balance' }, children: description })] }), showAction && (_jsx(Box, { px: ['container.sm', 'container.md', 'container.lg'], pb: "container.md", mb: "6", children: _jsx(Button, { as: "a", href: actionHref, w: "full", children: actionLabel }) }))] }), _jsx(Footer, {})] }));
10
+ sx: { textWrap: 'balance' }, children: description })] }), showAction && (_jsx(Box, { px: ONBOARDING_PAGE_PX, pb: "container.md", mb: "6", children: _jsx(Button, { as: "a", href: actionHref, w: "full", children: actionLabel }) }))] })), _jsx(Footer, {})] }));
11
11
  };
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { Box, Button, Text, Container, Stack, chakra } from '@chakra-ui/react';
4
- import { Logo, Footer, ButtonLoader, PasswordInput, BasePageWrapper, } from '../../../components';
4
+ import { Logo, Footer, ButtonLoader, PasswordInput, BasePageWrapper, ONBOARDING_PAGE_PX, onboardingCardProps, } from '../../../components';
5
5
  import { isValidPassword, passwordMatch } from '../../../utils';
6
6
  import { useNewPassword } from '../../../hooks';
7
7
  export const NewPassword = ({ isLoading, handleReset, userEmail, errorMessage, errorActionText, handleErrorAction, supportEmail, }) => {
8
8
  const { inputs, handleInputChange, handleSubmit, isValidated } = useNewPassword(handleReset);
9
- return (_jsxs(BasePageWrapper, { children: [_jsxs(Container, { size: "onboarding", boxShadow: "lg", children: [_jsx(Logo, {}), _jsx(Container, { variant: "ghost", mt: 4, mb: 6, children: _jsxs(Text, { variant: "title", textAlign: "center", px: [10, 0], noOfLines: [2, 1], children: [_jsx(chakra.span, { color: "gray.3", children: t('welcome.greeting2') }), _jsx(chakra.span, { color: "gray.3", children: userEmail }), _jsx(chakra.span, { color: "gray.3", children: "," })] }) }), _jsx(Box, { px: ['container.sm', 'container.md', 'container.lg'], pb: "container.lg", mb: 6, children: _jsxs(Stack, { spacing: 8, children: [_jsxs(Stack, { spacing: errorMessage ? 'base' : 8, children: [_jsx(Text, { textAlign: "center", variant: "info", children: t('newPassword.title') }), Boolean(errorMessage) && (
9
+ return (_jsxs(BasePageWrapper, { flushMobile: true, flushBelow: "sm", children: [_jsxs(Container, Object.assign({ size: "onboarding" }, onboardingCardProps({ below: 'sm' }), { children: [_jsx(Logo, {}), _jsx(Container, { variant: "ghost", mt: 4, mb: 6, children: _jsxs(Text, { variant: "title", textAlign: "center", px: [10, 0], noOfLines: [2, 1], children: [_jsx(chakra.span, { color: "gray.3", children: t('welcome.greeting2') }), _jsx(chakra.span, { color: "gray.3", children: userEmail }), _jsx(chakra.span, { color: "gray.3", children: "," })] }) }), _jsx(Box, { px: ONBOARDING_PAGE_PX, pb: "container.lg", mb: 6, children: _jsxs(Stack, { spacing: 8, children: [_jsxs(Stack, { spacing: errorMessage ? 'base' : 8, children: [_jsx(Text, { textAlign: "center", variant: "info", children: t('newPassword.title') }), Boolean(errorMessage) && (
10
10
  // Faint magenta box behind the whole message (Matt, 2026-10-06).
11
11
  _jsxs(Stack, { spacing: 2, align: "center", bg: "status.errorBg", borderRadius: "sm", px: 4, py: 3, children: [_jsx(Text, { variant: "error", textAlign: "center", children: errorMessage }), Boolean(errorActionText) && handleErrorAction && (_jsx(Button, { variant: "text", fontSize: "xs", lineHeight: "13px", h: "auto", onClick: handleErrorAction, children: errorActionText })), Boolean(supportEmail) && (_jsxs(Text, { textAlign: "center", variant: "hint", children: [t('newPassword.support'), ' ', _jsx("a", { href: `mailto:${supportEmail}`, children: supportEmail })] }))] })), _jsxs(Stack, { spacing: 3, children: [_jsx(PasswordInput, { errorMessage: !isValidPassword(inputs.password)
12
12
  ? t('forms.errorPasswordLength')
@@ -16,5 +16,5 @@ export const NewPassword = ({ isLoading, handleReset, userEmail, errorMessage, e
16
16
  ? t('forms.errorPasswordLength')
17
17
  : t('forms.errorPasswordMatch'), hasError: isValidated &&
18
18
  (!isValidPassword(inputs.confirmPassword) ||
19
- !passwordMatch(inputs.password, inputs.confirmPassword)), id: "confirmPassword", placeholder: t('newPassword.confirm'), value: inputs.confirmPassword || '', handleChange: handleInputChange })] })] }), _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: t('reset.resetBt') })] }) })] }), _jsx(Footer, {})] }));
19
+ !passwordMatch(inputs.password, inputs.confirmPassword)), id: "confirmPassword", placeholder: t('newPassword.confirm'), value: inputs.confirmPassword || '', handleChange: handleInputChange })] })] }), _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: t('reset.resetBt') })] }) })] })), _jsx(Footer, {})] }));
20
20
  };
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { chakra, Container, Text, Image, Center, Button, } from '@chakra-ui/react';
4
- import { BasePageWrapper, ButtonLoader, Logo } from '../../../components';
4
+ import { BasePageWrapper, ButtonLoader, Logo, ONBOARDING_PHONE_PX, onboardingCardProps, } from '../../../components';
5
5
  import { ResendPassword } from '../../../assets/images';
6
6
  export const ResendResetPassword = ({ email, isLoading = false, handleResendBt, handleBack }) => {
7
- return (_jsx(BasePageWrapper, { children: _jsxs(Container, { size: "validation", boxShadow: "lg", children: [_jsxs(Container, { variant: "secondary", children: [_jsx(Logo, {}), _jsxs(Text, { variant: "title", textAlign: "center", px: ['container.sm', 'container.xl'], pb: 6, minH: "6rem", children: [_jsx(chakra.span, { color: "gray.3", children: t('validation.title1') }), _jsx(chakra.span, { color: "gray.3", children: email }), _jsx(Text, { variant: "title", children: t('validation.title3') })] }), _jsx(Center, { children: _jsx(Image, { src: ResendPassword, alt: "Activate account", h: ['100px', '145px'], w: "auto" }) })] }), _jsx(Text, { variant: "info", px: ['container.md', 'container.lg'], py: "2rem", textAlign: "center", children: t('validation.alert1') }), _jsx(Center, { children: _jsx(Button, { mb: handleBack ? 5 : 10, mx: 4, variant: "secondary", onClick: handleResendBt, isLoading: isLoading, spinner: _jsx(ButtonLoader, { isOutlined: true }), size: "onboarding", children: t('validation.resendResetBt') }) }), handleBack && (_jsx(Center, { children: _jsx(Button, { mb: 10, mx: 4, variant: "primary", onClick: handleBack, isLoading: isLoading, spinner: _jsx(ButtonLoader, { isOutlined: true }), size: "onboarding", children: t('validation.backToLogin') }) }))] }) }));
7
+ return (_jsx(BasePageWrapper, { flushMobile: true, flushBelow: "sm", children: _jsxs(Container, Object.assign({ size: "validation" }, onboardingCardProps({ below: 'sm', maxW: 'container.lg' }), { children: [_jsxs(Container, { variant: "secondary", children: [_jsx(Logo, {}), _jsxs(Text, { variant: "title", textAlign: "center", px: [ONBOARDING_PHONE_PX, 'container.xl'], pb: 6, minH: "6rem", children: [_jsx(chakra.span, { color: "gray.3", children: t('validation.title1') }), _jsx(chakra.span, { color: "gray.3", children: email }), _jsx(Text, { variant: "title", children: t('validation.title3') })] }), _jsx(Center, { children: _jsx(Image, { src: ResendPassword, alt: "Activate account", h: ['100px', '145px'], w: "auto" }) })] }), _jsx(Text, { variant: "info", px: ['container.md', 'container.lg'], py: "2rem", textAlign: "center", children: t('validation.alert1') }), _jsx(Center, { children: _jsx(Button, { mb: handleBack ? 5 : 10, mx: [ONBOARDING_PHONE_PX, 4], variant: "secondary", onClick: handleResendBt, isLoading: isLoading, spinner: _jsx(ButtonLoader, { isOutlined: true }), size: "onboarding", children: t('validation.resendResetBt') }) }), handleBack && (_jsx(Center, { children: _jsx(Button, { mb: 10, mx: [ONBOARDING_PHONE_PX, 4], variant: "primary", onClick: handleBack, isLoading: isLoading, spinner: _jsx(ButtonLoader, { isOutlined: true }), size: "onboarding", children: t('validation.backToLogin') }) }))] })) }));
8
8
  };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { Box, Button, Text, Container, Stack } from '@chakra-ui/react';
4
- import { Logo, Footer, PageTitle, CardFooter, TextInput, ButtonLoader, BasePageWrapper, } from '../../../components';
4
+ import { Logo, Footer, PageTitle, CardFooter, TextInput, ButtonLoader, BasePageWrapper, ONBOARDING_PAGE_PX, onboardingCardProps, } from '../../../components';
5
5
  import { isEmptyField, isValidEmail } from '../../../utils';
6
6
  import { useResetPassword } from '../../../hooks';
7
7
  export const ResetPassword = ({ isLoading, handleReset, handleSignIn, resetError, }) => {
@@ -9,10 +9,10 @@ export const ResetPassword = ({ isLoading, handleReset, handleSignIn, resetError
9
9
  const resetErrorType = resetError
10
10
  ? t('forms.errorEmailNotActivated')
11
11
  : t('forms.errorEmail');
12
- return (_jsxs(BasePageWrapper, { children: [_jsxs(Container, { size: "onboarding", boxShadow: "lg", children: [_jsx(Logo, {}), _jsx(PageTitle, { title: t('reset.title') }), _jsx(Box, { px: ['container.sm', 'container.md', 'container.lg'], mb: 6, children: _jsxs(Stack, { spacing: 8, children: [_jsx(Text, { textAlign: "center", variant: "info", children: t('reset.instruction') }), _jsx(Stack, { spacing: 3, children: _jsx(TextInput, { autoCapitalize: "none", autoCorrect: "off", errorMessage: isEmptyField(inputs.email)
12
+ return (_jsxs(BasePageWrapper, { flushMobile: true, flushBelow: "sm", children: [_jsxs(Container, Object.assign({ size: "onboarding" }, onboardingCardProps({ below: 'sm' }), { children: [_jsx(Logo, {}), _jsx(PageTitle, { title: t('reset.title') }), _jsx(Box, { px: ONBOARDING_PAGE_PX, mb: 6, children: _jsxs(Stack, { spacing: 8, children: [_jsx(Text, { textAlign: "center", variant: "info", children: t('reset.instruction') }), _jsx(Stack, { spacing: 3, children: _jsx(TextInput, { autoCapitalize: "none", autoCorrect: "off", errorMessage: isEmptyField(inputs.email)
13
13
  ? t('forms.email') + ' ' + t('forms.required')
14
14
  : resetErrorType, hasError: isValidated &&
15
15
  (resetError ||
16
16
  isEmptyField(inputs.email) ||
17
- !isValidEmail(inputs.email)), id: "email", placeholder: t('reset.email'), value: inputs.email, handleChange: handleInputChange }) }), _jsx(Stack, { spacing: 4, children: _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: t('reset.resetBt') }) })] }) }), _jsx(CardFooter, { buttonLabel: t('reset.signinBt'), handleButtonClick: handleSignIn })] }), _jsx(Footer, {})] }));
17
+ !isValidEmail(inputs.email)), id: "email", placeholder: t('reset.email'), value: inputs.email, handleChange: handleInputChange }) }), _jsx(Stack, { spacing: 4, children: _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: t('reset.resetBt') }) })] }) }), _jsx(CardFooter, { buttonLabel: t('reset.signinBt'), handleButtonClick: handleSignIn })] })), _jsx(Footer, {})] }));
18
18
  };
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  import { t } from 'i18next';
12
12
  import { Box, Button, Center, Container, Divider, Flex, Stack, Text, } from '@chakra-ui/react';
13
- import { Footer, PageTitle, CardFooter, PasswordInput, TextInput, ButtonLoader, BasePageWrapper, AuthHeader, GoogleIcon, AppleIcon, } from '../../../components';
13
+ import { Footer, PageTitle, CardFooter, PasswordInput, TextInput, ButtonLoader, BasePageWrapper, ONBOARDING_PAGE_PX, onboardingCardProps, AuthHeader, GoogleIcon, AppleIcon, } from '../../../components';
14
14
  import { isEmptyField } from '../../../utils';
15
15
  import { useSignIn } from '../../../hooks';
16
16
  export const SignIn = ({ isPartner, isLoading, handleForgotPassword, handleSignIn, handleSignUp, handleGoogleSignIn, handleAppleSignIn, loginErrorMessage, heading, description, values = { email: '', password: '' }, }) => {
@@ -19,7 +19,7 @@ export const SignIn = ({ isPartner, isLoading, handleForgotPassword, handleSignI
19
19
  const showGoogle = Boolean(handleGoogleSignIn);
20
20
  const showApple = Boolean(handleAppleSignIn);
21
21
  const showSocial = showGoogle || showApple;
22
- return (_jsxs(BasePageWrapper, { flushMobile: true, children: [_jsxs(Container, { size: "onboarding", bg: "neutral.white", boxShadow: { base: 'none', md: 'lg' }, borderRadius: { base: 0, md: 'sm' }, maxW: { base: '100%', md: 'container.md' }, flex: { base: 1, md: 'initial' }, display: { base: 'flex', md: 'block' }, flexDirection: "column", children: [_jsx(AuthHeader, { isPartner: isPartner }), _jsx(PageTitle, { title: heading !== null && heading !== void 0 ? heading : (showSocial ? t('signin.titleSocial') : t('signin.title')), description: description }), _jsx(Box, { px: ['container.sm', 'container.md', 'container.lg'], mb: 6, children: _jsxs(Stack, { spacing: "base", children: [showSocial && (_jsxs(Stack, { spacing: "base", children: [showGoogle && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(GoogleIcon, { size: 20 }), onClick: handleGoogleSignIn, children: t('signup.continueGoogle') })), showApple && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(AppleIcon, { size: 20 }), onClick: handleAppleSignIn, children: t('signup.continueApple') })), _jsxs(Flex, { align: "center", gap: "3", py: "0", children: [_jsx(Divider, { flex: "1", borderColor: "border.default" }), _jsx(Text, { variant: "caption", children: t('signup.or') }), _jsx(Divider, { flex: "1", borderColor: "border.default" })] })] })), _jsxs(Stack, { spacing: "base", as: "form", children: [Boolean(loginErrorMessage) && (_jsx(Text, { variant: "error", children: loginErrorMessage })), _jsx(TextInput, { showLabel: false, autoCapitalize: "none", autoCorrect: "off", autoComplete: "username", errorMessage: t('forms.email') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(inputs.email), id: "email", placeholder: t('forms.email'), value: values.email || inputs.email, handleChange: (event) => {
22
+ return (_jsxs(BasePageWrapper, { flushMobile: true, children: [_jsxs(Container, Object.assign({ size: "onboarding", bg: "neutral.white" }, onboardingCardProps(), { children: [_jsx(AuthHeader, { isPartner: isPartner }), _jsx(PageTitle, { title: heading !== null && heading !== void 0 ? heading : (showSocial ? t('signin.titleSocial') : t('signin.title')), description: description }), _jsx(Box, { px: ONBOARDING_PAGE_PX, mb: 6, children: _jsxs(Stack, { spacing: "base", children: [showSocial && (_jsxs(Stack, { spacing: "base", children: [showGoogle && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(GoogleIcon, { size: 20 }), onClick: handleGoogleSignIn, children: t('signup.continueGoogle') })), showApple && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(AppleIcon, { size: 20 }), onClick: handleAppleSignIn, children: t('signup.continueApple') })), _jsxs(Flex, { align: "center", gap: "3", py: "0", children: [_jsx(Divider, { flex: "1", borderColor: "border.default" }), _jsx(Text, { variant: "caption", children: t('signup.or') }), _jsx(Divider, { flex: "1", borderColor: "border.default" })] })] })), _jsxs(Stack, { spacing: "base", as: "form", children: [Boolean(loginErrorMessage) && (_jsx(Text, { variant: "error", children: loginErrorMessage })), _jsx(TextInput, { showLabel: false, autoCapitalize: "none", autoCorrect: "off", autoComplete: "username", errorMessage: t('forms.email') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(inputs.email), id: "email", placeholder: t('forms.email'), value: values.email || inputs.email, handleChange: (event) => {
23
23
  values.email = event.target.value;
24
24
  handleInputChange(event);
25
25
  } }), _jsx(PasswordInput, { showLabel: false, autoComplete: "current-password", errorMessage: t('forms.password') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(inputs.password), id: "password", placeholder: t('forms.password'), value: values.password || inputs.password, handleChange: (event) => {
@@ -31,5 +31,5 @@ export const SignIn = ({ isPartner, isLoading, handleForgotPassword, handleSignI
31
31
  !isEmptyField(inputs.password)) {
32
32
  handleSignIn(inputs);
33
33
  }
34
- }), children: t('signin.signinBt') }), _jsx(Center, { children: _jsx(Button, { onClick: handleForgotPassword, variant: "text", children: t('signin.forgotBt') }) })] })] }) }), handleSignUp && (_jsx(CardFooter, { title: isPartner ? t('signin.signupPartner') : t('signin.signup'), buttonLabel: t('signin.signupBt'), handleButtonClick: handleSignUp }))] }), _jsx(Footer, {})] }));
34
+ }), children: t('signin.signinBt') }), _jsx(Center, { children: _jsx(Button, { onClick: handleForgotPassword, variant: "text", children: t('signin.forgotBt') }) })] })] }) }), handleSignUp && (_jsx(CardFooter, { title: isPartner ? t('signin.signupPartner') : t('signin.signup'), buttonLabel: t('signin.signupBt'), handleButtonClick: handleSignUp }))] })), _jsx(Footer, {})] }));
35
35
  };
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useState } from 'react';
3
3
  import { t } from 'i18next';
4
4
  import { Box, Button, Center, Container, Divider, Flex, Stack, Text, } from '@chakra-ui/react';
5
- import { Footer, CardFooter, PageTitle, PasswordInput, PasswordStrengthMeter, TextInput, ButtonLoader, BasePageWrapper, AuthHeader, GoogleIcon, AppleIcon, } from '../../../components';
5
+ import { Footer, CardFooter, PageTitle, PasswordInput, PasswordStrengthMeter, TextInput, ButtonLoader, BasePageWrapper, ONBOARDING_PAGE_PX, onboardingCardProps, AuthHeader, GoogleIcon, AppleIcon, } from '../../../components';
6
6
  import { isEmptyField, isValidEmail, isValidPassword } from '../../../utils';
7
7
  import { useSignUp } from '../../../hooks';
8
8
  export const SignUp = ({ isLoading, isPartner, handleCreateAccount, handleSignIn, handleGoogleSignIn, handleAppleSignIn, signupErrorMessage, values = {
@@ -25,6 +25,6 @@ export const SignUp = ({ isLoading, isPartner, handleCreateAccount, handleSignIn
25
25
  const showGoogle = Boolean(handleGoogleSignIn);
26
26
  const showApple = Boolean(handleAppleSignIn);
27
27
  const showSocial = showGoogle || showApple;
28
- return (_jsxs(BasePageWrapper, { flushMobile: true, children: [_jsxs(Container, { size: "onboarding", bg: "neutral.white", boxShadow: { base: 'none', md: 'lg' }, borderRadius: { base: 0, md: 'sm' }, maxW: { base: '100%', md: 'container.md' }, flex: { base: 1, md: 'initial' }, display: { base: 'flex', md: 'block' }, flexDirection: "column", children: [_jsx(AuthHeader, { isPartner: isPartner }), _jsx(PageTitle, { title: isPartner ? t('signup.titlePartner') : t('signup.title') }), _jsx(Box, { px: ['container.sm', 'container.md', 'container.lg'], mb: 6, children: _jsxs(Stack, { spacing: "base", as: "form", children: [Boolean(signupErrorMessage) && (_jsx(Text, { variant: "error", children: signupErrorMessage })), _jsx(TextInput, { showLabel: false, errorMessage: t('forms.fullName') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(inputs.name), id: "name", placeholder: t('forms.fullName'), value: (_a = inputs.name) !== null && _a !== void 0 ? _a : '', handleChange: handleInputChange, autoComplete: "name" }), _jsx(TextInput, { showLabel: false, autoCapitalize: "none", autoCorrect: "off", errorMessage: t('forms.email') + ' ' + t('forms.required'), hasError: isValidated &&
29
- (isEmptyField(inputs.email) || !isValidEmail(inputs.email)), id: "email", placeholder: t('forms.email'), value: inputs.email, handleChange: handleInputChange, autoComplete: "email" }), _jsxs(Box, { children: [_jsx(PasswordInput, { showLabel: false, errorMessage: passwordErrorMessage(values.password), hasError: isValidated && !isValidPassword(inputs.password), id: "password", placeholder: t('forms.password'), value: (_b = inputs.password) !== null && _b !== void 0 ? _b : '', handleChange: (event) => handleInputChange(event), autoComplete: "new-password" }), _jsx(PasswordStrengthMeter, { password: (_c = inputs.password) !== null && _c !== void 0 ? _c : '' })] }), _jsx(Center, { children: _jsx(Button, { variant: "text", leftIcon: _jsx(Text, { as: "span", fontSize: "md", lineHeight: "1", children: "+" }), onClick: () => setShowPartnerCode((prev) => !prev), children: t('signup.partnerCodePrompt') }) }), showPartnerCode && (_jsx(TextInput, { showLabel: false, autoCapitalize: "none", autoCorrect: "off", id: "partnerCode", placeholder: t('forms.promoCode'), value: (_d = inputs.partnerCode) !== null && _d !== void 0 ? _d : '', handleChange: handleInputChange, autoComplete: "off" })), _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: t('signup.signupBt') }), showSocial && (_jsxs(_Fragment, { children: [_jsxs(Flex, { align: "center", gap: "3", py: "1", children: [_jsx(Divider, { flex: "1", borderColor: "border.default" }), _jsx(Text, { variant: "caption", children: t('signup.or') }), _jsx(Divider, { flex: "1", borderColor: "border.default" })] }), showGoogle && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(GoogleIcon, { size: 20 }), onClick: handleGoogleSignIn, children: t('signup.continueGoogle') })), showApple && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(AppleIcon, { size: 20 }), onClick: handleAppleSignIn, children: t('signup.continueApple') }))] }))] }) }), _jsx(CardFooter, { title: isPartner ? t('signup.signinPartner') : t('signup.signin'), buttonLabel: t('signup.signinBt'), handleButtonClick: handleSignIn, children: _jsxs(Text, { textAlign: "center", variant: "info", w: "100%", children: [t('signup.terms'), ' ', _jsxs(Text, { as: "span", whiteSpace: "nowrap", children: ["Homefile", ' ', _jsx("a", { target: "_blank", href: t('footer.termsUrl'), children: t('footer.termsLink') }), "."] })] }) })] }), _jsx(Footer, {})] }));
28
+ return (_jsxs(BasePageWrapper, { flushMobile: true, children: [_jsxs(Container, Object.assign({ size: "onboarding", bg: "neutral.white" }, onboardingCardProps(), { children: [_jsx(AuthHeader, { isPartner: isPartner }), _jsx(PageTitle, { title: isPartner ? t('signup.titlePartner') : t('signup.title') }), _jsx(Box, { px: ONBOARDING_PAGE_PX, mb: 6, children: _jsxs(Stack, { spacing: "base", as: "form", children: [Boolean(signupErrorMessage) && (_jsx(Text, { variant: "error", children: signupErrorMessage })), _jsx(TextInput, { showLabel: false, errorMessage: t('forms.fullName') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(inputs.name), id: "name", placeholder: t('forms.fullName'), value: (_a = inputs.name) !== null && _a !== void 0 ? _a : '', handleChange: handleInputChange, autoComplete: "name" }), _jsx(TextInput, { showLabel: false, autoCapitalize: "none", autoCorrect: "off", errorMessage: t('forms.email') + ' ' + t('forms.required'), hasError: isValidated &&
29
+ (isEmptyField(inputs.email) || !isValidEmail(inputs.email)), id: "email", placeholder: t('forms.email'), value: inputs.email, handleChange: handleInputChange, autoComplete: "email" }), _jsxs(Box, { children: [_jsx(PasswordInput, { showLabel: false, errorMessage: passwordErrorMessage(values.password), hasError: isValidated && !isValidPassword(inputs.password), id: "password", placeholder: t('forms.password'), value: (_b = inputs.password) !== null && _b !== void 0 ? _b : '', handleChange: (event) => handleInputChange(event), autoComplete: "new-password" }), _jsx(PasswordStrengthMeter, { password: (_c = inputs.password) !== null && _c !== void 0 ? _c : '' })] }), _jsx(Center, { children: _jsx(Button, { variant: "text", leftIcon: _jsx(Text, { as: "span", fontSize: "md", lineHeight: "1", children: "+" }), onClick: () => setShowPartnerCode((prev) => !prev), children: t('signup.partnerCodePrompt') }) }), showPartnerCode && (_jsx(TextInput, { showLabel: false, autoCapitalize: "none", autoCorrect: "off", id: "partnerCode", placeholder: t('forms.promoCode'), value: (_d = inputs.partnerCode) !== null && _d !== void 0 ? _d : '', handleChange: handleInputChange, autoComplete: "off" })), _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: t('signup.signupBt') }), showSocial && (_jsxs(_Fragment, { children: [_jsxs(Flex, { align: "center", gap: "3", py: "1", children: [_jsx(Divider, { flex: "1", borderColor: "border.default" }), _jsx(Text, { variant: "caption", children: t('signup.or') }), _jsx(Divider, { flex: "1", borderColor: "border.default" })] }), showGoogle && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(GoogleIcon, { size: 20 }), onClick: handleGoogleSignIn, children: t('signup.continueGoogle') })), showApple && (_jsx(Button, { variant: "secondary", leftIcon: _jsx(AppleIcon, { size: 20 }), onClick: handleAppleSignIn, children: t('signup.continueApple') }))] }))] }) }), _jsx(CardFooter, { title: isPartner ? t('signup.signinPartner') : t('signup.signin'), buttonLabel: t('signup.signinBt'), handleButtonClick: handleSignIn, children: _jsxs(Text, { textAlign: "center", variant: "info", w: "100%", children: [t('signup.terms'), ' ', _jsxs(Text, { as: "span", whiteSpace: "nowrap", children: ["Homefile", ' ', _jsx("a", { target: "_blank", href: t('footer.termsUrl'), children: t('footer.termsLink') }), "."] })] }) })] })), _jsx(Footer, {})] }));
30
30
  };
@@ -1,2 +1,2 @@
1
1
  import { TwoFactorI } from '../../../interfaces';
2
- export declare const TwoFactor: ({ onReset, onResend, isDialog, isLoading, isPartner, twoFactorMethod, heading, description, warning, submitLabel, errorMessage, }: TwoFactorI) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const TwoFactor: ({ onReset, onResend, isDialog, isLoading, isPartner, twoFactorMethod, heading, description, note, submitLabel, errorMessage, resendNote, }: TwoFactorI) => import("react/jsx-runtime").JSX.Element;
@@ -1,12 +1,21 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { Box, Button, Text, Container, Stack, Center } from '@chakra-ui/react';
4
- import { Footer, ButtonLoader, TextInput, BasePageWrapper, AuthHeader, } from '../../../components';
4
+ import { Footer, ButtonLoader, TextInput, BasePageWrapper, ONBOARDING_PAGE_PX, onboardingCardProps, AuthHeader, } from '../../../components';
5
5
  import { isEmptyField } from '../../../utils';
6
6
  import { useTwoFactor } from '../../../hooks';
7
- export const TwoFactor = ({ onReset, onResend, isDialog, isLoading, isPartner, twoFactorMethod, heading, description, warning, submitLabel, errorMessage, }) => {
7
+ // In a dialog (Account 2FA) the code step is a plain card at every width.
8
+ const DIALOG_CARD = {
9
+ boxShadow: 'none',
10
+ borderRadius: 'sm',
11
+ maxW: 'container.md',
12
+ flex: 'initial',
13
+ display: 'block',
14
+ flexDirection: 'column',
15
+ };
16
+ export const TwoFactor = ({ onReset, onResend, isDialog, isLoading, isPartner, twoFactorMethod, heading, description, note, submitLabel, errorMessage, resendNote, }) => {
8
17
  const { code, handleInputChange, handleSubmit, isValidated } = useTwoFactor(onReset);
9
- return (_jsxs(BasePageWrapper, { flushMobile: !isDialog, children: [_jsxs(Container, { size: "onboarding", bg: "neutral.white", boxShadow: isDialog ? 'none' : { base: 'none', md: 'lg' }, borderRadius: isDialog ? 'sm' : { base: 0, md: 'sm' }, maxW: isDialog ? 'container.md' : { base: '100%', md: 'container.md' }, flex: isDialog ? 'initial' : { base: 1, md: 'initial' }, display: isDialog ? 'block' : { base: 'flex', md: 'block' }, flexDirection: "column", children: [_jsx(AuthHeader, { isPartner: isPartner }), _jsxs(Stack, { my: "6", children: [_jsx(Text, { variant: "title", textAlign: "center", px: "10", children: heading !== null && heading !== void 0 ? heading : t('reset.2FA.title') }), _jsx(Text, { fontFamily: "secondary", textAlign: "center", px: ['10', '20'],
18
+ return (_jsxs(BasePageWrapper, { flushMobile: !isDialog, children: [_jsxs(Container, Object.assign({ size: "onboarding", bg: "neutral.white" }, (isDialog ? DIALOG_CARD : onboardingCardProps()), { children: [_jsx(AuthHeader, { isPartner: isPartner }), _jsxs(Stack, { my: "6", children: [_jsx(Text, { variant: "title", textAlign: "center", px: "10", children: heading !== null && heading !== void 0 ? heading : t('reset.2FA.title') }), _jsx(Text, { fontFamily: "secondary", textAlign: "center", px: ['10', '20'],
10
19
  // Centred text wraps into even lines (no widows).
11
- sx: { textWrap: 'balance' }, children: description !== null && description !== void 0 ? description : (_jsxs(_Fragment, { children: [twoFactorMethod === 'email' && t('reset.2FA.subtitleEmail'), twoFactorMethod === 'sms' && t('reset.2FA.subtitleSms')] })) }), warning && (_jsx(Text, { fontFamily: "secondary", fontWeight: "semibold", textAlign: "center", px: ['10', '20'], pt: "4", sx: { textWrap: 'balance' }, children: warning }))] }), _jsx(Box, { px: ['container.sm', 'container.md', 'container.lg'], pb: "container.md", mb: "6", children: _jsxs(Stack, { spacing: "4", children: [Boolean(errorMessage) && _jsx(Text, { variant: "error", children: errorMessage }), _jsx(TextInput, { errorMessage: t('forms.code') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(code), id: "code", placeholder: t('reset.2FA.placeholder'), value: code, handleChange: handleInputChange }), _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: submitLabel !== null && submitLabel !== void 0 ? submitLabel : t('forms.submit') }), onResend && (_jsx(Center, { children: _jsx(Button, { onClick: onResend, variant: "text", children: t('reset.2FA.resend') }) }))] }) })] }), !isDialog && _jsx(Footer, {})] }));
20
+ sx: { textWrap: 'balance' }, children: description !== null && description !== void 0 ? description : (_jsxs(_Fragment, { children: [twoFactorMethod === 'email' && t('reset.2FA.subtitleEmail'), twoFactorMethod === 'sms' && t('reset.2FA.subtitleSms')] })) }), note && (_jsx(Text, { fontFamily: "secondary", textAlign: "center", px: ['10', '20'], pt: "4", sx: { textWrap: 'balance' }, children: note }))] }), _jsx(Box, { px: ONBOARDING_PAGE_PX, pb: "container.md", mb: "6", children: _jsxs(Stack, { spacing: "4", children: [Boolean(errorMessage) && _jsx(Text, { variant: "error", children: errorMessage }), _jsx(TextInput, { errorMessage: t('forms.code') + ' ' + t('forms.required'), hasError: isValidated && isEmptyField(code), id: "code", placeholder: t('reset.2FA.placeholder'), value: code, handleChange: handleInputChange }), _jsx(Button, { isLoading: isLoading, spinner: _jsx(ButtonLoader, {}), onClick: handleSubmit, children: submitLabel !== null && submitLabel !== void 0 ? submitLabel : t('forms.submit') }), onResend && (_jsx(Center, { children: _jsx(Button, { onClick: onResend, variant: "text", children: t('reset.2FA.resend') }) })), resendNote && (_jsx(Text, { fontFamily: "secondary", textAlign: "center", sx: { textWrap: 'balance' }, children: resendNote }))] }) })] })), !isDialog && _jsx(Footer, {})] }));
12
21
  };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { t } from 'i18next';
3
3
  import { Box, Container, Text, Center, Button, Stack, AspectRatio, } from '@chakra-ui/react';
4
- import { Logo, WelcomeHeader } from '../../../components';
4
+ import { Logo, WelcomeHeader, ONBOARDING_PHONE_PX } from '../../../components';
5
5
  export const Welcome = ({ handleClick, name, videoUrl = '' }) => {
6
- return (_jsx(Box, { w: "container.full", children: _jsxs(Container, { size: "validation", children: [_jsx(Container, { variant: "secondary", children: _jsx(Logo, {}) }), _jsx(Text, { variant: "heading", textAlign: "center", mt: "3rem", children: t('welcome.title') }), _jsx(Box, { px: ['container.sm', 'container.lg'], children: _jsxs(Stack, { spacing: "8", children: [_jsx(WelcomeHeader, { description: t('welcome.message'), greeting: t('welcome.greeting'), name: name }), videoUrl !== '' && (_jsx(AspectRatio, { w: "full", children: _jsx("iframe", { title: "Welcome Homefile", src: videoUrl, allowFullScreen: true }) })), _jsx(Text, { variant: "info", children: t('welcome.message2') }), _jsx(Text, { variant: "info", children: t('welcome.signature') }), _jsx(Center, { children: _jsx(Button, { onClick: handleClick, size: "onboarding", mb: "4rem", children: t('welcome.welcomeBt') }) })] }) }), _jsx(Container, { variant: "tertiary", h: "container.xxs" })] }) }));
6
+ return (_jsx(Box, { w: "container.full", children: _jsxs(Container, { size: "validation", children: [_jsx(Container, { variant: "secondary", children: _jsx(Logo, {}) }), _jsx(Text, { variant: "heading", textAlign: "center", mt: "3rem", children: t('welcome.title') }), _jsx(Box, { px: [ONBOARDING_PHONE_PX, 'container.lg'], children: _jsxs(Stack, { spacing: "8", children: [_jsx(WelcomeHeader, { description: t('welcome.message'), greeting: t('welcome.greeting'), name: name }), videoUrl !== '' && (_jsx(AspectRatio, { w: "full", children: _jsx("iframe", { title: "Welcome Homefile", src: videoUrl, allowFullScreen: true }) })), _jsx(Text, { variant: "info", children: t('welcome.message2') }), _jsx(Text, { variant: "info", children: t('welcome.signature') }), _jsx(Center, { children: _jsx(Button, { onClick: handleClick, size: "onboarding", mb: "4rem", children: t('welcome.welcomeBt') }) })] }) }), _jsx(Container, { variant: "tertiary", h: "container.xxs" })] }) }));
7
7
  };
@@ -7,7 +7,8 @@ export interface TwoFactorI {
7
7
  twoFactorMethod: 'sms' | 'email' | '';
8
8
  heading?: string;
9
9
  description?: string;
10
- warning?: string;
10
+ note?: string;
11
11
  submitLabel?: string;
12
12
  errorMessage?: string;
13
+ resendNote?: string;
13
14
  }
@@ -1,4 +1,4 @@
1
- import { Meta } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react';
2
2
  import { CardFooterI } from '../../interfaces';
3
3
  declare const _default: Meta<CardFooterI>;
4
4
  export default _default;
@@ -9,3 +9,4 @@ export declare const CardFooterComponent: {
9
9
  buttonLabel: string;
10
10
  };
11
11
  };
12
+ export declare const CardFooterPhone: StoryObj<CardFooterI>;
@@ -1,5 +1,16 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
+ import { within } from '@storybook/test';
2
12
  import { CardFooter } from '../../components';
13
+ import { PHONE, expectCardFullWidth, expectSides, getCard } from './phoneLayout';
3
14
  export default {
4
15
  title: 'Components/Onboarding',
5
16
  component: CardFooter,
@@ -11,3 +22,16 @@ CardFooterComponent.args = {
11
22
  title: 'Card title',
12
23
  buttonLabel: 'Click here',
13
24
  };
25
+ // The Sign-up box on a phone: its text keeps 13px from the sides of the screen.
26
+ export const CardFooterPhone = {
27
+ parameters: PHONE,
28
+ args: {
29
+ title: 'Card title',
30
+ buttonLabel: 'Click here',
31
+ },
32
+ play: (_a) => __awaiter(void 0, [_a], void 0, function* ({ canvasElement }) {
33
+ const box = getCard(canvasElement);
34
+ yield expectCardFullWidth(box);
35
+ yield expectSides(box, { text: within(canvasElement).getByText('Card title') });
36
+ }),
37
+ };
@@ -1,4 +1,4 @@
1
- import { Meta } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react';
2
2
  import { ActivateAccountI } from '../../../interfaces';
3
3
  declare const _default: Meta<ActivateAccountI>;
4
4
  export default _default;
@@ -9,3 +9,5 @@ export declare const ActivateAccountPage: {
9
9
  isLoading: boolean;
10
10
  };
11
11
  };
12
+ export declare const ActivateAccountPhone: StoryObj<ActivateAccountI>;
13
+ export declare const ActivateAccountSmallTablet: StoryObj<ActivateAccountI>;
@@ -1,6 +1,17 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx } from "react/jsx-runtime";
2
11
  import { Box } from '@chakra-ui/react';
12
+ import { fn, within } from '@storybook/test';
3
13
  import { ActivateAccount } from '../../../components';
14
+ import { PHONE, SMALL_TABLET, expectCardAtTop, expectCardBelowTopGap, expectCardFullWidth, expectPageFillsScreen, expectSides, getCard, } from '../phoneLayout';
4
15
  export default {
5
16
  title: 'Pages/Onboarding',
6
17
  component: ActivateAccount,
@@ -12,3 +23,33 @@ ActivateAccountPage.args = {
12
23
  name: 'Matthew',
13
24
  isLoading: true,
14
25
  };
26
+ // Activate account on a phone: like sign in, the card starts at the top, spans
27
+ // the screen and runs down to the bottom of it; its text keeps 13px from the
28
+ // sides.
29
+ export const ActivateAccountPhone = {
30
+ parameters: PHONE,
31
+ args: {
32
+ name: 'Jordan',
33
+ isLoading: false,
34
+ handleActivateBt: fn(),
35
+ },
36
+ play: (_a) => __awaiter(void 0, [_a], void 0, function* ({ canvasElement }) {
37
+ const canvas = within(canvasElement);
38
+ const card = getCard(canvasElement);
39
+ yield expectCardAtTop(card);
40
+ yield expectCardFullWidth(card);
41
+ yield expectSides(card, {
42
+ instruction: canvas.getByText('To complete your Homefile registration process, please click on the button below to confirm and activate your account.'),
43
+ signature: canvas.getByText('Your Homefile Crew'),
44
+ });
45
+ yield expectPageFillsScreen(card);
46
+ }),
47
+ };
48
+ // Activate account on a small tablet (744px): the card keeps the top gap.
49
+ export const ActivateAccountSmallTablet = {
50
+ parameters: SMALL_TABLET,
51
+ args: ActivateAccountPhone.args,
52
+ play: (_a) => __awaiter(void 0, [_a], void 0, function* ({ canvasElement }) {
53
+ yield expectCardBelowTopGap(getCard(canvasElement));
54
+ }),
55
+ };
@@ -1,4 +1,4 @@
1
- import { Meta } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react';
2
2
  import { EmailValidationI } from '../../../interfaces';
3
3
  declare const _default: Meta<EmailValidationI>;
4
4
  export default _default;
@@ -9,3 +9,5 @@ export declare const EmailValidationPage: {
9
9
  isLoading: boolean;
10
10
  };
11
11
  };
12
+ export declare const EmailValidationPhone: StoryObj<EmailValidationI>;
13
+ export declare const EmailValidationSmallTablet: StoryObj<EmailValidationI>;
@@ -1,6 +1,17 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx } from "react/jsx-runtime";
2
11
  import { Box } from '@chakra-ui/react';
12
+ import { fn, within } from '@storybook/test';
3
13
  import { EmailValidation } from '../../../components';
14
+ import { PHONE, SMALL_TABLET, expectCardAtTop, expectCardBelowTopGap, expectCardFullWidth, expectContentSides, expectPageFillsScreen, expectSides, getCard, } from '../phoneLayout';
4
15
  export default {
5
16
  title: 'Pages/Onboarding',
6
17
  component: EmailValidation,
@@ -12,3 +23,35 @@ EmailValidationPage.args = {
12
23
  email: 'user@user.com.br',
13
24
  isLoading: true,
14
25
  };
26
+ // The check-your-email page on a phone: like sign in, the card starts at the
27
+ // top, spans the screen and runs down to the bottom of it; the title and the
28
+ // button keep 13px from its sides.
29
+ export const EmailValidationPhone = {
30
+ parameters: PHONE,
31
+ args: {
32
+ email: 'jordan@example.com',
33
+ isLoading: false,
34
+ handleResendBt: fn(),
35
+ },
36
+ play: (_a) => __awaiter(void 0, [_a], void 0, function* ({ canvasElement }) {
37
+ const canvas = within(canvasElement);
38
+ const card = getCard(canvasElement);
39
+ yield expectCardAtTop(card);
40
+ yield expectCardFullWidth(card);
41
+ yield expectContentSides(card, {
42
+ title: canvas.getByText('jordan@example.com').parentElement,
43
+ });
44
+ yield expectSides(card, {
45
+ 'Resend button': canvas.getByRole('button', { name: 'Resend Email Verification' }),
46
+ });
47
+ yield expectPageFillsScreen(card);
48
+ }),
49
+ };
50
+ // The check-your-email page on a small tablet (744px): the card keeps the top gap.
51
+ export const EmailValidationSmallTablet = {
52
+ parameters: SMALL_TABLET,
53
+ args: EmailValidationPhone.args,
54
+ play: (_a) => __awaiter(void 0, [_a], void 0, function* ({ canvasElement }) {
55
+ yield expectCardBelowTopGap(getCard(canvasElement));
56
+ }),
57
+ };
@@ -9,11 +9,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { expect, within } from '@storybook/test';
11
11
  import { MessagePage } from '../../../components';
12
+ import { PHONE, expectCardAtTop, expectCardFullWidth, expectSides, getCard, } from '../phoneLayout';
12
13
  export default {
13
14
  title: 'Pages/Onboarding/Message Page',
14
15
  component: MessagePage,
15
- // A whole page: render edge to edge, as on a phone.
16
- parameters: { layout: 'fullscreen' },
16
+ // A whole page on a phone: edge to edge, at 390x844.
17
+ parameters: PHONE,
17
18
  };
18
19
  const BACK_TO_TEXTS = { actionLabel: 'Back to my texts', actionHref: 'sms:' };
19
20
  // Every message page shows its whole title and line; the button only when it has
@@ -36,6 +37,13 @@ const play = (_a) => __awaiter(void 0, [_a], void 0, function* ({ canvasElement,
36
37
  yield expect(links).toHaveLength(0);
37
38
  yield expect(canvas.queryAllByRole('button')).toHaveLength(0);
38
39
  }
40
+ // On a phone: full screen, no bar on top, and the button 13px from the sides.
41
+ const card = getCard(canvasElement);
42
+ yield expectCardAtTop(card);
43
+ yield expectCardFullWidth(card);
44
+ if (links.length > 0) {
45
+ yield expectSides(card, { [`${args.actionLabel} button`]: links[0] });
46
+ }
39
47
  });
40
48
  export const Connected = {
41
49
  args: Object.assign({ title: '(512) 555-0147 is connected', description: 'Go back to your texts. Homi will know it’s you now.' }, BACK_TO_TEXTS),
@@ -1,4 +1,4 @@
1
- import { Meta } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react';
2
2
  import { NewPasswordI } from '../../../interfaces';
3
3
  declare const _default: Meta<NewPasswordI>;
4
4
  export default _default;
@@ -28,3 +28,5 @@ export declare const NewPasswordNoAnswer: {
28
28
  supportEmail: string;
29
29
  };
30
30
  };
31
+ export declare const NewPasswordPhone: StoryObj<NewPasswordI>;
32
+ export declare const NewPasswordSmallTablet: StoryObj<NewPasswordI>;