@pradip1995/create-storefront 1.0.1

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 (338) hide show
  1. package/bin/create-storefront.js +239 -0
  2. package/lib/kit-next-config.js +84 -0
  3. package/package.json +32 -0
  4. package/templates/storefront/.eslintrc.json +3 -0
  5. package/templates/storefront/README.md +35 -0
  6. package/templates/storefront/check-env-variables.js +51 -0
  7. package/templates/storefront/kit-next-config.js +71 -0
  8. package/templates/storefront/next-env.d.ts +5 -0
  9. package/templates/storefront/next.config.js +25 -0
  10. package/templates/storefront/package.json +56 -0
  11. package/templates/storefront/postcss.config.js +6 -0
  12. package/templates/storefront/public/favicon.png +0 -0
  13. package/templates/storefront/src/app/[countryCode]/(checkout)/checkout/page.tsx +23 -0
  14. package/templates/storefront/src/app/[countryCode]/(checkout)/checkout/payment/page.tsx +47 -0
  15. package/templates/storefront/src/app/[countryCode]/(checkout)/layout.tsx +31 -0
  16. package/templates/storefront/src/app/[countryCode]/(checkout)/not-found.tsx +19 -0
  17. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/addresses/page.tsx +31 -0
  18. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/loading.tsx +9 -0
  19. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/details/[id]/page.tsx +35 -0
  20. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/exchange/[id]/page.tsx +47 -0
  21. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/page.tsx +28 -0
  22. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/orders/return/[id]/page.tsx +66 -0
  23. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/page.tsx +22 -0
  24. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/payment-methods/page.tsx +23 -0
  25. package/templates/storefront/src/app/[countryCode]/(main)/account/@dashboard/profile/page.tsx +43 -0
  26. package/templates/storefront/src/app/[countryCode]/(main)/account/@login/default.tsx +11 -0
  27. package/templates/storefront/src/app/[countryCode]/(main)/account/@login/page.tsx +18 -0
  28. package/templates/storefront/src/app/[countryCode]/(main)/account/guest-orders/page.tsx +13 -0
  29. package/templates/storefront/src/app/[countryCode]/(main)/account/layout.tsx +22 -0
  30. package/templates/storefront/src/app/[countryCode]/(main)/account/loading.tsx +9 -0
  31. package/templates/storefront/src/app/[countryCode]/(main)/cart/loading.tsx +5 -0
  32. package/templates/storefront/src/app/[countryCode]/(main)/cart/not-found.tsx +21 -0
  33. package/templates/storefront/src/app/[countryCode]/(main)/cart/page.tsx +23 -0
  34. package/templates/storefront/src/app/[countryCode]/(main)/categories/[...category]/page.tsx +11 -0
  35. package/templates/storefront/src/app/[countryCode]/(main)/collections/[handle]/page.tsx +11 -0
  36. package/templates/storefront/src/app/[countryCode]/(main)/contact/page.tsx +21 -0
  37. package/templates/storefront/src/app/[countryCode]/(main)/guest-orders/page.tsx +12 -0
  38. package/templates/storefront/src/app/[countryCode]/(main)/help/page.tsx +28 -0
  39. package/templates/storefront/src/app/[countryCode]/(main)/layout.tsx +21 -0
  40. package/templates/storefront/src/app/[countryCode]/(main)/not-found.tsx +20 -0
  41. package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/confirmed/loading.tsx +5 -0
  42. package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/confirmed/page.tsx +23 -0
  43. package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/transfer/[token]/accept/page.tsx +41 -0
  44. package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/transfer/[token]/decline/page.tsx +41 -0
  45. package/templates/storefront/src/app/[countryCode]/(main)/order/[id]/transfer/[token]/page.tsx +38 -0
  46. package/templates/storefront/src/app/[countryCode]/(main)/order/exchange/[id]/page.tsx +47 -0
  47. package/templates/storefront/src/app/[countryCode]/(main)/order/return/[id]/page.tsx +61 -0
  48. package/templates/storefront/src/app/[countryCode]/(main)/orders/[id]/page.tsx +33 -0
  49. package/templates/storefront/src/app/[countryCode]/(main)/page.tsx +24 -0
  50. package/templates/storefront/src/app/[countryCode]/(main)/privacy-policy/page.tsx +173 -0
  51. package/templates/storefront/src/app/[countryCode]/(main)/products/[handle]/page.tsx +193 -0
  52. package/templates/storefront/src/app/[countryCode]/(main)/reset-password/page.tsx +192 -0
  53. package/templates/storefront/src/app/[countryCode]/(main)/store/page.tsx +72 -0
  54. package/templates/storefront/src/app/[countryCode]/(main)/terms-of-use/page.tsx +179 -0
  55. package/templates/storefront/src/app/[countryCode]/(main)/wishlist/page.tsx +19 -0
  56. package/templates/storefront/src/app/api/meta/event/route.ts +63 -0
  57. package/templates/storefront/src/app/auth/customer/google/callback/page.tsx +126 -0
  58. package/templates/storefront/src/app/layout.tsx +104 -0
  59. package/templates/storefront/src/app/not-found.tsx +30 -0
  60. package/templates/storefront/src/app/opengraph-image.jpg +0 -0
  61. package/templates/storefront/src/app/robots.ts +15 -0
  62. package/templates/storefront/src/app/sitemap.ts +65 -0
  63. package/templates/storefront/src/app/twitter-image.jpg +0 -0
  64. package/templates/storefront/src/modules/account/components/account-deletion/index.tsx +160 -0
  65. package/templates/storefront/src/modules/account/components/account-info/index.tsx +145 -0
  66. package/templates/storefront/src/modules/account/components/account-nav/icons.tsx +43 -0
  67. package/templates/storefront/src/modules/account/components/account-nav/index.tsx +318 -0
  68. package/templates/storefront/src/modules/account/components/account-nav/logout-modal.tsx +92 -0
  69. package/templates/storefront/src/modules/account/components/account-nav/payment-methods-icon.tsx +9 -0
  70. package/templates/storefront/src/modules/account/components/address-book/index.tsx +47 -0
  71. package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +377 -0
  72. package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +468 -0
  73. package/templates/storefront/src/modules/account/components/deletion-pending-modal/index.tsx +213 -0
  74. package/templates/storefront/src/modules/account/components/forgot-password/index.tsx +1 -0
  75. package/templates/storefront/src/modules/account/components/login/index.tsx +1 -0
  76. package/templates/storefront/src/modules/account/components/order-card/index.tsx +221 -0
  77. package/templates/storefront/src/modules/account/components/order-overview/index.tsx +159 -0
  78. package/templates/storefront/src/modules/account/components/overview/index.tsx +189 -0
  79. package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +447 -0
  80. package/templates/storefront/src/modules/account/components/profile-email/index.tsx +75 -0
  81. package/templates/storefront/src/modules/account/components/profile-form/index.tsx +416 -0
  82. package/templates/storefront/src/modules/account/components/profile-name/index.tsx +76 -0
  83. package/templates/storefront/src/modules/account/components/profile-password/index.tsx +70 -0
  84. package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +185 -0
  85. package/templates/storefront/src/modules/account/components/register/index.tsx +1 -0
  86. package/templates/storefront/src/modules/account/components/return-item-selector/index.tsx +187 -0
  87. package/templates/storefront/src/modules/account/components/return-shipping-selector/index.tsx +118 -0
  88. package/templates/storefront/src/modules/account/components/transfer-request-form/index.tsx +81 -0
  89. package/templates/storefront/src/modules/account/templates/account-layout.tsx +38 -0
  90. package/templates/storefront/src/modules/account/templates/exchange-request-template.tsx +389 -0
  91. package/templates/storefront/src/modules/account/templates/guest-orders-template.tsx +123 -0
  92. package/templates/storefront/src/modules/account/templates/login-template.tsx +44 -0
  93. package/templates/storefront/src/modules/account/templates/payment-methods-template.tsx +478 -0
  94. package/templates/storefront/src/modules/account/templates/return-request-template.tsx +300 -0
  95. package/templates/storefront/src/modules/cart/components/abandoned-carts/ScrollToPendingOrdersButton.tsx +21 -0
  96. package/templates/storefront/src/modules/cart/components/abandoned-carts/index.tsx +335 -0
  97. package/templates/storefront/src/modules/cart/components/applied-promotions/index.tsx +121 -0
  98. package/templates/storefront/src/modules/cart/components/cart-delivery-selection/index.tsx +203 -0
  99. package/templates/storefront/src/modules/cart/components/cart-item-card/index.tsx +476 -0
  100. package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +73 -0
  101. package/templates/storefront/src/modules/cart/components/cart-view-tracker/index.tsx +44 -0
  102. package/templates/storefront/src/modules/cart/components/delivery-information/index.tsx +89 -0
  103. package/templates/storefront/src/modules/cart/components/empty-cart-message/index.tsx +38 -0
  104. package/templates/storefront/src/modules/cart/components/item/index.tsx +150 -0
  105. package/templates/storefront/src/modules/cart/components/pincode-checker/index.tsx +174 -0
  106. package/templates/storefront/src/modules/cart/components/sign-in-prompt/index.tsx +26 -0
  107. package/templates/storefront/src/modules/cart/components/you-may-also-like/index.tsx +137 -0
  108. package/templates/storefront/src/modules/cart/templates/index.tsx +88 -0
  109. package/templates/storefront/src/modules/cart/templates/items.tsx +49 -0
  110. package/templates/storefront/src/modules/cart/templates/preview.tsx +51 -0
  111. package/templates/storefront/src/modules/cart/templates/summary.tsx +29 -0
  112. package/templates/storefront/src/modules/checkout/components/add-address-modal/index.tsx +390 -0
  113. package/templates/storefront/src/modules/checkout/components/address-card/index.tsx +135 -0
  114. package/templates/storefront/src/modules/checkout/components/address-select/index.tsx +116 -0
  115. package/templates/storefront/src/modules/checkout/components/addresses/index.tsx +605 -0
  116. package/templates/storefront/src/modules/checkout/components/back-link/index.tsx +32 -0
  117. package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +301 -0
  118. package/templates/storefront/src/modules/checkout/components/checkout-begin-tracker/index.tsx +45 -0
  119. package/templates/storefront/src/modules/checkout/components/checkout-leave-guard/index.tsx +109 -0
  120. package/templates/storefront/src/modules/checkout/components/checkout-shipping-tracker/index.tsx +45 -0
  121. package/templates/storefront/src/modules/checkout/components/country-select/index.tsx +50 -0
  122. package/templates/storefront/src/modules/checkout/components/discount-code/index.tsx +220 -0
  123. package/templates/storefront/src/modules/checkout/components/error-message/index.tsx +13 -0
  124. package/templates/storefront/src/modules/checkout/components/payment/index.tsx +572 -0
  125. package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +257 -0
  126. package/templates/storefront/src/modules/checkout/components/payment-button/razorpay-payment-button.tsx +136 -0
  127. package/templates/storefront/src/modules/checkout/components/payment-container/index.tsx +129 -0
  128. package/templates/storefront/src/modules/checkout/components/payment-test/index.tsx +12 -0
  129. package/templates/storefront/src/modules/checkout/components/payment-wrapper/index.tsx +50 -0
  130. package/templates/storefront/src/modules/checkout/components/payment-wrapper/stripe-wrapper.tsx +54 -0
  131. package/templates/storefront/src/modules/checkout/components/processing-overlay/index.tsx +83 -0
  132. package/templates/storefront/src/modules/checkout/components/review/index.tsx +60 -0
  133. package/templates/storefront/src/modules/checkout/components/select-address-modal/index.tsx +103 -0
  134. package/templates/storefront/src/modules/checkout/components/shipping/index.tsx +533 -0
  135. package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +521 -0
  136. package/templates/storefront/src/modules/checkout/components/submit-button/index.tsx +32 -0
  137. package/templates/storefront/src/modules/checkout/templates/checkout-form/index.tsx +38 -0
  138. package/templates/storefront/src/modules/checkout/templates/checkout-summary/index.tsx +274 -0
  139. package/templates/storefront/src/modules/common/components/breadcrumb/index.tsx +43 -0
  140. package/templates/storefront/src/modules/common/components/cart-totals/index.tsx +473 -0
  141. package/templates/storefront/src/modules/common/components/checkbox/index.tsx +98 -0
  142. package/templates/storefront/src/modules/common/components/delete-button/index.tsx +156 -0
  143. package/templates/storefront/src/modules/common/components/divider/index.tsx +9 -0
  144. package/templates/storefront/src/modules/common/components/filter-checkbox-group/index.tsx +134 -0
  145. package/templates/storefront/src/modules/common/components/filter-radio-group/index.tsx +62 -0
  146. package/templates/storefront/src/modules/common/components/input/index.tsx +79 -0
  147. package/templates/storefront/src/modules/common/components/interactive-link/index.tsx +33 -0
  148. package/templates/storefront/src/modules/common/components/line-item-options/index.tsx +26 -0
  149. package/templates/storefront/src/modules/common/components/line-item-price/index.tsx +64 -0
  150. package/templates/storefront/src/modules/common/components/line-item-unit-price/index.tsx +61 -0
  151. package/templates/storefront/src/modules/common/components/localized-client-link/index.tsx +32 -0
  152. package/templates/storefront/src/modules/common/components/login-popup/index.tsx +78 -0
  153. package/templates/storefront/src/modules/common/components/modal/index.tsx +123 -0
  154. package/templates/storefront/src/modules/common/components/native-select/index.tsx +75 -0
  155. package/templates/storefront/src/modules/common/components/obfuscated-email/index.tsx +30 -0
  156. package/templates/storefront/src/modules/common/components/product/product-rating/index.tsx +172 -0
  157. package/templates/storefront/src/modules/common/components/product/review-modal/index.tsx +333 -0
  158. package/templates/storefront/src/modules/common/components/product/share-button/index.tsx +227 -0
  159. package/templates/storefront/src/modules/common/components/product/wishlist-icon/index.tsx +46 -0
  160. package/templates/storefront/src/modules/common/components/radio/index.tsx +27 -0
  161. package/templates/storefront/src/modules/common/components/select/index.tsx +164 -0
  162. package/templates/storefront/src/modules/common/components/side-panel/index.tsx +65 -0
  163. package/templates/storefront/src/modules/common/icons/arrow-left.tsx +36 -0
  164. package/templates/storefront/src/modules/common/icons/back.tsx +37 -0
  165. package/templates/storefront/src/modules/common/icons/bancontact.tsx +26 -0
  166. package/templates/storefront/src/modules/common/icons/chevron-down.tsx +30 -0
  167. package/templates/storefront/src/modules/common/icons/delivered.tsx +29 -0
  168. package/templates/storefront/src/modules/common/icons/envelope.tsx +27 -0
  169. package/templates/storefront/src/modules/common/icons/eye-off.tsx +37 -0
  170. package/templates/storefront/src/modules/common/icons/eye.tsx +37 -0
  171. package/templates/storefront/src/modules/common/icons/fast-delivery.tsx +65 -0
  172. package/templates/storefront/src/modules/common/icons/ideal.tsx +26 -0
  173. package/templates/storefront/src/modules/common/icons/lock.tsx +31 -0
  174. package/templates/storefront/src/modules/common/icons/map-pin.tsx +37 -0
  175. package/templates/storefront/src/modules/common/icons/medusa.tsx +27 -0
  176. package/templates/storefront/src/modules/common/icons/menu.tsx +45 -0
  177. package/templates/storefront/src/modules/common/icons/nextjs.tsx +27 -0
  178. package/templates/storefront/src/modules/common/icons/package.tsx +44 -0
  179. package/templates/storefront/src/modules/common/icons/paypal.tsx +30 -0
  180. package/templates/storefront/src/modules/common/icons/phone.tsx +30 -0
  181. package/templates/storefront/src/modules/common/icons/placeholder-image.tsx +44 -0
  182. package/templates/storefront/src/modules/common/icons/refresh.tsx +51 -0
  183. package/templates/storefront/src/modules/common/icons/spinner.tsx +37 -0
  184. package/templates/storefront/src/modules/common/icons/trash.tsx +51 -0
  185. package/templates/storefront/src/modules/common/icons/user.tsx +37 -0
  186. package/templates/storefront/src/modules/common/icons/x.tsx +37 -0
  187. package/templates/storefront/src/modules/contact/templates/index.tsx +272 -0
  188. package/templates/storefront/src/modules/help/templates/index.tsx +629 -0
  189. package/templates/storefront/src/modules/home/components/dynamic-banner/index.tsx +190 -0
  190. package/templates/storefront/src/modules/home/components/featured-products/index.tsx +16 -0
  191. package/templates/storefront/src/modules/home/components/featured-products/product-rail/index.tsx +51 -0
  192. package/templates/storefront/src/modules/home/components/features/index.tsx +1 -0
  193. package/templates/storefront/src/modules/home/components/hero/index.tsx +1 -0
  194. package/templates/storefront/src/modules/home/components/loved-by-moms/index.tsx +1 -0
  195. package/templates/storefront/src/modules/home/components/new-arrivals/index.tsx +1 -0
  196. package/templates/storefront/src/modules/home/components/shop-by-age/index.tsx +1 -0
  197. package/templates/storefront/src/modules/home/components/shop-by-category/index.tsx +1 -0
  198. package/templates/storefront/src/modules/home/components/testimonials/index.tsx +1 -0
  199. package/templates/storefront/src/modules/home/components/why-choose-us/dynamic-features.tsx +93 -0
  200. package/templates/storefront/src/modules/home/components/why-choose-us/index.tsx +1 -0
  201. package/templates/storefront/src/modules/layout/components/account-dropdown/index.tsx +56 -0
  202. package/templates/storefront/src/modules/layout/components/cart-button/index.tsx +8 -0
  203. package/templates/storefront/src/modules/layout/components/cart-dropdown/index.tsx +424 -0
  204. package/templates/storefront/src/modules/layout/components/cart-mismatch-banner/index.tsx +57 -0
  205. package/templates/storefront/src/modules/layout/components/cookie-consent/index.tsx +116 -0
  206. package/templates/storefront/src/modules/layout/components/country-select/index.tsx +135 -0
  207. package/templates/storefront/src/modules/layout/components/desktop-search/index.tsx +148 -0
  208. package/templates/storefront/src/modules/layout/components/dynamic-logo/index.tsx +27 -0
  209. package/templates/storefront/src/modules/layout/components/footer-categories/index.tsx +34 -0
  210. package/templates/storefront/src/modules/layout/components/footer-contact/index.tsx +87 -0
  211. package/templates/storefront/src/modules/layout/components/footer-description/index.tsx +12 -0
  212. package/templates/storefront/src/modules/layout/components/footer-logo/index.tsx +22 -0
  213. package/templates/storefront/src/modules/layout/components/footer-newsletter/index.tsx +100 -0
  214. package/templates/storefront/src/modules/layout/components/language-select/index.tsx +192 -0
  215. package/templates/storefront/src/modules/layout/components/medusa-cta/index.tsx +21 -0
  216. package/templates/storefront/src/modules/layout/components/mobile-menu/index.tsx +296 -0
  217. package/templates/storefront/src/modules/layout/components/nav-links/index.tsx +66 -0
  218. package/templates/storefront/src/modules/layout/components/nav-wrapper/index.tsx +14 -0
  219. package/templates/storefront/src/modules/layout/components/promo-bar/index.tsx +7 -0
  220. package/templates/storefront/src/modules/layout/components/promo-bar/promo-bar-content.tsx +174 -0
  221. package/templates/storefront/src/modules/layout/components/push-notification-manager/index.tsx +191 -0
  222. package/templates/storefront/src/modules/layout/components/search-panel/index.tsx +136 -0
  223. package/templates/storefront/src/modules/layout/components/side-menu/index.tsx +144 -0
  224. package/templates/storefront/src/modules/layout/components/verification-banner/index.tsx +217 -0
  225. package/templates/storefront/src/modules/layout/components/wishlist-counter/index.tsx +17 -0
  226. package/templates/storefront/src/modules/layout/templates/footer/index.tsx +7 -0
  227. package/templates/storefront/src/modules/layout/templates/nav/index.tsx +14 -0
  228. package/templates/storefront/src/modules/order/components/cancel-order-modal/index.tsx +168 -0
  229. package/templates/storefront/src/modules/order/components/help/index.tsx +25 -0
  230. package/templates/storefront/src/modules/order/components/item/index.tsx +62 -0
  231. package/templates/storefront/src/modules/order/components/items/index.tsx +44 -0
  232. package/templates/storefront/src/modules/order/components/onboarding-cta/index.tsx +28 -0
  233. package/templates/storefront/src/modules/order/components/order-confirmation-back-handler/index.tsx +28 -0
  234. package/templates/storefront/src/modules/order/components/order-details/index.tsx +63 -0
  235. package/templates/storefront/src/modules/order/components/order-purchase-tracker/index.tsx +48 -0
  236. package/templates/storefront/src/modules/order/components/order-redesign/index.tsx +887 -0
  237. package/templates/storefront/src/modules/order/components/order-summary/index.tsx +60 -0
  238. package/templates/storefront/src/modules/order/components/payment-details/index.tsx +63 -0
  239. package/templates/storefront/src/modules/order/components/shipping-details/index.tsx +73 -0
  240. package/templates/storefront/src/modules/order/components/transfer-actions/index.tsx +81 -0
  241. package/templates/storefront/src/modules/order/components/transfer-image/index.tsx +275 -0
  242. package/templates/storefront/src/modules/order/templates/order-completed-template.tsx +233 -0
  243. package/templates/storefront/src/modules/order/templates/order-details-template.tsx +128 -0
  244. package/templates/storefront/src/modules/products/components/image-gallery/index.tsx +297 -0
  245. package/templates/storefront/src/modules/products/components/product-actions/index.tsx +1400 -0
  246. package/templates/storefront/src/modules/products/components/product-actions/mobile-actions.tsx +217 -0
  247. package/templates/storefront/src/modules/products/components/product-actions/option-select.tsx +62 -0
  248. package/templates/storefront/src/modules/products/components/product-onboarding-cta/index.tsx +30 -0
  249. package/templates/storefront/src/modules/products/components/product-preview/index.tsx +5 -0
  250. package/templates/storefront/src/modules/products/components/product-preview/price.tsx +29 -0
  251. package/templates/storefront/src/modules/products/components/product-price/index.tsx +58 -0
  252. package/templates/storefront/src/modules/products/components/product-rating/index.tsx +1 -0
  253. package/templates/storefront/src/modules/products/components/product-tabs/accordion.tsx +100 -0
  254. package/templates/storefront/src/modules/products/components/product-tabs/index.tsx +127 -0
  255. package/templates/storefront/src/modules/products/components/product-tabs/ratings-tab.tsx +598 -0
  256. package/templates/storefront/src/modules/products/components/product-view-tracker/index.tsx +53 -0
  257. package/templates/storefront/src/modules/products/components/related-products/index.tsx +152 -0
  258. package/templates/storefront/src/modules/products/components/review-modal/index.tsx +1 -0
  259. package/templates/storefront/src/modules/products/components/share-button/index.tsx +1 -0
  260. package/templates/storefront/src/modules/products/components/thumbnail/index.tsx +91 -0
  261. package/templates/storefront/src/modules/products/components/wishlist-icon/index.tsx +1 -0
  262. package/templates/storefront/src/modules/products/context/product-context.tsx +52 -0
  263. package/templates/storefront/src/modules/products/templates/index.tsx +26 -0
  264. package/templates/storefront/src/modules/products/templates/product-actions-wrapper/index.tsx +1 -0
  265. package/templates/storefront/src/modules/products/templates/product-info/index.tsx +2 -0
  266. package/templates/storefront/src/modules/shipping/components/free-shipping-price-nudge/index.tsx +283 -0
  267. package/templates/storefront/src/modules/skeletons/components/skeleton-button/index.tsx +5 -0
  268. package/templates/storefront/src/modules/skeletons/components/skeleton-card-details/index.tsx +10 -0
  269. package/templates/storefront/src/modules/skeletons/components/skeleton-cart-item/index.tsx +35 -0
  270. package/templates/storefront/src/modules/skeletons/components/skeleton-cart-totals/index.tsx +30 -0
  271. package/templates/storefront/src/modules/skeletons/components/skeleton-code-form/index.tsx +13 -0
  272. package/templates/storefront/src/modules/skeletons/components/skeleton-line-item/index.tsx +35 -0
  273. package/templates/storefront/src/modules/skeletons/components/skeleton-order-confirmed-header/index.tsx +14 -0
  274. package/templates/storefront/src/modules/skeletons/components/skeleton-order-information/index.tsx +36 -0
  275. package/templates/storefront/src/modules/skeletons/components/skeleton-order-items/index.tsx +43 -0
  276. package/templates/storefront/src/modules/skeletons/components/skeleton-order-summary/index.tsx +15 -0
  277. package/templates/storefront/src/modules/skeletons/components/skeleton-product-preview/index.tsx +15 -0
  278. package/templates/storefront/src/modules/skeletons/templates/skeleton-cart-page/index.tsx +65 -0
  279. package/templates/storefront/src/modules/skeletons/templates/skeleton-order-confirmed/index.tsx +21 -0
  280. package/templates/storefront/src/modules/skeletons/templates/skeleton-product-grid/index.tsx +23 -0
  281. package/templates/storefront/src/modules/skeletons/templates/skeleton-related-products/index.tsx +25 -0
  282. package/templates/storefront/src/modules/store/components/client-paginated-products.tsx +108 -0
  283. package/templates/storefront/src/modules/store/components/mobile-filters/index.tsx +135 -0
  284. package/templates/storefront/src/modules/store/components/pagination/index.tsx +118 -0
  285. package/templates/storefront/src/modules/store/components/product-list-view-tracker/index.tsx +43 -0
  286. package/templates/storefront/src/modules/store/components/refinement-list/index.tsx +299 -0
  287. package/templates/storefront/src/modules/store/components/refinement-list/sort-products/index.tsx +120 -0
  288. package/templates/storefront/src/modules/store/components/store-header/index.tsx +67 -0
  289. package/templates/storefront/src/modules/store/templates/index.tsx +1 -0
  290. package/templates/storefront/src/modules/store/templates/paginated-products.tsx +175 -0
  291. package/templates/storefront/src/modules/wishlist/components/wishlist-item/index.tsx +797 -0
  292. package/templates/storefront/src/modules/wishlist/templates/index.tsx +176 -0
  293. package/templates/storefront/src/storefront.config.ts +12 -0
  294. package/templates/storefront/src/styles/globals.css +326 -0
  295. package/templates/storefront/src/theme/valero/blocks/home/Features/index.tsx +61 -0
  296. package/templates/storefront/src/theme/valero/blocks/home/Hero/index.tsx +102 -0
  297. package/templates/storefront/src/theme/valero/blocks/home/LovedByMoms/index.tsx +407 -0
  298. package/templates/storefront/src/theme/valero/blocks/home/NewArrivals/index.tsx +48 -0
  299. package/templates/storefront/src/theme/valero/blocks/home/ShopByAge/index.tsx +128 -0
  300. package/templates/storefront/src/theme/valero/blocks/home/ShopByCategory/index.tsx +409 -0
  301. package/templates/storefront/src/theme/valero/blocks/home/Testimonials/index.tsx +697 -0
  302. package/templates/storefront/src/theme/valero/blocks/home/WhyChooseUs/index.tsx +62 -0
  303. package/templates/storefront/src/theme/valero/layouts/MainLayoutShell.tsx +14 -0
  304. package/templates/storefront/src/theme/valero/primitives/Button.tsx +28 -0
  305. package/templates/storefront/src/theme/valero/primitives/Card.tsx +32 -0
  306. package/templates/storefront/src/theme/valero/primitives/index.ts +2 -0
  307. package/templates/storefront/src/theme/valero/slots/account/ForgotPassword/index.tsx +1 -0
  308. package/templates/storefront/src/theme/valero/slots/account/Login/index.tsx +1 -0
  309. package/templates/storefront/src/theme/valero/slots/account/LoginTemplate/index.tsx +44 -0
  310. package/templates/storefront/src/theme/valero/slots/account/Register/index.tsx +1 -0
  311. package/templates/storefront/src/theme/valero/slots/cart/CartItem/index.tsx +11 -0
  312. package/templates/storefront/src/theme/valero/slots/cart/CartSummary/index.tsx +13 -0
  313. package/templates/storefront/src/theme/valero/slots/checkout/CheckoutForm/index.tsx +1 -0
  314. package/templates/storefront/src/theme/valero/slots/checkout/CheckoutSummary/index.tsx +1 -0
  315. package/templates/storefront/src/theme/valero/slots/layout/Footer/index.tsx +104 -0
  316. package/templates/storefront/src/theme/valero/slots/layout/Nav/index.tsx +97 -0
  317. package/templates/storefront/src/theme/valero/slots/layout/PromoBar/index.tsx +19 -0
  318. package/templates/storefront/src/theme/valero/slots/layout/PromoBar/promo-bar-content.tsx +174 -0
  319. package/templates/storefront/src/theme/valero/slots/order/OrderDetails/index.tsx +12 -0
  320. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductCTASection.tsx +191 -0
  321. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductDetailsSection.tsx +137 -0
  322. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductFeaturePanel.tsx +245 -0
  323. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductHighlightsSection.tsx +98 -0
  324. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductOptionsSection.tsx +233 -0
  325. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductPriceSection.tsx +53 -0
  326. package/templates/storefront/src/theme/valero/slots/product/ProductActions/ProductTrustSection.tsx +84 -0
  327. package/templates/storefront/src/theme/valero/slots/product/ProductActions/index.tsx +161 -0
  328. package/templates/storefront/src/theme/valero/slots/product/ProductCard/index.tsx +132 -0
  329. package/templates/storefront/src/theme/valero/slots/product/ProductInfo/index.tsx +40 -0
  330. package/templates/storefront/src/theme/valero/templates/StorePage/index.tsx +154 -0
  331. package/templates/storefront/src/theme/valero/tokens/colors.js +16 -0
  332. package/templates/storefront/src/theme/valero/tokens/colors.ts +21 -0
  333. package/templates/storefront/src/theme/valero/tokens/fonts.ts +13 -0
  334. package/templates/storefront/src/theme/valero/tokens/index.ts +3 -0
  335. package/templates/storefront/src/theme/valero/tokens/spacing.ts +9 -0
  336. package/templates/storefront/src/theme/valero/tokens/theme.css +91 -0
  337. package/templates/storefront/tailwind.config.js +221 -0
  338. package/templates/storefront/tsconfig.json +30 -0
