@vendure-platform/create 0.4.0 → 0.5.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 (334) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +39 -39
  3. package/dist/add-to-existing.js +1 -1
  4. package/dist/assets/demo-data/initial-data.json +663 -663
  5. package/dist/assets/storefront/components.json +20 -20
  6. package/dist/assets/storefront/eslint.config.mjs +10 -10
  7. package/dist/assets/storefront/graphql.config.yml +1 -1
  8. package/dist/assets/storefront/messages/de.json +2 -0
  9. package/dist/assets/storefront/messages/en.json +2 -0
  10. package/dist/assets/storefront/next.config.ts +5 -4
  11. package/dist/assets/storefront/package.json +1 -1
  12. package/dist/assets/storefront/postcss.config.mjs +1 -1
  13. package/dist/assets/storefront/src/app/[locale]/(catalog)/catalog/page.tsx +17 -21
  14. package/dist/assets/storefront/src/app/[locale]/(catalog)/collection/[slug]/page.tsx +64 -42
  15. package/dist/assets/storefront/src/app/[locale]/(catalog)/layout.tsx +1 -5
  16. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/actions.ts +69 -65
  17. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/page.tsx +68 -37
  18. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/page.tsx +24 -27
  19. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-results.tsx +11 -9
  20. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-term.tsx +4 -4
  21. package/dist/assets/storefront/src/app/[locale]/(scenario)/[...path]/page.tsx +1 -1
  22. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/accept-invitation-client.tsx +8 -13
  23. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/actions.ts +11 -14
  24. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/page.tsx +30 -33
  25. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/sign-out-and-retry.tsx +6 -6
  26. package/dist/assets/storefront/src/app/[locale]/account/addresses/actions.ts +30 -45
  27. package/dist/assets/storefront/src/app/[locale]/account/addresses/address-form.tsx +166 -159
  28. package/dist/assets/storefront/src/app/[locale]/account/addresses/addresses-client.tsx +35 -26
  29. package/dist/assets/storefront/src/app/[locale]/account/addresses/loading.tsx +1 -3
  30. package/dist/assets/storefront/src/app/[locale]/account/addresses/page.tsx +16 -18
  31. package/dist/assets/storefront/src/app/[locale]/account/approvals/actions.ts +5 -8
  32. package/dist/assets/storefront/src/app/[locale]/account/approvals/page.tsx +77 -69
  33. package/dist/assets/storefront/src/app/[locale]/account/company/actions.ts +10 -11
  34. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/actions.ts +6 -15
  35. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/address-form.tsx +57 -49
  36. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/addresses-client.tsx +23 -25
  37. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/page.tsx +30 -30
  38. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/actions.ts +20 -29
  39. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-unit-form.tsx +32 -37
  40. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-units-client.tsx +32 -25
  41. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/page.tsx +24 -24
  42. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/types.ts +7 -4
  43. package/dist/assets/storefront/src/app/[locale]/account/company/edit-company-form.tsx +11 -21
  44. package/dist/assets/storefront/src/app/[locale]/account/company/page.tsx +23 -28
  45. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/page.tsx +24 -24
  46. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/payment-methods-client.tsx +5 -7
  47. package/dist/assets/storefront/src/app/[locale]/account/company/roles/page.tsx +22 -25
  48. package/dist/assets/storefront/src/app/[locale]/account/company/roles/roles-client.tsx +11 -26
  49. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/actions.ts +6 -10
  50. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/page.tsx +18 -16
  51. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/tax-ids-client.tsx +74 -67
  52. package/dist/assets/storefront/src/app/[locale]/account/company/users/actions.ts +16 -25
  53. package/dist/assets/storefront/src/app/[locale]/account/company/users/edit-user-form.tsx +27 -25
  54. package/dist/assets/storefront/src/app/[locale]/account/company/users/invite-user-form.tsx +27 -19
  55. package/dist/assets/storefront/src/app/[locale]/account/company/users/page.tsx +32 -29
  56. package/dist/assets/storefront/src/app/[locale]/account/company/users/users-client.tsx +35 -38
  57. package/dist/assets/storefront/src/app/[locale]/account/error.tsx +1 -3
  58. package/dist/assets/storefront/src/app/[locale]/account/layout.tsx +16 -22
  59. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/page.tsx +151 -103
  60. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-actions.ts +6 -7
  61. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-dialog.tsx +22 -48
  62. package/dist/assets/storefront/src/app/[locale]/account/orders/loading.tsx +8 -8
  63. package/dist/assets/storefront/src/app/[locale]/account/orders/page.tsx +101 -61
  64. package/dist/assets/storefront/src/app/[locale]/account/profile/actions.ts +32 -23
  65. package/dist/assets/storefront/src/app/[locale]/account/profile/change-password-form.tsx +6 -16
  66. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-email-form.tsx +7 -17
  67. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-profile-form.tsx +6 -16
  68. package/dist/assets/storefront/src/app/[locale]/account/profile/loading.tsx +12 -18
  69. package/dist/assets/storefront/src/app/[locale]/account/profile/page.tsx +15 -15
  70. package/dist/assets/storefront/src/app/[locale]/account/quick-order/file-upload-tab.tsx +2 -6
  71. package/dist/assets/storefront/src/app/[locale]/account/quick-order/manual-entry-tab.tsx +18 -15
  72. package/dist/assets/storefront/src/app/[locale]/account/quick-order/page.tsx +3 -6
  73. package/dist/assets/storefront/src/app/[locale]/account/quick-order/preview-table.tsx +10 -2
  74. package/dist/assets/storefront/src/app/[locale]/account/quick-order/save-to-list-dialog.tsx +24 -26
  75. package/dist/assets/storefront/src/app/[locale]/account/quick-order/sku-autocomplete.tsx +19 -10
  76. package/dist/assets/storefront/src/app/[locale]/account/quick-order/text-input-tab.tsx +3 -8
  77. package/dist/assets/storefront/src/app/[locale]/account/quotes/[id]/page.tsx +86 -59
  78. package/dist/assets/storefront/src/app/[locale]/account/quotes/actions.ts +38 -45
  79. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/new-quote-form.tsx +3 -5
  80. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/page.tsx +6 -6
  81. package/dist/assets/storefront/src/app/[locale]/account/quotes/page.tsx +92 -59
  82. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/activity-feed.tsx +152 -0
  83. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-item-search.tsx +132 -0
  84. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-member-form.tsx +140 -0
  85. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/members-panel.tsx +259 -0
  86. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/page.tsx +55 -0
  87. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/rename-dialog.tsx +117 -0
  88. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/shared-cart-detail-client.tsx +555 -0
  89. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/actions.ts +305 -0
  90. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/new-shared-cart-form.tsx +84 -0
  91. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/page.tsx +47 -0
  92. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/page.tsx +276 -0
  93. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/page.tsx +22 -8
  94. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/shopping-list-detail-client.tsx +62 -49
  95. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/actions.ts +9 -4
  96. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/create-shopping-list-form.tsx +5 -11
  97. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/loading.tsx +1 -1
  98. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/page.tsx +32 -42
  99. package/dist/assets/storefront/src/app/[locale]/account/store-credits/actions.ts +8 -8
  100. package/dist/assets/storefront/src/app/[locale]/account/store-credits/claim-form.tsx +6 -10
  101. package/dist/assets/storefront/src/app/[locale]/account/store-credits/page.tsx +76 -55
  102. package/dist/assets/storefront/src/app/[locale]/account/store-credits/reveal-code.tsx +10 -6
  103. package/dist/assets/storefront/src/app/[locale]/account/verify-email/page.tsx +32 -39
  104. package/dist/assets/storefront/src/app/[locale]/cart/actions.ts +29 -23
  105. package/dist/assets/storefront/src/app/[locale]/cart/cart-items.tsx +111 -40
  106. package/dist/assets/storefront/src/app/[locale]/cart/cart-line-actions.tsx +9 -9
  107. package/dist/assets/storefront/src/app/[locale]/cart/cart-quantity-control.tsx +61 -48
  108. package/dist/assets/storefront/src/app/[locale]/cart/cart-remove-button.tsx +15 -9
  109. package/dist/assets/storefront/src/app/[locale]/cart/cart.tsx +38 -41
  110. package/dist/assets/storefront/src/app/[locale]/cart/code-input.tsx +8 -8
  111. package/dist/assets/storefront/src/app/[locale]/cart/order-summary.tsx +70 -29
  112. package/dist/assets/storefront/src/app/[locale]/cart/page.tsx +11 -11
  113. package/dist/assets/storefront/src/app/[locale]/cart/promotion-code.tsx +48 -42
  114. package/dist/assets/storefront/src/app/[locale]/cart/reapproval-confirm.tsx +22 -20
  115. package/dist/assets/storefront/src/app/[locale]/cart/request-quote-button.tsx +7 -16
  116. package/dist/assets/storefront/src/app/[locale]/checkout/actions.ts +39 -65
  117. package/dist/assets/storefront/src/app/[locale]/checkout/cancel-quote-checkout-button.tsx +5 -5
  118. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-flow.tsx +202 -202
  119. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-provider.tsx +142 -142
  120. package/dist/assets/storefront/src/app/[locale]/checkout/order-summary.tsx +158 -139
  121. package/dist/assets/storefront/src/app/[locale]/checkout/page.tsx +56 -47
  122. package/dist/assets/storefront/src/app/[locale]/checkout/steps/delivery-step.tsx +86 -88
  123. package/dist/assets/storefront/src/app/[locale]/checkout/steps/payment-step.tsx +90 -91
  124. package/dist/assets/storefront/src/app/[locale]/checkout/steps/review-step.tsx +166 -161
  125. package/dist/assets/storefront/src/app/[locale]/checkout/steps/shipping-address-step.tsx +573 -494
  126. package/dist/assets/storefront/src/app/[locale]/error.tsx +3 -5
  127. package/dist/assets/storefront/src/app/[locale]/forgot-password/actions.ts +10 -7
  128. package/dist/assets/storefront/src/app/[locale]/forgot-password/forgot-password-form.tsx +10 -25
  129. package/dist/assets/storefront/src/app/[locale]/forgot-password/page.tsx +5 -5
  130. package/dist/assets/storefront/src/app/[locale]/globals.css +48 -48
  131. package/dist/assets/storefront/src/app/[locale]/layout.tsx +53 -47
  132. package/dist/assets/storefront/src/app/[locale]/not-found.tsx +3 -5
  133. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/order-confirmation.tsx +71 -44
  134. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/page.tsx +7 -5
  135. package/dist/assets/storefront/src/app/[locale]/page.tsx +33 -35
  136. package/dist/assets/storefront/src/app/[locale]/register/actions.ts +7 -7
  137. package/dist/assets/storefront/src/app/[locale]/register/page.tsx +22 -16
  138. package/dist/assets/storefront/src/app/[locale]/register/registration-form.tsx +22 -34
  139. package/dist/assets/storefront/src/app/[locale]/register-company/actions.ts +15 -19
  140. package/dist/assets/storefront/src/app/[locale]/register-company/page.tsx +17 -15
  141. package/dist/assets/storefront/src/app/[locale]/register-company/registration-form.tsx +9 -15
  142. package/dist/assets/storefront/src/app/[locale]/reset-password/actions.ts +7 -8
  143. package/dist/assets/storefront/src/app/[locale]/reset-password/page.tsx +18 -12
  144. package/dist/assets/storefront/src/app/[locale]/reset-password/reset-password-form.tsx +8 -16
  145. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/add-to-cart-button.tsx +10 -4
  146. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/page.tsx +62 -30
  147. package/dist/assets/storefront/src/app/[locale]/sign-in/actions.ts +14 -16
  148. package/dist/assets/storefront/src/app/[locale]/sign-in/login-form.tsx +17 -30
  149. package/dist/assets/storefront/src/app/[locale]/sign-in/page.tsx +35 -30
  150. package/dist/assets/storefront/src/app/[locale]/verify/actions.ts +8 -8
  151. package/dist/assets/storefront/src/app/[locale]/verify/page.tsx +18 -14
  152. package/dist/assets/storefront/src/app/[locale]/verify/verify-content.tsx +25 -27
  153. package/dist/assets/storefront/src/app/[locale]/verify-pending/page.tsx +23 -23
  154. package/dist/assets/storefront/src/app/api/clear-company-context/route.ts +6 -3
  155. package/dist/assets/storefront/src/app/api/revalidate/route.ts +19 -28
  156. package/dist/assets/storefront/src/app/api/search-analytics/route.ts +1 -1
  157. package/dist/assets/storefront/src/components/commerce/account-nav-items.ts +44 -17
  158. package/dist/assets/storefront/src/components/commerce/account-sidebar.tsx +30 -22
  159. package/dist/assets/storefront/src/components/commerce/active-filters.tsx +1 -1
  160. package/dist/assets/storefront/src/components/commerce/add-to-shared-cart.tsx +247 -0
  161. package/dist/assets/storefront/src/components/commerce/approval-decision-form.tsx +9 -13
  162. package/dist/assets/storefront/src/components/commerce/approval-status-badge.tsx +23 -15
  163. package/dist/assets/storefront/src/components/commerce/business-unit-switcher.tsx +11 -11
  164. package/dist/assets/storefront/src/components/commerce/catalog-search-bar.tsx +2 -2
  165. package/dist/assets/storefront/src/components/commerce/category-product-section.tsx +28 -16
  166. package/dist/assets/storefront/src/components/commerce/category-sidebar.tsx +31 -18
  167. package/dist/assets/storefront/src/components/commerce/collection-hero-banner.tsx +2 -4
  168. package/dist/assets/storefront/src/components/commerce/company-state-badge.tsx +10 -16
  169. package/dist/assets/storefront/src/components/commerce/company-switcher.tsx +12 -12
  170. package/dist/assets/storefront/src/components/commerce/configurator-form.tsx +188 -79
  171. package/dist/assets/storefront/src/components/commerce/facet-filters.tsx +29 -49
  172. package/dist/assets/storefront/src/components/commerce/gift-card-pdp.tsx +4 -4
  173. package/dist/assets/storefront/src/components/commerce/gift-card-product-info.tsx +20 -30
  174. package/dist/assets/storefront/src/components/commerce/instant-search-dropdown.tsx +258 -227
  175. package/dist/assets/storefront/src/components/commerce/order-status-badge.tsx +27 -19
  176. package/dist/assets/storefront/src/components/commerce/packaging-unit-selector.tsx +27 -26
  177. package/dist/assets/storefront/src/components/commerce/permission-gate.tsx +4 -4
  178. package/dist/assets/storefront/src/components/commerce/price-range-filter.tsx +5 -5
  179. package/dist/assets/storefront/src/components/commerce/price-tiers.tsx +38 -21
  180. package/dist/assets/storefront/src/components/commerce/price.tsx +3 -3
  181. package/dist/assets/storefront/src/components/commerce/product-card-list.tsx +35 -14
  182. package/dist/assets/storefront/src/components/commerce/product-card.tsx +31 -16
  183. package/dist/assets/storefront/src/components/commerce/product-carousel.tsx +20 -12
  184. package/dist/assets/storefront/src/components/commerce/product-grid.tsx +14 -13
  185. package/dist/assets/storefront/src/components/commerce/product-image-carousel.tsx +10 -8
  186. package/dist/assets/storefront/src/components/commerce/product-info.tsx +129 -72
  187. package/dist/assets/storefront/src/components/commerce/product-list-expansion.tsx +102 -74
  188. package/dist/assets/storefront/src/components/commerce/product-list-view.tsx +1 -1
  189. package/dist/assets/storefront/src/components/commerce/product-sidebar.tsx +36 -11
  190. package/dist/assets/storefront/src/components/commerce/product-view-switcher.tsx +33 -21
  191. package/dist/assets/storefront/src/components/commerce/quote-action-buttons.tsx +54 -36
  192. package/dist/assets/storefront/src/components/commerce/quote-activity-timeline.tsx +126 -50
  193. package/dist/assets/storefront/src/components/commerce/quote-comment-form.tsx +9 -13
  194. package/dist/assets/storefront/src/components/commerce/quote-csv-export-button.tsx +6 -6
  195. package/dist/assets/storefront/src/components/commerce/quote-product-search.tsx +22 -18
  196. package/dist/assets/storefront/src/components/commerce/quote-request-form.tsx +28 -27
  197. package/dist/assets/storefront/src/components/commerce/quote-status-badge.tsx +26 -18
  198. package/dist/assets/storefront/src/components/commerce/quote-validity-indicator.tsx +7 -7
  199. package/dist/assets/storefront/src/components/commerce/quote-version-comparison.tsx +50 -30
  200. package/dist/assets/storefront/src/components/commerce/related-products.tsx +37 -28
  201. package/dist/assets/storefront/src/components/commerce/shared-cart-role.ts +39 -0
  202. package/dist/assets/storefront/src/components/commerce/shared-cart-status-badge.tsx +28 -0
  203. package/dist/assets/storefront/src/components/commerce/shop-by-category.tsx +8 -7
  204. package/dist/assets/storefront/src/components/commerce/shopping-list-toggle.tsx +14 -20
  205. package/dist/assets/storefront/src/components/commerce/sort-dropdown.tsx +9 -16
  206. package/dist/assets/storefront/src/components/commerce/store-credit-summary.tsx +30 -32
  207. package/dist/assets/storefront/src/components/commerce/subcollection-tiles.tsx +11 -13
  208. package/dist/assets/storefront/src/components/layout/auth-page-shell.tsx +2 -2
  209. package/dist/assets/storefront/src/components/layout/draft-mode-indicator.tsx +2 -7
  210. package/dist/assets/storefront/src/components/layout/draft-mode-link.tsx +4 -2
  211. package/dist/assets/storefront/src/components/layout/footer.tsx +70 -28
  212. package/dist/assets/storefront/src/components/layout/navbar/actions.ts +9 -12
  213. package/dist/assets/storefront/src/components/layout/navbar/cart-icon.tsx +9 -9
  214. package/dist/assets/storefront/src/components/layout/navbar/channel-picker-wrapper.tsx +4 -9
  215. package/dist/assets/storefront/src/components/layout/navbar/channel-picker.tsx +13 -8
  216. package/dist/assets/storefront/src/components/layout/navbar/currency-picker-wrapper.tsx +4 -4
  217. package/dist/assets/storefront/src/components/layout/navbar/currency-picker.tsx +11 -6
  218. package/dist/assets/storefront/src/components/layout/navbar/language-picker.tsx +7 -7
  219. package/dist/assets/storefront/src/components/layout/navbar/login-button.tsx +24 -21
  220. package/dist/assets/storefront/src/components/layout/navbar/mobile-nav.tsx +8 -8
  221. package/dist/assets/storefront/src/components/layout/navbar/nav-menu-items.tsx +4 -6
  222. package/dist/assets/storefront/src/components/layout/navbar/navbar-cart.tsx +1 -1
  223. package/dist/assets/storefront/src/components/layout/navbar/navbar-collections.tsx +41 -42
  224. package/dist/assets/storefront/src/components/layout/navbar/navbar-link.tsx +7 -10
  225. package/dist/assets/storefront/src/components/layout/navbar/navbar-user.tsx +18 -23
  226. package/dist/assets/storefront/src/components/layout/navbar/theme-switcher.tsx +9 -9
  227. package/dist/assets/storefront/src/components/layout/navbar.tsx +36 -31
  228. package/dist/assets/storefront/src/components/layout/search-input.tsx +35 -32
  229. package/dist/assets/storefront/src/components/providers/awaiting-approval-banner.tsx +12 -10
  230. package/dist/assets/storefront/src/components/providers/cart-count-server.tsx +14 -12
  231. package/dist/assets/storefront/src/components/providers/company-context-guard.tsx +4 -4
  232. package/dist/assets/storefront/src/components/providers/company-permissions-server.tsx +2 -6
  233. package/dist/assets/storefront/src/components/providers/theme-provider.tsx +3 -3
  234. package/dist/assets/storefront/src/components/shared/breadcrumbs.tsx +4 -1
  235. package/dist/assets/storefront/src/components/shared/country-select.tsx +63 -67
  236. package/dist/assets/storefront/src/components/shared/pagination.tsx +15 -28
  237. package/dist/assets/storefront/src/components/shared/prefetch-link.tsx +1 -1
  238. package/dist/assets/storefront/src/components/shared/skeletons/search-input-skeleton.tsx +1 -3
  239. package/dist/assets/storefront/src/components/ui/accordion.tsx +46 -51
  240. package/dist/assets/storefront/src/components/ui/alert-dialog.tsx +94 -121
  241. package/dist/assets/storefront/src/components/ui/alert.tsx +48 -54
  242. package/dist/assets/storefront/src/components/ui/aspect-ratio.tsx +5 -7
  243. package/dist/assets/storefront/src/components/ui/avatar.tsx +29 -44
  244. package/dist/assets/storefront/src/components/ui/badge.tsx +28 -37
  245. package/dist/assets/storefront/src/components/ui/breadcrumb.tsx +82 -89
  246. package/dist/assets/storefront/src/components/ui/button.tsx +43 -49
  247. package/dist/assets/storefront/src/components/ui/calendar.tsx +157 -198
  248. package/dist/assets/storefront/src/components/ui/card.tsx +53 -76
  249. package/dist/assets/storefront/src/components/ui/carousel.tsx +194 -212
  250. package/dist/assets/storefront/src/components/ui/chart.tsx +274 -317
  251. package/dist/assets/storefront/src/components/ui/checkbox.tsx +24 -27
  252. package/dist/assets/storefront/src/components/ui/collapsible.tsx +9 -21
  253. package/dist/assets/storefront/src/components/ui/command.tsx +114 -159
  254. package/dist/assets/storefront/src/components/ui/context-menu.tsx +167 -199
  255. package/dist/assets/storefront/src/components/ui/dialog.tsx +97 -114
  256. package/dist/assets/storefront/src/components/ui/drawer.tsx +93 -107
  257. package/dist/assets/storefront/src/components/ui/dropdown-menu.tsx +171 -206
  258. package/dist/assets/storefront/src/components/ui/empty-state.tsx +5 -5
  259. package/dist/assets/storefront/src/components/ui/field.tsx +196 -208
  260. package/dist/assets/storefront/src/components/ui/form.tsx +115 -139
  261. package/dist/assets/storefront/src/components/ui/hover-card.tsx +27 -33
  262. package/dist/assets/storefront/src/components/ui/input-otp.tsx +50 -59
  263. package/dist/assets/storefront/src/components/ui/input.tsx +17 -17
  264. package/dist/assets/storefront/src/components/ui/kbd-shortcut.tsx +3 -1
  265. package/dist/assets/storefront/src/components/ui/label.tsx +16 -19
  266. package/dist/assets/storefront/src/components/ui/menubar.tsx +193 -223
  267. package/dist/assets/storefront/src/components/ui/navigation-menu.tsx +123 -130
  268. package/dist/assets/storefront/src/components/ui/pagination.tsx +87 -108
  269. package/dist/assets/storefront/src/components/ui/popover.tsx +29 -35
  270. package/dist/assets/storefront/src/components/ui/progress.tsx +19 -26
  271. package/dist/assets/storefront/src/components/ui/radio-group.tsx +32 -38
  272. package/dist/assets/storefront/src/components/ui/resizable.tsx +37 -42
  273. package/dist/assets/storefront/src/components/ui/scroll-area.tsx +41 -47
  274. package/dist/assets/storefront/src/components/ui/select.tsx +130 -152
  275. package/dist/assets/storefront/src/components/ui/separator.tsx +21 -21
  276. package/dist/assets/storefront/src/components/ui/sheet.tsx +90 -111
  277. package/dist/assets/storefront/src/components/ui/sidebar.tsx +611 -649
  278. package/dist/assets/storefront/src/components/ui/skeleton.tsx +10 -10
  279. package/dist/assets/storefront/src/components/ui/slider.tsx +50 -55
  280. package/dist/assets/storefront/src/components/ui/sonner.tsx +20 -20
  281. package/dist/assets/storefront/src/components/ui/switch.tsx +23 -26
  282. package/dist/assets/storefront/src/components/ui/table.tsx +65 -97
  283. package/dist/assets/storefront/src/components/ui/tabs.tsx +39 -55
  284. package/dist/assets/storefront/src/components/ui/textarea.tsx +14 -14
  285. package/dist/assets/storefront/src/components/ui/toggle-group.tsx +56 -62
  286. package/dist/assets/storefront/src/components/ui/toggle.tsx +37 -38
  287. package/dist/assets/storefront/src/components/ui/tooltip.tsx +38 -46
  288. package/dist/assets/storefront/src/config/scenario-meta.ts +2 -2
  289. package/dist/assets/storefront/src/config/scenario.ts +14 -16
  290. package/dist/assets/storefront/src/contexts/auth-context.tsx +5 -6
  291. package/dist/assets/storefront/src/graphql-env.d.ts +18 -5
  292. package/dist/assets/storefront/src/graphql.ts +5 -5
  293. package/dist/assets/storefront/src/hooks/use-mobile.ts +13 -13
  294. package/dist/assets/storefront/src/i18n/locale-utils.ts +3 -3
  295. package/dist/assets/storefront/src/i18n/navigation.ts +4 -4
  296. package/dist/assets/storefront/src/i18n/request.ts +4 -4
  297. package/dist/assets/storefront/src/i18n/routing.ts +5 -5
  298. package/dist/assets/storefront/src/i18n/server.ts +3 -3
  299. package/dist/assets/storefront/src/lib/actions/switch-channel.ts +9 -9
  300. package/dist/assets/storefront/src/lib/actions/switch-currency.ts +7 -7
  301. package/dist/assets/storefront/src/lib/auth.ts +1 -1
  302. package/dist/assets/storefront/src/lib/backend-health.ts +3 -3
  303. package/dist/assets/storefront/src/lib/cart-count-context.tsx +10 -4
  304. package/dist/assets/storefront/src/lib/cart-guard-utils.ts +2 -1
  305. package/dist/assets/storefront/src/lib/cart-guard.ts +7 -6
  306. package/dist/assets/storefront/src/lib/channel-server.ts +4 -4
  307. package/dist/assets/storefront/src/lib/company-context.ts +1 -1
  308. package/dist/assets/storefront/src/lib/company-permissions-context.tsx +1 -5
  309. package/dist/assets/storefront/src/lib/currency-server.ts +4 -4
  310. package/dist/assets/storefront/src/lib/format.ts +16 -7
  311. package/dist/assets/storefront/src/lib/metadata.ts +39 -44
  312. package/dist/assets/storefront/src/lib/quantity.ts +2 -4
  313. package/dist/assets/storefront/src/lib/search-bar-context.tsx +7 -4
  314. package/dist/assets/storefront/src/lib/use-recent-searches.ts +8 -6
  315. package/dist/assets/storefront/src/lib/utils.ts +3 -3
  316. package/dist/assets/storefront/src/lib/vendure/actions.ts +18 -16
  317. package/dist/assets/storefront/src/lib/vendure/api.ts +44 -27
  318. package/dist/assets/storefront/src/lib/vendure/approval-utils.ts +9 -8
  319. package/dist/assets/storefront/src/lib/vendure/cached.ts +20 -15
  320. package/dist/assets/storefront/src/lib/vendure/mutations.ts +96 -0
  321. package/dist/assets/storefront/src/lib/vendure/queries.ts +157 -5
  322. package/dist/assets/storefront/src/middleware.ts +1 -1
  323. package/dist/assets/storefront/src/scenarios/customer/hero.tsx +2 -2
  324. package/dist/assets/storefront/src/scenarios/customer/meta.ts +1 -1
  325. package/dist/assets/storefront/src/schema.graphql +134 -0
  326. package/dist/bin/run.js +1 -1
  327. package/dist/cli.d.ts +1 -1
  328. package/dist/index.d.ts +5 -5
  329. package/dist/index.js +1 -1
  330. package/dist/plugin-registry.js +1 -1
  331. package/dist/scaffold-storefront-only.js +1 -1
  332. package/dist/scaffolder.js +1 -1
  333. package/dist/template-renderer.js +1 -1
  334. package/package.json +2 -2
