@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,174 @@
1
+ "use client"
2
+
3
+ import { useState } from "react"
4
+ import Link from "next/link"
5
+ import { Copy, Check } from "lucide-react"
6
+
7
+ export default function PromoBarContent({ text, code: explicitCode, value: explicitValue }: { text: string; code: string | null; value: string | null }) {
8
+ const [copied, setCopied] = useState(false)
9
+
10
+ // Regex for code and value
11
+ const codeRegex = /\b[A-Z0-9]{4,}\b/;
12
+ const valueRegex = /(\d+%\s?(OFF)?)|([₹$]\d+)|(\d+\s?(Rs|₹|%|OFF))/gi;
13
+
14
+ let currentText = text;
15
+ let codeToCopy = explicitCode || "";
16
+
17
+ // Find code part
18
+ let codeMatch = explicitCode && currentText.includes(explicitCode)
19
+ ? { text: explicitCode, index: currentText.indexOf(explicitCode) }
20
+ : null;
21
+
22
+ if (!codeMatch) {
23
+ const regMatch = currentText.match(codeRegex);
24
+ if (regMatch) {
25
+ codeMatch = { text: regMatch[0], index: regMatch.index! };
26
+ if (!explicitCode) codeToCopy = regMatch[0];
27
+ }
28
+ }
29
+
30
+ // Find value part
31
+ let valueMatch = explicitValue && currentText.includes(explicitValue)
32
+ ? { text: explicitValue, index: currentText.indexOf(explicitValue) }
33
+ : null;
34
+
35
+ if (!valueMatch) {
36
+ const regMatch = Array.from(currentText.matchAll(valueRegex));
37
+ if (regMatch.length > 0) {
38
+ const firstValue = regMatch[0];
39
+ valueMatch = { text: firstValue[0], index: firstValue.index! };
40
+ }
41
+ }
42
+
43
+ // Handle priority: if explicitCode/explicitValue exist but not found in text,
44
+ // we replace the detected ones or append if none detected?
45
+ // User said "replace" essentially by saying priority.
46
+
47
+ // To render precisely, we need to collect all segments.
48
+ const segments: Array<{ text: string; type: 'text' | 'code' | 'value' }> = [];
49
+ let lastIndex = 0;
50
+
51
+ const matches = [
52
+ ...(codeMatch ? [{ ...codeMatch, type: 'code' as const }] : []),
53
+ ...(valueMatch ? [{ ...valueMatch, type: 'value' as const }] : [])
54
+ ].sort((a, b) => a.index - b.index);
55
+
56
+ // Avoid overlaps
57
+ let filteredMatches: typeof matches = [];
58
+ let currentPos = 0;
59
+ for (const match of matches) {
60
+ if (match.index >= currentPos) {
61
+ filteredMatches.push(match);
62
+ currentPos = match.index + match.text.length;
63
+ }
64
+ }
65
+
66
+ filteredMatches.forEach(match => {
67
+ if (match.index > lastIndex) {
68
+ segments.push({ text: currentText.substring(lastIndex, match.index), type: 'text' });
69
+ }
70
+
71
+ // Use explicit values if they exist, even if the text match was different (Priority logic)
72
+ const displayText = match.type === 'code' ? (explicitCode || match.text) : (explicitValue || match.text);
73
+ segments.push({ text: displayText, type: match.type });
74
+ lastIndex = match.index + match.text.length;
75
+ });
76
+
77
+ if (lastIndex < currentText.length) {
78
+ segments.push({ text: currentText.substring(lastIndex), type: 'text' });
79
+ }
80
+
81
+ // Fallback for cases where no match was found but explicit values exist:
82
+ // (Optional: we could append them, but usually text should contain them)
83
+
84
+ const handleCopy = () => {
85
+ navigator.clipboard.writeText(codeToCopy || text)
86
+ setCopied(true)
87
+ setTimeout(() => setCopied(false), 2000)
88
+ }
89
+
90
+ return (
91
+ <div className="max-w-[1440px] mx-auto w-full relative z-10 flex flex-row items-center justify-start lg:justify-center gap-x-4 text-center font-medium overflow-hidden whitespace-nowrap py-0.5">
92
+ {/* Visual Feedback Overlay for Copy Success - Mobile Only */}
93
+ {copied && (
94
+ <div className="absolute inset-0 z-50 flex sm:hidden items-center justify-center bg-gradient-to-r from-[#8B5AB1] via-[#9B6BC1] to-[#8B5AB1] animate-in fade-in zoom-in duration-200">
95
+ <span className="text-yellow-300 text-[11px] sm:text-[13px] font-extrabold tracking-wider uppercase flex items-center gap-2 drop-shadow-md">
96
+ PROMOCODE COPIED! APPLY AT CHECKOUT 🎁
97
+ </span>
98
+ </div>
99
+ )}
100
+
101
+ <div className="flex items-center lg:animate-none animate-marquee whitespace-nowrap min-w-full lg:min-w-0">
102
+ <button
103
+ onClick={handleCopy}
104
+ className="group/btn flex items-center justify-center gap-1.5 focus:outline-none flex-shrink-0"
105
+ title={codeToCopy ? `Click to copy promo code: ${codeToCopy}` : "Click to copy"}
106
+ >
107
+ {/* Main Content Segment */}
108
+ <div className="flex items-center gap-1.5 px-2 sm:px-0">
109
+ <span className="text-[11px] sm:text-[12.5px] font-bold tracking-[0.05em] uppercase drop-shadow-sm group-hover/btn:text-yellow-100 transition-colors flex items-center">
110
+ {segments.length > 0 ? segments.map((s, i) => (
111
+ s.type === 'text' ? (
112
+ <span key={i}>{s.text}</span>
113
+ ) : (
114
+ <span key={i} className="text-yellow-300 text-[12px] sm:text-[13.5px] mx-1 font-extrabold shadow-sm group-hover/btn:text-yellow-200 transition-colors drop-shadow-md">
115
+ "{s.text}"
116
+ </span>
117
+ )
118
+ )) : text}
119
+ </span>
120
+ <span className="bg-white/20 p-1 rounded-md group-hover/btn:bg-white/30 transition-colors flex items-center justify-center flex-shrink-0 ml-1">
121
+ {copied ? (
122
+ <Check size={13} className="text-green-300" strokeWidth={3} />
123
+ ) : (
124
+ <Copy size={13} className="text-white/80 group-hover/btn:text-white" strokeWidth={2.5} />
125
+ )}
126
+ </span>
127
+ </div>
128
+ </button>
129
+
130
+ <div className="mx-4 h-3 w-px bg-white/30 flex-shrink-0" />
131
+
132
+ <Link
133
+ href="/store"
134
+ className="text-[11px] sm:text-[12.5px] font-bold tracking-[0.02em] uppercase text-yellow-300 hover:text-white underline underline-offset-4 decoration-white/40 hover:decoration-white transition-all flex items-center group/link flex-shrink-0 mr-8 sm:mr-0"
135
+ >
136
+ SHOP NOW
137
+ <svg
138
+ className="ml-1 w-3 h-3 transform group-hover/link:translate-x-1 transition-transform"
139
+ fill="none"
140
+ viewBox="0 0 24 24"
141
+ stroke="currentColor"
142
+ >
143
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M9 5l7 7-7 7" />
144
+ </svg>
145
+ </Link>
146
+
147
+ {/* Duplicated Content for Seamless Loop on Mobile and Tablet */}
148
+ <div className="flex lg:hidden items-center gap-x-4">
149
+ <div className="mx-4 h-3 w-px bg-white/30 flex-shrink-0" />
150
+ <div className="flex items-center gap-1.5 px-2">
151
+ <span className="text-[11px] font-bold tracking-[0.05em] uppercase drop-shadow-sm flex items-center">
152
+ {segments.length > 0 ? segments.map((s, i) => (
153
+ s.type === 'text' ? (
154
+ <span key={i}>{s.text}</span>
155
+ ) : (
156
+ <span key={i} className="text-yellow-300 text-[12px] mx-1 font-extrabold">
157
+ "{s.text}"
158
+ </span>
159
+ )
160
+ )) : text}
161
+ </span>
162
+ <span className="bg-white/20 p-1 rounded-md flex items-center justify-center flex-shrink-0 ml-1">
163
+ <Copy size={13} className="text-white/80" strokeWidth={2.5} />
164
+ </span>
165
+ </div>
166
+ <div className="mx-4 h-3 w-px bg-white/30 flex-shrink-0" />
167
+ <span className="text-[11px] font-bold tracking-[0.02em] uppercase text-yellow-300 flex items-center mr-8">
168
+ SHOP NOW
169
+ </span>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ )
174
+ }
@@ -0,0 +1,191 @@
1
+ "use client"
2
+
3
+ import React, { useEffect, useState } from "react"
4
+ import { registerNotificationToken } from "@core/data/notifications"
5
+ import { Button, IconButton } from "@medusajs/ui"
6
+ import { XMark } from "@medusajs/icons"
7
+
8
+ interface PushNotificationManagerProps {
9
+ customerId?: string
10
+ }
11
+
12
+ const PushNotificationManager: React.FC<PushNotificationManagerProps> = ({ customerId }) => {
13
+ const [showPrompt, setShowPrompt] = useState(false)
14
+ const [status, setStatus] = useState<"idle" | "requesting" | "registered" | "denied">("idle")
15
+
16
+ useEffect(() => {
17
+
18
+
19
+ const checkStatus = async () => {
20
+ if (typeof window === "undefined") return
21
+
22
+ const permission = Notification.permission
23
+ const storageKey = customerId ? `fcm_reg_${customerId}` : "fcm_reg_guest"
24
+ const alreadyRegistered = localStorage.getItem(storageKey)
25
+
26
+ console.log("DEBUG: PushNotification Status", {
27
+ customerId,
28
+ permission,
29
+ alreadyRegistered,
30
+ isDismissed: localStorage.getItem("push_notification_dismissed")
31
+ })
32
+
33
+ if (permission === "default") {
34
+ const isDismissed = localStorage.getItem("push_notification_dismissed")
35
+ if (isDismissed === "true") return
36
+ setShowPrompt(true)
37
+ } else if (permission === "granted") {
38
+ if (!alreadyRegistered) {
39
+ handleAllow(true)
40
+ } else {
41
+ setStatus("registered")
42
+ }
43
+ } else if (permission === "denied") {
44
+ setStatus("denied")
45
+ }
46
+ }
47
+
48
+ setTimeout(checkStatus, 1000)
49
+
50
+ // Listen for foreground messages
51
+ const setupListener = async () => {
52
+ try {
53
+ const { onMessageListener } = await import("@core/firebase")
54
+ onMessageListener().then((payload: any) => {
55
+
56
+ if (Notification.permission === "granted") {
57
+ new Notification(payload.notification.title, {
58
+ body: payload.notification.body,
59
+ icon: "/Logo.png"
60
+ })
61
+ }
62
+ })
63
+ } catch (err) {
64
+ // Listener setup error
65
+ }
66
+ }
67
+ setupListener()
68
+ }, [customerId])
69
+
70
+ const handleAllow = async (isBackground = false) => {
71
+ if (!isBackground) setStatus("requesting")
72
+ try {
73
+ const { requestNotificationPermission } = await import("@core/firebase")
74
+ const token = await requestNotificationPermission()
75
+ if (token) {
76
+ const deviceInfo = {
77
+ userAgent: navigator.userAgent,
78
+ platform: navigator.platform,
79
+ language: navigator.language,
80
+ }
81
+ const success = await registerNotificationToken(token, deviceInfo)
82
+ if (success) {
83
+ const storageKey = customerId ? `fcm_reg_${customerId}` : "fcm_reg_guest"
84
+ localStorage.setItem(storageKey, "true")
85
+ setStatus("registered")
86
+ setShowPrompt(false)
87
+ if (!isBackground) alert("Notifications enabled successfully!")
88
+ } else {
89
+ setStatus("idle")
90
+ if (!isBackground) alert("Failed to register token with backend.")
91
+ }
92
+ } else {
93
+ setStatus("denied")
94
+ }
95
+ } catch (error) {
96
+ setStatus("idle")
97
+ if (!isBackground) alert("Failed to enable notifications. Please check your browser's settings.")
98
+ }
99
+ }
100
+
101
+ const handleDismiss = () => {
102
+ setShowPrompt(false)
103
+ localStorage.setItem("push_notification_dismissed", "true")
104
+ }
105
+
106
+ if (!customerId || !showPrompt || status === "registered") return null
107
+
108
+ return (
109
+ <div
110
+ id="push-notification-prompt"
111
+ className="fixed inset-0 z-[999999] flex items-center justify-center p-6"
112
+ >
113
+ {/* Backdrop with elegant blur */}
114
+ <div
115
+ className="absolute inset-0 bg-black/40 backdrop-blur-sm animate-in fade-in duration-500"
116
+ onClick={handleDismiss}
117
+ />
118
+
119
+ <div className="bg-white dark:bg-neutral-900 w-full max-w-[440px] rounded-[32px] shadow-[0_32px_128px_-16px_rgba(0,0,0,0.3)] border border-neutral-100 dark:border-neutral-800 relative overflow-hidden animate-in zoom-in-95 fade-in slide-in-from-bottom-20 duration-500">
120
+ {/* Subtle Brand Background Blobs */}
121
+ <div className="absolute top-0 right-0 -mt-16 -mr-16 w-48 h-48 bg-[#8B5AB1]/10 rounded-full blur-[60px]" />
122
+
123
+ <div className="relative z-10 p-10">
124
+ <div className="flex justify-between items-start mb-8">
125
+ <div className="bg-gradient-to-br from-[#A879CF] to-[#8B5AB1] w-16 h-16 rounded-[24px] shadow-[0_20px_40px_-10px_rgba(139,90,177,0.6)] grid place-items-center flex-shrink-0 border border-white/20 relative group">
126
+ <div className="absolute inset-0 bg-white/10 opacity-0 group-hover:opacity-100 transition-opacity rounded-[24px]" />
127
+ <svg
128
+ width="34"
129
+ height="34"
130
+ viewBox="0 0 24 24"
131
+ fill="none"
132
+ stroke="white"
133
+ strokeWidth="2.2"
134
+ strokeLinecap="round"
135
+ strokeLinejoin="round"
136
+ className="drop-shadow-sm"
137
+ >
138
+ <path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" />
139
+ <path d="M10.3 21a1.94 1.94 0 0 0 3.4 0" />
140
+ </svg>
141
+ </div>
142
+ <button
143
+ onClick={handleDismiss}
144
+ className="p-2.5 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-full transition-all group active:scale-90"
145
+ >
146
+ <XMark className="w-6 h-6 text-neutral-300 group-hover:text-neutral-900 dark:group-hover:text-white" />
147
+ </button>
148
+ </div>
149
+
150
+ <div className="text-left">
151
+ <h3 className="text-2xl sm:text-3xl font-black text-neutral-900 dark:text-white mb-3 tracking-tight">
152
+ {status === "denied" ? "Notifications Blocked" : "Enable Notifications?"}
153
+ </h3>
154
+ <p className="text-neutral-500 dark:text-neutral-400 text-base sm:text-lg mb-10 leading-relaxed">
155
+ {status === "denied"
156
+ ? "Please enable notifications in your browser settings to stay updated."
157
+ : "Don't miss out! Get real-time updates for your order status and exclusive member-only offers."}
158
+ </p>
159
+ </div>
160
+
161
+ {status !== "denied" && (
162
+ <div className="flex flex-col gap-4">
163
+ <button
164
+ className="w-full rounded-[20px] h-14 bg-gradient-to-r from-[#8B5AB1] to-[#784ca1] hover:bg-[#7a4f9b] text-white font-bold text-lg shadow-[0_12px_32px_rgba(139,90,177,0.25)] hover:shadow-[0_16px_40px_rgba(139,90,177,0.35)] active:scale-[0.98] transition-all flex items-center justify-center gap-3 disabled:opacity-75"
165
+ onClick={() => handleAllow()}
166
+ disabled={status === "requesting"}
167
+ >
168
+ {status === "requesting" ? (
169
+ <>
170
+ <div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
171
+ <span>Connecting...</span>
172
+ </>
173
+ ) : (
174
+ "Yes, Notify Me"
175
+ )}
176
+ </button>
177
+ <button
178
+ className="w-full rounded-[20px] h-14 bg-white dark:bg-neutral-800 border-2 border-neutral-100 dark:border-neutral-800 text-neutral-500 dark:text-neutral-300 font-bold text-lg hover:bg-neutral-50 dark:hover:bg-neutral-700/50 hover:text-neutral-900 dark:hover:text-white transition-all active:scale-[0.98]"
179
+ onClick={handleDismiss}
180
+ >
181
+ Maybe Later
182
+ </button>
183
+ </div>
184
+ )}
185
+ </div>
186
+ </div>
187
+ </div>
188
+ )
189
+ }
190
+
191
+ export default PushNotificationManager
@@ -0,0 +1,136 @@
1
+ "use client"
2
+
3
+ import { Popover, PopoverPanel, Transition } from "@headlessui/react"
4
+ import { XMark } from "@medusajs/icons"
5
+ import { Fragment, useState, useEffect, useRef } from "react"
6
+ import { useSearchParams } from "next/navigation"
7
+ import Image from "next/image"
8
+ import LocalizedClientLink from "@modules/common/components/localized-client-link"
9
+
10
+ type SearchPanelProps = {
11
+ countryCode: string
12
+ }
13
+
14
+ const SearchPanel = ({ countryCode }: SearchPanelProps) => {
15
+ const searchParams = useSearchParams()
16
+ const q = searchParams.get("q") || ""
17
+ const [searchQuery, setSearchQuery] = useState(q)
18
+ const prevOpenRef = useRef(false)
19
+
20
+ useEffect(() => {
21
+ setSearchQuery(q)
22
+ }, [q])
23
+
24
+ // Cleanup on unmount
25
+ useEffect(() => {
26
+ return () => {
27
+ document.body.style.overflow = "unset"
28
+ }
29
+ }, [])
30
+
31
+ return (
32
+ <div className="h-full">
33
+ <div className="flex items-center h-full">
34
+ <Popover className="h-full flex">
35
+ {({ open, close }) => {
36
+ // Lock body scroll when panel opens/closes
37
+ if (open !== prevOpenRef.current) {
38
+ prevOpenRef.current = open
39
+ if (open) {
40
+ document.body.style.overflow = "hidden"
41
+ } else {
42
+ document.body.style.overflow = "unset"
43
+ }
44
+ }
45
+
46
+ return (
47
+ <>
48
+ <Popover.Button
49
+ data-testid="search-panel-button"
50
+ className="relative h-full flex items-center transition-all ease-out duration-200 focus:outline-none hover:opacity-80"
51
+ >
52
+ <Image
53
+ src="/Search.svg"
54
+ alt="Search"
55
+ width={26}
56
+ height={26}
57
+ className="w-5 h-5"
58
+ />
59
+ </Popover.Button>
60
+
61
+ {open && (
62
+ <div
63
+ className="fixed inset-0 z-[50] bg-black/20 backdrop-blur-sm pointer-events-auto"
64
+ onClick={close}
65
+ data-testid="search-panel-backdrop"
66
+ />
67
+ )}
68
+
69
+ <Transition
70
+ show={open}
71
+ as={Fragment}
72
+ enter="transition ease-out duration-200"
73
+ enterFrom="translate-x-full opacity-0"
74
+ enterTo="translate-x-0 opacity-100"
75
+ leave="transition ease-in duration-150"
76
+ leaveFrom="translate-x-0 opacity-100"
77
+ leaveTo="translate-x-full opacity-0"
78
+ >
79
+ <PopoverPanel className="fixed right-0 top-0 h-full w-full max-w-[400px] min-[300px]:max-w-[300px] min-[400px]:max-w-[320px] min-[640px]:max-w-[400px] bg-page-bg shadow-2xl z-[51] flex flex-col">
80
+ <div className="flex flex-col h-full">
81
+ <div className="flex items-center justify-between p-6 border-b border-[var(--color-border)]">
82
+ <h2 className="text-xl font-bold text-heading">Search</h2>
83
+ <button
84
+ data-testid="close-search-button"
85
+ onClick={close}
86
+ className="p-2 hover:bg-surface-muted transition-colors"
87
+ >
88
+ <XMark className="w-5 h-5 text-muted" />
89
+ </button>
90
+ </div>
91
+
92
+ <div className="p-6 border-b border-[var(--color-border)]">
93
+ <div className="relative">
94
+ <input
95
+ type="text"
96
+ placeholder="Search products..."
97
+ value={searchQuery}
98
+ onChange={(e) => setSearchQuery(e.target.value)}
99
+ className="w-full pl-4 pr-12 py-3 border border-[var(--color-border)] bg-surface-muted focus:bg-surface focus:outline-none focus:ring-2 focus:ring-brand-accent transition-all"
100
+ autoFocus
101
+ />
102
+ <LocalizedClientLink
103
+ href={`/store?q=${encodeURIComponent(searchQuery)}`}
104
+ onClick={close}
105
+ className="absolute right-3 top-1/2 -translate-y-1/2 p-2 hover:bg-surface-muted transition-colors"
106
+ >
107
+ <Image
108
+ src="/Search.svg"
109
+ alt="Search"
110
+ width={20}
111
+ height={20}
112
+ className="w-5 h-5"
113
+ />
114
+ </LocalizedClientLink>
115
+ </div>
116
+ </div>
117
+
118
+ <div className="flex-1 overflow-y-auto p-6">
119
+ <div className="flex flex-col items-center justify-center py-12 text-center">
120
+ <p className="text-muted">Start typing to search...</p>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ </PopoverPanel>
125
+ </Transition>
126
+ </>
127
+ )
128
+ }}
129
+ </Popover>
130
+ </div>
131
+ </div>
132
+ )
133
+ }
134
+
135
+ export default SearchPanel
136
+
@@ -0,0 +1,144 @@
1
+ "use client"
2
+
3
+ import { Popover, PopoverPanel, Transition } from "@headlessui/react"
4
+ import { ArrowRightMini, XMark } from "@medusajs/icons"
5
+ import { Text, clx, useToggleState } from "@medusajs/ui"
6
+ import { Fragment } from "react"
7
+
8
+ import LocalizedClientLink from "@modules/common/components/localized-client-link"
9
+ import CountrySelect from "../country-select"
10
+ import LanguageSelect from "../language-select"
11
+ import { HttpTypes } from "@medusajs/types"
12
+ import { Locale } from "@core/data/locales"
13
+
14
+ const SideMenuItems = {
15
+ Home: "/",
16
+ Store: "/store",
17
+ Account: "/account",
18
+ Cart: "/cart",
19
+ }
20
+
21
+ type SideMenuProps = {
22
+ regions: HttpTypes.StoreRegion[] | null
23
+ locales: Locale[] | null
24
+ currentLocale: string | null
25
+ }
26
+
27
+ const SideMenu = ({ regions, locales, currentLocale }: SideMenuProps) => {
28
+ const countryToggleState = useToggleState()
29
+ const languageToggleState = useToggleState()
30
+
31
+ return (
32
+ <div className="h-full">
33
+ <div className="flex items-center h-full">
34
+ <Popover className="h-full flex">
35
+ {({ open, close }) => (
36
+ <>
37
+ <div className="relative flex h-full">
38
+ <Popover.Button
39
+ data-testid="nav-menu-button"
40
+ className="relative h-full flex items-center transition-all ease-out duration-200 focus:outline-none hover:text-ui-fg-base"
41
+ >
42
+ Menu
43
+ </Popover.Button>
44
+ </div>
45
+
46
+ {open && (
47
+ <div
48
+ className="fixed inset-0 z-[50] bg-black/0 pointer-events-auto"
49
+ onClick={close}
50
+ data-testid="side-menu-backdrop"
51
+ />
52
+ )}
53
+
54
+ <Transition
55
+ show={open}
56
+ as={Fragment}
57
+ enter="transition ease-out duration-150"
58
+ enterFrom="opacity-0"
59
+ enterTo="opacity-100 backdrop-blur-2xl"
60
+ leave="transition ease-in duration-150"
61
+ leaveFrom="opacity-100 backdrop-blur-2xl"
62
+ leaveTo="opacity-0"
63
+ >
64
+ <PopoverPanel className="flex flex-col absolute w-full pr-4 sm:pr-0 sm:w-1/3 2xl:w-1/4 sm:min-w-min h-[calc(100vh-1rem)] z-[51] inset-x-0 text-sm text-ui-fg-on-color m-2 backdrop-blur-2xl">
65
+ <div
66
+ data-testid="nav-menu-popup"
67
+ className="flex flex-col h-full bg-[rgba(3,7,18,0.5)] rounded-rounded justify-between p-6"
68
+ >
69
+ <div className="flex justify-end" id="xmark">
70
+ <button data-testid="close-menu-button" onClick={close}>
71
+ <XMark />
72
+ </button>
73
+ </div>
74
+ <ul className="flex flex-col gap-6 items-start justify-start">
75
+ {Object.entries(SideMenuItems).map(([name, href]) => {
76
+ return (
77
+ <li key={name}>
78
+ <LocalizedClientLink
79
+ href={href}
80
+ className="text-3xl leading-10 hover:text-ui-fg-disabled"
81
+ onClick={close}
82
+ data-testid={`${name.toLowerCase()}-link`}
83
+ >
84
+ {name}
85
+ </LocalizedClientLink>
86
+ </li>
87
+ )
88
+ })}
89
+ </ul>
90
+ <div className="flex flex-col gap-y-6">
91
+ {!!locales?.length && (
92
+ <div
93
+ className="flex justify-between"
94
+ onMouseEnter={languageToggleState.open}
95
+ onMouseLeave={languageToggleState.close}
96
+ >
97
+ <LanguageSelect
98
+ toggleState={languageToggleState}
99
+ locales={locales}
100
+ currentLocale={currentLocale}
101
+ />
102
+ <ArrowRightMini
103
+ className={clx(
104
+ "transition-transform duration-150",
105
+ languageToggleState.state ? "-rotate-90" : ""
106
+ )}
107
+ />
108
+ </div>
109
+ )}
110
+ <div
111
+ className="flex justify-between"
112
+ onMouseEnter={countryToggleState.open}
113
+ onMouseLeave={countryToggleState.close}
114
+ >
115
+ {regions && (
116
+ <CountrySelect
117
+ toggleState={countryToggleState}
118
+ regions={regions}
119
+ />
120
+ )}
121
+ <ArrowRightMini
122
+ className={clx(
123
+ "transition-transform duration-150",
124
+ countryToggleState.state ? "-rotate-90" : ""
125
+ )}
126
+ />
127
+ </div>
128
+ <Text className="flex justify-between txt-compact-small">
129
+ © {new Date().getFullYear()} Chocomelon. All rights
130
+ reserved.
131
+ </Text>
132
+ </div>
133
+ </div>
134
+ </PopoverPanel>
135
+ </Transition>
136
+ </>
137
+ )}
138
+ </Popover>
139
+ </div>
140
+ </div>
141
+ )
142
+ }
143
+
144
+ export default SideMenu