@sonic-equipment/ui 184.0.0 → 185.0.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.
Files changed (93) hide show
  1. package/dist/cards/data-card/data-card.js +37 -20
  2. package/dist/cards/data-card/data-card.module.css.js +1 -1
  3. package/dist/country-selector/country-selector-dialog/country-selector-dialog.js +1 -5
  4. package/dist/exports.d.ts +20 -2
  5. package/dist/forms/form/form.d.ts +7 -3
  6. package/dist/forms/form/form.js +2 -2
  7. package/dist/forms/password-validation/password-validation.d.ts +4 -0
  8. package/dist/forms/password-validation/password-validation.js +32 -0
  9. package/dist/forms/select/select.d.ts +2 -1
  10. package/dist/forms/select/select.js +2 -2
  11. package/dist/index.js +21 -3
  12. package/dist/intl/translation-id.d.ts +1 -1
  13. package/dist/intl/use-formatted-message.js +2 -1
  14. package/dist/lists/menu-list/menu-list.d.ts +2 -1
  15. package/dist/lists/menu-list/menu-list.js +2 -2
  16. package/dist/lists/widget-grid/widget-grid.d.ts +5 -0
  17. package/dist/lists/widget-grid/widget-grid.js +9 -0
  18. package/dist/lists/widget-grid/widget-grid.module.css.js +3 -0
  19. package/dist/lists/widget-grid/widget.d.ts +6 -0
  20. package/dist/lists/widget-grid/widget.js +10 -0
  21. package/dist/modals/dialog/dialog.d.ts +5 -5
  22. package/dist/modals/dialog/dialog.js +18 -18
  23. package/dist/modals/dialog/dialog.module.css.js +1 -1
  24. package/dist/modals/recover-password/recover-password-dialog.js +1 -3
  25. package/dist/pages/account/components/create-account-form/create-account-form.js +2 -17
  26. package/dist/pages/account/create-account-page/create-account-page.js +4 -5
  27. package/dist/pages/account/layouts/sign-in-page-layout/sign-in-page-layout.js +1 -1
  28. package/dist/pages/account/sign-in-page/sign-in-page.js +2 -3
  29. package/dist/pages/checkout/shipping-page/hooks/use-patch-shipping-details.d.ts +1 -0
  30. package/dist/pages/components/page-container/page-container.js +1 -1
  31. package/dist/pages/my-sonic/actions/change-customer/change-customer-dialog.d.ts +4 -3
  32. package/dist/pages/my-sonic/actions/change-customer/change-customer-dialog.js +10 -4
  33. package/dist/pages/my-sonic/actions/change-customer/change-customer.d.ts +5 -2
  34. package/dist/pages/my-sonic/actions/change-customer/change-customer.js +16 -7
  35. package/dist/pages/my-sonic/actions/change-customer/change-customer.module.css.js +1 -1
  36. package/dist/pages/my-sonic/actions/change-customer/connected-change-customer-dialog.d.ts +7 -2
  37. package/dist/pages/my-sonic/actions/change-customer/connected-change-customer-dialog.js +9 -6
  38. package/dist/pages/my-sonic/actions/change-password/change-password-dialog.d.ts +10 -0
  39. package/dist/pages/my-sonic/actions/change-password/change-password-dialog.js +24 -0
  40. package/dist/pages/my-sonic/actions/change-password/change-password.d.ts +7 -0
  41. package/dist/pages/my-sonic/actions/change-password/change-password.js +35 -0
  42. package/dist/pages/my-sonic/actions/change-password/change-password.module.css.js +3 -0
  43. package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.d.ts +5 -0
  44. package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.js +39 -0
  45. package/dist/pages/my-sonic/actions/edit-user-info/connected-edit-user-info-dialog.d.ts +5 -0
  46. package/dist/pages/my-sonic/actions/edit-user-info/connected-edit-user-info-dialog.js +56 -0
  47. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info-dialog.d.ts +10 -0
  48. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info-dialog.js +15 -0
  49. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info.d.ts +11 -0
  50. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info.js +29 -0
  51. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info.module.css.js +3 -0
  52. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-aside.d.ts +4 -0
  53. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-aside.js +9 -0
  54. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-main.d.ts +4 -0
  55. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-main.js +9 -0
  56. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-page.d.ts +5 -0
  57. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-page.js +10 -0
  58. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-pre-aside.d.ts +4 -0
  59. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-pre-aside.js +9 -0
  60. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-title.d.ts +4 -0
  61. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-title.js +10 -0
  62. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout.d.ts +5 -0
  63. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout.js +10 -0
  64. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout.module.css.js +3 -0
  65. package/dist/pages/my-sonic/navigation/connected-my-sonic-navigation.js +3 -4
  66. package/dist/pages/my-sonic/navigation/connected-my-sonic-navigation.module.css.js +3 -0
  67. package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.d.ts +2 -1
  68. package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.js +2 -2
  69. package/dist/pages/my-sonic/navigation/my-sonic-mobile-navigation.d.ts +2 -1
  70. package/dist/pages/my-sonic/navigation/my-sonic-mobile-navigation.js +2 -2
  71. package/dist/pages/my-sonic/widgets/connected-customer-information-widget.js +3 -3
  72. package/dist/pages/my-sonic/widgets/connected-user-account-widget.js +16 -5
  73. package/dist/shared/api/shared/hooks/use-awaitable-mutation.d.ts +1 -0
  74. package/dist/shared/api/shared/hooks/use-awaitable-mutation.js +6 -0
  75. package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-account.d.ts +1 -1
  76. package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-account.js +3 -1
  77. package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-guest-account.js +3 -1
  78. package/dist/shared/api/storefront/hooks/account/use-fetch-current-account.d.ts +3 -0
  79. package/dist/shared/api/storefront/hooks/account/use-fetch-current-account.js +13 -0
  80. package/dist/shared/api/storefront/hooks/account/use-patch-current-account.d.ts +11 -0
  81. package/dist/shared/api/storefront/hooks/account/use-patch-current-account.js +20 -0
  82. package/dist/shared/api/storefront/hooks/authentication/use-patch-session.d.ts +1 -0
  83. package/dist/shared/api/storefront/hooks/authentication/use-patch-session.js +1 -1
  84. package/dist/shared/api/storefront/hooks/cart/use-patch-cart.d.ts +1 -0
  85. package/dist/shared/api/storefront/hooks/cart/use-place-order.d.ts +1 -0
  86. package/dist/shared/api/storefront/hooks/customer/use-patch-bill-to-address.d.ts +1 -0
  87. package/dist/shared/api/storefront/services/account-service.d.ts +31 -0
  88. package/dist/shared/api/storefront/services/account-service.js +84 -0
  89. package/dist/shared/api/storefront/services/authentication-service.d.ts +7 -26
  90. package/dist/shared/api/storefront/services/authentication-service.js +38 -65
  91. package/dist/styles.css +351 -240
  92. package/package.json +1 -1
  93. /package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-guest-account.d.ts +0 -0
