@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.
Files changed (47) hide show
  1. package/dist/collapsables/accordion/accordion-item.js +2 -1
  2. package/dist/collapsables/accordion/accordion.module.css.js +1 -1
  3. package/dist/exports.d.ts +1 -0
  4. package/dist/footer/connected-footer.d.ts +2 -1
  5. package/dist/footer/connected-footer.js +9 -2
  6. package/dist/footer/footer.d.ts +6 -10
  7. package/dist/footer/footer.js +24 -18
  8. package/dist/footer/footer.module.css.js +1 -1
  9. package/dist/header/connected-header.js +9 -1
  10. package/dist/header/drawers/desktop-navigation-drawer.d.ts +3 -3
  11. package/dist/header/drawers/desktop-navigation-drawer.js +2 -4
  12. package/dist/header/drawers/mobile-navigation-drawer.d.ts +3 -3
  13. package/dist/header/drawers/mobile-navigation-drawer.js +2 -2
  14. package/dist/header/header.d.ts +3 -3
  15. package/dist/header/header.js +15 -9
  16. package/dist/header/link-list/navigation-link-list.d.ts +5 -5
  17. package/dist/header/link-list/navigation-link-list.js +10 -5
  18. package/dist/index.js +1 -0
  19. package/dist/intl/translation-id.d.ts +1 -1
  20. package/dist/lists/menu-list/menu-list-header.d.ts +1 -1
  21. package/dist/lists/menu-list/menu-list-item.d.ts +2 -2
  22. package/dist/lists/menu-list/menu-list-item.js +1 -1
  23. package/dist/lists/menu-list/menu-list.d.ts +6 -4
  24. package/dist/lists/menu-list/menu-list.js +3 -3
  25. package/dist/media/image-lightbox/image-lightbox.js +12 -2
  26. package/dist/media/zoom-image/zoom-image.js +6 -1
  27. package/dist/navigation/mobile-navigation/mobile-navigation.d.ts +3 -3
  28. package/dist/navigation/mobile-navigation/mobile-navigation.js +2 -2
  29. package/dist/navigation/panel-navigation/panel-navigation.d.ts +5 -7
  30. package/dist/navigation/panel-navigation/panel-navigation.js +11 -14
  31. package/dist/pages/checkout/payment-page/components/adyen-payment.js +8 -2
  32. package/dist/pages/checkout/payment-page/components/payment.d.ts +1 -2
  33. package/dist/pages/checkout/payment-page/components/payment.js +2 -75
  34. package/dist/pages/checkout/payment-page/payment-page-content.d.ts +1 -3
  35. package/dist/pages/checkout/payment-page/payment-page-content.js +3 -3
  36. package/dist/pages/checkout/payment-page/payment-page.js +1 -2
  37. package/dist/pages/product/product-details-page/components/product-details-panel/product-details-panel.js +1 -1
  38. package/dist/pages/product/product-details-page/components/product-details-panel/product-details-panel.module.css.js +1 -1
  39. package/dist/shared/api/bff/hooks/use-fetch-navigation-links.d.ts +1 -1
  40. package/dist/shared/api/bff/model/bff.model.d.ts +22 -14
  41. package/dist/shared/api/bff/model/bff.model.js +11 -0
  42. package/dist/shared/api/bff/services/bff-service.d.ts +2 -2
  43. package/dist/shared/api/bff/services/bff-service.js +1 -1
  44. package/dist/shared/data/navigation.d.ts +2 -0
  45. package/dist/shared/data/navigation.js +2605 -0
  46. package/dist/styles.css +1549 -1481
  47. package/package.json +1 -1
@@ -1,17 +1,15 @@
1
1
  import { ReactNode } from 'react';
2
- import { NavigationLink } from '../../shared/api/bff/model/bff.model';
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?: string | {
9
- href: string;
10
- title: string;
11
- };
9
+ header?: MenuHeader;
12
10
  id?: string;
13
11
  isNarrow?: boolean;
14
- links?: NavigationLink[];
12
+ linkItems?: NavigationLinkItem[];
15
13
  variant?: 'primary';
16
14
  }
17
- export declare function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow, links, variant, }: PanelNavigationProps): import("react/jsx-runtime").JSX.Element;
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, links, scrollable, variant, }, ref) => {
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: links?.map(link => link.links && link.links.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
+ 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.title }, link.key)) : (jsx(MenuListItem, { "data-test-selector": "panelNavigationItem", href: link.url, image: link.image, openInNewTab: link.openInNewTab, children: link.title }, 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
+ : 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.title
51
+ : header.label
51
52
  : t('Main menu'),
52
53
  }
53
- : undefined, header: selectedNavigationLink?.url
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, links: selectedNavigationLink && 'links' in selectedNavigationLink
61
- ? selectedNavigationLink.links
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, links, variant, }) {
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, links: links, scrollable: children ? false : undefined, variant: variant, children: children }) }) }) }));
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
- return jsx("div", { children: String(error) });
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, onValidatingVAT, }: PaymentProps): import("react/jsx-runtime").JSX.Element;
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, onValidatingVAT, }) {
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'), name: "customerVatNumber", onBlur: e => validateVAT(e.target.value), onChange: setCustomerVatNumber, validate: () => validationErrors.customerVatNumber ?? true, value: 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:
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, isValidatingVAT, onPaymentComplete, setIsProcessing, setIsValidatingVAT, }: PaymentContentProps): import("react/jsx-runtime").JSX.Element;
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, isValidatingVAT, onPaymentComplete, setIsProcessing, setIsValidatingVAT, }) {
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 ? (jsx(FormattedMessage, { id: "Processing" })) : isValidatingVAT ? (jsx(FormattedMessage, { id: "Validating" })) : (false), type: "submit", children: cart.paymentMethod?.name === 'PBI' ? (jsx(FormattedMessage, { id: "Finalize order" })) : (jsx(FormattedMessage, { id: "Finalize payment" })) })),
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, onValidatingVAT: setIsValidatingVAT }) }) }), 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: {
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, isValidatingVAT: isValidating, onPaymentComplete: onPaymentComplete, setIsProcessing: setIsProcessing, setIsValidatingVAT: setIsValidating }));
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").NavigationLinkResponse, Error>;
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
- external?: boolean;
191
- image?: ImageType;
190
+ href: string;
191
+ image?: ImageType | null;
192
192
  key: string;
193
- links?: NavigationLink[];
193
+ label: string;
194
194
  openInNewTab?: boolean;
195
- title: string;
196
- type: 'link' | 'category' | 'section';
197
- url?: string;
198
- }
199
- export interface NavigationLinkResponse {
200
- footer: {
201
- bottomLinks: NavigationLink[];
202
- copyright: string;
203
- linkBlocks: NavigationLink[];
204
- };
205
- header: NavigationLink[];
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 { NavigationLinkResponse, ProductDetailsPageDataResponse, ProductSummary } from '../model/bff.model';
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<NavigationLinkResponse>;
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[]>;
@@ -102,7 +102,7 @@ async function fetchNavigationLinks({ cultureCode, source, }) {
102
102
  `navigation-${source}-${cultureCode}`,
103
103
  ],
104
104
  },
105
- url: `${config.BFF_API_URL}/navigation`,
105
+ url: `${config.BFF_API_URL}/v2/navigation`,
106
106
  });
107
107
  return body;
108
108
  }
@@ -0,0 +1,2 @@
1
+ import { NavigationResponse } from '../api/bff/model/bff.model';
2
+ export declare const navigationData: NavigationResponse;