@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,31 +1,47 @@
1
1
  'use client';
2
2
 
3
- import { useState, useEffect, useRef, useCallback, useTransition, type ReactNode } from 'react';
4
- import { useTranslations } from 'next-intl';
5
- import { Input } from '@/components/ui/input';
3
+ import { Price } from '@/components/commerce/price';
6
4
  import { Button } from '@/components/ui/button';
5
+ import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';
6
+ import { Input } from '@/components/ui/input';
7
7
  import { Label } from '@/components/ui/label';
8
- import { Switch } from '@/components/ui/switch';
9
8
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
10
- import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';
11
- import { Price } from '@/components/commerce/price';
12
- import { ShoppingCart, CheckCircle2, ChevronDown, Info, AlertCircle, Loader2, Minus, Plus } from 'lucide-react';
13
- import { toast } from 'sonner';
9
+ import { Switch } from '@/components/ui/switch';
14
10
  import type {
15
- ConfiguratorSystem,
16
- ConfiguratorModule,
17
- ConfiguratorField,
18
11
  ConfigurationEvaluation,
12
+ ConfiguratorField,
13
+ ConfiguratorModule,
14
+ ConfiguratorSystem,
19
15
  EvaluatedField,
20
16
  EvaluatedLine,
21
17
  } from '@/lib/vendure/queries';
18
+ import {
19
+ AlertCircle,
20
+ CheckCircle2,
21
+ ChevronDown,
22
+ Info,
23
+ Loader2,
24
+ Minus,
25
+ Plus,
26
+ ShoppingCart,
27
+ } from 'lucide-react';
28
+ import { useTranslations } from 'next-intl';
29
+ import { useCallback, useEffect, useRef, useState, useTransition, type ReactNode } from 'react';
30
+ import { toast } from 'sonner';
22
31
 
23
32
  interface ConfiguratorFormProps {
24
33
  system: ConfiguratorSystem;
25
34
  productName: string;
26
35
  currencyCode?: string;
27
- evaluateAction: (systemId: string, values: { fieldRef: string; value: string }[]) => Promise<{ data?: ConfigurationEvaluation; error?: string }>;
28
- addToOrderAction: (systemId: string, values: { fieldRef: string; value: string }[], name?: string) => Promise<{ success: boolean; error?: string }>;
36
+ evaluateAction: (
37
+ systemId: string,
38
+ values: { fieldRef: string; value: string }[],
39
+ ) => Promise<{ data?: ConfigurationEvaluation; error?: string }>;
40
+ addToOrderAction: (
41
+ systemId: string,
42
+ values: { fieldRef: string; value: string }[],
43
+ name?: string,
44
+ ) => Promise<{ success: boolean; error?: string }>;
29
45
  children?: ReactNode;
30
46
  }
31
47
 
@@ -33,7 +49,14 @@ function buildFieldRef(moduleCode: string, fieldCode: string) {
33
49
  return `${moduleCode}.${fieldCode}`;
34
50
  }
35
51
 
