@vendure-platform/create 0.5.0 → 0.5.2

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 (325) 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/next.config.ts +5 -4
  9. package/dist/assets/storefront/package.json +1 -1
  10. package/dist/assets/storefront/postcss.config.mjs +1 -1
  11. package/dist/assets/storefront/src/app/[locale]/(catalog)/catalog/page.tsx +17 -21
  12. package/dist/assets/storefront/src/app/[locale]/(catalog)/collection/[slug]/page.tsx +64 -42
  13. package/dist/assets/storefront/src/app/[locale]/(catalog)/layout.tsx +1 -5
  14. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/actions.ts +69 -65
  15. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/page.tsx +64 -38
  16. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/page.tsx +24 -27
  17. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-results.tsx +11 -9
  18. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-term.tsx +4 -4
  19. package/dist/assets/storefront/src/app/[locale]/(scenario)/[...path]/page.tsx +1 -1
  20. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/accept-invitation-client.tsx +8 -13
  21. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/actions.ts +11 -14
  22. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/page.tsx +30 -33
  23. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/sign-out-and-retry.tsx +6 -6
  24. package/dist/assets/storefront/src/app/[locale]/account/addresses/actions.ts +30 -45
  25. package/dist/assets/storefront/src/app/[locale]/account/addresses/address-form.tsx +166 -159
  26. package/dist/assets/storefront/src/app/[locale]/account/addresses/addresses-client.tsx +35 -26
  27. package/dist/assets/storefront/src/app/[locale]/account/addresses/loading.tsx +1 -3
  28. package/dist/assets/storefront/src/app/[locale]/account/addresses/page.tsx +16 -18
  29. package/dist/assets/storefront/src/app/[locale]/account/approvals/actions.ts +5 -8
  30. package/dist/assets/storefront/src/app/[locale]/account/approvals/page.tsx +77 -69
  31. package/dist/assets/storefront/src/app/[locale]/account/company/actions.ts +10 -11
  32. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/actions.ts +6 -15
  33. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/address-form.tsx +57 -49
  34. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/addresses-client.tsx +23 -25
  35. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/page.tsx +30 -30
  36. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/actions.ts +20 -29
  37. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-unit-form.tsx +32 -37
  38. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-units-client.tsx +32 -25
  39. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/page.tsx +24 -24
  40. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/types.ts +7 -4
  41. package/dist/assets/storefront/src/app/[locale]/account/company/edit-company-form.tsx +11 -21
  42. package/dist/assets/storefront/src/app/[locale]/account/company/page.tsx +23 -28
  43. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/page.tsx +24 -24
  44. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/payment-methods-client.tsx +5 -7
  45. package/dist/assets/storefront/src/app/[locale]/account/company/roles/page.tsx +22 -25
  46. package/dist/assets/storefront/src/app/[locale]/account/company/roles/roles-client.tsx +11 -26
  47. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/actions.ts +6 -10
  48. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/page.tsx +18 -16
  49. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/tax-ids-client.tsx +74 -67
  50. package/dist/assets/storefront/src/app/[locale]/account/company/users/actions.ts +16 -25
  51. package/dist/assets/storefront/src/app/[locale]/account/company/users/edit-user-form.tsx +27 -25
  52. package/dist/assets/storefront/src/app/[locale]/account/company/users/invite-user-form.tsx +27 -19
  53. package/dist/assets/storefront/src/app/[locale]/account/company/users/page.tsx +32 -29
  54. package/dist/assets/storefront/src/app/[locale]/account/company/users/users-client.tsx +35 -38
  55. package/dist/assets/storefront/src/app/[locale]/account/error.tsx +1 -3
  56. package/dist/assets/storefront/src/app/[locale]/account/layout.tsx +16 -22
  57. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/page.tsx +151 -103
  58. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-actions.ts +6 -7
  59. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-dialog.tsx +22 -48
  60. package/dist/assets/storefront/src/app/[locale]/account/orders/loading.tsx +8 -8
  61. package/dist/assets/storefront/src/app/[locale]/account/orders/page.tsx +101 -61
  62. package/dist/assets/storefront/src/app/[locale]/account/profile/actions.ts +32 -23
  63. package/dist/assets/storefront/src/app/[locale]/account/profile/change-password-form.tsx +6 -16
  64. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-email-form.tsx +7 -17
  65. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-profile-form.tsx +6 -16
  66. package/dist/assets/storefront/src/app/[locale]/account/profile/loading.tsx +12 -18
  67. package/dist/assets/storefront/src/app/[locale]/account/profile/page.tsx +15 -15
  68. package/dist/assets/storefront/src/app/[locale]/account/quick-order/file-upload-tab.tsx +2 -6
  69. package/dist/assets/storefront/src/app/[locale]/account/quick-order/manual-entry-tab.tsx +18 -15
  70. package/dist/assets/storefront/src/app/[locale]/account/quick-order/page.tsx +3 -6
  71. package/dist/assets/storefront/src/app/[locale]/account/quick-order/preview-table.tsx +10 -2
  72. package/dist/assets/storefront/src/app/[locale]/account/quick-order/save-to-list-dialog.tsx +24 -26
  73. package/dist/assets/storefront/src/app/[locale]/account/quick-order/sku-autocomplete.tsx +19 -10
  74. package/dist/assets/storefront/src/app/[locale]/account/quick-order/text-input-tab.tsx +3 -8
  75. package/dist/assets/storefront/src/app/[locale]/account/quotes/[id]/page.tsx +86 -59
  76. package/dist/assets/storefront/src/app/[locale]/account/quotes/actions.ts +38 -45
  77. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/new-quote-form.tsx +3 -5
  78. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/page.tsx +6 -6
  79. package/dist/assets/storefront/src/app/[locale]/account/quotes/page.tsx +92 -59
  80. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-item-search.tsx +11 -9
  81. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-member-form.tsx +31 -15
  82. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/members-panel.tsx +52 -33
  83. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/page.tsx +22 -14
  84. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/rename-dialog.tsx +34 -13
  85. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/actions.ts +117 -72
  86. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/new-shared-cart-form.tsx +21 -14
  87. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/page.tsx +10 -10
  88. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/page.tsx +54 -41
  89. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/page.tsx +22 -8
  90. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/shopping-list-detail-client.tsx +62 -49
  91. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/actions.ts +9 -4
  92. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/create-shopping-list-form.tsx +5 -11
  93. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/loading.tsx +1 -1
  94. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/page.tsx +32 -42
  95. package/dist/assets/storefront/src/app/[locale]/account/store-credits/actions.ts +8 -8
  96. package/dist/assets/storefront/src/app/[locale]/account/store-credits/claim-form.tsx +6 -10
  97. package/dist/assets/storefront/src/app/[locale]/account/store-credits/page.tsx +76 -55
  98. package/dist/assets/storefront/src/app/[locale]/account/store-credits/reveal-code.tsx +10 -6
  99. package/dist/assets/storefront/src/app/[locale]/account/verify-email/page.tsx +32 -39
  100. package/dist/assets/storefront/src/app/[locale]/cart/actions.ts +29 -23
  101. package/dist/assets/storefront/src/app/[locale]/cart/cart-items.tsx +111 -40
  102. package/dist/assets/storefront/src/app/[locale]/cart/cart-line-actions.tsx +9 -9
  103. package/dist/assets/storefront/src/app/[locale]/cart/cart-quantity-control.tsx +61 -48
  104. package/dist/assets/storefront/src/app/[locale]/cart/cart-remove-button.tsx +15 -9
  105. package/dist/assets/storefront/src/app/[locale]/cart/cart.tsx +38 -41
  106. package/dist/assets/storefront/src/app/[locale]/cart/code-input.tsx +8 -8
  107. package/dist/assets/storefront/src/app/[locale]/cart/order-summary.tsx +50 -32
  108. package/dist/assets/storefront/src/app/[locale]/cart/page.tsx +11 -11
  109. package/dist/assets/storefront/src/app/[locale]/cart/promotion-code.tsx +48 -42
  110. package/dist/assets/storefront/src/app/[locale]/cart/reapproval-confirm.tsx +22 -20
  111. package/dist/assets/storefront/src/app/[locale]/cart/request-quote-button.tsx +7 -16
  112. package/dist/assets/storefront/src/app/[locale]/checkout/actions.ts +39 -65
  113. package/dist/assets/storefront/src/app/[locale]/checkout/cancel-quote-checkout-button.tsx +5 -5
  114. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-flow.tsx +202 -202
  115. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-provider.tsx +142 -142
  116. package/dist/assets/storefront/src/app/[locale]/checkout/order-summary.tsx +158 -139
  117. package/dist/assets/storefront/src/app/[locale]/checkout/page.tsx +56 -47
  118. package/dist/assets/storefront/src/app/[locale]/checkout/steps/delivery-step.tsx +86 -88
  119. package/dist/assets/storefront/src/app/[locale]/checkout/steps/payment-step.tsx +90 -91
  120. package/dist/assets/storefront/src/app/[locale]/checkout/steps/review-step.tsx +166 -161
  121. package/dist/assets/storefront/src/app/[locale]/checkout/steps/shipping-address-step.tsx +573 -494
  122. package/dist/assets/storefront/src/app/[locale]/error.tsx +3 -5
  123. package/dist/assets/storefront/src/app/[locale]/forgot-password/actions.ts +10 -7
  124. package/dist/assets/storefront/src/app/[locale]/forgot-password/forgot-password-form.tsx +10 -25
  125. package/dist/assets/storefront/src/app/[locale]/forgot-password/page.tsx +5 -5
  126. package/dist/assets/storefront/src/app/[locale]/globals.css +48 -48
  127. package/dist/assets/storefront/src/app/[locale]/layout.tsx +53 -47
  128. package/dist/assets/storefront/src/app/[locale]/not-found.tsx +3 -5
  129. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/order-confirmation.tsx +71 -44
  130. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/page.tsx +7 -5
  131. package/dist/assets/storefront/src/app/[locale]/page.tsx +33 -35
  132. package/dist/assets/storefront/src/app/[locale]/register/actions.ts +7 -7
  133. package/dist/assets/storefront/src/app/[locale]/register/page.tsx +22 -16
  134. package/dist/assets/storefront/src/app/[locale]/register/registration-form.tsx +22 -34
  135. package/dist/assets/storefront/src/app/[locale]/register-company/actions.ts +15 -19
  136. package/dist/assets/storefront/src/app/[locale]/register-company/page.tsx +17 -15
  137. package/dist/assets/storefront/src/app/[locale]/register-company/registration-form.tsx +9 -15
  138. package/dist/assets/storefront/src/app/[locale]/reset-password/actions.ts +7 -8
  139. package/dist/assets/storefront/src/app/[locale]/reset-password/page.tsx +18 -12
  140. package/dist/assets/storefront/src/app/[locale]/reset-password/reset-password-form.tsx +8 -16
  141. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/add-to-cart-button.tsx +10 -4
  142. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/page.tsx +62 -30
  143. package/dist/assets/storefront/src/app/[locale]/sign-in/actions.ts +14 -16
  144. package/dist/assets/storefront/src/app/[locale]/sign-in/login-form.tsx +17 -30
  145. package/dist/assets/storefront/src/app/[locale]/sign-in/page.tsx +35 -30
  146. package/dist/assets/storefront/src/app/[locale]/verify/actions.ts +8 -8
  147. package/dist/assets/storefront/src/app/[locale]/verify/page.tsx +18 -14
  148. package/dist/assets/storefront/src/app/[locale]/verify/verify-content.tsx +25 -27
  149. package/dist/assets/storefront/src/app/[locale]/verify-pending/page.tsx +23 -23
  150. package/dist/assets/storefront/src/app/api/clear-company-context/route.ts +6 -3
  151. package/dist/assets/storefront/src/app/api/revalidate/route.ts +19 -28
  152. package/dist/assets/storefront/src/app/api/search-analytics/route.ts +1 -1
  153. package/dist/assets/storefront/src/components/commerce/account-nav-items.ts +43 -18
  154. package/dist/assets/storefront/src/components/commerce/account-sidebar.tsx +30 -22
  155. package/dist/assets/storefront/src/components/commerce/active-filters.tsx +1 -1
  156. package/dist/assets/storefront/src/components/commerce/add-to-shared-cart.tsx +49 -27
  157. package/dist/assets/storefront/src/components/commerce/approval-decision-form.tsx +9 -13
  158. package/dist/assets/storefront/src/components/commerce/approval-status-badge.tsx +23 -15
  159. package/dist/assets/storefront/src/components/commerce/business-unit-switcher.tsx +11 -11
  160. package/dist/assets/storefront/src/components/commerce/catalog-search-bar.tsx +2 -2
  161. package/dist/assets/storefront/src/components/commerce/category-product-section.tsx +28 -16
  162. package/dist/assets/storefront/src/components/commerce/category-sidebar.tsx +31 -18
  163. package/dist/assets/storefront/src/components/commerce/collection-hero-banner.tsx +2 -4
  164. package/dist/assets/storefront/src/components/commerce/company-state-badge.tsx +10 -16
  165. package/dist/assets/storefront/src/components/commerce/company-switcher.tsx +12 -12
  166. package/dist/assets/storefront/src/components/commerce/configurator-form.tsx +188 -79
  167. package/dist/assets/storefront/src/components/commerce/facet-filters.tsx +29 -49
  168. package/dist/assets/storefront/src/components/commerce/gift-card-pdp.tsx +4 -4
  169. package/dist/assets/storefront/src/components/commerce/gift-card-product-info.tsx +20 -30
  170. package/dist/assets/storefront/src/components/commerce/instant-search-dropdown.tsx +258 -227
  171. package/dist/assets/storefront/src/components/commerce/order-status-badge.tsx +27 -19
  172. package/dist/assets/storefront/src/components/commerce/packaging-unit-selector.tsx +27 -26
  173. package/dist/assets/storefront/src/components/commerce/permission-gate.tsx +4 -4
  174. package/dist/assets/storefront/src/components/commerce/price-range-filter.tsx +5 -5
  175. package/dist/assets/storefront/src/components/commerce/price-tiers.tsx +38 -21
  176. package/dist/assets/storefront/src/components/commerce/price.tsx +3 -3
  177. package/dist/assets/storefront/src/components/commerce/product-card-list.tsx +35 -14
  178. package/dist/assets/storefront/src/components/commerce/product-card.tsx +31 -16
  179. package/dist/assets/storefront/src/components/commerce/product-carousel.tsx +20 -12
  180. package/dist/assets/storefront/src/components/commerce/product-grid.tsx +14 -13
  181. package/dist/assets/storefront/src/components/commerce/product-image-carousel.tsx +10 -8
  182. package/dist/assets/storefront/src/components/commerce/product-info.tsx +118 -74
  183. package/dist/assets/storefront/src/components/commerce/product-list-expansion.tsx +102 -74
  184. package/dist/assets/storefront/src/components/commerce/product-list-view.tsx +1 -1
  185. package/dist/assets/storefront/src/components/commerce/product-sidebar.tsx +36 -11
  186. package/dist/assets/storefront/src/components/commerce/product-view-switcher.tsx +33 -21
  187. package/dist/assets/storefront/src/components/commerce/quote-action-buttons.tsx +54 -36
  188. package/dist/assets/storefront/src/components/commerce/quote-activity-timeline.tsx +126 -50
  189. package/dist/assets/storefront/src/components/commerce/quote-comment-form.tsx +9 -13
  190. package/dist/assets/storefront/src/components/commerce/quote-csv-export-button.tsx +6 -6
  191. package/dist/assets/storefront/src/components/commerce/quote-product-search.tsx +22 -18
  192. package/dist/assets/storefront/src/components/commerce/quote-request-form.tsx +28 -27
  193. package/dist/assets/storefront/src/components/commerce/quote-status-badge.tsx +26 -18
  194. package/dist/assets/storefront/src/components/commerce/quote-validity-indicator.tsx +7 -7
  195. package/dist/assets/storefront/src/components/commerce/quote-version-comparison.tsx +50 -30
  196. package/dist/assets/storefront/src/components/commerce/related-products.tsx +37 -28
  197. package/dist/assets/storefront/src/components/commerce/shared-cart-status-badge.tsx +12 -8
  198. package/dist/assets/storefront/src/components/commerce/shop-by-category.tsx +8 -7
  199. package/dist/assets/storefront/src/components/commerce/shopping-list-toggle.tsx +14 -20
  200. package/dist/assets/storefront/src/components/commerce/sort-dropdown.tsx +9 -16
  201. package/dist/assets/storefront/src/components/commerce/store-credit-summary.tsx +30 -32
  202. package/dist/assets/storefront/src/components/commerce/subcollection-tiles.tsx +11 -13
  203. package/dist/assets/storefront/src/components/layout/auth-page-shell.tsx +2 -2
  204. package/dist/assets/storefront/src/components/layout/draft-mode-indicator.tsx +2 -7
  205. package/dist/assets/storefront/src/components/layout/draft-mode-link.tsx +4 -2
  206. package/dist/assets/storefront/src/components/layout/footer.tsx +70 -28
  207. package/dist/assets/storefront/src/components/layout/navbar/actions.ts +9 -12
  208. package/dist/assets/storefront/src/components/layout/navbar/cart-icon.tsx +9 -9
  209. package/dist/assets/storefront/src/components/layout/navbar/channel-picker-wrapper.tsx +4 -9
  210. package/dist/assets/storefront/src/components/layout/navbar/channel-picker.tsx +13 -8
  211. package/dist/assets/storefront/src/components/layout/navbar/currency-picker-wrapper.tsx +4 -4
  212. package/dist/assets/storefront/src/components/layout/navbar/currency-picker.tsx +11 -6
  213. package/dist/assets/storefront/src/components/layout/navbar/language-picker.tsx +7 -7
  214. package/dist/assets/storefront/src/components/layout/navbar/login-button.tsx +24 -21
  215. package/dist/assets/storefront/src/components/layout/navbar/mobile-nav.tsx +8 -8
  216. package/dist/assets/storefront/src/components/layout/navbar/nav-menu-items.tsx +4 -6
  217. package/dist/assets/storefront/src/components/layout/navbar/navbar-cart.tsx +1 -1
  218. package/dist/assets/storefront/src/components/layout/navbar/navbar-collections.tsx +41 -42
  219. package/dist/assets/storefront/src/components/layout/navbar/navbar-link.tsx +7 -10
  220. package/dist/assets/storefront/src/components/layout/navbar/navbar-user.tsx +18 -23
  221. package/dist/assets/storefront/src/components/layout/navbar/theme-switcher.tsx +9 -9
  222. package/dist/assets/storefront/src/components/layout/navbar.tsx +36 -31
  223. package/dist/assets/storefront/src/components/layout/search-input.tsx +35 -32
  224. package/dist/assets/storefront/src/components/providers/awaiting-approval-banner.tsx +12 -10
  225. package/dist/assets/storefront/src/components/providers/cart-count-server.tsx +14 -12
  226. package/dist/assets/storefront/src/components/providers/company-context-guard.tsx +4 -4
  227. package/dist/assets/storefront/src/components/providers/company-permissions-server.tsx +2 -6
  228. package/dist/assets/storefront/src/components/providers/theme-provider.tsx +3 -3
  229. package/dist/assets/storefront/src/components/shared/breadcrumbs.tsx +4 -1
  230. package/dist/assets/storefront/src/components/shared/country-select.tsx +63 -67
  231. package/dist/assets/storefront/src/components/shared/pagination.tsx +15 -28
  232. package/dist/assets/storefront/src/components/shared/prefetch-link.tsx +1 -1
  233. package/dist/assets/storefront/src/components/shared/skeletons/search-input-skeleton.tsx +1 -3
  234. package/dist/assets/storefront/src/components/ui/accordion.tsx +46 -51
  235. package/dist/assets/storefront/src/components/ui/alert-dialog.tsx +94 -121
  236. package/dist/assets/storefront/src/components/ui/alert.tsx +48 -54
  237. package/dist/assets/storefront/src/components/ui/aspect-ratio.tsx +5 -7
  238. package/dist/assets/storefront/src/components/ui/avatar.tsx +29 -44
  239. package/dist/assets/storefront/src/components/ui/badge.tsx +28 -37
  240. package/dist/assets/storefront/src/components/ui/breadcrumb.tsx +82 -89
  241. package/dist/assets/storefront/src/components/ui/button.tsx +43 -49
  242. package/dist/assets/storefront/src/components/ui/calendar.tsx +157 -198
  243. package/dist/assets/storefront/src/components/ui/card.tsx +53 -76
  244. package/dist/assets/storefront/src/components/ui/carousel.tsx +194 -212
  245. package/dist/assets/storefront/src/components/ui/chart.tsx +274 -317
  246. package/dist/assets/storefront/src/components/ui/checkbox.tsx +24 -27
  247. package/dist/assets/storefront/src/components/ui/collapsible.tsx +9 -21
  248. package/dist/assets/storefront/src/components/ui/command.tsx +114 -159
  249. package/dist/assets/storefront/src/components/ui/context-menu.tsx +167 -199
  250. package/dist/assets/storefront/src/components/ui/dialog.tsx +97 -114
  251. package/dist/assets/storefront/src/components/ui/drawer.tsx +93 -107
  252. package/dist/assets/storefront/src/components/ui/dropdown-menu.tsx +171 -206
  253. package/dist/assets/storefront/src/components/ui/empty-state.tsx +5 -5
  254. package/dist/assets/storefront/src/components/ui/field.tsx +196 -208
  255. package/dist/assets/storefront/src/components/ui/form.tsx +115 -139
  256. package/dist/assets/storefront/src/components/ui/hover-card.tsx +27 -33
  257. package/dist/assets/storefront/src/components/ui/input-otp.tsx +50 -59
  258. package/dist/assets/storefront/src/components/ui/input.tsx +17 -17
  259. package/dist/assets/storefront/src/components/ui/kbd-shortcut.tsx +3 -1
  260. package/dist/assets/storefront/src/components/ui/label.tsx +16 -19
  261. package/dist/assets/storefront/src/components/ui/menubar.tsx +193 -223
  262. package/dist/assets/storefront/src/components/ui/navigation-menu.tsx +123 -130
  263. package/dist/assets/storefront/src/components/ui/pagination.tsx +87 -108
  264. package/dist/assets/storefront/src/components/ui/popover.tsx +29 -35
  265. package/dist/assets/storefront/src/components/ui/progress.tsx +19 -26
  266. package/dist/assets/storefront/src/components/ui/radio-group.tsx +32 -38
  267. package/dist/assets/storefront/src/components/ui/resizable.tsx +37 -42
  268. package/dist/assets/storefront/src/components/ui/scroll-area.tsx +41 -47
  269. package/dist/assets/storefront/src/components/ui/select.tsx +130 -152
  270. package/dist/assets/storefront/src/components/ui/separator.tsx +21 -21
  271. package/dist/assets/storefront/src/components/ui/sheet.tsx +90 -111
  272. package/dist/assets/storefront/src/components/ui/sidebar.tsx +611 -649
  273. package/dist/assets/storefront/src/components/ui/skeleton.tsx +10 -10
  274. package/dist/assets/storefront/src/components/ui/slider.tsx +50 -55
  275. package/dist/assets/storefront/src/components/ui/sonner.tsx +20 -20
  276. package/dist/assets/storefront/src/components/ui/switch.tsx +23 -26
  277. package/dist/assets/storefront/src/components/ui/table.tsx +65 -97
  278. package/dist/assets/storefront/src/components/ui/tabs.tsx +39 -55
  279. package/dist/assets/storefront/src/components/ui/textarea.tsx +14 -14
  280. package/dist/assets/storefront/src/components/ui/toggle-group.tsx +56 -62
  281. package/dist/assets/storefront/src/components/ui/toggle.tsx +37 -38
  282. package/dist/assets/storefront/src/components/ui/tooltip.tsx +38 -46
  283. package/dist/assets/storefront/src/config/scenario-meta.ts +2 -2
  284. package/dist/assets/storefront/src/config/scenario.ts +14 -16
  285. package/dist/assets/storefront/src/contexts/auth-context.tsx +5 -6
  286. package/dist/assets/storefront/src/graphql.ts +5 -5
  287. package/dist/assets/storefront/src/hooks/use-mobile.ts +13 -13
  288. package/dist/assets/storefront/src/i18n/locale-utils.ts +3 -3
  289. package/dist/assets/storefront/src/i18n/navigation.ts +4 -4
  290. package/dist/assets/storefront/src/i18n/request.ts +4 -4
  291. package/dist/assets/storefront/src/i18n/routing.ts +5 -5
  292. package/dist/assets/storefront/src/i18n/server.ts +3 -3
  293. package/dist/assets/storefront/src/lib/actions/switch-channel.ts +9 -9
  294. package/dist/assets/storefront/src/lib/actions/switch-currency.ts +7 -7
  295. package/dist/assets/storefront/src/lib/auth.ts +1 -1
  296. package/dist/assets/storefront/src/lib/backend-health.ts +3 -3
  297. package/dist/assets/storefront/src/lib/cart-count-context.tsx +10 -4
  298. package/dist/assets/storefront/src/lib/cart-guard-utils.ts +2 -1
  299. package/dist/assets/storefront/src/lib/cart-guard.ts +7 -6
  300. package/dist/assets/storefront/src/lib/channel-server.ts +4 -4
  301. package/dist/assets/storefront/src/lib/company-context.ts +1 -1
  302. package/dist/assets/storefront/src/lib/company-permissions-context.tsx +1 -5
  303. package/dist/assets/storefront/src/lib/currency-server.ts +4 -4
  304. package/dist/assets/storefront/src/lib/format.ts +16 -7
  305. package/dist/assets/storefront/src/lib/metadata.ts +39 -44
  306. package/dist/assets/storefront/src/lib/quantity.ts +2 -4
  307. package/dist/assets/storefront/src/lib/search-bar-context.tsx +7 -4
  308. package/dist/assets/storefront/src/lib/use-recent-searches.ts +8 -6
  309. package/dist/assets/storefront/src/lib/utils.ts +3 -3
  310. package/dist/assets/storefront/src/lib/vendure/actions.ts +18 -16
  311. package/dist/assets/storefront/src/lib/vendure/api.ts +36 -23
  312. package/dist/assets/storefront/src/lib/vendure/approval-utils.ts +9 -8
  313. package/dist/assets/storefront/src/lib/vendure/cached.ts +20 -15
  314. package/dist/assets/storefront/src/lib/vendure/queries.ts +15 -5
  315. package/dist/assets/storefront/src/middleware.ts +1 -1
  316. package/dist/assets/storefront/src/scenarios/customer/hero.tsx +2 -2
  317. package/dist/assets/storefront/src/scenarios/customer/meta.ts +1 -1
  318. package/dist/bin/run.js +1 -1
  319. package/dist/cli.d.ts +1 -1
  320. package/dist/index.d.ts +5 -5
  321. package/dist/index.js +1 -1
  322. package/dist/scaffold-storefront-only.js +1 -1
  323. package/dist/scaffolder.js +1 -1
  324. package/dist/template-renderer.js +1 -1
  325. package/package.json +2 -2
