@vendure-platform/create 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/CHANGELOG.md +4 -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,11 +1,11 @@
1
1
  'use client';
2
2
 
3
- import { Label } from '@/components/ui/label';
4
3
  import { Price } from '@/components/commerce/price';
5
- import { Badge } from '@/components/ui/badge';
6
- import { Package } from 'lucide-react';
7
4
  import type { PriceTier } from '@/components/commerce/price-tiers';
5
+ import { Badge } from '@/components/ui/badge';
6
+ import { Label } from '@/components/ui/label';
8
7
  import type { PackagingUnitOption } from '@/lib/vendure/queries';
8
+ import { Package } from 'lucide-react';
9
9
 
10
10
  interface PackagingUnitSelectorProps {
11
11
  packagingUnits: PackagingUnitOption[];
@@ -22,7 +22,11 @@ interface PackagingUnitSelectorProps {
22
22
  * Returns the per-piece price for the given effective base-unit quantity.
23
23
  * Falls back to basePrice if no tier matches.
24
24
  */
25
- function getTierAdjustedPiecePrice(basePrice: number, tiers: PriceTier[] | undefined, effectivePieces: number): number {
25
+ function getTierAdjustedPiecePrice(
26
+ basePrice: number,
27
+ tiers: PriceTier[] | undefined,
28
+ effectivePieces: number,
29
+ ): number {
26
30
  if (!tiers || tiers.length === 0) return basePrice;
27
31
  let price = basePrice;
28
32
  for (const tier of tiers) {
@@ -44,7 +48,7 @@ export function PackagingUnitSelector({
44
48
  if (packagingUnits.length === 0) return null;
45
49
 
46
50
  const sortedTiers = priceTiers
47
- ? [...priceTiers].filter(t => t.minQuantity != null).sort((a, b) => a.minQuantity! - b.minQuantity!)
51
+ ? [...priceTiers].filter((t) => t.minQuantity != null).sort((a, b) => a.minQuantity! - b.minQuantity!)
48
52
  : undefined;
49
53
 
50
54
  return (
@@ -62,9 +66,15 @@ export function PackagingUnitSelector({
62
66
  // Prefer the packaging-unit's own tier ladder so any
63
67
  // packaging-unit-gated discounts are reflected on the card.
64
68
  const puTiers = pu.priceTiers
65
- ? [...pu.priceTiers].filter(t => t.minQuantity != null).sort((a, b) => a.minQuantity! - b.minQuantity!)
69
+ ? [...pu.priceTiers]
70
+ .filter((t) => t.minQuantity != null)
71
+ .sort((a, b) => a.minQuantity! - b.minQuantity!)
66
72
  : sortedTiers;
67
- const perPiecePrice = getTierAdjustedPiecePrice(baseVariantPrice, puTiers, effectivePieces);
73
+ const perPiecePrice = getTierAdjustedPiecePrice(
74
+ baseVariantPrice,
75
+ puTiers,
76
+ effectivePieces,
77
+ );
68
78
  const displayPrice = Math.round(perPiecePrice * pu.conversionFactor);
69
79
 
70
80
  const stockLevel = pu.effectiveStockLevel;
@@ -80,8 +90,8 @@ export function PackagingUnitSelector({
80
90
  isSelected
81
91
  ? 'border-primary bg-primary/5'
82
92
  : isOutOfStock
83
- ? 'border-muted opacity-50 cursor-not-allowed'
84
- : 'border-muted bg-popover hover:bg-accent hover:text-accent-foreground cursor-pointer'
93
+ ? 'border-muted opacity-50 cursor-not-allowed'
94
+ : 'border-muted bg-popover hover:bg-accent hover:text-accent-foreground cursor-pointer'
85
95
  }`}
86
96
  >
87
97
  <div className="flex items-center gap-2 w-full">
@@ -91,10 +101,7 @@ export function PackagingUnitSelector({
91
101
  : `${pu.packagingUnit.name} (${pu.conversionFactor} pcs)`}
92
102
  </span>
93
103
  {pu.isBaseUnit && (
94
- <Badge
95
- variant="secondary"
96
- className="text-[10px] px-1.5 py-0"
97
- >
104
+ <Badge variant="secondary" className="text-[10px] px-1.5 py-0">
98
105
  Base
99
106
  </Badge>
100
107
  )}
@@ -102,16 +109,14 @@ export function PackagingUnitSelector({
102
109
 
103
110
  <div className="flex items-center gap-2 text-xs text-muted-foreground">
104
111
  <span className="font-medium text-foreground">
105
- <Price
106
- value={displayPrice}
107
- currencyCode={currencyCode}
108
- />
112
+ <Price value={displayPrice} currencyCode={currencyCode} />
109
113
  </span>
110
114
  {pu.conversionFactor > 1 && (
111
115
  <>
112
116
  <span>·</span>
113
117
  <span>
114
- <Price value={perPiecePrice} currencyCode={currencyCode} />/pc
118
+ <Price value={perPiecePrice} currencyCode={currencyCode} />
119
+ /pc
115
120
  </span>
116
121
  </>
117
122
  )}
@@ -124,20 +129,16 @@ export function PackagingUnitSelector({
124
129
  isOutOfStock
125
130
  ? 'text-red-600'
126
131
  : stockLevel < 10
127
- ? 'text-amber-600'
128
- : 'text-emerald-600'
132
+ ? 'text-amber-600'
133
+ : 'text-emerald-600'
129
134
  }
130
135
  >
131
- {isOutOfStock
132
- ? 'Out of stock'
133
- : `${stockLevel} available`}
136
+ {isOutOfStock ? 'Out of stock' : `${stockLevel} available`}
134
137
  </span>
135
138
  )}
136
139
  {pu.minQuantity > 1 && (
137
140
  <>
138
- {stockLevel !== null && (
139
- <span>·</span>
140
- )}
141
+ {stockLevel !== null && <span>·</span>}
141
142
  <span>Min. {pu.minQuantity}</span>
142
143
  </>
143
144
  )}
@@ -1,5 +1,5 @@
1
- import type {ReactNode} from 'react';
2
- import {getCompanyAccount} from '@/lib/vendure/actions';
1
+ import { getCompanyAccount } from '@/lib/vendure/actions';
2
+ import type { ReactNode } from 'react';
3
3
 
4
4
  interface PermissionGateProps {
5
5
  permission: string | string[];
@@ -7,14 +7,14 @@ interface PermissionGateProps {
7
7
  fallback?: ReactNode;
8
8
  }
9
9
 
10
- export async function PermissionGate({permission, children, fallback = null}: PermissionGateProps) {
10
+ export async function PermissionGate({ permission, children, fallback = null }: PermissionGateProps) {
11
11
  const companyAccount = await getCompanyAccount();
12
12
 
13
13
  if (!companyAccount) return fallback;
14
14
 
15
15
  const permissions = companyAccount.permissions;
16
16
  const required = Array.isArray(permission) ? permission : [permission];
17
- const hasPermission = required.some(p => permissions.includes(p));
17
+ const hasPermission = required.some((p) => permissions.includes(p));
18
18
 
19
19
  return hasPermission ? <>{children}</> : <>{fallback}</>;
20
20
  }
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
- import { useState, useCallback, useEffect } from 'react';
4
- import { useSearchParams } from 'next/navigation';
5
- import { usePathname, useRouter } from '@/i18n/navigation';
6
- import { useTranslations } from 'next-intl';
7
- import { Slider } from '@/components/ui/slider';
8
3
  import { Input } from '@/components/ui/input';
9
4
  import { Label } from '@/components/ui/label';
5
+ import { Slider } from '@/components/ui/slider';
6
+ import { usePathname, useRouter } from '@/i18n/navigation';
7
+ import { useTranslations } from 'next-intl';
8
+ import { useSearchParams } from 'next/navigation';
9
+ import { useCallback, useEffect, useState } from 'react';
10
10
 
11
11
  interface PriceRangeFilterProps {
12
12
  min: number;
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
 
3
- import {ResultOf} from '@/graphql';
4
- import {GetProductDetailQuery} from '@/lib/vendure/queries';
5
- import {Price} from '@/components/commerce/price';
6
- import {useTranslations} from 'next-intl';
3
+ import { Price } from '@/components/commerce/price';
4
+ import { ResultOf } from '@/graphql';
5
+ import { GetProductDetailQuery } from '@/lib/vendure/queries';
6
+ import { useTranslations } from 'next-intl';
7
7
 
8
8
  type ProductVariant = NonNullable<ResultOf<typeof GetProductDetailQuery>['product']>['variants'][number];
9
9
  export type PriceTier = NonNullable<ProductVariant['priceTiers']>[number];
@@ -20,10 +20,18 @@ interface PriceTiersProps {
20
20
  currencyCode?: string;
21
21
  }
22
22
 
23
- export function PriceTiers({tiers, basePrice, quantity = 1, onTierClick, conversionFactor = 1, unitName, currencyCode}: PriceTiersProps) {
23
+ export function PriceTiers({
24
+ tiers,
25
+ basePrice,
26
+ quantity = 1,
27
+ onTierClick,
28
+ conversionFactor = 1,
29
+ unitName,
30
+ currencyCode,
31
+ }: PriceTiersProps) {
24
32
  const t = useTranslations('Product');
25
33
  const sorted = [...tiers]
26
- .filter(t => t.minQuantity != null)
34
+ .filter((t) => t.minQuantity != null)
27
35
  .sort((a, b) => a.minQuantity! - b.minQuantity!);
28
36
 
29
37
  if (sorted.length < 2) {
@@ -35,18 +43,23 @@ export function PriceTiers({tiers, basePrice, quantity = 1, onTierClick, convers
35
43
  const hasPackagingUnit = conversionFactor > 1 && unitName;
36
44
 
37
45
  // Find the active tier based on effective base-unit quantity
38
- const activeTierIndex = sorted.reduce((activeIdx, tier, idx) =>
39
- effectiveQuantity >= tier.minQuantity! ? idx : activeIdx
40
- , -1);
46
+ const activeTierIndex = sorted.reduce(
47
+ (activeIdx, tier, idx) => (effectiveQuantity >= tier.minQuantity! ? idx : activeIdx),
48
+ -1,
49
+ );
41
50
 
42
51
  return (
43
52
  <div className="rounded-lg border bg-muted/30 p-4">
44
- <h3 className="text-sm font-semibold mb-3">{t('volumePricing')} <span className="text-[10px] font-normal text-muted-foreground">{t('volumePricingExclTax')}</span></h3>
53
+ <h3 className="text-sm font-semibold mb-3">
54
+ {t('volumePricing')}{' '}
55
+ <span className="text-[10px] font-normal text-muted-foreground">
56
+ {t('volumePricingExclTax')}
57
+ </span>
58
+ </h3>
45
59
  <div className="space-y-1">
46
60
  {sorted.map((tier, idx) => {
47
- const savings = tier.price < basePrice
48
- ? Math.round((1 - tier.price / basePrice) * 100)
49
- : 0;
61
+ const savings =
62
+ tier.price < basePrice ? Math.round((1 - tier.price / basePrice) * 100) : 0;
50
63
  const isActive = idx === activeTierIndex;
51
64
  const isClickable = !!onTierClick && !hasPackagingUnit;
52
65
  const packagePrice = hasPackagingUnit ? Math.round(tier.price * conversionFactor) : null;
@@ -61,31 +74,35 @@ export function PriceTiers({tiers, basePrice, quantity = 1, onTierClick, convers
61
74
  isActive
62
75
  ? 'bg-primary/15 ring-1 ring-primary/30 font-medium'
63
76
  : isClickable
64
- ? 'hover:bg-muted cursor-pointer'
65
- : ''
77
+ ? 'hover:bg-muted cursor-pointer'
78
+ : ''
66
79
  } ${!isClickable ? 'cursor-default' : ''}`}
67
- aria-label={`${t('unitsPlus', {qty: tier.minQuantity!})} at ${(tier.price / 100).toFixed(2)} ${t('eachUnit')}${isActive ? ' (current tier)' : ''}`}
80
+ aria-label={`${t('unitsPlus', { qty: tier.minQuantity! })} at ${(
81
+ tier.price / 100
82
+ ).toFixed(2)} ${t('eachUnit')}${isActive ? ' (current tier)' : ''}`}
68
83
  aria-current={isActive ? 'true' : undefined}
69
84
  >
70
85
  <span className={isActive ? 'text-primary' : 'text-muted-foreground'}>
71
- {t('unitsPlus', {qty: tier.minQuantity!})}
86
+ {t('unitsPlus', { qty: tier.minQuantity! })}
72
87
  </span>
73
88
  <div className="flex items-center gap-2">
74
89
  {savings > 0 && (
75
90
  <span className="text-xs text-green-600 font-medium">
76
- {t('savePercent', {percent: savings})}
91
+ {t('savePercent', { percent: savings })}
77
92
  </span>
78
93
  )}
79
94
  {packagePrice != null ? (
80
95
  <span className="font-medium">
81
- <Price value={packagePrice} currencyCode={currencyCode}/>
96
+ <Price value={packagePrice} currencyCode={currencyCode} />
82
97
  <span className="text-xs text-muted-foreground font-normal ml-1">
83
- (<Price value={tier.price} currencyCode={currencyCode}/>{t('perPiece')})
98
+ (<Price value={tier.price} currencyCode={currencyCode} />
99
+ {t('perPiece')})
84
100
  </span>
85
101
  </span>
86
102
  ) : (
87
103
  <span className="font-medium">
88
- <Price value={tier.price} currencyCode={currencyCode}/> {t('eachUnit')}
104
+ <Price value={tier.price} currencyCode={currencyCode} />{' '}
105
+ {t('eachUnit')}
89
106
  </span>
90
107
  )}
91
108
  </div>
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import {useLocale, useTranslations} from 'next-intl';
4
- import {toIntlLocale} from '@/i18n/locale-utils';
3
+ import { toIntlLocale } from '@/i18n/locale-utils';
4
+ import { useLocale, useTranslations } from 'next-intl';
5
5
 
6
6
  interface PriceProps {
7
7
  value: number;
@@ -10,7 +10,7 @@ interface PriceProps {
10
10
  taxLabel?: 'excl' | 'incl';
11
11
  }
12
12
 
13
- export function Price({value, currencyCode = 'EUR', taxLabel}: PriceProps) {
13
+ export function Price({ value, currencyCode = 'EUR', taxLabel }: PriceProps) {
14
14
  const locale = useLocale();
15
15
  const t = useTranslations('Price');
16
16
  return (
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
 
3
- import { useRef } from 'react';
4
- import Image from 'next/image';
5
- import {Link} from '@/i18n/navigation';
6
- import { FragmentOf, readFragment } from '@/graphql';
7
- import { ProductCardFragment } from '@/lib/vendure/fragments';
8
3
  import { Price } from '@/components/commerce/price';
9
4
  import { Badge } from '@/components/ui/badge';
5
+ import { FragmentOf, readFragment } from '@/graphql';
6
+ import { Link } from '@/i18n/navigation';
7
+ import { ProductCardFragment } from '@/lib/vendure/fragments';
10
8
  import { ChevronDown, ChevronUp } from 'lucide-react';
9
+ import Image from 'next/image';
10
+ import { useRef } from 'react';
11
11
  import { HighlightedText } from './highlighted-text';
12
12
  import { ProductListExpansion, prefetchProduct } from './product-list-expansion';
13
13
 
@@ -78,18 +78,22 @@ export function ProductCardList({ product: productProp, isExpanded, onToggle }:
78
78
  />
79
79
  )}
80
80
  {product.sku && (
81
- <p className="text-xs text-muted-foreground font-mono mt-0.5">
82
- {product.sku}
83
- </p>
81
+ <p className="text-xs text-muted-foreground font-mono mt-0.5">{product.sku}</p>
84
82
  )}
85
83
  </div>
86
84
  <div className="flex items-center gap-4 flex-shrink-0">
87
85
  {product.inStock ? (
88
- <Badge variant="secondary" className="bg-emerald-900/80 text-emerald-300 border-0 text-[10px] uppercase tracking-wider">
86
+ <Badge
87
+ variant="secondary"
88
+ className="bg-emerald-900/80 text-emerald-300 border-0 text-[10px] uppercase tracking-wider"
89
+ >
89
90
  In Stock
90
91
  </Badge>
91
92
  ) : (
92
- <Badge variant="secondary" className="bg-red-900/80 text-red-300 border-0 text-[10px] uppercase tracking-wider">
93
+ <Badge
94
+ variant="secondary"
95
+ className="bg-red-900/80 text-red-300 border-0 text-[10px] uppercase tracking-wider"
96
+ >
93
97
  Out of Stock
94
98
  </Badge>
95
99
  )}
@@ -97,13 +101,26 @@ export function ProductCardList({ product: productProp, isExpanded, onToggle }:
97
101
  {product.price.__typename === 'PriceRange' ? (
98
102
  product.price.min !== product.price.max ? (
99
103
  <>
100
- from <Price value={product.price.min} currencyCode={product.currencyCode} taxLabel="excl" />
104
+ from{' '}
105
+ <Price
106
+ value={product.price.min}
107
+ currencyCode={product.currencyCode}
108
+ taxLabel="excl"
109
+ />
101
110
  </>
102
111
  ) : (
103
- <Price value={product.price.min} currencyCode={product.currencyCode} taxLabel="excl" />
112
+ <Price
113
+ value={product.price.min}
114
+ currencyCode={product.currencyCode}
115
+ taxLabel="excl"
116
+ />
104
117
  )
105
118
  ) : product.price.__typename === 'SinglePrice' ? (
106
- <Price value={product.price.value} currencyCode={product.currencyCode} taxLabel="excl" />
119
+ <Price
120
+ value={product.price.value}
121
+ currencyCode={product.currencyCode}
122
+ taxLabel="excl"
123
+ />
107
124
  ) : null}
108
125
  </p>
109
126
  {isExpanded ? (
@@ -114,7 +131,11 @@ export function ProductCardList({ product: productProp, isExpanded, onToggle }:
114
131
  </div>
115
132
  </div>
116
133
  {isExpanded && (
117
- <ProductListExpansion slug={product.slug} productName={product.productName} currencyCode={product.currencyCode} />
134
+ <ProductListExpansion
135
+ slug={product.slug}
136
+ productName={product.productName}
137
+ currencyCode={product.currencyCode}
138
+ />
118
139
  )}
119
140
  </div>
120
141
  );
@@ -1,12 +1,12 @@
1
- import Image from 'next/image';
2
- import {useTranslations} from 'next-intl';
3
- import {Package} from 'lucide-react';
4
- import { FragmentOf, readFragment } from '@/graphql';
5
- import { ProductCardFragment } from '@/lib/vendure/fragments';
6
1
  import { Price } from '@/components/commerce/price';
7
- import { Suspense } from 'react';
8
2
  import { PrefetchLink } from '@/components/shared/prefetch-link';
9
3
  import { Badge } from '@/components/ui/badge';
4
+ import { FragmentOf, readFragment } from '@/graphql';
5
+ import { ProductCardFragment } from '@/lib/vendure/fragments';
6
+ import { Package } from 'lucide-react';
7
+ import { useTranslations } from 'next-intl';
8
+ import Image from 'next/image';
9
+ import { Suspense } from 'react';
10
10
  import { HighlightedText } from './highlighted-text';
11
11
 
12
12
  interface ProductCardProps {
@@ -42,11 +42,17 @@ export function ProductCard({ product: productProp }: ProductCardProps) {
42
42
  {/* Stock badge overlay */}
43
43
  <div className="absolute top-2 right-2">
44
44
  {product.inStock ? (
45
- <Badge variant="secondary" className="bg-emerald-900/80 text-emerald-300 border-0 text-[10px] uppercase tracking-wider">
45
+ <Badge
46
+ variant="secondary"
47
+ className="bg-emerald-900/80 text-emerald-300 border-0 text-[10px] uppercase tracking-wider"
48
+ >
46
49
  {t('inStock')}
47
50
  </Badge>
48
51
  ) : (
49
- <Badge variant="secondary" className="bg-red-900/80 text-red-300 border-0 text-[10px] uppercase tracking-wider">
52
+ <Badge
53
+ variant="secondary"
54
+ className="bg-red-900/80 text-red-300 border-0 text-[10px] uppercase tracking-wider"
55
+ >
50
56
  {t('outOfStock')}
51
57
  </Badge>
52
58
  )}
@@ -63,23 +69,32 @@ export function ProductCard({ product: productProp }: ProductCardProps) {
63
69
  className="text-xs text-muted-foreground line-clamp-2"
64
70
  />
65
71
  )}
66
- {product.sku && (
67
- <p className="text-xs text-muted-foreground font-mono">
68
- {product.sku}
69
- </p>
70
- )}
72
+ {product.sku && <p className="text-xs text-muted-foreground font-mono">{product.sku}</p>}
71
73
  <Suspense fallback={<div className="h-6 w-28 rounded bg-muted" />}>
72
74
  <p className="text-base font-bold">
73
75
  {product.price.__typename === 'PriceRange' ? (
74
76
  product.price.min !== product.price.max ? (
75
77
  <>
76
- {t('from')} <Price value={product.price.min} currencyCode={product.currencyCode} taxLabel="excl" />
78
+ {t('from')}{' '}
79
+ <Price
80
+ value={product.price.min}
81
+ currencyCode={product.currencyCode}
82
+ taxLabel="excl"
83
+ />
77
84
  </>
78
85
  ) : (
79
- <Price value={product.price.min} currencyCode={product.currencyCode} taxLabel="excl" />
86
+ <Price
87
+ value={product.price.min}
88
+ currencyCode={product.currencyCode}
89
+ taxLabel="excl"
90
+ />
80
91
  )
81
92
  ) : product.price.__typename === 'SinglePrice' ? (
82
- <Price value={product.price.value} currencyCode={product.currencyCode} taxLabel="excl" />
93
+ <Price
94
+ value={product.price.value}
95
+ currencyCode={product.currencyCode}
96
+ taxLabel="excl"
97
+ />
83
98
  ) : null}
84
99
  </p>
85
100
  </Suspense>
@@ -1,17 +1,23 @@
1
1
  'use client';
2
2
 
3
- import {ProductCard} from "@/components/commerce/product-card";
4
- import {Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,} from "@/components/ui/carousel";
5
- import {FragmentOf} from "@/graphql";
6
- import {ProductCardFragment} from "@/lib/vendure/fragments";
7
- import {useId} from "react";
3
+ import { ProductCard } from '@/components/commerce/product-card';
4
+ import {
5
+ Carousel,
6
+ CarouselContent,
7
+ CarouselItem,
8
+ CarouselNext,
9
+ CarouselPrevious,
10
+ } from '@/components/ui/carousel';
11
+ import { FragmentOf } from '@/graphql';
12
+ import { ProductCardFragment } from '@/lib/vendure/fragments';
13
+ import { useId } from 'react';
8
14
 
9
15
  interface ProductCarouselClientProps {
10
16
  title: string;
11
17
  products: Array<FragmentOf<typeof ProductCardFragment>>;
12
18
  }
13
19
 
14
- export function ProductCarousel({title, products}: ProductCarouselClientProps) {
20
+ export function ProductCarousel({ title, products }: ProductCarouselClientProps) {
15
21
  const id = useId();
16
22
 
17
23
  return (
@@ -20,21 +26,23 @@ export function ProductCarousel({title, products}: ProductCarouselClientProps) {
20
26
  <h2 className="text-3xl md:text-4xl font-bold mb-8">{title}</h2>
21
27
  <Carousel
22
28
  opts={{
23
- align: "start",
29
+ align: 'start',
24
30
  loop: true,
25
31
  }}
26
32
  className="w-full"
27
33
  >
28
34
  <CarouselContent className="-ml-2 md:-ml-4">
29
35
  {products.map((product, i) => (
30
- <CarouselItem key={id + i}
31
- className="pl-2 md:pl-4 basis-full sm:basis-1/2 lg:basis-1/3 xl:basis-1/4">
32
- <ProductCard product={product}/>
36
+ <CarouselItem
37
+ key={id + i}
38
+ className="pl-2 md:pl-4 basis-full sm:basis-1/2 lg:basis-1/3 xl:basis-1/4"
39
+ >
40
+ <ProductCard product={product} />
33
41
  </CarouselItem>
34
42
  ))}
35
43
  </CarouselContent>
36
- <CarouselPrevious className="hidden md:flex"/>
37
- <CarouselNext className="hidden md:flex"/>
44
+ <CarouselPrevious className="hidden md:flex" />
45
+ <CarouselNext className="hidden md:flex" />
38
46
  </Carousel>
39
47
  </div>
40
48
  </section>
@@ -1,10 +1,10 @@
1
1
  import { Pagination } from '@/components/shared/pagination';
2
- import { SortDropdown } from './sort-dropdown';
3
- import { ProductViewSwitcher } from './product-view-switcher';
2
+ import { EmptyState } from '@/components/ui/empty-state';
4
3
  import { type SearchProductsResult } from '@/lib/vendure/queries';
5
- import {getTranslations} from 'next-intl/server';
6
4
  import { PackageSearch } from 'lucide-react';
7
- import {EmptyState} from '@/components/ui/empty-state';
5
+ import { getTranslations } from 'next-intl/server';
6
+ import { ProductViewSwitcher } from './product-view-switcher';
7
+ import { SortDropdown } from './sort-dropdown';
8
8
 
9
9
  interface ProductGridProps {
10
10
  productDataPromise: SearchProductsResult;
@@ -14,11 +14,14 @@ interface ProductGridProps {
14
14
  emptyMessage?: string;
15
15
  }
16
16
 
17
- export async function ProductGrid({ productDataPromise, currentPage, take, view, emptyMessage }: ProductGridProps) {
18
- const [result, t] = await Promise.all([
19
- productDataPromise,
20
- getTranslations('Catalog'),
21
- ]);
17
+ export async function ProductGrid({
18
+ productDataPromise,
19
+ currentPage,
20
+ take,
21
+ view,
22
+ emptyMessage,
23
+ }: ProductGridProps) {
24
+ const [result, t] = await Promise.all([productDataPromise, getTranslations('Catalog')]);
22
25
 
23
26
  const searchResult = result.data.search;
24
27
  const totalPages = Math.ceil(searchResult.totalItems / take);
@@ -29,7 +32,7 @@ export async function ProductGrid({ productDataPromise, currentPage, take, view,
29
32
  icon={PackageSearch}
30
33
  heading={t('noProductsFound')}
31
34
  body={emptyMessage ?? t('emptySearchMessage')}
32
- action={{label: t('browseAllProducts'), href: '/'}}
35
+ action={{ label: t('browseAllProducts'), href: '/' }}
33
36
  />
34
37
  );
35
38
  }
@@ -46,9 +49,7 @@ export async function ProductGrid({ productDataPromise, currentPage, take, view,
46
49
  <SortDropdown />
47
50
  </ProductViewSwitcher>
48
51
 
49
- {totalPages > 1 && (
50
- <Pagination currentPage={currentPage} totalPages={totalPages} />
51
- )}
52
+ {totalPages > 1 && <Pagination currentPage={currentPage} totalPages={totalPages} />}
52
53
  </div>
53
54
  );
54
55
  }
@@ -1,11 +1,11 @@
1
1
  'use client';
2
2
 
3
- import { useState } from 'react';
4
- import Image from 'next/image';
5
- import { ChevronLeft, ChevronRight } from 'lucide-react';
6
- import { useTranslations } from 'next-intl';
7
3
  import { Button } from '@/components/ui/button';
8
4
  import type { ProductDetail } from '@/lib/vendure/queries';
5
+ import { ChevronLeft, ChevronRight } from 'lucide-react';
6
+ import { useTranslations } from 'next-intl';
7
+ import Image from 'next/image';
8
+ import { useState } from 'react';
9
9
 
10
10
  export interface ProductImageCarouselProps {
11
11
  images: ProductDetail['assets'];
@@ -50,7 +50,7 @@ export function ProductImageCarousel({ images, selectedIndex, onIndexChange }: P
50
50
  {/* Preview image — always rendered, acts as placeholder */}
51
51
  <Image
52
52
  src={currentImage.preview}
53
- alt={t('productImageAlt', {index: currentIndex + 1})}
53
+ alt={t('productImageAlt', { index: currentIndex + 1 })}
54
54
  fill
55
55
  className="object-cover"
56
56
  sizes="(max-width: 1024px) 100vw, 50vw"
@@ -59,9 +59,11 @@ export function ProductImageCarousel({ images, selectedIndex, onIndexChange }: P
59
59
  {/* Source image — layered on top, fades in when loaded */}
60
60
  <Image
61
61
  src={currentImage.source}
62
- alt={t('productImageAlt', {index: currentIndex + 1})}
62
+ alt={t('productImageAlt', { index: currentIndex + 1 })}
63
63
  fill
64
- className={`object-cover transition-opacity duration-300 ${sourceLoaded ? 'opacity-100' : 'opacity-0'}`}
64
+ className={`object-cover transition-opacity duration-300 ${
65
+ sourceLoaded ? 'opacity-100' : 'opacity-0'
66
+ }`}
65
67
  sizes="(max-width: 1024px) 100vw, 50vw"
66
68
  onLoad={() => {
67
69
  setLoadedSources((prev) => new Set(prev).add(currentIndex));
@@ -113,7 +115,7 @@ export function ProductImageCarousel({ images, selectedIndex, onIndexChange }: P
113
115
  >
114
116
  <Image
115
117
  src={image.preview}
116
- alt={t('thumbnailAlt', {index: index + 1})}
118
+ alt={t('thumbnailAlt', { index: index + 1 })}
117
119
  fill
118
120
  className="object-cover"
119
121
  sizes="25vw"