@homefile/components-v2 2.61.0 → 2.62.0

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.
@@ -689,7 +689,8 @@
689
689
  "newPassword": {
690
690
  "confirm": "Confirm Password",
691
691
  "create": "Create Password",
692
- "title": "Please enter your new password."
692
+ "title": "Please enter your new password.",
693
+ "support": "Still stuck? Email"
693
694
  },
694
695
  "notifications": {
695
696
  "noNotifications": "You currently have no notifications.",
@@ -4,5 +4,5 @@ import { chakra, Container, Text, Image, Center, Button, } from '@chakra-ui/reac
4
4
  import { Logo, ButtonLoader, BasePageWrapper } 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: "blue.2", 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, { 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') }) })] }) }));
8
8
  };
@@ -1,2 +1,2 @@
1
1
  import { NewPasswordI } from '../../../interfaces';
2
- export declare const NewPassword: ({ isLoading, handleReset, userEmail, }: NewPasswordI) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const NewPassword: ({ isLoading, handleReset, userEmail, errorMessage, errorActionText, handleErrorAction, supportEmail, }: NewPasswordI) => import("react/jsx-runtime").JSX.Element;
@@ -4,15 +4,17 @@ import { Box, Button, Text, Container, Stack, chakra } from '@chakra-ui/react';
4
4
  import { Logo, Footer, ButtonLoader, PasswordInput, BasePageWrapper, } from '../../../components';
5
5
  import { isValidPassword, passwordMatch } from '../../../utils';
6
6
  import { useNewPassword } from '../../../hooks';
7
- export const NewPassword = ({ isLoading, handleReset, userEmail, }) => {
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: "blue.2", 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: [_jsx(Text, { textAlign: "center", variant: "info", children: t('newPassword.title') }), _jsxs(Stack, { spacing: 3, children: [_jsx(PasswordInput, { errorMessage: !isValidPassword(inputs.password)
10
- ? t('forms.errorPasswordLength')
11
- : t('forms.errorPasswordMatch'), hasError: isValidated &&
12
- (!isValidPassword(inputs.password) ||
13
- !passwordMatch(inputs.password, inputs.confirmPassword)), id: "password", placeholder: t('newPassword.create'), value: inputs.password || '', handleChange: handleInputChange }), _jsx(PasswordInput, { errorMessage: !isValidPassword(inputs.confirmPassword)
14
- ? t('forms.errorPasswordLength')
15
- : t('forms.errorPasswordMatch'), hasError: isValidated &&
16
- (!isValidPassword(inputs.confirmPassword) ||
17
- !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, {})] }));
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) && (
10
+ // Faint magenta box behind the whole message (Matt, 2026-10-06).
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
+ ? t('forms.errorPasswordLength')
13
+ : t('forms.errorPasswordMatch'), hasError: isValidated &&
14
+ (!isValidPassword(inputs.password) ||
15
+ !passwordMatch(inputs.password, inputs.confirmPassword)), id: "password", placeholder: t('newPassword.create'), value: inputs.password || '', handleChange: handleInputChange }), _jsx(PasswordInput, { errorMessage: !isValidPassword(inputs.confirmPassword)
16
+ ? t('forms.errorPasswordLength')
17
+ : t('forms.errorPasswordMatch'), hasError: isValidated &&
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, {})] }));
18
20
  };
@@ -4,5 +4,5 @@ import { chakra, Container, Text, Image, Center, Button, } from '@chakra-ui/reac
4
4
  import { BasePageWrapper, ButtonLoader, Logo } 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: "blue.2", 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, { 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') }) }))] }) }));
8
8
  };
@@ -6,4 +6,11 @@ export interface NewPasswordI {
6
6
  isLoading: boolean;
7
7
  handleReset: (form: NewPasswordFormI) => void;
8
8
  userEmail: string;
9
+ /** Shown above the password fields, in the same error style as sign-in. */
10
+ errorMessage?: string;
11
+ /** Optional button under the error line (for example "Send a new link"). */
12
+ errorActionText?: string;
13
+ handleErrorAction?: () => void;
14
+ /** Optional support address under the error line, shown as an email link. */
15
+ supportEmail?: string;
9
16
  }
@@ -9,3 +9,22 @@ export declare const NewPasswordPage: {
9
9
  userEmail: string;
10
10
  };
11
11
  };
12
+ export declare const NewPasswordLinkExpired: {
13
+ (args: NewPasswordI): import("react/jsx-runtime").JSX.Element;
14
+ args: {
15
+ isLoading: boolean;
16
+ userEmail: string;
17
+ errorMessage: string;
18
+ errorActionText: string;
19
+ handleErrorAction: () => void;
20
+ };
21
+ };
22
+ export declare const NewPasswordNoAnswer: {
23
+ (args: NewPasswordI): import("react/jsx-runtime").JSX.Element;
24
+ args: {
25
+ isLoading: boolean;
26
+ userEmail: string;
27
+ errorMessage: string;
28
+ supportEmail: string;
29
+ };
30
+ };
@@ -11,3 +11,20 @@ NewPasswordPage.args = {
11
11
  isLoading: true,
12
12
  userEmail: 'user@user.com',
13
13
  };
14
+ // The reset link was refused (expired, already used, or too many tries).
15
+ export const NewPasswordLinkExpired = (args) => (_jsx(CloudsAnimation, { children: _jsx(NewPassword, Object.assign({}, args)) }));
16
+ NewPasswordLinkExpired.args = {
17
+ isLoading: false,
18
+ userEmail: 'user@user.com',
19
+ errorMessage: 'This link has expired.',
20
+ errorActionText: 'Send a new link',
21
+ handleErrorAction: () => { },
22
+ };
23
+ // The request got no answer (offline, or the server didn't respond).
24
+ export const NewPasswordNoAnswer = (args) => (_jsx(CloudsAnimation, { children: _jsx(NewPassword, Object.assign({}, args)) }));
25
+ NewPasswordNoAnswer.args = {
26
+ isLoading: false,
27
+ userEmail: 'user@user.com',
28
+ errorMessage: "We couldn't reach Homefile. Check your connection, then press Reset Password.",
29
+ supportEmail: 'support@homefile.com',
30
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homefile/components-v2",
3
- "version": "2.61.0",
3
+ "version": "2.62.0",
4
4
  "author": "Homefile",
5
5
  "license": "UNLICENSED",
6
6
  "typings": "dist/index.d.ts",