@sonic-equipment/ui 186.0.0 → 188.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/collapsables/accordion/accordion-item.js +2 -1
- package/dist/collapsables/accordion/accordion.module.css.js +1 -1
- package/dist/exports.d.ts +1 -0
- package/dist/footer/connected-footer.d.ts +2 -1
- package/dist/footer/connected-footer.js +9 -2
- package/dist/footer/footer.d.ts +6 -10
- package/dist/footer/footer.js +24 -18
- package/dist/footer/footer.module.css.js +1 -1
- package/dist/header/connected-header.js +9 -1
- package/dist/header/drawers/desktop-navigation-drawer.d.ts +3 -3
- package/dist/header/drawers/desktop-navigation-drawer.js +2 -4
- package/dist/header/drawers/mobile-navigation-drawer.d.ts +3 -3
- package/dist/header/drawers/mobile-navigation-drawer.js +2 -2
- package/dist/header/header.d.ts +3 -3
- package/dist/header/header.js +15 -9
- package/dist/header/link-list/navigation-link-list.d.ts +5 -5
- package/dist/header/link-list/navigation-link-list.js +10 -5
- package/dist/index.js +1 -0
- package/dist/intl/translation-id.d.ts +1 -1
- package/dist/lists/menu-list/menu-list-header.d.ts +1 -1
- package/dist/lists/menu-list/menu-list-item.d.ts +2 -2
- package/dist/lists/menu-list/menu-list-item.js +1 -1
- package/dist/lists/menu-list/menu-list.d.ts +6 -4
- package/dist/lists/menu-list/menu-list.js +3 -3
- package/dist/media/image-lightbox/image-lightbox.js +12 -2
- package/dist/media/zoom-image/zoom-image.js +6 -1
- package/dist/navigation/mobile-navigation/mobile-navigation.d.ts +3 -3
- package/dist/navigation/mobile-navigation/mobile-navigation.js +2 -2
- package/dist/navigation/panel-navigation/panel-navigation.d.ts +5 -7
- package/dist/navigation/panel-navigation/panel-navigation.js +11 -14
- package/dist/pages/checkout/payment-page/components/adyen-payment.js +8 -2
- package/dist/pages/checkout/payment-page/components/payment.d.ts +1 -2
- package/dist/pages/checkout/payment-page/components/payment.js +2 -75
- package/dist/pages/checkout/payment-page/payment-page-content.d.ts +1 -3
- package/dist/pages/checkout/payment-page/payment-page-content.js +3 -3
- package/dist/pages/checkout/payment-page/payment-page.js +1 -2
- package/dist/pages/product/product-details-page/components/product-details-panel/product-details-panel.js +1 -1
- package/dist/pages/product/product-details-page/components/product-details-panel/product-details-panel.module.css.js +1 -1
- package/dist/shared/api/bff/hooks/use-fetch-navigation-links.d.ts +1 -1
- package/dist/shared/api/bff/model/bff.model.d.ts +22 -14
- package/dist/shared/api/bff/model/bff.model.js +11 -0
- package/dist/shared/api/bff/services/bff-service.d.ts +2 -2
- package/dist/shared/api/bff/services/bff-service.js +1 -1
- package/dist/shared/data/navigation.d.ts +2 -0
- package/dist/shared/data/navigation.js +2605 -0
- package/dist/styles.css +1549 -1481
- package/package.json +1 -1
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { MenuHeader } from '../../lists/menu-list/menu-list';
|
|
3
|
+
import { NavigationLinkItem } from '../../shared/api/bff/model/bff.model';
|
|
3
4
|
export interface PanelNavigationProps {
|
|
4
5
|
allowBack?: boolean;
|
|
5
6
|
children?: ReactNode;
|
|
6
7
|
className?: string;
|
|
7
8
|
'data-test-selector'?: string;
|
|
8
|
-
header?:
|
|
9
|
-
href: string;
|
|
10
|
-
title: string;
|
|
11
|
-
};
|
|
9
|
+
header?: MenuHeader;
|
|
12
10
|
id?: string;
|
|
13
11
|
isNarrow?: boolean;
|
|
14
|
-
|
|
12
|
+
linkItems?: NavigationLinkItem[];
|
|
15
13
|
variant?: 'primary';
|
|
16
14
|
}
|
|
17
|
-
export declare function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow,
|
|
15
|
+
export declare function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow, linkItems, variant, }: PanelNavigationProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,6 +7,7 @@ import { CascadingComponentContainer } from '../../collapsables/cascading-compon
|
|
|
7
7
|
import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
8
8
|
import { MenuList } from '../../lists/menu-list/menu-list.js';
|
|
9
9
|
import { MenuListItem } from '../../lists/menu-list/menu-list-item.js';
|
|
10
|
+
import { isNavigationLinkGroup } from '../../shared/api/bff/model/bff.model.js';
|
|
10
11
|
import { multiRef } from '../../shared/utils/refs.js';
|
|
11
12
|
import styles from './panel-navigation.module.css.js';
|
|
12
13
|
|
|
@@ -18,7 +19,7 @@ const focusableSelectors = [
|
|
|
18
19
|
'select:not([disabled])',
|
|
19
20
|
'[tabindex]:not([tabindex="-1"])',
|
|
20
21
|
].join(',');
|
|
21
|
-
const NavigationMenu = forwardRef(({ allowBack, back, children, className, header, id, isNarrow,
|
|
22
|
+
const NavigationMenu = forwardRef(({ allowBack, back, children, className, header, id, isNarrow, linkItems, scrollable, variant, }, ref) => {
|
|
22
23
|
const menuRef = useRef();
|
|
23
24
|
const submenuRef = useRef(null);
|
|
24
25
|
const [selectedNavigationLink, setSelectedNavigationLink] = useState();
|
|
@@ -37,9 +38,9 @@ const NavigationMenu = forwardRef(({ allowBack, back, children, className, heade
|
|
|
37
38
|
setSelectedNavigationVisible(Boolean(selectedNavigationLink));
|
|
38
39
|
}, [selectedNavigationLink]);
|
|
39
40
|
const t = useFormattedMessage();
|
|
40
|
-
return (jsxs(Fragment, { children: [jsxs("div", { ref: multiRef(ref, menuRef), className: clsx(styles['panel'], isNarrow && styles['narrow'], className), "data-test-selector": "panelNavigation", id: id, children: [jsx(MenuList, { back: back, header: header, scrollable: scrollable, variant: variant, children:
|
|
41
|
+
return (jsxs(Fragment, { children: [jsxs("div", { ref: multiRef(ref, menuRef), className: clsx(styles['panel'], isNarrow && styles['narrow'], className), "data-test-selector": "panelNavigation", id: id, children: [jsx(MenuList, { back: back, header: header, scrollable: scrollable, variant: variant, children: linkItems?.map(link => link.type === 'link-group' && link.items.length > 0 ? (jsx(MenuListItem, { hasChildren: true, "aria-controls": `menu-${link.key}`, "data-test-selector": "panelNavigationItem", image: link.image, isSelected: selectedNavigationLink?.key === link.key, onClick: () => setSelectedNavigationLink(selectedNavigationLink?.key === link.key
|
|
41
42
|
? undefined
|
|
42
|
-
: link), children: link.
|
|
43
|
+
: link), children: link.label }, link.key)) : (jsx(MenuListItem, { "data-test-selector": "panelNavigationItem", href: link.href, image: link.image, openInNewTab: link.openInNewTab, children: link.label }, link.key))) }), children] }), jsx(CascadingComponent, { isVisible: selectedNavigationVisible, nodeRef: submenuRef, onEntered: onFocus(submenuRef), onExited: onFocus(menuRef), onUnmounted: onUnmounted, children: jsx(NavigationMenu, { ref: submenuRef, allowBack: allowBack, back: allowBack
|
|
43
44
|
? {
|
|
44
45
|
onClick: () => {
|
|
45
46
|
setSelectedNavigationVisible(false);
|
|
@@ -47,23 +48,19 @@ const NavigationMenu = forwardRef(({ allowBack, back, children, className, heade
|
|
|
47
48
|
title: header
|
|
48
49
|
? typeof header === 'string'
|
|
49
50
|
? header
|
|
50
|
-
: header.
|
|
51
|
+
: header.label
|
|
51
52
|
: t('Main menu'),
|
|
52
53
|
}
|
|
53
|
-
: undefined, header: selectedNavigationLink?.
|
|
54
|
-
? {
|
|
55
|
-
href: selectedNavigationLink.url,
|
|
56
|
-
title: selectedNavigationLink.title,
|
|
57
|
-
}
|
|
58
|
-
: selectedNavigationLink?.title, id: selectedNavigationLink?.key
|
|
54
|
+
: undefined, header: selectedNavigationLink, id: selectedNavigationLink?.key
|
|
59
55
|
? `menu-${selectedNavigationLink.key}`
|
|
60
|
-
: undefined, isNarrow: isNarrow,
|
|
61
|
-
|
|
56
|
+
: undefined, isNarrow: isNarrow, linkItems: selectedNavigationLink &&
|
|
57
|
+
isNavigationLinkGroup(selectedNavigationLink)
|
|
58
|
+
? selectedNavigationLink.items
|
|
62
59
|
: [] }, selectedNavigationLink?.key) })] }));
|
|
63
60
|
});
|
|
64
61
|
NavigationMenu.displayName = 'NavigationMenu';
|
|
65
|
-
function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow,
|
|
66
|
-
return (jsx("section", { className: clsx(styles['panel-navigation'], className), "data-test-selector": dataTestSelector, id: id, children: jsx(CascadingComponentContainer, { children: jsx("div", { className: clsx(styles['panels'], isNarrow && styles['narrow']), children: jsx(NavigationMenu, { allowBack: allowBack, className: children ? styles['top-panel'] : undefined, header: header, id: "panel-navigation-first-level", isNarrow: isNarrow,
|
|
62
|
+
function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow, linkItems, variant, }) {
|
|
63
|
+
return (jsx("section", { className: clsx(styles['panel-navigation'], className), "data-test-selector": dataTestSelector, id: id, children: jsx(CascadingComponentContainer, { children: jsx("div", { className: clsx(styles['panels'], isNarrow && styles['narrow']), children: jsx(NavigationMenu, { allowBack: allowBack, className: children ? styles['top-panel'] : undefined, header: header, id: "panel-navigation-first-level", isNarrow: isNarrow, linkItems: linkItems, scrollable: children ? false : undefined, variant: variant, children: children }) }) }) }));
|
|
67
64
|
}
|
|
68
65
|
|
|
69
66
|
export { PanelNavigation };
|
|
@@ -5,6 +5,9 @@ import AdyenCheckout from '@adyen/adyen-web';
|
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import qs from 'query-string';
|
|
7
7
|
import { useCultureCode } from '../../../../intl/use-culture-code.js';
|
|
8
|
+
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
9
|
+
import { logger } from '../../../../logging/logger.js';
|
|
10
|
+
import { Message } from '../../../../message/message.js';
|
|
8
11
|
import { useCreateAdyenSession } from '../../../../shared/api/storefront/hooks/payment/use-create-adyen-session.js';
|
|
9
12
|
import { useFetchAdyenConfig } from '../../../../shared/api/storefront/hooks/payment/use-fetch-adyen-config.js';
|
|
10
13
|
import { postAdyenPayment, getAdyenPaymentDetails } from '../../../../shared/api/storefront/services/cart-service.js';
|
|
@@ -12,6 +15,7 @@ import { parseAmount } from '../utils/parse-amount.js';
|
|
|
12
15
|
import styles from './adyen-payment.module.css.js';
|
|
13
16
|
|
|
14
17
|
function AdyenPayment({ amount, cartId, countryCode, currencyCode, customerId, dropinRef, environment, isDisabled, onComplete, onError, orderAmount, returnUrl, }) {
|
|
18
|
+
const t = useFormattedMessage();
|
|
15
19
|
const cultureCode = useCultureCode();
|
|
16
20
|
// Get and remove Adyen query string params and keep them in a ref
|
|
17
21
|
const queryStringParams = useRef(getAndRemoveAdyenQueryParams());
|
|
@@ -125,8 +129,10 @@ function AdyenPayment({ amount, cartId, countryCode, currencyCode, customerId, d
|
|
|
125
129
|
adyenAmount,
|
|
126
130
|
adyenCustomerId,
|
|
127
131
|
]);
|
|
128
|
-
if (error)
|
|
129
|
-
|
|
132
|
+
if (error) {
|
|
133
|
+
logger.error('Adyen Payment Error:', error);
|
|
134
|
+
return (jsx(Message, { type: "danger", children: t('All payment methods are unavailable at this time. Please contact customer support.') }));
|
|
135
|
+
}
|
|
130
136
|
return (jsx("div", { ref: dropinDivRef, className: clsx(Boolean(redirectResult) && styles.loading, isDisabled && styles.loading), id: "dropin" }));
|
|
131
137
|
}
|
|
132
138
|
function getAndRemoveAdyenQueryParams() {
|
|
@@ -9,7 +9,6 @@ interface PaymentProps {
|
|
|
9
9
|
cartId: string;
|
|
10
10
|
}) => void;
|
|
11
11
|
onProcessing: (processing: boolean) => void;
|
|
12
|
-
onValidatingVAT: (validating: boolean) => void;
|
|
13
12
|
}
|
|
14
|
-
export declare function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPaymentComplete, onProcessing,
|
|
13
|
+
export declare function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPaymentComplete, onProcessing, }: PaymentProps): import("react/jsx-runtime").JSX.Element;
|
|
15
14
|
export {};
|
|
@@ -18,7 +18,6 @@ import { useInvalidateCurrentCart } from '../../../../shared/api/storefront/hook
|
|
|
18
18
|
import { usePatchCart } from '../../../../shared/api/storefront/hooks/cart/use-patch-cart.js';
|
|
19
19
|
import { usePlaceOrder } from '../../../../shared/api/storefront/hooks/cart/use-place-order.js';
|
|
20
20
|
import { useInvalidateAdyen } from '../../../../shared/api/storefront/hooks/payment/use-invalidate-adyen.js';
|
|
21
|
-
import { validateVATNumber } from '../../../../shared/api/storefront/services/finance-service.js';
|
|
22
21
|
import { useDataLayer } from '../../../../shared/ga/use-data-layer.js';
|
|
23
22
|
import { getCurrencyCodeBySymbol } from '../../../../shared/model/currency.js';
|
|
24
23
|
import { environment } from '../../../../shared/utils/environment.js';
|
|
@@ -27,7 +26,7 @@ import { useHasReturnedFromAdyen } from '../hooks/use-has-returned-from-adyen.js
|
|
|
27
26
|
import { AdyenPayment } from './adyen-payment.js';
|
|
28
27
|
import styles from './payment.module.css.js';
|
|
29
28
|
|
|
30
|
-
function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPaymentComplete, onProcessing,
|
|
29
|
+
function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPaymentComplete, onProcessing, }) {
|
|
31
30
|
const { createEcommerceEvent, dataLayer } = useDataLayer();
|
|
32
31
|
const { mutate: patchCart } = usePatchCart();
|
|
33
32
|
const { mutate: placeOrder } = usePlaceOrder();
|
|
@@ -49,7 +48,6 @@ function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPa
|
|
|
49
48
|
throw new Error(`Country code not found for cart with country abbreviation: ${_cart.billTo?.country?.abbreviation}`);
|
|
50
49
|
const countryCode = _cart.billTo.country.abbreviation;
|
|
51
50
|
const currencyCode = getCurrencyCodeBySymbol(cart.currencySymbol);
|
|
52
|
-
const lastVATNumber = useRef(cart.customerVatNumber);
|
|
53
51
|
if (!currencyCode)
|
|
54
52
|
throw new Error(`Currency code not found for cart with currency symbol: ${cart.currencySymbol}`);
|
|
55
53
|
const isAdyenPayment = selectedPaymentMethod === 'ADY' &&
|
|
@@ -66,7 +64,6 @@ function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPa
|
|
|
66
64
|
cartRef.current = _cart;
|
|
67
65
|
}, [_cart]);
|
|
68
66
|
const [validationErrors, setValidationErrors] = useState({});
|
|
69
|
-
const [customerVatNumber, setCustomerVatNumber] = useState(cart.customerVatNumber);
|
|
70
67
|
const atpSelectOptions = atp
|
|
71
68
|
.filter(atp => Boolean(atp.date))
|
|
72
69
|
.reduce((acc, atp) => ({
|
|
@@ -77,72 +74,6 @@ function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPa
|
|
|
77
74
|
acc[method.name] = t(`paymentMethod.${method.description}`);
|
|
78
75
|
return acc;
|
|
79
76
|
}, {});
|
|
80
|
-
const validateVAT = useCallback(async (value) => {
|
|
81
|
-
if (!value) {
|
|
82
|
-
setValidationErrors(errors => {
|
|
83
|
-
const result = { ...errors };
|
|
84
|
-
delete result.customerVatNumber;
|
|
85
|
-
return result;
|
|
86
|
-
});
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
if (value.length < 8) {
|
|
90
|
-
setValidationErrors({
|
|
91
|
-
...validationErrors,
|
|
92
|
-
customerVatNumber: t('validation.tooShort'),
|
|
93
|
-
});
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
try {
|
|
97
|
-
if (lastVATNumber.current === value)
|
|
98
|
-
return true;
|
|
99
|
-
onValidatingVAT(true);
|
|
100
|
-
const response = await validateVATNumber({ vatNumber: value });
|
|
101
|
-
lastVATNumber.current = value;
|
|
102
|
-
if (response.isValid) {
|
|
103
|
-
setValidationErrors(validationErrors => {
|
|
104
|
-
const result = { ...validationErrors };
|
|
105
|
-
delete result.customerVatNumber;
|
|
106
|
-
return result;
|
|
107
|
-
});
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
setValidationErrors(validationErrors => ({
|
|
112
|
-
...validationErrors,
|
|
113
|
-
customerVatNumber: t('validation.invalid'),
|
|
114
|
-
}));
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
// When an error occurs, we don't want to show the error message
|
|
120
|
-
// because it might be a temporary issue with the service.
|
|
121
|
-
// The customer can not do anything about it, so we just remove the error message.
|
|
122
|
-
setValidationErrors(validationErrors => {
|
|
123
|
-
const result = { ...validationErrors };
|
|
124
|
-
delete result.customerVatNumber;
|
|
125
|
-
return result;
|
|
126
|
-
});
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
finally {
|
|
130
|
-
onValidatingVAT(false);
|
|
131
|
-
}
|
|
132
|
-
}, [onValidatingVAT, t, validationErrors]);
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
/* When a customer has an existing VAT that is
|
|
135
|
-
* not valid (e.g. invalid, undetermined, or failure),
|
|
136
|
-
* then trigger a client side validation. */
|
|
137
|
-
if (!cart.customerVatNumber)
|
|
138
|
-
return;
|
|
139
|
-
if (cart.properties.customerVatNumberStatus === 'valid')
|
|
140
|
-
return;
|
|
141
|
-
onValidatingVAT(true);
|
|
142
|
-
lastVATNumber.current = '';
|
|
143
|
-
validateVAT(cart.customerVatNumber);
|
|
144
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
145
|
-
}, []);
|
|
146
77
|
const onPlaceOrderCompleted = useCallback(({ cart, payment_type }) => {
|
|
147
78
|
dataLayer.push(createEcommerceEvent({
|
|
148
79
|
cart,
|
|
@@ -189,10 +120,6 @@ function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPa
|
|
|
189
120
|
};
|
|
190
121
|
cart.requestedDeliveryDate = formData.get('deliveryDate')?.toString();
|
|
191
122
|
cart.requestedDeliveryDateDisplay = undefined;
|
|
192
|
-
if (cart.customerVatNumber &&
|
|
193
|
-
lastVATNumber.current !== cart.customerVatNumber &&
|
|
194
|
-
!(await validateVAT(cart.customerVatNumber)))
|
|
195
|
-
return;
|
|
196
123
|
if (Object.keys(validationErrors).length > 0)
|
|
197
124
|
return;
|
|
198
125
|
if (isAdyenPayment) {
|
|
@@ -317,7 +244,7 @@ function Payment({ atp, cart: _cart, form, isProcessing, onError: _onError, onPa
|
|
|
317
244
|
MA: t('industry.MA'),
|
|
318
245
|
OT: t('industry.OT'),
|
|
319
246
|
/* eslint-enable sort-keys-fix/sort-keys-fix */
|
|
320
|
-
}, placeholder: t('Select an industry'), variant: "solid" }), jsx(TextField, { showLabel: true, isDisabled: isDisabled, label: t('VAT Number'),
|
|
247
|
+
}, placeholder: t('Select an industry'), variant: "solid" }), jsx(TextField, { showLabel: true, isDisabled: isDisabled, label: t('VAT Number'), minLength: 8, name: "customerVatNumber" }, `vat${Boolean(validationErrors.customerVatNumber)}`), jsx(TextField, { showLabel: true, defaultValue: cart.poNumber, isDisabled: isDisabled, isRequired: cart.requiresPoNumber, label: t('PO Number'), name: "poNumber" }), paymentMethodOptions && Object.keys(paymentMethodOptions).length > 1 && (jsx(Select, { "data-test-selector": "paymentMethodSelect", defaultSelectedOption: cart.paymentOptions?.paymentMethods?.[0]?.name || 'ADY', isDisabled: isDisabled, label: t('Payment method'), name: "paymentMethod", onChange: setSelectedPaymentMethod, options: paymentMethodOptions, selectedOption: selectedPaymentMethod, variant: "solid" })), isAdyenPayment && cart.billTo && (jsx(AdyenPayment, { amount: cart.orderGrandTotal, cartId: cart.trackId, countryCode: countryCode, currencyCode: currencyCode, customerId: cart.billTo.id, dropinRef: dropinRef, environment: environment === 'production' ? 'live' : 'test', isDisabled: isDisabled, onComplete: onComplete, onError: onError, orderAmount: cart.orderGrandTotal, returnUrl:
|
|
321
248
|
/* eslint-disable ssr-friendly/no-dom-globals-in-react-fc */
|
|
322
249
|
typeof window === 'undefined'
|
|
323
250
|
? ''
|
|
@@ -5,11 +5,9 @@ export interface PaymentContentProps {
|
|
|
5
5
|
formId: string;
|
|
6
6
|
hasAtp: boolean;
|
|
7
7
|
isProcessing: boolean;
|
|
8
|
-
isValidatingVAT: boolean;
|
|
9
8
|
onPaymentComplete: ({ cartId }: {
|
|
10
9
|
cartId: string;
|
|
11
10
|
}) => void;
|
|
12
11
|
setIsProcessing: (isProcessing: boolean) => void;
|
|
13
|
-
setIsValidatingVAT: (isValidating: boolean) => void;
|
|
14
12
|
}
|
|
15
|
-
export declare function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing,
|
|
13
|
+
export declare function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing, onPaymentComplete, setIsProcessing, }: PaymentContentProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -16,7 +16,7 @@ import { CheckoutPageSection } from '../layouts/checkout-page-layout/components/
|
|
|
16
16
|
import { CheckoutPageSectionContent } from '../layouts/checkout-page-layout/components/checkout-page-section-content.js';
|
|
17
17
|
import { Payment } from './components/payment.js';
|
|
18
18
|
|
|
19
|
-
function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing,
|
|
19
|
+
function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing, onPaymentComplete, setIsProcessing, }) {
|
|
20
20
|
const t = useFormattedMessage();
|
|
21
21
|
const currencyCode = getCurrencyCodeBySymbol(cart.currencySymbol);
|
|
22
22
|
if (!currencyCode)
|
|
@@ -28,9 +28,9 @@ function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing, isValidat
|
|
|
28
28
|
label: t('Review and payment'),
|
|
29
29
|
},
|
|
30
30
|
], "data-test-selector": "paymentPage", title: t('Review and payment'), children: jsxs(CheckoutPageLayout, { actions: {
|
|
31
|
-
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_placeOrder", form: formId, isDisabled: isProcessing, isLoading: isProcessing ?
|
|
31
|
+
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_placeOrder", form: formId, isDisabled: isProcessing, isLoading: isProcessing ? jsx(FormattedMessage, { id: "Processing" }) : false, type: "submit", children: cart.paymentMethod?.name === 'PBI' ? (jsx(FormattedMessage, { id: "Finalize order" })) : (jsx(FormattedMessage, { id: "Finalize payment" })) })),
|
|
32
32
|
}, mobileSummary: jsx(CartTotalsSummary, { currencyCode: currencyCode, totalAmount: cart.orderGrandTotal }), overview: jsx(CartTotals, { currencyCode: currencyCode, deliveryDate: hasAtp ? undefined : cart.requestedDeliveryDate, fulfillmentMethod: cart.fulfillmentMethod, isPayByInvoice: (cart.paymentOptions?.paymentMethods?.length || 1) <= 1 &&
|
|
33
|
-
cart.paymentMethod?.name === 'PBI', shippingCost: cart.shippingAndHandling, subtotal: cart.orderSubTotal, tax: cart.totalTax, total: cart.orderGrandTotal, 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, isProcessing: isProcessing, onPaymentComplete: onPaymentComplete, onProcessing: setIsProcessing
|
|
33
|
+
cart.paymentMethod?.name === 'PBI', shippingCost: cart.shippingAndHandling, subtotal: cart.orderSubTotal, tax: cart.totalTax, total: cart.orderGrandTotal, 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, isProcessing: isProcessing, onPaymentComplete: onPaymentComplete, onProcessing: setIsProcessing }) }) }), 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 ?? null, href: cartLine.productUri, image: {
|
|
34
34
|
fit: 'contain',
|
|
35
35
|
image: {
|
|
36
36
|
'1': cartLine.smallImagePath,
|
|
@@ -23,7 +23,6 @@ function PaymentPage() {
|
|
|
23
23
|
const hasAtp = atp !== undefined && atp.length > 1;
|
|
24
24
|
const isLoading = isLoadingCart || isAtpLoading;
|
|
25
25
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
26
|
-
const [isValidating, setIsValidating] = useState(false);
|
|
27
26
|
const { isNavigating, navigate } = useNavigate();
|
|
28
27
|
const onPaymentComplete = useCallback(({ cartId }) => {
|
|
29
28
|
navigate(`${PATHS.ORDER_CONFIRMATION}?cartId=${cartId}`);
|
|
@@ -58,7 +57,7 @@ function PaymentPage() {
|
|
|
58
57
|
return null;
|
|
59
58
|
if (!atp)
|
|
60
59
|
throw new Error('Unexpected condition: ATP is undefined');
|
|
61
|
-
return (jsx(PaymentPageContent, { atp: atp, cart: cart, formId: PAYMENT_FORM_ID, hasAtp: hasAtp, isProcessing: isProcessing,
|
|
60
|
+
return (jsx(PaymentPageContent, { atp: atp, cart: cart, formId: PAYMENT_FORM_ID, hasAtp: hasAtp, isProcessing: isProcessing, onPaymentComplete: onPaymentComplete, setIsProcessing: setIsProcessing }));
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export { PaymentPage };
|
|
@@ -16,7 +16,7 @@ import styles from './product-details-panel.module.css.js';
|
|
|
16
16
|
|
|
17
17
|
function ProductDetailsPanel({ priceComponent, product, }) {
|
|
18
18
|
const { sendAddToCartFromProductDetailsPageEvent, sendAddToWishListFromProductDetailsPageEvent, } = useAlgoliaInsights();
|
|
19
|
-
return (jsxs("div", { className: styles['product-details-panel'], children: [jsxs("div", { className: styles.heading, children: [jsx(Heading, { italic: true, size: "xs", tag: "h1", children: product.productTitle }), jsx(ProductSku, { sku: product.productNumber })] }), jsxs("div", { className: styles['price-action-container'], children: [priceComponent || (jsx(Price, { className: styles.price, currencyCode: product.currencyCode, "data-test": "productPrice_unitNetPrice", isVatIncluded: product.isVatIncluded, originalPrice: product.originalPrice, price: product.price, variant: "sonic" })), jsxs("div", { className: styles['action-container'], children: [product.canAddToCart && (jsx(ConnectedAddToCartButton, { onAddToCart: ({ cartLine }) => {
|
|
19
|
+
return (jsxs("div", { className: styles['product-details-panel'], children: [jsxs("div", { className: styles.heading, children: [jsx(Heading, { italic: true, size: "xs", tag: "h1", children: product.productTitle }), jsx(ProductSku, { className: styles.sku, sku: product.productNumber })] }), jsxs("div", { className: styles['price-action-container'], children: [priceComponent || (jsx(Price, { className: styles.price, currencyCode: product.currencyCode, "data-test": "productPrice_unitNetPrice", isVatIncluded: product.isVatIncluded, originalPrice: product.originalPrice, price: product.price, variant: "sonic" })), jsxs("div", { className: styles['action-container'], children: [product.canAddToCart && (jsx(ConnectedAddToCartButton, { onAddToCart: ({ cartLine }) => {
|
|
20
20
|
sendAddToCartFromProductDetailsPageEvent({
|
|
21
21
|
cartLine,
|
|
22
22
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var styles = {"product-details-panel":"product-details-panel-module-MXfPm","heading":"product-details-panel-module-rtZYR","price-action-container":"product-details-panel-module-wHZCr","price":"product-details-panel-module-dI2JL","action-container":"product-details-panel-module-QLafW","description":"product-details-panel-module-9L-Nm","feature-list":"product-details-panel-module-NC2nx"};
|
|
1
|
+
var styles = {"product-details-panel":"product-details-panel-module-MXfPm","heading":"product-details-panel-module-rtZYR","sku":"product-details-panel-module-IbS9-","price-action-container":"product-details-panel-module-wHZCr","price":"product-details-panel-module-dI2JL","action-container":"product-details-panel-module-QLafW","description":"product-details-panel-module-9L-Nm","feature-list":"product-details-panel-module-NC2nx"};
|
|
2
2
|
|
|
3
3
|
export { styles as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FetchNavigationLinksArgs } from '../services/bff-service';
|
|
2
|
-
export declare function useFetchNavigationLinks({ cultureCode, source, }: FetchNavigationLinksArgs): import("@tanstack/react-query").UseQueryResult<import("../model/bff.model").
|
|
2
|
+
export declare function useFetchNavigationLinks({ cultureCode, source, }: FetchNavigationLinksArgs): import("@tanstack/react-query").UseQueryResult<import("../model/bff.model").NavigationSection, Error>;
|
|
@@ -187,21 +187,29 @@ interface Announcement {
|
|
|
187
187
|
}
|
|
188
188
|
export type AnnouncementResponse = Announcement[];
|
|
189
189
|
export interface NavigationLink {
|
|
190
|
-
|
|
191
|
-
image?: ImageType;
|
|
190
|
+
href: string;
|
|
191
|
+
image?: ImageType | null;
|
|
192
192
|
key: string;
|
|
193
|
-
|
|
193
|
+
label: string;
|
|
194
194
|
openInNewTab?: boolean;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
195
|
+
type: 'link';
|
|
196
|
+
}
|
|
197
|
+
export declare const isNavigationLink: (item?: unknown) => item is NavigationLink;
|
|
198
|
+
export interface NavigationLinkGroup extends Omit<NavigationLink, 'type' | 'href'> {
|
|
199
|
+
header?: string;
|
|
200
|
+
href?: string | null;
|
|
201
|
+
items: NavigationLinkItem[];
|
|
202
|
+
type: 'link-group';
|
|
203
|
+
}
|
|
204
|
+
export declare const isNavigationLinkGroup: (item?: unknown) => item is NavigationLinkGroup;
|
|
205
|
+
export interface NavigationSection {
|
|
206
|
+
items: NavigationItem[];
|
|
207
|
+
key: string;
|
|
208
|
+
type: 'section';
|
|
206
209
|
}
|
|
210
|
+
export declare const isNavigationSection: (item?: unknown) => item is NavigationSection;
|
|
211
|
+
export type NavigationLinkItem = NavigationLink | NavigationLinkGroup;
|
|
212
|
+
export declare const isNavigationLinkItem: (item?: unknown) => item is NavigationLinkItem;
|
|
213
|
+
export type NavigationItem = NavigationSection | NavigationLinkItem;
|
|
214
|
+
export type NavigationResponse = NavigationSection;
|
|
207
215
|
export {};
|
|
@@ -1 +1,12 @@
|
|
|
1
|
+
const isNavigationLink = (item) =>
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
|
+
item?.type === 'link';
|
|
4
|
+
const isNavigationLinkGroup = (item) =>
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
item?.type === 'link-group';
|
|
7
|
+
const isNavigationSection = (item) =>
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
item?.type === 'section';
|
|
10
|
+
const isNavigationLinkItem = (item) => isNavigationLink(item) || isNavigationLinkGroup(item);
|
|
1
11
|
|
|
12
|
+
export { isNavigationLink, isNavigationLinkGroup, isNavigationLinkItem, isNavigationSection };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CultureCode } from '../../../../intl/types';
|
|
2
2
|
import { ProductListingPageData } from '../../../../pages/product/product-listing-page/product-listing-page-data-types';
|
|
3
3
|
import { AnnouncementObject } from '../../../model/announcement';
|
|
4
|
-
import {
|
|
4
|
+
import { NavigationResponse, ProductDetailsPageDataResponse, ProductSummary } from '../model/bff.model';
|
|
5
5
|
export interface FetchAnnouncementsArgs {
|
|
6
6
|
cultureCode: CultureCode;
|
|
7
7
|
}
|
|
@@ -17,7 +17,7 @@ export interface FetchNavigationLinksArgs {
|
|
|
17
17
|
cultureCode: CultureCode;
|
|
18
18
|
source: NavigationLinkSource;
|
|
19
19
|
}
|
|
20
|
-
export declare function fetchNavigationLinks({ cultureCode, source, }: FetchNavigationLinksArgs): Promise<
|
|
20
|
+
export declare function fetchNavigationLinks({ cultureCode, source, }: FetchNavigationLinksArgs): Promise<NavigationResponse>;
|
|
21
21
|
export declare function fetchRecentlyViewedProducts({ cultureCode, }: {
|
|
22
22
|
cultureCode: CultureCode;
|
|
23
23
|
}): Promise<ProductSummary[]>;
|