@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,572 @@
1
+ "use client"
2
+
3
+ import { RadioGroup } from "@headlessui/react"
4
+ import { isStripeLike, paymentInfoMap, isRazorpay } from "@core/constants"
5
+ import { RazorpayPaymentButton } from "../payment-button/razorpay-payment-button"
6
+ import { initiatePaymentSession, placeOrder } from "@core/data/cart"
7
+ import ProcessingOverlay from "@modules/checkout/components/processing-overlay"
8
+ import { convertToLocale } from "@core/util/money"
9
+ import { CheckCircleSolid, CreditCard } from "@medusajs/icons"
10
+ import { Container, Heading, Text, clx } from "@medusajs/ui"
11
+ import ErrorMessage from "@modules/checkout/components/error-message"
12
+ import {
13
+ StripeCardContainer,
14
+ } from "@modules/checkout/components/payment-container"
15
+ import Divider from "@modules/common/components/divider"
16
+ import { useElements, useStripe } from "@stripe/react-stripe-js"
17
+ import { usePathname, useRouter, useSearchParams } from "next/navigation"
18
+ import { useCallback, useEffect, useState } from "react"
19
+
20
+ const Payment = ({
21
+ cart,
22
+ availablePaymentMethods,
23
+ }: {
24
+ cart: any
25
+ availablePaymentMethods: any[]
26
+ }) => {
27
+ const activeSession = cart.payment_collection?.payment_sessions?.find(
28
+ (paymentSession: any) => paymentSession.status === "pending"
29
+ )
30
+
31
+ const [isLoading, setIsLoading] = useState(false)
32
+ const [error, setError] = useState<string | null>(null)
33
+ const [cardBrand, setCardBrand] = useState<string | null>(null)
34
+ const [cardComplete, setCardComplete] = useState(false)
35
+ const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(
36
+ activeSession?.provider_id ?? ""
37
+ )
38
+
39
+ const searchParams = useSearchParams()
40
+ const router = useRouter()
41
+ const pathname = usePathname()
42
+
43
+ // Check if we're on the payment page or if step=payment query param exists
44
+ const isOnPaymentPage = pathname.includes("/checkout/payment")
45
+ const isReviewStep = searchParams.get("step") === "review"
46
+ const isOpen = (searchParams.get("step") === "payment" || isOnPaymentPage) && !isReviewStep
47
+
48
+ const setPaymentMethod = async (method: string) => {
49
+ setError(null)
50
+ setSelectedPaymentMethod(method)
51
+ if (isStripeLike(method) || isRazorpay(method)) {
52
+ await initiatePaymentSession(cart, {
53
+ provider_id: method,
54
+ })
55
+ }
56
+ }
57
+
58
+ const paidByGiftcard =
59
+ cart?.gift_cards && cart?.gift_cards?.length > 0 && cart?.total === 0
60
+
61
+ const paymentReady =
62
+ (activeSession && cart?.shipping_methods.length !== 0) || paidByGiftcard
63
+
64
+ const createQueryString = useCallback(
65
+ (name: string, value: string) => {
66
+ const params = new URLSearchParams(searchParams)
67
+ params.set(name, value)
68
+
69
+ return params.toString()
70
+ },
71
+ [searchParams]
72
+ )
73
+
74
+ const handleEdit = () => {
75
+ router.push(pathname + "?" + createQueryString("step", "payment"), {
76
+ scroll: false,
77
+ })
78
+ }
79
+
80
+ useEffect(() => {
81
+ setError(null)
82
+ }, [isOpen])
83
+
84
+ // Scroll to top on mount
85
+ useEffect(() => {
86
+ window.scrollTo({ top: 0, behavior: 'instant' as ScrollBehavior })
87
+ }, [])
88
+
89
+ // Get cart total for Pay button
90
+ const cartTotal = cart?.total || 0
91
+ const currencyCode = cart?.currency_code || "INR"
92
+
93
+ return (
94
+ <div className="bg-page-bg" >
95
+ <div className={clx("flex flex-row items-center justify-between", { "mb-6": !isOpen && paymentReady, "hidden": isOpen })}>
96
+ <Heading
97
+ level="h2"
98
+ className="flex flex-row text-3xl-regular gap-x-2 items-baseline hidden"
99
+ >
100
+ {!isOpen && paymentReady && <CheckCircleSolid />}
101
+ </Heading>
102
+ {!isOpen && paymentReady && (
103
+ <Text>
104
+ <button
105
+ onClick={handleEdit}
106
+ className="text-ui-fg-interactive hover:text-ui-fg-interactive-hover"
107
+ data-testid="edit-payment-button"
108
+ >
109
+ Edit
110
+ </button>
111
+ </Text>
112
+ )}
113
+ </div>
114
+ <div>
115
+ <div className={isOpen ? "block" : "hidden"}>
116
+ {/* Smart Promotion Display - Dynamic based on count */}
117
+ {cart.promotions && cart.promotions.length === 1 && (
118
+ <div className="rounded-xl p-3 min-[550px]:p-4 mb-5 border border-brand-accent-border shadow-sm transition-all text-left" style={{ backgroundColor: 'var(--color-brand-accent-muted)' }}>
119
+ {cart.promotions.map((promotion: any) => {
120
+ const isPercentage = promotion.application_method?.type === "percentage"
121
+ const discountValue = promotion.application_method?.value
122
+ return (
123
+ <div key={promotion.id}>
124
+ <div className="flex items-center justify-between gap-3">
125
+ <div className="flex items-center gap-3">
126
+ <div className="w-11 h-11 min-[550px]:w-14 min-[550px]:h-14 rounded-full bg-white flex items-center justify-center flex-shrink-0 shadow-sm border border-brand-accent-border p-1">
127
+ <span className={clx("font-bold text-brand-accent text-center leading-tight", isPercentage ? "text-base min-[550px]:text-lg" : "text-[11px] min-[550px]:text-sm")}>
128
+ {isPercentage ? `${discountValue}%` : convertToLocale({ amount: discountValue || 0, currency_code: cart.region?.currency_code })}
129
+ </span>
130
+ </div>
131
+ <div>
132
+ <div className="flex items-center gap-2">
133
+ <Heading level="h3" className="text-sm min-[550px]:text-base font-bold text-heading leading-tight">Offer Applied</Heading>
134
+ <span className="bg-brand-accent-muted text-brand-accent text-[10px] px-2 py-0.5 rounded font-bold uppercase">{promotion.code}</span>
135
+ </div>
136
+ <Text className="text-xs text-gray-500 mt-1 leading-tight">Savings applied to your cart</Text>
137
+ </div>
138
+ </div>
139
+ <div className="text-right flex-shrink-0">
140
+ <Text className="text-[10px] font-bold text-gray-400 uppercase tracking-wider">You Saved</Text>
141
+ <Text className="text-lg min-[550px]:text-xl font-black text-brand-accent leading-none">
142
+ {convertToLocale({ amount: cart.discount_total || 0, currency_code: cart.region?.currency_code })}
143
+ </Text>
144
+ </div>
145
+ </div>
146
+ <div className="mt-3 pt-3 border-t border-brand-accent-border">
147
+ <div className="flex items-center gap-1.5">
148
+ <div className="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse"></div>
149
+ <Text className="text-[10px] font-semibold text-green-600 uppercase tracking-wide">Best value applied</Text>
150
+ </div>
151
+ </div>
152
+ </div>
153
+ )
154
+ })}
155
+ </div>
156
+ )}
157
+
158
+ {cart.promotions && cart.promotions.length > 1 && (
159
+ <div className="rounded-xl p-3 mb-5 border border-brand-accent-border shadow-sm transition-all text-left" style={{ backgroundColor: 'var(--color-brand-accent-muted)' }}>
160
+ <div className="flex items-center justify-between gap-3">
161
+ <div className="flex items-center gap-2.5 text-left">
162
+ <div className="w-9 h-9 rounded-full bg-white flex items-center justify-center flex-shrink-0 shadow-sm border border-brand-accent-border">
163
+ <span className="text-lg font-bold text-brand-accent">%</span>
164
+ </div>
165
+ <div>
166
+ <Heading level="h3" className="text-sm font-bold text-heading leading-tight">Offers Applied</Heading>
167
+ <div className="flex flex-wrap gap-1.5 mt-1">
168
+ {cart.promotions.map((p: any) => (
169
+ <span key={p.id} className="bg-brand-accent-muted text-brand-accent text-[10px] px-2 py-0.5 rounded font-bold uppercase">{p.code}</span>
170
+ ))}
171
+ </div>
172
+ </div>
173
+ </div>
174
+ <div className="text-right flex-shrink-0">
175
+ <Text className="text-[10px] font-bold text-gray-400 uppercase tracking-tight">Total Saved</Text>
176
+ <Text className="text-lg min-[550px]:text-xl font-black text-brand-accent leading-none">
177
+ {convertToLocale({ amount: cart.discount_total || 0, currency_code: cart.region?.currency_code })}
178
+ </Text>
179
+ </div>
180
+ </div>
181
+ <div className="mt-3 pt-3 border-t border-brand-accent-border space-y-2.5 text-left">
182
+ {cart.promotions.map((promotion: any) => {
183
+ const isPercentage = promotion.application_method?.type === "percentage"
184
+ const discountValue = promotion.application_method?.value
185
+ return (
186
+ <div key={promotion.id} className="flex items-center justify-between text-xs">
187
+ <div className="flex flex-col">
188
+ <span className="font-bold text-gray-700 leading-tight">{promotion.is_automatic ? "Offer Applied" : `Coupon: ${promotion.code}`}</span>
189
+ <span className="text-gray-500 font-medium leading-tight text-[10px]">Savings added to your cart</span>
190
+ </div>
191
+ <div className="bg-white px-2 py-1 rounded border border-brand-accent-border font-bold text-brand-accent shadow-sm ml-4 whitespace-nowrap">
192
+ {isPercentage ? `${discountValue}% Off` : convertToLocale({ amount: discountValue || 0, currency_code: cart.region?.currency_code }) + " Off"}
193
+ </div>
194
+ </div>
195
+ )
196
+ })}
197
+ </div>
198
+ <div className="mt-3 pt-2.5 border-t border-brand-accent-border">
199
+ <div className="flex items-center gap-1.5 text-left">
200
+ <div className="w-1 h-1 rounded-full bg-green-500"></div>
201
+ <Text className="text-[10px] font-semibold text-green-600 uppercase tracking-tight">Best value applied</Text>
202
+ </div>
203
+ </div>
204
+ </div>
205
+ )}
206
+
207
+ {/* Payment Options Section - Only show when methods are available */}
208
+ {availablePaymentMethods && availablePaymentMethods.length > 0 && (
209
+ <>
210
+ <Heading level="h3" className="text-lg min-[550px]:text-xl font-bold mb-3 min-[550px]:mb-4">
211
+ Choose Payment Mode
212
+ </Heading>
213
+
214
+ {!paidByGiftcard && (
215
+ <div className="flex flex-col min-[768px]:flex-row gap-4 min-[550px]:gap-5 sm:gap-6">
216
+ {/* Left Side - Payment Options Navigation */}
217
+ <div className="w-full min-[768px]:w-64 min-[768px]:flex-shrink-0">
218
+ <RadioGroup
219
+ value={selectedPaymentMethod}
220
+ onChange={(value: string) => setPaymentMethod(value)}
221
+ className="flex flex-col gap-2"
222
+ >
223
+ {availablePaymentMethods.map((paymentMethod) => (
224
+ <RadioGroup.Option
225
+ key={paymentMethod.id}
226
+ value={paymentMethod.id}
227
+ className={({ checked }) => clx(
228
+ "text-left p-3 min-[550px]:p-4 rounded-lg border-2 transition-all w-full cursor-pointer outline-none",
229
+ {
230
+ "border-brand-accent bg-brand-accent-muted": checked,
231
+ "border-gray-200 hover:border-gray-300": !checked,
232
+ }
233
+ )}
234
+ >
235
+ {({ checked }) => (
236
+ <div className="flex items-center gap-2 min-[550px]:gap-3">
237
+ <div className={clx(
238
+ "w-4 h-4 min-[550px]:w-5 min-[550px]:h-5 rounded-full border-2 flex items-center justify-center flex-shrink-0",
239
+ {
240
+ "border-brand-accent": checked,
241
+ "border-gray-300": !checked,
242
+ }
243
+ )}>
244
+ {checked && (
245
+ <div className="w-2 h-2 min-[550px]:w-3 min-[550px]:h-3 rounded-full bg-brand-accent"></div>
246
+ )}
247
+ </div>
248
+ <div className="flex items-center gap-2 flex-1 min-w-0">
249
+ <span className="text-base min-[550px]:text-lg flex-shrink-0">
250
+ {paymentInfoMap[paymentMethod.id]?.icon || <CreditCard />}
251
+ </span>
252
+ <Text className="text-xs min-[550px]:text-sm font-medium truncate">
253
+ {paymentInfoMap[paymentMethod.id]?.title || paymentMethod.id}
254
+ </Text>
255
+ </div>
256
+ </div>
257
+ )}
258
+ </RadioGroup.Option>
259
+ ))}
260
+ </RadioGroup>
261
+ </div>
262
+
263
+ {/* Right Side - Selected Payment Details */}
264
+ <div className="flex-1 min-w-0 max-w-[440px] w-full min-[768px]:ml-20">
265
+ {selectedPaymentMethod && (
266
+ <div className="bg-page-bg rounded-lg p-4 min-[550px]:p-5 sm:p-6 border shadow-sm" style={{ borderColor: 'var(--color-border)' }}>
267
+ {isStripeLike(selectedPaymentMethod) ? (
268
+ <StripeCardContainer
269
+ paymentProviderId={selectedPaymentMethod}
270
+ selectedPaymentOptionId={selectedPaymentMethod}
271
+ paymentInfoMap={paymentInfoMap}
272
+ setCardBrand={setCardBrand}
273
+ setError={setError}
274
+ setCardComplete={setCardComplete}
275
+ />
276
+ ) : (
277
+ <div>
278
+ {selectedPaymentMethod.includes("manual") || selectedPaymentMethod.includes("system") ? (
279
+ <div className="flex flex-col">
280
+ <Heading level="h3" className="text-lg font-bold text-heading mb-6">
281
+ Cash On Delivery (Cash/UPI)
282
+ </Heading>
283
+
284
+ <div className="flex flex-col gap-y-1">
285
+ <div className="flex items-center justify-between w-full">
286
+ <div className="flex items-center gap-3">
287
+ <div className="w-5 h-5 rounded-full border-2 border-brand-accent flex items-center justify-center flex-shrink-0">
288
+ <div className="w-3 h-3 rounded-full bg-brand-accent"></div>
289
+ </div>
290
+ <Text className="text-base font-bold text-heading">
291
+ Cash on Delivery (Cash/UPI)
292
+ </Text>
293
+ </div>
294
+ <div className="text-2xl opacity-70">
295
+ <svg width="28" height="20" viewBox="0 0 28 20" fill="none" xmlns="http://www.w3.org/2000/svg">
296
+ <rect x="0.5" y="0.5" width="23" height="15" rx="1.5" stroke="#333" />
297
+ <circle cx="12" cy="8" r="3.5" stroke="#333" />
298
+ <path d="M4 4L6 4M21 12H19" stroke="#333" strokeWidth="1.5" />
299
+ <rect x="3.5" y="3.5" width="23" height="15" rx="1.5" stroke="#333" />
300
+ <circle cx="15" cy="11" r="3" stroke="#333" />
301
+ <path d="M14 11H16M15 10V12" stroke="#333" strokeWidth="0.5" />
302
+ <path d="M15 11C15 11.5523 14.5523 12 14 12C13.4477 12 13 11.5523 13 11C13 10.4477 13.4477 10 14 10C14.5523 10 15 10.4477 15 11Z" fill="#333" />
303
+ <text x="14" y="11.5" fontSize="4" textAnchor="middle" fill="#333" style={{ fontSize: '3px', fontWeight: 'bold' }}>₹</text>
304
+ </svg>
305
+ </div>
306
+ </div>
307
+ <Text className="text-sm text-gray-500 ml-8">
308
+ You can pay via Cash/UPI on delivery.
309
+ </Text>
310
+ </div>
311
+ </div>
312
+ ) : (
313
+ <div>
314
+ <div className="flex items-center gap-2 min-[550px]:gap-3 mb-3 min-[550px]:mb-4">
315
+ <div className="w-4 h-4 min-[550px]:w-5 min-[550px]:h-5 rounded-full border-2 border-brand-accent flex items-center justify-center flex-shrink-0">
316
+ <div className="w-2 h-2 min-[550px]:w-3 min-[550px]:h-3 rounded-full bg-brand-accent"></div>
317
+ </div>
318
+ <Text className="text-base min-[550px]:text-lg font-semibold">
319
+ {paymentInfoMap[selectedPaymentMethod]?.title || selectedPaymentMethod}
320
+ </Text>
321
+ </div>
322
+ <Text className="text-sm min-[550px]:text-base text-gray-600">
323
+ {paymentInfoMap[selectedPaymentMethod]?.title || "Payment method selected"}
324
+ </Text>
325
+ </div>
326
+ )}
327
+ </div>
328
+ )}
329
+
330
+ <ErrorMessage
331
+ error={error}
332
+ data-testid="payment-method-error-message"
333
+ />
334
+
335
+ {isStripeLike(selectedPaymentMethod) ? (
336
+ activeSession?.provider_id === selectedPaymentMethod ? (
337
+ <StripeButton
338
+ cart={cart}
339
+ activeSession={activeSession}
340
+ selectedPaymentMethod={selectedPaymentMethod}
341
+ cardComplete={cardComplete}
342
+ cartTotal={cartTotal}
343
+ currencyCode={currencyCode}
344
+ setError={setError}
345
+ />
346
+ ) : (
347
+ <button
348
+ disabled
349
+ className="w-full py-2 min-[550px]:py-2.5 px-4 min-[550px]:px-6 rounded-full font-semibold text-base transition-all mt-6 shadow-sm bg-gray-200 text-gray-400 cursor-not-allowed"
350
+ >
351
+ Pay with Stripe
352
+ </button>
353
+ )
354
+ ) : isRazorpay(selectedPaymentMethod) ? (
355
+ activeSession?.provider_id === selectedPaymentMethod ? (
356
+ <div className="mt-6" onClick={() => {
357
+ // Dispatch event to save address before Razorpay opens
358
+ window.dispatchEvent(new CustomEvent('submit-address-for-payment'))
359
+ }}>
360
+ <RazorpayPaymentButton
361
+ session={activeSession}
362
+ notReady={false}
363
+ cart={cart}
364
+ />
365
+ </div>
366
+ ) : (
367
+ <button
368
+ disabled
369
+ className="w-full py-2 min-[550px]:py-2.5 px-4 min-[550px]:px-6 rounded-full font-semibold text-base transition-all mt-6 shadow-sm bg-gray-200 text-gray-400 cursor-not-allowed"
370
+ >
371
+ Pay with Razorpay
372
+ </button>
373
+ )
374
+ ) : (
375
+ <ManualButton
376
+ cart={cart}
377
+ activeSession={activeSession}
378
+ selectedPaymentMethod={selectedPaymentMethod}
379
+ cartTotal={cartTotal}
380
+ currencyCode={currencyCode}
381
+ setError={setError}
382
+ />
383
+ )}
384
+ </div>
385
+ )}
386
+ </div>
387
+ </div>
388
+ )}
389
+ </>
390
+ )}
391
+ </div>
392
+ </div>
393
+ </div>
394
+ )
395
+ }
396
+
397
+ // Sub-component for Stripe Button to safely use Stripe hooks
398
+ const StripeButton = ({
399
+ cart,
400
+ activeSession,
401
+ selectedPaymentMethod,
402
+ cardComplete,
403
+ cartTotal,
404
+ currencyCode,
405
+ setError
406
+ }: any) => {
407
+ const [isLoading, setIsLoading] = useState(false)
408
+ const stripe = useStripe()
409
+ const elements = useElements()
410
+
411
+ const handleStripePayment = async () => {
412
+ setIsLoading(true)
413
+ setError(null)
414
+
415
+ try {
416
+ let currentSession = activeSession
417
+ if (activeSession?.provider_id !== selectedPaymentMethod) {
418
+ const updatedCart = await initiatePaymentSession(cart, {
419
+ provider_id: selectedPaymentMethod,
420
+ })
421
+ currentSession = updatedCart.payment_collection?.payment_sessions?.find(
422
+ (s: any) => s.provider_id === selectedPaymentMethod
423
+ )
424
+ }
425
+
426
+ const card = elements?.getElement("card")
427
+ if (!stripe || !elements || !card || !currentSession) {
428
+ throw new Error("Stripe is not initialized or session is missing")
429
+ }
430
+
431
+ const { error: stripeError, paymentIntent } = await stripe.confirmCardPayment(
432
+ currentSession.data.client_secret as string,
433
+ {
434
+ payment_method: {
435
+ card: card,
436
+ billing_details: {
437
+ name: `${cart.billing_address?.first_name} ${cart.billing_address?.last_name}`,
438
+ email: cart.email,
439
+ phone: cart.billing_address?.phone || undefined,
440
+ address: {
441
+ city: cart.billing_address?.city || undefined,
442
+ country: cart.billing_address?.country_code || undefined,
443
+ line1: cart.billing_address?.address_1 || undefined,
444
+ line2: cart.billing_address?.address_2 || undefined,
445
+ postal_code: cart.billing_address?.postal_code || undefined,
446
+ state: cart.billing_address?.province || undefined,
447
+ },
448
+ },
449
+ },
450
+ }
451
+ )
452
+
453
+ if (stripeError) {
454
+ throw new Error(stripeError.message)
455
+ }
456
+
457
+ if (paymentIntent?.status === "succeeded" || paymentIntent?.status === "requires_capture") {
458
+ await placeOrder()
459
+ }
460
+ } catch (err: any) {
461
+ if (err.message === "NEXT_REDIRECT") {
462
+ return
463
+ }
464
+ setError(err.message)
465
+ setIsLoading(false)
466
+ }
467
+ }
468
+
469
+ return (
470
+ <>
471
+ <ProcessingOverlay isOpen={isLoading} variant="payment" />
472
+ <button
473
+ onClick={handleStripePayment}
474
+ disabled={isLoading || !cardComplete}
475
+ className={clx(
476
+ "w-full py-2 min-[550px]:py-2.5 px-4 min-[550px]:px-6 rounded-full font-semibold text-base transition-all mt-6 shadow-sm",
477
+ {
478
+ "bg-brand-accent text-inverse hover:bg-brand-accent-hover": !isLoading && cardComplete,
479
+ "bg-gray-300 text-gray-500 cursor-not-allowed": isLoading || !cardComplete,
480
+ }
481
+ )}
482
+ >
483
+ {isLoading ? "Processing..." : !cardComplete ? "Enter card details" : `Pay now ${convertToLocale({ amount: cartTotal, currency_code: currencyCode })}`}
484
+ </button>
485
+ </>
486
+ )
487
+ }
488
+
489
+ // Sub-component for Manual Button
490
+ const ManualButton = ({
491
+ cart,
492
+ activeSession,
493
+ selectedPaymentMethod,
494
+ cartTotal,
495
+ currencyCode,
496
+ setError
497
+ }: any) => {
498
+ const [isLoading, setIsLoading] = useState(false)
499
+
500
+ const handleManualPayment = async () => {
501
+ setIsLoading(true)
502
+ setError(null)
503
+
504
+ try {
505
+ // 1. Final Handshake: Save all address data from DOM to server explicitly
506
+ const firstNameInput = document.getElementById("shipping_first_name_field") as HTMLInputElement
507
+ const lastNameInput = document.getElementById("shipping_last_name_field") as HTMLInputElement
508
+ const address1Input = document.getElementById("shipping_address_1_field") as HTMLInputElement
509
+ const companyInput = document.getElementById("shipping_company_field") as HTMLInputElement
510
+ const cityInput = document.getElementById("shipping_city_field") as HTMLInputElement
511
+ const provinceInput = document.getElementById("shipping_province_field") as HTMLInputElement
512
+ const postalInput = document.getElementById("shipping_postal_code_field") as HTMLInputElement
513
+ const phoneInput = document.getElementById("shipping_phone_field_internal") as HTMLInputElement
514
+ const emailInput = document.getElementById("shipping_email_field") as HTMLInputElement
515
+
516
+ const { updateAddressSilently } = await import("@core/data/cart")
517
+ await updateAddressSilently({
518
+ email: emailInput?.value || cart?.email || "",
519
+ shipping_address: {
520
+ first_name: firstNameInput?.value || cart?.shipping_address?.first_name || "Visitor",
521
+ last_name: lastNameInput?.value || cart?.shipping_address?.last_name || "Customer",
522
+ address_1: address1Input?.value || cart?.shipping_address?.address_1 || "",
523
+ company: companyInput?.value || cart?.shipping_address?.company || "",
524
+ city: cityInput?.value || cart?.shipping_address?.city || "",
525
+ province: provinceInput?.value || cart?.shipping_address?.province || "",
526
+ postal_code: postalInput?.value || cart?.shipping_address?.postal_code || "",
527
+ phone: phoneInput?.value || cart?.shipping_address?.phone || "",
528
+ country_code: cart?.shipping_address?.country_code || "in",
529
+ }
530
+ })
531
+
532
+ if (activeSession?.provider_id !== selectedPaymentMethod) {
533
+ await initiatePaymentSession(cart, {
534
+ provider_id: selectedPaymentMethod,
535
+ })
536
+ }
537
+
538
+ await placeOrder()
539
+ } catch (err: any) {
540
+ if (err.message === "NEXT_REDIRECT") {
541
+ return
542
+ }
543
+ setError(err.message)
544
+ setIsLoading(false)
545
+ }
546
+ }
547
+
548
+ const isCOD = selectedPaymentMethod.includes("manual") || selectedPaymentMethod.includes("system")
549
+
550
+ return (
551
+ <>
552
+ <ProcessingOverlay isOpen={isLoading} variant="order" />
553
+ <button
554
+ onClick={handleManualPayment}
555
+ disabled={isLoading}
556
+ className={clx(
557
+ "w-full py-2 min-[550px]:py-2.5 px-4 min-[550px]:px-6 rounded-full font-semibold text-base transition-all mt-6 shadow-sm",
558
+ {
559
+ "bg-brand-accent text-inverse hover:bg-brand-accent-hover": !isLoading,
560
+ "bg-gray-300 text-gray-500 cursor-not-allowed": isLoading,
561
+ }
562
+ )}
563
+ data-ga-event="cod_payment_click"
564
+ data-ga-label="Continue to process"
565
+ >
566
+ {isLoading ? "Processing..." : isCOD ? "Continue to process" : `Pay now ${convertToLocale({ amount: cartTotal, currency_code: currencyCode })}`}
567
+ </button>
568
+ </>
569
+ )
570
+ }
571
+
572
+ export default Payment