@sonic-equipment/ui 134.0.0 → 136.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/address/address.d.ts +5 -2
- package/dist/address/address.js +3 -2
- package/dist/algolia/algolia-initialization.js +2 -1
- package/dist/algolia/algolia-insights-provider.js +3 -3
- package/dist/algolia/algolia-searchclient-offline.js +3 -2
- package/dist/algolia/use-algolia-insights.js +24 -23
- package/dist/buttons/link/link.d.ts +2 -1
- package/dist/buttons/link/link.js +4 -2
- package/dist/collapsables/accordion/accordion-item.d.ts +2 -1
- package/dist/collapsables/accordion/accordion-item.js +13 -4
- package/dist/exports.d.ts +7 -0
- package/dist/footer/footer.d.ts +9 -0
- package/dist/footer/footer.js +14 -0
- package/dist/footer/footer.model.d.ts +18 -0
- package/dist/footer/footer.module.css.js +3 -0
- package/dist/header/hamburger-button/hamburger-button.d.ts +6 -0
- package/dist/header/hamburger-button/hamburger-button.js +14 -0
- package/dist/header/hamburger-button/hamburger-button.module.css.js +3 -0
- package/dist/header/header-layout/header-layout.d.ts +9 -0
- package/dist/header/header-layout/header-layout.js +8 -0
- package/dist/header/header-layout/header-layout.module.css.js +3 -0
- package/dist/header/sonic-logo/sonic-logo.d.ts +5 -0
- package/dist/header/sonic-logo/sonic-logo.js +11 -0
- package/dist/header/sonic-logo/sonic-logo.module.css.js +3 -0
- package/dist/index.js +7 -0
- package/dist/intl/translation-id.d.ts +1 -1
- package/dist/intl/utils.js +2 -1
- package/dist/logging/logger.d.ts +11 -0
- package/dist/logging/logger.js +22 -0
- package/dist/logging/use-log-error.d.ts +1 -0
- package/dist/logging/use-log-error.js +12 -0
- package/dist/notifications/announcements/announcement-provider.js +3 -6
- package/dist/pages/checkout/components/billing-and-invoice-information.js +1 -1
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +1 -1
- package/dist/pages/checkout/payment-page/components/adyen-payment.js +34 -24
- package/dist/pages/checkout/payment-page/components/payment.js +29 -17
- package/dist/pages/checkout/payment-page/payment-page-content.js +1 -1
- package/dist/pages/checkout/shipping-page/components/edit-address.d.ts +3 -2
- package/dist/pages/checkout/shipping-page/components/edit-address.js +5 -5
- package/dist/pages/checkout/shipping-page/components/readonly-address.js +25 -1
- package/dist/pages/checkout/shipping-page/shipping-page-content.d.ts +2 -1
- package/dist/pages/checkout/shipping-page/shipping-page-content.js +2 -2
- package/dist/pages/checkout/shipping-page/shipping-page.js +3 -2
- package/dist/pages/product/search-result-page/search-results-page.js +1 -1
- package/dist/shared/ga/data-layer.js +3 -2
- package/dist/shared/providers/global-state-provider.js +3 -5
- package/dist/shared/utils/debug.d.ts +2 -0
- package/dist/shared/utils/debug.js +21 -0
- package/dist/shared/utils/environment.js +4 -2
- package/dist/styles.css +242 -3
- package/package.json +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef
|
|
3
|
+
import { useRef } from 'react';
|
|
4
4
|
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
|
5
5
|
import { useCultureCode } from '../../intl/use-culture-code.js';
|
|
6
|
+
import { useLogError } from '../../logging/use-log-error.js';
|
|
6
7
|
import { useFetchAnnouncements } from '../../shared/api/bff/hooks/use-fetch-announcements.js';
|
|
7
8
|
import { useLocalStorage } from '../../shared/hooks/use-local-storage.js';
|
|
8
9
|
import { ConnectedAnnouncement } from './connected-announcement.js';
|
|
@@ -14,11 +15,7 @@ function AnnouncementProvider() {
|
|
|
14
15
|
const { data: announcements, error } = useFetchAnnouncements({
|
|
15
16
|
cultureCode,
|
|
16
17
|
});
|
|
17
|
-
|
|
18
|
-
if (!error)
|
|
19
|
-
return;
|
|
20
|
-
console.error(error);
|
|
21
|
-
}, [error]);
|
|
18
|
+
useLogError(error);
|
|
22
19
|
const [dismissedIds, setDismissedIds] = useLocalStorage('dismissedAnnouncementIds', []);
|
|
23
20
|
const filteredAnnouncements = announcements?.filter(({ id }) => !dismissedIds.includes(id));
|
|
24
21
|
return (jsx(TransitionGroup, { className: styles['announcement-provider'], children: filteredAnnouncements?.map(announcement => (jsx(CSSTransition, { classNames: {
|
|
@@ -6,7 +6,7 @@ import styles from './billing-and-invoice-information.module.css.js';
|
|
|
6
6
|
|
|
7
7
|
function BillingAndInvoiceInformation({ billToAddress, shipToAddress, }) {
|
|
8
8
|
const t = useFormattedMessage();
|
|
9
|
-
return (jsxs("div", { className: styles['billing-and-invoice-information'], children: [jsx("section", { className: styles.section, children: jsx(InfoDisplay, { id: "billing-address", label: t('Billing address'), value: jsx(Address, {
|
|
9
|
+
return (jsxs("div", { className: styles['billing-and-invoice-information'], children: [jsx("section", { className: styles.section, children: jsx(InfoDisplay, { id: "billing-address", label: t('Billing address'), value: jsx(Address, { address: billToAddress, "data-test-selector": "orderConfirmationBillingInformation" }) }) }), jsx("section", { className: styles.section, children: jsx(InfoDisplay, { id: "shipping-address", label: t('Shipping address'), value: jsx(Address, { address: shipToAddress, "data-test-selector": "orderConfirmationShippingInformation" }) }) })] }));
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export { BillingAndInvoiceInformation };
|
|
@@ -40,7 +40,7 @@ function OrderConfirmationPageContent({ cart, }) {
|
|
|
40
40
|
},
|
|
41
41
|
});
|
|
42
42
|
return (jsx(Page, { breadCrumb: [{ href: CHECKOUT_PATHS.HOME, label: t('Home') }], title: t('Order confirmation'), children: jsx(CheckoutPageLayout, { actions: {
|
|
43
|
-
primary: (jsx(RouteButton, { withArrow: true, "data-test-selector": "
|
|
43
|
+
primary: (jsx(RouteButton, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_continueShopping", href: "/", children: jsx(FormattedMessage, { id: "Continue shopping" }) })),
|
|
44
44
|
secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(RouteButton, { color: "secondary", onClick: () => {
|
|
45
45
|
saveCartForLater.mutate({ cart });
|
|
46
46
|
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })), jsx(PrintButton, {})] })),
|
|
@@ -42,34 +42,44 @@ function AdyenPayment({ amount, cartId, countryCode, currencyCode, customerId, d
|
|
|
42
42
|
if (!state.details.redirectResult) {
|
|
43
43
|
return onError(new Error('No redirectResult'), null);
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
try {
|
|
46
|
+
const result = await getAdyenPaymentDetails({
|
|
47
|
+
redirectResult: state.details.redirectResult,
|
|
48
|
+
});
|
|
49
|
+
if (amount.toFixed(2).replaceAll(/[,.]/gi, '') !== adyenAmount)
|
|
50
|
+
return onError(new Error('Invalid amount'), result);
|
|
51
|
+
if (customerId !== adyenCustomerId)
|
|
52
|
+
return onError(new Error('Invalid customer'), result);
|
|
53
|
+
return handlePaymentResponse(result, onComplete, onError);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return onError(error, null);
|
|
57
|
+
}
|
|
53
58
|
}),
|
|
54
59
|
onSubmit: (async (state, _component) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
state.data.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (result.action
|
|
68
|
-
|
|
60
|
+
try {
|
|
61
|
+
dropinDivRef.current?.classList.add(styles.loading);
|
|
62
|
+
if (state.data.paymentMethod.type === 'paybybank') {
|
|
63
|
+
state.data.countryCode = countryCode;
|
|
64
|
+
}
|
|
65
|
+
const result = await postAdyenPayment({
|
|
66
|
+
currencyCode,
|
|
67
|
+
data: state.data,
|
|
68
|
+
orderAmount,
|
|
69
|
+
returnUrl,
|
|
70
|
+
webOrderNumber: adyenSession.webOrderNumber,
|
|
71
|
+
});
|
|
72
|
+
if (result.action) {
|
|
73
|
+
if (result.action.type === 'redirect') {
|
|
74
|
+
return handleRedirectPaymentAction(result);
|
|
75
|
+
}
|
|
76
|
+
return onError(new Error('Invalid payment response'), result);
|
|
69
77
|
}
|
|
70
|
-
return
|
|
78
|
+
return handlePaymentResponse(result, onComplete, onError);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return onError(error, null);
|
|
71
82
|
}
|
|
72
|
-
return handlePaymentResponse(result, onComplete, onError);
|
|
73
83
|
}),
|
|
74
84
|
session: {
|
|
75
85
|
...adyenSession,
|
|
@@ -12,7 +12,9 @@ import { TextField } from '../../../../forms/text-field/text-field.js';
|
|
|
12
12
|
import { InfoIconTooltip } from '../../../../info-icon-tooltip/info-icon-tooltip.js';
|
|
13
13
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
14
14
|
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
15
|
+
import { logger } from '../../../../logging/logger.js';
|
|
15
16
|
import { usePatchSession } from '../../../../shared/api/storefront/hooks/authentication/use-patch-session.js';
|
|
17
|
+
import { useInvalidateCurrentCart } from '../../../../shared/api/storefront/hooks/cart/use-invalidate-current-cart.js';
|
|
16
18
|
import { usePatchCart } from '../../../../shared/api/storefront/hooks/cart/use-patch-cart.js';
|
|
17
19
|
import { usePlaceOrder } from '../../../../shared/api/storefront/hooks/cart/use-place-order.js';
|
|
18
20
|
import { useInvalidateAdyen } from '../../../../shared/api/storefront/hooks/payment/use-invalidate-adyen.js';
|
|
@@ -27,10 +29,13 @@ import styles from './payment.module.css.js';
|
|
|
27
29
|
|
|
28
30
|
function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete, onProcessing, onValidating, }) {
|
|
29
31
|
const { createEcommerceEvent, dataLayer } = useDataLayer();
|
|
30
|
-
const { isLoading: isPatchingCart, mutate: patchCart } = usePatchCart(
|
|
32
|
+
const { isLoading: isPatchingCart, mutate: patchCart } = usePatchCart({
|
|
33
|
+
skipInvalidation: true,
|
|
34
|
+
});
|
|
31
35
|
const { isLoading: isPatchingSession } = usePatchSession();
|
|
32
36
|
const { isLoading: isPlacingCart, mutate: placeOrder } = usePlaceOrder();
|
|
33
37
|
const { sendPurchaseEventFromPaymentPage } = useAlgoliaInsights();
|
|
38
|
+
const invalidateCurrentCart = useInvalidateCurrentCart();
|
|
34
39
|
const dropinRef = useRef(null);
|
|
35
40
|
const [paymentError, setPaymentError] = useState();
|
|
36
41
|
const [apiError, setAPIError] = useState();
|
|
@@ -151,7 +156,7 @@ function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete,
|
|
|
151
156
|
if (isAdyenPayment) {
|
|
152
157
|
/* Adyen Payment */
|
|
153
158
|
if (!dropinRef.current) {
|
|
154
|
-
|
|
159
|
+
logger.warn('Adyen Dropin not ready');
|
|
155
160
|
return;
|
|
156
161
|
}
|
|
157
162
|
dropinRef.current.showValidation();
|
|
@@ -168,20 +173,26 @@ function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete,
|
|
|
168
173
|
requestedDeliveryDate: formData.get('deliveryDate')?.toString(),
|
|
169
174
|
};
|
|
170
175
|
try {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
176
|
+
try {
|
|
177
|
+
cartRef.current = await patchCart({
|
|
178
|
+
cart: updatedCart,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
setAPIError(error);
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
dropinRef.current.submit();
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
setPaymentError(error);
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
181
192
|
}
|
|
182
193
|
catch (error) {
|
|
183
|
-
|
|
184
|
-
|
|
194
|
+
logger.error(error);
|
|
195
|
+
invalidateCurrentCart();
|
|
185
196
|
}
|
|
186
197
|
}
|
|
187
198
|
else {
|
|
@@ -196,8 +207,9 @@ function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete,
|
|
|
196
207
|
return onPaymentComplete({ cartId: cart.trackId });
|
|
197
208
|
}
|
|
198
209
|
catch (error) {
|
|
199
|
-
|
|
210
|
+
logger.error(error);
|
|
200
211
|
setPaymentError(error);
|
|
212
|
+
invalidateCurrentCart();
|
|
201
213
|
}
|
|
202
214
|
}
|
|
203
215
|
}
|
|
@@ -224,7 +236,7 @@ function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete,
|
|
|
224
236
|
return onPaymentComplete({ cartId: cart.trackId });
|
|
225
237
|
}
|
|
226
238
|
catch (error) {
|
|
227
|
-
|
|
239
|
+
logger.error(error);
|
|
228
240
|
setAPIError(error);
|
|
229
241
|
}
|
|
230
242
|
}, [onPaymentComplete, onPlaceOrderCompleted, placeOrder]);
|
|
@@ -232,7 +244,7 @@ function Payment({ atp, cart: _cart, form, onError: _onError, onPaymentComplete,
|
|
|
232
244
|
invalidateAdyen();
|
|
233
245
|
// invalidateCurrentCart()
|
|
234
246
|
setPaymentError(error);
|
|
235
|
-
|
|
247
|
+
logger.error(error);
|
|
236
248
|
_onError?.(error, result);
|
|
237
249
|
}, [_onError, invalidateAdyen]);
|
|
238
250
|
return (jsxs(Form, { className: styles['payment-form'], "data-test-selector": "paymentForm", id: form, onSubmit: e => {
|
|
@@ -22,7 +22,7 @@ function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing, isValidat
|
|
|
22
22
|
label: t('Review and payment'),
|
|
23
23
|
},
|
|
24
24
|
], title: t('Review and payment'), children: jsxs(CheckoutPageLayout, { actions: {
|
|
25
|
-
primary: (jsx(Button, { withArrow: true, "data-test-selector": "
|
|
25
|
+
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_placeOrder", form: formId, isDisabled: isProcessing, isLoading: isProcessing ? (jsx(FormattedMessage, { id: "Processing" })) : isValidating ? (jsx(FormattedMessage, { id: "Validating" })) : (false), type: "submit", children: jsx(FormattedMessage, { id: "Pay" }) })),
|
|
26
26
|
}, mobileSummary: jsx(CartTotalsSummary, { totalAmount: cart.orderGrandTotalDisplay }), overview: jsx(CartTotals, { deliveryDate: hasAtp ? undefined : cart.requestedDeliveryDate, fulfillmentMethod: cart.fulfillmentMethod, isPayByInvoice: (cart.paymentOptions?.paymentMethods?.length || 1) <= 1 &&
|
|
27
27
|
cart.paymentMethod?.name === 'PBI', shippingCost: cart.shippingAndHandlingDisplay, subtotal: cart.orderSubTotalDisplay, tax: cart.totalTaxDisplay, total: cart.orderGrandTotalDisplay, vatPercentage: cart.cartLines?.[0]?.pricing?.vatRate || 0 }), children: [jsx(CheckoutPageSection, { hasBorder: false, title: jsx(FormattedMessage, { id: "Payment" }), children: jsx(CheckoutPageSectionContent, { children: jsx(Payment, { atp: atp, cart: cart, form: formId, onPaymentComplete: onPaymentComplete, onProcessing: setIsProcessing, onValidating: setIsValidating }) }) }), jsx(CheckoutPageSection, { hasBorder: false, title: jsx(FormattedMessage, { id: "Order" }), children: jsx(CheckoutPageSectionContent, { stretch: true, children: jsx(OrderLineList, { children: cart.cartLines?.map(cartLine => (jsx(OrderLineCard, { deliveryDate: cartLine.atp?.date, href: cartLine.productUri, image: {
|
|
28
28
|
fit: 'contain',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CountryModel } from '../../../../shared/api/storefront/model/storefront.model';
|
|
1
|
+
import { BillToModel, CountryModel } from '../../../../shared/api/storefront/model/storefront.model';
|
|
2
2
|
export declare const EDIT_ADDRESS_FORM_ID = "billToForm";
|
|
3
3
|
interface Address {
|
|
4
4
|
address1: string;
|
|
@@ -13,7 +13,8 @@ interface Address {
|
|
|
13
13
|
phone: string;
|
|
14
14
|
postalCode: string;
|
|
15
15
|
}
|
|
16
|
-
export declare function EditAddresses({ countries, isLoading, isPickup, onSubmit, }: {
|
|
16
|
+
export declare function EditAddresses({ billTo, countries, isLoading, isPickup, onSubmit, }: {
|
|
17
|
+
billTo: BillToModel | undefined | null;
|
|
17
18
|
countries: CountryModel[];
|
|
18
19
|
isLoading: boolean;
|
|
19
20
|
isPickup: boolean;
|
|
@@ -15,10 +15,10 @@ import { SonicAddress } from './sonic-address.js';
|
|
|
15
15
|
import styles from './edit-address.module.css.js';
|
|
16
16
|
|
|
17
17
|
const EDIT_ADDRESS_FORM_ID = 'billToForm';
|
|
18
|
-
function EditAddresses({ countries, isLoading, isPickup, onSubmit, }) {
|
|
18
|
+
function EditAddresses({ billTo, countries, isLoading, isPickup, onSubmit, }) {
|
|
19
19
|
const t = useFormattedMessage();
|
|
20
|
-
const [companyName, setCompanyName] = useState('');
|
|
21
|
-
const [lastName, setLastName] = useState('');
|
|
20
|
+
const [companyName, setCompanyName] = useState(billTo?.companyName || '');
|
|
21
|
+
const [lastName, setLastName] = useState(billTo?.lastName || '');
|
|
22
22
|
const { data: cart } = useFetchCurrentCart();
|
|
23
23
|
return (jsxs(Fragment, { children: [jsx(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: jsx(CheckoutPageSectionContent, { children: jsxs(Form, { className: styles.form, "data-test-selector": "billToAddressForm", id: EDIT_ADDRESS_FORM_ID, onSubmit: e => {
|
|
24
24
|
e.preventDefault();
|
|
@@ -43,7 +43,7 @@ function EditAddresses({ countries, isLoading, isPickup, onSubmit, }) {
|
|
|
43
43
|
},
|
|
44
44
|
notes: formData.get('notes')?.toString() || '',
|
|
45
45
|
});
|
|
46
|
-
}, children: [jsx(TextField, { 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, { isDisabled: isLoading, label: t('Company name'), name: "companyName", onChange: setCompanyName, showLabel: true, value: companyName }), jsx(TextField, { isDisabled: isLoading, label: t('Attention'), name: "attention", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, isDisabled: isLoading, label: `${t('Address')} 1`, maxLength: 30, minLength: 3, name: "address1", showLabel: true }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isDisabled: isLoading, label: `${t('Address')} 2`, maxLength: 30, minLength: 3, name: "address2", showLabel: true }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isDisabled: isLoading, label: `${t('Address')} 3`, maxLength: 30, minLength: 3, name: "address3", showLabel: true }) }), jsx(TextField, { isRequired: true, isDisabled: isLoading, label: t('Postal Code'), maxLength: 10, minLength: 4, name: "postalCode", showLabel: true }), jsx(TextField, { isRequired: true, 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" }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, isDisabled: isLoading, label: t('Phone'), name: "phone", showLabel: true, validate: value => {
|
|
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
47
|
if (!value)
|
|
48
48
|
return value;
|
|
49
49
|
return (validatePhone(value) ||
|
|
@@ -53,7 +53,7 @@ function EditAddresses({ countries, isLoading, isPickup, onSubmit, }) {
|
|
|
53
53
|
return value;
|
|
54
54
|
return (validateEmail(value) ||
|
|
55
55
|
t('Please enter a valid e-mail address'));
|
|
56
|
-
} }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isDisabled: isLoading, isMultiline: true, label: t('Add order notes'), name: "notes", rows: 3, showLabel: true }) })] }) }) }), jsx(CheckoutPageSection, { title: jsx(FormattedMessage, { id: isPickup ? 'Pickup address' : 'Shipping address' }), children: jsx(CheckoutPageSectionContent, { children: jsx(Fragment, { children: isPickup ? (jsx(SonicAddress, {})) : (jsxs("div", { className: styles['use-invoice-checkbox'], children: [jsx(Checkbox, { "data-test-selector": "checkboxUseBillingAddress", isDisabled: true, isSelected: true, children: jsx(FormattedMessage, { id: "Use billing address" }) }), jsx(InfoIconTooltip, { variant: "stroke", children: t('Changing your address is currently not possible. Please contact customer support to change your address.') })] })) }) }) })] }));
|
|
56
|
+
} }) }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { defaultValue: cart?.notes, isDisabled: isLoading, isMultiline: true, label: t('Add order notes'), name: "notes", rows: 3, showLabel: true }) })] }) }) }), jsx(CheckoutPageSection, { title: jsx(FormattedMessage, { id: isPickup ? 'Pickup address' : 'Shipping address' }), children: jsx(CheckoutPageSectionContent, { children: jsx(Fragment, { children: isPickup ? (jsx(SonicAddress, {})) : (jsxs("div", { className: styles['use-invoice-checkbox'], children: [jsx(Checkbox, { "data-test-selector": "checkboxUseBillingAddress", isDisabled: true, isSelected: true, children: jsx(FormattedMessage, { id: "Use billing address" }) }), jsx(InfoIconTooltip, { variant: "stroke", children: t('Changing your address is currently not possible. Please contact customer support to change your address.') })] })) }) }) })] }));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export { EDIT_ADDRESS_FORM_ID, EditAddresses };
|
|
@@ -22,7 +22,31 @@ function ReadOnlyAddresses({ billTo, isLoading, isPickup, notes, onSubmit, shipT
|
|
|
22
22
|
onSubmit({
|
|
23
23
|
notes: formData.get('notes')?.toString() || '',
|
|
24
24
|
});
|
|
25
|
-
}, children: [jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: [jsx(CheckoutPageSectionLink, { children: jsxs(RouteLink, { color: "secondary", href: ACCOUNT_ADDRESSES_PATH, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit billing address" }), " >"] }) }), jsxs(CheckoutPageSectionContent, { children: [billTo && (jsx(Address, {
|
|
25
|
+
}, children: [jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: [jsx(CheckoutPageSectionLink, { children: jsxs(RouteLink, { color: "secondary", href: ACCOUNT_ADDRESSES_PATH, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit billing address" }), " >"] }) }), jsxs(CheckoutPageSectionContent, { children: [billTo && (jsx(Address, { address: {
|
|
26
|
+
address1: billTo.address1,
|
|
27
|
+
address2: billTo.address2,
|
|
28
|
+
address3: billTo.address3,
|
|
29
|
+
city: billTo.city,
|
|
30
|
+
companyName: billTo.companyName,
|
|
31
|
+
country: billTo.country?.name,
|
|
32
|
+
email: billTo.email,
|
|
33
|
+
firstName: billTo.firstName,
|
|
34
|
+
lastName: billTo.lastName,
|
|
35
|
+
phone: billTo.phone,
|
|
36
|
+
postalCode: billTo.postalCode,
|
|
37
|
+
} })), jsx("div", { className: styles.notes, children: jsx(TextField, { defaultValue: notes, isDisabled: isLoading, isMultiline: true, label: t('Add order notes'), name: "notes", rows: 3, showLabel: true }) })] })] }), jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: isPickup ? 'Pickup address' : 'Shipping address' }), children: [!isPickup && (jsx(CheckoutPageSectionLink, { children: jsxs(RouteLink, { color: "secondary", href: ACCOUNT_ADDRESSES_PATH, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit shipping address" }), " >"] }) })), jsx(CheckoutPageSectionContent, { children: isPickup ? (jsx(SonicAddress, {})) : (jsxs(Fragment, { children: [jsx(Checkbox, { className: styles['use-invoice-checkbox'], "data-test-selector": "checkboxUseBillingAddress", isDisabled: true, isSelected: true, children: jsx(FormattedMessage, { id: "Use billing address" }) }), shipTo && (jsx(Address, { address: {
|
|
38
|
+
address1: shipTo.address1,
|
|
39
|
+
address2: shipTo.address2,
|
|
40
|
+
address3: shipTo.address3,
|
|
41
|
+
city: shipTo.city,
|
|
42
|
+
companyName: shipTo.companyName,
|
|
43
|
+
country: shipTo.country?.name,
|
|
44
|
+
email: shipTo.email,
|
|
45
|
+
firstName: shipTo.firstName,
|
|
46
|
+
lastName: shipTo.lastName,
|
|
47
|
+
phone: shipTo.phone,
|
|
48
|
+
postalCode: shipTo.postalCode,
|
|
49
|
+
} }))] })) })] })] }));
|
|
26
50
|
}
|
|
27
51
|
|
|
28
52
|
export { ReadOnlyAddresses };
|
|
@@ -5,10 +5,11 @@ export interface ShippingPageContentProps {
|
|
|
5
5
|
editAddress: ReactNode;
|
|
6
6
|
errorPatchBillingAddress?: unknown;
|
|
7
7
|
fulfillmentMethods: string[] | undefined;
|
|
8
|
+
isGuest: boolean;
|
|
8
9
|
isLoadingFulfillmentMethods: boolean;
|
|
9
10
|
isPatching: boolean;
|
|
10
11
|
isPatchingSession: boolean;
|
|
11
12
|
onChangeFulfillmentMethod: (value: string) => void;
|
|
12
13
|
readOnlyAddress: ReactNode;
|
|
13
14
|
}
|
|
14
|
-
export declare function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulfillmentMethods, isLoadingFulfillmentMethods, isPatching, isPatchingSession, onChangeFulfillmentMethod, readOnlyAddress, }: ShippingPageContentProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulfillmentMethods, isGuest, isLoadingFulfillmentMethods, isPatching, isPatchingSession, onChangeFulfillmentMethod, readOnlyAddress, }: ShippingPageContentProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,7 +14,7 @@ import { CheckoutPageSectionContent } from '../layouts/checkout-page-layout/comp
|
|
|
14
14
|
import { EDIT_ADDRESS_FORM_ID } from './components/edit-address.js';
|
|
15
15
|
import styles from './shipping-page.module.css.js';
|
|
16
16
|
|
|
17
|
-
function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulfillmentMethods, isLoadingFulfillmentMethods, isPatching, isPatchingSession, onChangeFulfillmentMethod, readOnlyAddress, }) {
|
|
17
|
+
function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulfillmentMethods, isGuest, isLoadingFulfillmentMethods, isPatching, isPatchingSession, onChangeFulfillmentMethod, readOnlyAddress, }) {
|
|
18
18
|
const t = useFormattedMessage();
|
|
19
19
|
const fulfillmentMethodOptions = fulfillmentMethods?.reduce((acc, method) => ({
|
|
20
20
|
...acc,
|
|
@@ -34,7 +34,7 @@ function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulf
|
|
|
34
34
|
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutShippingCartTotalContinueButton", form: EDIT_ADDRESS_FORM_ID, isDisabled: isPatching, isLoading: isPatching || isPatchingSession ? (jsx(FormattedMessage, { id: "Updating address" })) : undefined, type: "submit", children: jsx(FormattedMessage, { id: "Continue shopping" }) })),
|
|
35
35
|
}, mobileSummary: jsx(CartTotalsSummary, { totalAmount: cart.orderGrandTotalDisplay }), overview: jsx(CartTotals, { fulfillmentMethod: fulfillmentMethods && fulfillmentMethods.length === 1
|
|
36
36
|
? cart.fulfillmentMethod
|
|
37
|
-
: undefined, shippingCost: cart.shippingAndHandlingDisplay, subtotal: cart.orderSubTotalDisplay, tax: cart.totalTaxDisplay, total: cart.orderGrandTotalDisplay, vatPercentage: cart.cartLines?.[0]?.pricing?.vatRate }), children: [jsxs(Fragment, { children: [fulfillmentMethods && fulfillmentMethods.length > 1 && (jsx(CheckoutPageSection, { hasBorder: true, title: t('Fulfillment method'), children: jsx(CheckoutPageSectionContent, { children: jsx("div", { className: styles['fulfillment-select-wrapper'], children: jsx(Select, { isRequired: true, showLabel: true, "data-test-selector": "fulfillmentMethodSelect", defaultSelectedOption: cart.fulfillmentMethod, isLoading: isLoadingFulfillmentMethods, label: t('Fulfillment method'), name: "fulfillmentMethod", onChange: onChangeFulfillmentMethod, options: fulfillmentMethodOptions || {}, variant: "solid" }) }) }) })), hasBillToAddress ? readOnlyAddress : editAddress] }), Boolean(errorPatchBillingAddress) && (jsx("div", { className: styles['error-message'], children: jsx(FormattedMessage, { id: "An unexpected error occured" }) }))] }) }));
|
|
37
|
+
: undefined, shippingCost: cart.shippingAndHandlingDisplay, subtotal: cart.orderSubTotalDisplay, tax: cart.totalTaxDisplay, total: cart.orderGrandTotalDisplay, vatPercentage: cart.cartLines?.[0]?.pricing?.vatRate }), children: [jsxs(Fragment, { children: [fulfillmentMethods && fulfillmentMethods.length > 1 && (jsx(CheckoutPageSection, { hasBorder: true, title: t('Fulfillment method'), children: jsx(CheckoutPageSectionContent, { children: jsx("div", { className: styles['fulfillment-select-wrapper'], children: jsx(Select, { isRequired: true, showLabel: true, "data-test-selector": "fulfillmentMethodSelect", defaultSelectedOption: cart.fulfillmentMethod, isLoading: isLoadingFulfillmentMethods, label: t('Fulfillment method'), name: "fulfillmentMethod", onChange: onChangeFulfillmentMethod, options: fulfillmentMethodOptions || {}, variant: "solid" }) }) }) })), hasBillToAddress && !isGuest ? readOnlyAddress : editAddress] }), Boolean(errorPatchBillingAddress) && (jsx("div", { className: styles['error-message'], children: jsx(FormattedMessage, { id: "An unexpected error occured" }) }))] }) }));
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export { ShippingPageContent };
|
|
@@ -75,13 +75,14 @@ function ShippingPage() {
|
|
|
75
75
|
if (isLoading || isNavigating || isError || isSuccess)
|
|
76
76
|
return jsx(LoadingPage, {});
|
|
77
77
|
if (!isAuthenticated ||
|
|
78
|
+
hasNo(session) ||
|
|
78
79
|
hasNo(cart) ||
|
|
79
80
|
hasNo(cart.cartLines) ||
|
|
80
81
|
cart.cartLines.length === 0 ||
|
|
81
82
|
hasNo(cart.billTo) ||
|
|
82
83
|
(hasNo(cart.billTo.address1) && hasNo(countries)))
|
|
83
84
|
return null;
|
|
84
|
-
return (jsx(ShippingPageContent, { cart: cart, editAddress: jsx(EditAddresses, { countries: countries || [], isLoading: isPatching, isPickup: isPickup, onSubmit: async ({ address, notes }) => {
|
|
85
|
+
return (jsx(ShippingPageContent, { cart: cart, editAddress: jsx(EditAddresses, { billTo: cart.billTo, countries: countries || [], isLoading: isPatching, isPickup: isPickup, onSubmit: async ({ address, notes }) => {
|
|
85
86
|
if (!cart.billTo)
|
|
86
87
|
return;
|
|
87
88
|
await patchShippingDetails({
|
|
@@ -93,7 +94,7 @@ function ShippingPage() {
|
|
|
93
94
|
cart,
|
|
94
95
|
event: { event: 'add_shipping_info' },
|
|
95
96
|
}));
|
|
96
|
-
} }), errorPatchBillingAddress: errorPatchBillingAddress, fulfillmentMethods: fulfillmentMethods, isLoadingFulfillmentMethods: isLoadingFulfillmentMethods, isPatching: isPatching, isPatchingSession: isPatchingSession, onChangeFulfillmentMethod: async (value) => {
|
|
97
|
+
} }), errorPatchBillingAddress: errorPatchBillingAddress, fulfillmentMethods: fulfillmentMethods, isGuest: session.isGuest, isLoadingFulfillmentMethods: isLoadingFulfillmentMethods, isPatching: isPatching, isPatchingSession: isPatchingSession, onChangeFulfillmentMethod: async (value) => {
|
|
97
98
|
await patchSession({
|
|
98
99
|
session: {
|
|
99
100
|
...session,
|
|
@@ -37,7 +37,7 @@ function SearchResultsPageContent({ keyword }) {
|
|
|
37
37
|
const { hits, isLoading } = useAlgoliaHits();
|
|
38
38
|
const hasHits = hits.length > 0;
|
|
39
39
|
const t = useFormattedMessage();
|
|
40
|
-
return (jsxs(Fragment, { children: [isLoading !== false && !hasHits && jsx(LoadingPage, {}), isLoading === false && !hasHits && (jsx(NoResults, { content: jsxs(
|
|
40
|
+
return (jsxs(Fragment, { children: [isLoading !== false && !hasHits && jsx(LoadingPage, {}), isLoading === false && !hasHits && (jsx(NoResults, { content: jsxs(Fragment, { children: [jsx(FormattedMessage, { id: "You could try checking the spelling of your search query" }), jsx("br", {}), jsx(FormattedMessage, { id: "Try another search" }), jsx("br", {}), jsx(FormattedMessage, { id: "Are you looking for information about our service? Please visit our customer support page" })] }), title: t("Unfortnately, We found no articles for your search '{0}'", {
|
|
41
41
|
replacementValues: { 0: keyword },
|
|
42
42
|
}) })), jsxs("div", { style: {
|
|
43
43
|
display: hasHits ? undefined : 'none',
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { logger } from '../../logging/logger.js';
|
|
2
|
+
|
|
1
3
|
const _dataLayer = [];
|
|
2
4
|
_dataLayer.push = (function (_push) {
|
|
3
5
|
return (...items) => {
|
|
4
|
-
|
|
5
|
-
console.log('dataLayer.push', items.length === 1 ? items[0] : items);
|
|
6
|
+
logger.info('dataLayer.push', items.length === 1 ? items[0] : items);
|
|
6
7
|
return _push(...items);
|
|
7
8
|
};
|
|
8
9
|
})(_dataLayer.push.bind(_dataLayer));
|
|
@@ -73,11 +73,9 @@ function useGlobalState(key, initialState) {
|
|
|
73
73
|
state.removeEventListener('stateChanged', updateState);
|
|
74
74
|
};
|
|
75
75
|
}, [state]);
|
|
76
|
-
|
|
77
|
-
state.value
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
return [rerenderState, useCallback(updateGlobalState, [updateGlobalState])];
|
|
76
|
+
const setGlobalState = useCallback((valueOrFn) => (state.value =
|
|
77
|
+
valueOrFn instanceof Function ? valueOrFn(state.value) : valueOrFn), [state]);
|
|
78
|
+
return [rerenderState, setGlobalState];
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
export { GlobalStateProvider, GlobalStateProviderContext, useGlobalState };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { logger } from '../../logging/logger.js';
|
|
2
|
+
|
|
3
|
+
const prevState = {};
|
|
4
|
+
function trackPropertyChange(name, value) {
|
|
5
|
+
if (typeof name === 'string') {
|
|
6
|
+
if (value === prevState[name]) {
|
|
7
|
+
logger.info(name, value === prevState[name]);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
logger.warn(name, value === prevState[name]);
|
|
11
|
+
}
|
|
12
|
+
prevState[name] = value;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
for (const [key, value] of Object.entries(name)) {
|
|
16
|
+
trackPropertyChange(key, value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { trackPropertyChange };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { logger } from '../../logging/logger.js';
|
|
2
|
+
|
|
1
3
|
const environments = [
|
|
2
4
|
'marketingLocal',
|
|
3
5
|
'sandbox',
|
|
@@ -26,7 +28,7 @@ function getEnvironment() {
|
|
|
26
28
|
}
|
|
27
29
|
else if (typeof window === 'undefined') {
|
|
28
30
|
environmentUrl = 'production';
|
|
29
|
-
|
|
31
|
+
logger.error('Unable to detect environment url');
|
|
30
32
|
}
|
|
31
33
|
else {
|
|
32
34
|
environmentUrl = `${window.location.hostname}:${window.location.port}`;
|
|
@@ -52,7 +54,7 @@ function getEnvironment() {
|
|
|
52
54
|
}
|
|
53
55
|
else {
|
|
54
56
|
environment = 'production';
|
|
55
|
-
|
|
57
|
+
logger.error(`Environment not detected for url ${environmentUrl}. Defaulting to production.`);
|
|
56
58
|
}
|
|
57
59
|
return environment;
|
|
58
60
|
}
|