@@ -0,0 +1,473 @@
1
+ "use client"
2
+
3
+ import { convertToLocale } from "@core/util/money"
4
+ import React from "react"
5
+ import { HttpTypes } from "@medusajs/types"
6
+ import { clx } from "@medusajs/ui"
7
+ import LocalizedClientLink from "@modules/common/components/localized-client-link"
8
+ import { useRouter, usePathname, useSearchParams } from "next/navigation"
9
+ import ProcessingOverlay from "@modules/checkout/components/processing-overlay"
10
+
11
+ type CartTotalsProps = {
12
+ totals: {
13
+ total?: number | null
14
+ subtotal?: number | null
15
+ tax_total?: number | null
16
+ currency_code: string
17
+ item_subtotal?: number | null
18
+ shipping_subtotal?: number | null
19
+ discount_subtotal?: number | null
20
+ }
21
+ items?: HttpTypes.StoreCartLineItem[]
22
+ checkoutStep?: string
23
+ customer?: HttpTypes.StoreCustomer | null
24
+ }
25
+
26
+ const CartTotals: React.FC<CartTotalsProps> = ({ totals, items = [], checkoutStep, customer }) => {
27
+ const router = useRouter()
28
+ const pathname = usePathname()
29
+ const searchParams = useSearchParams()
30
+ const activeStep = searchParams.get("step")
31
+
32
+ // Check if we're on the payment page, order page, or cart page
33
+ const isOnPaymentPage = pathname.includes("/checkout/payment")
34
+ const isOnOrderPage = pathname.includes("/order/")
35
+ const isOnCartPage = pathname.includes("/cart")
36
+
37
+ const {
38
+ currency_code,
39
+ total,
40
+ tax_total,
41
+ item_subtotal,
42
+ shipping_subtotal,
43
+ discount_subtotal,
44
+ } = totals
45
+
46
+ // Calculate Total MRP (sum of original_total from all items)
47
+ const totalMRP = items.reduce((sum, item) => {
48
+ return sum + (item.original_total || item.total || 0)
49
+ }, 0)
50
+
51
+ // Calculate total discount (difference between MRP and current subtotal)
52
+ const calculatedDiscount = totalMRP > (item_subtotal || 0)
53
+ ? totalMRP - (item_subtotal || 0)
54
+ : (discount_subtotal || 0)
55
+
56
+ // Use GST label for taxes (as shown in the image)
57
+ const gstAmount = tax_total || 0
58
+ const shippingAmount = shipping_subtotal || 0
59
+ const finalTotal = total || 0
60
+ const itemCount = items.length
61
+
62
+ const [isRedirecting, setIsRedirecting] = React.useState(false)
63
+ const [showOverlay, setShowOverlay] = React.useState(false)
64
+ const [processingVariant, setProcessingVariant] = React.useState<"payment" | "order">("payment")
65
+ const [isAutoSettingShipping, setIsAutoSettingShipping] = React.useState(false)
66
+
67
+ // Auto-set shipping method if on payment step and none is selected
68
+ const hasAutoSet = React.useRef<string | null>(null)
69
+
70
+ // Listen for real-time shipping updates
71
+ React.useEffect(() => {
72
+ const handlePostalUpdate = () => {
73
+ // Show loading state in totals
74
+ setIsAutoSettingShipping(true)
75
+ // Reset auto-set ref to allow re-selection of shipping for new pincode
76
+ hasAutoSet.current = ""
77
+ // Trigger a single router refresh as a safeguard
78
+ router.refresh()
79
+ }
80
+
81
+ window.addEventListener('postal-code-updated', handlePostalUpdate)
82
+ window.addEventListener('address-updated-silent', () => {
83
+ setIsAutoSettingShipping(true)
84
+ // Reset auto-set ref
85
+ hasAutoSet.current = ""
86
+ })
87
+ return () => {
88
+ window.removeEventListener('postal-code-updated', handlePostalUpdate)
89
+ window.removeEventListener('address-updated-silent', () => {})
90
+ }
91
+ }, [router])
92
+
93
+ // Safety reset for Calculating state
94
+ React.useEffect(() => {
95
+ const cart = totals as any
96
+ if (cart?.shipping_methods && cart.shipping_methods.length > 0) {
97
+ if (isAutoSettingShipping) {
98
+ setIsAutoSettingShipping(false)
99
+ }
100
+ }
101
+ }, [totals, isAutoSettingShipping])
102
+
103
+ React.useEffect(() => {
104
+ autoSetShipping()
105
+ }, [activeStep, totals, router])
106
+
107
+
108
+ const isSetting = React.useRef(false)
109
+
110
+ const autoSetShipping = async (retryCount = 0) => {
111
+ const cart = totals as any
112
+ if (!cart?.id || isSetting.current) return
113
+
114
+ // If shipping methods already exist, we are done
115
+ if (cart?.shipping_methods && cart.shipping_methods.length > 0) {
116
+ setIsAutoSettingShipping(false)
117
+ return
118
+ }
119
+
120
+ const { listCartOptions, setShippingMethod } = await import("@core/data/cart")
121
+ const currentKey = cart.id + cart.shipping_address?.postal_code
122
+
123
+ const isCheckoutPage = pathname.includes("/checkout")
124
+ const shouldAutoSet = (activeStep === "payment" || isCheckoutPage) && cart?.shipping_address?.postal_code?.length === 6
125
+
126
+ if (shouldAutoSet && hasAutoSet.current !== currentKey) {
127
+
128
+ isSetting.current = true
129
+ setIsAutoSettingShipping(true)
130
+
131
+ try {
132
+ const { shipping_options } = await listCartOptions()
133
+
134
+ if (shipping_options && shipping_options.length > 0) {
135
+ await setShippingMethod({ cartId: cart.id, shippingMethodId: shipping_options[0].id })
136
+ hasAutoSet.current = currentKey // Mark as done for this pincode
137
+ router.refresh()
138
+ // Final unlock delay
139
+ setTimeout(() => {
140
+ setIsAutoSettingShipping(false)
141
+ isSetting.current = false
142
+ }, 1500)
143
+ } else if (retryCount < 6) {
144
+ // Keep trying if no options yet
145
+ setTimeout(() => {
146
+ isSetting.current = false
147
+ autoSetShipping(retryCount + 1)
148
+ }, 1500)
149
+ } else {
150
+ setIsAutoSettingShipping(false)
151
+ isSetting.current = false
152
+ }
153
+ } catch (e) {
154
+ setIsAutoSettingShipping(false)
155
+ isSetting.current = false
156
+ }
157
+ } else {
158
+ setIsAutoSettingShipping(false)
159
+ isSetting.current = false
160
+ }
161
+ }
162
+
163
+ React.useEffect(() => {
164
+ autoSetShipping()
165
+ }, [activeStep, totals, router])
166
+
167
+ const syncLastEtdToCart = async () => {
168
+ try {
169
+ const cart = totals as any
170
+ const cookiesArr = document.cookie.split('; ')
171
+ const etdCookie = cookiesArr.find(row => row.startsWith('_medusa_last_etd='))
172
+ const lastEtdValue = etdCookie ? etdCookie.split('=')[1] : null
173
+
174
+ if (lastEtdValue && cart?.id && cart.metadata?.estimated_delivery !== lastEtdValue) {
175
+ const { updateCartMetadataSilently } = await import("@core/data/cart")
176
+ await updateCartMetadataSilently({
177
+ ...cart.metadata,
178
+ estimated_delivery: lastEtdValue
179
+ })
180
+ }
181
+ } catch (e) {
182
+ // Ignore sync failure as it's non-critical
183
+ }
184
+ }
185
+
186
+ const handleProceedToCheckout = async () => {
187
+ const countryCode = pathname.split('/')[1] || 'in'
188
+
189
+ if (customer && customer.addresses.length > 0) {
190
+ setIsRedirecting(true)
191
+ const defaultAddress = customer.addresses.find(a => a.is_default_shipping || a.metadata?.is_default === "true" || a.metadata?.is_default === true) || customer.addresses[0]
192
+
193
+ if (defaultAddress) {
194
+ const formData = new FormData()
195
+ formData.append("shipping_address.first_name", defaultAddress.first_name || "")
196
+ formData.append("shipping_address.last_name", defaultAddress.last_name || "")
197
+ formData.append("shipping_address.address_1", defaultAddress.address_1 || "")
198
+ formData.append("shipping_address.address_2", defaultAddress.address_2 || "")
199
+ formData.append("shipping_address.company", defaultAddress.company || "")
200
+ formData.append("shipping_address.postal_code", defaultAddress.postal_code || "")
201
+ formData.append("shipping_address.city", defaultAddress.city || "")
202
+ formData.append("shipping_address.country_code", defaultAddress.country_code || "")
203
+ formData.append("shipping_address.province", defaultAddress.province || "")
204
+ formData.append("shipping_address.phone", defaultAddress.phone || "")
205
+ formData.append("email", customer.email || "")
206
+ formData.append("same_as_billing", "on")
207
+
208
+ const { setAddresses } = await import("@core/data/cart")
209
+ await setAddresses(null, formData)
210
+ setIsRedirecting(false)
211
+
212
+ if (isOnCartPage) {
213
+ router.push(`/${countryCode}/checkout?step=payment`)
214
+ }
215
+ }
216
+ } else {
217
+ if (isOnCartPage) {
218
+ router.push(`/${countryCode}/checkout?step=payment`)
219
+ }
220
+ }
221
+ }
222
+
223
+ return (
224
+ <div className="bg-page-bg p-3 min-[550px]:p-4 sm:p-5 md:p-6 min-[1023px]:p-4 min-[1150px]:p-5 min-[1360px]:p-6 border border-[var(--color-border)] shadow-brand-sm w-full">
225
+ <ProcessingOverlay isOpen={showOverlay} variant={processingVariant} />
226
+ <h3 className="text-sm min-[550px]:text-base sm:text-lg min-[1023px]:text-base min-[1150px]:text-lg min-[1360px]:text-lg font-bold text-heading mb-2.5 min-[550px]:mb-3 sm:mb-4 min-[1023px]:mb-3 min-[1150px]:mb-4 min-[1360px]:mb-4">
227
+ PRICE SUMMARY ({itemCount} {itemCount === 1 ? "ITEM" : "ITEMS"})
228
+ </h3>
229
+
230
+ <div className="flex flex-col gap-y-2 min-[550px]:gap-y-2.5 sm:gap-y-3 min-[1023px]:gap-y-2 min-[1150px]:gap-y-3 min-[1360px]:gap-y-3 text-xs min-[550px]:text-sm sm:text-base min-[1023px]:text-sm min-[1150px]:text-base min-[1360px]:text-base text-body">
231
+ <div className="flex items-center justify-between">
232
+ <span>Total MRP</span>
233
+ <span data-testid="cart-mrp" data-value={totalMRP}>
234
+ {convertToLocale({ amount: totalMRP, currency_code })}
235
+ </span>
236
+ </div>
237
+
238
+ {calculatedDiscount > 0 && (
239
+ <div className="flex items-center justify-between">
240
+ <span>Discount</span>
241
+ <span
242
+ className="text-heading"
243
+ data-testid="cart-discount"
244
+ data-value={calculatedDiscount}
245
+ >
246
+ {convertToLocale({
247
+ amount: -calculatedDiscount,
248
+ currency_code,
249
+ })}
250
+ </span>
251
+ </div>
252
+ )}
253
+
254
+ <div className="flex items-center justify-between">
255
+ <span>GST</span>
256
+ <span data-testid="cart-taxes" data-value={gstAmount}>
257
+ {convertToLocale({ amount: gstAmount, currency_code })}
258
+ </span>
259
+ </div>
260
+
261
+ <div className="flex items-center justify-between">
262
+ <span>Shipping</span>
263
+ <span data-testid="cart-shipping" data-value={shippingAmount} className="flex items-center gap-x-2">
264
+ {isAutoSettingShipping && (
265
+ <span className="w-4 h-4 border-2 border-brand-accent border-t-transparent rounded-full animate-spin"></span>
266
+ )}
267
+ {convertToLocale({ amount: shippingAmount, currency_code })}
268
+ </span>
269
+ </div>
270
+ </div>
271
+
272
+ <div className="h-px w-full border-b border-[var(--color-border)] my-3 min-[550px]:my-4" />
273
+
274
+ <div className="flex items-center justify-between text-xs min-[550px]:text-sm sm:text-base min-[1023px]:text-sm min-[1150px]:text-base min-[1360px]:text-base font-bold text-heading mb-2.5 min-[550px]:mb-3 sm:mb-4 min-[1023px]:mb-3 min-[1150px]:mb-4 min-[1360px]:mb-4">
275
+ <span>Total</span>
276
+ <span
277
+ className="text-sm min-[550px]:text-base sm:text-lg min-[1023px]:text-base min-[1150px]:text-lg min-[1360px]:text-lg"
278
+ data-testid="cart-total"
279
+ data-value={finalTotal}
280
+ >
281
+ {convertToLocale({ amount: finalTotal, currency_code })}
282
+ </span>
283
+ </div>
284
+
285
+ {calculatedDiscount > 0 && (
286
+ <>
287
+ <div className="h-px w-full border-b border-dashed border-gray-300 my-2.5 min-[550px]:my-3 sm:my-4 min-[1023px]:my-3 min-[1150px]:my-4 min-[1360px]:my-4" />
288
+ <div className="text-center">
289
+ <p className="text-brand-success font-medium text-xs min-[550px]:text-sm sm:text-base min-[1023px]:text-sm min-[1150px]:text-base min-[1360px]:text-base">
290
+ 🎉 Yayy!!! You've saved {convertToLocale({ amount: calculatedDiscount, currency_code })}
291
+ </p>
292
+ </div>
293
+ </>
294
+ )}
295
+
296
+ {/* No manual continue button needed as we are in one-step mode */}
297
+ {isOnCartPage && (
298
+ <button
299
+ onClick={handleProceedToCheckout}
300
+ disabled={isRedirecting}
301
+ data-ga-event="proceed_to_checkout_click"
302
+ data-ga-label={convertToLocale({ amount: finalTotal, currency_code })}
303
+ className="w-full h-10 min-[550px]:h-11 sm:h-12 min-[1023px]:h-11 min-[1150px]:h-12 min-[1360px]:h-12 text-xs min-[550px]:text-sm sm:text-base min-[1023px]:text-sm min-[1150px]:text-base min-[1360px]:text-base text-inverse font-medium transition-colors duration-200 bg-brand-accent hover:bg-brand-accent-hover mt-3 min-[550px]:mt-4 sm:mt-6 min-[1023px]:mt-5 min-[1150px]:mt-6 min-[1360px]:mt-6 disabled:opacity-50"
304
+ data-testid="checkout-button"
305
+ >
306
+ {isRedirecting ? "Loading..." : "Proceed to Checkout"}
307
+ </button>
308
+ )}
309
+ {!isOnCartPage && (
310
+ <div className="w-full">
311
+ {activeStep === "delivery" || activeStep === "payment" || !((totals as any)?.shipping_address?.address_1) || pathname.includes("/checkout") ? (
312
+ <div className="flex flex-col gap-3 mt-3 min-[550px]:mt-4 sm:mt-6 min-[1023px]:mt-5 min-[1150px]:mt-6 min-[1360px]:mt-6">
313
+ {!isRedirecting ? (
314
+ (() => {
315
+ const isCheckoutReady =
316
+ ((totals as any).shipping_methods?.length > 0) &&
317
+ !!((totals as any).shipping_address?.address_1) &&
318
+ ((totals as any).shipping_address?.postal_code?.length >= 6);
319
+ const isPaymentDisabled = isAutoSettingShipping || !isCheckoutReady;
320
+
321
+ return (
322
+ <>
323
+ <button
324
+ onClick={async () => {
325
+ setProcessingVariant("order")
326
+ setShowOverlay(true)
327
+ setIsRedirecting(true)
328
+ try {
329
+ await syncLastEtdToCart()
330
+ const { initiatePaymentSession, placeOrder } = await import("@core/data/cart")
331
+ await initiatePaymentSession(totals as any, { provider_id: "pp_system_default" })
332
+ await placeOrder()
333
+ } catch (err: any) {
334
+ if (err.message === "NEXT_REDIRECT") {
335
+ throw err // Next.js needs this error to perform the redirect
336
+ }
337
+ setIsRedirecting(false)
338
+ setShowOverlay(false)
339
+ alert("Oops! Something went wrong with Cash on Delivery. " + err.message)
340
+ }
341
+ }}
342
+ disabled={isPaymentDisabled}
343
+ className={clx(
344
+ "w-full py-2.5 min-[550px]:py-3 text-xs min-[550px]:text-sm sm:text-base text-heading bg-surface border-2 font-bold transition-colors border-brand-accent",
345
+ {
346
+ "hover:bg-brand-accent-muted": !isPaymentDisabled,
347
+ "opacity-50 cursor-not-allowed": isPaymentDisabled
348
+ }
349
+ )}
350
+ >
351
+ Cash on Delivery
352
+ </button>
353
+ <button
354
+ onClick={async () => {
355
+ setProcessingVariant("payment")
356
+ setShowOverlay(true)
357
+ setIsRedirecting(true)
358
+ try {
359
+ await syncLastEtdToCart()
360
+ const { initiatePaymentSession, placeOrder } = await import("@core/data/cart")
361
+ const updatedCart: any = await initiatePaymentSession(totals as any, { provider_id: "pp_razorpay_razorpay" }).catch(() => initiatePaymentSession(totals as any, { provider_id: "razorpay" }))
362
+
363
+ const razorpaySession = updatedCart?.payment_collection?.payment_sessions?.find(
364
+ (s: any) => s.provider_id.includes("razorpay")
365
+ )
366
+ if (!razorpaySession?.data?.id) throw new Error("Could not initialize Razorpay")
367
+
368
+ // Load loadRazorpay dynamically so it resolves window.Razorpay
369
+ const useRazorpayMod = await import("react-razorpay")
370
+ const useRazorpay = useRazorpayMod.useRazorpay || useRazorpayMod.default?.useRazorpay || (globalThis as any).useRazorpay
371
+
372
+ // We must load via script if hook isn't directly invocable in this async context
373
+ // The safest pure JS way:
374
+ const script = document.createElement("script")
375
+ script.src = "https://checkout.razorpay.com/v1/checkout.js"
376
+ script.onload = () => {
377
+ const options = {
378
+ key: process.env.NEXT_PUBLIC_RAZORPAY_KEY ?? "",
379
+ amount: razorpaySession.amount,
380
+ order_id: razorpaySession.data.id,
381
+ currency: currency_code.toUpperCase(),
382
+ name: process.env.NEXT_PUBLIC_SHOP_NAME ?? "Chocomelon",
383
+ description: `Secure checkout for your order`,
384
+ handler: async function (response: any) {
385
+ await placeOrder().catch((err: any) => {
386
+ if (err.message === "NEXT_REDIRECT") throw err;
387
+ alert("Error placing order: " + err.message);
388
+ })
389
+ },
390
+ prefill: {
391
+ name: `${(totals as any).billing_address?.first_name || ""} ${(totals as any).billing_address?.last_name || ""}`,
392
+ email: (totals as any).email,
393
+ contact: (totals as any).shipping_address?.phone || (totals as any).billing_address?.phone || undefined,
394
+ },
395
+ theme: {
396
+ color: getComputedStyle(document.documentElement)
397
+ .getPropertyValue("--color-brand-accent")
398
+ .trim(),
399
+ },
400
+ modal: {
401
+ ondismiss: () => {
402
+ setIsRedirecting(false)
403
+ setShowOverlay(false)
404
+ }
405
+ }
406
+ }
407
+ const rzp = new (window as any).Razorpay(options)
408
+ rzp.on("payment.failed", function (response: any) {
409
+ setIsRedirecting(false)
410
+ setShowOverlay(false)
411
+ })
412
+ rzp.open()
413
+ }
414
+ document.body.appendChild(script)
415
+
416
+ } catch (err: any) {
417
+ setIsRedirecting(false)
418
+ setShowOverlay(false)
419
+ alert("Oops! Something went wrong with Razorpay. " + err.message)
420
+ }
421
+ }}
422
+ disabled={isPaymentDisabled}
423
+ className={clx(
424
+ "w-full py-2.5 min-[550px]:py-3 text-xs min-[550px]:text-sm sm:text-base text-inverse font-bold transition-colors bg-brand-accent",
425
+ {
426
+ "hover:bg-brand-accent-hover": !isPaymentDisabled,
427
+ "opacity-50 cursor-not-allowed": isPaymentDisabled
428
+ }
429
+ )}
430
+ >
431
+ Pay with Razorpay
432
+ </button>
433
+ </>
434
+ ); })()
435
+ ) : (
436
+ <button
437
+ disabled
438
+ className="w-full py-2.5 min-[550px]:py-3 text-xs min-[550px]:text-sm sm:text-base text-white font-bold rounded-lg bg-gray-400 opacity-50 cursor-not-allowed"
439
+ style={{ borderRadius: '30px' }}
440
+ >
441
+ Processing...
442
+ </button>
443
+ )}
444
+ </div>
445
+ ) : activeStep === "address" ? (
446
+ <button
447
+ onClick={() => {
448
+ window.dispatchEvent(new CustomEvent('trigger-checkout-step'))
449
+ }}
450
+ className="w-full py-2.5 min-[550px]:py-3 sm:py-4 min-[1023px]:py-3 min-[1150px]:py-4 min-[1360px]:py-4 text-xs min-[550px]:text-sm sm:text-base min-[1023px]:text-sm min-[1150px]:text-base min-[1360px]:text-base text-inverse font-medium mt-3 min-[550px]:mt-4 sm:mt-6 min-[1023px]:mt-5 min-[1150px]:mt-6 min-[1360px]:mt-6 transition-colors duration-200 bg-brand-accent hover:bg-brand-accent-hover"
451
+ data-testid="checkout-button-address"
452
+ >
453
+ Continue to delivery
454
+ </button>
455
+ ) : (
456
+ <button
457
+ onClick={handleProceedToCheckout}
458
+ disabled={isRedirecting}
459
+ data-ga-event="proceed_to_checkout_click"
460
+ data-ga-label={convertToLocale({ amount: finalTotal, currency_code })}
461
+ className="w-full h-10 min-[550px]:h-11 sm:h-12 min-[1023px]:h-11 min-[1150px]:h-12 min-[1360px]:h-12 text-xs min-[550px]:text-sm sm:text-base min-[1023px]:text-sm min-[1150px]:text-base min-[1360px]:text-base text-inverse font-medium transition-colors duration-200 bg-brand-accent hover:bg-brand-accent-hover mt-3 min-[550px]:mt-4 sm:mt-6 min-[1023px]:mt-5 min-[1150px]:mt-6 min-[1360px]:mt-6 disabled:opacity-50"
462
+ data-testid="checkout-button"
463
+ >
464
+ {isRedirecting ? "Loading..." : "Proceed to Checkout"}
465
+ </button>
466
+ )}
467
+ </div>
468
+ )}
469
+ </div>
470
+ )
471
+ }
472
+
473
+ export default CartTotals
@@ -0,0 +1,98 @@
1
+ import { Label } from "@medusajs/ui"
2
+ import React from "react"
3
+ import Color from "color"
4
+
5
+ type CheckboxProps = {
6
+ checked?: boolean
7
+ onChange?: () => void
8
+ label: string
9
+ name?: string
10
+ color?: string
11
+ hex?: string
12
+ 'data-testid'?: string
13
+ 'data-ga-event'?: string
14
+ 'data-ga-label'?: string
15
+ }
16
+
17
+ const CheckboxWithLabel: React.FC<CheckboxProps> = ({
18
+ checked = true,
19
+ onChange,
20
+ label,
21
+ name,
22
+ color,
23
+ hex,
24
+ 'data-testid': dataTestId,
25
+ 'data-ga-event': dataGaEvent,
26
+ 'data-ga-label': dataGaLabel
27
+ }) => {
28
+ const colorHex = React.useMemo(() => {
29
+ if (hex) return hex
30
+ if (!color) return null
31
+
32
+ try {
33
+ // Try parsing the original color name (handles things like "darkgreen")
34
+ return Color(color.toLowerCase().replace(/\s+/g, '')).hex()
35
+ } catch (e) {
36
+ try {
37
+ // Try parsing without modification (handles things like "rgb(0,0,0)")
38
+ return Color(color).hex()
39
+ } catch (e2) {
40
+ // Final fallback to the color string itself (might be a valid CSS name or hex already)
41
+ return color
42
+ }
43
+ }
44
+ }, [hex, color])
45
+
46
+ return (
47
+ <div className="flex items-center space-x-2 px-1 py-0.5">
48
+ <button
49
+ type="button"
50
+ role="checkbox"
51
+ aria-checked={checked}
52
+ onClick={onChange}
53
+ name={name}
54
+ data-testid={dataTestId}
55
+ data-ga-event={dataGaEvent}
56
+ data-ga-label={dataGaLabel}
57
+ className="w-5 h-5 rounded-md border-2 flex items-center justify-center transition-all focus:outline-none focus:ring-2 focus:ring-offset-2"
58
+ style={checked ? {
59
+ backgroundColor: '#8B5AB1',
60
+ borderColor: '#8B5AB1'
61
+ } : {
62
+ backgroundColor: 'white',
63
+ borderColor: '#C0C0C0'
64
+ }}
65
+ >
66
+ {checked && (
67
+ <svg
68
+ className="w-3 h-3 text-white"
69
+ fill="none"
70
+ strokeLinecap="round"
71
+ strokeLinejoin="round"
72
+ strokeWidth="2"
73
+ viewBox="0 0 24 24"
74
+ stroke="currentColor"
75
+ >
76
+ <path d="M5 13l4 4L19 7"></path>
77
+ </svg>
78
+ )}
79
+ </button>
80
+ <Label
81
+ htmlFor={name || "checkbox"}
82
+ className="!transform-none !txt-medium cursor-pointer flex items-center gap-2"
83
+ size="large"
84
+ onClick={onChange}
85
+ >
86
+ {colorHex && (
87
+ <div
88
+ className="w-4 h-4 rounded-full border border-gray-100 shadow-sm"
89
+ style={{ backgroundColor: colorHex }}
90
+ />
91
+ )}
92
+ {label}
93
+ </Label>
94
+ </div>
95
+ )
96
+ }
97
+
98
+ export default CheckboxWithLabel