@evenicanpm/storefront-core 1.0.5 → 1.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.
Files changed (307) hide show
  1. package/.storybook/main.ts +37 -0
  2. package/.storybook/preview.ts +14 -0
  3. package/README.md +17 -2
  4. package/__mocks__/next-font.js +4 -0
  5. package/package.json +19 -13
  6. package/src/api-manager/datasources/e4/graphqlRequestSdk.ts +265 -5
  7. package/src/api-manager/schemas/product.schema.ts +2 -2
  8. package/src/api-manager/services/cart/mutations/add-discount-code.ts +11 -0
  9. package/src/api-manager/services/cart/mutations/checkout.ts +1 -1
  10. package/src/api-manager/services/create-query.ts +11 -4
  11. package/src/api-manager/services/product/queries/get-product-availability.ts +1 -2
  12. package/src/api-manager/services/user/mutations/add-to-wishlist.ts +2 -2
  13. package/src/api-manager/services/user/mutations/copy-cart-to-wishlist.ts +2 -1
  14. package/src/api-manager/services/user/mutations/remove-from-wishlist.ts +4 -4
  15. package/src/api-manager/services/user/mutations/update-wishlist.ts +2 -1
  16. package/src/api-manager/services/user/queries/get-wishlist-details.ts +2 -2
  17. package/src/cms/blocks/components/product-carousel/index.tsx +6 -3
  18. package/src/cms/blocks/components/product-section-fullwidth/index.tsx +2 -2
  19. package/src/cms/blocks/components/shared/product-grid.tsx +5 -2
  20. package/src/cms/interfaces/navigation.ts +9 -9
  21. package/src/components/Blocks/Components/CategoryCarousel/index.tsx +3 -3
  22. package/src/components/Blocks/Components/HeroCarousel/index.tsx +2 -2
  23. package/src/components/Blocks/Components/ProductCarousel/index.tsx +5 -5
  24. package/src/components/Blocks/Components/ProductSectionFullWidth/index.tsx +6 -6
  25. package/src/components/Blocks/Components/Services/service-card.tsx +4 -1
  26. package/src/components/Blocks/Components/shared/featured-product-card.tsx +2 -2
  27. package/src/components/Blocks/Components/shared/product-category-item.tsx +3 -3
  28. package/src/components/Blocks/Components/shared/product-grid.tsx +2 -2
  29. package/src/components/Blocks/Components/shared/top-categories-card.tsx +1 -1
  30. package/src/components/Blocks/Components/shared/top-rating-product-card.tsx +6 -3
  31. package/src/components/Footer/sections/FooterAppStore.tsx +1 -1
  32. package/src/components/Footer/sections/FooterContact.tsx +1 -1
  33. package/src/components/Footer/sections/FooterLogo.tsx +2 -2
  34. package/src/components/Footer/sections/FooterSocialLinks.tsx +1 -1
  35. package/src/components/_components/MiniCartClient.tsx +2 -2
  36. package/src/components/_components/accordion/accordion-header.tsx +1 -1
  37. package/src/components/_components/carousel-cards/carousel-card-1/carousel-card-1.tsx +2 -2
  38. package/src/components/_components/carousel-cards/carousel-card-2/carousel-card-2.tsx +9 -4
  39. package/src/components/_components/carousel-cards/carousel-card-3/carousel-card-3.tsx +6 -3
  40. package/src/components/_components/carousel-cards/carousel-card-4/carousel-card-4.tsx +6 -1
  41. package/src/components/_components/categories/category-list/category-list.tsx +3 -3
  42. package/src/components/_components/categories/mega-menu/banner.tsx +7 -3
  43. package/src/components/_components/categories/mega-menu/column-list.tsx +3 -3
  44. package/src/components/_components/categories/mega-menu/mega-menu-1.tsx +2 -2
  45. package/src/components/_components/category-cards/category-card-1/category-card-1.tsx +2 -2
  46. package/src/components/_components/countdown/count-box.tsx +4 -1
  47. package/src/components/_components/countdown/count-down.tsx +1 -1
  48. package/src/components/_components/data-table/table-header.tsx +1 -1
  49. package/src/components/_components/footer/components/app-store.tsx +1 -1
  50. package/src/components/_components/footer/components/logo.tsx +2 -2
  51. package/src/components/_components/footer/components/social-links.tsx +1 -1
  52. package/src/components/_components/footer/footer-1.tsx +1 -1
  53. package/src/components/_components/footer/footer-2.tsx +2 -2
  54. package/src/components/_components/footer/footer-3.tsx +2 -2
  55. package/src/components/_components/footer/footer-4.tsx +3 -3
  56. package/src/components/_components/header/components/categories-menu.tsx +3 -3
  57. package/src/components/_components/header/components/mobile-header.tsx +9 -6
  58. package/src/components/_components/header/components/user.tsx +5 -5
  59. package/src/components/_components/header/header.tsx +2 -2
  60. package/src/components/_components/header/sticky-header.tsx +3 -3
  61. package/src/components/_components/mini-cart/components/cart-item.tsx +5 -2
  62. package/src/components/_components/mini-cart/components/empty-view.tsx +2 -2
  63. package/src/components/_components/mini-cart/components/top-header.tsx +5 -2
  64. package/src/components/_components/mini-cart/mini-cart.tsx +3 -3
  65. package/src/components/_components/mobile-navigation/mobile-navigation-bar.tsx +5 -5
  66. package/src/components/_components/nav-link/nav-link-2.tsx +1 -1
  67. package/src/components/_components/nav-link/nav-link-3.tsx +1 -1
  68. package/src/components/_components/navbar/categories.tsx +3 -3
  69. package/src/components/_components/navbar/category-based-menu/category-based-menu.tsx +1 -1
  70. package/src/components/_components/navbar/category-based-menu/components/child-categories.tsx +2 -2
  71. package/src/components/_components/navbar/mega-menu/category-list.tsx +1 -1
  72. package/src/components/_components/navbar/mega-menu/mega-menu.tsx +1 -1
  73. package/src/components/_components/navbar/mobile-menu/mobile-menu.tsx +2 -2
  74. package/src/components/_components/navbar/mobile-menu/render-levels.tsx +3 -3
  75. package/src/components/_components/navbar/nav-list/nav-item-child.tsx +3 -3
  76. package/src/components/_components/navbar/nav-list/nav-list.tsx +4 -4
  77. package/src/components/_components/newsletter/newsletter.tsx +5 -1
  78. package/src/components/_components/newsletter/social-icons.tsx +1 -1
  79. package/src/components/_components/page-sidenav/grocery-side-nav/components/link-item.tsx +2 -2
  80. package/src/components/_components/page-sidenav/grocery-side-nav/components/list-item.tsx +2 -2
  81. package/src/components/_components/page-sidenav/grocery-side-nav/components/nav-accordion.tsx +2 -2
  82. package/src/components/_components/page-sidenav/grocery-side-nav/grocery-side-nav.tsx +3 -3
  83. package/src/components/_components/page-sidenav/health-beauty-side-nav/components/list-item.tsx +2 -2
  84. package/src/components/_components/page-sidenav/health-beauty-side-nav/components/nav-accordion.tsx +2 -2
  85. package/src/components/_components/page-sidenav/health-beauty-side-nav/components/render-child.tsx +2 -2
  86. package/src/components/_components/page-sidenav/health-beauty-side-nav/health-beauty-side-nav.tsx +5 -5
  87. package/src/components/_components/page-sidenav/side-navbar/components/list-item.tsx +1 -1
  88. package/src/components/_components/page-sidenav/side-navbar/components/nav-accordion.tsx +3 -3
  89. package/src/components/_components/page-sidenav/side-navbar/components/render-child.tsx +1 -1
  90. package/src/components/_components/page-sidenav/side-navbar/side-nav-bar.tsx +4 -4
  91. package/src/components/_components/page-sidenav/side-navbar-2/components/sidebar-accordion.tsx +1 -1
  92. package/src/components/_components/page-sidenav/side-navbar-2/side-navbar-2.tsx +2 -2
  93. package/src/components/_components/product-cards/product-card-1/components/quantity-buttons.tsx +2 -2
  94. package/src/components/_components/product-cards/product-card-1/product-card.tsx +2 -2
  95. package/src/components/_components/product-cards/product-card-10/product-card.tsx +9 -5
  96. package/src/components/_components/product-cards/product-card-11/product-card.tsx +6 -3
  97. package/src/components/_components/product-cards/product-card-12/product-card.tsx +4 -4
  98. package/src/components/_components/product-cards/product-card-13/product-card.tsx +6 -3
  99. package/src/components/_components/product-cards/product-card-14/product-card.tsx +7 -4
  100. package/src/components/_components/product-cards/product-card-15/product-card.tsx +6 -3
  101. package/src/components/_components/product-cards/product-card-16/components/quantity-buttons.tsx +2 -2
  102. package/src/components/_components/product-cards/product-card-16/product-card.tsx +5 -2
  103. package/src/components/_components/product-cards/product-card-2/components/product-price.tsx +2 -2
  104. package/src/components/_components/product-cards/product-card-2/product-card.tsx +4 -4
  105. package/src/components/_components/product-cards/product-card-3/components/hover-actions.tsx +1 -1
  106. package/src/components/_components/product-cards/product-card-3/product-card.tsx +2 -2
  107. package/src/components/_components/product-cards/product-card-4/components/hover-actions.tsx +1 -1
  108. package/src/components/_components/product-cards/product-card-4/product-card.tsx +2 -2
  109. package/src/components/_components/product-cards/product-card-5/components/hover-actions.tsx +1 -1
  110. package/src/components/_components/product-cards/product-card-5/product-card.tsx +2 -2
  111. package/src/components/_components/product-cards/product-card-6/components/hover-actions.tsx +1 -1
  112. package/src/components/_components/product-cards/product-card-6/product-card.tsx +3 -3
  113. package/src/components/_components/product-cards/product-card-7/components/quantity-buttons.tsx +2 -2
  114. package/src/components/_components/product-cards/product-card-7/product-card.tsx +5 -2
  115. package/src/components/_components/product-cards/product-card-8/product-card.tsx +9 -5
  116. package/src/components/_components/product-cards/product-card-9/components/add-to-cart.tsx +5 -2
  117. package/src/components/_components/product-cards/product-card-9/product-card.tsx +1 -1
  118. package/src/components/_components/product-cards/product-price.tsx +2 -2
  119. package/src/components/_components/product-cards/product-rating.tsx +2 -2
  120. package/src/components/_components/product-cards/product-title.tsx +1 -1
  121. package/src/components/_components/product-cards/use-product.ts +1 -1
  122. package/src/components/_components/product-dimensions/product-dimensions.tsx +1 -1
  123. package/src/components/_components/product-quantity-buttons/product-quantity-buttons.tsx +2 -2
  124. package/src/components/_components/products-view/products-grid-view.tsx +2 -2
  125. package/src/components/_components/products-view/products-list-view.tsx +2 -2
  126. package/src/components/_components/search-box/components/category-dropdown.tsx +1 -1
  127. package/src/components/_components/search-box/components/search-result.tsx +1 -1
  128. package/src/components/_components/search-box/hooks/use-search.ts +1 -1
  129. package/src/components/_components/search-box/search-input-category.tsx +3 -3
  130. package/src/components/_components/service-cards/service-card-1/service-card-1.tsx +5 -2
  131. package/src/components/_components/service-cards/service-card-2/service-card-2.tsx +5 -2
  132. package/src/components/_components/service-cards/service-card-3/service-card-3.tsx +4 -1
  133. package/src/components/_components/settings/setting.tsx +3 -3
  134. package/src/components/_components/side-nav/side-nav.tsx +1 -1
  135. package/src/components/_components/stories/story-content/story-content.tsx +1 -1
  136. package/src/components/_components/stories/story-item/story-item.tsx +1 -1
  137. package/src/components/_components/topbar/top-bar.tsx +6 -3
  138. package/src/components/_components/wishlist-modal/wishlist-modal-item.tsx +1 -1
  139. package/src/components-v2/accordion/accordion-header.stories.tsx +28 -0
  140. package/src/components-v2/categories/category-list/category-list.tsx +2 -2
  141. package/src/components-v2/categories/category-list/styles.ts +3 -2
  142. package/src/components-v2/categories/mega-menu/column-list.tsx +1 -1
  143. package/src/components-v2/categories/mega-menu/mega-menu-1.tsx +6 -3
  144. package/src/components-v2/categories/mega-menu/mega-menu-2.tsx +2 -2
  145. package/src/components-v2/header/__tests__/user.test.tsx +12 -12
  146. package/src/components-v2/header/components/user.tsx +12 -11
  147. package/src/components-v2/mini-cart/mini-cart.tsx +9 -14
  148. package/src/components-v2/mobile-navigation/mobile-navigation-bar.tsx +1 -1
  149. package/src/components-v2/navbar/mobile-menu/mobile-menu.tsx +2 -2
  150. package/src/components-v2/product-cards/favorite-button.tsx +52 -0
  151. package/src/components-v2/product-cards/product-card/product-card.tsx +87 -47
  152. package/src/components-v2/product-cards/product-card-plp/product-card.tsx +140 -51
  153. package/src/components-v2/product-cards/product-card-plp/styles/index.ts +17 -0
  154. package/src/components-v2/product-cards/product-card-plp-list/product-card.tsx +76 -42
  155. package/src/components-v2/product-cards/product-card-search/product-card.tsx +50 -21
  156. package/src/components-v2/product-cards/product-card-search/styles/index.ts +0 -10
  157. package/src/components-v2/product-dialog/compound/product-dialog.tsx +39 -15
  158. package/src/components-v2/product-quantity-buttons/compound/quantity-buttons-root.tsx +22 -7
  159. package/src/components-v2/product-quantity-variants/index.tsx +1 -1
  160. package/src/components-v2/products-view/compound/context.ts +46 -1
  161. package/src/components-v2/products-view/compound/products-grid-view.tsx +23 -14
  162. package/src/components-v2/products-view/compound/products-list-view.tsx +12 -3
  163. package/src/components-v2/search-bar/compound/context.ts +24 -3
  164. package/src/components-v2/search-bar/compound/results-item-lg.tsx +14 -13
  165. package/src/components-v2/search-bar/compound/results-item-sm.tsx +5 -5
  166. package/src/components-v2/search-bar/compound/results-suspense.tsx +3 -3
  167. package/src/components-v2/search-bar/compound/results.tsx +4 -4
  168. package/src/components-v2/search-bar/compound/textfield-adornment-category.tsx +1 -1
  169. package/src/components-v2/search-bar/compound/textfield.tsx +3 -3
  170. package/src/components-v2/search-bar/hooks/use-click-outside.ts +1 -1
  171. package/src/components-v2/wishlist-dialogs/add-to-wishlist/add-to-wishlist-button.tsx +2 -6
  172. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-bottom-ui.tsx +6 -1
  173. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-dialog.tsx +22 -15
  174. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-list.tsx +8 -7
  175. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/context.ts +8 -8
  176. package/src/components-v2/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-item.tsx +29 -19
  177. package/src/components-v2/wishlist-dialogs/add-to-wishlist/hooks/use-add-to-wishlist.ts +27 -77
  178. package/src/components-v2/wishlist-dialogs/add-to-wishlist/index.tsx +1 -9
  179. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-bottom-ui.tsx +7 -2
  180. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-dialog.tsx +20 -12
  181. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/create-wishlist-form.tsx +25 -5
  182. package/src/hooks/use-cart.ts +11 -14
  183. package/src/hooks/use-favorite.ts +17 -0
  184. package/src/hooks/use-variants.ts +4 -3
  185. package/src/pages/account/addresses/address-item.tsx +1 -1
  186. package/src/pages/account/dashboard-header.tsx +3 -3
  187. package/src/pages/account/navigation.tsx +5 -2
  188. package/src/pages/account/no-records.tsx +1 -1
  189. package/src/pages/account/orders/order-progress.tsx +5 -2
  190. package/src/pages/account/orders/order-row.tsx +4 -1
  191. package/src/pages/account/orders/order-summary.tsx +6 -2
  192. package/src/pages/account/orders/ordered-products.tsx +9 -2
  193. package/src/pages/account/profile/user-info.tsx +5 -2
  194. package/src/pages/account/wishlist/create-new-list.tsx +1 -1
  195. package/src/pages/account/wishlist/wishlist-item.tsx +2 -2
  196. package/src/pages/checkout/checkout-alt-form/address-card.tsx +5 -2
  197. package/src/pages/checkout/checkout-alt-form/checkout-step.tsx +3 -3
  198. package/src/pages/checkout/checkout-alt-form/customer-information.tsx +1 -1
  199. package/src/pages/checkout/checkout-alt-form/delivery-address.tsx +5 -1
  200. package/src/pages/checkout/checkout-alt-form/delivery-options.tsx +6 -2
  201. package/src/pages/checkout/checkout-alt-form/edit-address-form.tsx +1 -1
  202. package/src/pages/checkout/checkout-alt-form/heading.tsx +2 -2
  203. package/src/pages/checkout/checkout-alt-form/new-address-form.tsx +9 -4
  204. package/src/pages/checkout/checkout-alt-form/payment-details.tsx +6 -3
  205. package/src/pages/checkout/checkout-alt-summary/cart-item.tsx +5 -2
  206. package/src/pages/checkout/checkout-alt-summary/checkout-alt-summary.tsx +4 -2
  207. package/src/pages/checkout/checkout-alt-summary/list-item.tsx +2 -2
  208. package/src/pages/confirmation/address.tsx +4 -1
  209. package/src/pages/confirmation/confirmation-summary.tsx +6 -3
  210. package/src/pages/confirmation/ordered-products.tsx +9 -2
  211. package/src/pages/product-details/available-shops.tsx +5 -2
  212. package/src/pages/product-details/bopis/find-in-store-modal.tsx +1 -1
  213. package/src/pages/product-details/bopis/pickup-option-select.tsx +1 -1
  214. package/src/pages/product-details/frequently-bought.tsx +9 -2
  215. package/src/pages/product-details/frequently-product-card.tsx +8 -5
  216. package/src/pages/product-details/product-comment.tsx +7 -2
  217. package/src/pages/product-details/product-description.tsx +1 -1
  218. package/src/pages/product-details/product-filter-card.tsx +11 -3
  219. package/src/pages/product-details/product-intro/product-intro-images.tsx +4 -1
  220. package/src/pages/product-details/product-intro/product-intro.tsx +8 -5
  221. package/src/pages/product-details/product-review.tsx +5 -2
  222. package/src/pages/product-details/related-products.tsx +2 -2
  223. package/src/pages/product-list/facet-group.tsx +1 -1
  224. package/src/pages/product-list/list-filter.tsx +5 -2
  225. package/src/pages/product-list/pagination.tsx +1 -1
  226. package/src/pages/product-list/quick-view-dialog-content.tsx +2 -2
  227. package/src/pages/product-list/selected-facets.tsx +1 -1
  228. package/src/pages/quickorder/order-upload.tsx +1 -1
  229. package/src/pages/quickorder/quick-order-form.tsx +6 -3
  230. package/src/pages/quickorder/quick-order-row.tsx +1 -1
  231. package/src/pages-v2/account/account-navigation.tsx +1 -1
  232. package/src/pages-v2/account/orders/order-summary.tsx +5 -2
  233. package/src/pages-v2/account/profile/user-info.tsx +6 -3
  234. package/src/pages-v2/account/wishlist/wishlist-item.tsx +1 -1
  235. package/src/pages-v2/cart/__tests__/checkout-form.test.tsx +1 -1
  236. package/src/pages-v2/cart/estimate-shipping.tsx +3 -0
  237. package/src/pages-v2/checkout/checkout-alt-form/checkout-step.tsx +4 -4
  238. package/src/pages-v2/checkout/checkout-alt-form/steps/address/address-card.tsx +1 -1
  239. package/src/pages-v2/checkout/checkout-alt-form/steps/address/delivery-address.tsx +12 -5
  240. package/src/pages-v2/checkout/checkout-alt-form/steps/address/new-address-form.tsx +27 -5
  241. package/src/pages-v2/checkout/checkout-alt-form/steps/address/styles.ts +2 -1
  242. package/src/pages-v2/checkout/checkout-alt-form/steps/customer-info/customer-information.tsx +27 -7
  243. package/src/pages-v2/checkout/checkout-alt-form/steps/shipping/delivery-options.tsx +8 -1
  244. package/src/pages-v2/confirmation/address.tsx +5 -1
  245. package/src/pages-v2/product-details/available-shops.tsx +4 -1
  246. package/src/pages-v2/product-details/bopis/find-in-store-button.tsx +1 -1
  247. package/src/pages-v2/product-details/bopis/find-in-store-modal.tsx +3 -5
  248. package/src/pages-v2/product-details/product-intro/compound/context.ts +69 -12
  249. package/src/pages-v2/product-details/product-intro/compound/product-info.tsx +73 -27
  250. package/src/pages-v2/product-details/product-intro/compound/product-intro-images.tsx +19 -6
  251. package/src/pages-v2/product-details/product-intro/utils.ts +2 -2
  252. package/src/pages-v2/product-details/product-tabs.tsx +19 -4
  253. package/src/pages-v2/product-details/related-products.tsx +3 -3
  254. package/src/pages-v2/quickorder/context.ts +2 -2
  255. package/src/pages-v2/quickorder/order-upload.tsx +6 -2
  256. package/src/pages-v2/quickorder/provider.tsx +24 -9
  257. package/src/pages-v2/quickorder/quick-order-actions.tsx +2 -2
  258. package/src/pages-v2/quickorder/quick-order-header.tsx +6 -3
  259. package/src/pages-v2/quickorder/quick-order-row.tsx +1 -1
  260. package/src/pages-v2/quickorder/quick-order-table.tsx +10 -4
  261. package/src/pages-v2/quickorder/quick-order-upload.tsx +2 -2
  262. package/src/stories/Button.stories.ts +54 -0
  263. package/src/stories/Button.tsx +35 -0
  264. package/src/stories/Configure.mdx +364 -0
  265. package/src/stories/Header.stories.ts +34 -0
  266. package/src/stories/Header.tsx +54 -0
  267. package/src/stories/Page.stories.ts +33 -0
  268. package/src/stories/Page.tsx +73 -0
  269. package/src/stories/assets/accessibility.png +0 -0
  270. package/src/stories/assets/accessibility.svg +1 -0
  271. package/src/stories/assets/addon-library.png +0 -0
  272. package/src/stories/assets/assets.png +0 -0
  273. package/src/stories/assets/avif-test-image.avif +0 -0
  274. package/src/stories/assets/context.png +0 -0
  275. package/src/stories/assets/discord.svg +1 -0
  276. package/src/stories/assets/docs.png +0 -0
  277. package/src/stories/assets/figma-plugin.png +0 -0
  278. package/src/stories/assets/github.svg +1 -0
  279. package/src/stories/assets/share.png +0 -0
  280. package/src/stories/assets/styling.png +0 -0
  281. package/src/stories/assets/testing.png +0 -0
  282. package/src/stories/assets/theming.png +0 -0
  283. package/src/stories/assets/tutorials.svg +1 -0
  284. package/src/stories/assets/youtube.svg +1 -0
  285. package/src/stories/button.css +30 -0
  286. package/src/stories/header.css +32 -0
  287. package/src/stories/page.css +68 -0
  288. package/src/theme/build-mui-theme.ts +104 -0
  289. package/src/theme/components.ts +163 -0
  290. package/src/theme/emotion-cache.tsx +101 -0
  291. package/src/theme/theme-colors.ts +205 -0
  292. package/src/theme/theme-options-sample.ts +69 -0
  293. package/src/theme/theme-options.ts +172 -0
  294. package/src/theme/theme-provider.tsx +44 -0
  295. package/src/theme/typography.ts +22 -0
  296. package/src/theme/utils.ts +17 -0
  297. package/tsconfig.json +3 -1
  298. package/src/api-manager/lib/cart-cookie-handler.ts +0 -14
  299. package/src/components-v2/product-cards/product-card/components/hover-actions.tsx +0 -37
  300. package/src/components-v2/product-cards/product-card-plp/components/quantity-buttons.tsx +0 -54
  301. package/src/components-v2/product-cards/product-card-plp-list/components/add-to-cart.tsx +0 -63
  302. package/src/components-v2/product-cards/product-card-plp-list/components/favorite-button.tsx +0 -27
  303. package/src/components-v2/product-cards/use-product.ts +0 -35
  304. package/src/components-v2/products-view/products-grid-view.tsx +0 -65
  305. package/src/components-v2/products-view/products-list-view.tsx +0 -66
  306. package/src/components-v2/wishlist-dialogs/create-wishlist/compound/context.ts +0 -2
  307. /package/src/components-v2/product-cards/{product-card/components/quantity-buttons.tsx → quantity-buttons.tsx} +0 -0
