@salifbiaye/create-boutique 0.1.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 (316) hide show
  1. package/README.md +1 -0
  2. package/cli/dist/commands.js +382 -0
  3. package/cli/dist/create.js +194 -0
  4. package/cli/dist/docker.js +19 -0
  5. package/cli/dist/generate.js +322 -0
  6. package/cli/dist/guide.js +72 -0
  7. package/cli/dist/index.js +156 -0
  8. package/cli/dist/paths.js +29 -0
  9. package/cli/dist/ports.js +54 -0
  10. package/cli/dist/project.js +119 -0
  11. package/cli/dist/themes.js +24 -0
  12. package/docs/fiche-client.en.html +137 -0
  13. package/docs/fiche-client.html +137 -0
  14. package/docs/guide-complet.en.html +259 -0
  15. package/docs/guide-complet.fr.html +259 -0
  16. package/package.json +51 -0
  17. package/templates/backend/.dockerignore +9 -0
  18. package/templates/backend/Dockerfile +30 -0
  19. package/templates/backend/README.md +78 -0
  20. package/templates/backend/TEMPLATE_VERSION +1 -0
  21. package/templates/backend/docker/entrypoint.sh +28 -0
  22. package/templates/backend/instrumentation.ts +24 -0
  23. package/templates/backend/medusa-config.ts +114 -0
  24. package/templates/backend/package-lock.json +16222 -0
  25. package/templates/backend/package.json +39 -0
  26. package/templates/backend/src/admin/README.md +33 -0
  27. package/templates/backend/src/admin/components/image-field.tsx +61 -0
  28. package/templates/backend/src/admin/i18n/README.md +58 -0
  29. package/templates/backend/src/admin/i18n/index.ts +8 -0
  30. package/templates/backend/src/admin/i18n/json/en.json +66 -0
  31. package/templates/backend/src/admin/i18n/json/fr.json +66 -0
  32. package/templates/backend/src/admin/lib/client.ts +9 -0
  33. package/templates/backend/src/admin/routes/boutique-campaigns/campaign-drawer.tsx +286 -0
  34. package/templates/backend/src/admin/routes/boutique-campaigns/page.tsx +113 -0
  35. package/templates/backend/src/admin/tsconfig.json +24 -0
  36. package/templates/backend/src/admin/vite-env.d.ts +1 -0
  37. package/templates/backend/src/admin/widgets/category-image.tsx +56 -0
  38. package/templates/backend/src/api/README.md +135 -0
  39. package/templates/backend/src/api/admin/boutique-campaigns/[salesChannelId]/route.ts +30 -0
  40. package/templates/backend/src/api/admin/boutique-campaigns/route.ts +24 -0
  41. package/templates/backend/src/api/middlewares.ts +28 -0
  42. package/templates/backend/src/api/rate-limit.ts +30 -0
  43. package/templates/backend/src/api/route.ts +6 -0
  44. package/templates/backend/src/api/store/campaign/route.ts +25 -0
  45. package/templates/backend/src/api/store/order-lookup/route.ts +74 -0
  46. package/templates/backend/src/emails/en.json +64 -0
  47. package/templates/backend/src/emails/fr.json +64 -0
  48. package/templates/backend/src/jobs/README.md +38 -0
  49. package/templates/backend/src/lib/emails.ts +94 -0
  50. package/templates/backend/src/lib/notify.ts +148 -0
  51. package/templates/backend/src/lib/project.ts +146 -0
  52. package/templates/backend/src/links/README.md +26 -0
  53. package/templates/backend/src/links/campaign-sales-channel.ts +9 -0
  54. package/templates/backend/src/modules/README.md +117 -0
  55. package/templates/backend/src/modules/campaign/index.ts +9 -0
  56. package/templates/backend/src/modules/campaign/migrations/.snapshot-boutique-campaign.json +272 -0
  57. package/templates/backend/src/modules/campaign/migrations/Migration20260928141440.ts +16 -0
  58. package/templates/backend/src/modules/campaign/migrations/Migration20260928145243.ts +13 -0
  59. package/templates/backend/src/modules/campaign/models/campaign.ts +28 -0
  60. package/templates/backend/src/modules/campaign/service.ts +6 -0
  61. package/templates/backend/src/modules/campaign/validators.ts +94 -0
  62. package/templates/backend/src/modules/resend/index.ts +6 -0
  63. package/templates/backend/src/modules/resend/service.ts +63 -0
  64. package/templates/backend/src/scripts/README.md +63 -0
  65. package/templates/backend/src/scripts/campaign-export.ts +15 -0
  66. package/templates/backend/src/scripts/campaign-import.ts +38 -0
  67. package/templates/backend/src/scripts/price-report.ts +34 -0
  68. package/templates/backend/src/scripts/seed.ts +418 -0
  69. package/templates/backend/src/scripts/storage.ts +63 -0
  70. package/templates/backend/src/subscribers/README.md +61 -0
  71. package/templates/backend/src/subscribers/account-emails.ts +27 -0
  72. package/templates/backend/src/subscribers/fulfillment-emails.ts +42 -0
  73. package/templates/backend/src/subscribers/order-emails.ts +12 -0
  74. package/templates/backend/src/subscribers/return-refund-emails.ts +50 -0
  75. package/templates/backend/src/workflows/README.md +81 -0
  76. package/templates/backend/src/workflows/steps/upsert-campaign.ts +53 -0
  77. package/templates/backend/src/workflows/upsert-campaign.ts +30 -0
  78. package/templates/backend/tsconfig.json +36 -0
  79. package/templates/storefront/.dockerignore +7 -0
  80. package/templates/storefront/.github/ISSUE_TEMPLATE/bug-report.yml +71 -0
  81. package/templates/storefront/.prettierrc +8 -0
  82. package/templates/storefront/Dockerfile +37 -0
  83. package/templates/storefront/LICENSE +21 -0
  84. package/templates/storefront/README.md +127 -0
  85. package/templates/storefront/locales/en.json +269 -0
  86. package/templates/storefront/locales/fr.json +269 -0
  87. package/templates/storefront/next-env.d.ts +7 -0
  88. package/templates/storefront/next-sitemap.js +19 -0
  89. package/templates/storefront/next.config.js +29 -0
  90. package/templates/storefront/package-lock.json +9031 -0
  91. package/templates/storefront/package.json +49 -0
  92. package/templates/storefront/postcss.config.js +6 -0
  93. package/templates/storefront/public/favicon.ico +0 -0
  94. package/templates/storefront/scripts/sync-design.mjs +30 -0
  95. package/templates/storefront/src/app/(checkout)/checkout/page.tsx +31 -0
  96. package/templates/storefront/src/app/(checkout)/layout.tsx +29 -0
  97. package/templates/storefront/src/app/(checkout)/not-found.tsx +20 -0
  98. package/templates/storefront/src/app/(main)/account/@dashboard/addresses/page.tsx +34 -0
  99. package/templates/storefront/src/app/(main)/account/@dashboard/loading.tsx +9 -0
  100. package/templates/storefront/src/app/(main)/account/@dashboard/orders/details/[id]/page.tsx +33 -0
  101. package/templates/storefront/src/app/(main)/account/@dashboard/orders/page.tsx +37 -0
  102. package/templates/storefront/src/app/(main)/account/@dashboard/page.tsx +22 -0
  103. package/templates/storefront/src/app/(main)/account/@dashboard/profile/page.tsx +53 -0
  104. package/templates/storefront/src/app/(main)/account/@login/page.tsx +12 -0
  105. package/templates/storefront/src/app/(main)/account/layout.tsx +20 -0
  106. package/templates/storefront/src/app/(main)/account/loading.tsx +9 -0
  107. package/templates/storefront/src/app/(main)/cart/loading.tsx +5 -0
  108. package/templates/storefront/src/app/(main)/cart/not-found.tsx +21 -0
  109. package/templates/storefront/src/app/(main)/cart/page.tsx +21 -0
  110. package/templates/storefront/src/app/(main)/categories/[...category]/page.tsx +55 -0
  111. package/templates/storefront/src/app/(main)/collections/[handle]/page.tsx +55 -0
  112. package/templates/storefront/src/app/(main)/layout.tsx +43 -0
  113. package/templates/storefront/src/app/(main)/legal/[page]/page.tsx +42 -0
  114. package/templates/storefront/src/app/(main)/not-found.tsx +21 -0
  115. package/templates/storefront/src/app/(main)/order/[id]/confirmed/loading.tsx +5 -0
  116. package/templates/storefront/src/app/(main)/order/[id]/confirmed/page.tsx +23 -0
  117. package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/accept/page.tsx +42 -0
  118. package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/decline/page.tsx +42 -0
  119. package/templates/storefront/src/app/(main)/order/[id]/transfer/[token]/page.tsx +35 -0
  120. package/templates/storefront/src/app/(main)/order/track/page.tsx +32 -0
  121. package/templates/storefront/src/app/(main)/page.tsx +68 -0
  122. package/templates/storefront/src/app/(main)/products/[handle]/page.tsx +86 -0
  123. package/templates/storefront/src/app/(main)/store/page.tsx +28 -0
  124. package/templates/storefront/src/app/api/health/route.ts +13 -0
  125. package/templates/storefront/src/app/layout.tsx +42 -0
  126. package/templates/storefront/src/app/not-found.tsx +21 -0
  127. package/templates/storefront/src/app/opengraph-image.jpg +0 -0
  128. package/templates/storefront/src/app/twitter-image.jpg +0 -0
  129. package/templates/storefront/src/instrumentation-node.ts +18 -0
  130. package/templates/storefront/src/instrumentation.ts +9 -0
  131. package/templates/storefront/src/lib/boutique/campaign.ts +116 -0
  132. package/templates/storefront/src/lib/boutique/config.ts +152 -0
  133. package/templates/storefront/src/lib/boutique/fonts.ts +29 -0
  134. package/templates/storefront/src/lib/boutique/i18n-client.tsx +34 -0
  135. package/templates/storefront/src/lib/boutique/i18n.ts +43 -0
  136. package/templates/storefront/src/lib/boutique/schema.ts +131 -0
  137. package/templates/storefront/src/lib/config.ts +39 -0
  138. package/templates/storefront/src/lib/constants.tsx +75 -0
  139. package/templates/storefront/src/lib/context/modal-context.tsx +34 -0
  140. package/templates/storefront/src/lib/data/cart.ts +434 -0
  141. package/templates/storefront/src/lib/data/categories.ts +49 -0
  142. package/templates/storefront/src/lib/data/collections.ts +59 -0
  143. package/templates/storefront/src/lib/data/cookies.ts +103 -0
  144. package/templates/storefront/src/lib/data/customer.ts +261 -0
  145. package/templates/storefront/src/lib/data/fulfillment.ts +68 -0
  146. package/templates/storefront/src/lib/data/onboarding.ts +9 -0
  147. package/templates/storefront/src/lib/data/order-lookup.ts +34 -0
  148. package/templates/storefront/src/lib/data/orders.ts +112 -0
  149. package/templates/storefront/src/lib/data/payment.ts +35 -0
  150. package/templates/storefront/src/lib/data/products.ts +127 -0
  151. package/templates/storefront/src/lib/data/regions.ts +70 -0
  152. package/templates/storefront/src/lib/data/variants.ts +38 -0
  153. package/templates/storefront/src/lib/hooks/use-in-view.tsx +29 -0
  154. package/templates/storefront/src/lib/hooks/use-toggle-state.tsx +46 -0
  155. package/templates/storefront/src/lib/util/compare-addresses.ts +28 -0
  156. package/templates/storefront/src/lib/util/get-percentage-diff.ts +6 -0
  157. package/templates/storefront/src/lib/util/get-product-price.ts +79 -0
  158. package/templates/storefront/src/lib/util/isEmpty.ts +11 -0
  159. package/templates/storefront/src/lib/util/medusa-error.ts +22 -0
  160. package/templates/storefront/src/lib/util/money.ts +35 -0
  161. package/templates/storefront/src/lib/util/product.ts +5 -0
  162. package/templates/storefront/src/lib/util/repeat.ts +5 -0
  163. package/templates/storefront/src/lib/util/sort-products.ts +50 -0
  164. package/templates/storefront/src/modules/account/components/account-info/index.tsx +140 -0
  165. package/templates/storefront/src/modules/account/components/account-nav/index.tsx +198 -0
  166. package/templates/storefront/src/modules/account/components/address-book/index.tsx +28 -0
  167. package/templates/storefront/src/modules/account/components/address-card/add-address.tsx +169 -0
  168. package/templates/storefront/src/modules/account/components/address-card/edit-address-modal.tsx +241 -0
  169. package/templates/storefront/src/modules/account/components/login/index.tsx +65 -0
  170. package/templates/storefront/src/modules/account/components/order-card/index.tsx +88 -0
  171. package/templates/storefront/src/modules/account/components/order-overview/index.tsx +47 -0
  172. package/templates/storefront/src/modules/account/components/overview/index.tsx +169 -0
  173. package/templates/storefront/src/modules/account/components/profile-billing-address/index.tsx +193 -0
  174. package/templates/storefront/src/modules/account/components/profile-email/index.tsx +75 -0
  175. package/templates/storefront/src/modules/account/components/profile-name/index.tsx +79 -0
  176. package/templates/storefront/src/modules/account/components/profile-password/index.tsx +72 -0
  177. package/templates/storefront/src/modules/account/components/profile-phone/index.tsx +74 -0
  178. package/templates/storefront/src/modules/account/components/register/index.tsx +107 -0
  179. package/templates/storefront/src/modules/account/components/transfer-request-form/index.tsx +83 -0
  180. package/templates/storefront/src/modules/account/templates/account-layout.tsx +43 -0
  181. package/templates/storefront/src/modules/account/templates/login-template.tsx +27 -0
  182. package/templates/storefront/src/modules/cart/components/cart-item-select/index.tsx +75 -0
  183. package/templates/storefront/src/modules/cart/components/empty-cart-message/index.tsx +25 -0
  184. package/templates/storefront/src/modules/cart/components/item/index.tsx +144 -0
  185. package/templates/storefront/src/modules/cart/components/sign-in-prompt/index.tsx +27 -0
  186. package/templates/storefront/src/modules/cart/templates/index.tsx +51 -0
  187. package/templates/storefront/src/modules/cart/templates/items.tsx +58 -0
  188. package/templates/storefront/src/modules/cart/templates/preview.tsx +51 -0
  189. package/templates/storefront/src/modules/cart/templates/summary.tsx +50 -0
  190. package/templates/storefront/src/modules/categories/templates/index.tsx +94 -0
  191. package/templates/storefront/src/modules/checkout/components/address-select/index.tsx +117 -0
  192. package/templates/storefront/src/modules/checkout/components/addresses/index.tsx +186 -0
  193. package/templates/storefront/src/modules/checkout/components/billing_address/index.tsx +114 -0
  194. package/templates/storefront/src/modules/checkout/components/country-select/index.tsx +50 -0
  195. package/templates/storefront/src/modules/checkout/components/discount-code/index.tsx +181 -0
  196. package/templates/storefront/src/modules/checkout/components/error-message/index.tsx +13 -0
  197. package/templates/storefront/src/modules/checkout/components/payment/index.tsx +261 -0
  198. package/templates/storefront/src/modules/checkout/components/payment-button/index.tsx +195 -0
  199. package/templates/storefront/src/modules/checkout/components/payment-container/index.tsx +130 -0
  200. package/templates/storefront/src/modules/checkout/components/payment-test/index.tsx +12 -0
  201. package/templates/storefront/src/modules/checkout/components/payment-wrapper/index.tsx +42 -0
  202. package/templates/storefront/src/modules/checkout/components/payment-wrapper/stripe-wrapper.tsx +54 -0
  203. package/templates/storefront/src/modules/checkout/components/review/index.tsx +54 -0
  204. package/templates/storefront/src/modules/checkout/components/shipping/index.tsx +417 -0
  205. package/templates/storefront/src/modules/checkout/components/shipping-address/index.tsx +219 -0
  206. package/templates/storefront/src/modules/checkout/components/submit-button/index.tsx +32 -0
  207. package/templates/storefront/src/modules/checkout/templates/checkout-form/index.tsx +38 -0
  208. package/templates/storefront/src/modules/checkout/templates/checkout-summary/index.tsx +31 -0
  209. package/templates/storefront/src/modules/collections/templates/index.tsx +44 -0
  210. package/templates/storefront/src/modules/common/components/cart-totals/index.tsx +84 -0
  211. package/templates/storefront/src/modules/common/components/checkbox/index.tsx +44 -0
  212. package/templates/storefront/src/modules/common/components/delete-button/index.tsx +42 -0
  213. package/templates/storefront/src/modules/common/components/divider/index.tsx +9 -0
  214. package/templates/storefront/src/modules/common/components/filter-radio-group/index.tsx +61 -0
  215. package/templates/storefront/src/modules/common/components/input/index.tsx +79 -0
  216. package/templates/storefront/src/modules/common/components/interactive-link/index.tsx +33 -0
  217. package/templates/storefront/src/modules/common/components/line-item-options/index.tsx +26 -0
  218. package/templates/storefront/src/modules/common/components/line-item-price/index.tsx +63 -0
  219. package/templates/storefront/src/modules/common/components/line-item-unit-price/index.tsx +62 -0
  220. package/templates/storefront/src/modules/common/components/localized-client-link/index.tsx +29 -0
  221. package/templates/storefront/src/modules/common/components/modal/index.tsx +118 -0
  222. package/templates/storefront/src/modules/common/components/native-select/index.tsx +76 -0
  223. package/templates/storefront/src/modules/common/components/radio/index.tsx +27 -0
  224. package/templates/storefront/src/modules/common/icons/back.tsx +37 -0
  225. package/templates/storefront/src/modules/common/icons/bancontact.tsx +26 -0
  226. package/templates/storefront/src/modules/common/icons/chevron-down.tsx +30 -0
  227. package/templates/storefront/src/modules/common/icons/eye-off.tsx +37 -0
  228. package/templates/storefront/src/modules/common/icons/eye.tsx +37 -0
  229. package/templates/storefront/src/modules/common/icons/fast-delivery.tsx +65 -0
  230. package/templates/storefront/src/modules/common/icons/ideal.tsx +26 -0
  231. package/templates/storefront/src/modules/common/icons/map-pin.tsx +37 -0
  232. package/templates/storefront/src/modules/common/icons/package.tsx +44 -0
  233. package/templates/storefront/src/modules/common/icons/paypal.tsx +30 -0
  234. package/templates/storefront/src/modules/common/icons/placeholder-image.tsx +44 -0
  235. package/templates/storefront/src/modules/common/icons/refresh.tsx +51 -0
  236. package/templates/storefront/src/modules/common/icons/spinner.tsx +37 -0
  237. package/templates/storefront/src/modules/common/icons/trash.tsx +51 -0
  238. package/templates/storefront/src/modules/common/icons/user.tsx +37 -0
  239. package/templates/storefront/src/modules/common/icons/x.tsx +37 -0
  240. package/templates/storefront/src/modules/layout/components/cart-mismatch-banner/index.tsx +59 -0
  241. package/templates/storefront/src/modules/order/components/help/index.tsx +26 -0
  242. package/templates/storefront/src/modules/order/components/item/index.tsx +57 -0
  243. package/templates/storefront/src/modules/order/components/items/index.tsx +44 -0
  244. package/templates/storefront/src/modules/order/components/onboarding-cta/index.tsx +28 -0
  245. package/templates/storefront/src/modules/order/components/order-details/index.tsx +64 -0
  246. package/templates/storefront/src/modules/order/components/order-summary/index.tsx +61 -0
  247. package/templates/storefront/src/modules/order/components/payment-details/index.tsx +64 -0
  248. package/templates/storefront/src/modules/order/components/shipping-details/index.tsx +74 -0
  249. package/templates/storefront/src/modules/order/components/transfer-actions/index.tsx +83 -0
  250. package/templates/storefront/src/modules/order/components/transfer-image/index.tsx +275 -0
  251. package/templates/storefront/src/modules/order/templates/order-completed-template.tsx +53 -0
  252. package/templates/storefront/src/modules/order/templates/order-details-template.tsx +46 -0
  253. package/templates/storefront/src/modules/products/components/thumbnail/index.tsx +70 -0
  254. package/templates/storefront/src/modules/products/templates/index.tsx +118 -0
  255. package/templates/storefront/src/modules/shipping/components/free-shipping-price-nudge/index.tsx +285 -0
  256. package/templates/storefront/src/modules/skeletons/components/skeleton-button/index.tsx +5 -0
  257. package/templates/storefront/src/modules/skeletons/components/skeleton-card-details/index.tsx +10 -0
  258. package/templates/storefront/src/modules/skeletons/components/skeleton-cart-item/index.tsx +35 -0
  259. package/templates/storefront/src/modules/skeletons/components/skeleton-cart-totals/index.tsx +30 -0
  260. package/templates/storefront/src/modules/skeletons/components/skeleton-code-form/index.tsx +13 -0
  261. package/templates/storefront/src/modules/skeletons/components/skeleton-line-item/index.tsx +35 -0
  262. package/templates/storefront/src/modules/skeletons/components/skeleton-order-confirmed-header/index.tsx +14 -0
  263. package/templates/storefront/src/modules/skeletons/components/skeleton-order-information/index.tsx +36 -0
  264. package/templates/storefront/src/modules/skeletons/components/skeleton-order-items/index.tsx +43 -0
  265. package/templates/storefront/src/modules/skeletons/components/skeleton-order-summary/index.tsx +15 -0
  266. package/templates/storefront/src/modules/skeletons/components/skeleton-product-preview/index.tsx +15 -0
  267. package/templates/storefront/src/modules/skeletons/templates/skeleton-cart-page/index.tsx +65 -0
  268. package/templates/storefront/src/modules/skeletons/templates/skeleton-order-confirmed/index.tsx +21 -0
  269. package/templates/storefront/src/modules/skeletons/templates/skeleton-product-grid/index.tsx +23 -0
  270. package/templates/storefront/src/modules/store/components/pagination/index.tsx +114 -0
  271. package/templates/storefront/src/modules/store/components/refinement-list/index.tsx +41 -0
  272. package/templates/storefront/src/modules/store/components/refinement-list/sort-products/index.tsx +48 -0
  273. package/templates/storefront/src/modules/store/templates/index.tsx +42 -0
  274. package/templates/storefront/src/modules/store/templates/paginated-products.tsx +80 -0
  275. package/templates/storefront/src/modules/ub/button.tsx +41 -0
  276. package/templates/storefront/src/modules/ub/campaign-blocks.tsx +197 -0
  277. package/templates/storefront/src/modules/ub/campaign-ended.tsx +28 -0
  278. package/templates/storefront/src/modules/ub/category-tiles.tsx +41 -0
  279. package/templates/storefront/src/modules/ub/countdown.tsx +46 -0
  280. package/templates/storefront/src/modules/ub/footer.tsx +56 -0
  281. package/templates/storefront/src/modules/ub/icons.tsx +42 -0
  282. package/templates/storefront/src/modules/ub/nav.tsx +90 -0
  283. package/templates/storefront/src/modules/ub/pdp/buy-box.tsx +140 -0
  284. package/templates/storefront/src/modules/ub/pdp/gallery.tsx +40 -0
  285. package/templates/storefront/src/modules/ub/product-card.tsx +66 -0
  286. package/templates/storefront/src/modules/ub/top-bar.tsx +20 -0
  287. package/templates/storefront/src/modules/ub/track-form.tsx +92 -0
  288. package/templates/storefront/src/proxy.ts +89 -0
  289. package/templates/storefront/src/styles/globals.css +98 -0
  290. package/templates/storefront/src/styles/ub/bundle.css +372 -0
  291. package/templates/storefront/src/styles/ub/fonts.css +17 -0
  292. package/templates/storefront/src/styles/ub/medusa-ui.css +90 -0
  293. package/templates/storefront/src/styles/ub/overrides.css +12 -0
  294. package/templates/storefront/src/styles/ub/tokens.css +9 -0
  295. package/templates/storefront/src/types/global.ts +24 -0
  296. package/templates/storefront/src/types/icon.ts +4 -0
  297. package/templates/storefront/tailwind.config.js +164 -0
  298. package/templates/storefront/themes/black-friday/campaign.en.json +31 -0
  299. package/templates/storefront/themes/black-friday/campaign.fr.json +31 -0
  300. package/templates/storefront/themes/black-friday/theme.json +9 -0
  301. package/templates/storefront/themes/cyber-monday/campaign.en.json +31 -0
  302. package/templates/storefront/themes/cyber-monday/campaign.fr.json +31 -0
  303. package/templates/storefront/themes/cyber-monday/theme.json +9 -0
  304. package/templates/storefront/themes/halloween/campaign.en.json +31 -0
  305. package/templates/storefront/themes/halloween/campaign.fr.json +31 -0
  306. package/templates/storefront/themes/halloween/theme.json +9 -0
  307. package/templates/storefront/themes/noel/campaign.en.json +31 -0
  308. package/templates/storefront/themes/noel/campaign.fr.json +31 -0
  309. package/templates/storefront/themes/noel/theme.json +9 -0
  310. package/templates/storefront/themes/nouvel-an/campaign.en.json +31 -0
  311. package/templates/storefront/themes/nouvel-an/campaign.fr.json +31 -0
  312. package/templates/storefront/themes/nouvel-an/theme.json +9 -0
  313. package/templates/storefront/themes/thanksgiving/campaign.en.json +31 -0
  314. package/templates/storefront/themes/thanksgiving/campaign.fr.json +31 -0
  315. package/templates/storefront/themes/thanksgiving/theme.json +9 -0
  316. package/templates/storefront/tsconfig.json +53 -0
