@sonic-equipment/ui 183.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 (98) 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/header/connected-header.js +1 -1
  12. package/dist/header/header.d.ts +1 -3
  13. package/dist/header/header.js +2 -2
  14. package/dist/index.js +21 -3
  15. package/dist/intl/translation-id.d.ts +1 -1
  16. package/dist/intl/use-formatted-message.js +2 -1
  17. package/dist/lists/menu-list/menu-list.d.ts +2 -1
  18. package/dist/lists/menu-list/menu-list.js +2 -2
  19. package/dist/lists/widget-grid/widget-grid.d.ts +5 -0
  20. package/dist/lists/widget-grid/widget-grid.js +9 -0
  21. package/dist/lists/widget-grid/widget-grid.module.css.js +3 -0
  22. package/dist/lists/widget-grid/widget.d.ts +6 -0
  23. package/dist/lists/widget-grid/widget.js +10 -0
  24. package/dist/modals/dialog/dialog.d.ts +5 -5
  25. package/dist/modals/dialog/dialog.js +18 -18
  26. package/dist/modals/dialog/dialog.module.css.js +1 -1
  27. package/dist/modals/recover-password/recover-password-dialog.js +1 -3
  28. package/dist/pages/account/components/create-account-form/create-account-form.js +2 -17
  29. package/dist/pages/account/create-account-page/create-account-page.js +4 -5
  30. package/dist/pages/account/layouts/sign-in-page-layout/sign-in-page-layout.js +1 -1
  31. package/dist/pages/account/sign-in-page/sign-in-page.js +2 -3
  32. package/dist/pages/checkout/layouts/checkout-page-layout/checkout-page-layout.js +2 -1
  33. package/dist/pages/checkout/shipping-page/hooks/use-patch-shipping-details.d.ts +1 -0
  34. package/dist/pages/components/page-container/page-container.js +1 -1
  35. package/dist/pages/my-sonic/actions/change-customer/change-customer-dialog.d.ts +4 -3
  36. package/dist/pages/my-sonic/actions/change-customer/change-customer-dialog.js +10 -4
  37. package/dist/pages/my-sonic/actions/change-customer/change-customer.d.ts +5 -2
  38. package/dist/pages/my-sonic/actions/change-customer/change-customer.js +16 -7
  39. package/dist/pages/my-sonic/actions/change-customer/change-customer.module.css.js +1 -1
  40. package/dist/pages/my-sonic/actions/change-customer/connected-change-customer-dialog.d.ts +7 -2
  41. package/dist/pages/my-sonic/actions/change-customer/connected-change-customer-dialog.js +9 -6
  42. package/dist/pages/my-sonic/actions/change-password/change-password-dialog.d.ts +10 -0
  43. package/dist/pages/my-sonic/actions/change-password/change-password-dialog.js +24 -0
  44. package/dist/pages/my-sonic/actions/change-password/change-password.d.ts +7 -0
  45. package/dist/pages/my-sonic/actions/change-password/change-password.js +35 -0
  46. package/dist/pages/my-sonic/actions/change-password/change-password.module.css.js +3 -0
  47. package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.d.ts +5 -0
  48. package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.js +39 -0
  49. package/dist/pages/my-sonic/actions/edit-user-info/connected-edit-user-info-dialog.d.ts +5 -0
  50. package/dist/pages/my-sonic/actions/edit-user-info/connected-edit-user-info-dialog.js +56 -0
  51. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info-dialog.d.ts +10 -0
  52. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info-dialog.js +15 -0
  53. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info.d.ts +11 -0
  54. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info.js +29 -0
  55. package/dist/pages/my-sonic/actions/edit-user-info/edit-user-info.module.css.js +3 -0
  56. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-aside.d.ts +4 -0
  57. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-aside.js +9 -0
  58. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-main.d.ts +4 -0
  59. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-main.js +9 -0
  60. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-page.d.ts +5 -0
  61. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-page.js +10 -0
  62. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-pre-aside.d.ts +4 -0
  63. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-pre-aside.js +9 -0
  64. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-title.d.ts +4 -0
  65. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout-title.js +10 -0
  66. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout.d.ts +5 -0
  67. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout.js +10 -0
  68. package/dist/pages/my-sonic/layouts/my-sonic-layout/my-sonic-layout.module.css.js +3 -0
  69. package/dist/pages/my-sonic/navigation/connected-my-sonic-navigation.js +3 -4
  70. package/dist/pages/my-sonic/navigation/connected-my-sonic-navigation.module.css.js +3 -0
  71. package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.d.ts +2 -1
  72. package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.js +2 -2
  73. package/dist/pages/my-sonic/navigation/my-sonic-mobile-navigation.d.ts +2 -1
  74. package/dist/pages/my-sonic/navigation/my-sonic-mobile-navigation.js +2 -2
  75. package/dist/pages/my-sonic/widgets/connected-customer-information-widget.js +3 -3
  76. package/dist/pages/my-sonic/widgets/connected-user-account-widget.js +16 -5
  77. package/dist/shared/api/shared/hooks/use-awaitable-mutation.d.ts +1 -0
  78. package/dist/shared/api/shared/hooks/use-awaitable-mutation.js +6 -0
  79. package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-account.d.ts +1 -1
  80. package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-account.js +3 -1
  81. package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-guest-account.js +3 -1
  82. package/dist/shared/api/storefront/hooks/account/use-fetch-current-account.d.ts +3 -0
  83. package/dist/shared/api/storefront/hooks/account/use-fetch-current-account.js +13 -0
  84. package/dist/shared/api/storefront/hooks/account/use-patch-current-account.d.ts +11 -0
  85. package/dist/shared/api/storefront/hooks/account/use-patch-current-account.js +20 -0
  86. package/dist/shared/api/storefront/hooks/authentication/use-patch-session.d.ts +1 -0
  87. package/dist/shared/api/storefront/hooks/authentication/use-patch-session.js +1 -1
  88. package/dist/shared/api/storefront/hooks/cart/use-patch-cart.d.ts +1 -0
  89. package/dist/shared/api/storefront/hooks/cart/use-place-order.d.ts +1 -0
  90. package/dist/shared/api/storefront/hooks/customer/use-patch-bill-to-address.d.ts +1 -0
  91. package/dist/shared/api/storefront/services/account-service.d.ts +31 -0
  92. package/dist/shared/api/storefront/services/account-service.js +84 -0
  93. package/dist/shared/api/storefront/services/authentication-service.d.ts +7 -26
  94. package/dist/shared/api/storefront/services/authentication-service.js +38 -65
  95. package/dist/shared/hooks/use-watch-css-property.js +9 -1
  96. package/dist/styles.css +354 -241
  97. package/package.json +1 -1
  98. /package/dist/shared/api/storefront/hooks/{authentication → account}/use-create-guest-account.d.ts +0 -0
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { Dialog as Dialog$1, Form } from 'react-aria-components';
3
+ import { Dialog as Dialog$1 } from 'react-aria-components';
4
4
  import clsx from 'clsx';