@@ -1,43 +1,54 @@
1
1
  "use client";
2
2
 
3
- import { createContext, ReactNode, useContext, useMemo, useState } from "react";
3
+ import React, {
4
+ createContext,
5
+ ReactNode,
6
+ useContext,
7
+ useMemo,
8
+ useState,
9
+ } from "react";
4
10
  import Link from "next/link";
5
11
  import Box from "@mui/material/Box";
6
12
  import Rating from "@mui/material/Rating";
7
13
  import IconButton from "@mui/material/IconButton";
8
14
  import { Delete, ShoppingCart } from "@mui/icons-material";
15
+ import RemoveRedEye from "@mui/icons-material/RemoveRedEye";
16
+ import { useTranslations } from "next-intl";
17
+ import { useIsFetching } from "@tanstack/react-query";
9
18
  // GLOBAL CUSTOM COMPONENTS
10
19
  import LazyImage from "@evenicanpm/storefront-core/src/components-v2/LazyImage";
11
20
  import { Span } from "@evenicanpm/storefront-core/src/components-v2/Typography";
12
21
  import { FlexBox } from "@evenicanpm/storefront-core/src/components-v2/flex-box";
22
+ import { useNotification } from "@evenicanpm/storefront-core/src/providers/notifications/use-notification";
23
+ import AddToWishlistDialog from "@evenicanpm/storefront-core/src/components-v2/wishlist-dialogs/add-to-wishlist";
24
+ import ProductViewDialog from "@evenicanpm/storefront-core/src/components-v2/product-dialog";
13
25
  // LOCAL CUSTOM COMPONENTS