@@ -1,17 +1,17 @@
1
- import {CartItems as DefaultCartItems} from "@/app/[locale]/cart/cart-items";
2
- import {OrderSummary} from "@/app/[locale]/cart/order-summary";
3
- import {PromotionCode} from "@/app/[locale]/cart/promotion-code";
4
- import {client, getVendureContext} from "@/lib/vendure/api";
5
- import type {VendureContext} from "@/lib/vendure/api";
6
- import {GetActiveOrderQuery} from "@/lib/vendure/queries";
7
- import {getLatestApprovalForOrder} from "@/lib/vendure/approval-utils";
8
- import {FileText, MessageSquare} from "lucide-react";
9
- import {cacheTag} from 'next/cache';
10
- import {CancelQuoteCheckoutButton} from "@/app/[locale]/checkout/cancel-quote-checkout-button";
11
- import {Link} from "@/i18n/navigation";
12
- import {Button} from "@/components/ui/button";
13
- import {getTranslations} from 'next-intl/server';
14
- import {getScenarioConfig} from "@/config/scenario";
1
+ import { CartItems as DefaultCartItems } from '@/app/[locale]/cart/cart-items';
2
+ import { OrderSummary } from '@/app/[locale]/cart/order-summary';
3
+ import { PromotionCode } from '@/app/[locale]/cart/promotion-code';
4
+ import { CancelQuoteCheckoutButton } from '@/app/[locale]/checkout/cancel-quote-checkout-button';
5
+ import { Button } from '@/components/ui/button';
6
+ import { getScenarioConfig } from '@/config/scenario';
7
+ import { Link } from '@/i18n/navigation';
8
+ import type { VendureContext } from '@/lib/vendure/api';
9
+ import { client, getVendureContext } from '@/lib/vendure/api';
10
+ import { getLatestApprovalForOrder } from '@/lib/vendure/approval-utils';
11
+ import { GetActiveOrderQuery } from '@/lib/vendure/queries';
12
+ import { FileText, MessageSquare } from 'lucide-react';
13
+ import { getTranslations } from 'next-intl/server';
14
+ import { cacheTag } from 'next/cache';
15
15
 