5
5
  import { Button } from '../../buttons/button/button.js';
6
6
  import { IconButton } from '../../buttons/icon-button/icon-button.js';
7
+ import { Form } from '../../forms/form/form.js';
7
8
  import { StrokeCloseboxIcon } from '../../icons/stroke/stroke-closebox-icon.js';
8
9
  import { FormattedMessage } from '../../intl/formatted-message.js';
9
10
  import { useFormattedMessage } from '../../intl/use-formatted-message.js';
@@ -16,23 +17,22 @@ function Footer({ allowSubmit = true, cancelLabel, close, isSubmitting, submitLa
16
17
  }
17
18
  function Dialog({ allowClose = true, allowSubmit = true, cancelLabel = 'Close', children, className, 'data-test-selector': dataTestSelector = 'dialog', footer = Footer, hasCloseButton = true, hideTitle, isDismissable, isFullScreen, isKeyboardDismissDisabled, isOpen, isSubmitting = false, onOpenChange, onSubmit, shouldCloseOnInteractOutside, submitLabel = 'Submit', title, validationErrors, }) {
18
19
  const t = useFormattedMessage();
19
- return (jsx(Modal, { className: clsx(styles['modal-overlay'], typeof className === 'string' ? className : className?.modal), hasCloseButton: false, isDismissable: isDismissable, isFullScreen: isFullScreen, isKeyboardDismissDisabled: isKeyboardDismissDisabled, isOpen: isOpen, onOpenChange: onOpenChange, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, children: jsx(Dialog$1, { "aria-label": title, className: clsx(styles.dialog, typeof className === 'string' ? undefined : className?.dialog), "data-test-selector": dataTestSelector, children: ({ close }) => (jsxs(Form, { className: clsx(styles.form, typeof className === 'string' ? undefined : className?.form), onSubmit: e => {
20
- e.preventDefault();
21
- e.stopPropagation();
22
- onSubmit?.(e);
23
- }, validationErrors: validationErrors, children: [jsxs("header", { className: clsx(styles.header, typeof className === 'string' ? undefined : className?.header), children: [!hideTitle && (jsx(Heading, { className: clsx(styles.heading, typeof className === 'string'
24
- ? undefined
25
- : className?.heading), size: "xs", tag: "h2", children: title })), hasCloseButton && (jsx("div", { className: clsx(styles.close, typeof className === 'string'
26
- ? undefined
27
- : className?.close), children: jsx(IconButton, { "aria-label": t('Close'), color: "secondary", isDisabled: !allowClose, onClick: close, children: jsx(StrokeCloseboxIcon, {}) }) }))] }), jsx("div", { className: clsx(styles.content, typeof className === 'string' ? undefined : className?.content), children: children instanceof Function ? children({ close }) : children }), jsx("footer", { className: clsx(styles.footer, typeof className === 'string' ? undefined : className?.footer), children: footer instanceof Function
28
- ? footer({
29
- allowSubmit,
30
- cancelLabel,
31
- close,
32
- isSubmitting,
33
- submitLabel,
34
- })
35
- : footer })] })) }) }));
20
+ return (jsx(Modal, { className: {
21
+ modal: styles.modal,
22
+ overlay: clsx(styles['modal-overlay'], typeof className === 'string' ? className : className?.modal),
23
+ }, hasCloseButton: false, isDismissable: isDismissable, isFullScreen: isFullScreen, isKeyboardDismissDisabled: isKeyboardDismissDisabled, isOpen: isOpen, onOpenChange: onOpenChange, shouldCloseOnInteractOutside: shouldCloseOnInteractOutside, children: jsx(Dialog$1, { "aria-label": title, className: clsx(styles.dialog, typeof className === 'string' ? undefined : className?.dialog), "data-test-selector": dataTestSelector, children: ({ close }) => (jsx(Form, { className: clsx(styles.form, typeof className === 'string' ? undefined : className?.form), footer: jsx("div", { className: clsx(styles.footer, typeof className === 'string' ? undefined : className?.footer), children: footer instanceof Function
24
+ ? footer({
25
+ allowSubmit,
26
+ cancelLabel,
27
+ close,
28
+ isSubmitting,
29
+ submitLabel,
30
+ })
31
+ : footer }), header: jsxs(Fragment, { children: [!hideTitle && (jsx(Heading, { className: clsx(styles.heading, typeof className === 'string'
32
+ ? undefined
33
+ : className?.heading), size: "xs", tag: "h2", children: title })), hasCloseButton && (jsx("div", { className: clsx(styles.close, typeof className === 'string'
34
+ ? undefined
35
+ : className?.close), children: jsx(IconButton, { "aria-label": t('Close'), color: "secondary", isDisabled: !allowClose, onClick: close, children: jsx(StrokeCloseboxIcon, {}) }) }))] }), onSubmit: onSubmit, validationErrors: validationErrors, children: jsx("div", { className: clsx(styles.content, typeof className === 'string' ? undefined : className?.content), children: children instanceof Function ? children({ close }) : children }) })) }) }));
36
36
  }
37
37
 
38
38
  export { Dialog };
@@ -1,3 +1,3 @@
1
- var styles = {"dialog":"dialog-module-qKzgy","header":"dialog-module-ZnsAe","close":"dialog-module-Y7Tqg","footer":"dialog-module-y7Axm"};
1
+ var styles = {"modal":"dialog-module-uKVDu","dialog":"dialog-module-qKzgy","form":"dialog-module-5sZYV","close":"dialog-module-Y7Tqg","footer":"dialog-module-y7Axm"};
2
2
 
3
3
  export { styles as default };
@@ -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,6 +13,7 @@ function CheckoutPageLayout({ actions, children, mobileSummary, overview, }) {
13
13
  const topRef = useRef(null);
14
14
  const bottomRef = useRef(null);
15
15
  const headerHeight = useWatchCssProperty('--header-bottom');
16
+ const isObservingIntersection = Boolean(headerHeight);
16
17
  const isScrolledBeyond = useIsScrolledBeyondElement(bottomRef.current || undefined);
17
18
  const observables = useMemo(() => [
18
19
  {
@@ -27,7 +28,7 @@ function CheckoutPageLayout({ actions, children, mobileSummary, overview, }) {
27
28
  isDisabled: isXXL,
28
29
  observables,
29
30
  });
30
- return (jsxs("div", { className: styles['checkout-page-layout'], children: [!isXXL && (jsxs(Fragment, { children: [mobileSummary, jsx("div", { ref: topRef }), jsxs("div", { className: clsx(styles['top-actions'], styles.actions), children: [actions?.primary, actions?.secondary] }), !isIntersecting && !isScrolledBeyond && (jsxs("div", { className: clsx(styles['top-actions-sticky'], styles.actions), children: [actions?.primary, actions?.secondary] }))] })), jsxs("div", { className: styles.wrapper, children: [jsx("div", { className: styles.main, children: children }), jsx("div", { className: styles.side, children: jsxs("div", { className: styles['sticky-side'], children: [overview, jsxs("div", { ref: bottomRef, className: styles.actions, children: [actions?.primary, actions?.secondary] })] }) })] })] }));
31
+ return (jsxs("div", { className: styles['checkout-page-layout'], children: [!isXXL && (jsxs(Fragment, { children: [mobileSummary, jsx("div", { ref: topRef }), jsxs("div", { className: clsx(styles['top-actions'], styles.actions), children: [actions?.primary, actions?.secondary] }), isObservingIntersection && !isIntersecting && !isScrolledBeyond && (jsxs("div", { className: clsx(styles['top-actions-sticky'], styles.actions), children: [actions?.primary, actions?.secondary] }))] })), jsxs("div", { className: styles.wrapper, children: [jsx("div", { className: styles.main, children: children }), jsx("div", { className: styles.side, children: jsxs("div", { className: styles['sticky-side'], children: [overview, jsxs("div", { ref: bottomRef, className: styles.actions, children: [actions?.primary, actions?.secondary] })] }) })] })] }));
31
32
  }
32
33
 
33
34
  export { CheckoutPageLayout };
@@ -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;