@evenicanpm/storefront-core 1.3.0 → 1.4.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/__mocks__/get-product-by-id.ts +0 -1
- package/__mocks__/query-client.ts +1 -1
- package/package.json +3 -3
- package/src/api-manager/datasources/d365/d365-address.datasource.ts +2 -2
- package/src/api-manager/datasources/d365/d365-cart.datasource.ts +4 -5
- package/src/api-manager/datasources/d365/d365-categories.datasource.ts +1 -1
- package/src/api-manager/datasources/d365/d365-product.datasource.ts +21 -7
- package/src/api-manager/datasources/d365/d365-session.datasource.ts +5 -7
- package/src/api-manager/datasources/d365/d365-user.datasource.ts +12 -23
- package/src/api-manager/datasources/d365/d365.datasource.ts +0 -2
- package/src/api-manager/datasources/d365/index.ts +2 -4
- package/src/api-manager/datasources/d365/utils/decode-jwt.ts +1 -2
- package/src/api-manager/datasources/d365/utils/parse-object.ts +1 -1
- package/src/api-manager/datasources/e4/address/e4-address.remaps.ts +2 -2
- package/src/api-manager/datasources/e4/address/e4-address.translator.ts +1 -1
- package/src/api-manager/datasources/e4/cart/e4-cart.datasource.ts +28 -27
- package/src/api-manager/datasources/e4/cart/e4-cart.remaps.ts +1 -1
- package/src/api-manager/datasources/e4/cart/e4-cart.translator.ts +1 -1
- package/src/api-manager/datasources/e4/categories/e4-categories.translator.ts +20 -20
- package/src/api-manager/datasources/e4/graphqlRequestSdk.ts +471 -7
- package/src/api-manager/datasources/e4/order/e4-order.remaps.ts +2 -2
- package/src/api-manager/datasources/e4/organization/e4-organization.datasource.ts +2 -8
- package/src/api-manager/datasources/e4/product/e4-product.remaps.ts +3 -3
- package/src/api-manager/datasources/e4/product/e4-product.translator.ts +13 -29
- package/src/api-manager/datasources/e4/session/e4-session.datasource.ts +1 -3
- package/src/api-manager/datasources/e4/user/e4-user.remaps.ts +2 -4
- package/src/api-manager/datasources/e4/utils/unwrap-e4-variants.ts +4 -4
- package/src/api-manager/index.ts +1 -1
- package/src/api-manager/lib/category-helpers.ts +3 -2
- package/src/api-manager/lib/get-graphql-client.ts +1 -2
- package/src/api-manager/services/cart/mutations/add-discount-code.ts +2 -2
- package/src/api-manager/services/cart/mutations/add-to-cart.ts +2 -2
- package/src/api-manager/services/product/server/product.server.ts +1 -1
- package/src/api-manager/types/Datasource.ts +4 -9
- package/src/auth/auth-options.test.ts +2 -58
- package/src/auth/auth-options.ts +1 -2
- package/src/auth/next-auth-cookie-manager.ts +0 -2
- package/src/auth/refresh-token.ts +3 -8
- package/src/auth/signout.ts +1 -1
- package/src/cms/blocks/block-manager.tsx +3 -3
- package/src/cms/blocks/components/category-card.tsx +1 -1
- package/src/cms/blocks/components/category-carousel/index.tsx +3 -1
- package/src/cms/blocks/components/footer/index.tsx +2 -2
- package/src/cms/blocks/components/footer/sections/footer-links.tsx +2 -2
- package/src/cms/blocks/components/footer/sections/footer-logo.tsx +1 -1
- package/src/cms/blocks/components/footer/sections/footer-social-links.tsx +10 -2
- package/src/cms/blocks/components/hero-carousel/index.tsx +29 -25
- package/src/cms/blocks/components/media-card.tsx +1 -1
- package/src/cms/blocks/components/product-carousel/index.tsx +1 -1
- package/src/cms/blocks/components/product-section-fullwidth/index.tsx +2 -2
- package/src/cms/blocks/components/seo/index.tsx +5 -1
- package/src/cms/blocks/components/services/index.tsx +1 -1
- package/src/cms/blocks/components/services/service-card.tsx +1 -1
- package/src/cms/blocks/components/shared/featured-product-card.tsx +4 -1
- package/src/cms/blocks/components/shared/product-category-item.tsx +1 -1
- package/src/cms/blocks/components/shared/product-grid.tsx +4 -1
- package/src/cms/blocks/components/shared/top-categories-card.tsx +5 -1
- package/src/cms/blocks/components/shared/top-rating-product-card.tsx +1 -1
- package/src/components-v2/BazaarImage.tsx +1 -1
- package/src/components-v2/BazaarMenu.tsx +2 -2
- package/src/components-v2/BazaarTextField.tsx +3 -3
- package/src/components-v2/BorderShadowCard.stories.tsx +1 -1
- package/src/components-v2/DropZone.tsx +1 -2
- package/src/components-v2/Typography.tsx +12 -12
- package/src/components-v2/accordion/accordion-header.tsx +1 -1
- package/src/components-v2/categories/category-list/styles.ts +0 -7
- package/src/components-v2/categories/category-list-item/category-menu-item.tsx +1 -1
- package/src/components-v2/categories/category-menu.tsx +16 -13
- package/src/components-v2/categories/mega-menu/mega-menu-1.tsx +1 -1
- package/src/components-v2/categories/mega-menu/mega-menu-2.tsx +2 -2
- package/src/components-v2/header/components/user.tsx +5 -5
- package/src/components-v2/mini-cart/__tests__/cart-item.test.tsx +13 -13
- package/src/components-v2/mini-cart/components/bottom-actions.tsx +1 -1
- package/src/components-v2/mini-cart/components/cart-item.tsx +3 -3
- package/src/components-v2/mini-cart/components/top-header.tsx +2 -2
- package/src/components-v2/mobile-navigation/mobile-navigation-bar.tsx +1 -1
- package/src/components-v2/nav-link/nav-link-2.tsx +1 -1
- package/src/components-v2/nav-link/nav-link-3.tsx +1 -1
- package/src/components-v2/nav-link/nav-link.tsx +1 -1
- package/src/components-v2/navbar/categories.tsx +3 -1
- package/src/components-v2/navbar/category-based-menu/category-based-menu.tsx +2 -2
- package/src/components-v2/navbar/mobile-menu/mobile-menu.tsx +11 -3
- package/src/components-v2/navbar/nav-list/nav-item-child.tsx +1 -1
- package/src/components-v2/navbar/nav-list/nav-list.tsx +118 -80
- package/src/components-v2/navbar/navbar.tsx +1 -1
- package/src/components-v2/no-records.tsx +1 -1
- package/src/components-v2/product-cards/favorite-button.tsx +1 -1
- package/src/components-v2/product-cards/product-card/product-card.tsx +5 -7
- package/src/components-v2/product-cards/product-card-plp/product-card.tsx +7 -6
- package/src/components-v2/product-cards/product-card-plp-list/components/tags.tsx +1 -1
- package/src/components-v2/product-cards/product-card-plp-list/product-card.tsx +7 -4
- package/src/components-v2/product-cards/product-card-search/product-card.tsx +4 -2
- package/src/components-v2/product-cards/product-price.tsx +1 -1
- package/src/components-v2/product-cards/product-rating.tsx +1 -1
- package/src/components-v2/product-cards/product-title.tsx +1 -1
- package/src/components-v2/product-cards/quantity-buttons.tsx +1 -1
- package/src/components-v2/product-dialog/compound/product-dialog.tsx +2 -2
- package/src/components-v2/product-dialog/index.tsx +1 -1
- package/src/components-v2/product-dimensions/compound/dimensions-group-list.tsx +6 -1
- package/src/components-v2/product-dimensions/index.tsx +3 -3
- package/src/components-v2/product-quantity-buttons/compound/quantity-buttons-root.tsx +1 -1
- package/src/components-v2/product-quantity-variants/index.tsx +1 -2
- package/src/components-v2/products-view/ProductsList.stories.tsx +0 -2
- package/src/components-v2/products-view/compound/products-grid-view.tsx +2 -2
- package/src/components-v2/products-view/compound/products-list-view.tsx +3 -3
- package/src/components-v2/products-view/index.tsx +2 -2
- package/src/components-v2/progress/progress.tsx +1 -1
- package/src/components-v2/scrollbar/scrollbar.tsx +1 -1
- package/src/components-v2/search-bar/compound/results-suspense.tsx +1 -2
- package/src/components-v2/search-bar/compound/results.tsx +6 -3
- package/src/components-v2/search-bar/compound/search-bar-root.tsx +4 -2
- package/src/components-v2/search-bar/compound/textfield-adornment-category.tsx +25 -27
- package/src/components-v2/search-bar/compound/textfield.tsx +0 -1
- package/src/components-v2/search-bar/hooks/use-search.ts +1 -1
- package/src/components-v2/section/Section.stories.tsx +1 -1
- package/src/components-v2/side-nav/side-nav.tsx +1 -1
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-dialog.tsx +1 -1
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-list.tsx +2 -2
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/hooks/use-add-to-wishlist.ts +2 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/index.tsx +11 -13
- package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-dialog.tsx +2 -1
- package/src/hooks/use-variants.ts +25 -27
- package/src/lib/build-detail-url.ts +1 -1
- package/src/lib/category-helpers.ts +3 -3
- package/src/lib/get-palette-color.ts +35 -15
- package/src/lib/hexToLuma.ts +2 -2
- package/src/lib/store-hours-helper.ts +5 -5
- package/src/pages-v2/account/addresses/address-form.tsx +10 -8
- package/src/pages-v2/account/addresses/address-item.tsx +1 -1
- package/src/pages-v2/account/orders/order-progress.tsx +1 -1
- package/src/pages-v2/account/orders/ordered-products.tsx +1 -1
- package/src/pages-v2/account/profile/user-info.tsx +1 -2
- package/src/pages-v2/account/wishlist/create-new-list.tsx +1 -0
- package/src/pages-v2/account/wishlist/wishlist-item.tsx +2 -1
- package/src/pages-v2/blog/blog-card.tsx +1 -1
- package/src/pages-v2/cart/__tests__/cart-item.test.tsx +0 -1
- package/src/pages-v2/cart/__tests__/checkout-form.test.tsx +0 -8
- package/src/pages-v2/cart/cart-item.tsx +86 -77
- package/src/pages-v2/cart/checkout-form.tsx +4 -4
- package/src/pages-v2/cart/coupon-entry.tsx +3 -3
- package/src/pages-v2/cart/estimate-shipping.tsx +6 -6
- package/src/pages-v2/checkout/checkout-alt-form/checkout-form.tsx +2 -2
- package/src/pages-v2/checkout/checkout-alt-form/checkout-step.tsx +2 -2
- package/src/pages-v2/checkout/checkout-alt-form/step-heading.tsx +1 -1
- package/src/pages-v2/checkout/checkout-alt-form/steps/address/delivery-address.tsx +12 -10
- package/src/pages-v2/checkout/checkout-alt-form/steps/address/new-address-form.tsx +5 -6
- package/src/pages-v2/checkout/checkout-alt-form/steps/customer-info/customer-information.tsx +8 -9
- package/src/pages-v2/checkout/checkout-alt-form/steps/payment/payment-details.tsx +17 -20
- package/src/pages-v2/checkout/checkout-alt-form/steps/shipping/delivery-date.tsx +1 -1
- package/src/pages-v2/checkout/checkout-alt-form/steps/shipping/delivery-options.tsx +14 -15
- package/src/pages-v2/confirmation/confirmation-summary.tsx +8 -7
- package/src/pages-v2/confirmation/ordered-products.tsx +3 -3
- package/src/pages-v2/product-details/bopis/pickup-option-select.tsx +1 -1
- package/src/pages-v2/product-details/bopis/store-card/shop-card.tsx +1 -1
- package/src/pages-v2/product-details/checkbox-label.tsx +1 -1
- package/src/pages-v2/product-details/frequently-bought.tsx +1 -1
- package/src/pages-v2/product-details/frequently-product-card.tsx +1 -1
- package/src/pages-v2/product-details/product-comment.tsx +1 -1
- package/src/pages-v2/product-details/product-description.tsx +2 -2
- package/src/pages-v2/product-details/product-filter-card.tsx +4 -1
- package/src/pages-v2/product-details/product-intro/compound/product-intro-images.tsx +36 -31
- package/src/pages-v2/product-details/product-intro/compound/product-intro.tsx +1 -1
- package/src/pages-v2/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +1 -1
- package/src/pages-v2/product-details/product-intro/utils.ts +2 -4
- package/src/pages-v2/product-details/product-review.tsx +1 -1
- package/src/pages-v2/product-details/product-tabs.tsx +5 -2
- package/src/pages-v2/product-details/related-products.tsx +7 -4
- package/src/pages-v2/product-list/breadcrumbs.tsx +1 -1
- package/src/pages-v2/product-list/checkbox-label.tsx +1 -1
- package/src/pages-v2/product-list/facet-group.tsx +1 -1
- package/src/pages-v2/product-list/list-filter.tsx +2 -2
- package/src/pages-v2/product-list/product-list-context.tsx +5 -1
- package/src/pages-v2/product-list/product-list-view.tsx +4 -1
- package/src/pages-v2/product-list/product-rating.tsx +4 -1
- package/src/pages-v2/product-list/quick-view-dialog-content.tsx +2 -4
- package/src/pages-v2/product-list/quick-view-dialog.tsx +5 -1
- package/src/pages-v2/product-list/range-filter.tsx +0 -1
- package/src/pages-v2/product-list/scrollbar.tsx +1 -1
- package/src/pages-v2/product-list/side-nav.tsx +1 -1
- package/src/pages-v2/product-list/swatch.tsx +12 -7
- package/src/pages-v2/product-list/utils/getCategoryFilterFromSlug.ts +33 -68
- package/src/pages-v2/product-list/utils/product-list-helper.ts +1 -1
- package/src/pages-v2/product-list/utils/search-for-category.ts +2 -2
- package/src/pages-v2/quickorder/order-upload.tsx +90 -76
- package/src/pages-v2/quickorder/provider.tsx +6 -4
- package/src/pages-v2/quickorder/quick-order-row.tsx +1 -1
- package/src/pages-v2/quickorder/quick-order.tsx +28 -21
- package/src/providers/notifications/notification-context.tsx +0 -1
|
@@ -62,7 +62,7 @@ const MobileNavContext = createContext<{ menuList: MenuItemProps[] }>({
|
|
|
62
62
|
export default function MobileNavigationBar({
|
|
63
63
|
children,
|
|
64
64
|
menuList,
|
|
65
|
-
}: MobileNavigationBarProps) {
|
|
65
|
+
}: Readonly<MobileNavigationBarProps>) {
|
|
66
66
|
const DOWN_900 = useMediaQuery((theme: Theme) => theme.breakpoints.down(900));
|
|
67
67
|
|
|
68
68
|
const defaultMenuList: MenuItemProps[] = [
|
|
@@ -17,7 +17,9 @@ const CategoriesContext = createContext<CategoriesContextValue | undefined>(
|
|
|
17
17
|
undefined,
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
export default function Categories({
|
|
20
|
+
export default function Categories({
|
|
21
|
+
children,
|
|
22
|
+
}: Readonly<{ children?: ReactNode }>) {
|
|
21
23
|
const t = useTranslations("Navigation");
|
|
22
24
|
|
|
23
25
|
const label = t("topLevelCategoryName");
|
|
@@ -107,13 +107,13 @@ CategoryBasedMenu.Section = () => {
|
|
|
107
107
|
<Scrollbar autoHide={false} sx={{ width: "100%" }}>
|
|
108
108
|
<Box px={6} py={2} height="100%">
|
|
109
109
|
{category.items.map((item, idx) => (
|
|
110
|
-
<div key={idx}>
|
|
110
|
+
<div key={item.title + idx}>
|
|
111
111
|
<H6 fontWeight={700} my={3}>
|
|
112
112
|
{item.title}
|
|
113
113
|
</H6>
|
|
114
114
|
<SubCategoryList>
|
|
115
115
|
{item.items.map((sub, subIdx) => (
|
|
116
|
-
<CategoryBasedMenu.Item item={sub} key={subIdx} />
|
|
116
|
+
<CategoryBasedMenu.Item item={sub} key={sub.title + subIdx} />
|
|
117
117
|
))}
|
|
118
118
|
</SubCategoryList>
|
|
119
119
|
</div>
|
|
@@ -76,7 +76,11 @@ MobileMenu.List = ({ data }: { data: TransformedNavItem[] }) => {
|
|
|
76
76
|
return (
|
|
77
77
|
<>
|
|
78
78
|
{data.map((item, idx) => (
|
|
79
|
-
<MobileMenu.Item
|
|
79
|
+
<MobileMenu.Item
|
|
80
|
+
key={item.title + idx}
|
|
81
|
+
item={item}
|
|
82
|
+
onClose={toggleMobileSideNav}
|
|
83
|
+
/>
|
|
80
84
|
))}
|
|
81
85
|
</>
|
|
82
86
|
);
|
|
@@ -107,7 +111,7 @@ MobileMenu.Item = ({
|
|
|
107
111
|
}) => {
|
|
108
112
|
const { href, title, items } = item;
|
|
109
113
|
|
|
110
|
-
if (items
|
|
114
|
+
if (items?.length) {
|
|
111
115
|
return (
|
|
112
116
|
<Accordion square elevation={0} disableGutters sx={ACCORDION_STYLES}>
|
|
113
117
|
<AccordionSummary
|
|
@@ -118,7 +122,11 @@ MobileMenu.Item = ({
|
|
|
118
122
|
</AccordionSummary>
|
|
119
123
|
<Box mx={2}>
|
|
120
124
|
{items.map((sub, idx) => (
|
|
121
|
-
<MobileMenu.Item
|
|
125
|
+
<MobileMenu.Item
|
|
126
|
+
key={sub.title + idx}
|
|
127
|
+
item={sub}
|
|
128
|
+
onClose={onClose}
|
|
129
|
+
/>
|
|
122
130
|
))}
|
|
123
131
|
</Box>
|
|
124
132
|
</Accordion>
|
|
@@ -25,7 +25,7 @@ interface Props extends PropsWithChildren {
|
|
|
25
25
|
}
|
|
26
26
|
// ==============================================================
|
|
27
27
|
|
|
28
|
-
export default function NavItemChild({ nav, children }: Props) {
|
|
28
|
+
export default function NavItemChild({ nav, children }: Readonly<Props>) {
|
|
29
29
|
const pathname = usePathname();
|
|
30
30
|
const { settings } = useSettings();
|
|
31
31
|
const { checkOverflow, elementRef, isLeftOverflowing, isRightOverflowing } =
|
|
@@ -17,19 +17,108 @@ import {
|
|
|
17
17
|
} from "@evenicanpm/storefront-core/src/components-v2/navbar/utils/transform-nav";
|
|
18
18
|
import { NavContext } from "@evenicanpm/storefront-core/src/providers/nav-provider";
|
|
19
19
|
import KeyboardArrowDown from "@mui/icons-material/KeyboardArrowDown";
|
|
20
|
-
// import { useContext as useReactContext } from "react";
|
|
21
20
|
import MenuItem from "@mui/material/MenuItem";
|
|
22
21
|
import { createContext, type ReactNode, useContext } from "react";
|
|
23
22
|
|
|
24
23
|
type NavigationContextValue = {
|
|
25
24
|
list: TransformedNavItem[];
|
|
26
25
|
};
|
|
26
|
+
|
|
27
27
|
const NavigationContext = createContext<NavigationContextValue | undefined>(
|
|
28
28
|
undefined,
|
|
29
29
|
);
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
type NavigationItemProps = Readonly<{
|
|
32
|
+
nav: TransformedNavItem;
|
|
33
|
+
isRoot?: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
|
|
36
|
+
function RenderMegaMenu(props: Readonly<{ nav: TransformedNavItem }>) {
|
|
37
|
+
const { nav } = props;
|
|
38
|
+
const columns = nav.items.map((item) => [item]);
|
|
39
|
+
const columnCount = columns.length;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<MegaMenu title={nav.title}>
|
|
43
|
+
<MegaMenu.Container>
|
|
44
|
+
{columns.map((column) => {
|
|
45
|
+
const columnKey = column.map((c) => c.title).join("-");
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<MegaMenu.Column key={columnKey} count={columnCount}>
|
|
49
|
+
{column.map((cat) => (
|
|
50
|
+
<MegaMenu.Category key={cat.title} title={cat.title}>
|
|
51
|
+
{cat.items.map((sub) => (
|
|
52
|
+
<MegaMenu.Item key={sub.title} href={sub.href}>
|
|
53
|
+
{sub.title}
|
|
54
|
+
</MegaMenu.Item>
|
|
55
|
+
))}
|
|
56
|
+
</MegaMenu.Category>
|
|
57
|
+
))}
|
|
58
|
+
</MegaMenu.Column>
|
|
59
|
+
);
|
|
60
|
+
})}
|
|
61
|
+
</MegaMenu.Container>
|
|
62
|
+
</MegaMenu>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function RenderFullScreenMenu({ nav }: Readonly<{ nav: TransformedNavItem }>) {
|
|
67
|
+
return (
|
|
68
|
+
<CategoryBasedMenu key={nav.title} title={nav.title} menuList={nav.items}>
|
|
69
|
+
<CategoryBasedMenu.MainList />
|
|
70
|
+
<CategoryBasedMenu.Section />
|
|
71
|
+
</CategoryBasedMenu>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function RenderRootWithChildren({
|
|
76
|
+
nav,
|
|
77
|
+
}: Readonly<{ nav: TransformedNavItem }>) {
|
|
78
|
+
const { title, items } = nav;
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<FlexBox
|
|
82
|
+
alignItems="center"
|
|
83
|
+
position="relative"
|
|
84
|
+
flexDirection="column"
|
|
85
|
+
sx={{
|
|
86
|
+
"&:hover": { "& > .child-nav-item": { display: "block" } },
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<FlexBox alignItems="flex-end" gap={0.3} sx={NAV_LINK_STYLES}>
|
|
90
|
+
{title}
|
|
91
|
+
<KeyboardArrowDown sx={{ color: "grey.500", fontSize: "1.1rem" }} />
|
|
92
|
+
</FlexBox>
|
|
93
|
+
|
|
94
|
+
<ChildNavListWrapper className="child-nav-item">
|
|
95
|
+
<BazaarCard elevation={3} sx={{ mt: 2.5, py: 1, minWidth: 100 }}>
|
|
96
|
+
{items.map((child) => (
|
|
97
|
+
<Navigation.Item key={child.title} nav={child} />
|
|
98
|
+
))}
|
|
99
|
+
</BazaarCard>
|
|
100
|
+
</ChildNavListWrapper>
|
|
101
|
+
</FlexBox>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function RenderChildWithChildren({
|
|
106
|
+
nav,
|
|
107
|
+
}: Readonly<{ nav: TransformedNavItem }>) {
|
|
108
|
+
return (
|
|
109
|
+
<Navigation.Child nav={nav}>
|
|
110
|
+
{nav.items.map((child) => (
|
|
111
|
+
<Navigation.Item key={child.title} nav={child} />
|
|
112
|
+
))}
|
|
113
|
+
</Navigation.Child>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export default function Navigation({
|
|
118
|
+
children,
|
|
119
|
+
}: Readonly<{ children?: ReactNode }>) {
|
|
32
120
|
const cmsList = transformCmsNav(useContext(NavContext).cmsNav ?? []);
|
|
121
|
+
|
|
33
122
|
return (
|
|
34
123
|
<NavigationContext.Provider value={{ list: cmsList }}>
|
|
35
124
|
<FlexBox gap={4}>{children ?? <Navigation.List />}</FlexBox>
|
|
@@ -40,6 +129,7 @@ export default function Navigation({ children }: { children?: ReactNode }) {
|
|
|
40
129
|
Navigation.List = function List() {
|
|
41
130
|
const ctx = useContext(NavigationContext);
|
|
42
131
|
if (!ctx) return null;
|
|
132
|
+
|
|
43
133
|
return (
|
|
44
134
|
<>
|
|
45
135
|
{ctx.list.map((nav) => (
|
|
@@ -49,96 +139,44 @@ Navigation.List = function List() {
|
|
|
49
139
|
);
|
|
50
140
|
};
|
|
51
141
|
|
|
52
|
-
Navigation.Item = function Item({
|
|
53
|
-
nav,
|
|
54
|
-
isRoot = false,
|
|
55
|
-
}: {
|
|
56
|
-
nav: TransformedNavItem;
|
|
57
|
-
isRoot?: boolean;
|
|
58
|
-
}) {
|
|
142
|
+
Navigation.Item = function Item({ nav, isRoot = false }: NavigationItemProps) {
|
|
59
143
|
const { href, title, items, menuType } = nav;
|
|
60
|
-
const hasChildren = !!
|
|
144
|
+
const hasChildren = !!items?.length;
|
|
61
145
|
|
|
146
|
+
// ROOT ITEMS
|
|
62
147
|
if (isRoot) {
|
|
63
148
|
if (menuType === "mega-menu") {
|
|
64
|
-
return
|
|
65
|
-
<MegaMenu title={title}>
|
|
66
|
-
<MegaMenu.Container>
|
|
67
|
-
{nav.items
|
|
68
|
-
.map((i) => [i])
|
|
69
|
-
.map((column, i) => (
|
|
70
|
-
<MegaMenu.Column
|
|
71
|
-
key={i}
|
|
72
|
-
count={nav.items.map((i) => [i]).length}
|
|
73
|
-
>
|
|
74
|
-
{column.map((cat) => (
|
|
75
|
-
<MegaMenu.Category key={cat.title} title={cat.title}>
|
|
76
|
-
{cat.items.map((sub) => (
|
|
77
|
-
<MegaMenu.Item key={sub.title} href={sub.href}>
|
|
78
|
-
{sub.title}
|
|
79
|
-
</MegaMenu.Item>
|
|
80
|
-
))}
|
|
81
|
-
</MegaMenu.Category>
|
|
82
|
-
))}
|
|
83
|
-
</MegaMenu.Column>
|
|
84
|
-
))}
|
|
85
|
-
</MegaMenu.Container>
|
|
86
|
-
</MegaMenu>
|
|
87
|
-
);
|
|
149
|
+
return <RenderMegaMenu nav={nav} />;
|
|
88
150
|
}
|
|
151
|
+
|
|
89
152
|
if (menuType === "full-screen-mega-menu") {
|
|
90
|
-
return
|
|
91
|
-
<CategoryBasedMenu key={title} title={title} menuList={nav.items}>
|
|
92
|
-
<CategoryBasedMenu.MainList />
|
|
93
|
-
<CategoryBasedMenu.Section />
|
|
94
|
-
</CategoryBasedMenu>
|
|
95
|
-
);
|
|
153
|
+
return <RenderFullScreenMenu nav={nav} />;
|
|
96
154
|
}
|
|
97
|
-
|
|
155
|
+
|
|
156
|
+
if (!hasChildren && href) {
|
|
98
157
|
return <StyledNavLink href={href}>{title}</StyledNavLink>;
|
|
99
158
|
}
|
|
159
|
+
|
|
100
160
|
if (hasChildren) {
|
|
101
|
-
return
|
|
102
|
-
<FlexBox
|
|
103
|
-
alignItems="center"
|
|
104
|
-
position="relative"
|
|
105
|
-
flexDirection="column"
|
|
106
|
-
sx={{
|
|
107
|
-
"&:hover": { "& > .child-nav-item": { display: "block" } },
|
|
108
|
-
}}
|
|
109
|
-
>
|
|
110
|
-
<FlexBox alignItems="flex-end" gap={0.3} sx={NAV_LINK_STYLES}>
|
|
111
|
-
{title}{" "}
|
|
112
|
-
<KeyboardArrowDown sx={{ color: "grey.500", fontSize: "1.1rem" }} />
|
|
113
|
-
</FlexBox>
|
|
114
|
-
<ChildNavListWrapper className="child-nav-item">
|
|
115
|
-
<BazaarCard elevation={3} sx={{ mt: 2.5, py: 1, minWidth: 100 }}>
|
|
116
|
-
{items.map((child) => (
|
|
117
|
-
<Navigation.Item key={child.title} nav={child} />
|
|
118
|
-
))}
|
|
119
|
-
</BazaarCard>
|
|
120
|
-
</ChildNavListWrapper>
|
|
121
|
-
</FlexBox>
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
} else {
|
|
125
|
-
if (href && !hasChildren) {
|
|
126
|
-
return (
|
|
127
|
-
<NavLink href={href}>
|
|
128
|
-
<MenuItem>{title}</MenuItem>
|
|
129
|
-
</NavLink>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
if (hasChildren) {
|
|
133
|
-
return (
|
|
134
|
-
<Navigation.Child nav={nav}>
|
|
135
|
-
{items.map((child) => (
|
|
136
|
-
<Navigation.Item key={child.title} nav={child} />
|
|
137
|
-
))}
|
|
138
|
-
</Navigation.Child>
|
|
139
|
-
);
|
|
161
|
+
return <RenderRootWithChildren nav={nav} />;
|
|
140
162
|
}
|
|
163
|
+
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// CHILD ITEMS
|
|
168
|
+
if (!hasChildren && href) {
|
|
169
|
+
return (
|
|
170
|
+
<NavLink href={href}>
|
|
171
|
+
<MenuItem>{title}</MenuItem>
|
|
172
|
+
</NavLink>
|
|
173
|
+
);
|
|
141
174
|
}
|
|
175
|
+
|
|
176
|
+
if (hasChildren) {
|
|
177
|
+
return <RenderChildWithChildren nav={nav} />;
|
|
178
|
+
}
|
|
179
|
+
|
|
142
180
|
return null;
|
|
143
181
|
};
|
|
144
182
|
|
|
@@ -56,7 +56,7 @@ export default function Navbar({
|
|
|
56
56
|
elevation = 2,
|
|
57
57
|
hideCategories = false,
|
|
58
58
|
children,
|
|
59
|
-
}: Props) {
|
|
59
|
+
}: Readonly<Props>) {
|
|
60
60
|
return (
|
|
61
61
|
<NavbarContext.Provider value={{ hideCategories }}>
|
|
62
62
|
<NavBarWrapper hoverEffect={false} elevation={elevation} border={border}>
|
|
@@ -28,7 +28,7 @@ export default function FavoriteButton({
|
|
|
28
28
|
activeColor = "primary",
|
|
29
29
|
inactiveColor = "disabled",
|
|
30
30
|
...rest
|
|
31
|
-
}: FavoriteButtonProps) {
|
|
31
|
+
}: Readonly<FavoriteButtonProps>) {
|
|
32
32
|
const iconProps = customIconSize
|
|
33
33
|
? { sx: { fontSize: customIconSize } }
|
|
34
34
|
: { fontSize: iconSize };
|
|
@@ -397,16 +397,14 @@ ProductCard.QuickViewButton = () => {
|
|
|
397
397
|
|
|
398
398
|
ProductCard.FavoriteButton = () => {
|
|
399
399
|
const internal = useContext(ProductCardInternalContext);
|
|
400
|
-
if (!internal) return null;
|
|
401
|
-
|
|
402
|
-
const { handleToggleFavorite } = internal;
|
|
403
|
-
|
|
404
400
|
const ctx = useContext(ProductCardContext);
|
|
405
|
-
if (!ctx) return null;
|
|
406
401
|
|
|
407
|
-
const
|
|
402
|
+
const id = ctx?.product?.id;
|
|
403
|
+
const isFavorite = useFavorite(id ? Number(id) : undefined);
|
|
404
|
+
|
|
405
|
+
if (!internal || !ctx) return null;
|
|
408
406
|
|
|
409
|
-
const
|
|
407
|
+
const { handleToggleFavorite } = internal;
|
|
410
408
|
|
|
411
409
|
return (
|
|
412
410
|
<FavoriteButton isFavorite={isFavorite} onToggle={handleToggleFavorite} />
|
|
@@ -201,11 +201,11 @@ ProductCardPlp.QuickViewButton = () => {
|
|
|
201
201
|
|
|
202
202
|
ProductCardPlp.FavoriteButton = () => {
|
|
203
203
|
const ctx = useContext(ProductCardPlpContext);
|
|
204
|
-
if (!ctx) return null;
|
|
205
204
|
|
|
206
|
-
const
|
|
205
|
+
const id = ctx?.product?.id;
|
|
206
|
+
const isFavorite = useFavorite(id ? Number(id) : undefined);
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
if (!ctx) return null;
|
|
209
209
|
|
|
210
210
|
return (
|
|
211
211
|
<FavoriteButton
|
|
@@ -216,17 +216,18 @@ ProductCardPlp.FavoriteButton = () => {
|
|
|
216
216
|
/>
|
|
217
217
|
);
|
|
218
218
|
};
|
|
219
|
-
|
|
220
219
|
// Using quantity buttons (addtocart) doesn't make sense when we have product variants to select.
|
|
221
220
|
// So hide them for now, implement based on client requirements.
|
|
222
221
|
ProductCardPlp.QuantityButtons = () => {
|
|
223
222
|
const ctx = useContext(ProductCardPlpContext);
|
|
224
|
-
if (!ctx) return null;
|
|
225
223
|
|
|
226
|
-
const
|
|
224
|
+
const id = ctx?.product?.id;
|
|
227
225
|
const { currentCartLine, handleCartAmountChange, loading } = useCart(id);
|
|
226
|
+
|
|
228
227
|
const [quantity, setQuantity] = useState(currentCartLine?.Quantity || 0);
|
|
229
228
|
|
|
229
|
+
if (!ctx) return null;
|
|
230
|
+
|
|
230
231
|
const handleIncrementQuantity = () => {
|
|
231
232
|
const qty = quantity + 1;
|
|
232
233
|
handleCartAmountChange(qty);
|
|
@@ -20,7 +20,7 @@ interface Props {
|
|
|
20
20
|
}
|
|
21
21
|
// ==============================================================
|
|
22
22
|
|
|
23
|
-
export default function ProductTags({ tags }: Props) {
|
|
23
|
+
export default function ProductTags({ tags }: Readonly<Props>) {
|
|
24
24
|
return (
|
|
25
25
|
<StyledRoot>
|
|
26
26
|
{tags.map((item) => (
|
|
@@ -201,11 +201,12 @@ ProductCardPlpList.Price = () => {
|
|
|
201
201
|
|
|
202
202
|
ProductCardPlpList.FavoriteButton = () => {
|
|
203
203
|
const ctx = useContext(ProductCardPlpListContext);
|
|
204
|
-
if (!ctx) return null;
|
|
205
204
|
|
|
206
|
-
const
|
|
205
|
+
const id = ctx?.product?.id;
|
|
207
206
|
const isFavorite = useFavorite(id);
|
|
208
207
|
|
|
208
|
+
if (!ctx) return null;
|
|
209
|
+
|
|
209
210
|
return (
|
|
210
211
|
<FavoriteButton
|
|
211
212
|
isFavorite={isFavorite}
|
|
@@ -220,12 +221,14 @@ ProductCardPlpList.FavoriteButton = () => {
|
|
|
220
221
|
// So hide them for now, implement based on client requirements.
|
|
221
222
|
ProductCardPlpList.QuantityButtons = () => {
|
|
222
223
|
const ctx = useContext(ProductCardPlpListContext);
|
|
223
|
-
if (!ctx) return null;
|
|
224
224
|
|
|
225
|
-
const
|
|
225
|
+
const id = ctx?.product?.id;
|
|
226
226
|
const { currentCartLine, handleCartAmountChange, loading } = useCart(id);
|
|
227
|
+
|
|
227
228
|
const [quantity, setQuantity] = useState(currentCartLine?.Quantity || 0);
|
|
228
229
|
|
|
230
|
+
if (!ctx) return null;
|
|
231
|
+
|
|
229
232
|
const handleIncrementQuantity = () => {
|
|
230
233
|
const qty = quantity + 1;
|
|
231
234
|
handleCartAmountChange(qty);
|
|
@@ -171,9 +171,11 @@ ProductCardSearch.QuickViewButton = () => {
|
|
|
171
171
|
|
|
172
172
|
ProductCardSearch.FavoriteButton = () => {
|
|
173
173
|
const ctx = useContext(ProductCardSearchContext);
|
|
174
|
+
|
|
175
|
+
const id = ctx?.product?.id;
|
|
176
|
+
const isFavorite = useFavorite(id ? Number(id) : undefined);
|
|
177
|
+
|
|
174
178
|
if (!ctx) return null;
|
|
175
|
-
const { id } = ctx.product;
|
|
176
|
-
const isFavorite = useFavorite(Number(id));
|
|
177
179
|
|
|
178
180
|
return (
|
|
179
181
|
<FavoriteButton
|
|
@@ -12,7 +12,7 @@ import Box from "@mui/material/Box";
|
|
|
12
12
|
type Props = { price: number; discount: number };
|
|
13
13
|
// ==============================================================
|
|
14
14
|
|
|
15
|
-
export default function ProductPrice({ discount, price }: Props) {
|
|
15
|
+
export default function ProductPrice({ discount, price }: Readonly<Props>) {
|
|
16
16
|
return (
|
|
17
17
|
<FlexBox alignItems="center" gap={1} mt={0.5}>
|
|
18
18
|
<Paragraph fontWeight={600} color="primary.main">
|
|
@@ -5,7 +5,7 @@ import Link from "next/link";
|
|
|
5
5
|
type Props = { title: string; slug: string };
|
|
6
6
|
// ==============================================================
|
|
7
7
|
|
|
8
|
-
export default function ProductTitle({ title, slug }: Props) {
|
|
8
|
+
export default function ProductTitle({ title, slug }: Readonly<Props>) {
|
|
9
9
|
return (
|
|
10
10
|
<Link href={`/products/${slug}`}>
|
|
11
11
|
<H3
|
|
@@ -17,7 +17,7 @@ interface Props {
|
|
|
17
17
|
}
|
|
18
18
|
// ==============================================================
|
|
19
19
|
|
|
20
|
-
export default function QuantityButtons(props: Props) {
|
|
20
|
+
export default function QuantityButtons(props: Readonly<Props>) {
|
|
21
21
|
const { quantity, handleDecrement, handleIncrement, isLineUpdating } =
|
|
22
22
|
props || {};
|
|
23
23
|
|
|
@@ -87,7 +87,7 @@ export const useProductDialog = () => {
|
|
|
87
87
|
* </ProductViewDialog.Content>
|
|
88
88
|
* </ProductViewDialog>
|
|
89
89
|
*/
|
|
90
|
-
export default function ProductDialog(props: Props) {
|
|
90
|
+
export default function ProductDialog(props: Readonly<Props>) {
|
|
91
91
|
const { children, openDialog, handleCloseDialog } = props;
|
|
92
92
|
const { data: product } = getProductById.useSuspenseData({
|
|
93
93
|
id: Number(props.productId),
|
|
@@ -161,7 +161,7 @@ export const ProductDialogContentImages = () => {
|
|
|
161
161
|
>
|
|
162
162
|
{product?.Images?.map((item: string, index: number) => (
|
|
163
163
|
<BazaarImage
|
|
164
|
-
key={index}
|
|
164
|
+
key={item + index}
|
|
165
165
|
src={item}
|
|
166
166
|
alt="product"
|
|
167
167
|
sx={{
|
|
@@ -10,7 +10,7 @@ interface Props {
|
|
|
10
10
|
/**
|
|
11
11
|
* @category Composed Component
|
|
12
12
|
*/
|
|
13
|
-
export default function ProductDialog(props: Props) {
|
|
13
|
+
export default function ProductDialog(props: Readonly<Props>) {
|
|
14
14
|
return (
|
|
15
15
|
<ProductViewDialog {...props}>
|
|
16
16
|
<ProductViewDialog.Content>
|
|
@@ -19,6 +19,11 @@ export const DimensionGroupList = () => {
|
|
|
19
19
|
const { dimensions } = context;
|
|
20
20
|
|
|
21
21
|
return dimensions.map((dimension, i) => {
|
|
22
|
-
return
|
|
22
|
+
return (
|
|
23
|
+
<DimensionGroupListChip
|
|
24
|
+
dimension={dimension}
|
|
25
|
+
key={`dimension-${i + 1}`}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
23
28
|
});
|
|
24
29
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Dimensions } from "@evenicanpm/storefront-core/src/components-v2/product-dimensions/compound/dimensions";
|
|
3
3
|
import type { ProductDimensionValueInventoryAvailability } from "@msdyn365-commerce/retail-proxy";
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// When selecting a single dimension, loading spinner starts... not necessary, inefficient.
|
|
6
6
|
|
|
7
7
|
export type Props = {
|
|
8
8
|
dimensionGroups: ProductDimensionValueInventoryAvailability[][];
|
|
@@ -18,7 +18,7 @@ export default function ProductDimensions({
|
|
|
18
18
|
selectDimensions,
|
|
19
19
|
handleChangeVariant,
|
|
20
20
|
showDimensionError,
|
|
21
|
-
}: Props) {
|
|
21
|
+
}: Readonly<Props>) {
|
|
22
22
|
return (
|
|
23
23
|
<Dimensions
|
|
24
24
|
dimensionGroups={dimensionGroups}
|
|
@@ -27,7 +27,7 @@ export default function ProductDimensions({
|
|
|
27
27
|
showDimensionError={showDimensionError}
|
|
28
28
|
>
|
|
29
29
|
{dimensionGroups.map((group, i) => (
|
|
30
|
-
<Dimensions.Group dimensions={group} key={i}>
|
|
30
|
+
<Dimensions.Group dimensions={group} key={`dim-grp-${i + 1}`}>
|
|
31
31
|
<Dimensions.Group.Label />
|
|
32
32
|
<Dimensions.Group.List />
|
|
33
33
|
<Dimensions.Group.Error />
|
|
@@ -84,7 +84,7 @@ export function QuantityButtons({
|
|
|
84
84
|
isOOS = false,
|
|
85
85
|
customAddToCart,
|
|
86
86
|
children,
|
|
87
|
-
}: QuantityButtonProps) {
|
|
87
|
+
}: Readonly<QuantityButtonProps>) {
|
|
88
88
|
const t = useTranslations("productDetail");
|
|
89
89
|
|
|
90
90
|
const { handleAddToCart, handleCartAmountChange, loading, currentCartLine } =
|
|
@@ -27,7 +27,7 @@ interface Props {
|
|
|
27
27
|
* and the quantity selector component. These two components are usually
|
|
28
28
|
* used together so this is a pre-wired version for convenience.
|
|
29
29
|
*/
|
|
30
|
-
export default function QuantityVariantsSelect({ product }: Props) {
|
|
30
|
+
export default function QuantityVariantsSelect({ product }: Readonly<Props>) {
|
|
31
31
|
const [showDimensionError, setShowDimensionError] = useState(false);
|
|
32
32
|
|
|
33
33
|
const { DimensionValues, RecordId } = product;
|
|
@@ -61,7 +61,6 @@ export default function QuantityVariantsSelect({ product }: Props) {
|
|
|
61
61
|
const OOSCode = "OOS"; // Always means out of stock
|
|
62
62
|
|
|
63
63
|
const aggregateCode =
|
|
64
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities &&
|
|
65
64
|
shippingInventoryData?.AggregatedProductInventoryAvailabilities?.[0]
|
|
66
65
|
?.TotalAvailableInventoryLevelCode;
|
|
67
66
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
4
|
import React from "react";
|
|
5
|
-
//import { useSession } from "next-auth/react";
|
|
6
|
-
import { expect, mocked } from "storybook/test";
|
|
7
5
|
import { data, prices } from "../../../__mocks__/products";
|
|
8
6
|
import { ProductsList } from "./index";
|
|
9
7
|
|
|
@@ -30,7 +30,7 @@ import { cloneElement } from "react";
|
|
|
30
30
|
* </ProductsGridView.Container>
|
|
31
31
|
* </ProductsGridView>
|
|
32
32
|
*/
|
|
33
|
-
export default function ProductsGridView(props: ProductsViewProps) {
|
|
33
|
+
export default function ProductsGridView(props: Readonly<ProductsViewProps>) {
|
|
34
34
|
const { products, productPrices, pagination, children } = props;
|
|
35
35
|
|
|
36
36
|
return (
|
|
@@ -68,7 +68,7 @@ ProductsGridView.Grid = ({ children }: { children: React.ReactElement }) => {
|
|
|
68
68
|
value={{ price: matchingPrice, product }}
|
|
69
69
|
>
|
|
70
70
|
{cloneElement(children, {
|
|
71
|
-
key:
|
|
71
|
+
key: product.RecordId ?? product.ItemId,
|
|
72
72
|
product: product,
|
|
73
73
|
price: matchingPrice,
|
|
74
74
|
})}
|