@sonic-equipment/ui 193.0.0 → 195.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/background-overlay/background-overlay.js +11 -5
- package/dist/exports.d.ts +1 -1
- package/dist/forms/partials/edit-address-form/edit-address-form.d.ts +2 -1
- package/dist/forms/partials/edit-address-form/edit-address-form.js +5 -4
- package/dist/header/buttons/account/connected-account-button.d.ts +1 -2
- package/dist/header/buttons/account/connected-account-button.js +10 -4
- package/dist/header/header.js +3 -2
- package/dist/index.js +3 -3
- package/dist/navigation/mobile-navigation/mobile-navigation.js +3 -2
- package/dist/pages/account/create-account-page/create-account-page.js +5 -4
- package/dist/pages/account/sign-in-page/sign-in-page.js +5 -4
- package/dist/pages/checkout/cart-page/cart-page.js +7 -5
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +4 -3
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page.js +5 -4
- package/dist/pages/checkout/payment-page/payment-page-content.js +4 -3
- package/dist/pages/checkout/payment-page/payment-page.js +9 -8
- package/dist/pages/checkout/shipping-page/components/currency-change-dialog.js +3 -2
- package/dist/pages/checkout/shipping-page/components/edit-checkout-bill-to-address-form.d.ts +2 -1
- package/dist/pages/checkout/shipping-page/components/edit-checkout-bill-to-address-form.js +2 -2
- package/dist/pages/checkout/shipping-page/components/readonly-address.js +4 -3
- package/dist/pages/checkout/shipping-page/shipping-page-content.js +4 -3
- package/dist/pages/checkout/shipping-page/shipping-page.js +10 -9
- package/dist/pages/error-page/error-page.js +4 -3
- package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.js +3 -2
- package/dist/pages/my-sonic/actions/edit-bill-to-address/edit-bill-to-address.js +1 -1
- package/dist/pages/my-sonic/navigation/connected-my-sonic-navigation.js +3 -2
- package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.js +2 -1
- package/dist/pages/my-sonic/navigation/my-sonic-mobile-navigation.js +2 -1
- package/dist/pages/my-sonic/navigation/my-sonic-navigation-items.d.ts +1 -1
- package/dist/pages/my-sonic/navigation/my-sonic-navigation-items.js +31 -23
- package/dist/shared/data/countries-languages.data.d.ts +1 -0
- package/dist/shared/data/countries-languages.data.js +10 -1
- package/dist/shared/routing/route-provider.d.ts +3 -2
- package/dist/shared/routing/route-provider.js +2 -1
- package/dist/shared/routing/types.d.ts +18 -0
- package/dist/shared/routing/use-paths.d.ts +2 -0
- package/dist/shared/routing/use-paths.js +10 -0
- package/package.json +1 -1
- package/dist/pages/paths.d.ts +0 -17
- package/dist/pages/paths.js +0 -19
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
3
|
import { BackgroundOverlayManager } from './background-overlay-manager.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -10,10 +10,16 @@ function BackgroundOverlay({ isOpen, onClick, onClose, position = 'in-front', })
|
|
|
10
10
|
* An instance of the BackgroundOverlay class is
|
|
11
11
|
* created using the BackgroundOverlayManager.
|
|
12
12
|
*/
|
|
13
|
-
const backgroundOverlay =
|
|
13
|
+
const [backgroundOverlay, setBackgroundOverlay] = useState();
|
|
14
14
|
useEffect(() => {
|
|
15
|
+
// eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
|
|
16
|
+
setBackgroundOverlay(backgroundOverlay => {
|
|
17
|
+
if (backgroundOverlay)
|
|
18
|
+
return backgroundOverlay;
|
|
19
|
+
return BackgroundOverlayManager.createBackgroundOverlay();
|
|
20
|
+
});
|
|
15
21
|
/* Mount or update the background overlay instance */
|
|
16
|
-
backgroundOverlay
|
|
22
|
+
backgroundOverlay?.mountOrUpdate({
|
|
17
23
|
isVisible: isOpen,
|
|
18
24
|
onClick,
|
|
19
25
|
onClose,
|
|
@@ -22,11 +28,11 @@ function BackgroundOverlay({ isOpen, onClick, onClose, position = 'in-front', })
|
|
|
22
28
|
}, [backgroundOverlay, isOpen, onClick, onClose, position]);
|
|
23
29
|
useEffect(() => {
|
|
24
30
|
/* Show or hide the background overlay */
|
|
25
|
-
backgroundOverlay
|
|
31
|
+
backgroundOverlay?.show(isOpen);
|
|
26
32
|
}, [backgroundOverlay, isOpen]);
|
|
27
33
|
useEffect(() => {
|
|
28
34
|
/* Unmount the background overlay instance */
|
|
29
|
-
return () => backgroundOverlay
|
|
35
|
+
return () => backgroundOverlay?.unmount();
|
|
30
36
|
}, [backgroundOverlay]);
|
|
31
37
|
return null;
|
|
32
38
|
}
|
package/dist/exports.d.ts
CHANGED
|
@@ -267,7 +267,6 @@ export * from './pages/my-sonic/widgets/connected-bill-to-address-widget';
|
|
|
267
267
|
export * from './pages/my-sonic/widgets/connected-customer-information-widget';
|
|
268
268
|
export * from './pages/my-sonic/widgets/connected-ship-to-address-widget';
|
|
269
269
|
export * from './pages/my-sonic/widgets/connected-user-account-widget';
|
|
270
|
-
export * from './pages/paths';
|
|
271
270
|
export * from './pages/product/components/product-overview';
|
|
272
271
|
export * from './pages/product/layouts/product-details-page-layout/product-details-page-layout';
|
|
273
272
|
export * from './pages/product/product-details-page/components/product-details-images/product-detail-images';
|
|
@@ -404,6 +403,7 @@ export * from './shared/routing/types';
|
|
|
404
403
|
export * from './shared/routing/use-location';
|
|
405
404
|
export * from './shared/routing/use-navigate';
|
|
406
405
|
export * from './shared/routing/use-on-navigate';
|
|
406
|
+
export * from './shared/routing/use-paths';
|
|
407
407
|
export * from './shared/routing/use-route-link';
|
|
408
408
|
export * from './shared/routing/use-route-link-element';
|
|
409
409
|
export * from './shared/routing/with-routing';
|
|
@@ -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(
|
|
16
|
+
const currentCountry = countries.find(c => c.id === address?.country?.id) || _currentCountry;
|
|
17
17
|
const [selectedCountry, setSelectedCountry] = useState(currentCountry);
|
|
18
|
-
const currencyHasChanged =
|
|
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: !
|
|
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)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export interface ConnectedAccountButtonProps {
|
|
2
2
|
className?: string;
|
|
3
3
|
'data-test-selector'?: string;
|
|
4
|
-
href?: string;
|
|
5
4
|
onClick?: () => void;
|
|
6
5
|
}
|
|
7
|
-
export declare function ConnectedAccountButton({ className, 'data-test-selector': dataTestSelector,
|
|
6
|
+
export declare function ConnectedAccountButton({ className, 'data-test-selector': dataTestSelector, onClick, }: ConnectedAccountButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,12 +3,18 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
3
3
|
import { IconButton } from '../../../buttons/icon-button/icon-button.js';
|
|
4
4
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
5
5
|
import { AccountIcon } from '../../../navigation/account-icon/account-icon.js';
|
|
6
|
-
import {
|
|
6
|
+
import { useIsAuthenticated } from '../../../shared/api/storefront/hooks/authentication/use-is-authenticated.js';
|
|
7
|
+
import { useLocation } from '../../../shared/routing/use-location.js';
|
|
8
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
7
9
|
|
|
8
|
-
function ConnectedAccountButton({ className, 'data-test-selector': dataTestSelector,
|
|
10
|
+
function ConnectedAccountButton({ className, 'data-test-selector': dataTestSelector, onClick, }) {
|
|
11
|
+
const paths = usePaths();
|
|
9
12
|
const t = useFormattedMessage();
|
|
10
|
-
const
|
|
11
|
-
|
|
13
|
+
const isAuthenticated = useIsAuthenticated();
|
|
14
|
+
const { href: returnUrl } = useLocation();
|
|
15
|
+
return (jsx(IconButton, { className: className, "data-authenticated": isAuthenticated ? true : false, "data-test-selector": dataTestSelector, href: isAuthenticated
|
|
16
|
+
? paths.ACCOUNT
|
|
17
|
+
: `${paths.SIGN_IN}${returnUrl ? `?returnUrl=${encodeURIComponent(returnUrl)}` : ''}`, onClick: onClick, children: jsx(AccountIcon, { "aria-label": isAuthenticated ? t('My Sonic') : t('Sign in or create account'), isAuthenticated: isAuthenticated }) }));
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
export { ConnectedAccountButton };
|
package/dist/header/header.js
CHANGED
|
@@ -5,11 +5,11 @@ import clsx from 'clsx';
|
|
|
5
5
|
import { useDrawer } from '../drawer/use-drawer.js';
|
|
6
6
|
import { useGlobalSearchDisclosure } from '../global-search/global-search-provider/use-search-disclosure.js';
|
|
7
7
|
import { useFormattedMessage } from '../intl/use-formatted-message.js';
|
|
8
|
-
import { PATHS } from '../pages/paths.js';
|
|
9
8
|
import { isNavigationLink, isNavigationSection, isNavigationLinkItem } from '../shared/api/bff/model/bff.model.js';
|
|
10
9
|
import { useIsBreakpoint } from '../shared/hooks/use-is-breakpoint.js';
|
|
11
10
|
import { useResizeObserver } from '../shared/hooks/use-resize-observer.js';
|
|
12
11
|
import { useOnNavigate } from '../shared/routing/use-on-navigate.js';
|
|
12
|
+
import { usePaths } from '../shared/routing/use-paths.js';
|
|
13
13
|
import { ConnectedAccountButton } from './buttons/account/connected-account-button.js';
|
|
14
14
|
import { ConnectedCartButton } from './buttons/cart/connected-cart-button.js';
|
|
15
15
|
import { ConnectedFavoritesButton } from './buttons/favorites/connected-favorites-button.js';
|
|
@@ -24,6 +24,7 @@ import { SonicLogo } from './sonic-logo/sonic-logo.js';
|
|
|
24
24
|
import styles from './header.module.css.js';
|
|
25
25
|
|
|
26
26
|
function Header({ className, headerNavigationSection, sticky, }) {
|
|
27
|
+
const paths = usePaths();
|
|
27
28
|
const [activeLinkGroup, setActiveLinkGroup] = useState();
|
|
28
29
|
const t = useFormattedMessage();
|
|
29
30
|
const isXl = useIsBreakpoint('xl');
|
|
@@ -72,7 +73,7 @@ function Header({ className, headerNavigationSection, sticky, }) {
|
|
|
72
73
|
const mainNavigationSection = headerNavigationSection?.items
|
|
73
74
|
.filter(isNavigationSection)
|
|
74
75
|
.find(item => item.key === 'main-navigation');
|
|
75
|
-
return (jsxs(Fragment, { children: [jsx("header", { ref: headerRef, className: clsx(styles['header'], sticky && styles['sticky'], className), "data-test-selector": "pageHeader", children: jsx(HeaderLayout, { hamburgerButton: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", "data-test-selector": "pageHeaderHamburgerButton", isActive: mobileNavigationOpen, onActiveChange: toggleMobileNavigation }), hasDrawersOpen: hasDrawersOpen, logo: jsx(SonicLogo, { "data-test-selector": "pageHeaderLogo", href: homeLink?.href || undefined, title: t('Home') }), mainNavigation: jsx(NavigationLinkList, { activeLink: activeLinkGroup, "data-test-selector": "pageHeaderMainNavigation", navigationSection: mainNavigationSection, onSubmenuToggle: toggleActiveSubmenu }), navigationActions: jsxs(Fragment, { children: [jsx(ConnectedAccountButton, { "data-test-selector": "pageHeaderAccountButton"
|
|
76
|
+
return (jsxs(Fragment, { children: [jsx("header", { ref: headerRef, className: clsx(styles['header'], sticky && styles['sticky'], className), "data-test-selector": "pageHeader", children: jsx(HeaderLayout, { hamburgerButton: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", "data-test-selector": "pageHeaderHamburgerButton", isActive: mobileNavigationOpen, onActiveChange: toggleMobileNavigation }), hasDrawersOpen: hasDrawersOpen, logo: jsx(SonicLogo, { "data-test-selector": "pageHeaderLogo", href: homeLink?.href || undefined, title: t('Home') }), mainNavigation: jsx(NavigationLinkList, { activeLink: activeLinkGroup, "data-test-selector": "pageHeaderMainNavigation", navigationSection: mainNavigationSection, onSubmenuToggle: toggleActiveSubmenu }), navigationActions: jsxs(Fragment, { children: [jsx(ConnectedAccountButton, { "data-test-selector": "pageHeaderAccountButton" }), jsx(ConnectedFavoritesButton, { "data-test-selector": "pageHeaderFavoritesButton", href: paths.FAVORITES }), jsx(ConnectedCartButton, { "data-test-selector": "pageHeaderCartButton", href: paths.CART })] }), search: jsx(SearchButton, { "aria-controls": "global-search", "data-test-selector": "pageHeaderSearchButton", isActive: searchOpen, onActiveChange: toggleSearch }) }) }), jsx(SearchDrawer, { groupId: searchGroupId, instanceId: searchInstanceId }), !isXl && (jsx(MobileNavigationDrawer, { groupId: mobileNavigationDrawer.groupId, instanceId: mobileNavigationDrawer.instanceId, linkItems: mainNavigationSection?.items.filter(isNavigationLinkItem) })), isXl && (jsx(DesktopNavigationDrawer, { groupId: desktopNavigationDrawer.groupId, instanceId: desktopNavigationDrawer.instanceId, linkGroup: activeLinkGroup, onClosed: () => setActiveLinkGroup(undefined) }))] }));
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export { Header };
|
package/dist/index.js
CHANGED
|
@@ -262,14 +262,13 @@ export { MySonicLayoutTitle } from './pages/my-sonic/layouts/my-sonic-layout/my-
|
|
|
262
262
|
export { ConnectedMySonicNavigation } from './pages/my-sonic/navigation/connected-my-sonic-navigation.js';
|
|
263
263
|
export { MySonicDesktopNavigation } from './pages/my-sonic/navigation/my-sonic-desktop-navigation.js';
|
|
264
264
|
export { MySonicMobileNavigation } from './pages/my-sonic/navigation/my-sonic-mobile-navigation.js';
|
|
265
|
-
export {
|
|
265
|
+
export { useMySonicNavigationItems } from './pages/my-sonic/navigation/my-sonic-navigation-items.js';
|
|
266
266
|
export { OrderHistory } from './pages/my-sonic/pages/order-history/order-history.js';
|
|
267
267
|
export { AddressDataCard } from './pages/my-sonic/widgets/components/address-data-card.js';
|
|
268
268
|
export { ConnectedBillToAddressWidget } from './pages/my-sonic/widgets/connected-bill-to-address-widget.js';
|
|
269
269
|
export { ConnectedCustomerInformationWidget } from './pages/my-sonic/widgets/connected-customer-information-widget.js';
|
|
270
270
|
export { ConnectedShipToAddressWidget } from './pages/my-sonic/widgets/connected-ship-to-address-widget.js';
|
|
271
271
|
export { ConnectedUserAccountWidget } from './pages/my-sonic/widgets/connected-user-account-widget.js';
|
|
272
|
-
export { PATHS } from './pages/paths.js';
|
|
273
272
|
export { ProductOverview } from './pages/product/components/product-overview.js';
|
|
274
273
|
export { ProductDetailsPageLayout } from './pages/product/layouts/product-details-page-layout/product-details-page-layout.js';
|
|
275
274
|
export { ProductDetailImages } from './pages/product/product-details-page/components/product-details-images/product-detail-images.js';
|
|
@@ -361,7 +360,7 @@ export { fetchTranslations } from './shared/api/storefront/services/translation-
|
|
|
361
360
|
export { fetchCountriesLanguages, fetchCountriesWithLanguages, fetchSettings, updateLocale } from './shared/api/storefront/services/website-service.js';
|
|
362
361
|
export { WishListNameAlreadyExistsError, addWishListItemToWishList, createWishList, deleteWishList, deleteWishListItemFromWishList, getWishList, getWishListItemsByWishListId, getWishLists } from './shared/api/storefront/services/wishlist-service.js';
|
|
363
362
|
export { cart } from './shared/data/cart.data.js';
|
|
364
|
-
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';
|
|
365
364
|
export { navigationData } from './shared/data/navigation.js';
|
|
366
365
|
export { useFeatureFlags } from './shared/feature-flags/use-feature-flags.js';
|
|
367
366
|
export { BadRequestError, ForbiddenRequestError, InternalServerErrorRequestError, NotFoundRequestError, RequestError, TimeoutRequestError, UnauthorizedRequestError, UnprocessableContentRequestError, isFormData, isJsonBody, isRequestError, request } from './shared/fetch/request.js';
|
|
@@ -403,6 +402,7 @@ export { buildHref } from './shared/routing/route-utils.js';
|
|
|
403
402
|
export { useLocation } from './shared/routing/use-location.js';
|
|
404
403
|
export { useNavigate } from './shared/routing/use-navigate.js';
|
|
405
404
|
export { useOnNavigate } from './shared/routing/use-on-navigate.js';
|
|
405
|
+
export { usePaths } from './shared/routing/use-paths.js';
|
|
406
406
|
export { useRouteLink } from './shared/routing/use-route-link.js';
|
|
407
407
|
export { useRouteLinkElement } from './shared/routing/use-route-link-element.js';
|
|
408
408
|
export { withRouting } from './shared/routing/with-routing.js';
|
|
@@ -6,9 +6,9 @@ import { SonicLogo } from '../../header/sonic-logo/sonic-logo.js';
|
|
|
6
6
|
import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
7
7
|
import { MenuList } from '../../lists/menu-list/menu-list.js';
|
|
8
8
|
import { MenuListItem } from '../../lists/menu-list/menu-list-item.js';
|
|
9
|
-
import { PATHS } from '../../pages/paths.js';
|
|
10
9
|
import { useFetchSession } from '../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
|
|
11
10
|
import { useFetchCurrentCartCount } from '../../shared/api/storefront/hooks/cart/use-fetch-current-cart-count.js';
|
|
11
|
+
import { usePaths } from '../../shared/routing/use-paths.js';
|
|
12
12
|
import { AccountIcon } from '../account-icon/account-icon.js';
|
|
13
13
|
import { CartIcon } from '../cart-icon/cart-icon.js';
|
|
14
14
|
import { FavoriteIcon } from '../favorite-icon/favorite-icon.js';
|
|
@@ -17,9 +17,10 @@ import styles from './mobile-navigation.module.css.js';
|
|
|
17
17
|
|
|
18
18
|
function MobileNavigation({ id, isActive, linkItems, onActiveChange, }) {
|
|
19
19
|
const t = useFormattedMessage();
|
|
20
|
+
const paths = usePaths();
|
|
20
21
|
const { data: { isAuthenticated } = {} } = useFetchSession();
|
|
21
22
|
const cartCount = useFetchCurrentCartCount();
|
|
22
|
-
return (jsxs("section", { "aria-label": t('Main menu'), className: clsx(styles['mobile-navigation'], isActive && styles['active']), "data-test-selector": "mobileNavigationMenu", id: id, children: [jsxs("header", { className: styles['header'], children: [jsx("div", { className: styles['logo'], role: "presentation", children: jsx(SonicLogo, {}) }), jsx("div", { className: styles['hamburger'], children: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", "data-test-selector": "mobileNavigationHamburgerButton", isActive: isActive, onActiveChange: onActiveChange }) })] }), jsx(PanelNavigation, { allowBack: true, className: styles['panels'], "data-test-selector": "mobileNavigationPanel", isNarrow: true, linkItems: linkItems, variant: "primary", children: jsxs(MenuList, { header: { label: t('My Sonic') }, scrollable: false, children: [jsx(MenuListItem, { badge: jsx(AccountIcon, { isAuthenticated: isAuthenticated }), "data-authenticated": isAuthenticated ? true : false, "data-test-selector": "mobileNavigationAccountButton", href:
|
|
23
|
+
return (jsxs("section", { "aria-label": t('Main menu'), className: clsx(styles['mobile-navigation'], isActive && styles['active']), "data-test-selector": "mobileNavigationMenu", id: id, children: [jsxs("header", { className: styles['header'], children: [jsx("div", { className: styles['logo'], role: "presentation", children: jsx(SonicLogo, {}) }), jsx("div", { className: styles['hamburger'], children: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", "data-test-selector": "mobileNavigationHamburgerButton", isActive: isActive, onActiveChange: onActiveChange }) })] }), jsx(PanelNavigation, { allowBack: true, className: styles['panels'], "data-test-selector": "mobileNavigationPanel", isNarrow: true, linkItems: linkItems, variant: "primary", children: jsxs(MenuList, { header: { label: t('My Sonic') }, scrollable: false, children: [jsx(MenuListItem, { badge: jsx(AccountIcon, { isAuthenticated: isAuthenticated }), "data-authenticated": isAuthenticated ? true : false, "data-test-selector": "mobileNavigationAccountButton", href: paths.ACCOUNT, children: isAuthenticated ? t('My Sonic') : t('Sign in or create account') }), jsx(MenuListItem, { badge: jsx(FavoriteIcon, {}), "data-test-selector": "mobileNavigationFavoritesButton", href: paths.FAVORITES, children: t('Favorites') }), jsx(MenuListItem, { badge: jsx(CartIcon, { count: cartCount }), "data-count": cartCount, "data-test-selector": "mobileNavigationCartButton", href: paths.CART, children: t('Shopping cart') })] }) })] }));
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export { MobileNavigation };
|
|
@@ -8,19 +8,20 @@ import { useCreateAccount } from '../../../shared/api/storefront/hooks/account/u
|
|
|
8
8
|
import { useFetchSession } from '../../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
|
|
9
9
|
import { ExistingAccountError } from '../../../shared/api/storefront/services/account-service.js';
|
|
10
10
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
11
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
11
12
|
import { LoadingPage } from '../../loading-page/loading-page.js';
|
|
12
|
-
import { PATHS } from '../../paths.js';
|
|
13
13
|
import { CreateAccountForm } from '../components/create-account-form/create-account-form.js';
|
|
14
14
|
import { SignInPageLayout } from '../layouts/sign-in-page-layout/sign-in-page-layout.js';
|
|
15
15
|
|
|
16
16
|
function CreateAccountPage({ returnUrl } = {}) {
|
|
17
|
+
const paths = usePaths();
|
|
17
18
|
const { navigate } = useNavigate();
|
|
18
19
|
const { data: session, isLoading: isLoadingSession } = useFetchSession();
|
|
19
20
|
const { error: errorCreateAccount, isPending: isPendingCreateAccount, isSuccess, mutate: createAccount, } = useCreateAccount();
|
|
20
21
|
const isExistingAccount = errorCreateAccount instanceof ExistingAccountError;
|
|
21
22
|
const isDisabled = isSuccess || isExistingAccount;
|
|
22
|
-
const continuePath = returnUrl && returnUrl !==
|
|
23
|
-
const isReturnToShipping = returnUrl ===
|
|
23
|
+
const continuePath = returnUrl && returnUrl !== paths.ACCOUNT_CREATE ? returnUrl : paths.ACCOUNT;
|
|
24
|
+
const isReturnToShipping = returnUrl === paths.CHECKOUT_SHIPPING;
|
|
24
25
|
const onSubmit = ({ data }) => {
|
|
25
26
|
createAccount(data, {
|
|
26
27
|
onSuccess() {
|
|
@@ -39,7 +40,7 @@ function CreateAccountPage({ returnUrl } = {}) {
|
|
|
39
40
|
navigate(continuePath, { reload: true });
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
|
-
return (jsxs(Fragment, { children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(CreateAccountForm, { errorType: errorType, isDisabled: isDisabled, isPendingCreateAccount: isPendingCreateAccount, onSubmit: onSubmit }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: continuePath, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isSuccess && !isReturnToShipping, title: "Account created", children: jsx("p", { children: jsx(FormattedMessage, { id: "Your new Sonic Equipment account was succesfully created. You should receive an email soon with further instructions on how to activate this account. If you do not receive this email, please contact Customer Support." }) }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: `${
|
|
43
|
+
return (jsxs(Fragment, { children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(CreateAccountForm, { errorType: errorType, isDisabled: isDisabled, isPendingCreateAccount: isPendingCreateAccount, onSubmit: onSubmit }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: continuePath, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isSuccess && !isReturnToShipping, title: "Account created", children: jsx("p", { children: jsx(FormattedMessage, { id: "Your new Sonic Equipment account was succesfully created. You should receive an email soon with further instructions on how to activate this account. If you do not receive this email, please contact Customer Support." }) }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: `${paths.SIGN_IN}${returnUrl ? `?returnUrl=${continuePath}` : ''}`, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue to sign in" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isExistingAccount, title: "Existing account", children: jsx("p", { children: jsx(FormattedMessage, { id: "The email address you entered is already associated with an existing account. Please sign in to this account or contact Customer Support." }) }) })] }));
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
export { CreateAccountPage };
|
|
@@ -8,11 +8,12 @@ import { useSignIn } from '../../../shared/api/storefront/hooks/authentication/u
|
|
|
8
8
|
import { isRequestError } from '../../../shared/fetch/request.js';
|
|
9
9
|
import { useDisclosure } from '../../../shared/hooks/use-disclosure.js';
|
|
10
10
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
11
|
-
import {
|
|
11
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
12
12
|
import { SignInForm } from '../components/sign-in-form/sign-in-form.js';
|
|
13
13
|
import { SignInPageLayout } from '../layouts/sign-in-page-layout/sign-in-page-layout.js';
|
|
14
14
|
|
|
15
15
|
function SignInPage({ returnUrl } = {}) {
|
|
16
|
+
const paths = usePaths();
|
|
16
17
|
const { navigate } = useNavigate();
|
|
17
18
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
18
19
|
const { isOpen: isRecoverPasswordDialogOpen, setIsOpen: setRecoverPasswordDialogOpen, } = useDisclosure(false);
|
|
@@ -33,10 +34,10 @@ function SignInPage({ returnUrl } = {}) {
|
|
|
33
34
|
}, [errorCreateGuest, errorSignIn]);
|
|
34
35
|
const onSuccess = () => {
|
|
35
36
|
setIsSuccess(true);
|
|
36
|
-
navigate(returnUrl ||
|
|
37
|
+
navigate(returnUrl || paths.HOME, { reload: true });
|
|
37
38
|
};
|
|
38
|
-
const allowGuestSignIn = returnUrl ===
|
|
39
|
-
const createAccountPath = `${
|
|
39
|
+
const allowGuestSignIn = returnUrl === paths.CHECKOUT_SHIPPING;
|
|
40
|
+
const createAccountPath = `${paths.ACCOUNT_CREATE}${returnUrl ? `?returnUrl=${returnUrl}` : ''}`;
|
|
40
41
|
const onSubmit = ({ data }) => {
|
|
41
42
|
resetSignIn();
|
|
42
43
|
resetCreateGuest();
|
|
@@ -19,11 +19,12 @@ import { Button } from '../../../buttons/button/button.js';
|
|
|
19
19
|
import { useFetchCurrentCartLinesWithAtp } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-lines-with-atp.js';
|
|
20
20
|
import { useFetchCurrentCartWithAtp } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-with-atp.js';
|
|
21
21
|
import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
|
|
22
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
22
23
|
import { ensureNumber } from '../../../shared/utils/number.js';
|
|
23
|
-
import { PATHS } from '../../paths.js';
|
|
24
24
|
import { EmptyCart } from './components/empty-cart-page.js';
|
|
25
25
|
|
|
26
26
|
function CartContent({ cartLines }) {
|
|
27
|
+
const paths = usePaths();
|
|
27
28
|
const { addToast } = useToast();
|
|
28
29
|
const { data: currentCart } = useFetchCurrentCartWithAtp();
|
|
29
30
|
const saveCartForLater = useSaveCartForLater({
|
|
@@ -84,7 +85,7 @@ function CartContent({ cartLines }) {
|
|
|
84
85
|
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutShippingCartTotalContinueButton", href: "/CheckoutShipping", children: jsx(FormattedMessage, { id: "Start checkout" }) })),
|
|
85
86
|
secondary: isAuthenticated ? (jsx(Button, { color: "secondary", "data-test-selector": "saveCartForLaterButton", onClick: () => {
|
|
86
87
|
saveCartForLater.mutate({ cart: currentCart });
|
|
87
|
-
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })) : (jsx(Button, { color: "secondary", "data-test-selector": "saveCartForLaterButton", href:
|
|
88
|
+
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })) : (jsx(Button, { color: "secondary", "data-test-selector": "saveCartForLaterButton", href: paths.SIGN_IN, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })),
|
|
88
89
|
}, mobileSummary: jsx(CartTotalsSummary, { currencyCode: currencyCode, totalAmount: currentCart.orderGrandTotal }), overview: jsx(CartTotals, { currencyCode: currencyCode, shippingCost: currentCart.shippingAndHandling, subtotal: currentCart.orderSubTotal, tax: currentCart.totalTax, total: currentCart.orderGrandTotal, vatPercentage: cartLines[0]?.pricing?.vatRate || 0 }), children: jsx(OrderLineList, { onRemoveAll: () => deleteCurrentCart.mutate(), children: cartLines.map(cartLine => (jsx(ConnectedOrderLineCard, { deliveryDate: cartLine.atp?.date ?? null, href: cartLine.productUri, image: {
|
|
89
90
|
fit: 'contain',
|
|
90
91
|
image: {
|
|
@@ -102,6 +103,7 @@ function CartContent({ cartLines }) {
|
|
|
102
103
|
}, productId: cartLine.productId || '', sku: cartLine.erpNumber || '', tags: [cartLine.properties.label].filter(Boolean), title: cartLine.shortDescription }, cartLine.id))) }) }));
|
|
103
104
|
}
|
|
104
105
|
function CartPage() {
|
|
106
|
+
const paths = usePaths();
|
|
105
107
|
const t = useFormattedMessage();
|
|
106
108
|
const { data: cartLines, error, isLoading, } = useFetchCurrentCartLinesWithAtp();
|
|
107
109
|
if (error)
|
|
@@ -109,9 +111,9 @@ function CartPage() {
|
|
|
109
111
|
if (isLoading)
|
|
110
112
|
return jsx(LoadingPage, {});
|
|
111
113
|
return (jsx(Page, { breadcrumb: [
|
|
112
|
-
{ href:
|
|
113
|
-
{ href:
|
|
114
|
-
], canonicalUrl:
|
|
114
|
+
{ href: paths.HOME, label: 'home' },
|
|
115
|
+
{ href: paths.CART, label: t('Cart') },
|
|
116
|
+
], canonicalUrl: paths.CART, "data-test-selector": "cartPage", title: t('Cart'), children: cartLines?.length ? (jsx(CartContent, { cartLines: cartLines })) : (jsx(EmptyCart, {})) }));
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
export { CartPage };
|
|
@@ -11,10 +11,10 @@ import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
|
11
11
|
import { OrderLineList } from '../../../lists/orderline-list/orderline-list.js';
|
|
12
12
|
import { useSaveCartForLater } from '../../../shared/api/storefront/hooks/cart/use-save-cart-for-later.js';
|
|
13
13
|
import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
|
|
14
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
14
15
|
import { ensureNumber } from '../../../shared/utils/number.js';
|
|
15
16
|
import { useToast } from '../../../toast/use-toast.js';
|
|
16
17
|
import { Page } from '../../components/page/page.js';
|
|
17
|
-
import { PATHS } from '../../paths.js';
|
|
18
18
|
import { BillingAndInvoiceInformation } from '../components/billing-and-invoice-information.js';
|
|
19
19
|
import { CheckoutPageLayout } from '../layouts/checkout-page-layout/checkout-page-layout.js';
|
|
20
20
|
import { CheckoutPageSection } from '../layouts/checkout-page-layout/components/checkout-page-section.js';
|
|
@@ -23,6 +23,7 @@ import styles from './order-confirmation-page.module.css.js';
|
|
|
23
23
|
|
|
24
24
|
function OrderConfirmationPageContent({ cart, }) {
|
|
25
25
|
const t = useFormattedMessage();
|
|
26
|
+
const paths = usePaths();
|
|
26
27
|
const { addToast } = useToast();
|
|
27
28
|
const saveCartForLater = useSaveCartForLater({
|
|
28
29
|
onError: () => {
|
|
@@ -44,9 +45,9 @@ function OrderConfirmationPageContent({ cart, }) {
|
|
|
44
45
|
if (!currencyCode)
|
|
45
46
|
throw new Error(`Currency code not found for symbol ${cart.currencySymbol}`);
|
|
46
47
|
return (jsx(Page, { breadcrumb: [
|
|
47
|
-
{ href:
|
|
48
|
+
{ href: paths.HOME, label: t('Home') },
|
|
48
49
|
{
|
|
49
|
-
href: `${
|
|
50
|
+
href: `${paths.ORDER_CONFIRMATION}?cartId=${cart.id}`,
|
|
50
51
|
label: t('Order confirmation'),
|
|
51
52
|
},
|
|
52
53
|
], "data-test-selector": "orderConfirmationPage", title: t('Order confirmation'), children: jsx(CheckoutPageLayout, { actions: {
|
|
@@ -5,12 +5,13 @@ import { LoadingPage } from '../../loading-page/loading-page.js';
|
|
|
5
5
|
import { useIsAuthenticated } from '../../../shared/api/storefront/hooks/authentication/use-is-authenticated.js';
|
|
6
6
|
import { useFetchCartById } from '../../../shared/api/storefront/hooks/cart/use-fetch-cart-by-id.js';
|
|
7
7
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
8
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
8
9
|
import { hasNo } from '../../../shared/utils/types.js';
|
|
9
10
|
import { ErrorPage } from '../../error-page/error-page.js';
|
|
10
|
-
import { PATHS } from '../../paths.js';
|
|
11
11
|
import { OrderConfirmationPageContent } from './order-confirmation-page-content.js';
|
|
12
12
|
|
|
13
13
|
function OrderConfirmationPage({ cartId }) {
|
|
14
|
+
const paths = usePaths();
|
|
14
15
|
const isAuthenticated = useIsAuthenticated();
|
|
15
16
|
const { isNavigating, navigate } = useNavigate();
|
|
16
17
|
const { data: cart, error, isLoading: cartIsLoading, } = useFetchCartById({
|
|
@@ -22,10 +23,10 @@ function OrderConfirmationPage({ cartId }) {
|
|
|
22
23
|
if (isAuthenticated === undefined)
|
|
23
24
|
return;
|
|
24
25
|
if (!isAuthenticated)
|
|
25
|
-
return navigate(
|
|
26
|
+
return navigate(paths.CART);
|
|
26
27
|
if (cart.status === 'Cart')
|
|
27
|
-
navigate(
|
|
28
|
-
}, [cart, navigate, isAuthenticated]);
|
|
28
|
+
navigate(paths.CART);
|
|
29
|
+
}, [cart, navigate, isAuthenticated, paths]);
|
|
29
30
|
if (error)
|
|
30
31
|
return jsx(ErrorPage, { error: error });
|
|
31
32
|
if (cartIsLoading || isNavigating)
|
|
@@ -8,9 +8,9 @@ import { FormattedMessage } from '../../../intl/formatted-message.js';
|
|
|
8
8
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
9
9
|
import { OrderLineList } from '../../../lists/orderline-list/orderline-list.js';
|
|
10
10
|
import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
|
|
11
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
11
12
|
import { ensureNumber } from '../../../shared/utils/number.js';
|
|
12
13
|
import { Page } from '../../components/page/page.js';
|
|
13
|
-
import { PATHS } from '../../paths.js';
|
|
14
14
|
import { CheckoutPageLayout } from '../layouts/checkout-page-layout/checkout-page-layout.js';
|
|
15
15
|
import { CheckoutPageSection } from '../layouts/checkout-page-layout/components/checkout-page-section.js';
|
|
16
16
|
import { CheckoutPageSectionContent } from '../layouts/checkout-page-layout/components/checkout-page-section-content.js';
|
|
@@ -18,13 +18,14 @@ import { Payment } from './components/payment.js';
|
|
|
18
18
|
|
|
19
19
|
function PaymentPageContent({ atp, cart, formId, hasAtp, isProcessing, onPaymentComplete, setIsProcessing, }) {
|
|
20
20
|
const t = useFormattedMessage();
|
|
21
|
+
const paths = usePaths();
|
|
21
22
|
const currencyCode = getCurrencyCodeBySymbol(cart.currencySymbol);
|
|
22
23
|
if (!currencyCode)
|
|
23
24
|
throw new Error(`Currency code not found for symbol ${cart.currencySymbol}`);
|
|
24
25
|
return (jsx(Page, { breadcrumb: [
|
|
25
|
-
{ href:
|
|
26
|
+
{ href: paths.HOME, label: t('Home') },
|
|
26
27
|
{
|
|
27
|
-
href:
|
|
28
|
+
href: paths.REVIEW_AND_SUBMIT,
|
|
28
29
|
label: t('Review and payment'),
|
|
29
30
|
},
|
|
30
31
|
], "data-test-selector": "paymentPage", title: t('Review and payment'), children: jsxs(CheckoutPageLayout, { actions: {
|
|
@@ -5,15 +5,16 @@ import { useIsAuthenticated } from '../../../shared/api/storefront/hooks/authent
|
|
|
5
5
|
import { useFetchCurrentCheckoutAtp } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-checkout-atp.js';
|
|
6
6
|
import { useFetchCurrentCartWithAtp } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-with-atp.js';
|
|
7
7
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
8
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
8
9
|
import { hasNo } from '../../../shared/utils/types.js';
|
|
9
10
|
import { ErrorPage } from '../../error-page/error-page.js';
|
|
10
11
|
import { LoadingPage } from '../../loading-page/loading-page.js';
|
|
11
|
-
import { PATHS } from '../../paths.js';
|
|
12
12
|
import { useHasReturnedFromAdyen } from './hooks/use-has-returned-from-adyen.js';
|
|
13
13
|
import { PaymentPageContent } from './payment-page-content.js';
|
|
14
14
|
|
|
15
15
|
const PAYMENT_FORM_ID = 'paymentForm';
|
|
16
16
|
function PaymentPage() {
|
|
17
|
+
const paths = usePaths();
|
|
17
18
|
const hasReturnedFromAdyen = useHasReturnedFromAdyen();
|
|
18
19
|
const isAuthenticated = useIsAuthenticated();
|
|
19
20
|
const { data: cart, error, isLoading: isLoadingCart, } = useFetchCurrentCartWithAtp({
|
|
@@ -25,24 +26,24 @@ function PaymentPage() {
|
|
|
25
26
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
26
27
|
const { isNavigating, navigate } = useNavigate();
|
|
27
28
|
const onPaymentComplete = useCallback(({ cartId }) => {
|
|
28
|
-
navigate(`${
|
|
29
|
-
}, [navigate]);
|
|
29
|
+
navigate(`${paths.ORDER_CONFIRMATION}?cartId=${cartId}`);
|
|
30
|
+
}, [navigate, paths]);
|
|
30
31
|
useEffect(() => {
|
|
31
32
|
if (isNavigating)
|
|
32
33
|
return;
|
|
33
34
|
if (isAuthenticated === undefined)
|
|
34
35
|
return;
|
|
35
36
|
if (!isAuthenticated)
|
|
36
|
-
return navigate(
|
|
37
|
+
return navigate(paths.CHECKOUT_SHIPPING_VIA_SIGNIN);
|
|
37
38
|
if (hasNo(cart))
|
|
38
39
|
return;
|
|
39
40
|
if (hasNo(cart.cartLines) || cart.cartLines.length === 0)
|
|
40
|
-
return navigate(
|
|
41
|
+
return navigate(paths.CART);
|
|
41
42
|
if (hasNo(cart.billTo))
|
|
42
|
-
return navigate(
|
|
43
|
+
return navigate(paths.CHECKOUT_SHIPPING_VIA_SIGNIN);
|
|
43
44
|
if (hasNo(cart.billTo.address1))
|
|
44
|
-
return navigate(
|
|
45
|
-
}, [cart, navigate, isAuthenticated, isNavigating]);
|
|
45
|
+
return navigate(paths.CHECKOUT_SHIPPING);
|
|
46
|
+
}, [cart, navigate, isAuthenticated, isNavigating, paths]);
|
|
46
47
|
if (error)
|
|
47
48
|
return jsx(ErrorPage, { error: error });
|
|
48
49
|
if (!isAtpLoading && !atp)
|
|
@@ -4,11 +4,12 @@ import { Link } from '../../../../buttons/link/link.js';
|
|
|
4
4
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
5
5
|
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
6
6
|
import { Dialog } from '../../../../modals/dialog/dialog.js';
|
|
7
|
-
import {
|
|
7
|
+
import { usePaths } from '../../../../shared/routing/use-paths.js';
|
|
8
8
|
|
|
9
9
|
function CurrencyChangeDialog({ isOpen, onOpenChange, onSubmit, }) {
|
|
10
10
|
const t = useFormattedMessage();
|
|
11
|
-
|
|
11
|
+
const paths = usePaths();
|
|
12
|
+
return (jsx(Dialog, { "data-test-selector": "currencyChangeDialog", isOpen: isOpen, onOpenChange: onOpenChange, onSubmit: onSubmit, shouldCloseOnInteractOutside: true, submitLabel: "Continue", title: t('Currency Change'), children: jsxs("p", { children: [jsx(FormattedMessage, { id: "You selected a country where we invoice in a different currency. This will result in your cart being converted to the new currency. If you would like to review your order, " }), jsx(Link, { hasUnderline: true, color: "secondary", href: paths.CART, onClick: onSubmit, children: jsx(FormattedMessage, { id: "please go back to your cart." }) }), ' ', jsx(FormattedMessage, { id: "If you want to proceed, click the continue button. If you want to change your country, close this message and select a different country." })] }) }));
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export { CurrencyChangeDialog };
|
package/dist/pages/checkout/shipping-page/components/edit-checkout-bill-to-address-form.d.ts
CHANGED
|
@@ -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 };
|
|
@@ -7,7 +7,7 @@ import { Checkbox } from '../../../../forms/elements/checkbox/checkbox.js';
|
|
|
7
7
|
import { TextField } from '../../../../forms/fields/text-field/text-field.js';
|
|
8
8
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
9
9
|
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
10
|
-
import {
|
|
10
|
+
import { usePaths } from '../../../../shared/routing/use-paths.js';
|
|
11
11
|
import { CheckoutPageSection } from '../../layouts/checkout-page-layout/components/checkout-page-section.js';
|
|
12
12
|
import { CheckoutPageSectionContent } from '../../layouts/checkout-page-layout/components/checkout-page-section-content.js';
|
|
13
13
|
import { CheckoutPageSectionLink } from '../../layouts/checkout-page-layout/components/checkout-page-section-link.js';
|
|
@@ -17,6 +17,7 @@ import styles from './readonly-address.module.css.js';
|
|
|
17
17
|
|
|
18
18
|
function ReadOnlyAddresses({ billTo, isLoading, isPickup, notes, onSubmit, shipTo, }) {
|
|
19
19
|
const t = useFormattedMessage();
|
|
20
|
+
const paths = usePaths();
|
|
20
21
|
return (jsxs(Form, { id: EDIT_ADDRESS_FORM_ID, onSubmit: e => {
|
|
21
22
|
e.preventDefault();
|
|
22
23
|
const formData = new FormData(e.currentTarget);
|
|
@@ -25,7 +26,7 @@ function ReadOnlyAddresses({ billTo, isLoading, isPickup, notes, onSubmit, shipT
|
|
|
25
26
|
? undefined
|
|
26
27
|
: formData.get('notes')?.toString() || '',
|
|
27
28
|
});
|
|
28
|
-
}, children: [jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: [jsx(CheckoutPageSectionLink, { children: jsxs(Link, { color: "secondary", href:
|
|
29
|
+
}, children: [jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: [jsx(CheckoutPageSectionLink, { children: jsxs(Link, { color: "secondary", href: paths.ACCOUNT_ADDRESSES, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit billing address" }), " >"] }) }), jsxs(CheckoutPageSectionContent, { children: [billTo && (jsx(AddressInfoDisplay, { address: {
|
|
29
30
|
address1: billTo.address1,
|
|
30
31
|
address2: billTo.address2,
|
|
31
32
|
address3: billTo.address3,
|
|
@@ -38,7 +39,7 @@ function ReadOnlyAddresses({ billTo, isLoading, isPickup, notes, onSubmit, shipT
|
|
|
38
39
|
lastName: billTo.lastName,
|
|
39
40
|
phone: billTo.phone,
|
|
40
41
|
postalCode: billTo.postalCode,
|
|
41
|
-
}, "data-test-selector": "billToAddress" })), 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(Link, { color: "secondary", href:
|
|
42
|
+
}, "data-test-selector": "billToAddress" })), 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(Link, { color: "secondary", href: paths.ACCOUNT_ADDRESSES, 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(AddressInfoDisplay, { address: {
|
|
42
43
|
address1: shipTo.address1,
|
|
43
44
|
address2: shipTo.address2,
|
|
44
45
|
address3: shipTo.address3,
|
|
@@ -7,8 +7,8 @@ import { Select } from '../../../forms/elements/select/select.js';
|
|
|
7
7
|
import { FormattedMessage } from '../../../intl/formatted-message.js';
|
|
8
8
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
9
9
|
import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
|
|
10
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
10
11
|
import { Page } from '../../components/page/page.js';
|
|
11
|
-
import { PATHS } from '../../paths.js';
|
|
12
12
|
import { CheckoutPageLayout } from '../layouts/checkout-page-layout/checkout-page-layout.js';
|
|
13
13
|
import { CheckoutPageSection } from '../layouts/checkout-page-layout/components/checkout-page-section.js';
|
|
14
14
|
import { CheckoutPageSectionContent } from '../layouts/checkout-page-layout/components/checkout-page-section-content.js';
|
|
@@ -17,6 +17,7 @@ import styles from './shipping-page.module.css.js';
|
|
|
17
17
|
|
|
18
18
|
function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulfillmentMethods, isGuest, isLoadingFulfillmentMethods, isPatching, isPatchingSession, onChangeFulfillmentMethod, readOnlyAddress, }) {
|
|
19
19
|
const t = useFormattedMessage();
|
|
20
|
+
const paths = usePaths();
|
|
20
21
|
const fulfillmentMethodOptions = fulfillmentMethods?.reduce((acc, method) => ({
|
|
21
22
|
...acc,
|
|
22
23
|
[method]: t(`fulfillmentmethod.${method}`),
|
|
@@ -26,9 +27,9 @@ function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulf
|
|
|
26
27
|
if (!currencyCode)
|
|
27
28
|
throw new Error(`Currency code not found for symbol ${cart.currencySymbol}`);
|
|
28
29
|
return (jsx(Page, { breadcrumb: [
|
|
29
|
-
{ href:
|
|
30
|
+
{ href: paths.HOME, label: t('Home') },
|
|
30
31
|
{
|
|
31
|
-
href:
|
|
32
|
+
href: paths.CHECKOUT_SHIPPING,
|
|
32
33
|
label: t('Shipping details'),
|
|
33
34
|
},
|
|
34
35
|
], "data-test-selector": "shippingPage", title: t('Shipping details'), children: jsxs(CheckoutPageLayout, { actions: {
|
|
@@ -9,10 +9,10 @@ import { useFetchFulfillmentMethodsForCurrentCart } from '../../../shared/api/st
|
|
|
9
9
|
import { useDataLayer } from '../../../shared/ga/use-data-layer.js';
|
|
10
10
|
import { useDisclosure } from '../../../shared/hooks/use-disclosure.js';
|
|
11
11
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
12
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
12
13
|
import { hasNo } from '../../../shared/utils/types.js';
|
|
13
14
|
import { ErrorPage } from '../../error-page/error-page.js';
|
|
14
15
|
import { LoadingPage } from '../../loading-page/loading-page.js';
|
|
15
|
-
import { PATHS } from '../../paths.js';
|
|
16
16
|
import { CurrencyChangeDialog } from './components/currency-change-dialog.js';
|
|
17
17
|
import { EditCheckoutBillToAddressForm } from './components/edit-checkout-bill-to-address-form.js';
|
|
18
18
|
import { ReadOnlyAddresses } from './components/readonly-address.js';
|
|
@@ -20,6 +20,7 @@ import { usePatchShippingDetails } from './hooks/use-patch-shipping-details.js';
|
|
|
20
20
|
import { ShippingPageContent } from './shipping-page-content.js';
|
|
21
21
|
|
|
22
22
|
function ShippingPage() {
|
|
23
|
+
const paths = usePaths();
|
|
23
24
|
const { createEcommerceEvent, dataLayer } = useDataLayer();
|
|
24
25
|
const gaEventPushed = useRef(false);
|
|
25
26
|
const { data: cart, error: errorFetchCart, isLoading: isLoadingCart, refetch: refetchCart, } = useFetchCurrentCart();
|
|
@@ -48,14 +49,14 @@ function ShippingPage() {
|
|
|
48
49
|
if (isAuthenticated === undefined)
|
|
49
50
|
return;
|
|
50
51
|
if (!isAuthenticated)
|
|
51
|
-
return navigate(
|
|
52
|
+
return navigate(paths.CHECKOUT_SHIPPING_VIA_SIGNIN);
|
|
52
53
|
if (hasNo(cart))
|
|
53
54
|
return;
|
|
54
55
|
if (hasNo(cart.cartLines) || cart.cartLines.length === 0)
|
|
55
|
-
return navigate(
|
|
56
|
+
return navigate(paths.CART);
|
|
56
57
|
if (hasNo(cart.billTo))
|
|
57
|
-
return navigate(
|
|
58
|
-
}, [cart, navigate, isAuthenticated, isNavigating]);
|
|
58
|
+
return navigate(paths.CHECKOUT_SHIPPING_VIA_SIGNIN);
|
|
59
|
+
}, [cart, navigate, isAuthenticated, isNavigating, paths]);
|
|
59
60
|
useEffect(() => {
|
|
60
61
|
/* Guards for when the bill to address is saved and we should navigate to the next page */
|
|
61
62
|
if (isPatching)
|
|
@@ -68,8 +69,8 @@ function ShippingPage() {
|
|
|
68
69
|
return location?.reload();
|
|
69
70
|
if (hasNo(cart?.billTo?.address1))
|
|
70
71
|
return;
|
|
71
|
-
return navigate(
|
|
72
|
-
}, [isSuccess, cart, navigate, isNavigating, isPatching, isError]);
|
|
72
|
+
return navigate(paths.REVIEW_AND_SUBMIT);
|
|
73
|
+
}, [isSuccess, cart, paths, navigate, isNavigating, isPatching, isError]);
|
|
73
74
|
useEffect(() => {
|
|
74
75
|
if (!cart || gaEventPushed.current)
|
|
75
76
|
return;
|
|
@@ -123,7 +124,7 @@ function ShippingPage() {
|
|
|
123
124
|
return (jsx(ShippingPageContent, { cart: cart,
|
|
124
125
|
// TODO: Combine editAddress and readOnlyAddress into one section in order
|
|
125
126
|
// for typescript to correctly infer which properties are set in what case
|
|
126
|
-
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 }) => {
|
|
127
128
|
if (!cart.billTo)
|
|
128
129
|
return;
|
|
129
130
|
formData.current = { address, notes };
|
|
@@ -157,7 +158,7 @@ function ShippingPage() {
|
|
|
157
158
|
if (!cart.billTo)
|
|
158
159
|
return;
|
|
159
160
|
if (notes === undefined) {
|
|
160
|
-
navigate(
|
|
161
|
+
navigate(paths.REVIEW_AND_SUBMIT);
|
|
161
162
|
}
|
|
162
163
|
else {
|
|
163
164
|
await patchShippingDetails({ cart, notes });
|
|
@@ -3,18 +3,19 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
3
3
|
import { useEffect } from 'react';
|
|
4
4
|
import { logger } from '../../logging/logger.js';
|
|
5
5
|
import { isRequestError } from '../../shared/fetch/request.js';
|
|
6
|
+
import { usePaths } from '../../shared/routing/use-paths.js';
|
|
6
7
|
import { environment } from '../../shared/utils/environment.js';
|
|
7
8
|
import { Heading } from '../../typography/heading/heading.js';
|
|
8
9
|
import { Page } from '../components/page/page.js';
|
|
9
|
-
import { PATHS } from '../paths.js';
|
|
10
10
|
|
|
11
11
|
function ErrorPage({ error }) {
|
|
12
|
+
const paths = usePaths();
|
|
12
13
|
useEffect(() => {
|
|
13
14
|
logger.error('ErrorPage error:', error);
|
|
14
15
|
}, [error]);
|
|
15
16
|
return (jsx(Page, { breadcrumb: [
|
|
16
|
-
{ href:
|
|
17
|
-
{ href:
|
|
17
|
+
{ href: paths.HOME, label: 'Home' },
|
|
18
|
+
{ href: paths.HOME, label: 'Error' },
|
|
18
19
|
], "data-test-selector": "errorPage", title: "Something went wrong", children: environment !== 'production' && (jsxs(Fragment, { children: [jsx(Heading, { size: "l", children: isRequestError(error) ? (jsxs(Fragment, { children: [error.status, " - ", error.statusText || 'Unknown error'] })) : (jsx(Fragment, { children: error.message })) }), isRequestError(error) && (jsxs(Fragment, { children: [jsx(Heading, { size: "xs", children: "Error details" }), jsx(Heading, { size: "xxs", children: "Body" }), jsx("pre", { children: JSON.stringify(error.body, null, 2) }), jsx(Heading, { size: "xxs", children: "Options" }), jsx("pre", { children: JSON.stringify(error.options, null, 2) })] }))] })) }));
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -3,11 +3,12 @@ import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
|
3
3
|
import { useFetchCurrentAccount } from '../../../../shared/api/storefront/hooks/account/use-fetch-current-account.js';
|
|
4
4
|
import { usePatchSession } from '../../../../shared/api/storefront/hooks/authentication/use-patch-session.js';
|
|
5
5
|
import { useNavigate } from '../../../../shared/routing/use-navigate.js';
|
|
6
|
+
import { usePaths } from '../../../../shared/routing/use-paths.js';
|
|
6
7
|
import { useToast } from '../../../../toast/use-toast.js';
|
|
7
|
-
import { PATHS } from '../../../paths.js';
|
|
8
8
|
import { ChangePasswordDialog } from './change-password-dialog.js';
|
|
9
9
|
|
|
10
10
|
function ConnectedChangePasswordDialog({ isOpen, onClose, }) {
|
|
11
|
+
const paths = usePaths();
|
|
11
12
|
const { error: errorPatchSession, isLoading: isUpdating, mutate: patchSession, } = usePatchSession();
|
|
12
13
|
const { addToast } = useToast();
|
|
13
14
|
const { navigate } = useNavigate();
|
|
@@ -30,7 +31,7 @@ function ConnectedChangePasswordDialog({ isOpen, onClose, }) {
|
|
|
30
31
|
messageType: 'success',
|
|
31
32
|
});
|
|
32
33
|
onClose();
|
|
33
|
-
navigate(`${
|
|
34
|
+
navigate(`${paths.SIGN_IN}${location?.pathname ? `?returnUrl=${encodeURIComponent(location.pathname + location.search)}` : ''}`);
|
|
34
35
|
}, username: account?.email }));
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -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 };
|
|
@@ -5,12 +5,13 @@ import { logger } from '../../../logging/logger.js';
|
|
|
5
5
|
import { useSignOut } from '../../../shared/api/storefront/hooks/authentication/use-sign-out.js';
|
|
6
6
|
import { useLocation } from '../../../shared/routing/use-location.js';
|
|
7
7
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
8
|
-
import {
|
|
8
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
9
9
|
import { MySonicDesktopNavigation } from './my-sonic-desktop-navigation.js';
|
|
10
10
|
import { MySonicMobileNavigation } from './my-sonic-mobile-navigation.js';
|
|
11
11
|
import styles from './connected-my-sonic-navigation.module.css.js';
|
|
12
12
|
|
|
13
13
|
function ConnectedMySonicNavigation() {
|
|
14
|
+
const paths = usePaths();
|
|
14
15
|
const { pathname } = useLocation();
|
|
15
16
|
const { navigate } = useNavigate();
|
|
16
17
|
const { mutate } = useSignOut({
|
|
@@ -18,7 +19,7 @@ function ConnectedMySonicNavigation() {
|
|
|
18
19
|
onSuccess: () => {
|
|
19
20
|
// TODO: Remove when Spire is deprecated
|
|
20
21
|
Cookies.remove('NavigationMode');
|
|
21
|
-
navigate(
|
|
22
|
+
navigate(paths.HOME, { reload: true });
|
|
22
23
|
},
|
|
23
24
|
});
|
|
24
25
|
return (jsxs("div", { style: { display: 'grid' }, children: [jsx(MySonicDesktopNavigation, { className: styles['large'], currentPath: pathname, onLogout: mutate }), jsx(MySonicMobileNavigation, { className: styles['small'], currentPath: pathname, onLogout: mutate })] }));
|
|
@@ -2,10 +2,11 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { FormattedMessage } from '../../../intl/formatted-message.js';
|
|
3
3
|
import { MenuList } from '../../../lists/menu-list/menu-list.js';
|
|
4
4
|
import { MenuListItem } from '../../../lists/menu-list/menu-list-item.js';
|
|
5
|
-
import {
|
|
5
|
+
import { useMySonicNavigationItems } from './my-sonic-navigation-items.js';
|
|
6
6
|
import styles from './my-sonic-desktop-navigation.module.css.js';
|
|
7
7
|
|
|
8
8
|
function MySonicDesktopNavigation({ className, currentPath, onLogout, }) {
|
|
9
|
+
const mySonicNavigationItems = useMySonicNavigationItems();
|
|
9
10
|
return (jsx(MenuList, { collapsible: true, className: className, children: mySonicNavigationItems.map(item => (jsx(MenuListItem, { badge: jsx(item.Icon, {}), ...(item.type === 'action'
|
|
10
11
|
? item.action === 'logout'
|
|
11
12
|
? { onClick: onLogout }
|
|
@@ -3,9 +3,10 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
3
3
|
import { Select } from '../../../forms/elements/select/select.js';
|
|
4
4
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
5
5
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
6
|
-
import {
|
|
6
|
+
import { useMySonicNavigationItems } from './my-sonic-navigation-items.js';
|
|
7
7
|
|
|
8
8
|
function MySonicMobileNavigation({ className, currentPath, onLogout, }) {
|
|
9
|
+
const mySonicNavigationItems = useMySonicNavigationItems();
|
|
9
10
|
const { navigate } = useNavigate();
|
|
10
11
|
const t = useFormattedMessage();
|
|
11
12
|
return (jsx(Select, { className: className, label: t('Navigate to...'), onChange: option => {
|
|
@@ -14,5 +14,5 @@ interface MySonicNavigationAction extends MySonicNavigationItemBase {
|
|
|
14
14
|
type: 'action';
|
|
15
15
|
}
|
|
16
16
|
type MySonicNavigationItem = MySonicNavigationLink | MySonicNavigationAction;
|
|
17
|
-
export declare
|
|
17
|
+
export declare function useMySonicNavigationItems(): MySonicNavigationItem[];
|
|
18
18
|
export {};
|
|
@@ -2,28 +2,36 @@ import { SolidCartIcon } from '../../../icons/solid/solid-cart-icon.js';
|
|
|
2
2
|
import { SolidFavoriteIcon } from '../../../icons/solid/solid-favorite-icon.js';
|
|
3
3
|
import { SolidLoginIcon } from '../../../icons/solid/solid-login-icon.js';
|
|
4
4
|
import { SolidLogOutIcon } from '../../../icons/solid/solid-logout-icon.js';
|
|
5
|
-
import {
|
|
5
|
+
import { usePaths } from '../../../shared/routing/use-paths.js';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
7
|
+
function useMySonicNavigationItems() {
|
|
8
|
+
const paths = usePaths();
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
Icon: SolidLoginIcon,
|
|
12
|
+
label: 'Account',
|
|
13
|
+
path: paths.ACCOUNT_SETTINGS.toLowerCase(),
|
|
14
|
+
type: 'link',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
Icon: SolidFavoriteIcon,
|
|
18
|
+
label: 'Favorites',
|
|
19
|
+
path: paths.ACCOUNT_MY_LISTS.toLowerCase(),
|
|
20
|
+
type: 'link',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
Icon: SolidCartIcon,
|
|
24
|
+
label: 'Orders',
|
|
25
|
+
path: paths.ACCOUNT_ORDERS.toLowerCase(),
|
|
26
|
+
type: 'link',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
Icon: SolidLogOutIcon,
|
|
30
|
+
action: 'logout',
|
|
31
|
+
label: 'Log out',
|
|
32
|
+
type: 'action',
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
28
36
|
|
|
29
|
-
export {
|
|
37
|
+
export { useMySonicNavigationItems };
|
|
@@ -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 };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ElementType, ReactNode } from 'react';
|
|
2
|
-
import { NavigateFunction, RouteLinkElementProps } from './types';
|
|
2
|
+
import { NavigateFunction, Paths, RouteLinkElementProps } from './types';
|
|
3
3
|
export interface RouteProviderProps {
|
|
4
4
|
Link?: ElementType<RouteLinkElementProps>;
|
|
5
5
|
children: ReactNode;
|
|
6
6
|
navigate: NavigateFunction;
|
|
7
|
+
paths: Paths;
|
|
7
8
|
url: {
|
|
8
9
|
basePathname?: string;
|
|
9
10
|
pathname: string;
|
|
10
11
|
search: string;
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
|
-
export declare function RouteProvider({ children, Link, navigate, url, }: RouteProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function RouteProvider({ children, Link, navigate, paths, url, }: RouteProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,10 +3,11 @@ import { jsx, Fragment } from 'react/jsx-runtime';
|
|
|
3
3
|
import { useGlobalState } from '../providers/global-state-provider.js';
|
|
4
4
|
import { withRouting } from './with-routing.js';
|
|
5
5
|
|
|
6
|
-
function RouteProvider({ children, Link = FallbackRouteLink, navigate, url, }) {
|
|
6
|
+
function RouteProvider({ children, Link = FallbackRouteLink, navigate, paths, url, }) {
|
|
7
7
|
useGlobalState('routing', {
|
|
8
8
|
Link,
|
|
9
9
|
navigate,
|
|
10
|
+
paths,
|
|
10
11
|
url,
|
|
11
12
|
});
|
|
12
13
|
return jsx(Fragment, { children: children });
|
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import { ElementType } from 'react';
|
|
2
|
+
export interface Paths {
|
|
3
|
+
ACCOUNT: string;
|
|
4
|
+
ACCOUNT_ADDRESSES: string;
|
|
5
|
+
ACCOUNT_CREATE: string;
|
|
6
|
+
ACCOUNT_INVOICES: string;
|
|
7
|
+
ACCOUNT_MY_LISTS: string;
|
|
8
|
+
ACCOUNT_ORDERS: string;
|
|
9
|
+
ACCOUNT_SETTINGS: string;
|
|
10
|
+
CART: string;
|
|
11
|
+
CHECKOUT_SHIPPING: string;
|
|
12
|
+
CHECKOUT_SHIPPING_VIA_SIGNIN: string;
|
|
13
|
+
FAVORITES: string;
|
|
14
|
+
HOME: string;
|
|
15
|
+
ORDER_CONFIRMATION: string;
|
|
16
|
+
REVIEW_AND_SUBMIT: string;
|
|
17
|
+
SIGN_IN: string;
|
|
18
|
+
}
|
|
2
19
|
export interface RouteContext {
|
|
3
20
|
Link?: ElementType<RouteLinkElementProps>;
|
|
4
21
|
navigate: NavigateFunction;
|
|
22
|
+
paths: Paths;
|
|
5
23
|
url: {
|
|
6
24
|
basePathname?: string;
|
|
7
25
|
pathname: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useGlobalState } from '../providers/global-state-provider.js';
|
|
2
|
+
|
|
3
|
+
function usePaths() {
|
|
4
|
+
const [routeState] = useGlobalState('routing');
|
|
5
|
+
if (!routeState)
|
|
6
|
+
throw new Error('usePaths must be used within a RouteProvider context');
|
|
7
|
+
return routeState.paths;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { usePaths };
|
package/package.json
CHANGED
package/dist/pages/paths.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare const PATHS: {
|
|
2
|
-
readonly ACCOUNT: "/MyAccount";
|
|
3
|
-
readonly ACCOUNT_ADDRESSES: "/MyAccount/Addresses";
|
|
4
|
-
readonly ACCOUNT_CREATE: "/MyAccount/CreateAccount";
|
|
5
|
-
readonly ACCOUNT_INVOICES: "/MyAccount/Invoices";
|
|
6
|
-
readonly ACCOUNT_MY_LISTS: "/MyAccount/MyLists";
|
|
7
|
-
readonly ACCOUNT_ORDERS: "/MyAccount/Orders";
|
|
8
|
-
readonly ACCOUNT_SETTINGS: "/MyAccount/AccountSettings";
|
|
9
|
-
readonly CART: "/Cart";
|
|
10
|
-
readonly CHECKOUT_SHIPPING: "/CheckoutShipping";
|
|
11
|
-
readonly CHECKOUT_SHIPPING_VIA_SIGNIN: "/SignIn?returnUrl=/CheckoutShipping";
|
|
12
|
-
readonly FAVORITES: "/MyAccount/MyLists";
|
|
13
|
-
readonly HOME: "/";
|
|
14
|
-
readonly ORDER_CONFIRMATION: "/OrderConfirmation";
|
|
15
|
-
readonly REVIEW_AND_SUBMIT: "/CheckoutReviewAndSubmit";
|
|
16
|
-
readonly SIGN_IN: "/SignIn";
|
|
17
|
-
};
|
package/dist/pages/paths.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const PATHS = {
|
|
2
|
-
ACCOUNT: '/MyAccount',
|
|
3
|
-
ACCOUNT_ADDRESSES: '/MyAccount/Addresses',
|
|
4
|
-
ACCOUNT_CREATE: '/MyAccount/CreateAccount',
|
|
5
|
-
ACCOUNT_INVOICES: '/MyAccount/Invoices',
|
|
6
|
-
ACCOUNT_MY_LISTS: '/MyAccount/MyLists',
|
|
7
|
-
ACCOUNT_ORDERS: '/MyAccount/Orders',
|
|
8
|
-
ACCOUNT_SETTINGS: '/MyAccount/AccountSettings',
|
|
9
|
-
CART: '/Cart',
|
|
10
|
-
CHECKOUT_SHIPPING: '/CheckoutShipping',
|
|
11
|
-
CHECKOUT_SHIPPING_VIA_SIGNIN: '/SignIn?returnUrl=/CheckoutShipping',
|
|
12
|
-
FAVORITES: '/MyAccount/MyLists',
|
|
13
|
-
HOME: '/',
|
|
14
|
-
ORDER_CONFIRMATION: '/OrderConfirmation',
|
|
15
|
-
REVIEW_AND_SUBMIT: '/CheckoutReviewAndSubmit',
|
|
16
|
-
SIGN_IN: '/SignIn',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export { PATHS };
|