@@ -1,21 +1,21 @@
1
1
  'use server';
2
2
 
3
- import {client} from '@/lib/vendure/api';
3
+ import { redirect } from '@/i18n/navigation';
4
+ import { cartGuard } from '@/lib/cart-guard';
5
+ import { getGuardError } from '@/lib/cart-guard-utils';
6
+ import { client } from '@/lib/vendure/api';
4
7
  import {
5
- SetOrderShippingAddressMutation,
6
- SetOrderBillingAddressMutation,
7
- SetOrderShippingMethodMutation,
8
8
  AddPaymentToOrderWithStoreCreditMutation,
9
- CreateCustomerAddressMutation,
10
- TransitionOrderToStateMutation,
11
9
  ApplyStoreCreditToOrderMutation,
10
+ CreateCustomerAddressMutation,
12
11
  RemoveStoreCreditFromOrderMutation,
12
+ SetOrderBillingAddressMutation,
13
+ SetOrderShippingAddressMutation,
14
+ SetOrderShippingMethodMutation,
15
+ TransitionOrderToStateMutation,
13
16
  } from '@/lib/vendure/mutations';
14
- import {GetActiveOrderQuery} from '@/lib/vendure/queries';
15
- import {revalidatePath, updateTag} from 'next/cache';
16
- import {redirect} from "@/i18n/navigation";
17
- import {cartGuard} from '@/lib/cart-guard';
18
- import {getGuardError} from '@/lib/cart-guard-utils';
17
+ import { GetActiveOrderQuery } from '@/lib/vendure/queries';
18
+ import { revalidatePath, updateTag } from 'next/cache';
19
19
 
