@sonic-equipment/ui 136.0.0 → 137.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 (25) hide show
  1. package/dist/config.js +2 -2
  2. package/dist/country-selector/country-select/country-select.d.ts +6 -0
  3. package/dist/country-selector/country-select/country-select.js +10 -4
  4. package/dist/exports.d.ts +1 -0
  5. package/dist/header/header.d.ts +1 -0
  6. package/dist/header/header.js +9 -0
  7. package/dist/index.js +1 -0
  8. package/dist/media/image/image.js +11 -4
  9. package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +7 -1
  10. package/dist/pages/checkout/payment-page/components/adyen-payment.js +6 -4
  11. package/dist/pages/checkout/payment-page/components/payment.js +1 -3
  12. package/dist/pages/checkout/shipping-page/components/edit-address.d.ts +1 -0
  13. package/dist/pages/checkout/shipping-page/components/edit-address.js +2 -1
  14. package/dist/pages/checkout/shipping-page/hooks/use-patch-shipping-details.d.ts +6 -2
  15. package/dist/pages/checkout/shipping-page/hooks/use-patch-shipping-details.js +27 -8
  16. package/dist/pages/checkout/shipping-page/shipping-page.js +3 -4
  17. package/dist/shared/api/shared/hooks/use-awaitable-mutation.d.ts +21 -20
  18. package/dist/shared/api/storefront/hooks/cart/use-patch-cart.d.ts +1 -3
  19. package/dist/shared/api/storefront/hooks/cart/use-patch-cart.js +4 -6
  20. package/dist/shared/api/storefront/hooks/cart/use-place-order.d.ts +1 -1
  21. package/dist/shared/api/storefront/hooks/cart/use-place-order.js +6 -5
  22. package/dist/shared/api/storefront/services/cart-service.js +7 -7
  23. package/dist/shared/model/image.d.ts +1 -2
  24. package/dist/styles.css +1 -1
  25. package/package.json +1 -1