@@ -17,9 +17,7 @@ function RecoverPasswordDialog({ isOpen, onOpenChange, }) {
17
17
  reset();
18
18
  // eslint-disable-next-line react-hooks/exhaustive-deps
19
19
  }, [isOpen]);
20
- const onSubmit = (event) => {
21
- const form = event.currentTarget;
22
- const formData = new FormData(form);
20
+ const onSubmit = ({ formData }) => {
23
21
  const email = formData.get('email')?.toString();
24
22
  if (!email)
25
23
  throw new Error('Email value is required');
@@ -7,12 +7,11 @@ import { useCountries } from '../../../../country-select/hooks/use-countries.js'
7
7
  import { Form } from '../../../../forms/form/form.js';
8
8
  import { FormSegment } from '../../../../forms/form/form-segment.js';
9
9
  import { FormSegmentGroup } from '../../../../forms/form/form-segment-group.js';
10
- import { PasswordField } from '../../../../forms/password-field/password-field.js';
10
+ import { PasswordValidation } from '../../../../forms/password-validation/password-validation.js';
11
11
  import { SwitchField } from '../../../../forms/switch-field/switch-field.js';
12
12
  import { TextField } from '../../../../forms/text-field/text-field.js';
13
13
  import { isCountryCode } from '../../../../intl/types.js';
14
14
  import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
15
- import { validatePassword } from '../../../../shared/model/account.js';
16
15
  import { validateEmail } from '../../../../shared/model/address.js';
17
16
  import { Heading } from '../../../../typography/heading/heading.js';
18
17
  import styles from './create-account-form.module.css.js';
@@ -22,8 +21,6 @@ function CreateAccountForm({ errorType, isDisabled: _isDisabled = false, isPendi
22
21
  const title = t('create account');
23
22
  const isDisabled = isPendingCreateAccount || _isDisabled;
24
23
  const [isPrivateAccount, setIsPrivateAccount] = useState(false);
25
- const [password, setPassword] = useState('');
26
- const [passwordConfirm, setPasswordConfirm] = useState('');
27
24
  const [lastName, setLastName] = useState('');
28
25
  const [companyName, setCompanyName] = useState('');
29
26
  const errorMessages = {
@@ -64,13 +61,6 @@ function CreateAccountForm({ errorType, isDisabled: _isDisabled = false, isPendi
64
61
  },
65
62
  });
66
63
  };
67
- const isMismatchingPasswords = () => {
68
- if (!passwordConfirm)
69
- return;
70
- if (passwordConfirm === password)
71
- return false;
72
- return true;
73
- };
74
64
  // form header
75
65
  const header = (jsx(Heading, { "data-test-selector": "PageTitle", italic: true, size: "m", tag: "h1", uppercase: true, children: title }));
76
66
  // form footer
@@ -79,12 +69,7 @@ function CreateAccountForm({ errorType, isDisabled: _isDisabled = false, isPendi
79
69
  if (!value)
80
70
  return value;
81
71
  return (validateEmail(value) || t('Please enter a valid email address'));
82
- } }) }), jsx(FormSegment, { children: jsx(PasswordField, { autoComplete: "new-password", "data-test-selector": "createAccount_password", info: "Password must be at least 8 characters long, include at least one number, at least one lowercase character, at least one uppercase character and at least one non-alphanumeric character.", isDisabled: isDisabled, isRequired: true, label: t('Password'), name: "password", onChange: setPassword, validate: value => {
83
- if (!value)
84
- return;
85
- return (validatePassword(value) ||
86
- t('Password does not meet requirements'));
87
- } }) }), jsx(FormSegment, { children: jsx(PasswordField, { autoComplete: "new-password", customErrorMessage: "Passwords do not match", "data-test-selector": "createAccount_passwordConfirm", isDisabled: isDisabled, isInvalid: isMismatchingPasswords(), isRequired: true, label: t('Confirm password'), onChange: setPasswordConfirm, value: passwordConfirm }) })] }), jsxs(FormSegmentGroup, { children: [jsx(FormSegment, { children: jsx(SwitchField, { isDisabled: isDisabled, isSelected: isPrivateAccount, name: "isPrivateAccount", onChange: setIsPrivateAccount, children: t('Private account') }) }), jsx(FormSegment, { children: jsx(TextField, { autoComplete: "organization", "data-test-selector": "createAccount_companyName", isDisabled: isDisabled, isRequired: !isPrivateAccount, label: t('Company name'), name: "companyName", onChange: setCompanyName, value: companyName }, `companyName-${Boolean(isPrivateAccount)}`) }), jsx(FormSegment, { children: jsx(TextField, { autoComplete: "given-name", "data-test-selector": "createAccount_firstName", isDisabled: isDisabled, label: t('First name'), name: "firstName" }) }), jsx(FormSegment, { children: jsx(TextField, { autoComplete: "family-name", "data-test-selector": "createAccount_lastName", isDisabled: isDisabled, isRequired: isPrivateAccount, label: t('Last name'), name: "lastName", onChange: setLastName, value: lastName }, `lastname-${Boolean(isPrivateAccount)}`) }), jsx(FormSegment, { children: jsx(CountrySelect, { isRequired: true, countries: countries || [], "data-test-selector": "createAccount_countrySelect", defaultSelectedCountry: defaultSelectedCountry, isDisabled: isLoadingCountries || isDisabled, isLoading: isLoadingCountries, name: "countrySelect" }, defaultSelectedCountry?.id) })] }), jsx(FormSegmentGroup, { children: jsx(FormSegment, { children: jsx(SwitchField, { isDisabled: isDisabled, name: "isSubscribed", children: t('Sign me up for newsletters and product updates') }) }) })] }));
72
+ } }) }), jsx(PasswordValidation, { isDisabled: isDisabled })] }), jsxs(FormSegmentGroup, { children: [jsx(FormSegment, { children: jsx(SwitchField, { isDisabled: isDisabled, isSelected: isPrivateAccount, name: "isPrivateAccount", onChange: setIsPrivateAccount, children: t('Private account') }) }), jsx(FormSegment, { children: jsx(TextField, { autoComplete: "organization", "data-test-selector": "createAccount_companyName", isDisabled: isDisabled, isRequired: !isPrivateAccount, label: t('Company name'), name: "companyName", onChange: setCompanyName, value: companyName }, `companyName-${Boolean(isPrivateAccount)}`) }), jsx(FormSegment, { children: jsx(TextField, { autoComplete: "given-name", "data-test-selector": "createAccount_firstName", isDisabled: isDisabled, label: t('First name'), name: "firstName" }) }), jsx(FormSegment, { children: jsx(TextField, { autoComplete: "family-name", "data-test-selector": "createAccount_lastName", isDisabled: isDisabled, isRequired: isPrivateAccount, label: t('Last name'), name: "lastName", onChange: setLastName, value: lastName }, `lastname-${Boolean(isPrivateAccount)}`) }), jsx(FormSegment, { children: jsx(CountrySelect, { isRequired: true, countries: countries || [], "data-test-selector": "createAccount_countrySelect", defaultSelectedCountry: defaultSelectedCountry, isDisabled: isLoadingCountries || isDisabled, isLoading: isLoadingCountries, name: "countrySelect" }, defaultSelectedCountry?.id) })] }), jsx(FormSegmentGroup, { children: jsx(FormSegment, { children: jsx(SwitchField, { isDisabled: isDisabled, name: "isSubscribed", children: t('Sign me up for newsletters and product updates') }) }) })] }));
88
73
  }
