@evenicanpm/storefront-core 1.3.0 → 1.6.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
|
@@ -155,21 +155,20 @@ const DeliveryOptions: DeliveryOptionsCompound = (props) => {
|
|
|
155
155
|
|
|
156
156
|
return (
|
|
157
157
|
<>
|
|
158
|
-
{children
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
)}
|
|
158
|
+
{children ||
|
|
159
|
+
(stepViewState === "preview" ? (
|
|
160
|
+
<DeliveryOptions.Preview
|
|
161
|
+
deliveryOptions={deliveryOptions}
|
|
162
|
+
selectedOption={selectedOption}
|
|
163
|
+
/>
|
|
164
|
+
) : (
|
|
165
|
+
<DeliveryOptions.Form
|
|
166
|
+
deliveryOptions={deliveryOptions}
|
|
167
|
+
deliveryUnavailable={deliveryUnavailable}
|
|
168
|
+
selectedOption={selectedOption}
|
|
169
|
+
onChange={handleOptionChange}
|
|
170
|
+
/>
|
|
171
|
+
))}
|
|
173
172
|
</>
|
|
174
173
|
);
|
|
175
174
|
};
|
|
@@ -68,16 +68,17 @@ OrderSummary.Title = () => {
|
|
|
68
68
|
|
|
69
69
|
OrderSummary.Item = ({ label, field }: ItemProps) => {
|
|
70
70
|
const ctx = useContext(SummaryContext);
|
|
71
|
-
if (!ctx) return null;
|
|
72
71
|
const t = useTranslations("Checkout.Summary");
|
|
72
|
+
if (!ctx) return null;
|
|
73
73
|
const { formatCurrency, order } = ctx;
|
|
74
74
|
const value = order[field];
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
let numericValue = 0;
|
|
76
|
+
|
|
77
|
+
if (typeof value === "number") {
|
|
78
|
+
numericValue = value;
|
|
79
|
+
} else if (typeof value === "string") {
|
|
80
|
+
numericValue = Number.parseFloat(value);
|
|
81
|
+
}
|
|
81
82
|
|
|
82
83
|
return (
|
|
83
84
|
<FlexBetween mb={1}>
|
|
@@ -35,10 +35,10 @@ export const OrderedProducts = ({ order, children }: Props) => {
|
|
|
35
35
|
|
|
36
36
|
OrderedProducts.Header = () => {
|
|
37
37
|
const ctx = useContext(OrderedProductsContext);
|
|
38
|
-
if (!ctx) return null;
|
|
39
38
|
const t = useTranslations("Confirmation");
|
|
40
|
-
const order = ctx;
|
|
41
39
|
const { dateTime } = useFormatter();
|
|
40
|
+
if (!ctx) return null;
|
|
41
|
+
const order = ctx;
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
44
|
<FlexBetween
|
|
@@ -128,7 +128,7 @@ OrderedProducts.Dimensions = ({ line }: LineProps) => {
|
|
|
128
128
|
return (
|
|
129
129
|
<Grid size={{ xs: 8, sm: 4 }}>
|
|
130
130
|
{line.Product.Dimensions.map((dim, i) => (
|
|
131
|
-
<Paragraph key={i} paddingLeft="15px">
|
|
131
|
+
<Paragraph key={`dim-${i + 1}`} paddingLeft="15px">
|
|
132
132
|
<Span>{ProductDimensionType[dim.DimensionTypeValue || 0]}:</Span>
|
|
133
133
|
<Span sx={{ ml: 1 }}>{dim.DimensionValue?.Value}</Span>
|
|
134
134
|
</Paragraph>
|
|
@@ -75,7 +75,7 @@ const PickupOptionSelect = ({
|
|
|
75
75
|
);
|
|
76
76
|
|
|
77
77
|
const handlePickupClick = () => {
|
|
78
|
-
if (selectedOption
|
|
78
|
+
if (selectedOption?.Code) {
|
|
79
79
|
const bopisInput: AddToCartBopisInput = {
|
|
80
80
|
warehouseId: storeId,
|
|
81
81
|
deliveryMode: selectedOption.Code,
|
|
@@ -35,7 +35,7 @@ type Props = {
|
|
|
35
35
|
inventoryRecord: ProductWarehouseInventoryAvailability | undefined;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
export default function ShopCard(props: Props) {
|
|
38
|
+
export default function ShopCard(props: Readonly<Props>) {
|
|
39
39
|
const { name, address, actionArea, openFrom, openTo, storeHours } =
|
|
40
40
|
props || {};
|
|
41
41
|
|
|
@@ -9,7 +9,7 @@ interface Props extends CheckboxProps {
|
|
|
9
9
|
}
|
|
10
10
|
// ==============================================================
|
|
11
11
|
|
|
12
|
-
export default function CheckboxLabel({ label, ...props }: Props) {
|
|
12
|
+
export default function CheckboxLabel({ label, ...props }: Readonly<Props>) {
|
|
13
13
|
return (
|
|
14
14
|
<FormControlLabel
|
|
15
15
|
label={label}
|
|
@@ -32,7 +32,7 @@ const WrapperBox = styled(Box)(({ theme }) => ({
|
|
|
32
32
|
type Props = { products: Product[] };
|
|
33
33
|
// ============================================================
|
|
34
34
|
|
|
35
|
-
export default function FrequentlyBought({ products }: Props) {
|
|
35
|
+
export default function FrequentlyBought({ products }: Readonly<Props>) {
|
|
36
36
|
return (
|
|
37
37
|
<WrapperBox mb={7.5}>
|
|
38
38
|
<H3 mb={3}>Frequently Bought Together</H3>
|
|
@@ -25,7 +25,7 @@ interface Props {
|
|
|
25
25
|
}
|
|
26
26
|
// =======================================================
|
|
27
27
|
|
|
28
|
-
export default function FrequentlyProductCard(props: Props) {
|
|
28
|
+
export default function FrequentlyProductCard(props: Readonly<Props>) {
|
|
29
29
|
const {
|
|
30
30
|
imgUrl = "/assets/images/products/Rectangle 116.png",
|
|
31
31
|
price,
|
|
@@ -24,7 +24,7 @@ interface Props {
|
|
|
24
24
|
}
|
|
25
25
|
// ===========================================================
|
|
26
26
|
|
|
27
|
-
export default function ProductComment(props: Props) {
|
|
27
|
+
export default function ProductComment(props: Readonly<Props>) {
|
|
28
28
|
const { name, imgUrl, rating, date, comment } = props || {};
|
|
29
29
|
|
|
30
30
|
return (
|
|
@@ -5,14 +5,14 @@ import type { AttributeValue } from "@msdyn365-commerce/retail-proxy";
|
|
|
5
5
|
|
|
6
6
|
type Props = { attributes: AttributeValue[] };
|
|
7
7
|
|
|
8
|
-
export default function ProductDescription({ attributes }: Props) {
|
|
8
|
+
export default function ProductDescription({ attributes }: Readonly<Props>) {
|
|
9
9
|
return (
|
|
10
10
|
<div>
|
|
11
11
|
<H3 mb={2}>Specifications:</H3>
|
|
12
12
|
{attributes?.map((attr, index) => {
|
|
13
13
|
if (attr?.TextValue && attr?.Name)
|
|
14
14
|
return (
|
|
15
|
-
<div key={index}>
|
|
15
|
+
<div key={`attr-${index + 1}`}>
|
|
16
16
|
{attr.Name}: {attr.TextValue}
|
|
17
17
|
</div>
|
|
18
18
|
);
|
|
@@ -71,7 +71,10 @@ interface Props {
|
|
|
71
71
|
}
|
|
72
72
|
// ============================================================================
|
|
73
73
|
|
|
74
|
-
export default function ProductFilterCard({
|
|
74
|
+
export default function ProductFilterCard({
|
|
75
|
+
filters,
|
|
76
|
+
changeFilters,
|
|
77
|
+
}: Readonly<Props>) {
|
|
75
78
|
const [collapsed, setCollapsed] = useState(true);
|
|
76
79
|
|
|
77
80
|
const handleChangePrice = (values: number[]) => {
|
|
@@ -21,7 +21,7 @@ type Props = {
|
|
|
21
21
|
/**
|
|
22
22
|
* @category Compound Component
|
|
23
23
|
*/
|
|
24
|
-
export default function ProductImages({ children }: Props) {
|
|
24
|
+
export default function ProductImages({ children }: Readonly<Props>) {
|
|
25
25
|
const [selectedImageIndex, setSelectedImageIndex] = useState<number>(0);
|
|
26
26
|
|
|
27
27
|
const ctx = useContext(ProductIntroContext);
|
|
@@ -34,12 +34,19 @@ export default function ProductImages({ children }: Props) {
|
|
|
34
34
|
* VARIANT SELECTION - IF VARIANT HAS IMAGES, USE THOSE
|
|
35
35
|
* IF NOT USE masterProduct
|
|
36
36
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
let images: string[] = [];
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
Array.isArray(selectedVariant?.Images) &&
|
|
41
|
+
selectedVariant.Images.length > 0
|
|
42
|
+
) {
|
|
43
|
+
images = selectedVariant.Images;
|
|
44
|
+
} else if (
|
|
45
|
+
Array.isArray(masterProduct?.Images) &&
|
|
46
|
+
masterProduct.Images.length > 0
|
|
47
|
+
) {
|
|
48
|
+
images = masterProduct.Images;
|
|
49
|
+
}
|
|
43
50
|
|
|
44
51
|
const primaryImageUrl =
|
|
45
52
|
selectedVariant?.PrimaryImageUrl || masterProduct?.PrimaryImageUrl || "";
|
|
@@ -80,30 +87,28 @@ ProductImages.Thumbnails = () => {
|
|
|
80
87
|
const { images, handleImageClick, selectedImageIndex } = ctx;
|
|
81
88
|
|
|
82
89
|
return (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
</FlexBox>
|
|
106
|
-
</>
|
|
90
|
+
<FlexBox overflow="auto" gap={1} justifyContent="center">
|
|
91
|
+
{images?.map((url: string, ind: number) => {
|
|
92
|
+
return (
|
|
93
|
+
<FlexRowCenter
|
|
94
|
+
key={`thumbnail-${ind + 1}`}
|
|
95
|
+
width={64}
|
|
96
|
+
height={64}
|
|
97
|
+
minWidth={64}
|
|
98
|
+
bgcolor="white"
|
|
99
|
+
border="1px solid"
|
|
100
|
+
borderRadius="10px"
|
|
101
|
+
style={{ cursor: "pointer" }}
|
|
102
|
+
onClick={handleImageClick(ind)}
|
|
103
|
+
borderColor={
|
|
104
|
+
selectedImageIndex === ind ? "primary.main" : "grey.400"
|
|
105
|
+
}
|
|
106
|
+
>
|
|
107
|
+
<ThumbnailWithSkeleton src={url} />
|
|
108
|
+
</FlexRowCenter>
|
|
109
|
+
);
|
|
110
|
+
})}
|
|
111
|
+
</FlexBox>
|
|
107
112
|
);
|
|
108
113
|
};
|
|
109
114
|
|
|
@@ -14,7 +14,7 @@ import type React from "react";
|
|
|
14
14
|
*/
|
|
15
15
|
type Props = { product: ProductDetails; children: React.ReactNode };
|
|
16
16
|
|
|
17
|
-
export default function ProductIntro({ product, children }: Props) {
|
|
17
|
+
export default function ProductIntro({ product, children }: Readonly<Props>) {
|
|
18
18
|
// HOOKS
|
|
19
19
|
const {
|
|
20
20
|
selectedVariant,
|
|
@@ -5,7 +5,7 @@ import { useState } from "react";
|
|
|
5
5
|
* Shows a skeleton until the image loads
|
|
6
6
|
* @category Sub-Component
|
|
7
7
|
*/
|
|
8
|
-
function ThumbnailWithSkeleton({ src }: { src: string }) {
|
|
8
|
+
function ThumbnailWithSkeleton({ src }: Readonly<{ src: string }>) {
|
|
9
9
|
const [loaded, setLoaded] = useState(false);
|
|
10
10
|
|
|
11
11
|
return (
|
|
@@ -4,8 +4,7 @@ export const getInventoryLabel = (
|
|
|
4
4
|
shippingInventoryData?: ProductWarehouseInventoryInformation,
|
|
5
5
|
): string | null => {
|
|
6
6
|
const aggregate =
|
|
7
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities
|
|
8
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities[0];
|
|
7
|
+
shippingInventoryData?.AggregatedProductInventoryAvailabilities?.[0];
|
|
9
8
|
if (aggregate) {
|
|
10
9
|
const { TotalAvailableInventoryLevelLabel } = aggregate;
|
|
11
10
|
return TotalAvailableInventoryLevelLabel || null;
|
|
@@ -19,8 +18,7 @@ export const checkProductOOS = (
|
|
|
19
18
|
//TODO: Incorporate global inventory enabled flag.
|
|
20
19
|
const OOSCode = "OOS"; // Always means out of stock
|
|
21
20
|
const aggregate =
|
|
22
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities
|
|
23
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities[0];
|
|
21
|
+
shippingInventoryData?.AggregatedProductInventoryAvailabilities?.[0];
|
|
24
22
|
if (aggregate) {
|
|
25
23
|
const { TotalAvailableInventoryLevelCode } = aggregate;
|
|
26
24
|
return TotalAvailableInventoryLevelCode === OOSCode;
|
|
@@ -37,7 +37,7 @@ interface TabPanelProps {
|
|
|
37
37
|
value: number;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function CustomTabPanel(props: TabPanelProps) {
|
|
40
|
+
function CustomTabPanel(props: Readonly<TabPanelProps>) {
|
|
41
41
|
const { children, value, index, ...other } = props;
|
|
42
42
|
|
|
43
43
|
return (
|
|
@@ -52,7 +52,10 @@ const TabsContext = createContext<TabsContext | null>(null);
|
|
|
52
52
|
/**
|
|
53
53
|
* @category Compound Component
|
|
54
54
|
*/
|
|
55
|
-
export default function ProductTabs({
|
|
55
|
+
export default function ProductTabs({
|
|
56
|
+
productAttributes,
|
|
57
|
+
children,
|
|
58
|
+
}: Readonly<Props>) {
|
|
56
59
|
const [selectedOption, setSelectedOption] = useState(0);
|
|
57
60
|
const handleOptionClick = (_: React.SyntheticEvent, value: number) =>
|
|
58
61
|
setSelectedOption(value);
|
|
@@ -12,7 +12,7 @@ import Grid from "@mui/material/Grid2";
|
|
|
12
12
|
type Props = { RecordId: number };
|
|
13
13
|
// ==============================================================
|
|
14
14
|
|
|
15
|
-
export default function RelatedProducts({ RecordId }: Props) {
|
|
15
|
+
export default function RelatedProducts({ RecordId }: Readonly<Props>) {
|
|
16
16
|
const { data: products } = GetRelatedProductsDataFetcher.useData({
|
|
17
17
|
id: RecordId,
|
|
18
18
|
});
|
|
@@ -21,12 +21,15 @@ export default function RelatedProducts({ RecordId }: Props) {
|
|
|
21
21
|
<H3 mb={3}>Related Products</H3>
|
|
22
22
|
|
|
23
23
|
<Grid container spacing={3}>
|
|
24
|
-
{products?.map((item
|
|
25
|
-
<Grid
|
|
24
|
+
{products?.map((item) => (
|
|
25
|
+
<Grid
|
|
26
|
+
size={{ lg: 3, md: 4, sm: 6, xs: 12 }}
|
|
27
|
+
key={item.RecordId ?? item.ItemId}
|
|
28
|
+
>
|
|
26
29
|
<ProductCard
|
|
27
30
|
product={{
|
|
28
31
|
id: item.ItemId ?? "",
|
|
29
|
-
slug: String(item?.RecordId
|
|
32
|
+
slug: String(item?.RecordId ?? ""),
|
|
30
33
|
title: item.Name ?? "",
|
|
31
34
|
price: item.Price ?? 0,
|
|
32
35
|
imgUrl: item.PrimaryImageUrl ?? "",
|
|
@@ -9,7 +9,7 @@ interface Props extends CheckboxProps {
|
|
|
9
9
|
}
|
|
10
10
|
// ==============================================================
|
|
11
11
|
|
|
12
|
-
export default function CheckboxLabel({ label, ...props }: Props) {
|
|
12
|
+
export default function CheckboxLabel({ label, ...props }: Readonly<Props>) {
|
|
13
13
|
return (
|
|
14
14
|
<FormControlLabel
|
|
15
15
|
label={label}
|
|
@@ -31,7 +31,7 @@ export default function FacetGroup({
|
|
|
31
31
|
facet,
|
|
32
32
|
selectedRefiners,
|
|
33
33
|
handleRefinerSelect,
|
|
34
|
-
}: Props) {
|
|
34
|
+
}: Readonly<Props>) {
|
|
35
35
|
const isAnyRefinerFromFacetSelected = () =>
|
|
36
36
|
facet.Values?.some((v) => isRefinerSelected(v));
|
|
37
37
|
const isRefinerSelected = (r1: ProductRefinerValue) =>
|
|
@@ -8,7 +8,7 @@ import React from "react";
|
|
|
8
8
|
import CheckboxLabel from "./checkbox-label";
|
|
9
9
|
import type { RenderedFacetProps } from "./facet-group";
|
|
10
10
|
|
|
11
|
-
type Props = RenderedFacetProps
|
|
11
|
+
type Props = RenderedFacetProps;
|
|
12
12
|
|
|
13
13
|
const generateKey = (f: ProductRefinerValue) => {
|
|
14
14
|
return `${f.LeftValueBoundString}-${f.RefinerRecordId}`;
|
|
@@ -18,7 +18,7 @@ export default function ListFilter({
|
|
|
18
18
|
facet,
|
|
19
19
|
handleRefinerSelect,
|
|
20
20
|
isRefinerSelected,
|
|
21
|
-
}: Props) {
|
|
21
|
+
}: Readonly<Props>) {
|
|
22
22
|
const createFacetLabel = (f: ProductRefinerValue) => {
|
|
23
23
|
const label = f.LeftValueBoundLocalizedString || f.LeftValueBoundString;
|
|
24
24
|
return (
|
|
@@ -117,8 +117,10 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
117
117
|
const refiners = newInputParams.searchState.refinement;
|
|
118
118
|
const priceIndex = ProductRefinerSource.Price;
|
|
119
119
|
const idx = refiners.findIndex((r) => areRefinersEqual(r, refiner));
|
|
120
|
+
|
|
120
121
|
if (refiner.RefinerSourceValue === priceIndex) {
|
|
121
122
|
const priceRefiner = refiners[idx];
|
|
123
|
+
|
|
122
124
|
if (idx > -1) {
|
|
123
125
|
if (
|
|
124
126
|
priceRefiner.LeftValueBoundString ===
|
|
@@ -133,7 +135,9 @@ const ProductListProvider = ({ children }: { children: React.ReactNode }) => {
|
|
|
133
135
|
} else {
|
|
134
136
|
refiners.push(refiner);
|
|
135
137
|
}
|
|
136
|
-
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (refiner.RefinerSourceValue !== priceIndex) {
|
|
137
141
|
if (idx > -1) {
|
|
138
142
|
refiners.splice(idx, 1);
|
|
139
143
|
} else {
|
|
@@ -32,7 +32,10 @@ const usePLV = () => {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
type RootProps = { categoryId: number; children?: ReactNode };
|
|
35
|
-
export default function ProductListView({
|
|
35
|
+
export default function ProductListView({
|
|
36
|
+
categoryId,
|
|
37
|
+
children,
|
|
38
|
+
}: Readonly<RootProps>) {
|
|
36
39
|
return (
|
|
37
40
|
<ProductListViewContext.Provider value={{ categoryId }}>
|
|
38
41
|
{children}
|
|
@@ -6,7 +6,10 @@ interface Props extends BoxProps {
|
|
|
6
6
|
rating: number;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export default function ProductRating({
|
|
9
|
+
export default function ProductRating({
|
|
10
|
+
rating = 0,
|
|
11
|
+
...props
|
|
12
|
+
}: Readonly<Props>) {
|
|
10
13
|
return (
|
|
11
14
|
<Box display="flex" gap={1} alignItems="center" {...props}>
|
|
12
15
|
<Rating size="small" value={rating} color="warn" readOnly />
|
|
@@ -5,7 +5,6 @@ import type {
|
|
|
5
5
|
} from "@evenicanpm/storefront-core/src/api-manager/schemas/product.schema";
|
|
6
6
|
import getProductAvailability from "@evenicanpm/storefront-core/src/api-manager/services/product/queries/get-product-availability";
|
|
7
7
|
import { FlexBox } from "@evenicanpm/storefront-core/src/components-v2/flex-box";
|
|
8
|
-
// import ImageWithFallback from "@app/_shared/ImageWithFallback";
|
|
9
8
|
import ImageWithFallback from "@evenicanpm/storefront-core/src/components-v2/ImageWithFallback";
|
|
10
9
|
import ProductDimensions from "@evenicanpm/storefront-core/src/components-v2/product-dimensions";
|
|
11
10
|
import QuantityButtons from "@evenicanpm/storefront-core/src/components-v2/product-quantity-buttons";
|
|
@@ -46,7 +45,7 @@ export default function QuickViewContent({
|
|
|
46
45
|
cart,
|
|
47
46
|
productDetails,
|
|
48
47
|
handleClose,
|
|
49
|
-
}: Props) {
|
|
48
|
+
}: Readonly<Props>) {
|
|
50
49
|
const [showDimensionError, setShowDimensionError] = useState(false);
|
|
51
50
|
const {
|
|
52
51
|
selectedVariant,
|
|
@@ -106,8 +105,7 @@ export default function QuickViewContent({
|
|
|
106
105
|
|
|
107
106
|
const getInventoryLabel = (): string | null => {
|
|
108
107
|
const aggregate =
|
|
109
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities
|
|
110
|
-
shippingInventoryData?.AggregatedProductInventoryAvailabilities[0];
|
|
108
|
+
shippingInventoryData?.AggregatedProductInventoryAvailabilities?.[0];
|
|
111
109
|
if (aggregate) {
|
|
112
110
|
const { TotalAvailableInventoryLevelLabel } = aggregate;
|
|
113
111
|
return TotalAvailableInventoryLevelLabel || null;
|
|
@@ -10,7 +10,11 @@ interface Props {
|
|
|
10
10
|
product: ProductSearchResult;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export default function QuickView({
|
|
13
|
+
export default function QuickView({
|
|
14
|
+
open,
|
|
15
|
+
handleClose,
|
|
16
|
+
product,
|
|
17
|
+
}: Readonly<Props>) {
|
|
14
18
|
if (!open) {
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
@@ -44,7 +44,6 @@ export default function RangeFilter({
|
|
|
44
44
|
setMaxVal(Number(selectedValues.RightValueBoundString));
|
|
45
45
|
setTextMin(Number(selectedValues.LeftValueBoundString));
|
|
46
46
|
setTextMax(Number(selectedValues.RightValueBoundString));
|
|
47
|
-
} else {
|
|
48
47
|
}
|
|
49
48
|
}, [selectedValues]);
|
|
50
49
|
|
|
@@ -4,7 +4,7 @@ import type { ProductRefinerValue } from "@msdyn365-commerce/retail-proxy";
|
|
|
4
4
|
import { Box, Chip, useTheme } from "@mui/material";
|
|
5
5
|
import type { RenderedFacetProps } from "./facet-group";
|
|
6
6
|
|
|
7
|
-
type Props = RenderedFacetProps
|
|
7
|
+
type Props = RenderedFacetProps;
|
|
8
8
|
|
|
9
9
|
const cssColorName = (color: string | undefined) => {
|
|
10
10
|
if (!color) return false;
|
|
@@ -21,12 +21,21 @@ export default function Swatch({
|
|
|
21
21
|
facet,
|
|
22
22
|
handleRefinerSelect,
|
|
23
23
|
isRefinerSelected,
|
|
24
|
-
}: Props) {
|
|
24
|
+
}: Readonly<Props>) {
|
|
25
25
|
const theme = useTheme();
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
28
|
<Box mb={3}>
|
|
29
29
|
{facet.Values?.map((colorItem: ProductRefinerValue) => {
|
|
30
|
+
const borderStyle = (() => {
|
|
31
|
+
if (checkWhite(colorItem.LeftValueBoundString)) {
|
|
32
|
+
return "1px solid black";
|
|
33
|
+
}
|
|
34
|
+
if (isRefinerSelected(colorItem)) {
|
|
35
|
+
return "2px solid";
|
|
36
|
+
}
|
|
37
|
+
return "2px solid transparent";
|
|
38
|
+
})();
|
|
30
39
|
return (
|
|
31
40
|
<Box
|
|
32
41
|
key={colorItem.LeftValueBoundString}
|
|
@@ -48,11 +57,7 @@ export default function Swatch({
|
|
|
48
57
|
: theme.palette.grey[300]),
|
|
49
58
|
width: 32,
|
|
50
59
|
height: 32,
|
|
51
|
-
border:
|
|
52
|
-
? "1px solid black"
|
|
53
|
-
: isRefinerSelected(colorItem)
|
|
54
|
-
? "2px solid"
|
|
55
|
-
: "2px solid transparent",
|
|
60
|
+
border: borderStyle,
|
|
56
61
|
"&:hover": {
|
|
57
62
|
backgroundColor:
|
|
58
63
|
colorItem.SwatchColorHexCode ||
|