@evenicanpm/storefront-core 2.0.0 → 2.1.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/.storybook/main.ts +2 -3
- package/.storybook/preview.tsx +0 -2
- package/__mocks__/create-mutation.ts +16 -8
- package/__mocks__/next-image.tsx +12 -3
- package/package.json +2 -2
- package/src/api-manager/datasources/d365/d365-categories.datasource.ts +2 -3
- package/src/api-manager/datasources/d365/d365-order.datasource.ts +4 -4
- package/src/api-manager/datasources/d365/d365-organization.datasource.ts +15 -8
- package/src/api-manager/datasources/d365/d365-product.datasource.ts +31 -19
- package/src/api-manager/datasources/d365/d365-user.datasource.ts +47 -19
- package/src/api-manager/datasources/e4/address/e4-address.remaps.ts +2 -2
- package/src/api-manager/datasources/e4/cart/e4-cart.remaps.ts +1 -1
- package/src/api-manager/datasources/e4/product/e4-product.remaps.ts +3 -3
- package/src/api-manager/datasources/e4/user/e4-user.datasource.ts +4 -8
- package/src/api-manager/index.ts +10 -127
- package/src/api-manager/lib/get-graphql-client.ts +2 -2
- package/src/api-manager/schemas/product.schema.ts +9 -0
- package/src/api-manager/services/create-extension-query.ts +1 -1
- package/src/api-manager/services/create-query.ts +106 -266
- package/src/api-manager/types/Datasource.ts +0 -3
- package/src/cms/blocks/components/category-card.tsx +0 -1
- package/src/cms/blocks/components/category-carousel/index.tsx +0 -1
- package/src/cms/blocks/components/featured-categories.tsx +1 -2
- package/src/cms/blocks/components/featured-products.tsx +1 -2
- package/src/cms/blocks/components/footer/index.tsx +0 -1
- package/src/cms/blocks/components/footer/sections/footer-app-store.tsx +1 -1
- package/src/cms/blocks/components/footer/sections/footer-contact.tsx +0 -1
- package/src/cms/blocks/components/footer/sections/footer-links.tsx +1 -1
- package/src/cms/blocks/components/footer/sections/footer-logo.tsx +0 -1
- package/src/cms/blocks/components/footer/sections/footer-social-links.tsx +0 -1
- package/src/cms/blocks/components/footer.tsx +0 -1
- package/src/cms/blocks/components/hero-carousel/index.tsx +0 -1
- package/src/cms/blocks/components/hero.tsx +0 -1
- package/src/cms/blocks/components/image.tsx +0 -1
- package/src/cms/blocks/components/media-card.tsx +0 -1
- package/src/cms/blocks/components/product-carousel/index.tsx +0 -1
- package/src/cms/blocks/components/product-section-fullwidth/index.tsx +0 -1
- package/src/cms/blocks/components/rich-text.tsx +0 -1
- package/src/cms/blocks/components/seo/index.tsx +1 -2
- package/src/cms/blocks/components/services/index.tsx +0 -1
- package/src/cms/blocks/components/services/service-card.tsx +0 -1
- package/src/cms/blocks/components/shared/featured-product-card.tsx +0 -1
- package/src/cms/blocks/components/shared/product-category-item.tsx +1 -1
- package/src/cms/blocks/components/shared/product-grid.tsx +0 -1
- package/src/cms/blocks/components/shared/top-categories-card.tsx +0 -1
- package/src/cms/blocks/components/shared/top-rating-product-card.tsx +0 -1
- package/src/cms/blocks/icons/components/category.tsx +0 -1
- package/src/cms/blocks/icons/components/dotted-star.tsx +0 -1
- package/src/cms/blocks/icons/components/fallback-icon.tsx +0 -1
- package/src/cms/blocks/icons/components/gift-box.tsx +0 -1
- package/src/cms/blocks/icons/components/light.tsx +0 -1
- package/src/cms/blocks/icons/components/new-arrival.tsx +0 -1
- package/src/cms/blocks/icons/components/rank-badge.tsx +0 -1
- package/src/components/BazaarTextField.tsx +7 -7
- package/src/components/CountryInput.stories.tsx +4 -2
- package/src/components/T/__tests__/T.test.tsx +9 -13
- package/src/components/T/index.tsx +0 -1
- package/src/components/Typography.tsx +0 -1
- package/src/components/_tests_/site-logo.test.tsx +4 -5
- package/src/components/categories/category-list/category-list.tsx +1 -1
- package/src/components/countries-input.tsx +1 -1
- package/src/components/nav-link/nav-link.tsx +2 -8
- package/src/components/navbar/mega-menu/mega-menu.tsx +7 -1
- package/src/components/navbar/mobile-menu/mobile-menu.test.tsx +2 -1
- package/src/components/navbar/nav-list/cms-nav.test.tsx +0 -1
- package/src/components/no-records.tsx +0 -1
- package/src/components/product-cards/favorite-button.tsx +0 -1
- package/src/components/product-cards/product-card/styles/index.ts +2 -2
- package/src/components/product-cards/product-card-plp-list/ProductCardPlpList.stories.tsx +0 -1
- package/src/components/product-cards/product-card-search/ProductCardSearch.stories.tsx +0 -1
- package/src/components/product-dimensions/Dimensions.stories.tsx +2 -4
- package/src/components/product-dimensions/compound/dimensions-group-list-chip.tsx +1 -1
- package/src/components/product-dimensions/compound/dimensions.tsx +1 -1
- package/src/components/product-quantity-buttons/ProductQuantity.stories.tsx +1 -3
- package/src/components/product-quantity-buttons/__tests__/product-quantity-buttons.test.tsx +3 -2
- package/src/components/product-quantity-buttons/compound/quantity-buttons-root.tsx +1 -1
- package/src/components/product-quantity-buttons/index.tsx +0 -1
- package/src/components/product-quantity-variants/ProductQuantity.stories.tsx +1 -3
- package/src/components/products-view/ProductsGrid.stories.tsx +1 -3
- package/src/components/products-view/ProductsList.stories.tsx +1 -3
- package/src/components/products-view/__tests__/products-view.test.tsx +20 -9
- package/src/components/products-view/index.tsx +1 -1
- package/src/components/scrollbar/Scrollbar.stories.tsx +1 -3
- package/src/components/scrollbar/__tests__/scrollbar.test.tsx +7 -1
- package/src/components/search-bar/SearchBarLarge.stories.tsx +1 -3
- package/src/components/search-bar/compound/results-item-lg.tsx +0 -1
- package/src/components/search-bar/compound/results-item-sm.tsx +0 -1
- package/src/components/search-bar/compound/textfield-adornment-category.tsx +0 -1
- package/src/components/search-bar/compound/textfield.tsx +0 -1
- package/src/components/search-bar/utils/findCategoryNameById.ts +3 -3
- package/src/components/section/__tests__/section.test.tsx +14 -7
- package/src/components/side-nav/SideNav.stories.tsx +1 -1
- package/src/components/site-logo.tsx +8 -1
- package/src/components/wishlist-dialogs/add-to-wishlist/add-to-wishlist-button.tsx +1 -1
- package/src/components/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-bottom-ui.tsx +1 -1
- package/src/components/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-header.tsx +0 -1
- package/src/components/wishlist-dialogs/create-wishlist/compound/create-wishlist-bottom-ui.tsx +1 -1
- package/src/hooks/use-nextauth-session.ts +4 -1
- package/src/lib/lib.ts +1 -1
- package/src/lib/page-slugs.ts +0 -2
- package/src/lib/refiner-utils.ts +3 -3
- package/src/pages/account/account-navigation.tsx +17 -20
- package/src/pages/account/addresses/address-form.tsx +15 -7
- package/src/pages/account/dashboard-header.tsx +1 -1
- package/src/pages/cart/checkout-form.tsx +1 -1
- package/src/pages/checkout/checkout-alt-form/checkout-step.tsx +1 -1
- package/src/pages/checkout/checkout-alt-form/steps/address/new-address-form.tsx +1 -1
- package/src/pages/checkout/checkout-alt-form/steps/payment/payment-details.tsx +5 -2
- package/src/pages/checkout/checkout-alt-summary/cart-item.tsx +1 -1
- package/src/pages/checkout/checkout-alt-summary/checkout-alt-summary.tsx +1 -1
- package/src/pages/confirmation/address.tsx +1 -1
- package/src/pages/confirmation/confirmation-summary.tsx +1 -1
- package/src/pages/product-details/currency.ts +1 -1
- package/src/pages/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +4 -1
- package/src/pages/product-list/breadcrumbs.tsx +0 -1
- package/src/pages/product-list/list-filter.tsx +0 -1
- package/src/pages/product-list/product-list-context.tsx +1 -1
- package/src/pages/product-list/product-list-view.tsx +2 -2
- package/src/pages/product-list/selected-facets.tsx +1 -1
- package/src/pages/quickorder/context.ts +8 -2
- package/src/pages/quickorder/order-upload.tsx +26 -8
- package/src/pages/quickorder/provider.tsx +8 -9
- package/src/pages/quickorder/quick-order.tsx +17 -11
- package/src/providers/nav-provider/index.tsx +1 -1
- package/tsconfig.json +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { CartLine } from "@evenicanpm/storefront-core/src/api-manager/schemas/cart.schema";
|
|
1
2
|
import { render } from "@testing-library/react";
|
|
2
3
|
import type { ReactNode } from "react";
|
|
3
|
-
import { vi } from "vitest";
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
4
5
|
import ProductQuantityButtons from "../index";
|
|
5
6
|
|
|
6
7
|
vi.mock("next-intl", () => ({
|
|
@@ -12,7 +13,7 @@ vi.mock("@evenicanpm/storefront-core/src/hooks/use-cart", () => ({
|
|
|
12
13
|
handleAddToCart: vi.fn(),
|
|
13
14
|
handleCartAmountChange: vi.fn(),
|
|
14
15
|
loading: false,
|
|
15
|
-
currentCartLine: { Quantity: 1 } as
|
|
16
|
+
currentCartLine: { Quantity: 1 } as CartLine | undefined,
|
|
16
17
|
})),
|
|
17
18
|
}));
|
|
18
19
|
|
|
@@ -9,7 +9,7 @@ import type { CartLine } from "@msdyn365-commerce/retail-proxy";
|
|
|
9
9
|
import Button from "@mui/material/Button";
|
|
10
10
|
import CircularProgress from "@mui/material/CircularProgress";
|
|
11
11
|
import { useTranslations } from "next-intl";
|
|
12
|
-
import
|
|
12
|
+
import { createContext, type ReactNode, useContext } from "react";
|
|
13
13
|
import { MdAdd as Add, MdRemove as Remove } from "react-icons/md";
|
|
14
14
|
// TODO: Encapsulate the addToCart api calls inside this component
|
|
15
15
|
// so no need to pass in props.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
|
|
2
2
|
|
|
3
|
-
import type { Meta
|
|
4
|
-
import React from "react";
|
|
3
|
+
import type { Meta } from "@storybook/react";
|
|
5
4
|
import { product } from "../../../__mocks__/product-dimensions";
|
|
6
5
|
import QuantityButtons from "./index";
|
|
7
6
|
|
|
@@ -12,7 +11,6 @@ const meta = {
|
|
|
12
11
|
} satisfies Meta<typeof QuantityButtons>;
|
|
13
12
|
|
|
14
13
|
export default meta;
|
|
15
|
-
type Story = StoryObj<typeof meta>;
|
|
16
14
|
|
|
17
15
|
export const Interactive = () => {
|
|
18
16
|
return <QuantityButtons product={product} />;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
|
|
2
2
|
|
|
3
|
-
import type { Meta
|
|
4
|
-
import React from "react";
|
|
3
|
+
import type { Meta } from "@storybook/react";
|
|
5
4
|
import { data, prices } from "../../../__mocks__/products";
|
|
6
5
|
import { ProductsGrid } from "./index";
|
|
7
6
|
|
|
@@ -12,7 +11,6 @@ const meta = {
|
|
|
12
11
|
} satisfies Meta<typeof ProductsGrid>;
|
|
13
12
|
|
|
14
13
|
export default meta;
|
|
15
|
-
type Story = StoryObj<typeof meta>;
|
|
16
14
|
|
|
17
15
|
export const Interactive = () => {
|
|
18
16
|
return <ProductsGrid products={data.products} productPrices={prices} />;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
|
|
2
2
|
|
|
3
|
-
import type { Meta
|
|
4
|
-
import React from "react";
|
|
3
|
+
import type { Meta } from "@storybook/react";
|
|
5
4
|
import { data, prices } from "../../../__mocks__/products";
|
|
6
5
|
import { ProductsList } from "./index";
|
|
7
6
|
|
|
@@ -12,7 +11,6 @@ const meta = {
|
|
|
12
11
|
} satisfies Meta<typeof ProductsList>;
|
|
13
12
|
|
|
14
13
|
export default meta;
|
|
15
|
-
type Story = StoryObj<typeof meta>;
|
|
16
14
|
|
|
17
15
|
export const Interactive = () => {
|
|
18
16
|
return <ProductsList products={data.products} productPrices={prices} />;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
2
2
|
import { render } from "@testing-library/react";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
3
4
|
import { vi } from "vitest";
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ProductsGrid,
|
|
7
|
+
ProductsList,
|
|
8
|
+
type Props as ProductsViewProps,
|
|
9
|
+
} from "../index";
|
|
10
|
+
|
|
11
|
+
type MockChildrenProps = { children?: ReactNode };
|
|
5
12
|
|
|
6
13
|
vi.mock("next-intl", () => ({
|
|
7
14
|
useTranslations: () => (key: string) => key,
|
|
@@ -19,11 +26,11 @@ vi.mock(
|
|
|
19
26
|
"@evenicanpm/storefront-core/src/components/products-view/compound/products-grid-view",
|
|
20
27
|
() => ({
|
|
21
28
|
default: Object.assign(
|
|
22
|
-
({ children }:
|
|
29
|
+
({ children }: MockChildrenProps) => (
|
|
23
30
|
<div data-testid="products-grid-view">{children}</div>
|
|
24
31
|
),
|
|
25
32
|
{
|
|
26
|
-
Grid: ({ children }:
|
|
33
|
+
Grid: ({ children }: MockChildrenProps) => (
|
|
27
34
|
<div data-testid="products-grid">{children}</div>
|
|
28
35
|
),
|
|
29
36
|
Card: () => <div data-testid="product-card">Card</div>,
|
|
@@ -36,11 +43,11 @@ vi.mock(
|
|
|
36
43
|
"@evenicanpm/storefront-core/src/components/products-view/compound/products-list-view",
|
|
37
44
|
() => ({
|
|
38
45
|
default: Object.assign(
|
|
39
|
-
({ children }:
|
|
46
|
+
({ children }: MockChildrenProps) => (
|
|
40
47
|
<div data-testid="products-list-view">{children}</div>
|
|
41
48
|
),
|
|
42
49
|
{
|
|
43
|
-
List: ({ children }:
|
|
50
|
+
List: ({ children }: MockChildrenProps) => (
|
|
44
51
|
<div data-testid="products-list">{children}</div>
|
|
45
52
|
),
|
|
46
53
|
Card: () => <div data-testid="product-card">Card</div>,
|
|
@@ -80,9 +87,11 @@ describe("ProductsView components", () => {
|
|
|
80
87
|
});
|
|
81
88
|
|
|
82
89
|
it("renders with product prices", () => {
|
|
83
|
-
const prices = [
|
|
90
|
+
const prices = [
|
|
91
|
+
{ price: 100, adjustedPrice: 80, productId: 1 },
|
|
92
|
+
] as NonNullable<ProductsViewProps["productPrices"]>;
|
|
84
93
|
const { container } = render(
|
|
85
|
-
<ProductsGrid products={mockProducts} productPrices={prices
|
|
94
|
+
<ProductsGrid products={mockProducts} productPrices={prices} />,
|
|
86
95
|
);
|
|
87
96
|
expect(
|
|
88
97
|
container.querySelector("[data-testid='products-grid-view']"),
|
|
@@ -126,9 +135,11 @@ describe("ProductsView components", () => {
|
|
|
126
135
|
});
|
|
127
136
|
|
|
128
137
|
it("renders with product prices", () => {
|
|
129
|
-
const prices = [
|
|
138
|
+
const prices = [
|
|
139
|
+
{ price: 100, adjustedPrice: 80, productId: 1 },
|
|
140
|
+
] as NonNullable<ProductsViewProps["productPrices"]>;
|
|
130
141
|
const { container } = render(
|
|
131
|
-
<ProductsList products={mockProducts} productPrices={prices
|
|
142
|
+
<ProductsList products={mockProducts} productPrices={prices} />,
|
|
132
143
|
);
|
|
133
144
|
expect(
|
|
134
145
|
container.querySelector("[data-testid='products-list-view']"),
|
|
@@ -3,7 +3,7 @@ import ProductsGridView from "@evenicanpm/storefront-core/src/components/product
|
|
|
3
3
|
import ProductsListView from "@evenicanpm/storefront-core/src/components/products-view/compound/products-list-view";
|
|
4
4
|
// DATA MODEL
|
|
5
5
|
import type { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
6
|
-
import
|
|
6
|
+
import type { ReactNode } from "react";
|
|
7
7
|
|
|
8
8
|
export interface Props {
|
|
9
9
|
/** List of products to display */
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
|
|
2
2
|
|
|
3
|
-
import type { Meta
|
|
4
|
-
import React from "react";
|
|
3
|
+
import type { Meta } from "@storybook/react";
|
|
5
4
|
import Scrollbar from "./index";
|
|
6
5
|
|
|
7
6
|
const meta = {
|
|
@@ -11,7 +10,6 @@ const meta = {
|
|
|
11
10
|
} satisfies Meta<typeof Scrollbar>;
|
|
12
11
|
|
|
13
12
|
export default meta;
|
|
14
|
-
type Story = StoryObj<typeof meta>;
|
|
15
13
|
|
|
16
14
|
export const WithLink = () => (
|
|
17
15
|
<div style={{ height: "500px" }}>
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
3
|
import { vi } from "vitest";
|
|
3
4
|
import Scrollbar from "../scrollbar";
|
|
4
5
|
|
|
6
|
+
type SimplebarMockProps = HTMLAttributes<HTMLDivElement> & {
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
autoHide?: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
5
11
|
vi.mock("simplebar-react", () => ({
|
|
6
|
-
default: ({ children, autoHide, ...props }:
|
|
12
|
+
default: ({ children, autoHide, ...props }: SimplebarMockProps) => (
|
|
7
13
|
<div data-testid="custom-scrollbar" data-autohide={autoHide} {...props}>
|
|
8
14
|
{children}
|
|
9
15
|
</div>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
|
|
2
2
|
|
|
3
|
-
import type { Meta
|
|
4
|
-
import React from "react";
|
|
3
|
+
import type { Meta } from "@storybook/react";
|
|
5
4
|
import { SearchBarViewLg } from "./index";
|
|
6
5
|
|
|
7
6
|
const meta = {
|
|
@@ -12,6 +11,5 @@ const meta = {
|
|
|
12
11
|
} satisfies Meta<typeof SearchBarViewLg>;
|
|
13
12
|
|
|
14
13
|
export default meta;
|
|
15
|
-
type Story = StoryObj<typeof meta>;
|
|
16
14
|
|
|
17
15
|
export const WithLink = () => <SearchBarViewLg></SearchBarViewLg>;
|
|
@@ -16,7 +16,6 @@ import { getProductDetailUrl } from "@evenicanpm/storefront-core/src/lib/build-p
|
|
|
16
16
|
import { currency } from "@evenicanpm/storefront-core/src/lib/lib";
|
|
17
17
|
import { Box, Grid } from "@mui/material";
|
|
18
18
|
import MenuItem from "@mui/material/MenuItem";
|
|
19
|
-
import React from "react";
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Small, horizontal result item card, used for mobile view.
|
|
@@ -10,7 +10,6 @@ import TouchRipple from "@mui/material/ButtonBase";
|
|
|
10
10
|
import MenuItem from "@mui/material/MenuItem";
|
|
11
11
|
import useTheme from "@mui/material/styles/useTheme";
|
|
12
12
|
import { useTranslations } from "next-intl";
|
|
13
|
-
import React from "react";
|
|
14
13
|
import { MdKeyboardArrowDown as KeyboardArrowDownOutlined } from "react-icons/md";
|
|
15
14
|
|
|
16
15
|
type DisplayCategory = {
|
|
@@ -10,7 +10,6 @@ import { INPUT_SX } from "@evenicanpm/storefront-core/src/components/search-bar/
|
|
|
10
10
|
import { useMediaQuery, useTheme } from "@mui/material";
|
|
11
11
|
import TextField from "@mui/material/TextField";
|
|
12
12
|
import { useTranslations } from "next-intl";
|
|
13
|
-
import React from "react";
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* The actual input field for the search bar.
|
|
@@ -5,9 +5,9 @@ import type { Category } from "@msdyn365-commerce/retail-proxy";
|
|
|
5
5
|
*/
|
|
6
6
|
export const findCategoryNameById = (
|
|
7
7
|
searchCategory: number,
|
|
8
|
-
categories:
|
|
9
|
-
t:
|
|
10
|
-
) => {
|
|
8
|
+
categories: Category[] | undefined,
|
|
9
|
+
t: (key: string) => string,
|
|
10
|
+
): string => {
|
|
11
11
|
if (searchCategory === 0) {
|
|
12
12
|
return t("Navigation.allCategoriesLabel");
|
|
13
13
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
|
-
import {
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import { describe, expect, it, vi } from "vitest";
|
|
3
4
|
import { Section } from "../compound/section";
|
|
4
5
|
|
|
5
6
|
vi.mock("next-intl", () => ({
|
|
@@ -14,7 +15,13 @@ vi.mock(
|
|
|
14
15
|
);
|
|
15
16
|
|
|
16
17
|
vi.mock("@mui/material/Container", () => ({
|
|
17
|
-
default: ({
|
|
18
|
+
default: ({
|
|
19
|
+
className,
|
|
20
|
+
children,
|
|
21
|
+
}: {
|
|
22
|
+
className?: string;
|
|
23
|
+
children?: ReactNode;
|
|
24
|
+
}) => (
|
|
18
25
|
<div data-testid="mui-container" className={className}>
|
|
19
26
|
{children}
|
|
20
27
|
</div>
|
|
@@ -28,7 +35,7 @@ describe("Section", () => {
|
|
|
28
35
|
<div>Section Content</div>
|
|
29
36
|
</Section>,
|
|
30
37
|
);
|
|
31
|
-
expect(screen.getByText("Section Content")).
|
|
38
|
+
expect(screen.getByText("Section Content")).toBeTruthy();
|
|
32
39
|
});
|
|
33
40
|
|
|
34
41
|
it("renders with Container component", () => {
|
|
@@ -69,7 +76,7 @@ describe("Section", () => {
|
|
|
69
76
|
<div>Spaced Content</div>
|
|
70
77
|
</Section>,
|
|
71
78
|
);
|
|
72
|
-
expect(screen.getByText("Spaced Content")).
|
|
79
|
+
expect(screen.getByText("Spaced Content")).toBeTruthy();
|
|
73
80
|
});
|
|
74
81
|
|
|
75
82
|
it("exposes Header subcomponent", () => {
|
|
@@ -84,9 +91,9 @@ describe("Section", () => {
|
|
|
84
91
|
<div>Child 3</div>
|
|
85
92
|
</Section>,
|
|
86
93
|
);
|
|
87
|
-
expect(screen.getByText("Child 1")).
|
|
88
|
-
expect(screen.getByText("Child 2")).
|
|
89
|
-
expect(screen.getByText("Child 3")).
|
|
94
|
+
expect(screen.getByText("Child 1")).toBeTruthy();
|
|
95
|
+
expect(screen.getByText("Child 2")).toBeTruthy();
|
|
96
|
+
expect(screen.getByText("Child 3")).toBeTruthy();
|
|
90
97
|
});
|
|
91
98
|
|
|
92
99
|
it("accepts custom sx styling", () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import Image from "next/image";
|
|
3
4
|
import Link from "next/link";
|
|
4
5
|
|
|
5
6
|
interface SiteLogoProps {
|
|
@@ -9,7 +10,13 @@ interface SiteLogoProps {
|
|
|
9
10
|
const SiteLogo: React.FC<SiteLogoProps> = () => {
|
|
10
11
|
return (
|
|
11
12
|
<Link href="/">
|
|
12
|
-
<
|
|
13
|
+
<Image
|
|
14
|
+
src="/logo-blue.png"
|
|
15
|
+
alt="E4 Logo"
|
|
16
|
+
width={180}
|
|
17
|
+
height={54}
|
|
18
|
+
style={{ width: "auto", height: 54 }}
|
|
19
|
+
/>
|
|
13
20
|
</Link>
|
|
14
21
|
);
|
|
15
22
|
};
|
|
@@ -23,7 +23,7 @@ const AddToWishlistButton = (props: Props) => {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
// conditionally render button styles based on variant (pdp or minicart)
|
|
26
|
-
let style:
|
|
26
|
+
let style: ButtonProps["sx"];
|
|
27
27
|
let btnFullwidth: boolean;
|
|
28
28
|
let btnColor: ButtonProps["color"];
|
|
29
29
|
let btnVariant: ButtonProps["variant"];
|
package/src/components/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-bottom-ui.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AddToWishListDialogContext } from "@evenicanpm/storefront-core/src/components/wishlist-dialogs/add-to-wishlist/compound/context";
|
|
2
2
|
import { Button, Grid } from "@mui/material";
|
|
3
3
|
import { useTranslations } from "next-intl";
|
|
4
|
-
import
|
|
4
|
+
import { useContext } from "react";
|
|
5
5
|
|
|
6
6
|
const AddToWishListBottomUI = () => {
|
|
7
7
|
const t = useTranslations("Account.Wishlists");
|
|
@@ -11,7 +11,6 @@ import { IconButton, styled, type Theme } from "@mui/material";
|
|
|
11
11
|
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
12
12
|
import { useSession } from "next-auth/react";
|
|
13
13
|
import { useTranslations } from "next-intl";
|
|
14
|
-
import React from "react";
|
|
15
14
|
// ICONS
|
|
16
15
|
import { MdFavorite } from "react-icons/md";
|
|
17
16
|
|
package/src/components/wishlist-dialogs/create-wishlist/compound/create-wishlist-bottom-ui.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { CreateNewWishlistContext } from "@evenicanpm/storefront-core/src/compon
|
|
|
2
2
|
import { Button } from "@mui/material";
|
|
3
3
|
import Grid from "@mui/material/Grid2";
|
|
4
4
|
import { useTranslations } from "next-intl";
|
|
5
|
-
import
|
|
5
|
+
import { useContext } from "react";
|
|
6
6
|
|
|
7
7
|
function BottomUI() {
|
|
8
8
|
const t = useTranslations("Account.Wishlists");
|
|
@@ -42,7 +42,10 @@ export function useAppSession() {
|
|
|
42
42
|
await initializeMsal();
|
|
43
43
|
const res = await getMsalInstance().handleRedirectPromise();
|
|
44
44
|
if (res) {
|
|
45
|
-
const { given_name, family_name } = res.idTokenClaims as
|
|
45
|
+
const { given_name, family_name } = res.idTokenClaims as {
|
|
46
|
+
given_name?: string;
|
|
47
|
+
family_name?: string;
|
|
48
|
+
};
|
|
46
49
|
if (given_name && family_name) {
|
|
47
50
|
updateUser({
|
|
48
51
|
AccountNumber: "",
|
package/src/lib/lib.ts
CHANGED
package/src/lib/page-slugs.ts
CHANGED
package/src/lib/refiner-utils.ts
CHANGED
|
@@ -12,11 +12,11 @@ const convertParameterToRefiner = (parameter: string): ProductRefinerValue => {
|
|
|
12
12
|
sourceValue,
|
|
13
13
|
] = parameter.split("|");
|
|
14
14
|
return {
|
|
15
|
-
RefinerRecordId: Number.parseInt(recordId),
|
|
16
|
-
DataTypeValue: Number.parseInt(dataTypeValue),
|
|
15
|
+
RefinerRecordId: Number.parseInt(recordId, 10),
|
|
16
|
+
DataTypeValue: Number.parseInt(dataTypeValue, 10),
|
|
17
17
|
LeftValueBoundString: leftBoundString,
|
|
18
18
|
RightValueBoundString: rightBoundString,
|
|
19
|
-
RefinerSourceValue: Number.parseInt(sourceValue),
|
|
19
|
+
RefinerSourceValue: Number.parseInt(sourceValue, 10),
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
|
|
@@ -114,25 +114,22 @@ const AccountNavigation = ({ items, children }: AccountNavigationProps) => {
|
|
|
114
114
|
return (
|
|
115
115
|
<AccountNavigationContext.Provider value={{ items: mergedItems }}>
|
|
116
116
|
<MainContainer>
|
|
117
|
-
{children ||
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
))}
|
|
134
|
-
</>
|
|
135
|
-
)}
|
|
117
|
+
{children ||
|
|
118
|
+
mergedItems.map((section) => (
|
|
119
|
+
<AccountNavigation.Section
|
|
120
|
+
key={section.title}
|
|
121
|
+
title={section.title}
|
|
122
|
+
>
|
|
123
|
+
{section.list.map((item) => (
|
|
124
|
+
<AccountNavigation.Item
|
|
125
|
+
key={item.title}
|
|
126
|
+
{...item}
|
|
127
|
+
isActive={pathname?.includes(item.href) ?? false}
|
|
128
|
+
label={t(item.title)}
|
|
129
|
+
/>
|
|
130
|
+
))}
|
|
131
|
+
</AccountNavigation.Section>
|
|
132
|
+
))}
|
|
136
133
|
</MainContainer>
|
|
137
134
|
</AccountNavigationContext.Provider>
|
|
138
135
|
);
|
|
@@ -156,7 +153,7 @@ AccountNavigation.Section = ({ title, children }: SectionProps) => {
|
|
|
156
153
|
|
|
157
154
|
interface ItemProps {
|
|
158
155
|
href: string;
|
|
159
|
-
Icon: React.ComponentType<
|
|
156
|
+
Icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
|
|
160
157
|
count?: number;
|
|
161
158
|
label: string;
|
|
162
159
|
isActive?: boolean;
|
|
@@ -28,8 +28,18 @@ import { useLocale, useTranslations } from "next-intl";
|
|
|
28
28
|
import React, { createContext, useContext } from "react";
|
|
29
29
|
import { z } from "zod";
|
|
30
30
|
|
|
31
|
+
interface AddressFormValues {
|
|
32
|
+
Name: string;
|
|
33
|
+
Street: string;
|
|
34
|
+
City: string;
|
|
35
|
+
State: string;
|
|
36
|
+
ZipCode: string;
|
|
37
|
+
Country: string;
|
|
38
|
+
Phone: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
interface FormContextValue {
|
|
32
|
-
formik: ReturnType<typeof useFormik<
|
|
42
|
+
formik: ReturnType<typeof useFormik<AddressFormValues>>;
|
|
33
43
|
countries: CountryRegionInfo[] | undefined;
|
|
34
44
|
states: { StateId?: string; StateName?: string }[] | undefined;
|
|
35
45
|
selectedCountry: CountryRegionInfo | null;
|
|
@@ -78,9 +88,7 @@ const AddressForm = ({ address, children }: RootProps) => {
|
|
|
78
88
|
Phone: z.string().optional().default(""),
|
|
79
89
|
});
|
|
80
90
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const initialValues: FormSchemaType = {
|
|
91
|
+
const initialValues: AddressFormValues = {
|
|
84
92
|
Name: address?.Name ?? "",
|
|
85
93
|
Street: address?.Street ?? "",
|
|
86
94
|
City: address?.City ?? "",
|
|
@@ -90,7 +98,7 @@ const AddressForm = ({ address, children }: RootProps) => {
|
|
|
90
98
|
Phone: address?.Phone ?? "",
|
|
91
99
|
};
|
|
92
100
|
|
|
93
|
-
const handleSubmit = async (values:
|
|
101
|
+
const handleSubmit = async (values: AddressFormValues) => {
|
|
94
102
|
let newAddress: Address = {
|
|
95
103
|
Name: values.Name,
|
|
96
104
|
Street: values.Street,
|
|
@@ -123,7 +131,7 @@ const AddressForm = ({ address, children }: RootProps) => {
|
|
|
123
131
|
}
|
|
124
132
|
};
|
|
125
133
|
|
|
126
|
-
const formik = useFormik<
|
|
134
|
+
const formik = useFormik<AddressFormValues>({
|
|
127
135
|
initialValues,
|
|
128
136
|
onSubmit: handleSubmit,
|
|
129
137
|
validate: withZodSchema(FormSchema),
|
|
@@ -140,7 +148,7 @@ const AddressForm = ({ address, children }: RootProps) => {
|
|
|
140
148
|
|
|
141
149
|
// ------------------- Fields -------------------
|
|
142
150
|
interface FieldProps {
|
|
143
|
-
name: keyof
|
|
151
|
+
name: keyof AddressFormValues;
|
|
144
152
|
label?: string;
|
|
145
153
|
required?: boolean;
|
|
146
154
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "@mui/material";
|
|
16
16
|
import Link from "next/link";
|
|
17
17
|
import { useTranslations } from "next-intl";
|
|
18
|
-
import
|
|
18
|
+
import { createContext, type ReactNode, useContext } from "react";
|
|
19
19
|
import type { IconType } from "react-icons";
|
|
20
20
|
import { MdMenu as Menu } from "react-icons/md";
|
|
21
21
|
|
|
@@ -141,7 +141,7 @@ CheckoutForm.Notes = () => {
|
|
|
141
141
|
multiline
|
|
142
142
|
onChange={debounceCommentUpdate}
|
|
143
143
|
inputRef={textRef}
|
|
144
|
-
inputProps={{
|
|
144
|
+
inputProps={{ "data-testid": "cart-comment" }}
|
|
145
145
|
/>
|
|
146
146
|
<Divider sx={{ mb: 2 }} />
|
|
147
147
|
</>
|
|
@@ -44,7 +44,7 @@ interface NewAddressFormCtx {
|
|
|
44
44
|
states: { StateName: string; StateId: string }[] | undefined;
|
|
45
45
|
selectedCountry: CountryRegionInfo | null;
|
|
46
46
|
setSelectedCountry: (c: CountryRegionInfo | null) => void;
|
|
47
|
-
errors: Record<
|
|
47
|
+
errors: Partial<Record<keyof AddressFormInput, { message?: string }>>;
|
|
48
48
|
t: ReturnType<typeof useTranslations>;
|
|
49
49
|
onCancel: () => void;
|
|
50
50
|
}
|
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
Small,
|
|
9
9
|
} from "@evenicanpm/storefront-core/src/components/Typography";
|
|
10
10
|
import type { CheckoutStepComponentProps } from "@evenicanpm/storefront-core/src/pages/checkout/checkout-alt-form/checkout-step";
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
CardPaymentAcceptPoint,
|
|
13
|
+
CardPaymentAcceptResult,
|
|
14
|
+
} from "@msdyn365-commerce/retail-proxy";
|
|
12
15
|
import { Alert, Box, Card } from "@mui/material";
|
|
13
16
|
import { useTranslations } from "next-intl";
|
|
14
17
|
import React from "react";
|
|
@@ -43,7 +46,7 @@ type PaymentDetailsCompound = React.FC<CheckoutStepComponentProps> & {
|
|
|
43
46
|
iframeReference: React.RefObject<HTMLIFrameElement>;
|
|
44
47
|
iframeHeight: number;
|
|
45
48
|
errorState: PaymentError[];
|
|
46
|
-
paymentAcceptPointData:
|
|
49
|
+
paymentAcceptPointData: CardPaymentAcceptPoint | null | undefined;
|
|
47
50
|
}>;
|
|
48
51
|
};
|
|
49
52
|
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Span,
|
|
8
8
|
} from "@evenicanpm/storefront-core/src/components/Typography";
|
|
9
9
|
import useCurrencyFormatter from "@evenicanpm/storefront-core/src/lib/currency-formatter";
|
|
10
|
-
import
|
|
10
|
+
import { createContext, type ReactNode, useContext } from "react";
|
|
11
11
|
|
|
12
12
|
interface CartItemContextValue {
|
|
13
13
|
cartLine: CartLine;
|
|
@@ -13,7 +13,7 @@ import ListItem from "@evenicanpm/storefront-core/src/pages/checkout/checkout-al
|
|
|
13
13
|
import Box from "@mui/material/Box";
|
|
14
14
|
import Divider from "@mui/material/Divider";
|
|
15
15
|
import { useTranslations } from "next-intl";
|
|
16
|
-
import
|
|
16
|
+
import { createContext, type ReactNode, useContext } from "react";
|
|
17
17
|
|
|
18
18
|
interface Props {
|
|
19
19
|
cart: Cart;
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "@evenicanpm/storefront-core/src/components/Typography";
|
|
8
8
|
import { Card } from "@mui/material";
|
|
9
9
|
import { useTranslations } from "next-intl";
|
|
10
|
-
import
|
|
10
|
+
import { createContext, type ReactNode, useContext } from "react";
|
|
11
11
|
|
|
12
12
|
const AddressContext = createContext<Address | null>(null);
|
|
13
13
|
|