@sonic-equipment/ui 194.0.0 → 196.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.
@@ -2,6 +2,7 @@
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
3
  import { useMemo, useEffect } from 'react';
4
4
  import { logger } from '../logging/logger.js';
5
+ import { useCookiebot } from '../shared/hooks/use-cookiebot.js';
5
6
  import { useDisclosure } from '../shared/hooks/use-disclosure.js';
6
7
  import { CountrySelectorDialog } from './country-selector-dialog/country-selector-dialog.js';
7
8
  import { CountrySelectorTrigger } from './country-selector-trigger/country-selector-trigger.js';
@@ -13,14 +14,24 @@ function ConnectedCountrySelector({ defaultCountryCode, defaultLanguageCode, onC
13
14
  defaultCountryCode,
14
15
  defaultLanguageCode,
15
16
  });
17
+ const { hasResponse: hasCookiebotResponse, isDialogOpen: isCookiebotDialogOpen, } = useCookiebot();
16
18
  const isCountryLanguageSelected = useMemo(() => selectedCountry !== undefined && selectedLanguage !== undefined, [selectedCountry, selectedLanguage]);
17
19
  const isDismissable = isCountryLanguageSelected;
18
20
  useEffect(() => {
19
- if (isOpen)
21
+ if (isOpen && !isCookiebotDialogOpen)
20
22
  return;
21
- setIsOpen(!isFetching && !isCountryLanguageSelected);
23
+ setIsOpen(!isFetching &&
24
+ !isCountryLanguageSelected &&
25
+ hasCookiebotResponse &&
26
+ !isCookiebotDialogOpen);
22
27
  // eslint-disable-next-line react-hooks/exhaustive-deps
23
- }, [isFetching, isCountryLanguageSelected, isOpen]);
28
+ }, [
29
+ isFetching,
30
+ isCountryLanguageSelected,
31
+ isOpen,
32
+ hasCookiebotResponse,
33
+ isCookiebotDialogOpen,
34
+ ]);
24
35
  if (isFetching)
25
36
  return null;