36
- export function ConfiguratorForm({ system, productName, currencyCode, evaluateAction, addToOrderAction, children }: ConfiguratorFormProps) {
52
+ export function ConfiguratorForm({
53
+ system,
54
+ productName,
55
+ currencyCode,
56
+ evaluateAction,
57
+ addToOrderAction,
58
+ children,
59
+ }: ConfiguratorFormProps) {
37
60
  const t = useTranslations('Configurator');
38
61
  const [values, setValues] = useState<Record<string, string>>(() => {
39
62
  const initial: Record<string, string> = {};
@@ -52,7 +75,7 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
52
75
  const [isAdding, startAddTransition] = useTransition();
53
76
  const [isAdded, setIsAdded] = useState(false);
54
77
  const [expandedModules, setExpandedModules] = useState<Set<string>>(() => {
55
- return new Set(system.modules.map(m => m.code));
78
+ return new Set(system.modules.map((m) => m.code));
56
79
  });
57
80
  const [bomDrawerOpen, setBomDrawerOpen] = useState(false);
58
81
  const evalTimeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);
@@ -79,7 +102,7 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
79
102
  }, [values, system.id, evaluateAction, fieldValueEntries]);
80
103
 
81
104
  const handleFieldChange = (moduleCode: string, fieldCode: string, value: string) => {
82
- setValues(prev => ({ ...prev, [buildFieldRef(moduleCode, fieldCode)]: value }));
105
+ setValues((prev) => ({ ...prev, [buildFieldRef(moduleCode, fieldCode)]: value }));
83
106
  };
84
107
 
85
108
  const handleAddToOrder = () => {
@@ -97,7 +120,7 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
97
120
  };
98
121
 
99
122
  const toggleModule = (code: string) => {
100
- setExpandedModules(prev => {
123
+ setExpandedModules((prev) => {
101
124
  const next = new Set(prev);
102
125
  if (next.has(code)) next.delete(code);
103
126
  else next.add(code);
@@ -131,8 +154,8 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
131
154
  }
132
155
  }
133
156
  const allErrors = [
134
- ...systemErrors.map(e => e.message),
135
- ...fieldIssues.map(e => `${e.fieldName}: ${e.message}`),
157
+ ...systemErrors.map((e) => e.message),
158
+ ...fieldIssues.map((e) => `${e.fieldName}: ${e.message}`),
136
159
  ];
137
160
  const hasErrors = allErrors.length > 0;
138
161
 
@@ -159,9 +182,7 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
159
182
  <div className="lg:col-span-3">
160
183
  <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
161
184
  {/* Image + description — sticky */}
162
- <div className="md:sticky md:top-20 md:self-start space-y-5">
163
- {children}
164
- </div>
185
+ <div className="md:sticky md:top-20 md:self-start space-y-5">{children}</div>
165
186
 
166
187
  {/* Configurator form */}
167
188
  <div>
@@ -170,7 +191,11 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
170
191
  {lines.length > 0 && (
171
192
  <div className="flex items-center gap-2">
172
193
  <span className="text-3xl font-bold text-primary">
173
- <Price value={totalPrice} currencyCode={currencyCode} taxLabel="excl" />
194
+ <Price
195
+ value={totalPrice}
196
+ currencyCode={currencyCode}
197
+ taxLabel="excl"
198
+ />
174
199
  </span>
175
200
  </div>
176
201
  )}
@@ -179,7 +204,10 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
179
204
  {allErrors.length > 0 && (
180
205
  <div className="mt-4 space-y-2">
181
206
  {allErrors.map((msg, i) => (
182
- <div key={i} className="rounded-lg border border-red-200 bg-red-50 px-3 py-2.5 flex items-start gap-2">
207
+ <div
208
+ key={i}
209
+ className="rounded-lg border border-red-200 bg-red-50 px-3 py-2.5 flex items-start gap-2"
210
+ >
183
211
  <AlertCircle className="w-4 h-4 mt-0.5 shrink-0 text-red-500" />
184
212
  <p className="text-sm text-red-800">{msg}</p>
185
213
  </div>
@@ -201,7 +229,6 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
201
229
  />
202
230
  ))}
203
231
  </div>
204
-
205
232
  </div>
206
233
  </div>
207
234
  </div>
@@ -211,9 +238,7 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
211
238
  <div className="lg:hidden fixed bottom-0 inset-x-0 z-40 border-t border-border bg-background shadow-[0_-4px_12px_rgba(0,0,0,0.05)]">
212
239
  <div className="flex items-center justify-between px-4 py-3">
213
240
  <div>
214
- <p className="text-xs text-muted-foreground">
215
- {t('items', { count: lines.length })}
216
- </p>
241
+ <p className="text-xs text-muted-foreground">{t('items', { count: lines.length })}</p>
217
242
  <p className="text-lg font-bold">
218
243
  <Price value={totalPrice} currencyCode={currencyCode} />
219
244
  </p>
@@ -230,11 +255,20 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
230
255
  onClick={handleAddToOrder}
231
256
  >
232
257
  {isAdded ? (
233
- <><CheckCircle2 className="mr-1.5 h-4 w-4" />{t('addedToCart')}</>
258
+ <>
259
+ <CheckCircle2 className="mr-1.5 h-4 w-4" />
260
+ {t('addedToCart')}
261
+ </>
234
262
  ) : isAdding ? (
235
- <><Loader2 className="mr-1.5 h-4 w-4 animate-spin" />{t('adding')}</>
263
+ <>
264
+ <Loader2 className="mr-1.5 h-4 w-4 animate-spin" />
265
+ {t('adding')}
266
+ </>
236
267
  ) : (
237
- <><ShoppingCart className="mr-1.5 h-4 w-4" />{t('addToCart')}</>
268
+ <>
269
+ <ShoppingCart className="mr-1.5 h-4 w-4" />
270
+ {t('addToCart')}
271
+ </>
238
272
  )}
239
273
  </Button>
240
274
  </div>
@@ -249,15 +283,25 @@ export function ConfiguratorForm({ system, productName, currencyCode, evaluateAc
249
283
  </DrawerHeader>
250
284
  <div className="px-4 pb-6 overflow-y-auto max-h-[60vh]">
251
285
  {lines.map((line, i) => (
252
- <div key={line.sourceKey ?? i} className="flex items-center justify-between py-2.5 border-b border-border last:border-0">
286
+ <div
287
+ key={line.sourceKey ?? i}
288
+ className="flex items-center justify-between py-2.5 border-b border-border last:border-0"
289
+ >
253
290
  <div className="min-w-0 flex-1">
254
291
  <p className="text-sm font-medium">{line.productVariant.name}</p>
255
- <p className="text-[11px] text-muted-foreground font-mono">{line.productVariant.sku}</p>
292
+ <p className="text-[11px] text-muted-foreground font-mono">
293
+ {line.productVariant.sku}
294
+ </p>
256
295
  </div>
257
296
  <div className="flex items-center gap-3 shrink-0 ml-3">
258
- <span className="text-xs text-muted-foreground font-mono">×{line.quantity}</span>
297
+ <span className="text-xs text-muted-foreground font-mono">
298
+ ×{line.quantity}
299
+ </span>
259
300
  <span className="text-sm font-mono tabular-nums">
260
- <Price value={line.productVariant.priceWithTax * line.quantity} currencyCode={currencyCode} />
301
+ <Price
302
+ value={line.productVariant.priceWithTax * line.quantity}
303
+ currencyCode={currencyCode}
304
+ />
261
305
  </span>
262
306
  </div>
263
307
  </div>
@@ -308,7 +352,9 @@ function BomSidebar({
308
352
  {lines.length}
309
353
  </span>
310
354
  )}
311
- {isEvaluating && <Loader2 className="w-3.5 h-3.5 animate-spin text-muted-foreground ml-auto" />}
355
+ {isEvaluating && (
356
+ <Loader2 className="w-3.5 h-3.5 animate-spin text-muted-foreground ml-auto" />
357
+ )}
312
358
  </div>
313
359
 
314
360
  {lines.length > 0 ? (
@@ -317,21 +363,28 @@ function BomSidebar({
317
363
  <div key={line.sourceKey ?? i} className="py-2">
318
364
  <div className="flex items-start justify-between gap-2">
319
365
  <div className="min-w-0 flex-1">
320
- <p className="text-sm font-medium leading-tight">{line.productVariant.name}</p>
321
- <p className="text-[11px] text-muted-foreground font-mono mt-0.5">{line.productVariant.sku}</p>
366
+ <p className="text-sm font-medium leading-tight">
367
+ {line.productVariant.name}
368
+ </p>
369
+ <p className="text-[11px] text-muted-foreground font-mono mt-0.5">
370
+ {line.productVariant.sku}
371
+ </p>
322
372
  </div>
323
- <span className="text-xs text-muted-foreground font-mono tabular-nums shrink-0">×{line.quantity}</span>
373
+ <span className="text-xs text-muted-foreground font-mono tabular-nums shrink-0">
374
+ ×{line.quantity}
375
+ </span>
324
376
  </div>
325
377
  <p className="text-sm font-mono tabular-nums text-right mt-0.5">
326
- <Price value={line.productVariant.priceWithTax * line.quantity} currencyCode={currencyCode} />
378
+ <Price
379
+ value={line.productVariant.priceWithTax * line.quantity}
380
+ currencyCode={currencyCode}
381
+ />
327
382
  </p>
328
383
  </div>
329
384
  ))}
330
385
  </div>
331
386
  ) : (
332
- <p className="text-sm text-muted-foreground py-4">
333
- {t('emptyBom')}
334
- </p>
387
+ <p className="text-sm text-muted-foreground py-4">{t('emptyBom')}</p>
335
388
  )}
336
389
  </div>
337
390
 
@@ -350,11 +403,20 @@ function BomSidebar({
350
403
  onClick={onAddToOrder}
351
404
  >
352
405
  {isAdded ? (
353
- <><CheckCircle2 className="mr-2 h-5 w-5" />{t('addedToCart')}</>
406
+ <>
407
+ <CheckCircle2 className="mr-2 h-5 w-5" />
408
+ {t('addedToCart')}
409
+ </>
354
410
  ) : isAdding ? (
355
- <><Loader2 className="mr-2 h-5 w-5 animate-spin" />{t('adding')}</>
411
+ <>
412
+ <Loader2 className="mr-2 h-5 w-5 animate-spin" />
413
+ {t('adding')}
414
+ </>
356
415
  ) : (
357
- <><ShoppingCart className="mr-2 h-5 w-5" />{t('addToCart')}</>
416
+ <>
417
+ <ShoppingCart className="mr-2 h-5 w-5" />
418
+ {t('addToCart')}
419
+ </>
358
420
  )}
359
421
  </Button>
360
422
  </div>
@@ -384,21 +446,21 @@ function ModuleSection({
384
446
  }) {
385
447
  const t = useTranslations('Configurator');
386
448
  const visibleFields = mod.fields
387
- .filter(f => {
449
+ .filter((f) => {
388
450
  const ef = evalFieldMap.get(buildFieldRef(mod.code, f.code));
389
451
  return !ef?.hidden;
390
452
  })
391
453
  .sort((a, b) => a.sortOrder - b.sortOrder);
392
454
 
393
455
  const allFilled = visibleFields
394
- .filter(f => f.required)
395
- .every(f => {
456
+ .filter((f) => f.required)
457
+ .every((f) => {
396
458
  const val = values[buildFieldRef(mod.code, f.code)];
397
459
  return val != null && val !== '';
398
460
  });
399
461
 
400
462
  const summaryParts = visibleFields
401
- .map(f => {
463
+ .map((f) => {
402
464
  const val = values[buildFieldRef(mod.code, f.code)];
403
465
  if (!val) return null;
404
466
  if (f.fieldType === 'BOOL') return val === 'true' ? f.name : null;
@@ -409,17 +471,23 @@ function ModuleSection({
409
471
  const summary = summaryParts.slice(0, 3).join(', ');
410
472
 
411
473
  return (
412
- <section className={`border border-border rounded-lg overflow-hidden transition-shadow ${expanded ? 'ring-1 ring-primary/20' : ''}`}>
474
+ <section
475
+ className={`border border-border rounded-lg overflow-hidden transition-shadow ${
476
+ expanded ? 'ring-1 ring-primary/20' : ''
477
+ }`}
478
+ >
413
479
  <button
414
480
  type="button"
415
481
  onClick={onToggle}
416
482
  className="w-full flex items-center gap-2.5 px-4 py-3 text-left hover:bg-muted/30 transition-colors"
417
483
  >
418
- <div className={`w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-semibold shrink-0 ${
419
- allFilled && summaryParts.length > 0
420
- ? 'bg-primary text-white'
421
- : 'border-2 border-muted-foreground/30 text-muted-foreground'
422
- }`}>
484
+ <div
485
+ className={`w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-semibold shrink-0 ${
486
+ allFilled && summaryParts.length > 0
487
+ ? 'bg-primary text-white'
488
+ : 'border-2 border-muted-foreground/30 text-muted-foreground'
489
+ }`}
490
+ >
423
491
  {allFilled && summaryParts.length > 0 ? (
424
492
  <CheckCircle2 className="w-3 h-3" />
425
493
  ) : (
@@ -427,26 +495,44 @@ function ModuleSection({
427
495
  )}
428
496
  </div>
429
497
  <div className="flex-1 min-w-0">
430
- <h2 className={`text-sm font-semibold ${allFilled && summaryParts.length > 0 ? 'text-foreground' : expanded ? 'text-foreground' : 'text-muted-foreground'}`}>
498
+ <h2
499
+ className={`text-sm font-semibold ${
500
+ allFilled && summaryParts.length > 0
501
+ ? 'text-foreground'
502
+ : expanded
503
+ ? 'text-foreground'
504
+ : 'text-muted-foreground'
505
+ }`}
506
+ >
431
507
  {mod.name}
432
- {mod.optional && <span className="ml-1.5 text-xs font-normal text-muted-foreground">{t('optional')}</span>}
508
+ {mod.optional && (
509
+ <span className="ml-1.5 text-xs font-normal text-muted-foreground">
510
+ {t('optional')}
511
+ </span>
512
+ )}
433
513
  </h2>
434
514
  </div>
435
515
  {!expanded && summary && (
436
- <span className="text-xs text-muted-foreground hidden sm:inline truncate max-w-32">{summary}</span>
516
+ <span className="text-xs text-muted-foreground hidden sm:inline truncate max-w-32">
517
+ {summary}
518
+ </span>
437
519
  )}
438
- <ChevronDown className={`w-4 h-4 text-muted-foreground transition-transform ${expanded ? 'rotate-180' : ''}`} />
520
+ <ChevronDown
521
+ className={`w-4 h-4 text-muted-foreground transition-transform ${
522
+ expanded ? 'rotate-180' : ''
523
+ }`}
524
+ />
439
525
  </button>
440
526
  {expanded && (
441
527
  <div className="px-4 pb-4 pt-2 space-y-3.5 border-t border-border">
442
- {visibleFields.map(field => (
528
+ {visibleFields.map((field) => (
443
529
  <FieldInput
444
530
  key={field.id}
445
531
  field={field}
446
532
  moduleCode={mod.code}
447
533
  value={values[buildFieldRef(mod.code, field.code)] ?? ''}
448
534
  evalField={evalFieldMap.get(buildFieldRef(mod.code, field.code))}
449
- onChange={val => onFieldChange(mod.code, field.code, val)}
535
+ onChange={(val) => onFieldChange(mod.code, field.code, val)}
450
536
  />
451
537
  ))}
452
538
  </div>
@@ -480,7 +566,7 @@ function FieldInput({
480
566
  <Label className="text-sm font-medium">{field.name}</Label>
481
567
  <Switch
482
568
  checked={value === 'true'}
483
- onCheckedChange={checked => onChange(checked ? 'true' : 'false')}
569
+ onCheckedChange={(checked) => onChange(checked ? 'true' : 'false')}
484
570
  />
485
571
  </div>
486
572
  ) : (
@@ -494,15 +580,22 @@ function FieldInput({
494
580
  ) : field.fieldType === 'SELECT' || field.fieldType === 'DYNAMIC_SELECT' ? (
495
581
  <SelectInput field={field} value={value} evalField={evalField} onChange={onChange} />
496
582
  ) : (
497
- <Input value={value} onChange={e => onChange(e.target.value)} />
583
+ <Input value={value} onChange={(e) => onChange(e.target.value)} />
498
584
  )}
499
585
  </>
500
586
  )}
501
587
 
502
588
  {messages.map((msg, i) => (
503
- <p key={i} className={`text-xs flex items-center gap-1 ${
504
- msg.type === 'error' ? 'text-red-600' : msg.type === 'warning' ? 'text-amber-600' : 'text-muted-foreground'
505
- }`}>
589
+ <p
590
+ key={i}
591
+ className={`text-xs flex items-center gap-1 ${
592
+ msg.type === 'error'
593
+ ? 'text-red-600'
594
+ : msg.type === 'warning'
595
+ ? 'text-amber-600'
596
+ : 'text-muted-foreground'
597
+ }`}
598
+ >
506
599
  <Info className="w-3 h-3 shrink-0" />
507
600
  {msg.message}
508
601
  </p>
@@ -512,20 +605,37 @@ function FieldInput({
512
605
  <p className="text-xs text-muted-foreground font-mono tabular-nums">
513
606
  {field.min && field.max
514
607
  ? t('range', {
515
- min: `${Number(field.min).toLocaleString()}`,
516
- max: `${Number(field.max).toLocaleString()}${field.unit ? ` ${field.unit}` : ''}`,
517
- })
608
+ min: `${Number(field.min).toLocaleString()}`,
609
+ max: `${Number(field.max).toLocaleString()}${
610
+ field.unit ? ` ${field.unit}` : ''
611
+ }`,
612
+ })
518
613
  : field.min
519
- ? t('min', { value: `${Number(field.min).toLocaleString()}${field.unit ? ` ${field.unit}` : ''}` })
520
- : t('max', { value: `${Number(field.max).toLocaleString()}${field.unit ? ` ${field.unit}` : ''}` })
521
- }
614
+ ? t('min', {
615
+ value: `${Number(field.min).toLocaleString()}${
616
+ field.unit ? ` ${field.unit}` : ''
617
+ }`,
618
+ })
619
+ : t('max', {
620
+ value: `${Number(field.max).toLocaleString()}${
621
+ field.unit ? ` ${field.unit}` : ''
622
+ }`,
623
+ })}
522
624
  </p>
523
625
  )}
524
626
  </div>
525
627
  );
526
628
  }
527
629
 
528
- function NumberInput({ field, value, onChange }: { field: ConfiguratorField; value: string; onChange: (v: string) => void }) {
630
+ function NumberInput({
631
+ field,
632
+ value,
633
+ onChange,
634
+ }: {
635
+ field: ConfiguratorField;
636
+ value: string;
637
+ onChange: (v: string) => void;
638
+ }) {
529
639
  const step = field.unit === 'mm' ? 100 : 1;
530
640
  const min = field.min ? Number(field.min) : undefined;
531
641
  const max = field.max ? Number(field.max) : undefined;
@@ -553,7 +663,7 @@ function NumberInput({ field, value, onChange }: { field: ConfiguratorField; val
553
663
  min={min}
554
664
  max={max}
555
665
  step={step}
556
- onChange={e => onChange(e.target.value)}
666
+ onChange={(e) => onChange(e.target.value)}
557
667
  className="flex-1 h-9 px-3 text-sm focus:outline-none bg-transparent font-mono tabular-nums text-center [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
558
668
  />
559
669
  <button
@@ -585,8 +695,8 @@ function SelectInput({
585
695
  }) {
586
696
  const t = useTranslations('Configurator');
587
697
  const options = evalField?.availableOptions?.length
588
- ? evalField.availableOptions.map(o => ({ value: o.value, label: o.label ?? o.value }))
589
- : (field.options ?? []).map(o => ({ value: o.code, label: o.label }));
698
+ ? evalField.availableOptions.map((o) => ({ value: o.value, label: o.label ?? o.value }))
699
+ : (field.options ?? []).map((o) => ({ value: o.code, label: o.label }));
590
700
 
591
701
  return (
592
702
  <Select value={value || undefined} onValueChange={onChange}>
@@ -594,7 +704,7 @@ function SelectInput({
594
704
  <SelectValue placeholder={t('selectPlaceholder', { field: field.name.toLowerCase() })} />
595
705
  </SelectTrigger>
596
706
  <SelectContent>
597
- {options.map(opt => (
707
+ {options.map((opt) => (
598
708
  <SelectItem key={opt.value} value={opt.value}>
599
709
  {opt.label}
600
710
  </SelectItem>
@@ -603,4 +713,3 @@ function SelectInput({
603
713
  </Select>
604
714
  );
605
715
  }
606
-
@@ -1,32 +1,21 @@
1
1
  'use client';
2
2
 
3
- import { use, useState } from 'react';
4
- import { useTranslations } from 'next-intl';
5
- import { useSearchParams } from 'next/navigation';
6
- import { usePathname, useRouter } from '@/i18n/navigation';
3
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
4
+ import { Badge } from '@/components/ui/badge';
5
+ import { Button } from '@/components/ui/button';
7
6
  import { Checkbox } from '@/components/ui/checkbox';
8
7
  import { Label } from '@/components/ui/label';
9
- import { Button } from '@/components/ui/button';
10
- import { Badge } from '@/components/ui/badge';
11
- import {
12
- Accordion,
13
- AccordionContent,
14
- AccordionItem,
15
- AccordionTrigger,
16
- } from '@/components/ui/accordion';
17
- import {
18
- Sheet,
19
- SheetContent,
20
- SheetHeader,
21
- SheetTitle,
22
- SheetTrigger,
23
- } from '@/components/ui/sheet';
24
- import { SlidersHorizontal, Layers, ListTree, Tag } from 'lucide-react';
25
- import { type SearchProductsResult } from '@/lib/vendure/queries';
8
+ import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet';
9
+ import { Switch } from '@/components/ui/switch';
10
+ import { usePathname, useRouter } from '@/i18n/navigation';
26
11
  import { RESERVED_PARAMS, STRUCTURAL_PARAMS } from '@/lib/search-helpers';
12
+ import { type SearchProductsResult } from '@/lib/vendure/queries';
13
+ import { Layers, ListTree, SlidersHorizontal, Tag } from 'lucide-react';
14
+ import { useTranslations } from 'next-intl';
15
+ import { useSearchParams } from 'next/navigation';
16
+ import { use, useState } from 'react';
27
17
  import { ActiveFilters } from './active-filters';
28
18
  import { PriceRangeFilter } from './price-range-filter';
29
- import { Switch } from '@/components/ui/switch';
30
19
 
31
20
  const VISIBLE_COUNT = 6;
32
21
 
@@ -79,9 +68,9 @@ export function FacetFilters({ productDataPromise }: FacetFiltersProps) {
79
68
  const activeFilterCount =
80
69
  [...searchParams.entries()]
81
70
  .filter(([key]) => !RESERVED_PARAMS.has(key))
82
- .reduce((n, [, v]) => n + v.split(',').length, 0)
83
- + (searchParams.has('priceMin') || searchParams.has('priceMax') ? 1 : 0)
84
- + (searchParams.get('inStock') === 'true' ? 1 : 0);
71
+ .reduce((n, [, v]) => n + v.split(',').length, 0) +
72
+ (searchParams.has('priceMin') || searchParams.has('priceMax') ? 1 : 0) +
73
+ (searchParams.get('inStock') === 'true' ? 1 : 0);
85
74
 
86
75
  const toggleFacet = (facetCode: string, valueCode: string) => {
87
76
  const params = new URLSearchParams(searchParams);
@@ -143,7 +132,9 @@ export function FacetFilters({ productDataPromise }: FacetFiltersProps) {
143
132
  variant="ghost"
144
133
  size="sm"
145
134
  onClick={clearFilters}
146
- className={`h-7 text-xs text-muted-foreground hover:text-foreground ${!hasActiveFilters ? 'invisible' : ''}`}
135
+ className={`h-7 text-xs text-muted-foreground hover:text-foreground ${
136
+ !hasActiveFilters ? 'invisible' : ''
137
+ }`}
147
138
  >
148
139
  {t('clearAll')}
149
140
  </Button>
@@ -155,11 +146,7 @@ export function FacetFilters({ productDataPromise }: FacetFiltersProps) {
155
146
  <Label htmlFor="in-stock-toggle" className="text-sm font-normal cursor-pointer">
156
147
  {t('inStockOnly')}
157
148
  </Label>
158
- <Switch
159
- id="in-stock-toggle"
160
- checked={isInStock}
161
- onCheckedChange={toggleInStock}
162
- />
149
+ <Switch id="in-stock-toggle" checked={isInStock} onCheckedChange={toggleInStock} />
163
150
  </div>
164
151
 
165
152
  <PriceRangeFilter min={prices.range.min} max={prices.range.max} />
@@ -167,9 +154,12 @@ export function FacetFilters({ productDataPromise }: FacetFiltersProps) {
167
154
  <Accordion type="multiple" defaultValue={defaultOpen}>
168
155
  {facetGroups.map((facet) => {
169
156
  const facetNameLower = facet.name.toLowerCase();
170
- const FacetIcon = facetNameLower.includes('subcategory') ? ListTree
171
- : facetNameLower.includes('category') ? Layers
172
- : facetNameLower.includes('brand') ? Tag
157
+ const FacetIcon = facetNameLower.includes('subcategory')
158
+ ? ListTree
159
+ : facetNameLower.includes('category')
160
+ ? Layers
161
+ : facetNameLower.includes('brand')
162
+ ? Tag
173
163
  : SlidersHorizontal;
174
164
 
175
165
  const selectedValues = searchParams.get(facet.code)?.split(',') ?? [];
@@ -200,9 +190,7 @@ export function FacetFilters({ productDataPromise }: FacetFiltersProps) {
200
190
  return (
201
191
  <>
202
192
  {/* Desktop: sticky sidebar */}
203
- <div className="hidden lg:block sticky top-20">
204
- {filterContent}
205
- </div>
193
+ <div className="hidden lg:block sticky top-20">{filterContent}</div>
206
194
 
207
195
  {/* Mobile: sheet trigger */}
208
196
  <div className="lg:hidden">
@@ -212,9 +200,7 @@ export function FacetFilters({ productDataPromise }: FacetFiltersProps) {
212
200
  <SlidersHorizontal className="h-4 w-4" />
213
201
  {t('filtersButton')}
214
202
  {hasActiveFilters && (
215
- <Badge className="h-5 min-w-5 px-1.5 text-[10px]">
216
- {activeFilterCount}
217
- </Badge>
203
+ <Badge className="h-5 min-w-5 px-1.5 text-[10px]">{activeFilterCount}</Badge>
218
204
  )}
219
205
  </Button>
220
206
  </SheetTrigger>
@@ -261,12 +247,8 @@ function FacetValueList({
261
247
  htmlFor={`facet-${facetCode}-${value.code}`}
262
248
  className="text-sm font-normal cursor-pointer flex-1 flex items-center justify-between"
263
249
  >
264
- <span className={isChecked ? 'text-foreground' : ''}>
265
- {value.name}
266
- </span>
267
- <span className="text-xs text-muted-foreground tabular-nums">
268
- {value.count}
269
- </span>
250
+ <span className={isChecked ? 'text-foreground' : ''}>{value.name}</span>
251
+ <span className="text-xs text-muted-foreground tabular-nums">{value.count}</span>
270
252
  </Label>
271
253
  </div>
272
254
  );
@@ -276,9 +258,7 @@ function FacetValueList({
276
258
  onClick={() => setExpanded(!expanded)}
277
259
  className="text-xs text-primary hover:text-primary/80 pt-1"
278
260
  >
279
- {expanded
280
- ? t('showLess')
281
- : t('moreCount', { count: values.length - VISIBLE_COUNT })}
261
+ {expanded ? t('showLess') : t('moreCount', { count: values.length - VISIBLE_COUNT })}
282
262
  </button>
283
263
  )}
284
264
  </div>