89
74
 
90
75
  export { CreateAccountForm };
@@ -1,14 +1,13 @@
1
1
  "use client";
2
- import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { useMemo } from 'react';
4
4
  import { Button } from '../../../buttons/button/button.js';
5
5
  import { FormattedMessage } from '../../../intl/formatted-message.js';
6
6
  import { Dialog } from '../../../modals/dialog/dialog.js';
7
- import { useCreateAccount } from '../../../shared/api/storefront/hooks/authentication/use-create-account.js';
7
+ import { useCreateAccount } from '../../../shared/api/storefront/hooks/account/use-create-account.js';
8
8
  import { useFetchSession } from '../../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
9
- import { ExistingAccountError } from '../../../shared/api/storefront/services/authentication-service.js';
9
+ import { ExistingAccountError } from '../../../shared/api/storefront/services/account-service.js';
10
10
  import { useNavigate } from '../../../shared/routing/use-navigate.js';
11
- import { Page } from '../../components/page/page.js';
12
11
  import { LoadingPage } from '../../loading-page/loading-page.js';
13
12
  import { PATHS } from '../../paths.js';
14
13
  import { CreateAccountForm } from '../components/create-account-form/create-account-form.js';
@@ -40,7 +39,7 @@ function CreateAccountPage({ returnUrl } = {}) {
40
39
  navigate(continuePath, { reload: true });
41
40
  return;
42
41
  }
