@evenicanpm/storefront-core 1.0.3 → 1.0.4
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/docs.tsconfig.json +35 -0
- package/package.json +6 -3
- package/src/api-manager/schemas/product.schema.ts +0 -1
- package/src/api-manager/services/create-query.ts +10 -0
- package/src/api-manager/services/product/queries/get-product-availability.ts +1 -1
- package/src/api-manager/services/user/mutations/add-to-wishlist.ts +23 -3
- package/src/api-manager/services/user/mutations/remove-from-wishlist.ts +23 -0
- package/src/cms/blocks/Components/CategoryCarousel/index.tsx +6 -7
- package/src/cms/blocks/Components/HeroCarousel/index.tsx +25 -19
- package/src/cms/blocks/Components/ProductCarousel/index.tsx +44 -38
- package/src/cms/blocks/Components/ProductSectionFullWidth/index.tsx +7 -3
- package/src/cms/blocks/Components/shared/product-grid.tsx +38 -23
- package/src/components/_components/wishlist/add-to-wishlist-dialog.tsx +1 -1
- package/src/components/_components/wishlist/remove-from-wishlist-dialog.tsx +1 -1
- package/src/components/_components/wishlist-modal/add-to-wishlist-dialog.tsx +1 -1
- package/src/components/_components/wishlist-modal/remove-from-wishlist-dialog.tsx +1 -1
- package/src/components-v2/carousel/carousel.tsx +69 -35
- package/src/components-v2/carousel/components/carousel-arrows.tsx +40 -46
- package/src/components-v2/carousel/components/carousel-dots.tsx +10 -13
- package/src/components-v2/carousel/index.ts +0 -2
- package/src/components-v2/carousel-cards/carousel-card-1/carousel-card-1.tsx +68 -49
- package/src/components-v2/categories/category-list/category-list.tsx +83 -41
- package/src/components-v2/categories/category-list/styles.ts +7 -1
- package/src/components-v2/categories/category-menu.tsx +2 -0
- package/src/components-v2/categories/mega-menu/banner.tsx +68 -37
- package/src/components-v2/categories/mega-menu/column-list.tsx +59 -52
- package/src/components-v2/categories/mega-menu/mega-menu-1.tsx +19 -1
- package/src/components-v2/categories/mega-menu/mega-menu-2.tsx +32 -2
- package/src/components-v2/header/components/mobile-header.tsx +119 -46
- package/src/components-v2/header/components/user.tsx +163 -117
- package/src/components-v2/header/header.tsx +62 -42
- package/src/components-v2/header/sticky-header.tsx +34 -2
- package/src/components-v2/mini-cart/components/bottom-actions.tsx +71 -17
- package/src/components-v2/mini-cart/components/cart-item.tsx +159 -101
- package/src/components-v2/mini-cart/components/empty-view.tsx +59 -19
- package/src/components-v2/mini-cart/components/top-header.tsx +61 -22
- package/src/components-v2/mini-cart/mini-cart-trigger.tsx +99 -0
- package/src/components-v2/mini-cart/mini-cart.tsx +111 -43
- package/src/components-v2/mobile-navigation/mobile-navigation-bar.tsx +93 -48
- package/src/components-v2/navbar/categories.tsx +70 -16
- package/src/components-v2/navbar/category-based-menu/category-based-menu.tsx +135 -41
- package/src/components-v2/navbar/mega-menu/mega-menu.tsx +115 -48
- package/src/components-v2/navbar/mobile-menu/mobile-menu.test.tsx +111 -0
- package/src/components-v2/navbar/mobile-menu/mobile-menu.tsx +127 -56
- package/src/components-v2/navbar/nav-list/nav-list.tsx +125 -103
- package/src/components-v2/navbar/navbar.tsx +72 -20
- package/src/components-v2/product-cards/{product-card-1 → product-card}/components/quantity-buttons.tsx +1 -1
- package/src/components-v2/product-cards/product-card/product-card.tsx +410 -0
- package/src/components-v2/product-cards/{product-card-1 → product-card}/styles/index.ts +6 -0
- package/src/components-v2/product-cards/product-card-plp/product-card.tsx +161 -0
- package/src/components-v2/product-cards/product-card-plp-list/index.ts +1 -0
- package/src/components-v2/product-cards/product-card-plp-list/product-card.tsx +219 -0
- package/src/components-v2/product-cards/product-card-search/product-card.tsx +166 -0
- package/src/components-v2/product-dialog/compound/product-dialog.tsx +225 -0
- package/src/components-v2/product-dialog/index.tsx +29 -0
- package/src/components-v2/product-dimensions/{components → compound}/dimensions-group-error.tsx +1 -1
- package/src/components-v2/product-dimensions/{components → compound}/dimensions-group-label.tsx +1 -1
- package/src/components-v2/product-dimensions/{components → compound}/dimensions-group-list-chip.tsx +1 -1
- package/src/components-v2/product-dimensions/{components → compound}/dimensions-group-list.tsx +1 -1
- package/src/components-v2/product-dimensions/{components → compound}/dimensions-group.tsx +1 -1
- package/src/components-v2/product-dimensions/{components → compound}/dimensions.tsx +0 -3
- package/src/components-v2/product-dimensions/index.tsx +1 -1
- package/src/components-v2/product-quantity-buttons/compound/quantity-buttons-root.tsx +181 -0
- package/src/components-v2/product-quantity-buttons/index.tsx +22 -0
- package/src/components-v2/product-quantity-variants/index.tsx +90 -0
- package/src/components-v2/products-view/compound/context.ts +25 -0
- package/src/components-v2/products-view/compound/products-grid-view.tsx +109 -0
- package/src/components-v2/products-view/compound/products-list-view.tsx +98 -0
- package/src/components-v2/products-view/compound/types.ts +12 -0
- package/src/components-v2/products-view/index.tsx +45 -0
- package/src/components-v2/products-view/products-grid-view.tsx +24 -11
- package/src/components-v2/products-view/products-list-view.tsx +29 -12
- package/src/components-v2/search-bar/compound/context.ts +31 -0
- package/src/components-v2/search-bar/compound/results-item-lg.tsx +43 -0
- package/src/components-v2/search-bar/compound/results-item-sm.tsx +48 -0
- package/src/components-v2/search-bar/compound/results-suspense.tsx +49 -0
- package/src/components-v2/search-bar/compound/results.tsx +42 -0
- package/src/components-v2/search-bar/compound/search-bar-root.tsx +64 -0
- package/src/components-v2/search-bar/compound/textfield-adornment-button.tsx +22 -0
- package/src/components-v2/{search-box/components/category-dropdown.tsx → search-bar/compound/textfield-adornment-category.tsx} +29 -7
- package/src/components-v2/search-bar/compound/textfield-adornment-search-icon.tsx +34 -0
- package/src/components-v2/search-bar/compound/textfield.tsx +58 -0
- package/src/components-v2/search-bar/hooks/use-click-outside.ts +20 -0
- package/src/components-v2/search-bar/hooks/use-search.ts +63 -0
- package/src/components-v2/search-bar/index.tsx +36 -0
- package/src/components-v2/{search-box → search-bar}/styles/index.ts +5 -3
- package/src/components-v2/search-bar/utils/findCategoryNameById.ts +18 -0
- package/src/components-v2/section/compound/section-header.tsx +63 -0
- package/src/components-v2/section/compound/section.tsx +26 -0
- package/src/components-v2/section/index.ts +1 -0
- package/src/components-v2/side-nav/side-nav.tsx +4 -5
- package/src/components-v2/sticky/index.ts +1 -1
- package/src/components-v2/{wishlist-modal → wishlist-dialogs/add-to-wishlist}/add-to-wishlist-button.tsx +1 -1
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-bottom-ui.tsx +35 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-dialog.tsx +79 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-list.tsx +41 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/context.ts +29 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-header.tsx +74 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-item.tsx +82 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/hooks/use-add-to-wishlist.ts +152 -0
- package/src/components-v2/wishlist-dialogs/add-to-wishlist/index.tsx +39 -0
- package/src/components-v2/wishlist-dialogs/create-wishlist/compound/context.ts +2 -0
- package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-bottom-ui.tsx +42 -0
- package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-dialog.tsx +92 -0
- package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-form.tsx +96 -0
- package/src/components-v2/{wishlist/components → wishlist-dialogs/create-wishlist}/create-wishlist-button.tsx +5 -3
- package/src/components-v2/wishlist-dialogs/create-wishlist/index.tsx +22 -0
- package/src/hooks/use-cart.ts +29 -23
- package/src/hooks/use-variants.ts +106 -53
- package/src/lib/build-detail-url.ts +2 -1
- package/src/pages/product-details/product-intro/product-intro.tsx +26 -23
- package/src/pages/product-list/quick-view-dialog-content.tsx +18 -9
- package/src/pages-v2/product-details/bopis/find-in-store-button.tsx +9 -8
- package/src/pages-v2/product-details/bopis/find-in-store-modal.tsx +2 -2
- package/src/{components-v2/shop-card → pages-v2/product-details/bopis/store-card}/shop-card.tsx +17 -48
- package/src/pages-v2/product-details/bopis/store-card/utils/convertSecondsToTime.ts +8 -0
- package/src/pages-v2/product-details/bopis/store-card/utils/getDaysResources.ts +25 -0
- package/src/pages-v2/product-details/product-intro/compound/context.ts +52 -0
- package/src/pages-v2/product-details/product-intro/compound/product-info.tsx +231 -0
- package/src/pages-v2/product-details/product-intro/compound/product-intro-images.tsx +124 -0
- package/src/pages-v2/product-details/product-intro/compound/product-intro.tsx +49 -0
- package/src/pages-v2/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +28 -0
- package/src/pages-v2/product-details/product-intro/utils.ts +42 -0
- package/src/pages-v2/product-details/product-tabs.tsx +87 -21
- package/src/pages-v2/product-details/related-products.tsx +26 -12
- package/src/pages-v2/product-list/quick-view-dialog-content.tsx +17 -10
- package/typedoc.js +3 -1
- package/src/components-v2/MiniCartClient.tsx +0 -65
- package/src/components-v2/carousel-cards/carousel-card-2/carousel-card-2.tsx +0 -78
- package/src/components-v2/carousel-cards/carousel-card-2/index.ts +0 -1
- package/src/components-v2/carousel-cards/carousel-card-2/styles.ts +0 -26
- package/src/components-v2/carousel-cards/carousel-card-3/carousel-card-3.tsx +0 -37
- package/src/components-v2/carousel-cards/carousel-card-3/index.ts +0 -1
- package/src/components-v2/carousel-cards/carousel-card-3/styles.ts +0 -28
- package/src/components-v2/carousel-cards/carousel-card-4/carousel-card-4.tsx +0 -81
- package/src/components-v2/carousel-cards/carousel-card-4/index.ts +0 -1
- package/src/components-v2/carousel-cards/carousel-card-4/styles.ts +0 -27
- package/src/components-v2/category-cards/category-card-1/category-card-1.tsx +0 -21
- package/src/components-v2/category-cards/category-card-1/index.ts +0 -1
- package/src/components-v2/category-cards/category-card-1/styles.ts +0 -37
- package/src/components-v2/countdown/count-box.tsx +0 -19
- package/src/components-v2/countdown/count-down.tsx +0 -24
- package/src/components-v2/countdown/index.tsx +0 -2
- package/src/components-v2/countdown/useCountDown.ts +0 -41
- package/src/components-v2/data-table/index.ts +0 -2
- package/src/components-v2/data-table/table-header.tsx +0 -91
- package/src/components-v2/data-table/table-pagination.tsx +0 -36
- package/src/components-v2/footer/components/about-links.tsx +0 -23
- package/src/components-v2/footer/components/app-store.tsx +0 -38
- package/src/components-v2/footer/components/customer-care-links.tsx +0 -21
- package/src/components-v2/footer/components/logo.tsx +0 -23
- package/src/components-v2/footer/components/social-links.tsx +0 -43
- package/src/components-v2/footer/data/index.ts +0 -54
- package/src/components-v2/footer/footer-1.tsx +0 -62
- package/src/components-v2/footer/footer-2.tsx +0 -57
- package/src/components-v2/footer/footer-3.tsx +0 -53
- package/src/components-v2/footer/footer-4.tsx +0 -71
- package/src/components-v2/footer/index.ts +0 -4
- package/src/components-v2/footer/styles/index.ts +0 -42
- package/src/components-v2/navbar/category-based-menu/components/categories.tsx +0 -44
- package/src/components-v2/navbar/category-based-menu/components/category-item.tsx +0 -31
- package/src/components-v2/navbar/category-based-menu/components/child-categories.tsx +0 -38
- package/src/components-v2/navbar/mega-menu/category-list.tsx +0 -29
- package/src/components-v2/navbar/mobile-menu/render-levels.test.tsx +0 -71
- package/src/components-v2/navbar/mobile-menu/render-levels.tsx +0 -62
- package/src/components-v2/newsletter/index.ts +0 -1
- package/src/components-v2/newsletter/newsletter.tsx +0 -112
- package/src/components-v2/newsletter/social-icons.tsx +0 -35
- package/src/components-v2/newsletter/styles.ts +0 -65
- package/src/components-v2/page-sidenav/grocery-side-nav/components/link-item.tsx +0 -21
- package/src/components-v2/page-sidenav/grocery-side-nav/components/list-item.tsx +0 -27
- package/src/components-v2/page-sidenav/grocery-side-nav/components/nav-accordion.tsx +0 -36
- package/src/components-v2/page-sidenav/grocery-side-nav/components/render-child.tsx +0 -26
- package/src/components-v2/page-sidenav/grocery-side-nav/grocery-side-nav.tsx +0 -32
- package/src/components-v2/page-sidenav/grocery-side-nav/index.ts +0 -1
- package/src/components-v2/page-sidenav/grocery-side-nav/styles/index.ts +0 -11
- package/src/components-v2/page-sidenav/health-beauty-side-nav/components/list-item.tsx +0 -27
- package/src/components-v2/page-sidenav/health-beauty-side-nav/components/nav-accordion.tsx +0 -44
- package/src/components-v2/page-sidenav/health-beauty-side-nav/components/render-child.tsx +0 -20
- package/src/components-v2/page-sidenav/health-beauty-side-nav/health-beauty-side-nav.tsx +0 -43
- package/src/components-v2/page-sidenav/health-beauty-side-nav/index.ts +0 -1
- package/src/components-v2/page-sidenav/health-beauty-side-nav/styles/index.ts +0 -27
- package/src/components-v2/page-sidenav/side-navbar/components/list-item.tsx +0 -25
- package/src/components-v2/page-sidenav/side-navbar/components/nav-accordion.tsx +0 -46
- package/src/components-v2/page-sidenav/side-navbar/components/render-child.tsx +0 -20
- package/src/components-v2/page-sidenav/side-navbar/index.ts +0 -1
- package/src/components-v2/page-sidenav/side-navbar/side-nav-bar.tsx +0 -77
- package/src/components-v2/page-sidenav/side-navbar/styles/index.ts +0 -73
- package/src/components-v2/page-sidenav/side-navbar-2/components/button-content.tsx +0 -32
- package/src/components-v2/page-sidenav/side-navbar-2/components/sidebar-accordion.tsx +0 -66
- package/src/components-v2/page-sidenav/side-navbar-2/index.ts +0 -1
- package/src/components-v2/page-sidenav/side-navbar-2/side-navbar-2.tsx +0 -63
- package/src/components-v2/page-sidenav/side-navbar-2/styles/index.ts +0 -68
- package/src/components-v2/product-cards/product-card-1/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-1/product-card-1-wrapper.tsx +0 -304
- package/src/components-v2/product-cards/product-card-1/product-card.tsx +0 -107
- package/src/components-v2/product-cards/product-card-10/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-10/product-card.tsx +0 -128
- package/src/components-v2/product-cards/product-card-10/styles/index.ts +0 -38
- package/src/components-v2/product-cards/product-card-11/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-11/product-card.tsx +0 -66
- package/src/components-v2/product-cards/product-card-11/styles/index.ts +0 -16
- package/src/components-v2/product-cards/product-card-12/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-12/product-card.tsx +0 -42
- package/src/components-v2/product-cards/product-card-12/styles/index.ts +0 -16
- package/src/components-v2/product-cards/product-card-13/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-13/product-card.tsx +0 -48
- package/src/components-v2/product-cards/product-card-13/styles/index.ts +0 -25
- package/src/components-v2/product-cards/product-card-14/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-14/product-card.tsx +0 -125
- package/src/components-v2/product-cards/product-card-14/styles/index.ts +0 -40
- package/src/components-v2/product-cards/product-card-15/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-15/product-card.tsx +0 -121
- package/src/components-v2/product-cards/product-card-15/styles/index.ts +0 -57
- package/src/components-v2/product-cards/product-card-16/product-card.tsx +0 -116
- package/src/components-v2/product-cards/product-card-2/components/favorite-button.tsx +0 -29
- package/src/components-v2/product-cards/product-card-2/components/product-price.tsx +0 -26
- package/src/components-v2/product-cards/product-card-2/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-2/product-card.tsx +0 -70
- package/src/components-v2/product-cards/product-card-3/components/hover-actions.tsx +0 -83
- package/src/components-v2/product-cards/product-card-3/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-3/product-card.tsx +0 -110
- package/src/components-v2/product-cards/product-card-3/styles/index.ts +0 -89
- package/src/components-v2/product-cards/product-card-4/components/hover-actions.tsx +0 -50
- package/src/components-v2/product-cards/product-card-4/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-4/product-card.tsx +0 -128
- package/src/components-v2/product-cards/product-card-4/styles/index.ts +0 -66
- package/src/components-v2/product-cards/product-card-5/components/button-actions.tsx +0 -49
- package/src/components-v2/product-cards/product-card-5/components/hover-actions.tsx +0 -50
- package/src/components-v2/product-cards/product-card-5/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-5/product-card.tsx +0 -137
- package/src/components-v2/product-cards/product-card-5/styles/index.ts +0 -94
- package/src/components-v2/product-cards/product-card-6/components/hover-actions.tsx +0 -50
- package/src/components-v2/product-cards/product-card-6/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-6/product-card.tsx +0 -121
- package/src/components-v2/product-cards/product-card-6/styles/index.ts +0 -63
- package/src/components-v2/product-cards/product-card-7/components/product-status.tsx +0 -18
- package/src/components-v2/product-cards/product-card-7/components/quantity-buttons.tsx +0 -47
- package/src/components-v2/product-cards/product-card-7/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-7/product-card.tsx +0 -139
- package/src/components-v2/product-cards/product-card-7/styles/index.ts +0 -98
- package/src/components-v2/product-cards/product-card-8/product-card.tsx +0 -151
- package/src/components-v2/product-cards/product-card-9/index.ts +0 -1
- package/src/components-v2/product-cards/product-card-9/product-card.tsx +0 -169
- package/src/components-v2/product-cards/product-card-wishlist/components/hover-actions.tsx +0 -37
- package/src/components-v2/product-cards/product-card-wishlist/product-card.tsx +0 -118
- package/src/components-v2/product-cards/product-card-wishlist/styles/index.ts +0 -53
- package/src/components-v2/product-quantity-buttons/product-quantity-buttons.tsx +0 -88
- package/src/components-v2/products-view/product-view-dialog.tsx +0 -218
- package/src/components-v2/search-box/__test__/search-input-category.test.tsx +0 -110
- package/src/components-v2/search-box/__test__/search-input.test.tsx +0 -137
- package/src/components-v2/search-box/__test__/search-results.json +0 -165
- package/src/components-v2/search-box/components/search-result.tsx +0 -86
- package/src/components-v2/search-box/hooks/use-search.ts +0 -63
- package/src/components-v2/search-box/index.ts +0 -2
- package/src/components-v2/search-box/search-input-category.test.tsx +0 -110
- package/src/components-v2/search-box/search-input-category.tsx +0 -203
- package/src/components-v2/search-box/search-input.test.tsx +0 -41
- package/src/components-v2/search-box/search-input.tsx +0 -66
- package/src/components-v2/section-header/index.ts +0 -2
- package/src/components-v2/section-header/section-creator.tsx +0 -29
- package/src/components-v2/section-header/section-header.tsx +0 -44
- package/src/components-v2/service-cards/icon-component.tsx +0 -18
- package/src/components-v2/service-cards/service-card-1/index.ts +0 -1
- package/src/components-v2/service-cards/service-card-1/service-card-1.tsx +0 -42
- package/src/components-v2/service-cards/service-card-2/index.ts +0 -1
- package/src/components-v2/service-cards/service-card-2/service-card-2.tsx +0 -37
- package/src/components-v2/service-cards/service-card-3/index.ts +0 -1
- package/src/components-v2/service-cards/service-card-3/service-card-3.tsx +0 -28
- package/src/components-v2/service-cards/service-card-3/styles.ts +0 -23
- package/src/components-v2/settings/index.ts +0 -1
- package/src/components-v2/settings/setting.tsx +0 -141
- package/src/components-v2/settings/styles.ts +0 -57
- package/src/components-v2/sticky-wrapper/index.ts +0 -1
- package/src/components-v2/sticky-wrapper/sticky-wrapper.tsx +0 -21
- package/src/components-v2/sticky-wrapper/styles.ts +0 -25
- package/src/components-v2/stories/story-content/index.ts +0 -1
- package/src/components-v2/stories/story-content/story-content.tsx +0 -28
- package/src/components-v2/stories/story-content/styles.ts +0 -22
- package/src/components-v2/stories/story-item/index.ts +0 -1
- package/src/components-v2/stories/story-item/story-item.tsx +0 -24
- package/src/components-v2/stories/story-item/styles.ts +0 -11
- package/src/components-v2/stories/story-viewer/index.ts +0 -1
- package/src/components-v2/stories/story-viewer/story-viewer.tsx +0 -44
- package/src/components-v2/stories/story-viewer/styles.ts +0 -15
- package/src/components-v2/subscribe-input/index.ts +0 -1
- package/src/components-v2/subscribe-input/styles.ts +0 -14
- package/src/components-v2/subscribe-input/subscribe-input.tsx +0 -43
- package/src/components-v2/topbar/index.ts +0 -1
- package/src/components-v2/topbar/styles.ts +0 -55
- package/src/components-v2/topbar/top-bar.tsx +0 -115
- package/src/components-v2/wishlist/add-to-wishlist-dialog.tsx +0 -161
- package/src/components-v2/wishlist/components/create-new-list.tsx +0 -167
- package/src/components-v2/wishlist/components/dashboard-header.tsx +0 -123
- package/src/components-v2/wishlist/components/navigation.tsx +0 -87
- package/src/components-v2/wishlist/components/no-records.tsx +0 -20
- package/src/components-v2/wishlist/components/wishlist-modal-item.tsx +0 -66
- package/src/components-v2/wishlist/remove-from-wishlist-dialog.tsx +0 -175
- package/src/components-v2/wishlist-modal/TODO.md +0 -10
- package/src/components-v2/wishlist-modal/add-to-wishlist-dialog.tsx +0 -161
- package/src/components-v2/wishlist-modal/remove-from-wishlist-dialog.tsx +0 -174
- package/src/components-v2/wishlist-modal/wishlist-modal-item.tsx +0 -65
- package/src/pages-v2/product-details/product-intro/product-intro-images.tsx +0 -90
- package/src/pages-v2/product-details/product-intro/product-intro.tsx +0 -256
- /package/src/{pages-v2/account → components-v2}/no-records.tsx +0 -0
- /package/src/components-v2/product-cards/{product-card-1 → product-card}/components/hover-actions.tsx +0 -0
- /package/src/components-v2/product-cards/{product-card-16 → product-card}/index.ts +0 -0
- /package/src/components-v2/product-cards/{product-card-16 → product-card-plp}/components/quantity-buttons.tsx +0 -0
- /package/src/components-v2/product-cards/{product-card-wishlist → product-card-plp}/index.ts +0 -0
- /package/src/components-v2/product-cards/{product-card-16 → product-card-plp}/styles/index.ts +0 -0
- /package/src/components-v2/product-cards/{product-card-9 → product-card-plp-list}/components/add-to-cart.tsx +0 -0
- /package/src/components-v2/product-cards/{product-card-9 → product-card-plp-list}/components/favorite-button.tsx +0 -0
- /package/src/components-v2/product-cards/{product-card-9 → product-card-plp-list}/components/tags.tsx +0 -0
- /package/src/components-v2/product-cards/{product-card-8 → product-card-search}/index.ts +0 -0
- /package/src/components-v2/product-cards/{product-card-8 → product-card-search}/styles/index.ts +0 -0
- /package/src/components-v2/sticky/{Sticky.tsx → sticky.tsx} +0 -0
- /package/src/components-v2/{wishlist → wishlist-dialogs}/styles.ts +0 -0
- /package/src/{components-v2/shop-card → pages-v2/product-details/bopis/store-card}/index.ts +0 -0
- /package/src/{components-v2/shop-card → pages-v2/product-details/bopis/store-card}/styles.ts +0 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ProductQuantityButtons
|
|
3
|
+
*/
|
|
4
|
+
import React, { createContext, useContext, ReactNode, useMemo } from "react";
|
|
5
|
+
import { FlexBox } from "@evenicanpm/storefront-core/src/components-v2/flex-box";
|
|
6
|
+
import Button from "@mui/material/Button";
|
|
7
|
+
import { CartLine } from "@msdyn365-commerce/retail-proxy";
|
|
8
|
+
import { useTranslations } from "next-intl";
|
|
9
|
+
import { MdAdd as Add } from "react-icons/md";
|
|
10
|
+
import { MdRemove as Remove } from "react-icons/md";
|
|
11
|
+
import { H3 } from "@evenicanpm/storefront-core/src/components-v2/Typography";
|
|
12
|
+
import CircularProgress from "@mui/material/CircularProgress";
|
|
13
|
+
import useCart from "@evenicanpm/storefront-core/src/hooks/use-cart";
|
|
14
|
+
// TODO: Encapsulate the addToCart api calls inside this component
|
|
15
|
+
// so no need to pass in props.
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @category Context
|
|
19
|
+
*/
|
|
20
|
+
export interface QuantityContextType {
|
|
21
|
+
/** Loading state, usually triggered by mutating quantity */
|
|
22
|
+
loading: boolean;
|
|
23
|
+
/** Current quantity of the passed in cartline */
|
|
24
|
+
quantity: number;
|
|
25
|
+
/** Is the product out of stock? */
|
|
26
|
+
isOOS: boolean;
|
|
27
|
+
/** The cartline to display/mutate the quantity of */
|
|
28
|
+
productCartLine: CartLine;
|
|
29
|
+
/** Handler for when the quantity is changed via sub-component buttons */
|
|
30
|
+
handleCartAmountChange: (amount: number, currentCartLine: CartLine) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export const QuantityContext = createContext<QuantityContextType | undefined>(
|
|
37
|
+
undefined,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @category Props
|
|
42
|
+
*/
|
|
43
|
+
export interface QuantityButtonProps {
|
|
44
|
+
/** The cartline that this component will display the quantity of */
|
|
45
|
+
productId: number;
|
|
46
|
+
/** Is the item out of stock? */
|
|
47
|
+
isOOS?: boolean;
|
|
48
|
+
/** React children */
|
|
49
|
+
children?: ReactNode;
|
|
50
|
+
/** An optional custom handler for add to cart, if project needs to plug in logic */
|
|
51
|
+
customAddToCart?: () => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Quantity button component, takes quantity of a product, if it's zero
|
|
56
|
+
* will display an add to cart button, if it's not zero it will display the current
|
|
57
|
+
* quantity with small add and remove buttons on either side.
|
|
58
|
+
* @example
|
|
59
|
+
* <QuantityButtons {...props}>
|
|
60
|
+
* <QuantityButtons.Remove />
|
|
61
|
+
* <QuantityButtons.Quantity />
|
|
62
|
+
* <QuantityButtons.Add />
|
|
63
|
+
* </QuantityButtons>
|
|
64
|
+
*
|
|
65
|
+
* @category Compound Component
|
|
66
|
+
*/
|
|
67
|
+
export function QuantityButtons({
|
|
68
|
+
productId,
|
|
69
|
+
isOOS = false,
|
|
70
|
+
customAddToCart,
|
|
71
|
+
children,
|
|
72
|
+
}: QuantityButtonProps) {
|
|
73
|
+
const t = useTranslations("productDetail");
|
|
74
|
+
|
|
75
|
+
const { handleAddToCart, handleCartAmountChange, loading, currentCartLine } =
|
|
76
|
+
useCart(productId);
|
|
77
|
+
|
|
78
|
+
if (!currentCartLine || currentCartLine?.Quantity === 0) {
|
|
79
|
+
return (
|
|
80
|
+
<Button
|
|
81
|
+
color="primary"
|
|
82
|
+
variant="contained"
|
|
83
|
+
onClick={() => {
|
|
84
|
+
customAddToCart ? customAddToCart() : handleAddToCart();
|
|
85
|
+
}}
|
|
86
|
+
disabled={isOOS}
|
|
87
|
+
>
|
|
88
|
+
{t("btnAddToCart")}
|
|
89
|
+
</Button>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const value: QuantityContextType = {
|
|
94
|
+
loading,
|
|
95
|
+
quantity: currentCartLine?.Quantity,
|
|
96
|
+
isOOS,
|
|
97
|
+
productCartLine: currentCartLine,
|
|
98
|
+
handleCartAmountChange,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<QuantityContext.Provider value={value}>
|
|
103
|
+
<FlexBox alignItems="center">{children}</FlexBox>
|
|
104
|
+
</QuantityContext.Provider>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The remove/decrementor button that appears when the quantity is not 0
|
|
110
|
+
* @category Sub-Component
|
|
111
|
+
*/
|
|
112
|
+
QuantityButtons.Remove = () => {
|
|
113
|
+
const { handleCartAmountChange, loading, productCartLine } =
|
|
114
|
+
useContext(QuantityContext);
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<Button
|
|
118
|
+
size="small"
|
|
119
|
+
sx={{ p: 1 }}
|
|
120
|
+
color="primary"
|
|
121
|
+
variant="outlined"
|
|
122
|
+
disabled={loading}
|
|
123
|
+
onClick={() =>
|
|
124
|
+
handleCartAmountChange(
|
|
125
|
+
(productCartLine?.Quantity || 0) - 1,
|
|
126
|
+
productCartLine,
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
>
|
|
130
|
+
<Remove fontSize="small" />
|
|
131
|
+
</Button>
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The add/incrementor button that appears when the quantity is not 0
|
|
137
|
+
* @category Sub-Component
|
|
138
|
+
*/
|
|
139
|
+
QuantityButtons.Add = () => {
|
|
140
|
+
const { handleCartAmountChange, loading, productCartLine } =
|
|
141
|
+
useContext(QuantityContext);
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<Button
|
|
145
|
+
size="small"
|
|
146
|
+
sx={{ p: 1 }}
|
|
147
|
+
color="primary"
|
|
148
|
+
variant="outlined"
|
|
149
|
+
disabled={loading}
|
|
150
|
+
onClick={() =>
|
|
151
|
+
handleCartAmountChange(
|
|
152
|
+
(productCartLine?.Quantity || 0) + 1,
|
|
153
|
+
productCartLine,
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
>
|
|
157
|
+
<Add fontSize="small" />
|
|
158
|
+
</Button>
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The display component that shows the current quantity.
|
|
164
|
+
* @category Sub-Component
|
|
165
|
+
*/
|
|
166
|
+
QuantityButtons.Quantity = () => {
|
|
167
|
+
const { loading, productCartLine } = useContext(QuantityContext);
|
|
168
|
+
return (
|
|
169
|
+
<H3
|
|
170
|
+
fontWeight="600"
|
|
171
|
+
mx={2.5}
|
|
172
|
+
sx={{ width: "20px", display: "flex", justifyContent: "center" }}
|
|
173
|
+
>
|
|
174
|
+
{loading ? (
|
|
175
|
+
<CircularProgress size={"10px"} />
|
|
176
|
+
) : (
|
|
177
|
+
productCartLine?.Quantity.toString().padStart(2, "0")
|
|
178
|
+
)}
|
|
179
|
+
</H3>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @component
|
|
3
|
+
* @category Implementation component
|
|
4
|
+
*/
|
|
5
|
+
import React from "react";
|
|
6
|
+
import { QuantityButtons } from "./compound/quantity-buttons-root";
|
|
7
|
+
import { QuantityButtonProps } from "./compound/quantity-buttons-root";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Pre-composed version of quantity buttons.
|
|
11
|
+
*/
|
|
12
|
+
const ProductQuantityButtons = (props: QuantityButtonProps) => {
|
|
13
|
+
return (
|
|
14
|
+
<QuantityButtons {...props}>
|
|
15
|
+
<QuantityButtons.Remove />
|
|
16
|
+
<QuantityButtons.Quantity />
|
|
17
|
+
<QuantityButtons.Add />
|
|
18
|
+
</QuantityButtons>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default ProductQuantityButtons;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import Box from "@mui/material/Box";
|
|
4
|
+
|
|
5
|
+
// GLOBAL CUSTOM COMPONENTS
|
|
6
|
+
import QuantityButtons from "@evenicanpm/storefront-core/src/components-v2/product-quantity-buttons";
|
|
7
|
+
// API MANAGER
|
|
8
|
+
import { ProductDetails } from "@/api-manager/schemas/product.schema";
|
|
9
|
+
import getProductAvailability from "@/api-manager/services/product/queries/get-product-availability";
|
|
10
|
+
|
|
11
|
+
// LOCAL HOOKS
|
|
12
|
+
import useVariants from "@evenicanpm/storefront-core/src/hooks/use-variants";
|
|
13
|
+
import useCart, {
|
|
14
|
+
AddToCartBopisInput,
|
|
15
|
+
} from "@evenicanpm/storefront-core/src/hooks/use-cart";
|
|
16
|
+
|
|
17
|
+
// LOCAL COMPONENTS
|
|
18
|
+
import ProductDimensions from "@evenicanpm/storefront-core/src/components-v2/product-dimensions";
|
|
19
|
+
|
|
20
|
+
interface Props {
|
|
21
|
+
product: ProductDetails;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default function QuantityVariantsSelect({ product }: Props) {
|
|
25
|
+
const [showDimensionError, setShowDimensionError] = useState(false);
|
|
26
|
+
|
|
27
|
+
const { DimensionValues, RecordId } = product;
|
|
28
|
+
|
|
29
|
+
const {
|
|
30
|
+
selectedVariant,
|
|
31
|
+
selectDimensions,
|
|
32
|
+
handleChangeVariant,
|
|
33
|
+
allDimensionsSelected,
|
|
34
|
+
} = useVariants(product);
|
|
35
|
+
|
|
36
|
+
const { handleAddToCart } = useCart(RecordId, selectedVariant.RecordId);
|
|
37
|
+
|
|
38
|
+
const searchCriteria = {
|
|
39
|
+
searchCriteria: {
|
|
40
|
+
defaultWarehouseOnly: true,
|
|
41
|
+
productIds: [selectedVariant?.RecordId || RecordId],
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const { data: shippingInventoryData } =
|
|
46
|
+
getProductAvailability.useData(searchCriteria);
|
|
47
|
+
|
|
48
|
+
const addToCartDisabled = () => {
|
|
49
|
+
if (!allDimensionsSelected) {
|
|
50
|
+
return false; // Don't disable add to cart if dimensions are not selected, so clicking the button will provide an error message showing the user what to do.
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const OOSCode = "OOS"; // Always means out of stock
|
|
54
|
+
const aggregate =
|
|
55
|
+
shippingInventoryData?.AggregatedProductInventoryAvailabilities &&
|
|
56
|
+
shippingInventoryData?.AggregatedProductInventoryAvailabilities[0];
|
|
57
|
+
|
|
58
|
+
if (aggregate) {
|
|
59
|
+
const { TotalAvailableInventoryLevelCode } = aggregate;
|
|
60
|
+
return TotalAvailableInventoryLevelCode === OOSCode;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const onAddToCart = (bopisInput?: AddToCartBopisInput) => {
|
|
67
|
+
if (!allDimensionsSelected) {
|
|
68
|
+
setShowDimensionError(true);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
setShowDimensionError(false);
|
|
72
|
+
handleAddToCart(bopisInput);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Box width="100%">
|
|
77
|
+
<ProductDimensions
|
|
78
|
+
dimensionGroups={DimensionValues}
|
|
79
|
+
selectDimensions={selectDimensions}
|
|
80
|
+
handleChangeVariant={handleChangeVariant}
|
|
81
|
+
showDimensionError={showDimensionError}
|
|
82
|
+
/>
|
|
83
|
+
<QuantityButtons
|
|
84
|
+
customAddToCart={onAddToCart}
|
|
85
|
+
isOOS={addToCartDisabled()}
|
|
86
|
+
productId={selectedVariant?.RecordId}
|
|
87
|
+
/>
|
|
88
|
+
</Box>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ProductsView
|
|
3
|
+
*/
|
|
4
|
+
import { createContext } from "react";
|
|
5
|
+
// DATA MODEL
|
|
6
|
+
import { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
7
|
+
import { ProductPrice } from "@/api-manager/schemas/product.schema";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Shared context value for the products list passed into root component.
|
|
11
|
+
* @category Context
|
|
12
|
+
*/
|
|
13
|
+
export interface ProductsViewContext {
|
|
14
|
+
/** List of products to display */
|
|
15
|
+
products: Product[];
|
|
16
|
+
/** Array of product pricing */
|
|
17
|
+
productPrices?: ProductPrice[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export const ProductsViewContext = createContext<null | ProductsViewContext>(
|
|
24
|
+
null,
|
|
25
|
+
);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ProductsView
|
|
3
|
+
*/
|
|
4
|
+
import React, { useContext, cloneElement } from "react";
|
|
5
|
+
import Grid from "@mui/material/Grid2";
|
|
6
|
+
// GLOBAL CUSTOM COMPONENTS
|
|
7
|
+
import { FlexBetween } from "@evenicanpm/storefront-core/src/components-v2/flex-box/index";
|
|
8
|
+
import ProductCardPlp from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card-plp/product-card";
|
|
9
|
+
// DATA MODEL
|
|
10
|
+
import { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
11
|
+
import { ProductPrice } from "@/api-manager/schemas/product.schema";
|
|
12
|
+
import { ProductsViewContext } from "./context";
|
|
13
|
+
import { ProductsViewProps } from "./types";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Root component of products grid view.
|
|
17
|
+
* @category Compound Component
|
|
18
|
+
* @example
|
|
19
|
+
* <ProductsGridView products={products} productPrices={prices}>
|
|
20
|
+
* <ProductsGridView.Container>
|
|
21
|
+
* <ProductsGridView.Grid>
|
|
22
|
+
* <ProductsGridView.Card />
|
|
23
|
+
* </ProductsGridView.Grid>
|
|
24
|
+
* </ProductsGridView.Container>
|
|
25
|
+
* </ProductsGridView>
|
|
26
|
+
*/
|
|
27
|
+
export default function ProductsGridView(props: ProductsViewProps) {
|
|
28
|
+
const { products, productPrices, pagination, children } = props;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<ProductsViewContext.Provider value={{ products, productPrices }}>
|
|
32
|
+
<Grid container spacing={3}>
|
|
33
|
+
{children}
|
|
34
|
+
</Grid>
|
|
35
|
+
<FlexBetween flexWrap="wrap" mt={6}>
|
|
36
|
+
{pagination}
|
|
37
|
+
</FlexBetween>
|
|
38
|
+
</ProductsViewContext.Provider>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* Grid that handles rendering the list of component and passing
|
|
45
|
+
* product and pricing props to individual items.
|
|
46
|
+
* @category Sub-Component
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
ProductsGridView.Grid = ({ children }: { children: React.ReactElement }) => {
|
|
50
|
+
const { products, productPrices } = useContext(ProductsViewContext);
|
|
51
|
+
return (
|
|
52
|
+
<>
|
|
53
|
+
{products.map((item: Product, i) => {
|
|
54
|
+
const matchingPrice = productPrices?.find(
|
|
55
|
+
(price) => price.ProductId === item.RecordId,
|
|
56
|
+
);
|
|
57
|
+
// Legacy API, consider alternatives.
|
|
58
|
+
// Using this to pass props to child.
|
|
59
|
+
return cloneElement(children, {
|
|
60
|
+
key: i,
|
|
61
|
+
product: item,
|
|
62
|
+
price: matchingPrice,
|
|
63
|
+
});
|
|
64
|
+
})}
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @category Props
|
|
71
|
+
*/
|
|
72
|
+
export interface ProductCardProps {
|
|
73
|
+
product?: Product;
|
|
74
|
+
price?: ProductPrice;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Individual product card component displayed in the grid.
|
|
79
|
+
* @param props.item The product data to render.
|
|
80
|
+
* @param props.price The product price data.
|
|
81
|
+
* @category Sub-Component
|
|
82
|
+
*/
|
|
83
|
+
ProductsGridView.Card = ({ product, price }: ProductCardProps) => {
|
|
84
|
+
return (
|
|
85
|
+
<Grid size={{ lg: 4, sm: 6, xs: 12 }} key={product.ItemId}>
|
|
86
|
+
<ProductCardPlp
|
|
87
|
+
key={product.RecordId}
|
|
88
|
+
product={{
|
|
89
|
+
title: product.Name ?? "",
|
|
90
|
+
slug: product.ItemId ?? "",
|
|
91
|
+
price: price?.CustomerContextualPrice ?? 0,
|
|
92
|
+
imgUrl: product.PrimaryImageUrl ?? "",
|
|
93
|
+
rating: product.TotalRatings ?? 0,
|
|
94
|
+
discount: 0, // Need to get discount info for product.
|
|
95
|
+
id: product.RecordId,
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
<ProductCardPlp.Image />
|
|
99
|
+
<ProductCardPlp.Body>
|
|
100
|
+
<ProductCardPlp.Info>
|
|
101
|
+
<ProductCardPlp.Title />
|
|
102
|
+
<ProductCardPlp.Rating />
|
|
103
|
+
<ProductCardPlp.Price />
|
|
104
|
+
</ProductCardPlp.Info>
|
|
105
|
+
</ProductCardPlp.Body>
|
|
106
|
+
</ProductCardPlp>
|
|
107
|
+
</Grid>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ProductsView
|
|
3
|
+
*/
|
|
4
|
+
import { useContext, cloneElement } from "react";
|
|
5
|
+
// GLOBAL CUSTOM COMPONENTS
|
|
6
|
+
import FlexBetween from "@evenicanpm/storefront-core/src/components-v2/flex-box/flex-between";
|
|
7
|
+
import { ProductCardPlpList } from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card-plp-list/index";
|
|
8
|
+
import { ProductPrice } from "@/api-manager/schemas/product.schema";
|
|
9
|
+
// DATA MODEL
|
|
10
|
+
import { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
11
|
+
import { ProductsViewContext } from "./context";
|
|
12
|
+
import { ProductsViewProps } from "./types";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Root component of the ProductsListView.
|
|
16
|
+
*/
|
|
17
|
+
export default function ProductsListView(props: ProductsViewProps) {
|
|
18
|
+
const { pagination, products, productPrices, children } = props;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ProductsViewContext.Provider value={{ products, productPrices }}>
|
|
22
|
+
{children}
|
|
23
|
+
<FlexBetween flexWrap="wrap" mt={4}>
|
|
24
|
+
{pagination}
|
|
25
|
+
</FlexBetween>
|
|
26
|
+
</ProductsViewContext.Provider>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* Grid that handles rendering the list of component and passing
|
|
33
|
+
* product and pricing props to individual items.
|
|
34
|
+
* @category Sub-Component
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
ProductsListView.List = ({ children }: { children: React.ReactElement }) => {
|
|
38
|
+
const { products, productPrices } = useContext(ProductsViewContext);
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
{products.map((item: Product, i) => {
|
|
42
|
+
const matchingPrice = productPrices?.find(
|
|
43
|
+
(price) => price.ProductId === item.RecordId,
|
|
44
|
+
);
|
|
45
|
+
// Legacy API, consider alternatives.
|
|
46
|
+
// Using this to pass props to child.
|
|
47
|
+
return cloneElement(children, {
|
|
48
|
+
key: i,
|
|
49
|
+
product: item,
|
|
50
|
+
price: matchingPrice,
|
|
51
|
+
});
|
|
52
|
+
})}
|
|
53
|
+
</>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @category Props
|
|
59
|
+
*/
|
|
60
|
+
export interface ProductCardProps {
|
|
61
|
+
product?: Product;
|
|
62
|
+
price?: ProductPrice;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Individual product card component displayed in the grid.
|
|
67
|
+
* @param props.item The product data to render.
|
|
68
|
+
* @param props.price The product price data.
|
|
69
|
+
* @category Sub-Component
|
|
70
|
+
*/
|
|
71
|
+
ProductsListView.Card = ({ product, price }: ProductCardProps) => {
|
|
72
|
+
return (
|
|
73
|
+
<ProductCardPlpList
|
|
74
|
+
key={product.RecordId}
|
|
75
|
+
product={{
|
|
76
|
+
id: product.RecordId,
|
|
77
|
+
title: product.Name ?? "",
|
|
78
|
+
slug: product.ItemId ?? "",
|
|
79
|
+
price: price?.CustomerContextualPrice ?? 0,
|
|
80
|
+
imgUrl: product.PrimaryImageUrl ?? "",
|
|
81
|
+
rating: product.TotalRatings ?? 0,
|
|
82
|
+
discount: 0, // Need to get discount info for product.,
|
|
83
|
+
//tags: ["Bike", "Motor", "Ducati"], // Example tags
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
<ProductCardPlpList.Body>
|
|
87
|
+
<ProductCardPlpList.Image />
|
|
88
|
+
<ProductCardPlpList.Content>
|
|
89
|
+
<ProductCardPlpList.Info>
|
|
90
|
+
<ProductCardPlpList.Title />
|
|
91
|
+
<ProductCardPlpList.Price />
|
|
92
|
+
<ProductCardPlpList.Rating />
|
|
93
|
+
</ProductCardPlpList.Info>
|
|
94
|
+
</ProductCardPlpList.Content>
|
|
95
|
+
</ProductCardPlpList.Body>
|
|
96
|
+
</ProductCardPlpList>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ProductsViewContext } from "./context";
|
|
2
|
+
import { PropsWithChildren, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This prop type is used for both the ProductsViewGrid and the ProductsViewList.
|
|
6
|
+
* @category Props
|
|
7
|
+
*/
|
|
8
|
+
export interface ProductsViewProps
|
|
9
|
+
extends ProductsViewContext,
|
|
10
|
+
PropsWithChildren {
|
|
11
|
+
pagination?: ReactNode;
|
|
12
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import ProductsGridView from "./compound/products-grid-view";
|
|
3
|
+
import ProductsListView from "./compound/products-list-view";
|
|
4
|
+
// DATA MODEL
|
|
5
|
+
import { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
6
|
+
import { ProductPrice } from "@/api-manager/schemas/product.schema";
|
|
7
|
+
|
|
8
|
+
export interface Props {
|
|
9
|
+
/** List of products to display */
|
|
10
|
+
products: Product[];
|
|
11
|
+
/** Pagination component */
|
|
12
|
+
pagination?: ReactNode;
|
|
13
|
+
/** Array of product pricing */
|
|
14
|
+
productPrices?: ProductPrice[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* Pre-composed implementation of ProductGrid
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
export function ProductsGrid(props: Props) {
|
|
23
|
+
return (
|
|
24
|
+
<ProductsGridView {...props}>
|
|
25
|
+
<ProductsGridView.Grid>
|
|
26
|
+
<ProductsGridView.Card />
|
|
27
|
+
</ProductsGridView.Grid>
|
|
28
|
+
</ProductsGridView>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* Pre-composed implementation of ProductList
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
export function ProductsList(props: Props) {
|
|
38
|
+
return (
|
|
39
|
+
<ProductsListView {...props}>
|
|
40
|
+
<ProductsListView.List>
|
|
41
|
+
<ProductsListView.Card />
|
|
42
|
+
</ProductsListView.List>
|
|
43
|
+
</ProductsListView>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -2,7 +2,7 @@ import { Fragment, ReactNode } from "react";
|
|
|
2
2
|
import Grid from "@mui/material/Grid2";
|
|
3
3
|
// GLOBAL CUSTOM COMPONENTS
|
|
4
4
|
import { FlexBetween } from "@evenicanpm/storefront-core/src/components-v2/flex-box/index";
|
|
5
|
-
import
|
|
5
|
+
import ProductCardPlp from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card-plp/product-card";
|
|
6
6
|
// DATA MODEL
|
|
7
7
|
import { ProductSearchResult as Product } from "@msdyn365-commerce/retail-proxy";
|
|
8
8
|
import { ProductPrice } from "@/api-manager/schemas/product.schema";
|
|
@@ -29,17 +29,30 @@ export default function ProductsGridView({
|
|
|
29
29
|
);
|
|
30
30
|
return (
|
|
31
31
|
<Grid size={{ lg: 4, sm: 6, xs: 12 }} key={item.ItemId}>
|
|
32
|
-
<
|
|
33
|
-
id={item.RecordId}
|
|
32
|
+
<ProductCardPlp
|
|
34
33
|
key={item.RecordId}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
product={{
|
|
35
|
+
title: item.Name ?? "",
|
|
36
|
+
slug: item.ItemId ?? "",
|
|
37
|
+
price: matchingPrice?.CustomerContextualPrice ?? 0,
|
|
38
|
+
imgUrl: item.PrimaryImageUrl ?? "",
|
|
39
|
+
rating: item.TotalRatings ?? 0,
|
|
40
|
+
discount: 0, // Need to get discount info for product.
|
|
41
|
+
id: item.RecordId,
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
<ProductCardPlp.Image />
|
|
45
|
+
<ProductCardPlp.Body>
|
|
46
|
+
<ProductCardPlp.Info>
|
|
47
|
+
<ProductCardPlp.Title />
|
|
48
|
+
<ProductCardPlp.Rating />
|
|
49
|
+
<ProductCardPlp.Price />
|
|
50
|
+
</ProductCardPlp.Info>
|
|
51
|
+
{/* <ProductCardPlp.Actions>
|
|
52
|
+
<ProductCardPlp.QuantityButtons />
|
|
53
|
+
</ProductCardPlp.Actions> */}
|
|
54
|
+
</ProductCardPlp.Body>
|
|
55
|
+
</ProductCardPlp>
|
|
43
56
|
</Grid>
|
|
44
57
|
);
|
|
45
58
|
})}
|