14
26
  import ProductPrice from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-price";
15
27
  import ProductTitle from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-title";
16
- import QuantityBtns from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card/components/quantity-buttons";
28
+ import QuantityBtns from "@evenicanpm/storefront-core/src/components-v2/product-cards/quantity-buttons";
17
29
  import DiscountChip from "@evenicanpm/storefront-core/src/components-v2/product-cards/discount-chip";
18
- import HoverActions from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card/components/hover-actions";
30
+ import FavoriteButton from "@evenicanpm/storefront-core/src/components-v2/product-cards/favorite-button";
19
31
  // STYLED COMPONENTS
20
32
  import {
21
33
  ImageWrapper,
22
34
  ContentWrapper,
23
35
  StyledBazaarCard,
36
+ HoverIconWrapper,
24
37
  } from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card/styles/index";
25
-
38
+ // LIBRARY AND HOOKS
26
39
  import buildDetailUrl from "@/lib/build-detail-url";
27
- import { useTranslations } from "next-intl";
28
- import { useNotification } from "@evenicanpm/storefront-core/src/providers/notifications/use-notification";
40
+ import useFavorite from "@/hooks/use-favorite";
41
+ // API AND SCHEMAS
29
42
  import useRemoveFromWishlist from "@/api-manager/services/user/mutations/remove-from-wishlist";