26
37
  if (error !== undefined) {
package/dist/exports.d.ts CHANGED
@@ -369,6 +369,7 @@ export * from './shared/ga/types';
369
369
  export * from './shared/ga/use-data-layer';
370
370
  export * from './shared/hooks/use-breakpoint';
371
371
  export * from './shared/hooks/use-cookie';
372
+ export * from './shared/hooks/use-cookiebot';
372
373
  export * from './shared/hooks/use-css-link';
373
374
  export * from './shared/hooks/use-debounced-callback';
374
375
  export * from './shared/hooks/use-disclosure';
@@ -3,6 +3,7 @@ import { Country } from '../../../shared/model/countries-languages';
3
3
  export interface EditAddressFormProps {
4
4
  address: Address | null | undefined;
5
5
  countries: Country[];
6
+ currentCountry: Country | undefined;
6
7
  isLoading: boolean;
7
8
  }
8
- export declare function EditAddressForm({ address, countries, isLoading, }: EditAddressFormProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function EditAddressForm({ address, countries, currentCountry: _currentCountry, isLoading, }: EditAddressFormProps): import("react/jsx-runtime").JSX.Element;
@@ -9,17 +9,18 @@ import { Message } from '../../../message/message.js';
9
9
  import { validatePhone, validateEmail } from '../../../shared/model/address.js';
10
10
  import styles from './edit-address-form.module.css.js';
11
11
 
12
- function EditAddressForm({ address, countries, isLoading, }) {
12
+ function EditAddressForm({ address, countries, currentCountry: _currentCountry, isLoading, }) {
13
13
  const t = useFormattedMessage();
14
14
  const [companyName, setCompanyName] = useState(address?.companyName || '');
15
15
  const [lastName, setLastName] = useState(address?.lastName || '');
16
- const currentCountry = countries.find(country => country.id === address?.country?.id);
16
+ const currentCountry = countries.find(c => c.id === address?.country?.id) || _currentCountry;
17
17
  const [selectedCountry, setSelectedCountry] = useState(currentCountry);
18
- const currencyHasChanged = selectedCountry?.currencyCode !== currentCountry?.currencyCode;
18
+ const currencyHasChanged = Boolean(currentCountry) &&
19
+ selectedCountry?.currencyCode !== currentCountry?.currencyCode;
19
20
  if (countries.length === 0) {
20
21
  return (jsx(Message, { type: "danger", children: jsx(FormattedMessage, { force: true, id: "No countries available. Unable to change address." }) }));
21
22
  }
22
- return (jsxs(Fragment, { children: [jsx(TextField, { defaultValue: address?.firstName, isDisabled: isLoading, label: t('First name'), name: "firstName", showLabel: true }), jsx(TextField, { isDisabled: isLoading, isRequired: !address?.companyName, label: t('Last name'), minLength: 3, name: "lastName", onChange: setLastName, showLabel: true, value: lastName }, `lastname-${Boolean(address?.companyName)}`), jsx(TextField, { defaultValue: address?.companyName, isDisabled: isLoading, label: t('Company name'), name: "companyName", onChange: setCompanyName, showLabel: true, value: companyName }), jsx(TextField, { defaultValue: address?.attention, isDisabled: isLoading, label: t('Attention'), name: "attention", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: address?.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: address?.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: address?.address3, isDisabled: isLoading, label: `${t('Address')} 3`, maxLength: 30, minLength: 3, name: "address3", showLabel: true }) }), jsx(TextField, { isRequired: true, defaultValue: address?.postalCode, isDisabled: isLoading, label: t('Postal Code'), maxLength: 10, minLength: 4, name: "postalCode", showLabel: true }), jsx(TextField, { isRequired: true, defaultValue: address?.city, isDisabled: isLoading, label: t('City'), maxLength: 30, minLength: 3, name: "city", showLabel: true }), jsxs("div", { className: styles['span-2'], children: [jsx(CountrySelect, { isRequired: true, countries: countries, "data-test-selector": "countrySelect", isDisabled: isLoading, name: "countrySelect", onCountryChange: setSelectedCountry, selectedCountry: selectedCountry }), currencyHasChanged && (jsx(Message, { className: styles['currency-warning'], type: "warning", children: jsx(FormattedMessage, { id: "Selecting this country will result in your cart to be converted to the currency {0}", replacementValues: {
23
+ return (jsxs(Fragment, { children: [jsx(TextField, { defaultValue: address?.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: address?.companyName, isDisabled: isLoading, label: t('Company name'), name: "companyName", onChange: setCompanyName, showLabel: true, value: companyName }), jsx(TextField, { defaultValue: address?.attention, isDisabled: isLoading, label: t('Attention'), name: "attention", showLabel: true }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: address?.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: address?.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: address?.address3, isDisabled: isLoading, label: `${t('Address')} 3`, maxLength: 30, minLength: 3, name: "address3", showLabel: true }) }), jsx(TextField, { isRequired: true, defaultValue: address?.postalCode, isDisabled: isLoading, label: t('Postal Code'), maxLength: 10, minLength: 4, name: "postalCode", showLabel: true }), jsx(TextField, { isRequired: true, defaultValue: address?.city, isDisabled: isLoading, label: t('City'), maxLength: 30, minLength: 3, name: "city", showLabel: true }), jsxs("div", { className: styles['span-2'], children: [jsx(CountrySelect, { isRequired: true, countries: countries, "data-test-selector": "countrySelect", isDisabled: isLoading, name: "countrySelect", onCountryChange: setSelectedCountry, selectedCountry: selectedCountry }), currencyHasChanged && (jsx(Message, { className: styles['currency-warning'], type: "warning", children: jsx(FormattedMessage, { id: "Selecting this country will result in your cart to be converted to the currency {0}", replacementValues: {
23
24
  '0': selectedCountry?.currencyCode || t('Unknown'),
24
25
  } }) }))] }), jsx("div", { className: styles['span-2'], children: jsx(TextField, { isRequired: true, defaultValue: address?.phone, isDisabled: isLoading, label: t('Phone'), name: "phone", showLabel: true, validate: value => {
25
26
  if (!value)
package/dist/index.js CHANGED
@@ -360,7 +360,7 @@ export { fetchTranslations } from './shared/api/storefront/services/translation-
360
360
  export { fetchCountriesLanguages, fetchCountriesWithLanguages, fetchSettings, updateLocale } from './shared/api/storefront/services/website-service.js';
361
361
  export { WishListNameAlreadyExistsError, addWishListItemToWishList, createWishList, deleteWishList, deleteWishListItemFromWishList, getWishList, getWishListItemsByWishListId, getWishLists } from './shared/api/storefront/services/wishlist-service.js';
362
362
  export { cart } from './shared/data/cart.data.js';
363
- export { countries, dutch, english, france, french, german, germany, languages, netherlands, unitedKingdom } from './shared/data/countries-languages.data.js';
363
+ export { countries, dutch, english, france, french, german, germany, languages, netherlands, switzerland, unitedKingdom } from './shared/data/countries-languages.data.js';
364
364
  export { navigationData } from './shared/data/navigation.js';
365
365
  export { useFeatureFlags } from './shared/feature-flags/use-feature-flags.js';
366
366
  export { BadRequestError, ForbiddenRequestError, InternalServerErrorRequestError, NotFoundRequestError, RequestError, TimeoutRequestError, UnauthorizedRequestError, UnprocessableContentRequestError, isFormData, isJsonBody, isRequestError, request } from './shared/fetch/request.js';
@@ -370,6 +370,7 @@ export { isGAEvent } from './shared/ga/types.js';
370
370
  export { useDataLayer } from './shared/ga/use-data-layer.js';
371
371
  export { useBreakpoint } from './shared/hooks/use-breakpoint.js';
372
372
  export { defaultCookieOptions, useCookie } from './shared/hooks/use-cookie.js';
373
+ export { useCookiebot } from './shared/hooks/use-cookiebot.js';
373
374
  export { useCSSLink } from './shared/hooks/use-css-link.js';
374
375
  export { useDebouncedCallback } from './shared/hooks/use-debounced-callback.js';
375
376
  export { useDisclosure } from './shared/hooks/use-disclosure.js';
@@ -6,9 +6,10 @@ export interface EditAddressesFormData {
6
6
  address: ValidAddress;
7
7
  notes: string | undefined;
8
8
  }
9
- export declare function EditCheckoutBillToAddressForm({ billTo, countries, isLoading, isPickup, onSubmit, }: {
9
+ export declare function EditCheckoutBillToAddressForm({ billTo, countries, currentCountry, isLoading, isPickup, onSubmit, }: {
10
10
  billTo: BillToModel | undefined | null;
11
11
  countries: Country[];
12
+ currentCountry: Country | undefined;
12
13
  isLoading: boolean;
13
14
  isPickup: boolean;
14
15
  onSubmit: (event: EditAddressesFormData) => void;
@@ -14,7 +14,7 @@ import { SonicAddress } from './sonic-address.js';
14
14
  import styles from './edit-checkout-bill-to-address-form.module.css.js';
15
15
 
16
16
  const EDIT_ADDRESS_FORM_ID = 'billToForm';
17
- function EditCheckoutBillToAddressForm({ billTo, countries, isLoading, isPickup, onSubmit, }) {
17
+ function EditCheckoutBillToAddressForm({ billTo, countries, currentCountry, isLoading, isPickup, onSubmit, }) {
18
18
  const t = useFormattedMessage();
19
19
  const { data: cart } = useFetchCurrentCart();
20
20
  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 => {
@@ -43,7 +43,7 @@ function EditCheckoutBillToAddressForm({ billTo, countries, isLoading, isPickup,
43
43
  ? undefined
44
44
  : formData.get('notes')?.toString() || '',
45
45
  });
46
- }, children: [jsx(EditAddressForm, { address: billTo, countries: countries, isLoading: isLoading }), 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.') })] })) }) }) })] }));
46
+ }, children: [jsx(EditAddressForm, { address: billTo, countries: countries, currentCountry: currentCountry, isLoading: isLoading }), 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.') })] })) }) }) })] }));
47
47
  }
48
48
 
49
49
  export { EDIT_ADDRESS_FORM_ID, EditCheckoutBillToAddressForm };
@@ -124,7 +124,7 @@ function ShippingPage() {
124
124
  return (jsx(ShippingPageContent, { cart: cart,
125
125
  // TODO: Combine editAddress and readOnlyAddress into one section in order
126
126
  // for typescript to correctly infer which properties are set in what case
127
- editAddress: jsxs(Fragment, { children: [jsx(EditCheckoutBillToAddressForm, { billTo: cart.billTo, countries: countries || [], isLoading: isPatching, isPickup: isPickup, onSubmit: async ({ address, notes }) => {
127
+ editAddress: jsxs(Fragment, { children: [jsx(EditCheckoutBillToAddressForm, { billTo: cart.billTo, countries: countries || [], currentCountry: currentCountry, isLoading: isPatching, isPickup: isPickup, onSubmit: async ({ address, notes }) => {
128
128
  if (!cart.billTo)
129
129
  return;
130
130
  formData.current = { address, notes };
@@ -2,7 +2,7 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { EditAddressForm } from '../../../../forms/partials/edit-address-form/edit-address-form.js';
3
3
 
4
4
  function EditBillToAddress() {
5
- return (jsx(EditAddressForm, { address: undefined, countries: [], isLoading: false }));
5
+ return (jsx(EditAddressForm, { address: undefined, countries: [], currentCountry: undefined, isLoading: false }));
6
6
  }
7
7
 
8
8
  export { EditBillToAddress };
@@ -6,6 +6,7 @@ export declare const german: Language;
6
6
  export declare const netherlands: Country;
7
7
  export declare const unitedKingdom: Country;
8
8
  export declare const germany: Country;
9
+ export declare const switzerland: Country;
9
10
  export declare const france: Country;
10
11
  export declare const countries: Country[];
11
12
  export declare const languages: Language[];
@@ -46,6 +46,14 @@ const germany = {
46
46
  name: 'Germany',
47
47
  states: null,
48
48
  };
49
+ const switzerland = {
50
+ abbreviation: 'CH',
51
+ currencyCode: 'CHF',
52
+ id: '423f6a9b-0b7b-4b3b-8b3b-3b7b0b9a6f46',
53
+ languages: [german, french],
54
+ name: 'Switserland',
55
+ states: null,
56
+ };
49
57
  const france = {
50
58
  abbreviation: 'FR',
51
59
  currencyCode: 'EUR',
@@ -57,9 +65,10 @@ const france = {
57
65
  const countries = [
58
66
  netherlands,
59
67
  unitedKingdom,
68
+ switzerland,
60
69
  germany,
61
70
  france,
62
71
  ];
63
72
  const languages = [english, dutch, french, german];
64
73
 
65
- export { countries, dutch, english, france, french, german, germany, languages, netherlands, unitedKingdom };
74
+ export { countries, dutch, english, france, french, german, germany, languages, netherlands, switzerland, unitedKingdom };
@@ -0,0 +1,11 @@
1
+ declare global {
2
+ interface Window {
3
+ Cookiebot?: {
4
+ hasResponse: boolean;
5
+ };
6
+ }
7
+ }
8
+ export declare function useCookiebot(): {
9
+ hasResponse: boolean;
10
+ isDialogOpen: boolean;
11
+ };
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { useState, useEffect } from 'react';
3
+
4
+ // https://www.cookiebot.com/en/developer/
5
+ function useCookiebot() {
6
+ const [hasResponse, setHasResponse] = useState(Boolean(window?.Cookiebot?.hasResponse));
7
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
8
+ const handleDialogDisplay = () => {
9
+ setIsDialogOpen(true);
10
+ };
11
+ const handleAcceptDecline = () => {
12
+ setHasResponse(Boolean(window?.Cookiebot?.hasResponse));
13
+ setIsDialogOpen(false);
14
+ };
15
+ useEffect(() => {
16
+ window?.addEventListener('CookiebotOnDialogDisplay', handleDialogDisplay);
17
+ window?.addEventListener('CookiebotOnAccept', handleAcceptDecline);
18
+ window?.addEventListener('CookiebotOnDecline', handleAcceptDecline);
19
+ return () => {
20
+ window?.removeEventListener('CookiebotOnDialogDisplay', handleDialogDisplay);
21
+ window?.removeEventListener('CookiebotOnAccept', handleAcceptDecline);
22
+ window?.removeEventListener('CookiebotOnDecline', handleAcceptDecline);
23
+ };
24
+ }, []);
25
+ return {
26
+ hasResponse,
27
+ isDialogOpen,
28
+ };
29
+ }
30
+
31
+ export { useCookiebot };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonic-equipment/ui",
3
- "version": "194.0.0",
3
+ "version": "196.0.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "engines": {