20
20
  interface AddressInput {
21
21
  fullName: string;
@@ -29,14 +29,10 @@ interface AddressInput {
29
29
  company?: string;
30
30
  }
31
31
 
32
- export async function setShippingAddress(
33
- shippingAddress: AddressInput,
34
- billingAddress?: AddressInput,
35
- ) {
36
- const [shippingResult, shippingError] = await client.mutate(
37
- SetOrderShippingAddressMutation,
38
- {input: shippingAddress},
39
- );
32
+ export async function setShippingAddress(shippingAddress: AddressInput, billingAddress?: AddressInput) {
33
+ const [shippingResult, shippingError] = await client.mutate(SetOrderShippingAddressMutation, {
34
+ input: shippingAddress,
35
+ });
40
36
  if (shippingError) throw shippingError;
41
37
 
42
38
  if (shippingResult.data.setOrderShippingAddress.__typename !== 'Order') {
@@ -44,20 +40,16 @@ export async function setShippingAddress(
44
40
  }
45
41
 
46
42
  const billingInput = billingAddress ?? shippingAddress;
47
- const [, billingError] = await client.mutate(
48
- SetOrderBillingAddressMutation,
49
- {input: billingInput},
50
- );
43
+ const [, billingError] = await client.mutate(SetOrderBillingAddressMutation, { input: billingInput });
51
44
  if (billingError) throw billingError;
52
45
 
53
46
  revalidatePath('/checkout');
54
47
  }
55
48
 
56
49
  export async function setShippingMethod(shippingMethodId: string) {
57
- const [result, error] = await client.mutate(
58
- SetOrderShippingMethodMutation,
59
- {shippingMethodId: [shippingMethodId]},
60
- );
50
+ const [result, error] = await client.mutate(SetOrderShippingMethodMutation, {
51
+ shippingMethodId: [shippingMethodId],
52
+ });
61
53
  if (error) throw error;
62
54
 
63
55
  if (result.data.setOrderShippingMethod.__typename !== 'Order') {
@@ -68,10 +60,7 @@ export async function setShippingMethod(shippingMethodId: string) {
68
60
  }
69
61
 
70
62
  export async function createCustomerAddress(address: AddressInput) {
71
- const [result, error] = await client.mutate(
72
- CreateCustomerAddressMutation,
73
- {input: address},
74
- );
63
+ const [result, error] = await client.mutate(CreateCustomerAddressMutation, { input: address });
75
64
  if (error) throw error;
76
65
 
77
66
  if (!result.data.createCustomerAddress) {
@@ -85,39 +74,33 @@ export async function createCustomerAddress(address: AddressInput) {
85
74
  export async function applyStoreCredit(code: string) {
86
75
  const guard = await cartGuard();
87
76
  const guardError = getGuardError(guard);
88
- if (guardError) return {error: guardError};
77
+ if (guardError) return { error: guardError };
89
78
 
90
- const [result, error] = await client.mutate(
91
- ApplyStoreCreditToOrderMutation,
92
- {code},
93
- );
79
+ const [result, error] = await client.mutate(ApplyStoreCreditToOrderMutation, { code });
94
80
  if (error) throw error;
95
81
 
96
82
  if (result.data.applyStoreCreditToOrder.__typename !== 'Order') {
97
83
  const errorResult = result.data.applyStoreCreditToOrder;
98
- return {error: errorResult.message};
84
+ return { error: errorResult.message };
99
85
  }
100
86
 
101
87
  revalidatePath('/checkout');
102
- return {success: true};
88
+ return { success: true };
103
89
  }
104
90
 
105
91
  export async function removeStoreCredit(code: string) {
106
92
  const guard = await cartGuard();
107
93
  const guardError = getGuardError(guard);
108
- if (guardError) return {error: guardError};
94
+ if (guardError) return { error: guardError };
109
95
 
110
- const [, error] = await client.mutate(
111
- RemoveStoreCreditFromOrderMutation,
112
- {code},
113
- );
96
+ const [, error] = await client.mutate(RemoveStoreCreditFromOrderMutation, { code });
114
97
 
115
98
  if (error) {
116
- return {error: error.message || 'Failed to remove store credit'};
99
+ return { error: error.message || 'Failed to remove store credit' };
117
100
  }
118
101
 
119
102
  revalidatePath('/checkout');
120
- return {success: true};
103
+ return { success: true };
121
104
  }
122
105
 
123
106
  export async function placeOrder(paymentMethodCode?: string) {
@@ -129,10 +112,9 @@ export async function placeOrder(paymentMethodCode?: string) {
129
112
 
130
113
  if (currentState !== 'ArrangingPayment') {
131
114
  // Try to transition the order to ArrangingPayment state
132
- const [transitionResult, transitionError] = await client.mutate(
133
- TransitionOrderToStateMutation,
134
- {state: 'ArrangingPayment'},
135
- );
115
+ const [transitionResult, transitionError] = await client.mutate(TransitionOrderToStateMutation, {
116
+ state: 'ArrangingPayment',
117
+ });
136
118
  if (transitionError) throw transitionError;
137
119
 
138
120
  // If the transition fails, check if the order requires approval
@@ -141,10 +123,9 @@ export async function placeOrder(paymentMethodCode?: string) {
141
123
 
142
124
  // Try transitioning to AwaitingApproval instead
143
125
  if (transitionError.fromState === 'AddingItems') {
144
- const [approvalResult, approvalError] = await client.mutate(
145
- TransitionOrderToStateMutation,
146
- {state: 'AwaitingApproval'},
147
- );
126
+ const [approvalResult, approvalError] = await client.mutate(TransitionOrderToStateMutation, {
127
+ state: 'AwaitingApproval',
128
+ });
148
129
  if (approvalError) throw approvalError;
149
130
 
150
131
  if (approvalResult.data.transitionOrderToState?.__typename === 'Order') {
@@ -157,7 +138,7 @@ export async function placeOrder(paymentMethodCode?: string) {
157
138
 
158
139
  // If we get here, neither transition worked
159
140
  throw new Error(
160
- `Failed to transition order state: ${transitionError.errorCode} - ${transitionError.message}`
141
+ `Failed to transition order state: ${transitionError.errorCode} - ${transitionError.message}`,
161
142
  );
162
143
  }
163
144
  }
@@ -166,21 +147,14 @@ export async function placeOrder(paymentMethodCode?: string) {
166
147
  // auto-deducts any applied store credits before charging the remainder
167
148
  // via the selected payment method.
168
149
  // When store credits fully cover the order, no payment input is needed.
169
- const [result, error] = await client.mutate(
170
- AddPaymentToOrderWithStoreCreditMutation,
171
- {
172
- input: paymentMethodCode
173
- ? { method: paymentMethodCode, metadata: {} }
174
- : null,
175
- },
176
- );
150
+ const [result, error] = await client.mutate(AddPaymentToOrderWithStoreCreditMutation, {
151
+ input: paymentMethodCode ? { method: paymentMethodCode, metadata: {} } : null,
152
+ });
177
153
  if (error) throw error;
178
154
 
179
155
  if (result.data.addPaymentToOrderWithStoreCredit.__typename !== 'Order') {
180
156
  const errorResult = result.data.addPaymentToOrderWithStoreCredit;
181
- throw new Error(
182
- `Failed to place order: ${errorResult.errorCode} - ${errorResult.message}`
183
- );
157
+ throw new Error(`Failed to place order: ${errorResult.errorCode} - ${errorResult.message}`);
184
158
  }
185
159
 
186
160
  const orderCode = result.data.addPaymentToOrderWithStoreCredit.code;
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
 
3
- import {useRouter} from '@/i18n/navigation';
4
- import {useTransition} from 'react';
5
- import {useTranslations} from 'next-intl';
6
- import {Button} from '@/components/ui/button';
7
- import {cancelQuoteCheckout} from '@/app/[locale]/account/quotes/actions';
3
+ import { cancelQuoteCheckout } from '@/app/[locale]/account/quotes/actions';
4
+ import { Button } from '@/components/ui/button';
5
+ import { useRouter } from '@/i18n/navigation';
6
+ import { useTranslations } from 'next-intl';
7
+ import { useTransition } from 'react';
8
8
 
9
9
  export function CancelQuoteCheckoutButton() {
10
10
  const router = useRouter();
@@ -1,214 +1,214 @@
1
1
  'use client';
2
2
 
3
- import { useState } from 'react';
4
- import { useTranslations } from 'next-intl';
5
3
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
6
- import ShippingAddressStep from './steps/shipping-address-step';
4
+ import { useTranslations } from 'next-intl';
5
+ import { useState } from 'react';
6
+ import { useCheckout } from './checkout-provider';
7
+ import OrderSummary from './order-summary';
7
8
  import DeliveryStep from './steps/delivery-step';
8
9
  import PaymentStep from './steps/payment-step';
9
10
  import ReviewStep from './steps/review-step';
10
- import OrderSummary from './order-summary';
11
- import { useCheckout } from './checkout-provider';
11
+ import ShippingAddressStep from './steps/shipping-address-step';
12
12
 
13
13
  type CheckoutStep = 'shipping' | 'delivery' | 'payment' | 'review';
14
14
 
15
15
  export default function CheckoutFlow() {
16
- const { order, storeCreditsCoverOrder } = useCheckout();
17
- const t = useTranslations('Checkout');
18
-
19
- // Determine initial step and completed steps based on order state
20
- const getInitialState = () => {
21
- const completed = new Set<CheckoutStep>();
22
- let current: CheckoutStep = 'shipping';
23
-
24
- // Check if shipping address has required fields, not just if the object exists
25
- if (order.shippingAddress?.streetLine1 && order.shippingAddress?.country) {
26
- completed.add('shipping');
27
- current = 'delivery';
28
- }
29
-
30
- if (order.shippingLines && order.shippingLines.length > 0) {
31
- completed.add('delivery');
32
- current = 'payment';
33
-
34
- // When store credits cover the full order, skip the payment step
35
- if (storeCreditsCoverOrder) {
36
- completed.add('payment');
37
- current = 'review';
38
- }
39
- }
40
-
41
- return { completed, current };
42
- };
43
-
44
- const initialState = getInitialState();
45
- const [currentStep, setCurrentStep] = useState<CheckoutStep>(initialState.current);
46
- const [completedSteps, setCompletedSteps] = useState<Set<CheckoutStep>>(initialState.completed);
47
-
48
- const handleStepComplete = (step: CheckoutStep) => {
49
- setCompletedSteps(prev => new Set([...prev, step]));
50
-
51
- const stepOrder: CheckoutStep[] = ['shipping', 'delivery', 'payment', 'review'];
52
- const currentIndex = stepOrder.indexOf(step);
53
-
54
- // If all subsequent steps are already completed, jump straight to review
55
- for (let i = currentIndex + 1; i < stepOrder.length; i++) {
56
- if (!completedSteps.has(stepOrder[i])) {
57
- setCurrentStep(stepOrder[i]);
58
- return;
59
- }
60
- }
61
- setCurrentStep('review');
62
- };
63
-
64
- const willReturnToReview = (step: CheckoutStep): boolean => {
65
- const stepOrder: CheckoutStep[] = ['shipping', 'delivery', 'payment', 'review'];
66
- const currentIndex = stepOrder.indexOf(step);
67
- return stepOrder.slice(currentIndex + 1).every(s => completedSteps.has(s) || s === 'review');
68
- };
69
-
70
- const canAccessStep = (step: CheckoutStep): boolean => {
71
- const stepOrder: CheckoutStep[] = ['shipping', 'delivery', 'payment', 'review'];
72
- const stepIndex = stepOrder.indexOf(step);
73
-
74
- if (stepIndex === 0) return true;
75
-
76
- const previousStep = stepOrder[stepIndex - 1];
77
- return completedSteps.has(previousStep);
78
- };
79
-
80
- return (
81
- <div className="grid lg:grid-cols-3 gap-8">
82
- <div className="lg:col-span-2">
83
- <Accordion
84
- type="single"
85
- collapsible
86
- value={currentStep}
87
- onValueChange={(value) => {
88
- if (value && canAccessStep(value as CheckoutStep)) {
89
- setCurrentStep(value as CheckoutStep);
16
+ const { order, storeCreditsCoverOrder } = useCheckout();
17
+ const t = useTranslations('Checkout');
18
+
19
+ // Determine initial step and completed steps based on order state
20
+ const getInitialState = () => {
21
+ const completed = new Set<CheckoutStep>();
22
+ let current: CheckoutStep = 'shipping';
23
+
24
+ // Check if shipping address has required fields, not just if the object exists
25
+ if (order.shippingAddress?.streetLine1 && order.shippingAddress?.country) {
26
+ completed.add('shipping');
27
+ current = 'delivery';
28
+ }
29
+
30
+ if (order.shippingLines && order.shippingLines.length > 0) {
31
+ completed.add('delivery');
32
+ current = 'payment';
33
+
34
+ // When store credits cover the full order, skip the payment step
35
+ if (storeCreditsCoverOrder) {
36
+ completed.add('payment');
37
+ current = 'review';
38
+ }
39
+ }
40
+
41
+ return { completed, current };
42
+ };
43
+
44
+ const initialState = getInitialState();
45
+ const [currentStep, setCurrentStep] = useState<CheckoutStep>(initialState.current);
46
+ const [completedSteps, setCompletedSteps] = useState<Set<CheckoutStep>>(initialState.completed);
47
+
48
+ const handleStepComplete = (step: CheckoutStep) => {
49
+ setCompletedSteps((prev) => new Set([...prev, step]));
50
+
51
+ const stepOrder: CheckoutStep[] = ['shipping', 'delivery', 'payment', 'review'];
52
+ const currentIndex = stepOrder.indexOf(step);
53
+
54
+ // If all subsequent steps are already completed, jump straight to review
55
+ for (let i = currentIndex + 1; i < stepOrder.length; i++) {
56
+ if (!completedSteps.has(stepOrder[i])) {
57
+ setCurrentStep(stepOrder[i]);
58
+ return;
90
59
  }
91
- }}
92
- className="space-y-4"
93
- >
94
- <AccordionItem value="shipping" className="border rounded-lg px-6">
95
- <AccordionTrigger className="hover:no-underline">
96
- <div className="flex items-center gap-3">
97
- <div className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
98
- completedSteps.has('shipping')
99
- ? 'bg-green-500 text-white'
100
- : currentStep === 'shipping'
101
- ? 'bg-primary text-primary-foreground'
102
- : 'bg-muted text-muted-foreground'
103
- }`}>
104
- {completedSteps.has('shipping') ? '✓' : '1'}
105
- </div>
106
- <span className="text-lg font-semibold">{t('shippingAddress')}</span>
107
- </div>
108
- </AccordionTrigger>
109
- <AccordionContent className="pt-4">
110
- <ShippingAddressStep
111
- onComplete={() => handleStepComplete('shipping')}
112
- returnsToReview={willReturnToReview('shipping')}
113
- />
114
- </AccordionContent>
115
- </AccordionItem>
116
-
117
- <AccordionItem
118
- value="delivery"
119
- className="border rounded-lg px-6"
120
- disabled={!canAccessStep('delivery')}
121
- >
122
- <AccordionTrigger
123
- className="hover:no-underline"
124
- disabled={!canAccessStep('delivery')}
125
- >
126
- <div className="flex items-center gap-3">
127
- <div className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
128
- completedSteps.has('delivery')
129
- ? 'bg-green-500 text-white'
130
- : currentStep === 'delivery'
131
- ? 'bg-primary text-primary-foreground'
132
- : 'bg-muted text-muted-foreground'
133
- }`}>
134
- {completedSteps.has('delivery') ? '✓' : '2'}
135
- </div>
136
- <span className="text-lg font-semibold">{t('deliveryMethod')}</span>
137
- </div>
138
- </AccordionTrigger>
139
- <AccordionContent className="pt-4">
140
- <DeliveryStep
141
- onComplete={() => handleStepComplete('delivery')}
142
- returnsToReview={willReturnToReview('delivery')}
143
- />
144
- </AccordionContent>
145
- </AccordionItem>
146
-
147
- <AccordionItem
148
- value="payment"
149
- className="border rounded-lg px-6"
150
- disabled={!canAccessStep('payment')}
151
- >
152
- <AccordionTrigger
153
- className="hover:no-underline"
154
- disabled={!canAccessStep('payment')}
155
- >
156
- <div className="flex items-center gap-3">
157
- <div className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
158
- completedSteps.has('payment')
159
- ? 'bg-green-500 text-white'
160
- : currentStep === 'payment'
161
- ? 'bg-primary text-primary-foreground'
162
- : 'bg-muted text-muted-foreground'
163
- }`}>
164
- {completedSteps.has('payment') ? '✓' : '3'}
165
- </div>
166
- <span className="text-lg font-semibold">{t('paymentMethod')}</span>
167
- </div>
168
- </AccordionTrigger>
169
- <AccordionContent className="pt-4">
170
- <PaymentStep
171
- onComplete={() => handleStepComplete('payment')}
172
- />
173
- </AccordionContent>
174
- </AccordionItem>
175
-
176
- <AccordionItem
177
- value="review"
178
- className="border rounded-lg px-6 last:border-b"
179
- disabled={!canAccessStep('review')}
180
- >
181
- <AccordionTrigger
182
- className="hover:no-underline"
183
- disabled={!canAccessStep('review')}
184
- >
185
- <div className="flex items-center gap-3">
186
- <div className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
187
- currentStep === 'review'
188
- ? 'bg-primary text-primary-foreground'
189
- : 'bg-muted text-muted-foreground'
190
- }`}>
191
- 4
192
- </div>
193
- <span className="text-lg font-semibold">{t('reviewAndPlaceOrder')}</span>
194
- </div>
195
- </AccordionTrigger>
196
- <AccordionContent className="pt-4">
197
- <ReviewStep
198
- onEditStep={setCurrentStep}
199
- onStartOver={() => {
200
- setCompletedSteps(new Set());
201
- setCurrentStep('shipping');
202
- }}
203
- />
204
- </AccordionContent>
205
- </AccordionItem>
206
- </Accordion>
207
- </div>
208
-
209
- <div className="lg:col-span-1">
210
- <OrderSummary />
211
- </div>
212
- </div>
213
- );
60
+ }
61
+ setCurrentStep('review');
62
+ };
63
+
64
+ const willReturnToReview = (step: CheckoutStep): boolean => {
65
+ const stepOrder: CheckoutStep[] = ['shipping', 'delivery', 'payment', 'review'];
66
+ const currentIndex = stepOrder.indexOf(step);
67
+ return stepOrder.slice(currentIndex + 1).every((s) => completedSteps.has(s) || s === 'review');
68
+ };
69
+
70
+ const canAccessStep = (step: CheckoutStep): boolean => {
71
+ const stepOrder: CheckoutStep[] = ['shipping', 'delivery', 'payment', 'review'];
72
+ const stepIndex = stepOrder.indexOf(step);
73
+
74
+ if (stepIndex === 0) return true;
75
+
76
+ const previousStep = stepOrder[stepIndex - 1];
77
+ return completedSteps.has(previousStep);
78
+ };
79
+
80
+ return (
81
+ <div className="grid lg:grid-cols-3 gap-8">
82
+ <div className="lg:col-span-2">
83
+ <Accordion
84
+ type="single"
85
+ collapsible
86
+ value={currentStep}
87
+ onValueChange={(value) => {
88
+ if (value && canAccessStep(value as CheckoutStep)) {
89
+ setCurrentStep(value as CheckoutStep);
90
+ }
91
+ }}
92
+ className="space-y-4"
93
+ >
94
+ <AccordionItem value="shipping" className="border rounded-lg px-6">
95
+ <AccordionTrigger className="hover:no-underline">
96
+ <div className="flex items-center gap-3">
97
+ <div
98
+ className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
99
+ completedSteps.has('shipping')
100
+ ? 'bg-green-500 text-white'
101
+ : currentStep === 'shipping'
102
+ ? 'bg-primary text-primary-foreground'
103
+ : 'bg-muted text-muted-foreground'
104
+ }`}
105
+ >
106
+ {completedSteps.has('shipping') ? '✓' : '1'}
107
+ </div>
108
+ <span className="text-lg font-semibold">{t('shippingAddress')}</span>
109
+ </div>
110
+ </AccordionTrigger>
111
+ <AccordionContent className="pt-4">
112
+ <ShippingAddressStep
113
+ onComplete={() => handleStepComplete('shipping')}
114
+ returnsToReview={willReturnToReview('shipping')}
115
+ />
116
+ </AccordionContent>
117
+ </AccordionItem>
118
+
119
+ <AccordionItem
120
+ value="delivery"
121
+ className="border rounded-lg px-6"
122
+ disabled={!canAccessStep('delivery')}
123
+ >
124
+ <AccordionTrigger
125
+ className="hover:no-underline"
126
+ disabled={!canAccessStep('delivery')}
127
+ >
128
+ <div className="flex items-center gap-3">
129
+ <div
130
+ className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
131
+ completedSteps.has('delivery')
132
+ ? 'bg-green-500 text-white'
133
+ : currentStep === 'delivery'
134
+ ? 'bg-primary text-primary-foreground'
135
+ : 'bg-muted text-muted-foreground'
136
+ }`}
137
+ >
138
+ {completedSteps.has('delivery') ? '✓' : '2'}
139
+ </div>
140
+ <span className="text-lg font-semibold">{t('deliveryMethod')}</span>
141
+ </div>
142
+ </AccordionTrigger>
143
+ <AccordionContent className="pt-4">
144
+ <DeliveryStep
145
+ onComplete={() => handleStepComplete('delivery')}
146
+ returnsToReview={willReturnToReview('delivery')}
147
+ />
148
+ </AccordionContent>
149
+ </AccordionItem>
150
+
151
+ <AccordionItem
152
+ value="payment"
153
+ className="border rounded-lg px-6"
154
+ disabled={!canAccessStep('payment')}
155
+ >
156
+ <AccordionTrigger className="hover:no-underline" disabled={!canAccessStep('payment')}>
157
+ <div className="flex items-center gap-3">
158
+ <div
159
+ className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
160
+ completedSteps.has('payment')
161
+ ? 'bg-green-500 text-white'
162
+ : currentStep === 'payment'
163
+ ? 'bg-primary text-primary-foreground'
164
+ : 'bg-muted text-muted-foreground'
165
+ }`}
166
+ >
167
+ {completedSteps.has('payment') ? '✓' : '3'}
168
+ </div>
169
+ <span className="text-lg font-semibold">{t('paymentMethod')}</span>
170
+ </div>
171
+ </AccordionTrigger>
172
+ <AccordionContent className="pt-4">
173
+ <PaymentStep onComplete={() => handleStepComplete('payment')} />
174
+ </AccordionContent>
175
+ </AccordionItem>
176
+
177
+ <AccordionItem
178
+ value="review"
179
+ className="border rounded-lg px-6 last:border-b"
180
+ disabled={!canAccessStep('review')}
181
+ >
182
+ <AccordionTrigger className="hover:no-underline" disabled={!canAccessStep('review')}>
183
+ <div className="flex items-center gap-3">
184
+ <div
185
+ className={`flex items-center justify-center w-8 h-8 rounded-full text-sm font-semibold ${
186
+ currentStep === 'review'
187
+ ? 'bg-primary text-primary-foreground'
188
+ : 'bg-muted text-muted-foreground'
189
+ }`}
190
+ >
191
+ 4
192
+ </div>
193
+ <span className="text-lg font-semibold">{t('reviewAndPlaceOrder')}</span>
194
+ </div>
195
+ </AccordionTrigger>
196
+ <AccordionContent className="pt-4">
197
+ <ReviewStep
198
+ onEditStep={setCurrentStep}
199
+ onStartOver={() => {
200
+ setCompletedSteps(new Set());
201
+ setCurrentStep('shipping');
202
+ }}
203
+ />
204
+ </AccordionContent>
205
+ </AccordionItem>
206
+ </Accordion>
207
+ </div>
208
+
209
+ <div className="lg:col-span-1">
210
+ <OrderSummary />
211
+ </div>
212
+ </div>
213
+ );
214
214
  }