16
16
  // Scenario override: replace the default CartItems with the scenario-registered
17
17
  // slot when present. The slot is a ServerComponent with the same shape as the
@@ -25,10 +25,7 @@ const CartItems = getScenarioConfig().overrides?.cart?.CartItems ?? DefaultCartI
25
25
  const ScenarioCartBanner = getScenarioConfig().overrides?.cart?.Banner ?? null;
26
26
 
27
27
  export async function Cart() {
28
- const [ctx, t] = await Promise.all([
29
- getVendureContext(),
30
- getTranslations('Cart'),
31
- ]);
28
+ const [ctx, t] = await Promise.all([getVendureContext(), getTranslations('Cart')]);
32
29
  return (
33
30
  <CartCached
34
31
  ctx={ctx}
@@ -59,14 +56,14 @@ async function CartCached({
59
56
  changesRequestedLabel: string;
60
57
  changesRequestedMessage: string;
61
58
  }) {
62
- "use cache: private"
59
+ 'use cache: private';
63
60
  cacheTag('cart');
64
61
 
65
62
  const [result, error] = await client.query(GetActiveOrderQuery, {}, ctx);
66
63
  if (error) {
67
- return <CartItems activeOrder={null}/>;
64
+ return <CartItems activeOrder={null} />;
68
65
  }
69
- const {data} = result;
66
+ const { data } = result;
70
67
 
71
68
  const activeOrder = data.activeOrder;
72
69
 
@@ -93,16 +90,19 @@ async function CartCached({
93
90
  <div className="rounded-lg border border-primary/30 bg-primary/10 p-4">
94
91
  <div className="flex items-center justify-between">
95
92
  <div className="flex gap-3">
96
- <FileText className="h-5 w-5 text-primary flex-shrink-0 mt-0.5"/>
93
+ <FileText className="h-5 w-5 text-primary flex-shrink-0 mt-0.5" />
97
94
  <div>
98
95
  <h3 className="font-medium text-foreground">{quoteCheckoutTitle}</h3>
99
- <p className="text-sm text-muted-foreground mt-1">
100
- {quoteCheckoutMessage}
101
- </p>
96
+ <p className="text-sm text-muted-foreground mt-1">{quoteCheckoutMessage}</p>
102
97
  </div>
103
98
  </div>
104
99
  <div className="flex items-center gap-2 shrink-0 ml-4">
105
- <Button asChild variant="outline" size="sm" className="border-primary/40 text-primary hover:bg-primary/10">
100
+ <Button
101
+ asChild
102
+ variant="outline"
103
+ size="sm"
104
+ className="border-primary/40 text-primary hover:bg-primary/10"
105
+ >
106
106
  <Link href={`/account/quotes/${sourceQuoteId}`}>{viewQuote}</Link>
107
107
  </Button>
108
108
  <CancelQuoteCheckoutButton />
@@ -112,7 +112,7 @@ async function CartCached({
112
112
  <div className="grid lg:grid-cols-3 gap-8">
113
113
  <CartItems activeOrder={activeOrder} readOnly />
114
114
  <div className="lg:col-span-1">
115
- <OrderSummary activeOrder={activeOrder}/>
115
+ <OrderSummary activeOrder={activeOrder} />
116
116
  </div>
117
117
  </div>
118
118
  </div>
@@ -120,26 +120,23 @@ async function CartCached({
120
120
  }
121
121
 
122
122
  // Check if this order was returned from an approval flow with changes requested
123
- const { latestApproval, changesRequested, changesComment } = await getLatestApprovalForOrder(activeOrder.id, ctx);
123
+ const { latestApproval, changesRequested, changesComment } = await getLatestApprovalForOrder(
124
+ activeOrder.id,
125
+ ctx,
126
+ );
124
127
  const wasApproved = latestApproval?.status === 'APPROVED';
125
128
 
126
129
  return (
127
130
  <div className="space-y-6">
128
131
  {ScenarioCartBanner && <ScenarioCartBanner />}
129
- {wasApproved && (
130
- <p className="text-sm text-muted-foreground">
131
- {approvedOrderWarning}
132
- </p>
133
- )}
132
+ {wasApproved && <p className="text-sm text-muted-foreground">{approvedOrderWarning}</p>}
134
133
  {changesRequested && (
135
134
  <div className="rounded-lg border border-destructive/30 bg-destructive/10 p-4">
136
135
  <div className="flex gap-3">
137
- <MessageSquare className="h-5 w-5 text-destructive flex-shrink-0 mt-0.5"/>
136
+ <MessageSquare className="h-5 w-5 text-destructive flex-shrink-0 mt-0.5" />
138
137
  <div>
139
138
  <h3 className="font-medium text-foreground">{changesRequestedLabel}</h3>
140
- <p className="text-sm text-muted-foreground mt-1">
141
- {changesRequestedMessage}
142
- </p>
139
+ <p className="text-sm text-muted-foreground mt-1">{changesRequestedMessage}</p>
143
140
  {changesComment && (
144
141
  <blockquote className="mt-2 border-l-2 border-destructive/40 pl-3 text-sm text-muted-foreground italic">
145
142
  &ldquo;{changesComment}&rdquo;
@@ -150,13 +147,13 @@ async function CartCached({
150
147
  </div>
151
148
  )}
152
149
  <div className="grid lg:grid-cols-3 gap-8">
153
- <CartItems activeOrder={activeOrder} wasApproved={wasApproved}/>
150
+ <CartItems activeOrder={activeOrder} wasApproved={wasApproved} />
154
151
 
155
152
  <div className="lg:col-span-1 sticky top-20 space-y-4">
156
- <OrderSummary activeOrder={activeOrder}/>
157
- <PromotionCode activeOrder={activeOrder}/>
153
+ <OrderSummary activeOrder={activeOrder} />
154
+ <PromotionCode activeOrder={activeOrder} />
158
155
  </div>
159
156
  </div>
160
157
  </div>
161
- )
158
+ );
162
159
  }
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
 
3
- import {useRef, useTransition} from 'react';
4
- import {useRouter} from '@/i18n/navigation';
5
- import {toast} from 'sonner';
6
- import {Button} from '@/components/ui/button';
7
- import {Input} from '@/components/ui/input';
8
- import {Loader2} from 'lucide-react';
9
- import {applyCode} from './actions';
10
- import {useTranslations} from 'next-intl';
3
+ import { Button } from '@/components/ui/button';
4
+ import { Input } from '@/components/ui/input';
5
+ import { useRouter } from '@/i18n/navigation';
6
+ import { Loader2 } from 'lucide-react';
7
+ import { useTranslations } from 'next-intl';
8
+ import { useRef, useTransition } from 'react';
9
+ import { toast } from 'sonner';
10
+ import { applyCode } from './actions';
11
11
 
12
12
  export function CodeInput() {
13
13
  const t = useTranslations('Cart');
@@ -1,11 +1,13 @@
1
- import {Link} from '@/i18n/navigation';
2
- import {Button} from '@/components/ui/button';
3
- import {Price} from '@/components/commerce/price';
4
- import {maskCode} from '@/lib/format';
5
- import {RequestQuoteButton} from './request-quote-button';
6
- import {getAuthToken} from '@/lib/auth';
7
- import {getActiveCustomer, getCompanyAccount} from '@/lib/vendure/actions';
8
- import {getTranslations} from 'next-intl/server';
1
+ import { AddToSharedCart } from '@/components/commerce/add-to-shared-cart';
2
+ import { Price } from '@/components/commerce/price';
3
+ import { canCreateSharedCarts } from '@/components/commerce/shared-cart-role';
4
+ import { Button } from '@/components/ui/button';
5
+ import { Link } from '@/i18n/navigation';
6
+ import { getAuthToken } from '@/lib/auth';
7
+ import { maskCode } from '@/lib/format';
8
+ import { getActiveCustomer, getCompanyAccount } from '@/lib/vendure/actions';
9
+ import { getTranslations } from 'next-intl/server';
10
+ import { RequestQuoteButton } from './request-quote-button';
9
11
 
10
12
  type ActiveOrder = {
11
13
  id: string;
@@ -46,13 +48,13 @@ type ActiveOrder = {
46
48
  }> | null;
47
49
  };
48
50
 
49
- export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder }) {
51
+ export async function OrderSummary({ activeOrder }: { activeOrder: ActiveOrder }) {
50
52
  const t = await getTranslations('Cart');
51
53
  const hasCreditsApplied = activeOrder.storeCreditsApplied.length > 0;
52
54
  const authToken = await getAuthToken();
53
55
  const taxTotal = activeOrder.totalWithTax - activeOrder.total;
54
56
  const MIN_QTY_FOR_QUOTE = 50;
55
- const hasHighQuantityLine = activeOrder.lines.some(line => line.quantity >= MIN_QTY_FOR_QUOTE);
57
+ const hasHighQuantityLine = activeOrder.lines.some((line) => line.quantity >= MIN_QTY_FOR_QUOTE);
56
58
 
57
59
  // Check PlaceOrders permission for company users
58
60
  const companyAccount = await getCompanyAccount();
@@ -71,6 +73,13 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
71
73
  }
72
74
  }
73
75
 
76
+ const canShareCart = canCreateSharedCarts(companyAccount?.permissions);
77
+ let shareDefaultName = 'Shared cart';
78
+ if (canShareCart) {
79
+ const customer = await getActiveCustomer();
80
+ if (customer?.firstName) shareDefaultName = `${customer.firstName}'s shared cart`;
81
+ }
82
+
74
83
  return (
75
84
  <div className="border rounded-lg p-6 bg-card">
76
85
  <h2 className="text-xl font-bold mb-4">{t('orderSummary')}</h2>
@@ -79,7 +88,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
79
88
  <div className="flex justify-between text-sm">
80
89
  <span className="text-muted-foreground">{t('subtotal')}</span>
81
90
  <span>
82
- <Price value={activeOrder.subTotal} currencyCode={activeOrder.currencyCode}/>
91
+ <Price value={activeOrder.subTotal} currencyCode={activeOrder.currencyCode} />
83
92
  </span>
84
93
  </div>
85
94
  {activeOrder.discounts && activeOrder.discounts.length > 0 && (
@@ -88,7 +97,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
88
97
  <div key={index} className="flex justify-between text-sm text-green-600">
89
98
  <span>{discount.description}</span>
90
99
  <span>
91
- <Price value={discount.amount} currencyCode={activeOrder.currencyCode}/>
100
+ <Price value={discount.amount} currencyCode={activeOrder.currencyCode} />
92
101
  </span>
93
102
  </div>
94
103
  ))}
@@ -97,9 +106,11 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
97
106
  <div className="flex justify-between text-sm">
98
107
  <span className="text-muted-foreground">{t('shipping')}</span>
99
108
  <span>
100
- {activeOrder.shipping > 0
101
- ? <Price value={activeOrder.shipping} currencyCode={activeOrder.currencyCode}/>
102
- : t('calculatedAtCheckout')}
109
+ {activeOrder.shipping > 0 ? (
110
+ <Price value={activeOrder.shipping} currencyCode={activeOrder.currencyCode} />
111
+ ) : (
112
+ t('calculatedAtCheckout')
113
+ )}
103
114
  </span>
104
115
  </div>
105
116
  {activeOrder.taxSummary && activeOrder.taxSummary.length > 0 ? (
@@ -109,7 +120,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
109
120
  {tax.description} ({tax.taxRate}%)
110
121
  </span>
111
122
  <span>
112
- <Price value={tax.taxTotal} currencyCode={activeOrder.currencyCode}/>
123
+ <Price value={tax.taxTotal} currencyCode={activeOrder.currencyCode} />
113
124
  </span>
114
125
  </div>
115
126
  ))
@@ -117,16 +128,23 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
117
128
  <div className="flex justify-between text-sm">
118
129
  <span className="text-muted-foreground">{t('tax')}</span>
119
130
  <span>
120
- <Price value={taxTotal} currencyCode={activeOrder.currencyCode}/>
131
+ <Price value={taxTotal} currencyCode={activeOrder.currencyCode} />
121
132
  </span>
122
133
  </div>
123
134
  )}
124
- {hasCreditsApplied && activeOrder.storeCreditsApplied.map((credit) => (
125
- <div key={credit.code} className="flex justify-between text-sm text-green-600">
126
- <span>{t('storeCredit', {code: maskCode(credit.code)})}</span>
127
- <span>-<Price value={credit.amountDeducted} currencyCode={activeOrder.currencyCode}/></span>
128
- </div>
129
- ))}
135
+ {hasCreditsApplied &&
136
+ activeOrder.storeCreditsApplied.map((credit) => (
137
+ <div key={credit.code} className="flex justify-between text-sm text-green-600">
138
+ <span>{t('storeCredit', { code: maskCode(credit.code) })}</span>
139
+ <span>
140
+ -
141
+ <Price
142
+ value={credit.amountDeducted}
143
+ currencyCode={activeOrder.currencyCode}
144
+ />
145
+ </span>
146
+ </div>
147
+ ))}
130
148
  </div>
131
149
 
132
150
  <div className="border-t pt-4 mb-6">
@@ -136,12 +154,23 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
136
154
  {hasCreditsApplied ? (
137
155
  <span className="flex items-center gap-2">
138
156
  <span className="text-sm font-normal text-muted-foreground line-through">
139
- <Price value={activeOrder.totalWithTax} currencyCode={activeOrder.currencyCode}/>
157
+ <Price
158
+ value={activeOrder.totalWithTax}
159
+ currencyCode={activeOrder.currencyCode}
160
+ />
140
161
  </span>
141
- <Price value={activeOrder.totalWithTaxAfterStoreCredit} currencyCode={activeOrder.currencyCode} taxLabel="incl" />
162
+ <Price
163
+ value={activeOrder.totalWithTaxAfterStoreCredit}
164
+ currencyCode={activeOrder.currencyCode}
165
+ taxLabel="incl"
166
+ />
142
167
  </span>
143
168
  ) : (
144
- <Price value={activeOrder.totalWithTax} currencyCode={activeOrder.currencyCode} taxLabel="incl" />
169
+ <Price
170
+ value={activeOrder.totalWithTax}
171
+ currencyCode={activeOrder.currencyCode}
172
+ taxLabel="incl"
173
+ />
145
174
  )}
146
175
  </span>
147
176
  </div>
@@ -156,9 +185,7 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
156
185
  <Button className="w-full" size="lg" disabled>
157
186
  {t('checkoutNotPermitted')}
158
187
  </Button>
159
- <p className="text-xs text-muted-foreground text-center">
160
- {t('noOrderingPermissions')}
161
- </p>
188
+ <p className="text-xs text-muted-foreground text-center">{t('noOrderingPermissions')}</p>
162
189
  </div>
163
190
  )}
164
191
 
@@ -170,6 +197,20 @@ export async function OrderSummary({activeOrder}: { activeOrder: ActiveOrder })
170
197
  />
171
198
  )}
172
199
 
200
+ {canShareCart && activeOrder.lines.length > 0 && (
201
+ <AddToSharedCart
202
+ lines={activeOrder.lines.map((line) => ({
203
+ productVariantId: line.productVariant.id,
204
+ quantity: line.quantity,
205
+ }))}
206
+ canCreate
207
+ defaultName={shareDefaultName}
208
+ label="Share this cart"
209
+ size="default"
210
+ className="w-full mt-2 gap-2"
211
+ />
212
+ )}
213
+
173
214
  <Button variant="outline" className="w-full mt-2" asChild>
174
215
  <Link href="/">{t('continueShopping')}</Link>
175
216
  </Button>
@@ -1,15 +1,15 @@
1
- import type {Metadata} from 'next';
2
- import {Cart} from "@/app/[locale]/cart/cart";
3
- import {Suspense} from "react";
4
- import {CartSkeleton} from "@/components/shared/skeletons/cart-skeleton";
5
- import {noIndexRobots} from '@/lib/metadata';
6
- import {locale as rootLocale} from 'next/root-params';
7
- import {getTranslations} from 'next-intl/server';
8
- import {type Locale} from '@/i18n/routing';
1
+ import { Cart } from '@/app/[locale]/cart/cart';
2
+ import { CartSkeleton } from '@/components/shared/skeletons/cart-skeleton';
3
+ import { type Locale } from '@/i18n/routing';
4
+ import { noIndexRobots } from '@/lib/metadata';
5
+ import type { Metadata } from 'next';
6
+ import { getTranslations } from 'next-intl/server';
7
+ import { locale as rootLocale } from 'next/root-params';
8
+ import { Suspense } from 'react';
9
9
 
10
10
  export async function generateMetadata(): Promise<Metadata> {
11
11
  const locale = (await rootLocale()) as Locale;
12
- const t = await getTranslations({locale, namespace: 'Cart'});
12
+ const t = await getTranslations({ locale, namespace: 'Cart' });
13
13
  return {
14
14
  title: t('title'),
15
15
  description: t('description'),
@@ -19,14 +19,14 @@ export async function generateMetadata(): Promise<Metadata> {
19
19
 
20
20
  export default async function CartPage() {
21
21
  const locale = (await rootLocale()) as Locale;
22
- const t = await getTranslations({locale, namespace: 'Cart'});
22
+ const t = await getTranslations({ locale, namespace: 'Cart' });
23
23
 
24
24
  return (
25
25
  <div className="container mx-auto px-4 py-8 mt-[var(--page-top-offset)]">
26
26
  <h1 className="text-3xl font-bold mb-8">{t('title')}</h1>
27
27
 
28
28
  <Suspense fallback={<CartSkeleton />}>
29
- <Cart/>
29
+ <Cart />
30
30
  </Suspense>
31
31
  </div>
32
32
  );
@@ -1,14 +1,14 @@
1
- import {Button} from '@/components/ui/button';
2
- import {Card, CardContent, CardDescription, CardHeader, CardTitle} from '@/components/ui/card';
3
- import {Tag, Wallet} from 'lucide-react';
4
- import {applyStoreCredit, removePromotionCode, removeStoreCredit} from './actions';
5
- import {CodeInput} from './code-input';
6
- import {client} from '@/lib/vendure/api';
7
- import {GetMyStoreCreditsQuery} from '@/lib/vendure/queries';
8
- import {getActiveCustomer} from '@/lib/vendure/actions';
9
- import {Price} from '@/components/commerce/price';
10
- import {maskCode} from '@/lib/format';
11
- import {getTranslations} from 'next-intl/server';
1
+ import { Price } from '@/components/commerce/price';
2
+ import { Button } from '@/components/ui/button';
3
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
4
+ import { maskCode } from '@/lib/format';
5
+ import { getActiveCustomer } from '@/lib/vendure/actions';
6
+ import { client } from '@/lib/vendure/api';
7
+ import { GetMyStoreCreditsQuery } from '@/lib/vendure/queries';
8
+ import { Tag, Wallet } from 'lucide-react';
9
+ import { getTranslations } from 'next-intl/server';
10
+ import { applyStoreCredit, removePromotionCode, removeStoreCredit } from './actions';
11
+ import { CodeInput } from './code-input';
12
12
 
13
13
  const MAX_STORE_CREDITS_IN_CART = 100;
14
14
 
@@ -20,46 +20,48 @@ type ActiveOrder = {
20
20
  currencyCode: string;
21
21
  };
22
22
 
23
- export async function PromotionCode({activeOrder}: { activeOrder: ActiveOrder }) {
23
+ export async function PromotionCode({ activeOrder }: { activeOrder: ActiveOrder }) {
24
24
  const [t, activeCustomer, [creditsResult, creditsError]] = await Promise.all([
25
25
  getTranslations('Cart'),
26
26
  getActiveCustomer(),
27
- client.query(GetMyStoreCreditsQuery, {options: {take: MAX_STORE_CREDITS_IN_CART}}),
27
+ client.query(GetMyStoreCreditsQuery, { options: { take: MAX_STORE_CREDITS_IN_CART } }),
28
28
  ]);
29
- const availableCredits = creditsError ? [] : (creditsResult.data.myStoreCredits?.items ?? []);
30
- const appliedCodes = new Set(activeOrder.storeCreditsApplied.map(c => c.code));
29
+ const availableCredits = creditsError ? [] : creditsResult.data.myStoreCredits?.items ?? [];
30
+ const appliedCodes = new Set(activeOrder.storeCreditsApplied.map((c) => c.code));
31
31
  const activeCustomerId = activeCustomer?.id;
32
32
  // Only show credits the current customer can actually redeem (own + unclaimed)
33
33
  // Hide when order is already fully covered by applied credits
34
34
  const orderFullyCovered = activeOrder.totalWithTaxAfterStoreCredit <= 0;
35
- const redeemableCredits = orderFullyCovered ? [] : availableCredits.filter(
36
- c => !appliedCodes.has(c.code) && (!c.issuedTo || c.issuedTo.id === activeCustomerId),
37
- );
35
+ const redeemableCredits = orderFullyCovered
36
+ ? []
37
+ : availableCredits.filter(
38
+ (c) => !appliedCodes.has(c.code) && (!c.issuedTo || c.issuedTo.id === activeCustomerId),
39
+ );
38
40
 
39
41
  return (
40
42
  <Card>
41
43
  <CardHeader>
42
44
  <CardTitle className="text-lg flex items-center gap-2">
43
- <Tag className="h-5 w-5"/>
45
+ <Tag className="h-5 w-5" />
44
46
  {t('promotionCode')}
45
47
  </CardTitle>
46
- <CardDescription>
47
- {t('enterDiscountCode')}
48
- </CardDescription>
48
+ <CardDescription>{t('enterDiscountCode')}</CardDescription>
49
49
  </CardHeader>
50
50
  <CardContent className="space-y-4">
51
51
  {/* Applied coupon codes */}
52
52
  {activeOrder.couponCodes && activeOrder.couponCodes.length > 0 && (
53
53
  <div className="space-y-2">
54
54
  {activeOrder.couponCodes.map((code) => (
55
- <div key={code}
56
- className="flex items-center justify-between p-3 border rounded-md bg-green-50 dark:bg-green-950/20">
55
+ <div
56
+ key={code}
57
+ className="flex items-center justify-between p-3 border rounded-md bg-green-50 dark:bg-green-950/20"
58
+ >
57
59
  <div className="flex items-center gap-2">
58
- <Tag className="h-4 w-4 text-green-600"/>
60
+ <Tag className="h-4 w-4 text-green-600" />
59
61
  <span className="font-medium text-sm">{code}</span>
60
62
  </div>
61
63
  <form action={removePromotionCode}>
62
- <input type="hidden" name="code" value={code}/>
64
+ <input type="hidden" name="code" value={code} />
63
65
  <Button
64
66
  type="submit"
65
67
  variant="ghost"
@@ -78,19 +80,23 @@ export async function PromotionCode({activeOrder}: { activeOrder: ActiveOrder })
78
80
  {activeOrder.storeCreditsApplied.length > 0 && (
79
81
  <div className="space-y-2">
80
82
  {activeOrder.storeCreditsApplied.map((credit) => (
81
- <div key={credit.code}
82
- className="flex items-center justify-between p-3 border rounded-md bg-green-50 dark:bg-green-950/20">
83
+ <div
84
+ key={credit.code}
85
+ className="flex items-center justify-between p-3 border rounded-md bg-green-50 dark:bg-green-950/20"
86
+ >
83
87
  <div className="flex items-center gap-2">
84
- <Wallet className="h-4 w-4 text-green-600"/>
85
- <span className="font-medium text-sm">
86
- {maskCode(credit.code)}
87
- </span>
88
+ <Wallet className="h-4 w-4 text-green-600" />
89
+ <span className="font-medium text-sm">{maskCode(credit.code)}</span>
88
90
  <span className="text-xs text-green-600">
89
- -<Price value={credit.amountDeducted} currencyCode={activeOrder.currencyCode}/>
91
+ -
92
+ <Price
93
+ value={credit.amountDeducted}
94
+ currencyCode={activeOrder.currencyCode}
95
+ />
90
96
  </span>
91
97
  </div>
92
98
  <form action={removeStoreCredit}>
93
- <input type="hidden" name="code" value={credit.code}/>
99
+ <input type="hidden" name="code" value={credit.code} />
94
100
  <Button
95
101
  type="submit"
96
102
  variant="ghost"
@@ -109,22 +115,22 @@ export async function PromotionCode({activeOrder}: { activeOrder: ActiveOrder })
109
115
  {redeemableCredits.length > 0 && (
110
116
  <div className="space-y-2">
111
117
  <p className="text-xs text-muted-foreground font-medium flex items-center gap-1.5">
112
- <Wallet className="h-3.5 w-3.5"/>
118
+ <Wallet className="h-3.5 w-3.5" />
113
119
  {t('availableStoreCredits')}
114
120
  </p>
115
121
  {redeemableCredits.map((credit) => (
116
- <div key={credit.id}
117
- className="flex items-center justify-between p-3 border rounded-md">
122
+ <div
123
+ key={credit.id}
124
+ className="flex items-center justify-between p-3 border rounded-md"
125
+ >
118
126
  <div className="flex items-center gap-2">
119
- <span className="font-mono text-sm">
120
- {maskCode(credit.code)}
121
- </span>
127
+ <span className="font-mono text-sm">{maskCode(credit.code)}</span>
122
128
  <span className="text-xs text-muted-foreground">
123
- <Price value={credit.balance} currencyCode={credit.currencyCode}/>
129
+ <Price value={credit.balance} currencyCode={credit.currencyCode} />
124
130
  </span>
125
131
  </div>
126
132
  <form action={applyStoreCredit}>
127
- <input type="hidden" name="code" value={credit.code}/>
133
+ <input type="hidden" name="code" value={credit.code} />
128
134
  <Button type="submit" variant="outline" size="sm" className="h-8">
129
135
  {t('apply')}
130
136
  </Button>
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
 
3
- import {useState, useCallback, useRef} from 'react';
4
3
  import {
5
4
  AlertDialog,
6
5
  AlertDialogAction,
@@ -11,7 +10,8 @@ import {
11
10
  AlertDialogHeader,
12
11
  AlertDialogTitle,
13
12
  } from '@/components/ui/alert-dialog';
14
- import {useTranslations} from 'next-intl';
13
+ import { useTranslations } from 'next-intl';
14
+ import { useCallback, useRef, useState } from 'react';
15
15
 
16
16
  /**
17
17
  * Hook that provides a confirmation gate for actions that would invalidate
@@ -26,23 +26,27 @@ export function useReapprovalConfirm(requiresReapproval?: boolean | (() => Promi
26
26
  const [isChecking, setIsChecking] = useState(false);
27
27
  const pendingActionRef = useRef<(() => void) | null>(null);
28
28
 
29
- const guardCartChange = useCallback(async (action: () => void) => {
30
- setIsChecking(true);
31
- try {
32
- const needsConfirmation = typeof requiresReapproval === 'function'
33
- ? await requiresReapproval()
34
- : requiresReapproval;
29
+ const guardCartChange = useCallback(
30
+ async (action: () => void) => {
31
+ setIsChecking(true);
32
+ try {
33
+ const needsConfirmation =
34
+ typeof requiresReapproval === 'function'
35
+ ? await requiresReapproval()
36
+ : requiresReapproval;
35
37
 
36
- if (needsConfirmation) {
37
- pendingActionRef.current = action;
38
- setOpen(true);
39
- } else {
40
- action();
38
+ if (needsConfirmation) {
39
+ pendingActionRef.current = action;
40
+ setOpen(true);
41
+ } else {
42
+ action();
43
+ }
44
+ } finally {
45
+ setIsChecking(false);
41
46
  }
42
- } finally {
43
- setIsChecking(false);
44
- }
45
- }, [requiresReapproval]);
47
+ },
48
+ [requiresReapproval],
49
+ );
46
50
 
47
51
  const handleConfirm = useCallback(() => {
48
52
  setOpen(false);
@@ -60,9 +64,7 @@ export function useReapprovalConfirm(requiresReapproval?: boolean | (() => Promi
60
64
  <AlertDialogContent>
61
65
  <AlertDialogHeader>
62
66
  <AlertDialogTitle>{t('reapprovalTitle')}</AlertDialogTitle>
63
- <AlertDialogDescription>
64
- {t('reapprovalMessage')}
65
- </AlertDialogDescription>
67
+ <AlertDialogDescription>{t('reapprovalMessage')}</AlertDialogDescription>
66
68
  </AlertDialogHeader>
67
69
  <AlertDialogFooter>
68
70
  <AlertDialogCancel onClick={handleCancel}>{t('cancel')}</AlertDialogCancel>