@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,156 @@
1
+ "use client"
2
+
3
+ import { deleteLineItem } from "@core/data/cart"
4
+ import { addToWishlist } from "@core/data/wishlist"
5
+ import { Spinner, Trash } from "@medusajs/icons"
6
+ import { clx, Button, Heading, Text } from "@medusajs/ui"
7
+ import Modal from "@modules/common/components/modal"
8
+ import { useState } from "react"
9
+ import { useWishlist } from "@core/context/wishlist-context"
10
+
11
+ import Image from "next/image"
12
+ import X from "@modules/common/icons/x"
13
+
14
+ const DeleteButton = ({
15
+ id,
16
+ productId,
17
+ thumbnail,
18
+ children,
19
+ className,
20
+ onAfterDelete,
21
+ "data-testid": dataTestId,
22
+ }: {
23
+ id: string
24
+ productId?: string
25
+ thumbnail?: string | null
26
+ children?: React.ReactNode
27
+ className?: string
28
+ onAfterDelete?: () => void
29
+ "data-testid"?: string
30
+ }) => {
31
+ const [isDeleting, setIsDeleting] = useState(false)
32
+ const [showModal, setShowModal] = useState(false)
33
+ const [wishlistLoading, setWishlistLoading] = useState(false)
34
+ const [error, setError] = useState<string | null>(null)
35
+ const { refreshWishlist } = useWishlist()
36
+
37
+ const handleDelete = async () => {
38
+ setIsDeleting(true)
39
+ setShowModal(false)
40
+ try {
41
+ await deleteLineItem(id)
42
+ onAfterDelete?.()
43
+ } catch {
44
+ // keep isDeleting false on error
45
+ } finally {
46
+ setIsDeleting(false)
47
+ }
48
+ }
49
+
50
+ const handleMoveToWishlist = async () => {
51
+ if (!productId) {
52
+ handleDelete()
53
+ return
54
+ }
55
+
56
+ setWishlistLoading(true)
57
+ setError(null)
58
+
59
+ const result = await addToWishlist(productId)
60
+
61
+ if (result.success) {
62
+ await refreshWishlist()
63
+ await handleDelete()
64
+ } else {
65
+ setError(result.error || "Please login to move items to wishlist.")
66
+ setWishlistLoading(false)
67
+ }
68
+ }
69
+
70
+ return (
71
+ <>
72
+ <div
73
+ className={clx(
74
+ "flex items-center justify-between text-small-regular",
75
+ className
76
+ )}
77
+ >
78
+ <button
79
+ className="flex gap-x-1 text-ui-fg-subtle hover:text-ui-fg-base cursor-pointer items-center"
80
+ onClick={() => setShowModal(true)}
81
+ data-testid={dataTestId}
82
+ >
83
+ {isDeleting ? <Spinner className="animate-spin" /> : <Trash />}
84
+ <span>{children}</span>
85
+ </button>
86
+ </div>
87
+
88
+ <Modal isOpen={showModal} close={() => setShowModal(false)} size="medium">
89
+ <div className="flex flex-col bg-white overflow-hidden rounded-sm relative">
90
+ {/* Close Icon */}
91
+ <button
92
+ onClick={() => setShowModal(false)}
93
+ className="absolute top-4 right-4 text-black hover:opacity-70 transition-opacity z-10"
94
+ >
95
+ <X size={24} />
96
+ </button>
97
+
98
+ {/* Body Content */}
99
+ <div className="p-6 flex gap-6 pr-12">
100
+ {/* Product Thumbnail */}
101
+ <div className="w-24 h-24 sm:w-28 sm:h-28 flex-shrink-0 bg-gray-50 rounded-sm overflow-hidden border border-gray-100 shadow-sm">
102
+ {thumbnail ? (
103
+ <Image
104
+ src={thumbnail}
105
+ alt="Product"
106
+ width={120}
107
+ height={120}
108
+ className="w-full h-full object-cover"
109
+ />
110
+ ) : (
111
+ <div className="w-full h-full flex items-center justify-center text-gray-300 bg-gray-50 uppercase text-[10px] font-bold">No Image</div>
112
+ )}
113
+ </div>
114
+
115
+ {/* Title and Description */}
116
+ <div className="flex flex-col justify-center">
117
+ <h3 className="text-[17px] font-bold text-gray-800 mb-1.5 leading-tight">Move from Bag</h3>
118
+ <p className="text-[15px] text-gray-500 leading-snug font-medium max-w-[280px]">
119
+ Are you sure you want to move this item from bag?
120
+ </p>
121
+
122
+ {error && (
123
+ <p className="text-red-500 text-[11px] font-bold mt-2 uppercase tracking-wide">{error}</p>
124
+ )}
125
+ </div>
126
+ </div>
127
+
128
+ {/* Footer with side-by-side buttons and separator */}
129
+ <div className="flex border-t border-gray-100 h-[52px]">
130
+ <button
131
+ onClick={handleDelete}
132
+ disabled={isDeleting}
133
+ className="flex-1 h-full flex items-center justify-center text-[13px] font-bold text-gray-500 tracking-wider hover:bg-gray-50 transition-colors uppercase"
134
+ >
135
+ {isDeleting ? <Spinner className="animate-spin" /> : "REMOVE"}
136
+ </button>
137
+
138
+ {/* Vertical Separator */}
139
+ <div className="w-px bg-gray-100 h-full" />
140
+
141
+ <button
142
+ onClick={handleMoveToWishlist}
143
+ disabled={wishlistLoading}
144
+ className="flex-1 h-full flex items-center justify-center text-[13px] font-bold tracking-wider hover:bg-gray-50 transition-colors uppercase"
145
+ style={{ color: '#D25C78' }} // Pinkish color from reference
146
+ >
147
+ {wishlistLoading ? <Spinner className="animate-spin" /> : "MOVE TO WISHLIST"}
148
+ </button>
149
+ </div>
150
+ </div>
151
+ </Modal>
152
+ </>
153
+ )
154
+ }
155
+
156
+ export default DeleteButton
@@ -0,0 +1,9 @@
1
+ import { clx } from "@medusajs/ui"
2
+
3
+ const Divider = ({ className }: { className?: string }) => (
4
+ <div
5
+ className={clx("h-px w-full border-b border-gray-200 mt-1", className)}
6
+ />
7
+ )
8
+
9
+ export default Divider
@@ -0,0 +1,134 @@
1
+ import { Heading } from "@medusajs/ui"
2
+ import CheckboxWithLabel from "@modules/common/components/checkbox"
3
+ import React from "react"
4
+
5
+ type FilterCheckboxGroupProps = {
6
+ title: string
7
+ items: { value: string; label: string }[]
8
+ values: string[]
9
+ handleChange: (value: string) => void
10
+ isColor?: boolean
11
+ 'data-testid'?: string
12
+ }
13
+
14
+ const FilterCheckboxGroup = ({
15
+ title,
16
+ items,
17
+ values,
18
+ handleChange,
19
+ isColor,
20
+ 'data-testid': dataTestId,
21
+ }: FilterCheckboxGroupProps) => {
22
+ const [isOpen, setIsOpen] = React.useState(true)
23
+ const [showAll, setShowAll] = React.useState(false)
24
+
25
+ // Optimistic local state — reflects clicks instantly without waiting for server
26
+ const [optimisticValues, setOptimisticValues] = React.useState<string[]>(values)
27
+
28
+ // Sync back when server props update (after navigation completes)
29
+ React.useEffect(() => {
30
+ setOptimisticValues(values)
31
+ }, [values])
32
+
33
+ const initialItemsCount = 6
34
+ const hasMore = items?.length > initialItemsCount
35
+
36
+ // Auto-expand if a selected item is hidden or if any item is selected
37
+ React.useEffect(() => {
38
+ if (values && values.length > 0) {
39
+ setIsOpen(true)
40
+ if (hasMore && items) {
41
+ const hiddenItems = items.slice(initialItemsCount)
42
+ const isAnyHiddenItemSelected = hiddenItems.some(item => values.includes(item.value))
43
+ if (isAnyHiddenItemSelected) {
44
+ setShowAll(true)
45
+ }
46
+ }
47
+ }
48
+ }, [values, items, hasMore])
49
+
50
+ const handleOptimisticChange = (value: string) => {
51
+ // Immediately toggle locally — no flicker
52
+ setOptimisticValues((prev) =>
53
+ prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]
54
+ )
55
+ // Trigger actual URL navigation in background
56
+ handleChange(value)
57
+ }
58
+
59
+ const displayedItems = showAll ? items : items?.slice(0, initialItemsCount)
60
+
61
+ return (
62
+ <div className="flex flex-col border-b border-gray-100 pb-4 last:border-0 last:pb-0">
63
+ <button
64
+ onClick={() => setIsOpen(!isOpen)}
65
+ className="flex items-center justify-between w-full group transition-all py-1"
66
+ >
67
+ <Heading
68
+ level="h3"
69
+ className="text-sm font-bold text-gray-900 uppercase tracking-wider group-hover:text-[#8B5AB1] transition-colors"
70
+ >
71
+ {title}
72
+ </Heading>
73
+ <span
74
+ className={`transform transition-transform duration-300 text-gray-400 group-hover:text-[#8B5AB1] ${isOpen ? "" : "-rotate-180"}`}
75
+ >
76
+ <svg
77
+ width="18"
78
+ height="18"
79
+ viewBox="0 0 24 24"
80
+ fill="none"
81
+ stroke="currentColor"
82
+ strokeWidth="2.5"
83
+ strokeLinecap="round"
84
+ strokeLinejoin="round"
85
+ >
86
+ <polyline points="18 15 12 9 6 15"></polyline>
87
+ </svg>
88
+ </span>
89
+ </button>
90
+
91
+ <div
92
+ className={`flex flex-col gap-y-1 transition-all duration-300 ease-in-out ${isOpen ? "mt-3 opacity-100 px-0.5" : "max-h-0 opacity-0 invisible overflow-hidden"}`}
93
+ style={isOpen ? { maxHeight: showAll ? '1000px' : '300px' } : {}}
94
+ >
95
+ {displayedItems?.map((i) => (
96
+ <CheckboxWithLabel
97
+ key={i.value}
98
+ label={i.label}
99
+ color={isColor ? i.value : undefined}
100
+ checked={optimisticValues.includes(i.value)}
101
+ onChange={() => handleOptimisticChange(i.value)}
102
+ data-testid={dataTestId}
103
+ data-ga-event="filter_checkbox_click"
104
+ data-ga-label={`${title} - ${i.label}`}
105
+ />
106
+ ))}
107
+
108
+ {hasMore && isOpen && (
109
+ <button
110
+ onClick={() => setShowAll(!showAll)}
111
+ className="text-xs font-bold text-[#8B5AB1] hover:underline mt-2 flex items-center gap-1 uppercase tracking-tight"
112
+ >
113
+ {showAll ? "View Less" : `View More (${items.length - initialItemsCount})`}
114
+ <svg
115
+ width="12"
116
+ height="12"
117
+ viewBox="0 0 24 24"
118
+ fill="none"
119
+ stroke="currentColor"
120
+ strokeWidth="3"
121
+ strokeLinecap="round"
122
+ strokeLinejoin="round"
123
+ className={`transform transition-transform ${showAll ? "rotate-180" : ""}`}
124
+ >
125
+ <polyline points="6 9 12 15 18 9"></polyline>
126
+ </svg>
127
+ </button>
128
+ )}
129
+ </div>
130
+ </div>
131
+ )
132
+ }
133
+
134
+ export default FilterCheckboxGroup
@@ -0,0 +1,62 @@
1
+ import { EllipseMiniSolid } from "@medusajs/icons"
2
+ import { Label, RadioGroup, Text, clx } from "@medusajs/ui"
3
+
4
+ type FilterRadioGroupProps = {
5
+ title: string
6
+ items: {
7
+ value: string
8
+ label: string
9
+ }[]
10
+ value: any
11
+ handleChange: (...args: any[]) => void
12
+ "data-testid"?: string
13
+ }
14
+
15
+ const FilterRadioGroup = ({
16
+ title,
17
+ items,
18
+ value,
19
+ handleChange,
20
+ "data-testid": dataTestId,
21
+ }: FilterRadioGroupProps) => {
22
+ return (
23
+ <div className="flex gap-x-3 flex-col gap-y-3">
24
+ <Text className="txt-compact-small-plus text-ui-fg-muted">{title}</Text>
25
+ <RadioGroup data-testid={dataTestId} onValueChange={handleChange}>
26
+ {items?.map((i) => (
27
+ <div
28
+ key={i.value}
29
+ className={clx("flex gap-x-2 items-center", {
30
+ "ml-[-23px]": i.value === value,
31
+ })}
32
+ >
33
+ {i.value === value && <EllipseMiniSolid />}
34
+ <RadioGroup.Item
35
+ checked={i.value === value}
36
+ className="hidden peer"
37
+ id={i.value}
38
+ value={i.value}
39
+ />
40
+ <Label
41
+ htmlFor={i.value}
42
+ className={clx(
43
+ "!txt-compact-small !transform-none text-ui-fg-subtle hover:cursor-pointer",
44
+ {
45
+ "text-ui-fg-base": i.value === value,
46
+ }
47
+ )}
48
+ data-testid="radio-label"
49
+ data-active={i.value === value}
50
+ data-ga-event="filter_sort_click"
51
+ data-ga-label={i.label}
52
+ >
53
+ {i.label}
54
+ </Label>
55
+ </div>
56
+ ))}
57
+ </RadioGroup>
58
+ </div>
59
+ )
60
+ }
61
+
62
+ export default FilterRadioGroup
@@ -0,0 +1,79 @@
1
+ import { Label } from "@medusajs/ui"
2
+ import React, { useEffect, useImperativeHandle, useState } from "react"
3
+
4
+ import Eye from "@modules/common/icons/eye"
5
+ import EyeOff from "@modules/common/icons/eye-off"
6
+
7
+ type InputProps = Omit<
8
+ Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">,
9
+ "placeholder"
10
+ > & {
11
+ label: string
12
+ errors?: Record<string, unknown>
13
+ touched?: Record<string, unknown>
14
+ name: string
15
+ topLabel?: string
16
+ }
17
+
18
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
19
+ ({ type, name, label, touched, required, topLabel, ...props }, ref) => {
20
+ const inputRef = React.useRef<HTMLInputElement>(null)
21
+ const [showPassword, setShowPassword] = useState(false)
22
+ const [inputType, setInputType] = useState(type)
23
+
24
+ useEffect(() => {
25
+ if (type === "password" && showPassword) {
26
+ setInputType("text")
27
+ }
28
+
29
+ if (type === "password" && !showPassword) {
30
+ setInputType("password")
31
+ }
32
+ }, [type, showPassword])
33
+
34
+ useImperativeHandle(ref, () => inputRef.current!)
35
+
36
+ return (
37
+ <div className="flex flex-col w-full">
38
+ {topLabel && (
39
+ <Label className="mb-2 txt-compact-medium-plus">{topLabel}</Label>
40
+ )}
41
+ <div className="flex relative z-0 w-full txt-compact-medium overflow-visible">
42
+ <input
43
+ type={inputType}
44
+ name={name}
45
+ placeholder=" "
46
+ required={required}
47
+ className="peer pt-6 pb-2 block w-full h-12 px-4 mt-0 bg-white border rounded-md appearance-none focus:outline-none focus:border-[#8B5AB1] focus:ring-0 hover:bg-gray-50 transition-colors duration-200 antialiased"
48
+ style={{ borderColor: '#C0C0C0' }}
49
+ {...props}
50
+ ref={inputRef}
51
+ />
52
+ {label && (
53
+ <label
54
+ htmlFor={name}
55
+ onClick={() => inputRef.current?.focus()}
56
+ className="flex items-center justify-center absolute left-4 px-1 transition-all duration-300 top-1/2 -translate-y-1/2 origin-0 text-ui-fg-subtle pointer-events-none peer-focus:top-2 peer-focus:translate-y-0 peer-focus:text-[11px] peer-focus:text-[#8B5AB1] peer-focus:z-10 peer-[:not(:placeholder-shown)]:top-2 peer-[:not(:placeholder-shown)]:translate-y-0 peer-[:not(:placeholder-shown)]:text-[11px] peer-[:not(:placeholder-shown)]:z-10"
57
+ >
58
+ {label}
59
+ {required && <span className="text-rose-500">*</span>}
60
+ </label>
61
+ )}
62
+ {type === "password" && (
63
+ <button
64
+ type="button"
65
+ onClick={() => setShowPassword(!showPassword)}
66
+ className="text-ui-fg-subtle px-4 focus:outline-none transition-all duration-150 outline-none focus:text-ui-fg-base absolute right-0 top-3"
67
+ >
68
+ {showPassword ? <Eye /> : <EyeOff />}
69
+ </button>
70
+ )}
71
+ </div>
72
+ </div>
73
+ )
74
+ }
75
+ )
76
+
77
+ Input.displayName = "Input"
78
+
79
+ export default Input
@@ -0,0 +1,33 @@
1
+ import { ArrowUpRightMini } from "@medusajs/icons"
2
+ import { Text } from "@medusajs/ui"
3
+ import LocalizedClientLink from "../localized-client-link"
4
+
5
+ type InteractiveLinkProps = {
6
+ href: string
7
+ children?: React.ReactNode
8
+ onClick?: () => void
9
+ }
10
+
11
+ const InteractiveLink = ({
12
+ href,
13
+ children,
14
+ onClick,
15
+ ...props
16
+ }: InteractiveLinkProps) => {
17
+ return (
18
+ <LocalizedClientLink
19
+ className="flex gap-x-1 items-center group"
20
+ href={href}
21
+ onClick={onClick}
22
+ {...props}
23
+ >
24
+ <Text className="text-ui-fg-interactive">{children}</Text>
25
+ <ArrowUpRightMini
26
+ className="group-hover:rotate-45 ease-in-out duration-150"
27
+ color="var(--fg-interactive)"
28
+ />
29
+ </LocalizedClientLink>
30
+ )
31
+ }
32
+
33
+ export default InteractiveLink
@@ -0,0 +1,26 @@
1
+ import { HttpTypes } from "@medusajs/types"
2
+ import { Text } from "@medusajs/ui"
3
+
4
+ type LineItemOptionsProps = {
5
+ variant: HttpTypes.StoreProductVariant | undefined
6
+ "data-testid"?: string
7
+ "data-value"?: HttpTypes.StoreProductVariant
8
+ }
9
+
10
+ const LineItemOptions = ({
11
+ variant,
12
+ "data-testid": dataTestid,
13
+ "data-value": dataValue,
14
+ }: LineItemOptionsProps) => {
15
+ return (
16
+ <Text
17
+ data-testid={dataTestid}
18
+ data-value={dataValue}
19
+ className="inline-block txt-medium text-ui-fg-subtle w-full overflow-hidden text-ellipsis"
20
+ >
21
+ Variant: {variant?.title}
22
+ </Text>
23
+ )
24
+ }
25
+
26
+ export default LineItemOptions
@@ -0,0 +1,64 @@
1
+ import { getPercentageDiff } from "@core/util/get-percentage-diff"
2
+ import { convertToLocale } from "@core/util/money"
3
+ import { HttpTypes } from "@medusajs/types"
4
+ import { clx } from "@medusajs/ui"
5
+
6
+ type LineItemPriceProps = {
7
+ item: HttpTypes.StoreCartLineItem | HttpTypes.StoreOrderLineItem
8
+ style?: "default" | "tight"
9
+ currencyCode: string
10
+ }
11
+
12
+ const LineItemPrice = ({
13
+ item,
14
+ style = "default",
15
+ currencyCode,
16
+ }: LineItemPriceProps) => {
17
+ const { total, original_total } = item
18
+ const originalPrice = original_total
19
+ const currentPrice = total
20
+ const hasReducedPrice = currentPrice < originalPrice
21
+
22
+ return (
23
+ <div className="flex flex-col gap-x-2 text-ui-fg-subtle items-end">
24
+ <div className="text-left">
25
+ {hasReducedPrice && (
26
+ <>
27
+ <p>
28
+ {style === "default" && (
29
+ <span className="text-ui-fg-subtle">Original: </span>
30
+ )}
31
+ <span
32
+ className="line-through text-ui-fg-muted"
33
+ data-testid="product-original-price"
34
+ >
35
+ {convertToLocale({
36
+ amount: originalPrice,
37
+ currency_code: currencyCode,
38
+ })}
39
+ </span>
40
+ </p>
41
+ {style === "default" && (
42
+ <span className="text-ui-fg-interactive">
43
+ -{getPercentageDiff(originalPrice, currentPrice || 0)}%
44
+ </span>
45
+ )}
46
+ </>
47
+ )}
48
+ <span
49
+ className={clx("text-base-regular", {
50
+ "text-ui-fg-interactive": hasReducedPrice,
51
+ })}
52
+ data-testid="product-price"
53
+ >
54
+ {convertToLocale({
55
+ amount: currentPrice,
56
+ currency_code: currencyCode,
57
+ })}
58
+ </span>
59
+ </div>
60
+ </div>
61
+ )
62
+ }
63
+
64
+ export default LineItemPrice
@@ -0,0 +1,61 @@
1
+ import { convertToLocale } from "@core/util/money"
2
+ import { HttpTypes } from "@medusajs/types"
3
+ import { clx } from "@medusajs/ui"
4
+
5
+ type LineItemUnitPriceProps = {
6
+ item: HttpTypes.StoreCartLineItem | HttpTypes.StoreOrderLineItem
7
+ style?: "default" | "tight"
8
+ currencyCode: string
9
+ }
10
+
11
+ const LineItemUnitPrice = ({
12
+ item,
13
+ style = "default",
14
+ currencyCode,
15
+ }: LineItemUnitPriceProps) => {
16
+ const { total, original_total } = item
17
+ const hasReducedPrice = total < original_total
18
+
19
+ const percentage_diff = Math.round(
20
+ ((original_total - total) / original_total) * 100
21
+ )
22
+
23
+ return (
24
+ <div className="flex flex-col text-ui-fg-muted justify-center h-full">
25
+ {hasReducedPrice && (
26
+ <>
27
+ <p>
28
+ {style === "default" && (
29
+ <span className="text-ui-fg-muted">Original: </span>
30
+ )}
31
+ <span
32
+ className="line-through"
33
+ data-testid="product-unit-original-price"
34
+ >
35
+ {convertToLocale({
36
+ amount: original_total / item.quantity,
37
+ currency_code: currencyCode,
38
+ })}
39
+ </span>
40
+ </p>
41
+ {style === "default" && (
42
+ <span className="text-ui-fg-interactive">-{percentage_diff}%</span>
43
+ )}
44
+ </>
45
+ )}
46
+ <span
47
+ className={clx("text-base-regular", {
48
+ "text-ui-fg-interactive": hasReducedPrice,
49
+ })}
50
+ data-testid="product-unit-price"
51
+ >
52
+ {convertToLocale({
53
+ amount: total / item.quantity,
54
+ currency_code: currencyCode,
55
+ })}
56
+ </span>
57
+ </div>
58
+ )
59
+ }
60
+
61
+ export default LineItemUnitPrice
@@ -0,0 +1,32 @@
1
+ "use client"
2
+
3
+ import Link from "next/link"
4
+ import { useParams } from "next/navigation"
5
+ import React from "react"
6
+
7
+ /**
8
+ * Use this component to create a Next.js `<Link />` that persists the current country code in the url,
9
+ * without having to explicitly pass it as a prop.
10
+ */
11
+ const LocalizedClientLink = ({
12
+ children,
13
+ href,
14
+ ...props
15
+ }: {
16
+ children?: React.ReactNode
17
+ href: string
18
+ className?: string
19
+ onClick?: () => void
20
+ passHref?: true
21
+ [x: string]: any
22
+ }) => {
23
+ const { countryCode } = useParams()
24
+
25
+ return (
26
+ <Link href={`/${countryCode}${href}`} {...props}>
27
+ {children}
28
+ </Link>
29
+ )
30
+ }
31
+
32
+ export default LocalizedClientLink