@@ -0,0 +1,261 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@lib/config"
4
+ import medusaError from "@lib/util/medusa-error"
5
+ import { HttpTypes } from "@medusajs/types"
6
+ import { updateTag } from "next/cache"
7
+ import { redirect } from "next/navigation"
8
+ import {
9
+ getAuthHeaders,
10
+ getCacheOptions,
11
+ getCacheTag,
12
+ getCartId,
13
+ removeAuthToken,
14
+ removeCartId,
15
+ setAuthToken,
16
+ } from "./cookies"
17
+
18
+ export const retrieveCustomer =
19
+ async (): Promise<HttpTypes.StoreCustomer | null> => {
20
+ const authHeaders = await getAuthHeaders()
21
+
22
+ if (!authHeaders) return null
23
+
24
+ const headers = {
25
+ ...authHeaders,
26
+ }
27
+
28
+ const next = {
29
+ ...(await getCacheOptions("customers")),
30
+ }
31
+
32
+ return await sdk.client
33
+ .fetch<{ customer: HttpTypes.StoreCustomer }>(`/store/customers/me`, {
34
+ method: "GET",
35
+ query: {
36
+ fields: "*orders",
37
+ },
38
+ headers,
39
+ next,
40
+ cache: "force-cache",
41
+ })
42
+ .then(({ customer }) => customer)
43
+ .catch(() => null)
44
+ }
45
+
46
+ export const updateCustomer = async (body: HttpTypes.StoreUpdateCustomer) => {
47
+ const headers = {
48
+ ...(await getAuthHeaders()),
49
+ }
50
+
51
+ const updateRes = await sdk.store.customer
52
+ .update(body, {}, headers)
53
+ .then(({ customer }) => customer)
54
+ .catch(medusaError)
55
+
56
+ const cacheTag = await getCacheTag("customers")
57
+ updateTag(cacheTag)
58
+
59
+ return updateRes
60
+ }
61
+
62
+ export async function signup(_currentState: unknown, formData: FormData) {
63
+ const password = formData.get("password") as string
64
+ const customerForm = {
65
+ email: formData.get("email") as string,
66
+ first_name: formData.get("first_name") as string,
67
+ last_name: formData.get("last_name") as string,
68
+ phone: formData.get("phone") as string,
69
+ }
70
+
71
+ try {
72
+ const token = await sdk.auth.register("customer", "emailpass", {
73
+ email: customerForm.email,
74
+ password: password,
75
+ })
76
+
77
+ await setAuthToken(token as string)
78
+
79
+ const headers = {
80
+ ...(await getAuthHeaders()),
81
+ }
82
+
83
+ const { customer: createdCustomer } = await sdk.store.customer.create(
84
+ customerForm,
85
+ {},
86
+ headers
87
+ )
88
+
89
+ const loginToken = await sdk.auth.login("customer", "emailpass", {
90
+ email: customerForm.email,
91
+ password,
92
+ })
93
+
94
+ await setAuthToken(loginToken as string)
95
+
96
+ const customerCacheTag = await getCacheTag("customers")
97
+ updateTag(customerCacheTag)
98
+
99
+ await transferCart()
100
+
101
+ return createdCustomer
102
+ } catch (error: any) {
103
+ return error.toString()
104
+ }
105
+ }
106
+
107
+ export async function login(_currentState: unknown, formData: FormData) {
108
+ const email = formData.get("email") as string
109
+ const password = formData.get("password") as string
110
+
111
+ try {
112
+ await sdk.auth
113
+ .login("customer", "emailpass", { email, password })
114
+ .then(async (token) => {
115
+ await setAuthToken(token as string)
116
+ const customerCacheTag = await getCacheTag("customers")
117
+ updateTag(customerCacheTag)
118
+ })
119
+ } catch (error: any) {
120
+ return error.toString()
121
+ }
122
+
123
+ try {
124
+ await transferCart()
125
+ } catch (error: any) {
126
+ return error.toString()
127
+ }
128
+ }
129
+
130
+ export async function signout() {
131
+ await sdk.auth.logout()
132
+
133
+ await removeAuthToken()
134
+
135
+ const customerCacheTag = await getCacheTag("customers")
136
+ updateTag(customerCacheTag)
137
+
138
+ await removeCartId()
139
+
140
+ const cartCacheTag = await getCacheTag("carts")
141
+ updateTag(cartCacheTag)
142
+
143
+ redirect(`/account`)
144
+ }
145
+
146
+ export async function transferCart() {
147
+ const cartId = await getCartId()
148
+
149
+ if (!cartId) {
150
+ return
151
+ }
152
+
153
+ const headers = await getAuthHeaders()
154
+
155
+ await sdk.store.cart.transferCart(cartId, {}, headers)
156
+
157
+ const cartCacheTag = await getCacheTag("carts")
158
+ updateTag(cartCacheTag)
159
+ }
160
+
161
+ export const addCustomerAddress = async (
162
+ currentState: Record<string, unknown>,
163
+ formData: FormData
164
+ ): Promise<any> => {
165
+ const isDefaultBilling = (currentState.isDefaultBilling as boolean) || false
166
+ const isDefaultShipping = (currentState.isDefaultShipping as boolean) || false
167
+
168
+ const address = {
169
+ first_name: formData.get("first_name") as string,
170
+ last_name: formData.get("last_name") as string,
171
+ company: formData.get("company") as string,
172
+ address_1: formData.get("address_1") as string,
173
+ address_2: formData.get("address_2") as string,
174
+ city: formData.get("city") as string,
175
+ postal_code: formData.get("postal_code") as string,
176
+ province: formData.get("province") as string,
177
+ country_code: formData.get("country_code") as string,
178
+ phone: formData.get("phone") as string,
179
+ is_default_billing: isDefaultBilling,
180
+ is_default_shipping: isDefaultShipping,
181
+ }
182
+
183
+ const headers = {
184
+ ...(await getAuthHeaders()),
185
+ }
186
+
187
+ return sdk.store.customer
188
+ .createAddress(address, {}, headers)
189
+ .then(async ({ customer }) => {
190
+ const customerCacheTag = await getCacheTag("customers")
191
+ updateTag(customerCacheTag)
192
+ return { success: true, error: null }
193
+ })
194
+ .catch((err) => {
195
+ return { success: false, error: err.toString() }
196
+ })
197
+ }
198
+
199
+ export const deleteCustomerAddress = async (
200
+ addressId: string
201
+ ): Promise<void> => {
202
+ const headers = {
203
+ ...(await getAuthHeaders()),
204
+ }
205
+
206
+ await sdk.store.customer
207
+ .deleteAddress(addressId, headers)
208
+ .then(async () => {
209
+ const customerCacheTag = await getCacheTag("customers")
210
+ updateTag(customerCacheTag)
211
+ return { success: true, error: null }
212
+ })
213
+ .catch((err) => {
214
+ return { success: false, error: err.toString() }
215
+ })
216
+ }
217
+
218
+ export const updateCustomerAddress = async (
219
+ currentState: Record<string, unknown>,
220
+ formData: FormData
221
+ ): Promise<any> => {
222
+ const addressId =
223
+ (currentState.addressId as string) || (formData.get("addressId") as string)
224
+
225
+ if (!addressId) {
226
+ return { success: false, error: "Address ID is required" }
227
+ }
228
+
229
+ const address = {
230
+ first_name: formData.get("first_name") as string,
231
+ last_name: formData.get("last_name") as string,
232
+ company: formData.get("company") as string,
233
+ address_1: formData.get("address_1") as string,
234
+ address_2: formData.get("address_2") as string,
235
+ city: formData.get("city") as string,
236
+ postal_code: formData.get("postal_code") as string,
237
+ province: formData.get("province") as string,
238
+ country_code: formData.get("country_code") as string,
239
+ } as HttpTypes.StoreUpdateCustomerAddress
240
+
241
+ const phone = formData.get("phone") as string
242
+
243
+ if (phone) {
244
+ address.phone = phone
245
+ }
246
+
247
+ const headers = {
248
+ ...(await getAuthHeaders()),
249
+ }
250
+
251
+ return sdk.store.customer
252
+ .updateAddress(addressId, address, {}, headers)
253
+ .then(async () => {
254
+ const customerCacheTag = await getCacheTag("customers")
255
+ updateTag(customerCacheTag)
256
+ return { success: true, error: null }
257
+ })
258
+ .catch((err) => {
259
+ return { success: false, error: err.toString() }
260
+ })
261
+ }
@@ -0,0 +1,68 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@lib/config"
4
+ import { HttpTypes } from "@medusajs/types"
5
+ import { getAuthHeaders, getCacheOptions } from "./cookies"
6
+
7
+ export const listCartShippingMethods = async (cartId: string) => {
8
+ const headers = {
9
+ ...(await getAuthHeaders()),
10
+ }
11
+
12
+ const next = {
13
+ ...(await getCacheOptions("fulfillment")),
14
+ }
15
+
16
+ return sdk.client
17
+ .fetch<HttpTypes.StoreShippingOptionListResponse>(
18
+ `/store/shipping-options`,
19
+ {
20
+ method: "GET",
21
+ query: {
22
+ cart_id: cartId,
23
+ },
24
+ headers,
25
+ next,
26
+ cache: "force-cache",
27
+ }
28
+ )
29
+ .then(({ shipping_options }) => shipping_options)
30
+ .catch(() => {
31
+ return null
32
+ })
33
+ }
34
+
35
+ export const calculatePriceForShippingOption = async (
36
+ optionId: string,
37
+ cartId: string,
38
+ data?: Record<string, unknown>
39
+ ) => {
40
+ const headers = {
41
+ ...(await getAuthHeaders()),
42
+ }
43
+
44
+ const next = {
45
+ ...(await getCacheOptions("fulfillment")),
46
+ }
47
+
48
+ const body = { cart_id: cartId, data }
49
+
50
+ if (data) {
51
+ body.data = data
52
+ }
53
+
54
+ return sdk.client
55
+ .fetch<{ shipping_option: HttpTypes.StoreCartShippingOption }>(
56
+ `/store/shipping-options/${optionId}/calculate`,
57
+ {
58
+ method: "POST",
59
+ body,
60
+ headers,
61
+ next,
62
+ }
63
+ )
64
+ .then(({ shipping_option }) => shipping_option)
65
+ .catch((e) => {
66
+ return null
67
+ })
68
+ }
@@ -0,0 +1,9 @@
1
+ "use server"
2
+ import { cookies as nextCookies } from "next/headers"
3
+ import { redirect } from "next/navigation"
4
+
5
+ export async function resetOnboardingState(orderId: string) {
6
+ const cookies = await nextCookies()
7
+ cookies.set("_medusa_onboarding", "false", { maxAge: -1 })
8
+ redirect(`http://localhost:7001/a/orders/${orderId}`)
9
+ }
@@ -0,0 +1,34 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@lib/config"
4
+
5
+ export type TrackedOrder = {
6
+ number: number
7
+ created_at: string
8
+ step: "placed" | "shipped" | "delivered" | "canceled"
9
+ currency_code: string
10
+ total: number
11
+ items: { title: string; variant?: string | null; quantity: number }[]
12
+ shipments: { shipped_at?: string | null; delivered_at?: string | null; tracking: { number?: string; url?: string }[] }[]
13
+ }
14
+
15
+ export type TrackState = { order?: TrackedOrder; error?: "notFound" | "tooMany" | "invalid" }
16
+
17
+ /** Suivi de commande sans compte : n° + e-mail, vérifiés par le backend (boutique courante uniquement). */
18
+ export async function trackOrder(_prev: TrackState, form: FormData): Promise<TrackState> {
19
+ const number = Number(String(form.get("number") ?? "").replace(/\D/g, ""))
20
+ const email = String(form.get("email") ?? "").trim()
21
+ if (!number || !/^\S+@\S+\.\S+$/.test(email)) return { error: "invalid" }
22
+
23
+ try {
24
+ const { order } = await sdk.client.fetch<{ order: TrackedOrder }>("/store/order-lookup", {
25
+ method: "POST",
26
+ body: { number, email },
27
+ cache: "no-store",
28
+ })
29
+ return { order }
30
+ } catch (e) {
31
+ const status = (e as { status?: number }).status
32
+ return { error: status === 429 ? "tooMany" : "notFound" }
33
+ }
34
+ }
@@ -0,0 +1,112 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@lib/config"
4
+ import medusaError from "@lib/util/medusa-error"
5
+ import { getAuthHeaders, getCacheOptions } from "./cookies"
6
+ import { HttpTypes } from "@medusajs/types"
7
+
8
+ export const retrieveOrder = async (id: string) => {
9
+ const headers = {
10
+ ...(await getAuthHeaders()),
11
+ }
12
+
13
+ const next = {
14
+ ...(await getCacheOptions("orders")),
15
+ }
16
+
17
+ return sdk.client
18
+ .fetch<HttpTypes.StoreOrderResponse>(`/store/orders/${id}`, {
19
+ method: "GET",
20
+ query: {
21
+ fields:
22
+ "*payment_collections.payments,*items,*items.metadata,*items.variant,*items.product",
23
+ },
24
+ headers,
25
+ next,
26
+ cache: "force-cache",
27
+ })
28
+ .then(({ order }) => order)
29
+ .catch((err) => medusaError(err))
30
+ }
31
+
32
+ export const listOrders = async (
33
+ limit: number = 10,
34
+ offset: number = 0,
35
+ filters?: Record<string, any>
36
+ ) => {
37
+ const headers = {
38
+ ...(await getAuthHeaders()),
39
+ }
40
+
41
+ const next = {
42
+ ...(await getCacheOptions("orders")),
43
+ }
44
+
45
+ return sdk.client
46
+ .fetch<HttpTypes.StoreOrderListResponse>(`/store/orders`, {
47
+ method: "GET",
48
+ query: {
49
+ limit,
50
+ offset,
51
+ order: "-created_at",
52
+ fields: "*items,+items.metadata,*items.variant,*items.product",
53
+ ...filters,
54
+ },
55
+ headers,
56
+ next,
57
+ cache: "force-cache",
58
+ })
59
+ .then(({ orders }) => orders)
60
+ .catch((err) => medusaError(err))
61
+ }
62
+
63
+ export const createTransferRequest = async (
64
+ state: {
65
+ success: boolean
66
+ error: string | null
67
+ order: HttpTypes.StoreOrder | null
68
+ },
69
+ formData: FormData
70
+ ): Promise<{
71
+ success: boolean
72
+ error: string | null
73
+ order: HttpTypes.StoreOrder | null
74
+ }> => {
75
+ const id = formData.get("order_id") as string
76
+
77
+ if (!id) {
78
+ return { success: false, error: "Order ID is required", order: null }
79
+ }
80
+
81
+ const headers = await getAuthHeaders()
82
+
83
+ return await sdk.store.order
84
+ .requestTransfer(
85
+ id,
86
+ {},
87
+ {
88
+ fields: "id, email",
89
+ },
90
+ headers
91
+ )
92
+ .then(({ order }) => ({ success: true, error: null, order }))
93
+ .catch((err) => ({ success: false, error: err.message, order: null }))
94
+ }
95
+
96
+ export const acceptTransferRequest = async (id: string, token: string) => {
97
+ const headers = await getAuthHeaders()
98
+
99
+ return await sdk.store.order
100
+ .acceptTransfer(id, { token }, {}, headers)
101
+ .then(({ order }) => ({ success: true, error: null, order }))
102
+ .catch((err) => ({ success: false, error: err.message, order: null }))
103
+ }
104
+
105
+ export const declineTransferRequest = async (id: string, token: string) => {
106
+ const headers = await getAuthHeaders()
107
+
108
+ return await sdk.store.order
109
+ .declineTransfer(id, { token }, {}, headers)
110
+ .then(({ order }) => ({ success: true, error: null, order }))
111
+ .catch((err) => ({ success: false, error: err.message, order: null }))
112
+ }
@@ -0,0 +1,35 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@lib/config"
4
+ import { getAuthHeaders, getCacheOptions } from "./cookies"
5
+ import { HttpTypes } from "@medusajs/types"
6
+
7
+ export const listCartPaymentMethods = async (regionId: string) => {
8
+ const headers = {
9
+ ...(await getAuthHeaders()),
10
+ }
11
+
12
+ const next = {
13
+ ...(await getCacheOptions("payment_providers")),
14
+ }
15
+
16
+ return sdk.client
17
+ .fetch<HttpTypes.StorePaymentProviderListResponse>(
18
+ `/store/payment-providers`,
19
+ {
20
+ method: "GET",
21
+ query: { region_id: regionId },
22
+ headers,
23
+ next,
24
+ cache: "force-cache",
25
+ }
26
+ )
27
+ .then(({ payment_providers }) =>
28
+ payment_providers.sort((a, b) => {
29
+ return a.id > b.id ? 1 : -1
30
+ })
31
+ )
32
+ .catch(() => {
33
+ return null
34
+ })
35
+ }
@@ -0,0 +1,127 @@
1
+ "use server"
2
+
3
+ import { sdk } from "@lib/config"
4
+ import { sortProducts } from "@lib/util/sort-products"
5
+ import { HttpTypes } from "@medusajs/types"
6
+ import { SortOptions } from "@modules/store/components/refinement-list/sort-products"
7
+ import { getAuthHeaders, getCacheOptions } from "./cookies"
8
+ import { getRegion, retrieveRegion } from "./regions"
9
+
10
+ export const listProducts = async ({
11
+ pageParam = 1,
12
+ queryParams,
13
+ regionId,
14
+ }: {
15
+ pageParam?: number
16
+ queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductListParams
17
+ regionId?: string
18
+ }): Promise<{
19
+ response: { products: HttpTypes.StoreProduct[]; count: number }
20
+ nextPage: number | null
21
+ queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductListParams
22
+ }> => {
23
+ const limit = queryParams?.limit || 12
24
+ const _pageParam = Math.max(pageParam, 1)
25
+ const offset = _pageParam === 1 ? 0 : (_pageParam - 1) * limit
26
+
27
+ let region: HttpTypes.StoreRegion | undefined | null
28
+
29
+ if (regionId) {
30
+ region = await retrieveRegion(regionId)
31
+ } else {
32
+ region = await getRegion()
33
+ }
34
+
35
+ if (!region) {
36
+ return {
37
+ response: { products: [], count: 0 },
38
+ nextPage: null,
39
+ }
40
+ }
41
+
42
+ const headers = {
43
+ ...(await getAuthHeaders()),
44
+ }
45
+
46
+ const next = {
47
+ ...(await getCacheOptions("products")),
48
+ }
49
+
50
+ return sdk.client
51
+ .fetch<{ products: HttpTypes.StoreProduct[]; count: number }>(
52
+ `/store/products`,
53
+ {
54
+ method: "GET",
55
+ query: {
56
+ limit,
57
+ offset,
58
+ region_id: region?.id,
59
+ fields:
60
+ "*variants.calculated_price,+variants.inventory_quantity,*variants.images,+metadata,+tags,",
61
+ ...queryParams,
62
+ },
63
+ headers,
64
+ next,
65
+ cache: "force-cache",
66
+ }
67
+ )
68
+ .then(({ products, count }) => {
69
+ const nextPage = count > offset + limit ? pageParam + 1 : null
70
+
71
+ return {
72
+ response: {
73
+ products,
74
+ count,
75
+ },
76
+ nextPage: nextPage,
77
+ queryParams,
78
+ }
79
+ })
80
+ }
81
+
82
+ /**
83
+ * This will fetch 100 products to the Next.js cache and sort them based on the sortBy parameter.
84
+ * It will then return the paginated products based on the page and limit parameters.
85
+ */
86
+ export const listProductsWithSort = async ({
87
+ page = 0,
88
+ queryParams,
89
+ sortBy = "created_at",
90
+ }: {
91
+ page?: number
92
+ queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductParams
93
+ sortBy?: SortOptions
94
+ }): Promise<{
95
+ response: { products: HttpTypes.StoreProduct[]; count: number }
96
+ nextPage: number | null
97
+ queryParams?: HttpTypes.FindParams & HttpTypes.StoreProductParams
98
+ }> => {
99
+ const limit = queryParams?.limit || 12
100
+
101
+ const {
102
+ response: { products, count },
103
+ } = await listProducts({
104
+ pageParam: 0,
105
+ queryParams: {
106
+ ...queryParams,
107
+ limit: 100,
108
+ },
109
+ })
110
+
111
+ const sortedProducts = sortProducts(products, sortBy)
112
+
113
+ const pageParam = (page - 1) * limit
114
+
115
+ const nextPage = count > pageParam + limit ? pageParam + limit : null
116
+
117
+ const paginatedProducts = sortedProducts.slice(pageParam, pageParam + limit)
118
+
119
+ return {
120
+ response: {
121
+ products: paginatedProducts,
122
+ count,
123
+ },
124
+ nextPage,
125
+ queryParams,
126
+ }
127
+ }