@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.
- package/dist/config.js +2 -2
- package/dist/country-selector/country-select/country-select.d.ts +6 -0
- package/dist/country-selector/country-select/country-select.js +10 -4
- package/dist/exports.d.ts +1 -0
- package/dist/header/header.d.ts +1 -0
- package/dist/header/header.js +9 -0
- package/dist/index.js +1 -0
- package/dist/media/image/image.js +11 -4
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +7 -1
- package/dist/pages/checkout/payment-page/components/adyen-payment.js +6 -4
- package/dist/pages/checkout/payment-page/components/payment.js +1 -3
- package/dist/pages/checkout/shipping-page/components/edit-address.d.ts +1 -0
- package/dist/pages/checkout/shipping-page/components/edit-address.js +2 -1
- package/dist/pages/checkout/shipping-page/hooks/use-patch-shipping-details.d.ts +6 -2
- package/dist/pages/checkout/shipping-page/hooks/use-patch-shipping-details.js +27 -8
- package/dist/pages/checkout/shipping-page/shipping-page.js +3 -4
- package/dist/shared/api/shared/hooks/use-awaitable-mutation.d.ts +21 -20
- package/dist/shared/api/storefront/hooks/cart/use-patch-cart.d.ts +1 -3
- package/dist/shared/api/storefront/hooks/cart/use-patch-cart.js +4 -6
- package/dist/shared/api/storefront/hooks/cart/use-place-order.d.ts +1 -1
- package/dist/shared/api/storefront/hooks/cart/use-place-order.js +6 -5
- package/dist/shared/api/storefront/services/cart-service.js +7 -7
- package/dist/shared/model/image.d.ts +1 -2
- package/dist/styles.css +1 -1
- 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: '
|
|
17
|
-
BFF_API_URL: '
|
|
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
|
|
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
|
-
[
|
|
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:
|
|
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: [
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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();
|
|
@@ -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",
|
|
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<
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
3
|
-
|
|
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?:
|
|
6
|
-
|
|
7
|
-
|
|
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 =
|
|
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 {};
|
|
@@ -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(
|
|
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
|
-
|
|
11
|
-
|
|
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,
|
|
@@ -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
|
|
7
|
-
queryClient.
|
|
6
|
+
const onSuccess = useCallback(({ data: cart, queryClient }) => {
|
|
7
|
+
queryClient.invalidateQueries({ queryKey: ['carts', 'current'] });
|
|
8
|
+
queryClient.setQueryData(['carts', cart.id], cart);
|
|
8
9
|
}, []);
|
|
9
|
-
const
|
|
10
|
-
queryClient.
|
|
10
|
+
const onError = useCallback(({ queryClient }) => {
|
|
11
|
+
queryClient.invalidateQueries({ queryKey: ['carts'] });
|
|
11
12
|
}, []);
|
|
12
13
|
return useAwaitableMutation({
|
|
13
14
|
mutationFn: placeOrder,
|
|
14
|
-
|
|
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.
|
|
47
|
+
url: `${config.BFF_API_URL}/api/v1/carts/current`,
|
|
48
48
|
});
|
|
49
|
-
return
|
|
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.
|
|
113
|
+
url: `${config.BFF_API_URL}/api/v1/carts/current`,
|
|
114
114
|
});
|
|
115
|
-
return
|
|
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.
|
|
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