@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,478 @@
1
+ "use client"
2
+
3
+ import { useEffect, useState } from "react"
4
+ import { HttpTypes } from "@medusajs/types"
5
+ import { Button, Heading, Text, Label, Input, clx } from "@medusajs/ui"
6
+ import { Plus, Trash } from "@medusajs/icons"
7
+ import { listPaymentDetails, createPaymentDetail, makeDefaultPaymentDetail, deletePaymentDetail } from "@core/data/payment-details"
8
+
9
+ // ✅ Matches backend validators exactly (strict mode)
10
+ // UPI: required = upi_id
11
+ type UpiForm = { upi_id: string }
12
+ // Bank: required = account_holder_name, bank_name, account_number, ifsc | optional = branch_name
13
+ type BankForm = { account_number: string; ifsc: string; account_holder_name: string; bank_name: string; branch_name: string }
14
+ // Card: required = card_holder_name, card_number, expiry_date, cvv
15
+ type CardForm = { card_holder_name: string; card_number: string; expiry_date: string; cvv: string }
16
+
17
+ // ✅ Regex for basic UPI validation (username@bank)
18
+ const UPI_REGEX = /^[a-zA-Z0-9.\-_]{2,256}@[a-zA-Z]{2,64}$/
19
+ // ✅ Regex for IFSC (11 chars, 4 letters, 0, then 6 alphanumeric)
20
+ const IFSC_REGEX = /^[A-Z]{4}0[A-Z0-9]{6}$/
21
+ // ✅ Regex for Bank Account Number (9-18 digits)
22
+ const ACCOUNT_NUMBER_REGEX = /^[0-9]{9,18}$/
23
+ // ✅ Regex for Card Number (12-19 digits)
24
+ const CARD_NUMBER_REGEX = /^[0-9]{12,19}$/
25
+ // ✅ Regex for CVV (3-4 digits)
26
+ const CVV_REGEX = /^[0-9]{3,4}$/
27
+
28
+ const defaultUpi: UpiForm = { upi_id: "" }
29
+ const defaultBank: BankForm = { account_number: "", ifsc: "", account_holder_name: "", bank_name: "", branch_name: "" }
30
+ const defaultCard: CardForm = { card_holder_name: "", card_number: "", expiry_date: "", cvv: "" }
31
+
32
+ export default function PaymentMethodsTemplate({ customer }: { customer: HttpTypes.StoreCustomer }) {
33
+ const [paymentMethods, setPaymentMethods] = useState<any[]>([])
34
+ const [isLoadingPayments, setIsLoadingPayments] = useState(true)
35
+ const [showAddPayment, setShowAddPayment] = useState(false)
36
+ const [newPaymentType, setNewPaymentType] = useState<"upi" | "bank" | "card">("upi")
37
+ const [upiForm, setUpiForm] = useState<UpiForm>(defaultUpi)
38
+ const [bankForm, setBankForm] = useState<BankForm>(defaultBank)
39
+ const [cardForm, setCardForm] = useState<CardForm>(defaultCard)
40
+ const [isAddingPayment, setIsAddingPayment] = useState(false)
41
+ const [error, setError] = useState<string | null>(null)
42
+
43
+ useEffect(() => {
44
+ fetchPaymentMethods()
45
+ }, [])
46
+
47
+ const fetchPaymentMethods = async () => {
48
+ setIsLoadingPayments(true)
49
+ try {
50
+ const methods = await listPaymentDetails()
51
+ setPaymentMethods(methods)
52
+ } catch (err) {
53
+ console.error(err)
54
+ } finally {
55
+ setIsLoadingPayments(false)
56
+ }
57
+ }
58
+
59
+ const resetForms = () => {
60
+ setUpiForm(defaultUpi)
61
+ setBankForm(defaultBank)
62
+ setCardForm(defaultCard)
63
+ }
64
+
65
+ const isFormValid = () => {
66
+ if (newPaymentType === "upi") {
67
+ const upiId = upiForm.upi_id.trim()
68
+ return !!upiId && UPI_REGEX.test(upiId)
69
+ }
70
+ if (newPaymentType === "bank") {
71
+ const ifsc = bankForm.ifsc.trim().toUpperCase()
72
+ const accNum = bankForm.account_number.trim()
73
+ return (
74
+ ACCOUNT_NUMBER_REGEX.test(accNum) &&
75
+ IFSC_REGEX.test(ifsc) &&
76
+ !!bankForm.bank_name.trim() &&
77
+ !!bankForm.account_holder_name.trim()
78
+ )
79
+ }
80
+ if (newPaymentType === "card") {
81
+ const cardNum = cardForm.card_number.trim().replace(/\s/g, "")
82
+ const cvv = cardForm.cvv.trim()
83
+ const expiry = cardForm.expiry_date.trim()
84
+
85
+ // Basic expiry check (MM/YY)
86
+ if (!/^\d{2}\/\d{2}$/.test(expiry)) return false
87
+ const [month, year] = expiry.split("/").map((n: string) => parseInt(n))
88
+ if (month < 1 || month > 12) return false
89
+
90
+ // Future date check
91
+ const now = new Date()
92
+ const currentYear = parseInt(now.getFullYear().toString().slice(-2))
93
+ const currentMonth = now.getMonth() + 1
94
+ if (year < currentYear || (year === currentYear && month < currentMonth)) return false
95
+
96
+ return (
97
+ CARD_NUMBER_REGEX.test(cardNum) &&
98
+ CVV_REGEX.test(cvv) &&
99
+ !!cardForm.card_holder_name.trim()
100
+ )
101
+ }
102
+ return false
103
+ }
104
+
105
+ const handleAddPayment = async () => {
106
+ setError(null)
107
+ setIsAddingPayment(true)
108
+ try {
109
+ let detailJson: Record<string, string> = {}
110
+
111
+ if (newPaymentType === "upi") {
112
+ detailJson = { upi_id: upiForm.upi_id.trim() }
113
+ }
114
+ if (newPaymentType === "bank") {
115
+ detailJson = {
116
+ account_number: bankForm.account_number.trim(),
117
+ bank_name: bankForm.bank_name.trim(),
118
+ account_holder_name: bankForm.account_holder_name.trim(),
119
+ ifsc: bankForm.ifsc.trim().toUpperCase()
120
+ }
121
+ if (bankForm.branch_name.trim()) detailJson.branch_name = bankForm.branch_name.trim()
122
+ }
123
+ if (newPaymentType === "card") {
124
+ detailJson = {
125
+ card_holder_name: cardForm.card_holder_name.trim(),
126
+ card_number: cardForm.card_number.trim(),
127
+ expiry_date: cardForm.expiry_date.trim(),
128
+ cvv: cardForm.cvv.trim()
129
+ }
130
+ }
131
+
132
+ const createRes = await createPaymentDetail(newPaymentType, detailJson)
133
+ if (createRes && createRes.payment_detail) {
134
+ if (paymentMethods.length === 0) {
135
+ await makeDefaultPaymentDetail(createRes.payment_detail.id)
136
+ createRes.payment_detail.is_default = true
137
+ }
138
+ setPaymentMethods([...paymentMethods, createRes.payment_detail])
139
+ setShowAddPayment(false)
140
+ resetForms()
141
+ }
142
+ } catch (err: any) {
143
+ console.error("Failed to add payment method", err)
144
+ setError(err.message || "Failed to add payment method. Please try again.")
145
+ } finally {
146
+ setIsAddingPayment(false)
147
+ }
148
+ }
149
+
150
+ const handleMakeDefault = async (id: string) => {
151
+ try {
152
+ await makeDefaultPaymentDetail(id)
153
+ setPaymentMethods(prev => prev.map(pm => ({
154
+ ...pm,
155
+ is_default: pm.id === id
156
+ })))
157
+ } catch (err) {
158
+ console.error(err)
159
+ }
160
+ }
161
+
162
+ const handleDelete = async (pm: any) => {
163
+ if (pm.is_default) {
164
+ setError("You cannot delete your default payment method. Please set another one as default first.")
165
+ return
166
+ }
167
+
168
+ if (!window.confirm("Are you sure you want to delete this payment method?")) {
169
+ return
170
+ }
171
+
172
+ try {
173
+ await deletePaymentDetail(pm.id)
174
+ setPaymentMethods(prev => prev.filter(p => p.id !== pm.id))
175
+ } catch (err: any) {
176
+ console.error("Failed to delete payment method", err)
177
+ setError(err.message || "Failed to delete payment method.")
178
+ }
179
+ }
180
+
181
+ return (
182
+ <div className="w-full">
183
+ <div className="mb-8 flex flex-col gap-y-4">
184
+ <Heading level="h1" className="text-2xl font-bold text-heading">Refund Settings</Heading>
185
+ <div className="bg-blue-50/50 border border-blue-100 p-4 rounded-2xl">
186
+ <Text className="text-sm text-blue-800 leading-relaxed">
187
+ <span className="font-bold block mb-1">Important Note:</span>
188
+ These details are <u>only</u> used to send money back to you when you return an item. For security, we do not use these methods for taking payments when you place an order.
189
+ </Text>
190
+ </div>
191
+ </div>
192
+
193
+ {error && (
194
+ <div className="mb-6 p-4 bg-red-50 border border-red-100 rounded-xl text-red-700 text-sm flex items-start gap-3">
195
+ <svg className="w-5 h-5 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
196
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
197
+ </svg>
198
+ <span className="font-medium">{error}</span>
199
+ </div>
200
+ )}
201
+
202
+ {isLoadingPayments ? (
203
+ <div className="animate-pulse flex flex-col gap-4">
204
+ <div className="bg-gray-100 h-24 rounded-2xl w-full"></div>
205
+ <div className="bg-gray-100 h-24 rounded-2xl w-full"></div>
206
+ </div>
207
+ ) : !showAddPayment ? (
208
+ <div className="space-y-6">
209
+ {paymentMethods.length > 0 ? (
210
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
211
+ {paymentMethods.map(pm => (
212
+ <div key={pm.id} className={`border-2 p-6 rounded-2xl flex flex-col justify-between items-start gap-4 transition-all ${pm.is_default ? 'border-brand-accent bg-brand-accent-muted/30' : 'border-gray-200 bg-white hover:border-gray-300'}`}>
213
+ <div className="flex flex-col gap-1">
214
+ <div className="flex items-center gap-3 mb-1">
215
+ <span className="font-bold text-heading uppercase">{pm.type}</span>
216
+ {pm.is_default && <span className="bg-brand-accent text-inverse text-[10px] font-bold px-2 py-0.5 rounded-full tracking-wide">DEFAULT</span>}
217
+ </div>
218
+ {pm.type === "upi" && (
219
+ <span className="text-gray-600 font-mono text-sm">{pm.detail_json?.upi_id}</span>
220
+ )}
221
+ {pm.type === "bank" && (
222
+ <>
223
+ <span className="text-heading font-semibold text-sm">{pm.detail_json?.bank_name}</span>
224
+ <span className="text-gray-600 font-mono text-sm">A/C: ****{pm.detail_json?.account_number?.slice(-4)}</span>
225
+ <span className="text-gray-400 text-xs">{pm.detail_json?.account_holder_name}</span>
226
+ <span className="text-gray-400 text-xs">IFSC: {pm.detail_json?.ifsc}</span>
227
+ </>
228
+ )}
229
+ {pm.type === "card" && (
230
+ <>
231
+ <span className="text-gray-600 font-mono text-sm">Card: **** {pm.detail_json?.card_number?.slice(-4)}</span>
232
+ <span className="text-gray-400 text-xs">{pm.detail_json?.card_holder_name}</span>
233
+ <span className="text-gray-400 text-xs font-mono">{pm.detail_json?.expiry_date}</span>
234
+ </>
235
+ )}
236
+ </div>
237
+
238
+ <div className="flex items-center justify-between w-full mt-auto">
239
+ {!pm.is_default ? (
240
+ <button
241
+ onClick={() => handleMakeDefault(pm.id)}
242
+ className="text-brand-accent text-sm font-medium hover:underline focus:outline-none"
243
+ >
244
+ Set as default
245
+ </button>
246
+ ) : (
247
+ <div />
248
+ )}
249
+
250
+ {!pm.is_default && (
251
+ <button
252
+ onClick={() => handleDelete(pm)}
253
+ className="text-gray-400 hover:text-red-500 transition-colors focus:outline-none p-1"
254
+ title="Delete payment method"
255
+ >
256
+ <Trash className="w-5 h-5" />
257
+ </button>
258
+ )}
259
+ </div>
260
+ </div>
261
+ ))}
262
+ </div>
263
+ ) : (
264
+ <div className="text-center p-10 border-2 border-dashed border-gray-200 rounded-3xl bg-gray-50/50">
265
+ <p className="text-gray-500 mb-2 font-semibold">No refund destination saved</p>
266
+ <p className="text-sm text-gray-400">Add your bank or UPI details to receive refunds directly to your account.</p>
267
+ </div>
268
+ )}
269
+
270
+ <Button
271
+ onClick={() => setShowAddPayment(true)}
272
+ variant="secondary"
273
+ className="w-full sm:w-auto mt-4 px-8 border-gray-200 shadow-sm rounded-full text-brand-accent hover:bg-brand-accent-muted/50 flex flex-row items-center gap-2"
274
+ >
275
+ <Plus className="w-4 h-4" /> Add refund destination
276
+ </Button>
277
+ </div>
278
+ ) : (
279
+ <div className="bg-white border text-heading border-gray-200 p-6 md:p-8 rounded-3xl shadow-sm space-y-6 animate-in fade-in slide-in-from-bottom-4">
280
+ <div className="flex items-center justify-between mb-2">
281
+ <h3 className="text-xl font-bold">Add Refund Account</h3>
282
+ <button onClick={() => { setShowAddPayment(false); resetForms() }} className="text-gray-400 hover:text-gray-600">
283
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
284
+ </button>
285
+ </div>
286
+
287
+ {/* Payment Type Selector */}
288
+ <div className="grid grid-cols-3 gap-3">
289
+ {(["upi", "bank", "card"] as const).map(type => (
290
+ <button
291
+ key={type}
292
+ type="button"
293
+ onClick={() => setNewPaymentType(type)}
294
+ className={`p-4 rounded-xl border flex flex-col items-center gap-2 transition-all ${newPaymentType === type ? 'border-brand-accent bg-brand-accent-muted text-brand-accent ring-2 ring-brand-accent-border ring-offset-1' : 'border-gray-200 bg-white text-gray-600 hover:bg-gray-50'}`}
295
+ >
296
+ <span className="font-semibold text-sm">{type === "bank" ? "Bank Account" : type === "card" ? "Card" : "UPI"}</span>
297
+ </button>
298
+ ))}
299
+ </div>
300
+
301
+ {/* ✅ UPI Form — only upi_id required */}
302
+ {newPaymentType === "upi" && (
303
+ <div className="space-y-4 pt-2">
304
+ <div className="space-y-2">
305
+ <Label className="font-medium text-gray-700">UPI ID <span className="text-red-500">*</span></Label>
306
+ <Input
307
+ required
308
+ value={upiForm.upi_id}
309
+ onChange={(e) => setUpiForm({ upi_id: e.target.value })}
310
+ placeholder="e.g. username@okaxis"
311
+ className={clx("bg-gray-50 focus:bg-white h-12 rounded-xl", {
312
+ "border-red-500 focus:border-red-600": upiForm.upi_id && !UPI_REGEX.test(upiForm.upi_id)
313
+ })}
314
+ />
315
+ {upiForm.upi_id && !UPI_REGEX.test(upiForm.upi_id) && (
316
+ <p className="text-[10px] text-red-500 font-bold uppercase mt-1">Please enter a valid UPI ID (e.g. name@bank)</p>
317
+ )}
318
+ </div>
319
+ </div>
320
+ )}
321
+
322
+ {/* ✅ Bank Form — account_number, bank_name, account_holder_name, ifsc required | branch_name optional */}
323
+ {newPaymentType === "bank" && (
324
+ <div className="space-y-4 pt-2">
325
+ <div className="space-y-2">
326
+ <Label className="font-medium text-gray-700">Bank Name <span className="text-red-500">*</span></Label>
327
+ <Input
328
+ required
329
+ value={bankForm.bank_name}
330
+ onChange={(e) => setBankForm({ ...bankForm, bank_name: e.target.value })}
331
+ placeholder="e.g. HDFC Bank"
332
+ className="bg-gray-50 focus:bg-white h-12 rounded-xl"
333
+ />
334
+ </div>
335
+ <div className="space-y-2">
336
+ <Label className="font-medium text-gray-700">Account Holder Name <span className="text-red-500">*</span></Label>
337
+ <Input
338
+ required
339
+ value={bankForm.account_holder_name}
340
+ onChange={(e) => setBankForm({ ...bankForm, account_holder_name: e.target.value })}
341
+ placeholder="e.g. Rahul Patel"
342
+ className="bg-gray-50 focus:bg-white h-12 rounded-xl"
343
+ />
344
+ </div>
345
+ <div className="space-y-2">
346
+ <Label className="font-medium text-gray-700">Account Number <span className="text-red-500">*</span></Label>
347
+ <Input
348
+ required
349
+ type="text"
350
+ inputMode="numeric"
351
+ value={bankForm.account_number}
352
+ onChange={(e) => setBankForm({ ...bankForm, account_number: e.target.value.replace(/\D/g, "") })}
353
+ placeholder="e.g. 123456789012"
354
+ className={clx("bg-gray-50 focus:bg-white h-12 rounded-xl", {
355
+ "border-red-500 focus:border-red-600": bankForm.account_number && !ACCOUNT_NUMBER_REGEX.test(bankForm.account_number)
356
+ })}
357
+ />
358
+ {bankForm.account_number && !ACCOUNT_NUMBER_REGEX.test(bankForm.account_number) && (
359
+ <p className="text-[10px] text-red-500 font-bold uppercase mt-1">Please enter a valid 9-18 digit account number</p>
360
+ )}
361
+ </div>
362
+ <div className="space-y-2">
363
+ <Label className="font-medium text-gray-700">IFSC Code <span className="text-red-500">*</span></Label>
364
+ <Input
365
+ required
366
+ value={bankForm.ifsc}
367
+ onChange={(e) => setBankForm({ ...bankForm, ifsc: e.target.value.toUpperCase() })}
368
+ placeholder="e.g. HDFC0001234"
369
+ className={clx("bg-gray-50 focus:bg-white h-12 rounded-xl", {
370
+ "border-red-500 focus:border-red-600": bankForm.ifsc && !IFSC_REGEX.test(bankForm.ifsc)
371
+ })}
372
+ />
373
+ {bankForm.ifsc && !IFSC_REGEX.test(bankForm.ifsc) && (
374
+ <p className="text-[10px] text-red-500 font-bold uppercase mt-1">Invalid IFSC (e.g. HDFC0001234)</p>
375
+ )}
376
+ </div>
377
+ <div className="space-y-2">
378
+ <Label className="font-medium text-gray-700">Branch Name <span className="text-gray-400 text-xs font-normal">(optional)</span></Label>
379
+ <Input
380
+ value={bankForm.branch_name}
381
+ onChange={(e) => setBankForm({ ...bankForm, branch_name: e.target.value })}
382
+ placeholder="e.g. Adajan Branch"
383
+ className="bg-gray-50 focus:bg-white h-12 rounded-xl"
384
+ />
385
+ </div>
386
+ </div>
387
+ )}
388
+
389
+ {/* ✅ Card Form — card_holder_name, card_number, expiry_date, cvv required */}
390
+ {newPaymentType === "card" && (
391
+ <div className="space-y-4 pt-2">
392
+ <div className="space-y-2">
393
+ <Label className="font-medium text-gray-700">Card Holder Name <span className="text-red-500">*</span></Label>
394
+ <Input
395
+ required
396
+ value={cardForm.card_holder_name}
397
+ onChange={(e) => setCardForm({ ...cardForm, card_holder_name: e.target.value })}
398
+ placeholder="e.g. Rahul Patel"
399
+ className="bg-gray-50 focus:bg-white h-12 rounded-xl"
400
+ />
401
+ </div>
402
+ <div className="space-y-2">
403
+ <Label className="font-medium text-gray-700">Card Number <span className="text-red-500">*</span></Label>
404
+ <Input
405
+ required
406
+ type="text"
407
+ inputMode="numeric"
408
+ value={cardForm.card_number}
409
+ onChange={(e) => {
410
+ let val = e.target.value.replace(/\D/g, "")
411
+ setCardForm({ ...cardForm, card_number: val })
412
+ }}
413
+ placeholder="e.g. 4242 4242 4242 4242"
414
+ className={clx("bg-gray-50 focus:bg-white h-12 rounded-xl", {
415
+ "border-red-500 focus:border-red-600": cardForm.card_number && !CARD_NUMBER_REGEX.test(cardForm.card_number)
416
+ })}
417
+ />
418
+ {cardForm.card_number && !CARD_NUMBER_REGEX.test(cardForm.card_number) && (
419
+ <p className="text-[10px] text-red-500 font-bold uppercase mt-1">Please enter a valid 12-19 digit card number</p>
420
+ )}
421
+ </div>
422
+ <div className="flex gap-4">
423
+ <div className="space-y-2 flex-1">
424
+ <Label className="font-medium text-gray-700">Expiry Date <span className="text-red-500">*</span></Label>
425
+ <Input
426
+ required
427
+ value={cardForm.expiry_date}
428
+ onChange={(e) => {
429
+ let val = e.target.value.replace(/\D/g, "")
430
+ if (val.length > 2) val = val.slice(0, 2) + "/" + val.slice(2, 4)
431
+ setCardForm({ ...cardForm, expiry_date: val.slice(0, 5) })
432
+ }}
433
+ placeholder="MM/YY"
434
+ className={clx("bg-gray-50 focus:bg-white h-12 rounded-xl", {
435
+ "border-red-500 focus:border-red-600": cardForm.expiry_date && (cardForm.expiry_date.length === 5 && !isFormValid())
436
+ })}
437
+ />
438
+ {cardForm.expiry_date && cardForm.expiry_date.length === 5 && !isFormValid() && (
439
+ <p className="text-[10px] text-red-500 font-bold uppercase mt-1">Invalid or Past Date</p>
440
+ )}
441
+ </div>
442
+ <div className="space-y-2 flex-1">
443
+ <Label className="font-medium text-gray-700">CVV <span className="text-red-500">*</span></Label>
444
+ <Input
445
+ required
446
+ type="password"
447
+ maxLength={4}
448
+ value={cardForm.cvv}
449
+ onChange={(e) => setCardForm({ ...cardForm, cvv: e.target.value.replace(/\D/g, "").slice(0, 4) })}
450
+ placeholder="***"
451
+ className={clx("bg-gray-50 focus:bg-white h-12 rounded-xl", {
452
+ "border-red-500 focus:border-red-600": cardForm.cvv && !CVV_REGEX.test(cardForm.cvv)
453
+ })}
454
+ />
455
+ {cardForm.cvv && !CVV_REGEX.test(cardForm.cvv) && (
456
+ <p className="text-[10px] text-red-500 font-bold uppercase mt-1">Invalid CVV</p>
457
+ )}
458
+ </div>
459
+ </div>
460
+ </div>
461
+ )}
462
+
463
+ <div className="flex gap-3 pt-2">
464
+ <Button
465
+ type="button"
466
+ isLoading={isAddingPayment}
467
+ onClick={handleAddPayment}
468
+ disabled={!isFormValid()}
469
+ className="flex-1 h-12 rounded-full bg-brand-accent hover:bg-brand-accent-hover text-inverse border-none font-bold"
470
+ >
471
+ Save Refund Details
472
+ </Button>
473
+ </div>
474
+ </div>
475
+ )}
476
+ </div>
477
+ )
478
+ }