package/dist/config.js CHANGED
@@ -13,8 +13,8 @@ const configPerEnvironment = {
13
13
  local: () => ({
14
14
  ALGOLIA_API_KEY: 'e0edf30798a6b2e4e44fd25f0f2f9646',
15
15
  ALGOLIA_APP_ID: 'testing9VXJ0U4GSV',
16
- ALGOLIA_HOST: 'shop-accept.sonic-equipment.workers.dev',
17
- BFF_API_URL: 'https://shop-accept.sonic-equipment.workers.dev/api/v1/bff',
16
+ ALGOLIA_HOST: 'sonic.local.com:4443',
17
+ BFF_API_URL: '/api/v1/bff',
18
18
  COOKIE_DOMAIN: undefined,
19
19
  SHOP_API_URL:
20
20
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -8,14 +8,20 @@ interface CountrySelectProps<T extends Country | CountryModel> {
8
8
  name?: string;
9
9
  showLabel?: boolean;
10
10
  }
11
+ interface CountrySelectPropsWithDefaultSelectedCountry<T extends Country | CountryModel> extends CountrySelectProps<T> {
12
+ defaultSelectedCountry: T;
13
+ onCountryChange?: (country: T) => void;
14
+ }
11
15
  interface CountrySelectPropsWithSelectedCountry<T extends Country | CountryModel> extends CountrySelectProps<T> {
12
16
  onCountryChange?: (country: T) => void;
13
17
  selectedCountry: T;
14
18
  }
15
19
  interface CountrySelectPropsWithoutSelectedCountry<T extends Country | CountryModel> extends CountrySelectProps<T> {
20
+ defaultSelectedCountry?: T | undefined;
16
21
  onCountryChange?: (country: T | undefined) => void;
17
22
  selectedCountry?: T | undefined;
18
23
  }
24
+ export declare function CountrySelect<T extends Country | CountryModel>(props: CountrySelectPropsWithDefaultSelectedCountry<T>): JSX.Element;
19
25
  export declare function CountrySelect<T extends Country | CountryModel>(props: CountrySelectPropsWithSelectedCountry<T>): JSX.Element;
20
26
  export declare function CountrySelect<T extends Country | CountryModel>(props: CountrySelectPropsWithoutSelectedCountry<T>): JSX.Element;
21
27
  export {};
@@ -3,15 +3,21 @@ import { useMemo } from 'react';
3
3
  import { Select } from '../../forms/select/select.js';
4
4
  import { useFormattedMessage } from '../../intl/use-formatted-message.js';
5
5
 
6
- function CountrySelect({ countries, 'data-test-selector': dataTestSelector, isDisabled, isRequired, name, onCountryChange, selectedCountry, showLabel = true, }) {
6
+ function CountrySelect({ countries, 'data-test-selector': dataTestSelector, defaultSelectedCountry, isDisabled, isRequired, name, onCountryChange, selectedCountry, showLabel = true, }) {
7
7
  const t = useFormattedMessage();
8
- const countryOptions = useMemo(() => countries.reduce((acc, country) => ({
8
+ const countryOptions = useMemo(() => countries
9
+ .map((country) => [
10
+ country.id,
11
+ t(`clSelector.${country.abbreviation}`),
12
+ ])
13
+ .sort(([, labelA], [, labelB]) => labelA.localeCompare(labelB))
14
+ .reduce((acc, [id, label]) => ({
9
15
  ...acc,
10
- [country.id]: t(`clSelector.${country.abbreviation}`),
16
+ [id]: label,
11
17
  }), {}),
12
18
  // eslint-disable-next-line react-hooks/exhaustive-deps
13
19
  [countries]);
14
- return (jsx(Select, { "data-test-selector": dataTestSelector, isDisabled: isDisabled, isRequired: isRequired, label: t('Country'), name: name, onChange: value => onCountryChange?.(countries.find(country => country.id === value)), options: countryOptions, selectedOption: selectedCountry?.id, showLabel: showLabel, showPlaceholder: false, variant: "solid" }));
20
+ return (jsx(Select, { "data-test-selector": dataTestSelector, defaultSelectedOption: defaultSelectedCountry?.id, isDisabled: isDisabled, isRequired: isRequired, label: t('Country'), name: name, onChange: value => onCountryChange?.(countries.find(country => country.id === value)), options: countryOptions, selectedOption: selectedCountry?.id, showLabel: showLabel, showPlaceholder: false, variant: "solid" }));
15
21
  }
16
22
 
17
23
  export { CountrySelect };
package/dist/exports.d.ts CHANGED
@@ -110,6 +110,7 @@ export * from './global-search/search-section/search-section';
110
110
  export * from './global-search/types';
111
111
  export * from './header/cart-icon/connected-cart-icon';
112
112
  export * from './header/hamburger-button/hamburger-button';
113
+ export * from './header/header';
113
114
  export * from './header/header-layout/header-layout';
114
115
  export * from './header/sonic-logo/sonic-logo';
115
116
  export * from './info-icon-tooltip/info-icon-tooltip';
@@ -0,0 +1 @@
1
+ export declare function Header(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { HeaderLayout } from './header-layout/header-layout.js';
3
+ import { SonicLogo } from './sonic-logo/sonic-logo.js';
4
+
5
+ function Header() {
6
+ return (jsx(HeaderLayout, { hamburgerButton: null, logo: jsx(SonicLogo, { href: "/" }), mainNavigation: null, navigationActions: null, search: null }));
7
+ }
8
+
9
+ export { Header };
package/dist/index.js CHANGED
@@ -114,6 +114,7 @@ export { SearchListItem } from './global-search/search-section/search-list-item.
114
114
  export { SearchSection } from './global-search/search-section/search-section.js';
115
115
  export { ConnectedCartIcon } from './header/cart-icon/connected-cart-icon.js';
116
116
  export { HamburgerButton } from './header/hamburger-button/hamburger-button.js';
117
+ export { Header } from './header/header.js';
117
118
  export { HeaderLayout } from './header/header-layout/header-layout.js';
118
119
  export { SonicLogo } from './header/sonic-logo/sonic-logo.js';
119
120
  export { InfoIconTooltip } from './info-icon-tooltip/info-icon-tooltip.js';
@@ -25,12 +25,19 @@ function Image({ className, fallbackSrc = 'https://res.cloudinary.com/dkz9eknwh/
25
25
  }
26
26
  return jsx(ImageComponent, { ...props, hasError: hasError, image: image });
27
27
  }
28
+ function createSrcSet(image) {
29
+ return ([
30
+ image[1] && `${image[1]} 1x`,
31
+ image[2] && `${image[2]} 2x`,
32
+ image[3] && `${image[3]} 3x`,
33
+ ]
34
+ .filter(Boolean)
35
+ .join(', ') || undefined);
36
+ }
28
37
  function ImageComponent({ className, fallbackSrc, fit = 'cover', hasError, image, ...rest }) {
29
38
  if (!image)
30
39
  return (jsx("img", { alt: "Missing", className: clsx(styles.image, className, styles[fit], styles['has-error']), src: fallbackSrc, ...rest }));
31
- const srcSet = hasError
32
- ? undefined
33
- : `${image[1]} 1x, ${image[2]} 2x, ${image[3]} 3x`;
40
+ const srcSet = hasError ? undefined : createSrcSet(image);
34
41
  return (jsx("img", { alt: image.altText, className: clsx(styles.image, className, styles[fit], {
35
42
  [styles['has-error']]: hasError,
36
43
  }), src: hasError ? fallbackSrc : image[3], srcSet: srcSet, ...rest }));
@@ -38,7 +45,7 @@ function ImageComponent({ className, fallbackSrc, fit = 'cover', hasError, image
38
45
  function PictureComponent({ className, fallbackSrc, fit = 'cover', hasError, image, ...rest }) {
39
46
  if (!image)
40
47
  return (jsx("picture", { className: clsx(styles.picture, className), children: jsx("img", { alt: "Missing", className: clsx(styles.image, styles[fit], styles['has-error']), src: fallbackSrc, ...rest }) }));
41
- return (jsxs("picture", { className: clsx(styles.picture, className), children: [jsx("source", { media: "(max-width: 768px)", srcSet: `${image.sm[1]} 1x, ${image.sm[2]} 2x, ${image.sm[3]} 3x` }), jsx("source", { media: "(max-width: 1439px)", srcSet: `${image.md[1]} 1x, ${image.md[2]} 2x, ${image.md[3]} 3x` }), jsx("source", { media: "(min-width: 1440px)", srcSet: `${image.lg[1]} 1x, ${image.lg[2]} 2x, ${image.lg[3]} 3x` }), jsx("img", { alt: image.altText, className: clsx(styles.image, styles[fit], {
48
+ return (jsxs("picture", { className: clsx(styles.picture, className), children: [jsx("source", { media: "(max-width: 768px)", srcSet: createSrcSet(image.sm) }), jsx("source", { media: "(max-width: 1439px)", srcSet: createSrcSet(image.md) }), jsx("source", { media: "(min-width: 1440px)", srcSet: createSrcSet(image.lg) }), jsx("img", { alt: image.altText, className: clsx(styles.image, styles[fit], {
42
49
  [styles['has-error']]: hasError,
43
50
  }), src: hasError ? fallbackSrc : image.lg[3], ...rest })] }));
44
51
  }
@@ -39,7 +39,13 @@ function OrderConfirmationPageContent({ cart, }) {
39
39
  });
40
40
  },
41
41
  });
42
- return (jsx(Page, { breadCrumb: [{ href: CHECKOUT_PATHS.HOME, label: t('Home') }], title: t('Order confirmation'), children: jsx(CheckoutPageLayout, { actions: {
42
+ return (jsx(Page, { breadCrumb: [
43
+ { href: CHECKOUT_PATHS.HOME, label: t('Home') },
44
+ {
45
+ href: `${CHECKOUT_PATHS.ORDER_CONFIRMATION}?cartId=${cart.id}`,
46
+ label: t('Order confirmation'),
47
+ },
48
+ ], title: t('Order confirmation'), children: jsx(CheckoutPageLayout, { actions: {
43
49
  primary: (jsx(RouteButton, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_continueShopping", href: "/", children: jsx(FormattedMessage, { id: "Continue shopping" }) })),
44
50
  secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(RouteButton, { color: "secondary", onClick: () => {
45
51
  saveCartForLater.mutate({ cart });
@@ -127,10 +127,12 @@ function getAndRemoveAdyenQueryParams() {
127
127
  return {};
128
128
  const params = qs.parse(window.location.search || '');
129
129
  const { amount, customerId, redirectResult } = params;
130
- delete params['redirectResult'];
131
- delete params['amount'];
132
- delete params['customerId'];
133
- history?.pushState({}, '', `${window.location.pathname}${qs.stringify(params) ? `?${qs.stringify(params)}` : ''}`);
130
+ if (redirectResult) {
131
+ delete params['redirectResult'];
132
+ delete params['amount'];
133
+ delete params['customerId'];
134
+ history?.pushState({}, '', `${window.location.pathname}${qs.stringify(params) ? `?${qs.stringify(params)}` : ''}`);
135
+ }
134
136
  return { amount, customerId, redirectResult };
135
137
  }
136
138
  async function handlePaymentResponse(result, onSubmit, onError) {
@@ -29,9 +29,7 @@ import styles from './payment.module.css.js';
29
29
 
30
30
  function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete, onProcessing, onValidating, }) {
31
31
  const { createEcommerceEvent, dataLayer } = useDataLayer();
32
- const { isLoading: isPatchingCart, mutate: patchCart } = usePatchCart({
33
- skipInvalidation: true,
34
- });
32
+ const { isLoading: isPatchingCart, mutate: patchCart } = usePatchCart();
35
33
  const { isLoading: isPatchingSession } = usePatchSession();
36
34
  const { isLoading: isPlacingCart, mutate: placeOrder } = usePlaceOrder();
37
35
  const { sendPurchaseEventFromPaymentPage } = useAlgoliaInsights();
@@ -8,6 +8,7 @@ interface Address {
8
8
  city: string;
9
9
  companyName: string;
10
10
  country: CountryModel;
11
+ email: string;
11
12
  firstName: string;
12
13
  lastName: string;
13
14
  phone: string;
@@ -36,6 +36,7 @@ function EditAddresses({ billTo, countries, isLoading, isPickup, onSubmit, }) {
36
36
  city: formData.get('address1')?.toString() || '',
37
37
  companyName: formData.get('companyName')?.toString() || '',
38
38
  country,
39
+ email: formData.get('email')?.toString() || '',
39
40
  firstName: formData.get('firstName')?.toString() || '',
40
41
  lastName: formData.get('address1')?.toString() || '',
41
42
  phone: formData.get('phone')?.toString() || '',
@@ -43,7 +44,7 @@ function EditAddresses({ billTo, countries, isLoading, isPickup, onSubmit, }) {
43
44
  },
44
45
  notes: formData.get('notes')?.toString() || '',
45
46
  });
46
- }, children: [jsx(TextField, { defaultValue: billTo?.firstName, isDisabled: isLoading, label: t('First name'), name: "firstName", showLabel: true }), jsx(TextField, { isDisabled: isLoading, isRequired: !companyName, label: t('Last name'), minLength: 3, name: "lastName", onChange: setLastName, showLabel: true, value: lastName }, `lastname-${Boolean(companyName)}`), jsx(TextField, { defaultValue: billTo?.companyName, isDisabled: isLoading, label: t('Company name'), name: "companyName", onChange: setCompanyName, showLabel: true, value: companyName }), jsx(TextField, { defaultValue: billTo?.attention, isDisabled: isLoading, label: t('Attention'), name: "attention", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: billTo?.address1, isDisabled: isLoading, label: `${t('Address')} 1`, maxLength: 30, minLength: 3, name: "address1", showLabel: true }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { defaultValue: billTo?.address2, isDisabled: isLoading, label: `${t('Address')} 2`, maxLength: 30, minLength: 3, name: "address2", showLabel: true }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { defaultValue: billTo?.address3, isDisabled: isLoading, label: `${t('Address')} 3`, maxLength: 30, minLength: 3, name: "address3", showLabel: true }) }), jsx(TextField, { isRequired: true, defaultValue: billTo?.postalCode, isDisabled: isLoading, label: t('Postal Code'), maxLength: 10, minLength: 4, name: "postalCode", showLabel: true }), jsx(TextField, { isRequired: true, defaultValue: billTo?.city, isDisabled: isLoading, label: t('City'), maxLength: 30, minLength: 3, name: "city", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(CountrySelect, { isRequired: true, countries: countries, "data-test-selector": "countrySelect", isDisabled: isLoading, name: "countrySelect", selectedCountry: countries.find(country => country.id === billTo?.country?.id) }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: billTo?.phone, isDisabled: isLoading, label: t('Phone'), name: "phone", showLabel: true, validate: value => {
47
+ }, children: [jsx(TextField, { defaultValue: billTo?.firstName, isDisabled: isLoading, label: t('First name'), name: "firstName", showLabel: true }), jsx(TextField, { isDisabled: isLoading, isRequired: !companyName, label: t('Last name'), minLength: 3, name: "lastName", onChange: setLastName, showLabel: true, value: lastName }, `lastname-${Boolean(companyName)}`), jsx(TextField, { defaultValue: billTo?.companyName, isDisabled: isLoading, label: t('Company name'), name: "companyName", onChange: setCompanyName, showLabel: true, value: companyName }), jsx(TextField, { defaultValue: billTo?.attention, isDisabled: isLoading, label: t('Attention'), name: "attention", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: billTo?.address1, isDisabled: isLoading, label: `${t('Address')} 1`, maxLength: 30, minLength: 3, name: "address1", showLabel: true }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { defaultValue: billTo?.address2, isDisabled: isLoading, label: `${t('Address')} 2`, maxLength: 30, minLength: 3, name: "address2", showLabel: true }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { defaultValue: billTo?.address3, isDisabled: isLoading, label: `${t('Address')} 3`, maxLength: 30, minLength: 3, name: "address3", showLabel: true }) }), jsx(TextField, { isRequired: true, defaultValue: billTo?.postalCode, isDisabled: isLoading, label: t('Postal Code'), maxLength: 10, minLength: 4, name: "postalCode", showLabel: true }), jsx(TextField, { isRequired: true, defaultValue: billTo?.city, isDisabled: isLoading, label: t('City'), maxLength: 30, minLength: 3, name: "city", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(CountrySelect, { isRequired: true, countries: countries, "data-test-selector": "countrySelect", defaultSelectedCountry: countries.find(country => country.id === billTo?.country?.id), isDisabled: isLoading, name: "countrySelect" }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: billTo?.phone, isDisabled: isLoading, label: t('Phone'), name: "phone", showLabel: true, validate: value => {
47
48
  if (!value)
48
49
  return value;
49
50
  return (validatePhone(value) ||
@@ -1,4 +1,4 @@
1
- import { BillToModel, CartModel } from '../../../../shared/api/storefront/model/storefront.model';
1
+ import { BillToModel, CartModel, SessionModel } from '../../../../shared/api/storefront/model/storefront.model';
2
2
  export declare function usePatchShippingDetails(): {
3
3
  error: unknown;
4
4
  isError: boolean;
@@ -8,5 +8,9 @@ export declare function usePatchShippingDetails(): {
8
8
  billTo?: BillToModel;
9
9
  cart: CartModel;
10
10
  notes: string | undefined;
11
- }) => Promise<void>;
11
+ }) => Promise<{
12
+ patchedBillTo: BillToModel | undefined;
13
+ patchedCart: CartModel;
14
+ patchedSession: SessionModel | undefined;
15
+ }>;
12
16
  };
@@ -1,19 +1,38 @@
1
1
  import { useAwaitableMutation } from '../../../../shared/api/shared/hooks/use-awaitable-mutation.js';
2
+ import { patchSession } from '../../../../shared/api/storefront/services/authentication-service.js';
2
3
  import { patchCart } from '../../../../shared/api/storefront/services/cart-service.js';
3
4
  import { patchBillToAddress } from '../../../../shared/api/storefront/services/customer-service.js';
4
5
 
5
6
  function usePatchShippingDetails() {
6
7
  return useAwaitableMutation({
7
8
  mutationFn: async ({ billTo, cart, notes, }) => {
8
- await Promise.all([
9
- billTo && patchBillToAddress({ billTo }),
10
- patchCart({ cart: { ...cart, notes } }),
11
- ].filter(Boolean));
9
+ const patchedBillTo = billTo
10
+ ? await patchBillToAddress({ billTo })
11
+ : undefined;
12
+ const patchedSession = patchedBillTo
13
+ ? await patchSession({
14
+ session: {
15
+ billTo: { id: patchedBillTo.id },
16
+ customerWasUpdated: true,
17
+ shipTo: { id: cart.shipTo?.id || patchedBillTo.id },
18
+ },
19
+ })
20
+ : undefined;
21
+ const patchedCart = await patchCart({
22
+ cart: { ...cart, billTo: patchedBillTo, notes },
23
+ });
24
+ return { patchedBillTo, patchedCart, patchedSession };
12
25
  },
13
- onSuccess: ({ queryClient }) => {
14
- queryClient.removeQueries({ queryKey: ['customer'] });
15
- queryClient.removeQueries({ queryKey: ['carts'] });
16
- queryClient.removeQueries({ queryKey: ['session'] });
26
+ onSuccess: ({ data: { patchedBillTo, patchedCart, patchedSession }, queryClient, }) => {
27
+ if (patchedBillTo)
28
+ queryClient.setQueryData(['customer', 'bill-to-addresses'], patchedBillTo);
29
+ if (patchedSession) {
30
+ queryClient.setQueryData(['session'], patchedSession);
31
+ }
32
+ else if (patchedBillTo) {
33
+ queryClient.removeQueries({ queryKey: ['session'] });
34
+ }
35
+ queryClient.setQueryData(['carts', patchedCart.id], patchedCart);
17
36
  },
18
37
  });
19
38
  }
@@ -1,7 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useRef, useEffect } from 'react';
3
3
  import { useFetchSession } from '../../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
4
- import { useIsAuthenticated } from '../../../shared/api/storefront/hooks/authentication/use-is-authenticated.js';
5
4
  import { usePatchSession } from '../../../shared/api/storefront/hooks/authentication/use-patch-session.js';
6
5
  import { useFetchCurrentCart } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart.js';
7
6
  import { useFetchFulfillmentMethodsForCurrentCart } from '../../../shared/api/storefront/hooks/customer/use-fetch-fulfillment-methods-for-current-cart.js';
@@ -18,17 +17,17 @@ import { usePatchShippingDetails } from './hooks/use-patch-shipping-details.js';
18
17
  import { ShippingPageContent } from './shipping-page-content.js';
19
18
 
20
19
  function ShippingPage() {
21
- const isAuthenticated = useIsAuthenticated();
22
20
  const { createEcommerceEvent, dataLayer } = useDataLayer();
23
21
  const gaEventPushed = useRef(false);
24
22
  const { data: cart, error: errorFetchCart, isLoading: isLoadingCart, refetch: refetchCart, } = useFetchCurrentCart();
23
+ const { data: session } = useFetchSession();
25
24
  const { data: countries, isLoading: isLoadingCountries } = useFetchCountries({
26
- enabled: hasNo(cart?.billTo?.address1),
25
+ enabled: hasNo(cart?.billTo?.address1) || Boolean(session?.isGuest),
27
26
  });
28
- const { data: session } = useFetchSession();
29
27
  const { data: fulfillmentMethods, isLoading: isLoadingFulfillmentMethods } = useFetchFulfillmentMethodsForCurrentCart();
30
28
  const { isLoading: isPatchingSession, mutate: patchSession } = usePatchSession();
31
29
  const { error: errorPatchBillingAddress, isError, isLoading: isPatching, isSuccess, mutate: patchShippingDetails, } = usePatchShippingDetails();
30
+ const isAuthenticated = session?.isAuthenticated;
32
31
  const isLoading = isLoadingCart || isLoadingCountries || isLoadingFulfillmentMethods;
33
32
  const { isNavigating, navigate } = useNavigate();
34
33
  const isPickup = cart?.fulfillmentMethod === 'PickUp';
@@ -1,29 +1,30 @@
1
1
  import { QueryClient } from '@tanstack/react-query';
2
- export type InferPromiseResult<T> = T extends (...args: any) => Promise<infer TResult> ? TResult : never;
3
- interface UseAwaitableMutationArgs<T extends (...args: any) => Promise<TResult>, TResult = InferPromiseResult<T>> {
2
+ export type OnError<T extends (...args: any) => Promise<unknown>> = (args: {
3
+ args: Parameters<T>;
4
+ error: unknown;
5
+ queryClient: QueryClient;
6
+ }) => void;
7
+ export type OnSuccess<T extends (...args: any) => Promise<TResult>, TResult = Awaited<ReturnType<T>>> = (args: {
8
+ args: Parameters<T>;
9
+ data: TResult;
10
+ queryClient: QueryClient;
11
+ }) => void;
12
+ export type OnComplete<T extends (...args: any) => Promise<TResult>, TResult = Awaited<ReturnType<T>>> = (args: {
13
+ args: Parameters<T>;
14
+ data: TResult | undefined;
15
+ error: unknown | undefined;
16
+ queryClient: QueryClient;
17
+ }) => void;
18
+ export interface UseAwaitableMutationArgs<T extends (...args: any) => Promise<TResult>, TResult = Awaited<ReturnType<T>>> {
4
19
  mutationFn: T;
5
- onComplete?: (args: {
6
- args: Parameters<T>;
7
- data: TResult | undefined;
8
- error: unknown | undefined;
9
- queryClient: QueryClient;
10
- }) => void;
11
- onError?: (args: {
12
- args: Parameters<T>;
13
- error: unknown;
14
- queryClient: QueryClient;
15
- }) => void;
16
- onSuccess?: (args: {
17
- args: Parameters<T>;
18
- data: TResult;
19
- queryClient: QueryClient;
20
- }) => void;
20
+ onComplete?: OnComplete<T, TResult>;
21
+ onError?: OnError<T>;
22
+ onSuccess?: OnSuccess<T, TResult>;
21
23
  }
22
- export declare function useAwaitableMutation<T extends (...args: any) => Promise<TResult>, TResult = InferPromiseResult<T>>({ mutationFn, onComplete, onError, onSuccess, }: UseAwaitableMutationArgs<T, TResult>): {
24
+ export declare function useAwaitableMutation<T extends (...args: any) => Promise<TResult>, TResult = Awaited<ReturnType<T>>>({ mutationFn, onComplete, onError, onSuccess, }: UseAwaitableMutationArgs<T, TResult>): {
23
25
  error: unknown;
24
26
  isError: boolean;
25
27
  isLoading: boolean;
26
28
  isSuccess: boolean;
27
29
  mutate: (...args: Parameters<T>) => Promise<TResult>;
28
30
  };
29
- export {};
@@ -1,6 +1,4 @@
1
- export declare function usePatchCart({ skipInvalidation, }?: {
2
- skipInvalidation?: boolean;
3
- }): {
1
+ export declare function usePatchCart(): {
4
2
  error: unknown;
5
3
  isError: boolean;
6
4
  isLoading: boolean;
@@ -2,15 +2,13 @@ import { useCallback } from 'react';
2
2
  import { useAwaitableMutation } from '../../../shared/hooks/use-awaitable-mutation.js';
3
3
  import { patchCart } from '../../services/cart-service.js';
4
4
 
5
- function usePatchCart({ skipInvalidation = false, } = {}) {
5
+ function usePatchCart() {
6
6
  const onError = useCallback(({ args: [{ cart }], queryClient }) => {
7
7
  queryClient.invalidateQueries({ queryKey: ['carts', cart.id] });
8
8
  }, []);
9
- const onSuccess = useCallback(({ args: [{ cart }], queryClient }) => {
10
- if (skipInvalidation)
11
- return;
12
- queryClient.removeQueries({ queryKey: ['carts', cart.id] });
13
- }, [skipInvalidation]);
9
+ const onSuccess = useCallback(({ args: [{ cart }], data, queryClient }) => {
10
+ queryClient.setQueryData(['carts', cart.id], data);
11
+ }, []);
14
12
  return useAwaitableMutation({
15
13
  mutationFn: patchCart,
16
14
  onError,
@@ -6,5 +6,5 @@ export declare const usePlaceOrder: () => {
6
6
  mutate: (args_0: {
7
7
  cart: import("../../model/storefront.model").CartModel;
8
8
  isPending?: boolean;
9
- }) => Promise<any>;
9
+ }) => Promise<import("../../model/storefront.model").CartModel>;
10
10
  };
@@ -3,15 +3,16 @@ import { useAwaitableMutation } from '../../../shared/hooks/use-awaitable-mutati
3
3
  import { placeOrder } from '../../services/cart-service.js';
4
4
 
5
5
  const usePlaceOrder = () => {
6
- const onComplete = useCallback(({ args: [{ cart }], queryClient }) => {
7
- queryClient.removeQueries({ queryKey: ['carts', cart.id] });
6
+ const onSuccess = useCallback(({ data: cart, queryClient }) => {
7
+ queryClient.invalidateQueries({ queryKey: ['carts', 'current'] });
8
+ queryClient.setQueryData(['carts', cart.id], cart);
8
9
  }, []);
9
- const onSuccess = useCallback(({ data: updatedCart, queryClient }) => {
10
- queryClient.removeQueries({ queryKey: ['carts', updatedCart.id] });
10
+ const onError = useCallback(({ queryClient }) => {
11
+ queryClient.invalidateQueries({ queryKey: ['carts'] });
11
12
  }, []);
12
13
  return useAwaitableMutation({
13
14
  mutationFn: placeOrder,
14
- onComplete,
15
+ onError,
15
16
  onSuccess,
16
17
  });
17
18
  };
@@ -37,16 +37,16 @@ async function patchCartLineById({ cartLine, cartLineId, }) {
37
37
  });
38
38
  }
39
39
  async function patchCart({ cart, }) {
40
- await request({
40
+ const { body } = await request({
41
41
  body: cart,
42
42
  credentials: 'include',
43
43
  headers: {
44
44
  'Content-Type': 'application/json',
45
45
  },
46
46
  method: 'PATCH',
47
- url: `${config.SHOP_API_URL}/api/v1/carts/current`,
47
+ url: `${config.BFF_API_URL}/api/v1/carts/current`,
48
48
  });
49
- return await fetchCart(cart);
49
+ return body;
50
50
  }
51
51
  async function deleteCurrentCart() {
52
52
  const { body } = await request({
@@ -103,16 +103,16 @@ async function placeOrder({ cart, isPending, }) {
103
103
  : isPending
104
104
  ? 'PendingPaymentValidation'
105
105
  : 'Submitted';
106
- await request({
106
+ const { body } = await request({
107
107
  body: { ...cart, status: newStatus },
108
108
  credentials: 'include',
109
109
  headers: {
110
110
  'Content-Type': 'application/json',
111
111
  },
112
112
  method: 'PATCH',
113
- url: `${config.SHOP_API_URL}/api/v1/carts/current`,
113
+ url: `${config.BFF_API_URL}/api/v1/carts/current`,
114
114
  });
115
- return await fetchCart(cart);
115
+ return body;
116
116
  }
117
117
  async function saveCartForLater({ cart }) {
118
118
  // USER NEEDS TO BE LOGGED IN
@@ -123,7 +123,7 @@ async function saveCartForLater({ cart }) {
123
123
  'Content-Type': 'application/json',
124
124
  },
125
125
  method: 'PATCH',
126
- url: `${config.SHOP_API_URL}/api/v1/carts/current`,
126
+ url: `${config.BFF_API_URL}/api/v1/carts/current`,
127
127
  });
128
128
  return body;
129
129
  }
@@ -1,4 +1,4 @@
1
- interface DPRSrcSet {
1
+ export interface DPRSrcSet {
2
2
  1: string;
3
3
  2: string;
4
4
  3: string;
@@ -24,4 +24,3 @@ export interface ResponsiveImageType {
24
24
  sm: DPRSrcSet;
25
25
  }
26
26
  export declare function isResponsiveImage(image: ImageType | ResponsiveImageType | undefined): image is ResponsiveImageType;
27
- export {};
package/dist/styles.css CHANGED
@@ -4928,7 +4928,7 @@ button.swiper-pagination-bullet {
4928
4928
  }
4929
4929
 
4930
4930
  .header-layout-module-VlTuk .header-layout-module-oKPyL {
4931
- width: var(--space-100);
4931
+ inline-size: min(var(--space-100), 100%);
4932
4932
  justify-self: center;
4933
4933
  }
4934
4934
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonic-equipment/ui",
3
- "version": "136.0.0",
3
+ "version": "137.0.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "engines": {