43
- return (jsxs(Page, { fluid: true, fullHeight: true, "data-test-selector": "createAccountPage", children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(CreateAccountForm, { errorType: errorType, isDisabled: isDisabled, isPendingCreateAccount: isPendingCreateAccount, onSubmit: onSubmit }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: continuePath, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isSuccess && !isReturnToShipping, title: "Account created", children: jsx("p", { children: jsx(FormattedMessage, { id: "Your new Sonic Equipment account was succesfully created. You should receive an email soon with further instructions on how to activate this account. If you do not receive this email, please contact Customer Support." }) }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: `${PATHS.SIGN_IN}${returnUrl ? `?returnUrl=${continuePath}` : ''}`, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue to sign in" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isExistingAccount, title: "Existing account", children: jsx("p", { children: jsx(FormattedMessage, { id: "The email address you entered is already associated with an existing account. Please sign in to this account or contact Customer Support." }) }) })] }));
42
+ return (jsxs(Fragment, { children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(CreateAccountForm, { errorType: errorType, isDisabled: isDisabled, isPendingCreateAccount: isPendingCreateAccount, onSubmit: onSubmit }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: continuePath, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isSuccess && !isReturnToShipping, title: "Account created", children: jsx("p", { children: jsx(FormattedMessage, { id: "Your new Sonic Equipment account was succesfully created. You should receive an email soon with further instructions on how to activate this account. If you do not receive this email, please contact Customer Support." }) }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: `${PATHS.SIGN_IN}${returnUrl ? `?returnUrl=${continuePath}` : ''}`, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue to sign in" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isExistingAccount, title: "Existing account", children: jsx("p", { children: jsx(FormattedMessage, { id: "The email address you entered is already associated with an existing account. Please sign in to this account or contact Customer Support." }) }) })] }));
44
43
  }
45
44
 
46
45
  export { CreateAccountPage };
@@ -8,7 +8,7 @@ import styles from './sign-in-page-layout.module.css.js';
8
8
 
9
9
  function SignInPageLayout({ children, fullHeight, image = SIGN_IN_PAGE_BACKGROUND_IMAGE, }) {
10
10
  const isLg = useIsBreakpoint('lg');
11
- return (jsxs("div", { className: clsx(styles['sign-in-page-layout'], fullHeight && styles['full-height']), children: [jsx("div", { className: styles.main, children: children }), isLg && (jsx("div", { className: styles.side, children: jsx("div", { className: styles.image, children: jsx(Image, { image: image, title: "" }) }) }))] }));
11
+ return (jsxs("div", { className: clsx(styles['sign-in-page-layout'], fullHeight && styles['full-height']), children: [jsx("section", { className: styles.main, children: children }), isLg && (jsx("div", { className: styles.side, children: jsx("div", { className: styles.image, children: jsx(Image, { image: image, title: "" }) }) }))] }));
12
12
  }
13
13
 
14
14
  export { SignInPageLayout };
@@ -2,13 +2,12 @@
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
3
  import { useState, useMemo } from 'react';
4
4
  import { RecoverPasswordDialog } from '../../../modals/recover-password/recover-password-dialog.js';
5
- import { useCreateGuestAccount } from '../../../shared/api/storefront/hooks/authentication/use-create-guest-account.js';
5
+ import { useCreateGuestAccount } from '../../../shared/api/storefront/hooks/account/use-create-guest-account.js';
6
6
  import { useFetchSession } from '../../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
7
7
  import { useSignIn } from '../../../shared/api/storefront/hooks/authentication/use-sign-in.js';
8
8
  import { isRequestError } from '../../../shared/fetch/request.js';
9
9
  import { useDisclosure } from '../../../shared/hooks/use-disclosure.js';
10
10
  import { useNavigate } from '../../../shared/routing/use-navigate.js';
11
- import { Page } from '../../components/page/page.js';
12
11
  import { PATHS } from '../../paths.js';
13
12
  import { SignInForm } from '../components/sign-in-form/sign-in-form.js';
14
13
  import { SignInPageLayout } from '../layouts/sign-in-page-layout/sign-in-page-layout.js';
@@ -57,7 +56,7 @@ function SignInPage({ returnUrl } = {}) {
57
56
  const onRecoverPasswordDialogOpen = () => {
58
57
  setRecoverPasswordDialogOpen(true);
59
58
  };
60
- return (jsxs(Fragment, { children: [jsx(Page, { fullHeight: true, "data-test-selector": "signInPage", fluid: true, children: jsx(SignInPageLayout, { fullHeight: true, children: jsx(SignInForm, { allowGuestSignIn: allowGuestSignIn, createAccountPath: createAccountPath, errorType: errorType, initialEmail: session?.isGuest ? '' : session?.email, initialRememberMe: session?.rememberMe, isDisabled: !session || isSuccess, isPendingGuestSignIn: isPendingCreateGuest, isPendingUserSignIn: isPendingSignIn, onRecoverPasswordDialogOpen: onRecoverPasswordDialogOpen, onSubmit: onSubmit }) }) }), jsx(RecoverPasswordDialog, { isOpen: isRecoverPasswordDialogOpen, onOpenChange: isOpen => setRecoverPasswordDialogOpen(isOpen) })] }));
59
+ return (jsxs(Fragment, { children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(SignInForm, { allowGuestSignIn: allowGuestSignIn, createAccountPath: createAccountPath, errorType: errorType, initialEmail: session?.isGuest ? '' : session?.email, initialRememberMe: session?.rememberMe, isDisabled: !session || isSuccess, isPendingGuestSignIn: isPendingCreateGuest, isPendingUserSignIn: isPendingSignIn, onRecoverPasswordDialogOpen: onRecoverPasswordDialogOpen, onSubmit: onSubmit }) }), jsx(RecoverPasswordDialog, { isOpen: isRecoverPasswordDialogOpen, onOpenChange: isOpen => setRecoverPasswordDialogOpen(isOpen) })] }));
61
60
  }
62
61
 
63
62
  export { SignInPage };
@@ -13,4 +13,5 @@ export declare function usePatchShippingDetails(): {
13
13
  patchedCart: CartModel | undefined;
14
14
  patchedSession: SessionModel | undefined;
15
15
  }>;
16
+ reset: () => void;
16
17
  };
@@ -4,7 +4,7 @@ import resetStyles from '../../../shared/reset.module.css.js';
4
4
  import styles from './page-container.module.css.js';
5
5
 
6
6
  function PageContainer({ breadcrumbSlot, children, className, 'data-test-selector': dataTestSelector, fluid, fullHeight, titleSlot, }) {
7
- return (jsx("div", { className: clsx(styles['page-container'], resetStyles.reset, fullHeight && styles['full-height'], fluid && styles['fluid'], className), "data-test-selector": dataTestSelector, children: jsxs("main", { className: styles['page-main'], children: [breadcrumbSlot && (jsx("div", { className: styles.breadcrumb, children: breadcrumbSlot })), titleSlot && jsx("div", { className: styles.title, children: titleSlot }), jsx("div", { className: styles.content, children: children })] }) }));
7
+ return (jsx("div", { className: clsx(styles['page-container'], resetStyles.reset, fullHeight && styles['full-height'], fluid && styles['fluid'], className), "data-test-selector": dataTestSelector, children: jsxs("div", { className: styles['page-main'], children: [breadcrumbSlot && (jsx("div", { className: styles.breadcrumb, children: breadcrumbSlot })), titleSlot && jsx("div", { className: styles.title, children: titleSlot }), jsx("div", { className: styles.content, children: children })] }) }));
8
8
  }
9
9
 
10
10
  export { PageContainer };
@@ -1,7 +1,8 @@
1
1
  import { BillToCollectionModel } from '../../../../shared/api/storefront/model/storefront.model';
2
2
  export interface ChangeCustomerDialogProps {
3
- currentlySelectedCustomerId?: string;
3
+ allowSetDefault?: boolean;
4
4
  data?: BillToCollectionModel;
5
+ defaultCustomerId?: string;
5
6
  error?: Error | null | unknown;
6
7
  filter?: string;
7
8
  hasErrorSubmitting?: boolean;
@@ -9,7 +10,7 @@ export interface ChangeCustomerDialogProps {
9
10
  isOpen: boolean;
10
11
  isUpdating?: boolean;
11
12
  onClose: () => void;
12
- onCustomerSelected: (id: string) => void;
13
+ onCustomerSelected: (id: string, setAsDefault: boolean) => void;
13
14
  onFilterChanged?: (filter: string) => void;
14
15
  }
15
- export declare function ChangeCustomerDialog({ currentlySelectedCustomerId, data, error, filter, hasErrorSubmitting, isLoading, isOpen, isUpdating, onClose, onCustomerSelected, onFilterChanged, }: ChangeCustomerDialogProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare function ChangeCustomerDialog({ allowSetDefault, data, defaultCustomerId, error, filter, hasErrorSubmitting, isLoading, isOpen, isUpdating, onClose, onCustomerSelected, onFilterChanged, }: ChangeCustomerDialogProps): import("react/jsx-runtime").JSX.Element | null;
@@ -8,17 +8,23 @@ import { Dialog } from '../../../../modals/dialog/dialog.js';
8
8
  import { ChangeCustomer } from './change-customer.js';
9
9
  import styles from './change-customer-dialog.module.css.js';
10
10
 
11
- function ChangeCustomerDialog({ currentlySelectedCustomerId, data, error, filter, hasErrorSubmitting, isLoading, isOpen, isUpdating = false, onClose, onCustomerSelected, onFilterChanged, }) {
11
+ function ChangeCustomerDialog({ allowSetDefault = false, data, defaultCustomerId, error, filter, hasErrorSubmitting, isLoading, isOpen, isUpdating = false, onClose, onCustomerSelected, onFilterChanged, }) {
12
12
  const t = useFormattedMessage();
13
13
  const [hasCustomerSelected, setHasCustomerSelected] = useState(false);
14
14
  const [selectedCustomerId, setSelectedCustomerId] = useState();
15
- return (jsx(Dialog, { allowSubmit: !hasErrorSubmitting && hasCustomerSelected, className: styles['change-customer-dialog'], isOpen: isOpen, isSubmitting: isUpdating || hasErrorSubmitting, onOpenChange: isOpen => !isOpen && onClose(), onSubmit: () => selectedCustomerId && onCustomerSelected(selectedCustomerId), title: t('Change customer'), children: hasErrorSubmitting ? (jsx(Message, { className: styles.error, type: "danger", children: jsx(FormattedMessage, { id: "An error occurred while changing the customer." }) })) : (jsx(ChangeCustomer, { className: styles.content, data: data, error: error, filter: filter, isLoading: isLoading, onCustomerSelected: id => {
15
+ const [setAsDefault, setSetAsDefault] = useState(false);
16
+ if (!isOpen && setAsDefault)
17
+ setSetAsDefault(false);
18
+ if (!isOpen)
19
+ return null;
20
+ return (jsx(Dialog, { allowSubmit: !hasErrorSubmitting && hasCustomerSelected, className: styles['change-customer-dialog'], isOpen: isOpen, isSubmitting: isUpdating || hasErrorSubmitting, onOpenChange: isOpen => !isOpen && onClose(), onSubmit: () => selectedCustomerId &&
21
+ onCustomerSelected(selectedCustomerId, setAsDefault), title: t('Change customer'), children: hasErrorSubmitting ? (jsx(Message, { className: styles.error, type: "danger", children: jsx(FormattedMessage, { id: "An error occurred while changing the customer." }) })) : (jsx(ChangeCustomer, { allowSetDefault: allowSetDefault, className: styles.content, data: data, defaultCustomerId: defaultCustomerId, error: error, filter: filter, isLoading: isLoading, onCustomerSelected: id => {
16
22
  setSelectedCustomerId(id);
17
- onCustomerSelected(id);
23
+ onCustomerSelected(id, setAsDefault);
18
24
  }, onCustomerSelectionChanged: id => {
19
25
  setSelectedCustomerId(id);
20
26
  setHasCustomerSelected(true);
21
- }, onFilterChanged: onFilterChanged, selectedId: currentlySelectedCustomerId })) }));
27
+ }, onFilterChanged: onFilterChanged, onSetAsDefaultChange: setSetAsDefault, setAsDefault: setAsDefault })) }));
22
28
  }
23
29
 
24
30
  export { ChangeCustomerDialog };
@@ -1,13 +1,16 @@
1
1
  import { BillToCollectionModel } from '../../../../shared/api/storefront/model/storefront.model';
2
2
  export interface ChangeCustomerProps {
3
+ allowSetDefault?: boolean;
3
4
  className?: string;
4
5
  data?: BillToCollectionModel;
6
+ defaultCustomerId?: string;
5
7
  error?: Error | null | unknown;
6
8
  filter?: string;
7
9
  isLoading?: boolean;
8
10
  onCustomerSelected?: (id: string) => void;
9
11
  onCustomerSelectionChanged?: (id: string) => void;
10
12
  onFilterChanged?: (filter: string) => void;
11
- selectedId?: string;
13
+ onSetAsDefaultChange?: (setAsDefault: boolean) => void;
14
+ setAsDefault?: boolean;
12
15
  }
13
- export declare function ChangeCustomer({ className, data, error, filter, isLoading, onCustomerSelected, onCustomerSelectionChanged, onFilterChanged, selectedId, }: ChangeCustomerProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare function ChangeCustomer({ allowSetDefault, className, data, defaultCustomerId, error, filter, isLoading, onCustomerSelected, onCustomerSelectionChanged: _onCustomerSelectionChanged, onFilterChanged, onSetAsDefaultChange, setAsDefault, }: ChangeCustomerProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { useRef, useMemo } from 'react';
3
+ import { useRef, useState, useCallback, useMemo } from 'react';
4
4
  import { ListBox, ListBoxItem, Text } from 'react-aria-components';
5
5
  import clsx from 'clsx';
6
+ import { Checkbox } from '../../../../forms/checkbox/checkbox.js';
6
7
  import { SearchField } from '../../../../forms/search-field/search-field.js';
7
8
  import { SolidRatingIcon } from '../../../../icons/solid/solid-rating-icon.js';
8
9
  import { FormattedMessage } from '../../../../intl/formatted-message.js';
@@ -13,13 +14,18 @@ import { HighlightText } from '../../../../text/highlight-text/highlight-text.js
13
14
  import styles from './change-customer.module.css.js';
14
15
 
15
16
  const DEFAULT_PAGE_SIZE = 20;
16
- function ChangeCustomer({ className, data, error, filter = '', isLoading = false, onCustomerSelected, onCustomerSelectionChanged, onFilterChanged, selectedId, }) {
17
+ function ChangeCustomer({ allowSetDefault = false, className, data, defaultCustomerId, error, filter = '', isLoading = false, onCustomerSelected, onCustomerSelectionChanged: _onCustomerSelectionChanged, onFilterChanged, onSetAsDefaultChange, setAsDefault = false, }) {
17
18
  const t = useFormattedMessage();
18
19
  const listBoxRef = useRef(null);
19
20
  const hasMoreResults = !isLoading &&
20
21
  data?.pagination &&
21
22
  data.pagination.totalItemCount > DEFAULT_PAGE_SIZE;
22
- const listBoxItems = useMemo(() => {
23
+ const [hasSelectedIdChanged, setHasSelectedIdChanged] = useState(false);
24
+ const onCustomerSelectionChanged = useCallback((key) => {
25
+ setHasSelectedIdChanged(true);
26
+ return _onCustomerSelectionChanged?.(String(key));
27
+ }, [_onCustomerSelectionChanged]);
28
+ const [listBoxItems, rerenderKey] = useMemo(() => {
23
29
  const listBoxItems = [...(data?.billTos || [])];
24
30
  if (error instanceof UnauthorizedRequestError) {
25
31
  listBoxItems.push({
@@ -42,13 +48,16 @@ function ChangeCustomer({ className, data, error, filter = '', isLoading = false
42
48
  type: 'warning',
43
49
  });
44
50
  }
45
- return listBoxItems;
46
- }, [data?.billTos, error, hasMoreResults, t]);
51
+ return [
52
+ listBoxItems,
53
+ Math.random().toString(36).slice(2, 15) + defaultCustomerId,
54
+ ];
55
+ }, [data?.billTos, error, hasMoreResults, t, defaultCustomerId]);
47
56
  return (jsxs("div", { className: clsx(styles['change-customer-container'], className), children: [jsx(SearchField, { autoFocus: true, isDebounced: true, "aria-controls": "filtered-customer-results-list", isLoading: isLoading, label: t('Search for a customer'), onChange: onFilterChanged, onKeyUp: ({ key }) => {
48
57
  if (key === 'ArrowDown') {
49
58
  listBoxRef.current?.focus();
50
59
  }
51
- }, placeholder: t('Search for a customer'), showLabel: false, size: "md", value: filter, variant: "outline" }), jsx(ListBox, { ref: listBoxRef, "aria-label": "List of customers", "aria-live": "polite", className: styles['list-box'], id: "filtered-customer-results-list", items: listBoxItems, onAction: key => onCustomerSelected?.(String(key)), onSelectionChange: keys => onCustomerSelectionChanged?.(String([...keys][0])), renderEmptyState: () => !isLoading && (jsx(Message, { type: "info", children: jsx(FormattedMessage, { id: "No results found. Please refine your search." }) })), selectionBehavior: "replace", selectionMode: "single", children: listBoxItem => 'type' in listBoxItem ? (jsx(ListBoxItem, { isDisabled: true, children: jsx(Message, { type: listBoxItem.type, children: listBoxItem.message }) }, "marker")) : (jsxs(ListBoxItem, { className: styles['list-box-item'], id: listBoxItem.id, children: [jsxs(Text, { slot: "label", children: [jsxs("div", { className: styles['company-name'], children: [jsx(HighlightText, { className: styles['company-name-text'], highlightText: filter, text: `${listBoxItem.companyName}` }), selectedId === listBoxItem.id && (jsx(SolidRatingIcon, { className: styles['selected-icon'] }))] }), jsx(HighlightText, { className: styles['customer-number'], highlightText: filter, text: `${listBoxItem.customerNumber}` })] }), jsxs(Text, { slot: "description", children: [jsx("div", { children: jsx(HighlightText, { highlightText: filter, text: [
60
+ }, placeholder: t('Search for a customer'), showLabel: false, size: "md", value: filter, variant: "outline" }), jsx(ListBox, { ref: listBoxRef, "aria-label": "List of customers", "aria-live": "polite", className: styles['list-box'], id: "filtered-customer-results-list", items: listBoxItems, onAction: key => onCustomerSelected?.(String(key)), onSelectionChange: keys => onCustomerSelectionChanged(String([...keys][0])), renderEmptyState: () => !isLoading && (jsx(Message, { type: "info", children: jsx(FormattedMessage, { id: "No results found. Please refine your search." }) })), selectionBehavior: "replace", selectionMode: "single", children: listBoxItem => 'type' in listBoxItem ? (jsx(ListBoxItem, { isDisabled: true, textValue: listBoxItem.id, children: jsx(Message, { type: listBoxItem.type, children: jsx(Text, { slot: "description", children: listBoxItem.message }) }) }, "marker")) : (jsxs(ListBoxItem, { className: styles['list-box-item'], id: listBoxItem.id, textValue: listBoxItem.id, children: [jsxs(Text, { slot: "label", children: [jsxs("div", { className: styles['company-name'], children: [jsx(HighlightText, { className: styles['company-name-text'], highlightText: filter, text: `${listBoxItem.companyName}` }), defaultCustomerId === listBoxItem.id && (jsx(SolidRatingIcon, { className: styles['selected-icon'] }))] }), jsx(HighlightText, { className: styles['customer-number'], highlightText: filter, text: `${listBoxItem.customerNumber}` })] }), jsxs(Text, { slot: "description", children: [jsx("div", { children: jsx(HighlightText, { highlightText: filter, text: [
52
61
  [listBoxItem.firstName, listBoxItem.lastName].join(' '),
53
62
  ]
54
63
  .filter(Boolean)
@@ -61,7 +70,7 @@ function ChangeCustomer({ className, data, error, filter = '', isLoading = false
61
70
  .filter(Boolean)
62
71
  .join(', ') }) }), jsx(HighlightText, { highlightText: filter, text: [listBoxItem.postalCode, listBoxItem.country?.name]
63
72
  .filter(Boolean)
64
- .join(', ') })] })] }, listBoxItem.id)) })] }));
73
+ .join(', ') })] })] }, `${listBoxItem.id}-${defaultCustomerId}`)) }, rerenderKey), allowSetDefault && (jsx(Checkbox, { isDisabled: !hasSelectedIdChanged, isSelected: setAsDefault, onChange: onSetAsDefaultChange, value: String(setAsDefault), children: jsx(FormattedMessage, { id: "Make this the default customer" }) }))] }));
65
74
  }
66
75
 
67
76
  export { ChangeCustomer };
@@ -1,3 +1,3 @@
1
- var styles = {"change-customer-container":"change-customer-module-2kOw4","list-box":"change-customer-module-StfiY","list-box-item":"change-customer-module-P7ouY","company-name":"change-customer-module-DSVPN","company-name-text":"change-customer-module-4KQoq","customer-number":"change-customer-module-4p6ab"};
1
+ var styles = {"change-customer-container":"change-customer-module-2kOw4","list-box":"change-customer-module-StfiY","list-box-item":"change-customer-module-P7ouY","selected-icon":"change-customer-module-lxmBJ","company-name":"change-customer-module-DSVPN","company-name-text":"change-customer-module-4KQoq","customer-number":"change-customer-module-4p6ab"};
2
2
 
3
3
  export { styles as default };
@@ -1,2 +1,7 @@
1
- import { ChangeCustomerDialogProps } from './change-customer-dialog';
2
- export declare function ConnectedChangeCustomerDialog({ currentlySelectedCustomerId, isOpen, onClose, onCustomerSelected, }: ChangeCustomerDialogProps): import("react/jsx-runtime").JSX.Element;
1
+ export interface ConnectedChangeCustomerDialogProps {
2
+ allowSetDefault?: boolean;
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ onCustomerSelected: (id: string, setAsDefault: boolean) => void;
6
+ }
7
+ export declare function ConnectedChangeCustomerDialog({ allowSetDefault, isOpen, onClose, onCustomerSelected, }: ConnectedChangeCustomerDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -1,25 +1,28 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { useState } from 'react';
3
+ import { useState, useEffect } from 'react';
4
+ import { useFetchCurrentAccount } from '../../../../shared/api/storefront/hooks/account/use-fetch-current-account.js';
4
5
  import { usePatchSession } from '../../../../shared/api/storefront/hooks/authentication/use-patch-session.js';
5
6
  import { useFetchBillToAddresses } from '../../../../shared/api/storefront/hooks/customer/use-fetch-bill-to-addresses.js';
6
7
  import { ChangeCustomerDialog } from './change-customer-dialog.js';
7
8
 
8
- function ConnectedChangeCustomerDialog({ currentlySelectedCustomerId, isOpen, onClose, onCustomerSelected, }) {
9
+ function ConnectedChangeCustomerDialog({ allowSetDefault = false, isOpen, onClose, onCustomerSelected, }) {
9
10
  const [filter, setFilter] = useState('');
10
- const { error: errorMutation, isLoading: isMutating, mutate, } = usePatchSession();
11
+ const { data: account } = useFetchCurrentAccount();
12
+ const { error: errorMutation, isLoading: isMutating, mutate, reset, } = usePatchSession();
11
13
  const { data, error, isFetching, isLoading } = useFetchBillToAddresses({
12
14
  filter,
13
15
  isEnabled: isOpen,
14
16
  });
15
- return (jsx(ChangeCustomerDialog, { currentlySelectedCustomerId: currentlySelectedCustomerId, data: data, error: error, filter: filter, hasErrorSubmitting: Boolean(errorMutation), isLoading: isLoading || isFetching, isOpen: isOpen, isUpdating: isMutating, onClose: onClose, onCustomerSelected: async (id) => {
17
+ useEffect(() => reset(), [isOpen, reset]);
18
+ return (jsx(ChangeCustomerDialog, { allowSetDefault: allowSetDefault, data: data, defaultCustomerId: account?.defaultCustomerId || undefined, error: error, filter: filter, hasErrorSubmitting: Boolean(errorMutation), isLoading: isLoading || isFetching, isOpen: isOpen, isUpdating: isMutating, onClose: onClose, onCustomerSelected: async (id, setAsDefault) => {
16
19
  id = `${id}`;
17
20
  try {
18
21
  await mutate({
19
22
  session: {
20
23
  billTo: {
21
24
  id,
22
- isDefault: false,
25
+ isDefault: setAsDefault,
23
26
  },
24
27
  billToId: id,
25
28
  customerWasUpdated: false,
@@ -29,7 +32,7 @@ function ConnectedChangeCustomerDialog({ currentlySelectedCustomerId, isOpen, on
29
32
  shipToId: id,
30
33
  },
31
34
  });
32
- onCustomerSelected(id);
35
+ onCustomerSelected(id, setAsDefault);
33
36
  }
34
37
  catch {
35
38
  // Handle error if needed
@@ -0,0 +1,10 @@
1
+ export interface ChangePasswordDialogProps {
2
+ error?: Error | null | unknown;
3
+ isLoading?: boolean;
4
+ isOpen: boolean;
5
+ isUpdating?: boolean;
6
+ onClose: () => void;
7
+ onPasswordChanged: (currentPassword: string, newPassword: string) => void;
8
+ username: string | undefined;
9
+ }
10
+ export declare function ChangePasswordDialog({ error, isLoading, isOpen, isUpdating, onClose, onPasswordChanged, username, }: ChangePasswordDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { FormSegmentGroup } from '../../../../forms/form/form-segment-group.js';
3
+ import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
4
+ import { Dialog } from '../../../../modals/dialog/dialog.js';
5
+ import { UnauthorizedRequestError } from '../../../../shared/fetch/request.js';
6
+ import { ChangePassword } from './change-password.js';
7
+
8
+ function ChangePasswordDialog({ error, isLoading = false, isOpen, isUpdating = false, onClose, onPasswordChanged, username, }) {
9
+ const t = useFormattedMessage();
10
+ return (jsx(Dialog, { allowSubmit: Boolean(username) &&
11
+ !isLoading &&
12
+ !isUpdating &&
13
+ !(error instanceof UnauthorizedRequestError), isOpen: isOpen, onOpenChange: isOpen => !isOpen && onClose(), onSubmit: ({ formData }) => {
14
+ const currentPassword = formData.get('current-password')?.toString();
15
+ const newPassword = formData.get('new-password')?.toString();
16
+ if (!currentPassword)
17
+ throw new Error('current password is required');
18
+ if (!newPassword)
19
+ throw new Error('New password is required');
20
+ onPasswordChanged(currentPassword, newPassword);
21
+ }, title: t('Change password'), children: jsx(FormSegmentGroup, { children: jsx(ChangePassword, { error: error, isLoading: isLoading, isUpdating: isUpdating, username: username }) }) }));
22
+ }
23
+
24
+ export { ChangePasswordDialog };
@@ -0,0 +1,7 @@
1
+ export interface ChangePasswordProps {
2
+ error?: Error | null | unknown;
3
+ isLoading?: boolean;
4
+ isUpdating?: boolean;
5
+ username: string | undefined;
6
+ }
7
+ export declare function ChangePassword({ error, isLoading, isUpdating, username, }: ChangePasswordProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { FormSegment } from '../../../../forms/form/form-segment.js';
3
+ import { PasswordField } from '../../../../forms/password-field/password-field.js';
4
+ import { PasswordValidation } from '../../../../forms/password-validation/password-validation.js';
5
+ import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
6
+ import { ProgressCircle } from '../../../../loading/progress-circle.js';
7
+ import { Message } from '../../../../message/message.js';
8
+ import { NonUniquePasswordError, InvalidPasswordError } from '../../../../shared/api/storefront/services/authentication-service.js';
9
+ import { UnauthorizedRequestError } from '../../../../shared/fetch/request.js';
10
+ import { validatePassword } from '../../../../shared/model/account.js';
11
+ import styles from './change-password.module.css.js';
12
+
13
+ function ChangePassword({ error, isLoading = false, isUpdating = false, username, }) {
14
+ const t = useFormattedMessage();
15
+ if (error instanceof UnauthorizedRequestError) {
16
+ return (jsx(FormSegment, { children: jsx(Message, { type: "danger", children: t('You are not authorized to perform this action') }) }));
17
+ }
18
+ if (isLoading) {
19
+ return (jsx("div", { className: styles['loading-panel'], children: jsx(ProgressCircle, { variant: "gray" }) }));
20
+ }
21
+ if (!username) {
22
+ return jsx(Message, { type: "danger", children: t('An unexpected error occured') });
23
+ }
24
+ return (jsxs(Fragment, { children: [jsxs(FormSegment, { children: [jsx("input", { autoComplete: "username", defaultValue: username, id: "username", name: "username", style: { display: 'none' }, type: "text" }), jsx(PasswordField, { autoComplete: "password", "data-test-selector": "current_password", isDisabled: isUpdating, isRequired: true, label: t('Password'), name: "current-password", validate: value => {
25
+ if (!value)
26
+ return;
27
+ return (validatePassword(value) ||
28
+ t('Password does not meet requirements'));
29
+ } })] }), jsx(PasswordValidation, { isDisabled: isUpdating }), error && (jsx(FormSegment, { children: jsx(Message, { className: styles['error-message'], type: "danger", children: error instanceof NonUniquePasswordError ||
30
+ error instanceof InvalidPasswordError
31
+ ? t(error.message)
32
+ : t('An unexpected error occured') }) }))] }));
33
+ }
34
+
35
+ export { ChangePassword };
@@ -0,0 +1,3 @@
1
+ var styles = {"loading-panel":"change-password-module-hSjXo","error-message":"change-password-module-HyPjt"};
2
+
3
+ export { styles as default };
@@ -0,0 +1,5 @@
1
+ export interface ConnectedChangePasswordDialogProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ export declare function ConnectedChangePasswordDialog({ isOpen, onClose, }: ConnectedChangePasswordDialogProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,39 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { FormattedMessage } from '../../../../intl/formatted-message.js';
3
+ import { logger } from '../../../../logging/logger.js';
4
+ import { useFetchCurrentAccount } from '../../../../shared/api/storefront/hooks/account/use-fetch-current-account.js';
5
+ import { usePatchSession } from '../../../../shared/api/storefront/hooks/authentication/use-patch-session.js';
6
+ import { useNavigate } from '../../../../shared/routing/use-navigate.js';
7
+ import { useToast } from '../../../../toast/use-toast.js';
8
+ import { PATHS } from '../../../paths.js';
9
+ import { ChangePasswordDialog } from './change-password-dialog.js';
10
+
11
+ function ConnectedChangePasswordDialog({ isOpen, onClose, }) {
12
+ const { error: errorPatchSession, isLoading: isUpdating, mutate: patchSession, } = usePatchSession();
13
+ const { addToast } = useToast();
14
+ const { navigate } = useNavigate();
15
+ const { data: account, error: errorFetchCurrentAccount, isLoading, } = useFetchCurrentAccount({
16
+ isEnabled: isOpen,
17
+ });
18
+ if (!isOpen)
19
+ return null;
20
+ return (jsx(ChangePasswordDialog, { error: errorFetchCurrentAccount || errorPatchSession, isLoading: isLoading, isOpen: isOpen, isUpdating: isUpdating, onClose: onClose, onPasswordChanged: async (currentPassword, newPassword) => {
21
+ logger.info(currentPassword, newPassword);
22
+ await patchSession({
23
+ session: {
24
+ email: account?.email,
25
+ newPassword,
26
+ password: currentPassword,
27
+ },
28
+ });
29
+ addToast({
30
+ body: (jsx(FormattedMessage, { id: "Password changed. Please sign in again." })),
31
+ isUserDismissable: false,
32
+ messageType: 'success',
33
+ });
34
+ onClose();
35
+ navigate(`${PATHS.SIGN_IN}${location?.pathname ? `?returnUrl=${encodeURIComponent(location.pathname + location.search)}` : ''}`);
36
+ }, username: account?.email }));
37
+ }
38
+
39
+ export { ConnectedChangePasswordDialog };
@@ -0,0 +1,5 @@
1
+ export interface ConnectedEditUserInfoDialogProps {
2
+ isOpen: boolean;
3
+ onClose?: () => void;
4
+ }
5
+ export declare function ConnectedEditUserInfoDialog({ isOpen, onClose, }: ConnectedEditUserInfoDialogProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { useState, useEffect } from 'react';
4
+ import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
5
+ import { useFetchCurrentAccount } from '../../../../shared/api/storefront/hooks/account/use-fetch-current-account.js';
6
+ import { usePatchCurrentAccount } from '../../../../shared/api/storefront/hooks/account/use-patch-current-account.js';
7
+ import { ExistingAccountError } from '../../../../shared/api/storefront/services/account-service.js';
8
+ import { EditUserInfoDialog } from './edit-user-info-dialog.js';
9
+
10
+ function ConnectedEditUserInfoDialog({ isOpen, onClose, }) {
11
+ const t = useFormattedMessage();
12
+ const [validationErrors, setValidationErrors] = useState({});
13
+ const { data: account, error, isLoading, } = useFetchCurrentAccount({
14
+ isEnabled: isOpen,
15
+ });
16
+ const { error: errorPatchCurrentAccount, isLoading: isMutating, mutate, reset, } = usePatchCurrentAccount();
17
+ useEffect(() => reset(), [isOpen, reset]);
18
+ if (!isOpen)
19
+ return null;
20
+ return (jsx(EditUserInfoDialog, { account: account, error: error || errorPatchCurrentAccount, isLoading: isLoading, isOpen: isOpen, isUpdating: isMutating, onOpenChange: isOpen => !isOpen && onClose?.(), onSubmit: async ({ formData }) => {
21
+ const email = formData.get('email')?.toString();
22
+ if (!email)
23
+ throw new Error('E-mail is required');
24
+ const lastName = formData.get('lastName')?.toString();
25
+ if (!lastName)
26
+ throw new Error('Last name is required');
27
+ const firstName = formData.get('firstName')?.toString();
28
+ if (!firstName)
29
+ throw new Error('First name is required');
30
+ try {
31
+ await mutate({
32
+ account: {
33
+ ...account,
34
+ email,
35
+ firstName,
36
+ lastName,
37
+ },
38
+ });
39
+ onClose?.();
40
+ }
41
+ catch (error) {
42
+ if (error instanceof ExistingAccountError) {
43
+ setValidationErrors(errors => ({
44
+ ...errors,
45
+ email: t('This email is already in use'),
46
+ }));
47
+ reset();
48
+ }
49
+ else {
50
+ throw error;
51
+ }
52
+ }
53
+ }, validationErrors: validationErrors }));
54
+ }
55
+
56
+ export { ConnectedEditUserInfoDialog };
@@ -0,0 +1,10 @@
1
+ import { OnSubmitHandler, ValidationErrors } from '../../../../forms/form/form';
2
+ import { EditUserInfoProps } from './edit-user-info';
3
+ export interface EditUserInfoDialogProps extends EditUserInfoProps {
4
+ isOpen: boolean;
5
+ isUpdating?: boolean;
6
+ onOpenChange?: (isOpen: boolean) => void;
7
+ onSubmit?: OnSubmitHandler;
8
+ validationErrors?: ValidationErrors;
9
+ }
10
+ export declare function EditUserInfoDialog({ account, error, isLoading, isOpen, isUpdating, onOpenChange, onSubmit, validationErrors, }: EditUserInfoDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
4
+ import { Dialog } from '../../../../modals/dialog/dialog.js';
5
+ import { UnauthorizedRequestError } from '../../../../shared/fetch/request.js';
6
+ import { EditUserInfo } from './edit-user-info.js';
7
+
8
+ function EditUserInfoDialog({ account, error, isLoading, isOpen = false, isUpdating = false, onOpenChange, onSubmit, validationErrors, }) {
9
+ const t = useFormattedMessage();
10
+ return (jsx(Dialog, { allowSubmit: !isLoading &&
11
+ !isUpdating &&
12
+ !(error instanceof UnauthorizedRequestError), isOpen: isOpen, isSubmitting: isUpdating, onOpenChange: onOpenChange, onSubmit: onSubmit, title: t('Edit Sonic account'), validationErrors: validationErrors, children: jsx(EditUserInfo, { account: account, error: error, isLoading: isLoading }) }));
13
+ }
14
+
15
+ export { EditUserInfoDialog };
@@ -0,0 +1,11 @@
1
+ import { AccountModel } from '../../../../shared/api/storefront/model/storefront.model';
2
+ export interface EditUserInfoProps {
3
+ account: AccountModel | {
4
+ email: string;
5
+ firstName: string;
6
+ lastName: string;
7
+ } | undefined;
8
+ error?: Error | null | unknown;
9
+ isLoading?: boolean;
10
+ }
11
+ export declare function EditUserInfo({ account, error, isLoading, }: EditUserInfoProps): import("react/jsx-runtime").JSX.Element;