30
43
  import useUpdateWishlist from "@/api-manager/services/user/mutations/update-wishlist";
31
44
  import useAddToCart from "@/api-manager/services/cart/mutations/add-to-cart";
45
+ import { WISHLIST_DETAILS_QUERY_KEY } from "@/api-manager/services/user/queries/get-wishlist-details";
32
46
  import {
33
47
  ExtendedWishlist,
34
48
  ExtendedProductListLine,
35
49
  WishlistLinesInput,
36
50
  } from "@/api-manager/schemas/user.schema";
37
51
  import { Cart } from "@/api-manager/schemas/cart.schema";
38
- import AddToWishlistDialog from "@evenicanpm/storefront-core/src/components-v2/wishlist-dialogs/add-to-wishlist";
39
- import ProductViewDialog from "@evenicanpm/storefront-core/src/components-v2/product-dialog";
40
- import React from "react";
41
52
 
42
53
  function findChild(
43
54
  children: ReactNode,
@@ -57,7 +68,6 @@ function findChild(
57
68
  return found;
58
69
  }
59
70
  type InternalCtx = {
60
- favorite: boolean;
61
71
  handleToggleFavorite: () => void;
62
72
  openProductModal: boolean;
63
73
  handleToggleProductModal: () => void;
@@ -108,11 +118,10 @@ const ProductCard = ({
108
118
  (item: ExtendedProductListLine) => item.ProductId === product.id,
109
119
  );
110
120
 
111
- const [favorite, setFavorite] = useState(!!foundWishlistProduct);
112
121
  const [openProductModal, setOpenProductModal] = useState(false);
113
122
  const [openAddToWishlistDialog, setOpenAddToWishlistDialog] = useState(false);
114
123
  const [quantity, setQuantity] = useState(foundWishlistProduct?.Quantity ?? 0);
115
- const [isLineUpdating, setIsLineUpdating] = useState(false);
124
+ const [isLineUpdatingLocal, setIsLineUpdatingLocal] = useState(false);
116
125
 
117
126
  // detect if WishlistControls are being rendered
118
127
  const containsWishlistControls = useMemo(
@@ -155,10 +164,6 @@ const ProductCard = ({
155
164
  setOpenProductModal((prev) => !prev);
156
165
  };
157
166
 
158
- const handleAddRemoveSuccess = () => {
159
- setFavorite(!favorite);
160
- };
161
-
162
167
  const handleAddItemToCart = async () => {
163
168
  if (!cart) return;
164
169
  try {
@@ -179,53 +184,67 @@ const ProductCard = ({
179
184
  }
180
185
  };
181
186
 
187
+ const isWishlistFetching =
188
+ useIsFetching({ queryKey: [WISHLIST_DETAILS_QUERY_KEY] }) > 0;
189
+ const isLineUpdating = isLineUpdatingLocal || isWishlistFetching;
190
+
182
191
  const handleIncrementQuantity = async () => {
183
- setIsLineUpdating(true);
184
- if (containsWishlistControls && wishlist) {
185
- try {
186
- const updatedLines = wishlist.ProductListLines.map((line) => {
192
+ if (isLineUpdating) return;
193
+ setIsLineUpdatingLocal(true);
194
+
195
+ try {
196
+ if (containsWishlistControls && wishlist) {
197
+ const updatedLines = (wishlist?.ProductListLines ?? []).map((line) => {
187
198
  const updated = { ...line, Product: undefined };
188
- if (line.ProductId === Number(product.id))
199
+ if (line.ProductId === Number(product.id)) {
189
200
  updated.Quantity = quantity + 1;
201
+ }
190
202
  return updated;
191
203
  });
204
+ if (!updatedLines) return;
192
205
  await updateWishlist({
193
- Id: wishlist.Id,
206
+ Id: wishlist?.Id,
194
207
  ProductListLines: updatedLines,
195
208
  });
196
- setQuantity((q) => q + 1);
197
- } catch {}
198
- } else {
209
+ }
210
+
199
211
  setQuantity((q) => q + 1);
212
+ } catch (err) {
213
+ console.error("Increment failed", err);
214
+ } finally {
215
+ setIsLineUpdatingLocal(false);
200
216
  }
201
- setIsLineUpdating(false);
202
217
  };
203
218
 
204
219
  const handleDecrementQuantity = async () => {
205
- if (quantity <= 0) return;
206
- setIsLineUpdating(true);
207
- if (containsWishlistControls && wishlist) {
208
- try {
209
- const updatedLines = wishlist.ProductListLines.map((line) => {
220
+ if (isLineUpdating || quantity <= 0) return;
221
+ setIsLineUpdatingLocal(true);
222
+
223
+ try {
224
+ if (containsWishlistControls && wishlist) {
225
+ const updatedLines = (wishlist?.ProductListLines ?? []).map((line) => {
210
226
  const updated = { ...line, Product: undefined };
211
- if (line.ProductId === Number(product.id))
227
+ if (line.ProductId === Number(product.id)) {
212
228
  updated.Quantity = quantity - 1;
229
+ }
213
230
  return updated;
214
231
  });
232
+ if (!updatedLines) return;
215
233
  await updateWishlist({
216
- Id: wishlist.Id,
234
+ Id: wishlist?.Id,
217
235
  ProductListLines: updatedLines,
218
236
  });
219
- setQuantity((q) => q - 1);
220
- } catch {}
221
- } else {
237
+ }
238
+
222
239
  setQuantity((q) => q - 1);
240
+ } catch (err) {
241
+ console.error("Decrement failed", err);
242
+ } finally {
243
+ setIsLineUpdatingLocal(false);
223
244
  }
224
- setIsLineUpdating(false);
225
245
  };
226
246
 
227
247
  const internalContextValue = {
228
- favorite,
229
248
  handleToggleFavorite,
230
249
  openProductModal,
231
250
  handleToggleProductModal,
@@ -249,7 +268,6 @@ const ProductCard = ({
249
268
  open={openAddToWishlistDialog}
250
269
  handleClose={() => setOpenAddToWishlistDialog(false)}
251
270
  productId={Number(product.id)}
252
- onSuccess={handleAddRemoveSuccess}
253
271
  />
254
272
  )}
255
273
  {openProductModal && (
@@ -331,7 +349,7 @@ ProductCard.Price = () => {
331
349
  if (!ctx) return null;
332
350
 
333
351
  const { discount, price } = ctx.product;
334
-
352
+ if (!price || !discount) return null;
335
353
  return <ProductPrice discount={discount} price={price} />;
336
354
  };
337
355
 
@@ -358,18 +376,40 @@ const QuantityButtons = () => {
358
376
 
359
377
  ProductCard.QuantityButtons = QuantityButtons;
360
378
 
361
- ProductCard.HoverActions = () => {
379
+ ProductCard.HoverActions = ({ children }: { children: React.ReactNode }) => {
380
+ return (
381
+ <HoverIconWrapper className="hover-box"> {children} </HoverIconWrapper>
382
+ );
383
+ };
384
+
385
+ ProductCard.QuickViewButton = () => {
362
386
  const internal = useContext(ProductCardInternalContext);
363
387
  if (!internal) return null;
364
388
 
365
- const { favorite, handleToggleProductModal, handleToggleFavorite } = internal;
389
+ const { handleToggleProductModal } = internal;
366
390
 
367
391
  return (
368
- <HoverActions
369
- isFavorite={favorite}
370
- toggleView={handleToggleProductModal}
371
- toggleFavorite={handleToggleFavorite}
372
- />
392
+ <IconButton onClick={handleToggleProductModal}>
393
+ <RemoveRedEye color="disabled" fontSize="small" />
394
+ </IconButton>
395
+ );
396
+ };
397
+
398
+ ProductCard.FavoriteButton = () => {
399
+ const internal = useContext(ProductCardInternalContext);
400
+ if (!internal) return null;
401
+
402
+ const { handleToggleFavorite } = internal;
403
+
404
+ const ctx = useContext(ProductCardContext);
405
+ if (!ctx) return null;
406
+
407
+ const { id } = ctx.product;
408
+
409
+ const isFavorite = useFavorite(Number(id));
410
+
411
+ return (
412
+ <FavoriteButton isFavorite={isFavorite} onToggle={handleToggleFavorite} />
373
413
  );
374
414
  };
375
415
 
@@ -1,6 +1,8 @@
1
- import { createContext, useContext, ReactNode } from "react";
1
+ import { createContext, useContext, ReactNode, useState } from "react";
2
2
  import Link from "next/link";
3
3
  import Rating from "@mui/material/Rating";
4
+ import IconButton from "@mui/material/IconButton";
5
+ import RemoveRedEye from "@mui/icons-material/RemoveRedEye";
4
6
  // GLOBAL CUSTOM COMPONENTS
5
7
  import { H6 } from "@evenicanpm/storefront-core/src/components-v2/Typography";
6
8
  import {
@@ -8,17 +10,22 @@ import {
8
10
  FlexBox,
9
11
  } from "@evenicanpm/storefront-core/src/components-v2/flex-box/index";
10
12
  import ImageWithFallback from "@evenicanpm/storefront-core/src/components-v2/ImageWithFallback";
11
- // CUSTOM UTILS LIBRARY FUNCTIONS
12
- import { calculateDiscount, currency } from "@/lib/lib";
13
- // STYLED COMPONENTS
14
- import { PriceText } from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card-plp/styles/index";
15
- // LOCAL COMPONENTS
13
+ import AddToWishlistDialog from "@evenicanpm/storefront-core/src/components-v2/wishlist-dialogs/add-to-wishlist";
14
+ import ProductViewDialog from "@evenicanpm/storefront-core/src/components-v2/product-dialog";
15
+ // LOCAL CUSTOM COMPONENTS
16
16
  import DiscountChip from "@evenicanpm/storefront-core/src/components-v2/product-cards/discount-chip";
17
- import QuantityButtons from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card-plp/components/quantity-buttons";
18
- // LOCAL CUSTOM HOOKS
19
- import useProduct from "@evenicanpm/storefront-core/src/components-v2/product-cards/use-product";
20
-
17
+ import QuantityButtons from "@evenicanpm/storefront-core/src/components-v2/product-cards/quantity-buttons";
18
+ import FavoriteButton from "@evenicanpm/storefront-core/src/components-v2/product-cards/favorite-button";
19
+ // LIBRARY AND HOOKS
20
+ import { calculateDiscount, currency } from "@/lib/lib";
21
21
  import buildDetailUrl from "@/lib/build-detail-url";
22
+ import useCart from "@/hooks/use-cart";
23
+ import useFavorite from "@/hooks/use-favorite";
24
+ // STYLED COMPONENTS
25
+ import {
26
+ PriceText,
27
+ HoverIconWrapper,
28
+ } from "@evenicanpm/storefront-core/src/components-v2/product-cards/product-card-plp/styles/index";
22
29
 
23
30
  type Product = {
24
31
  title: string;
@@ -30,7 +37,11 @@ type Product = {
30
37
  id: number;
31
38
  };
32
39
 
33
- const ProductCardPlpContext = createContext<{ product: Product } | null>(null);
40
+ const ProductCardPlpContext = createContext<{
41
+ product: Product;
42
+ setOpenAddToWishlistDialog?: (open: boolean) => void;
43
+ setOpenProductModal?: (open: boolean) => void;
44
+ } | null>(null);
34
45
 
35
46
  type ProductCardPlpProps = {
36
47
  product: Product;
@@ -38,37 +49,74 @@ type ProductCardPlpProps = {
38
49
  };
39
50
 
40
51
  const ProductCardPlp = ({ product, children }: ProductCardPlpProps) => {
52
+ const [openProductModal, setOpenProductModal] = useState(false);
53
+ const [openAddToWishlistDialog, setOpenAddToWishlistDialog] = useState(false);
54
+
41
55
  return (
42
- <ProductCardPlpContext.Provider value={{ product }}>
56
+ <ProductCardPlpContext.Provider
57
+ value={{ product, setOpenAddToWishlistDialog, setOpenProductModal }}
58
+ >
43
59
  <div>{children}</div>
60
+ {openAddToWishlistDialog && (
61
+ <AddToWishlistDialog
62
+ open={openAddToWishlistDialog}
63
+ handleClose={() => setOpenAddToWishlistDialog(false)}
64
+ productId={Number(product.id)}
65
+ />
66
+ )}
67
+ {openProductModal && (
68
+ <ProductViewDialog
69
+ openDialog={openProductModal}
70
+ handleCloseDialog={() => setOpenProductModal(false)}
71
+ productId={Number(product.id)}
72
+ />
73
+ )}
44
74
  </ProductCardPlpContext.Provider>
45
75
  );
46
76
  };
47
77
 
48
- ProductCardPlp.Image = () => {
78
+ ProductCardPlp.ImageWrapper = ({ children }: { children: React.ReactNode }) => {
49
79
  const ctx = useContext(ProductCardPlpContext);
50
80
  if (!ctx) return null;
51
81
 
52
- const { title, id, imgUrl, discount = 0 } = ctx.product;
82
+ const { title, id } = ctx.product;
53
83
 
54
84
  return (
55
85
  <Link href={buildDetailUrl(title, id)}>
56
- <FlexBox position="relative" bgcolor="grey.50" borderRadius={3} mb={2}>
57
- <ImageWithFallback
58
- alt={title ?? "Product Image"}
59
- width={380}
60
- height={379}
61
- src={imgUrl}
62
- style={{ borderRadius: "12px" }}
63
- />
64
- {discount ? (
65
- <DiscountChip discount={discount} sx={{ left: 20, top: 20 }} />
66
- ) : null}
86
+ <FlexBox
87
+ className="hover-box-container"
88
+ position="relative"
89
+ bgcolor="grey.50"
90
+ borderRadius={3}
91
+ mb={2}
92
+ >
93
+ {children}
67
94
  </FlexBox>
68
95
  </Link>
69
96
  );
70
97
  };
71
98
 
99
+ ProductCardPlp.Image = () => {
100
+ const ctx = useContext(ProductCardPlpContext);
101
+ if (!ctx) return null;
102
+
103
+ const { title, imgUrl, discount = 0 } = ctx.product;
104
+ return (
105
+ <>
106
+ <ImageWithFallback
107
+ alt={title ?? "Product Image"}
108
+ width={380}
109
+ height={379}
110
+ src={imgUrl}
111
+ style={{ borderRadius: "12px" }}
112
+ />
113
+ {discount ? (
114
+ <DiscountChip discount={discount} sx={{ left: 20, top: 20 }} />
115
+ ) : null}
116
+ </>
117
+ );
118
+ };
119
+
72
120
  ProductCardPlp.Body = ({ children }: { children: React.ReactNode }) => {
73
121
  return <FlexBetween alignItems="flex-end">{children}</FlexBetween>;
74
122
  };
@@ -108,52 +156,93 @@ ProductCardPlp.Price = () => {
108
156
  const ctx = useContext(ProductCardPlpContext);
109
157
  if (!ctx) return null;
110
158
 
111
- const { discount, price } = ctx.product;
159
+ const { discount = 0, price } = ctx.product;
160
+ if (price == null) return null;
112
161
 
113
162
  return (
114
163
  <PriceText>
115
- {discount ? <span className="base-price">{currency(price)}</span> : null}
116
- {calculateDiscount(price, discount)}
164
+ {discount > 0 ? (
165
+ <>
166
+ <span className="base-price">{currency(price)}</span>
167
+ {calculateDiscount(price, discount)}
168
+ </>
169
+ ) : (
170
+ currency(price)
171
+ )}
117
172
  </PriceText>
118
173
  );
119
174
  };
120
175
 
176
+ ProductCardPlp.HoverActions = ({ children }: { children: React.ReactNode }) => {
177
+ return (
178
+ <HoverIconWrapper className="hover-box"> {children} </HoverIconWrapper>
179
+ );
180
+ };
181
+
182
+ ProductCardPlp.QuickViewButton = () => {
183
+ const ctx = useContext(ProductCardPlpContext);
184
+ if (!ctx) return null;
185
+
186
+ return (
187
+ <IconButton
188
+ onClick={(e) => {
189
+ e.preventDefault();
190
+ e.stopPropagation();
191
+ ctx.setOpenProductModal?.(true);
192
+ }}
193
+ >
194
+ <RemoveRedEye color="disabled" fontSize="small" />
195
+ </IconButton>
196
+ );
197
+ };
198
+
199
+ ProductCardPlp.FavoriteButton = () => {
200
+ const ctx = useContext(ProductCardPlpContext);
201
+ if (!ctx) return null;
202
+
203
+ const { id } = ctx.product;
204
+
205
+ const isFavorite = useFavorite(Number(id));
206
+
207
+ return (
208
+ <FavoriteButton
209
+ isFavorite={isFavorite}
210
+ onToggle={() => {
211
+ ctx.setOpenAddToWishlistDialog?.(true);
212
+ }}
213
+ />
214
+ );
215
+ };
216
+
217
+ // Using quantity buttons (addtocart) doesn't make sense when we have product variants to select.
218
+ // So hide them for now, implement based on client requirements.
121
219
  ProductCardPlp.QuantityButtons = () => {
122
220
  const ctx = useContext(ProductCardPlpContext);
123
221
  if (!ctx) return null;
124
222
 
125
- const { id, price, title, imgUrl, slug } = ctx.product;
126
- const { cartItem, handleCartAmountChange } = useProduct(slug);
223
+ const { id } = ctx.product;
224
+ const { currentCartLine, handleCartAmountChange, loading } = useCart(id);
225
+ const [quantity, setQuantity] = useState(currentCartLine?.Quantity || 0);
226
+
127
227
  const handleIncrementQuantity = () => {
128
- const product = {
129
- id,
130
- slug,
131
- price,
132
- name: title,
133
- imgUrl,
134
- qty: (cartItem?.Quantity || 0) + 1,
135
- };
136
- product;
137
- handleCartAmountChange();
228
+ const qty = quantity + 1;
229
+ handleCartAmountChange(qty);
230
+ setQuantity(qty);
138
231
  };
139
232
 
140
233
  const handleDecrementQuantity = () => {
141
- const product = {
142
- id,
143
- slug,
144
- price,
145
- name: title,
146
- imgUrl,
147
- qty: (cartItem?.Quantity || 0) - 1,
148
- };
149
- product;
150
- handleCartAmountChange("remove");
234
+ if (quantity <= 0) return;
235
+ const qty = quantity - 1;
236
+ handleCartAmountChange(qty);
237
+ setQuantity(qty);
151
238
  };
239
+
152
240
  return (
153
241
  <QuantityButtons
154
- quantity={cartItem?.Quantity || 0}
242
+ quantity={quantity}
155
243
  handleIncrement={handleIncrementQuantity}
156
244
  handleDecrement={handleDecrementQuantity}
245
+ isLineUpdating={loading}
157
246
  />
158
247
  );
159
248
  };
@@ -16,3 +16,20 @@ export const PriceText = styled("p")(({ theme }) => ({
16
16
  color: theme.palette.grey[600],
17
17
  },
18
18
  }));
19
+
20
+ export const HoverIconWrapper = styled("div")({
21
+ zIndex: 2,
22
+ top: "7px",
23
+ right: "15px",
24
+ display: "flex",
25
+ cursor: "pointer",
26
+ position: "absolute",
27
+ flexDirection: "column",
28
+ opacity: 0,
29
+ transition: "all 0.3s ease-in-out",
30
+
31
+ // Show when parent (with .hover-box-container) is hovered
32
+ ".hover-box-container:hover &": {
33
+ opacity: 1,
34
+ },
35
+ });