@vendure-platform/create 0.1.0

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 (531) hide show
  1. package/README.md +70 -0
  2. package/dist/assets/demo-data/branding/logo.svg +4 -0
  3. package/dist/assets/demo-data/images/absorbent-pad.webp +0 -0
  4. package/dist/assets/demo-data/images/adjustable-wrench.webp +0 -0
  5. package/dist/assets/demo-data/images/anchor-bolt.webp +0 -0
  6. package/dist/assets/demo-data/images/angle-grinder.webp +0 -0
  7. package/dist/assets/demo-data/images/barrier-tape.webp +0 -0
  8. package/dist/assets/demo-data/images/bench-grinder.webp +0 -0
  9. package/dist/assets/demo-data/images/bracket.webp +0 -0
  10. package/dist/assets/demo-data/images/broom.webp +0 -0
  11. package/dist/assets/demo-data/images/bucket.webp +0 -0
  12. package/dist/assets/demo-data/images/cable-gland.webp +0 -0
  13. package/dist/assets/demo-data/images/cable-tie.webp +0 -0
  14. package/dist/assets/demo-data/images/cable-tray.webp +0 -0
  15. package/dist/assets/demo-data/images/cable.webp +0 -0
  16. package/dist/assets/demo-data/images/chimney-base-kit.webp +0 -0
  17. package/dist/assets/demo-data/images/chimney-cowl-bird-guard.webp +0 -0
  18. package/dist/assets/demo-data/images/chimney-cowl-open.webp +0 -0
  19. package/dist/assets/demo-data/images/chimney-storm-collar.webp +0 -0
  20. package/dist/assets/demo-data/images/chimney-wall-bracket.webp +0 -0
  21. package/dist/assets/demo-data/images/circular-saw.webp +0 -0
  22. package/dist/assets/demo-data/images/cleaning-spray.webp +0 -0
  23. package/dist/assets/demo-data/images/conduit.webp +0 -0
  24. package/dist/assets/demo-data/images/cordless-drill.webp +0 -0
  25. package/dist/assets/demo-data/images/drill-bits.webp +0 -0
  26. package/dist/assets/demo-data/images/dust-mask.webp +0 -0
  27. package/dist/assets/demo-data/images/ear-defenders.webp +0 -0
  28. package/dist/assets/demo-data/images/ear-plugs.webp +0 -0
  29. package/dist/assets/demo-data/images/extension-lead.webp +0 -0
  30. package/dist/assets/demo-data/images/eye-wash-station.webp +0 -0
  31. package/dist/assets/demo-data/images/face-shield.webp +0 -0
  32. package/dist/assets/demo-data/images/file-set.webp +0 -0
  33. package/dist/assets/demo-data/images/first-aid-kit.webp +0 -0
  34. package/dist/assets/demo-data/images/floor-sign.webp +0 -0
  35. package/dist/assets/demo-data/images/flue-bend-45.webp +0 -0
  36. package/dist/assets/demo-data/images/flue-bend-90.webp +0 -0
  37. package/dist/assets/demo-data/images/flue-section-1000mm.webp +0 -0
  38. package/dist/assets/demo-data/images/flue-section-250mm.webp +0 -0
  39. package/dist/assets/demo-data/images/flue-section-500mm.webp +0 -0
  40. package/dist/assets/demo-data/images/fuse.webp +0 -0
  41. package/dist/assets/demo-data/images/glove-dispenser.webp +0 -0
  42. package/dist/assets/demo-data/images/grinding-disc.webp +0 -0
  43. package/dist/assets/demo-data/images/hacksaw.webp +0 -0
  44. package/dist/assets/demo-data/images/hammer.webp +0 -0
  45. package/dist/assets/demo-data/images/hand-sanitiser.webp +0 -0
  46. package/dist/assets/demo-data/images/head-torch.webp +0 -0
  47. package/dist/assets/demo-data/images/heat-gun.webp +0 -0
  48. package/dist/assets/demo-data/images/hex-bolt.webp +0 -0
  49. package/dist/assets/demo-data/images/hex-key-set.webp +0 -0
  50. package/dist/assets/demo-data/images/hex-nut.webp +0 -0
  51. package/dist/assets/demo-data/images/hi-vis-jacket.webp +0 -0
  52. package/dist/assets/demo-data/images/hi-vis-vest.webp +0 -0
  53. package/dist/assets/demo-data/images/hose-clamp.webp +0 -0
  54. package/dist/assets/demo-data/images/impact-driver.webp +0 -0
  55. package/dist/assets/demo-data/images/jigsaw.webp +0 -0
  56. package/dist/assets/demo-data/images/junction-box.webp +0 -0
  57. package/dist/assets/demo-data/images/knee-pads.webp +0 -0
  58. package/dist/assets/demo-data/images/machine-screw.webp +0 -0
  59. package/dist/assets/demo-data/images/made-to-order-configurable-chimney.webp +0 -0
  60. package/dist/assets/demo-data/images/mallet.webp +0 -0
  61. package/dist/assets/demo-data/images/mcb.webp +0 -0
  62. package/dist/assets/demo-data/images/mop.webp +0 -0
  63. package/dist/assets/demo-data/images/paper-towels.webp +0 -0
  64. package/dist/assets/demo-data/images/pipe-wrench.webp +0 -0
  65. package/dist/assets/demo-data/images/pliers-set.webp +0 -0
  66. package/dist/assets/demo-data/images/pry-bar.webp +0 -0
  67. package/dist/assets/demo-data/images/rcd.webp +0 -0
  68. package/dist/assets/demo-data/images/reciprocating-saw.webp +0 -0
  69. package/dist/assets/demo-data/images/rivet.webp +0 -0
  70. package/dist/assets/demo-data/images/roof-flashing-high-pitch.webp +0 -0
  71. package/dist/assets/demo-data/images/roof-flashing-low-pitch.webp +0 -0
  72. package/dist/assets/demo-data/images/safety-boots.webp +0 -0
  73. package/dist/assets/demo-data/images/safety-glasses.webp +0 -0
  74. package/dist/assets/demo-data/images/safety-harness.webp +0 -0
  75. package/dist/assets/demo-data/images/safety-helmet.webp +0 -0
  76. package/dist/assets/demo-data/images/safety-sign.webp +0 -0
  77. package/dist/assets/demo-data/images/sanding-disc.webp +0 -0
  78. package/dist/assets/demo-data/images/saw-blade.webp +0 -0
  79. package/dist/assets/demo-data/images/screwdriver-set.webp +0 -0
  80. package/dist/assets/demo-data/images/screwdriver.webp +0 -0
  81. package/dist/assets/demo-data/images/self-tapping-screw.webp +0 -0
  82. package/dist/assets/demo-data/images/socket-set.webp +0 -0
  83. package/dist/assets/demo-data/images/socket.webp +0 -0
  84. package/dist/assets/demo-data/images/spanner-set.webp +0 -0
  85. package/dist/assets/demo-data/images/spanner.webp +0 -0
  86. package/dist/assets/demo-data/images/spill-kit.webp +0 -0
  87. package/dist/assets/demo-data/images/spirit-level.webp +0 -0
  88. package/dist/assets/demo-data/images/switch.webp +0 -0
  89. package/dist/assets/demo-data/images/tape-measure.webp +0 -0
  90. package/dist/assets/demo-data/images/terminal-block.webp +0 -0
  91. package/dist/assets/demo-data/images/threaded-rod.webp +0 -0
  92. package/dist/assets/demo-data/images/torque-wrench.webp +0 -0
  93. package/dist/assets/demo-data/images/utility-knife.webp +0 -0
  94. package/dist/assets/demo-data/images/wall-pass-sleeve.webp +0 -0
  95. package/dist/assets/demo-data/images/wall-plug.webp +0 -0
  96. package/dist/assets/demo-data/images/washer.webp +0 -0
  97. package/dist/assets/demo-data/images/waste-bin.webp +0 -0
  98. package/dist/assets/demo-data/images/wire-connector.webp +0 -0
  99. package/dist/assets/demo-data/images/wire-cutters.webp +0 -0
  100. package/dist/assets/demo-data/images/wood-screw.webp +0 -0
  101. package/dist/assets/demo-data/images/work-gloves.webp +0 -0
  102. package/dist/assets/demo-data/images/work-light.webp +0 -0
  103. package/dist/assets/demo-data/initial-data.json +667 -0
  104. package/dist/assets/demo-data/products.csv +779 -0
  105. package/dist/assets/storefront/.env.example +14 -0
  106. package/dist/assets/storefront/.env.local +1 -0
  107. package/dist/assets/storefront/components.json +22 -0
  108. package/dist/assets/storefront/eslint.config.mjs +23 -0
  109. package/dist/assets/storefront/graphql.config.yml +2 -0
  110. package/dist/assets/storefront/messages/de.json +1196 -0
  111. package/dist/assets/storefront/messages/en.json +1196 -0
  112. package/dist/assets/storefront/next-env.d.ts +6 -0
  113. package/dist/assets/storefront/next.config.ts +73 -0
  114. package/dist/assets/storefront/package.json +77 -0
  115. package/dist/assets/storefront/postcss.config.mjs +5 -0
  116. package/dist/assets/storefront/public/next.svg +22 -0
  117. package/dist/assets/storefront/public/scenarios/b2b-wholesale/hero/hero-bg.webp +0 -0
  118. package/dist/assets/storefront/public/scenarios/b2b-wholesale/logo.svg +4 -0
  119. package/dist/assets/storefront/public/scenarios/default/logo.svg +4 -0
  120. package/dist/assets/storefront/public/scenarios/kaminpro/hero/hero-bg.webp +0 -0
  121. package/dist/assets/storefront/public/scenarios/kaminpro/logo.svg +7 -0
  122. package/dist/assets/storefront/public/vendure.svg +4 -0
  123. package/dist/assets/storefront/src/app/[locale]/(catalog)/catalog/page.tsx +65 -0
  124. package/dist/assets/storefront/src/app/[locale]/(catalog)/collection/[slug]/loading.tsx +24 -0
  125. package/dist/assets/storefront/src/app/[locale]/(catalog)/collection/[slug]/page.tsx +194 -0
  126. package/dist/assets/storefront/src/app/[locale]/(catalog)/layout.tsx +9 -0
  127. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/actions.ts +139 -0
  128. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/loading.tsx +46 -0
  129. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/page.tsx +330 -0
  130. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/actions.ts +11 -0
  131. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/loading.tsx +20 -0
  132. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/page.tsx +97 -0
  133. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-analytics-tracker.tsx +46 -0
  134. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-results.tsx +53 -0
  135. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-term.tsx +26 -0
  136. package/dist/assets/storefront/src/app/[locale]/(scenario)/[...path]/page.tsx +31 -0
  137. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/accept-invitation-client.tsx +56 -0
  138. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/actions.ts +32 -0
  139. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/page.tsx +85 -0
  140. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/sign-out-and-retry.tsx +26 -0
  141. package/dist/assets/storefront/src/app/[locale]/account/addresses/actions.ts +125 -0
  142. package/dist/assets/storefront/src/app/[locale]/account/addresses/address-form.tsx +180 -0
  143. package/dist/assets/storefront/src/app/[locale]/account/addresses/addresses-client.tsx +292 -0
  144. package/dist/assets/storefront/src/app/[locale]/account/addresses/loading.tsx +48 -0
  145. package/dist/assets/storefront/src/app/[locale]/account/addresses/page.tsx +54 -0
  146. package/dist/assets/storefront/src/app/[locale]/account/approvals/actions.ts +28 -0
  147. package/dist/assets/storefront/src/app/[locale]/account/approvals/page.tsx +340 -0
  148. package/dist/assets/storefront/src/app/[locale]/account/company/actions.ts +33 -0
  149. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/actions.ts +83 -0
  150. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/address-form.tsx +267 -0
  151. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/addresses-client.tsx +253 -0
  152. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/page.tsx +75 -0
  153. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/actions.ts +70 -0
  154. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-unit-form.tsx +153 -0
  155. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-units-client.tsx +210 -0
  156. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/page.tsx +66 -0
  157. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/types.ts +8 -0
  158. package/dist/assets/storefront/src/app/[locale]/account/company/edit-company-form.tsx +57 -0
  159. package/dist/assets/storefront/src/app/[locale]/account/company/page.tsx +89 -0
  160. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/page.tsx +65 -0
  161. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/payment-methods-client.tsx +55 -0
  162. package/dist/assets/storefront/src/app/[locale]/account/company/roles/page.tsx +66 -0
  163. package/dist/assets/storefront/src/app/[locale]/account/company/roles/roles-client.tsx +93 -0
  164. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/actions.ts +51 -0
  165. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/page.tsx +57 -0
  166. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/tax-ids-client.tsx +326 -0
  167. package/dist/assets/storefront/src/app/[locale]/account/company/users/actions.ts +74 -0
  168. package/dist/assets/storefront/src/app/[locale]/account/company/users/edit-user-form.tsx +157 -0
  169. package/dist/assets/storefront/src/app/[locale]/account/company/users/invite-user-form.tsx +133 -0
  170. package/dist/assets/storefront/src/app/[locale]/account/company/users/page.tsx +104 -0
  171. package/dist/assets/storefront/src/app/[locale]/account/company/users/users-client.tsx +266 -0
  172. package/dist/assets/storefront/src/app/[locale]/account/error.tsx +24 -0
  173. package/dist/assets/storefront/src/app/[locale]/account/layout.tsx +50 -0
  174. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/page.tsx +463 -0
  175. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-actions.ts +160 -0
  176. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-dialog.tsx +386 -0
  177. package/dist/assets/storefront/src/app/[locale]/account/orders/loading.tsx +45 -0
  178. package/dist/assets/storefront/src/app/[locale]/account/orders/page.tsx +309 -0
  179. package/dist/assets/storefront/src/app/[locale]/account/profile/actions.ts +106 -0
  180. package/dist/assets/storefront/src/app/[locale]/account/profile/change-password-form.tsx +82 -0
  181. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-email-form.tsx +88 -0
  182. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-profile-form.tsx +80 -0
  183. package/dist/assets/storefront/src/app/[locale]/account/profile/loading.tsx +54 -0
  184. package/dist/assets/storefront/src/app/[locale]/account/profile/page.tsx +44 -0
  185. package/dist/assets/storefront/src/app/[locale]/account/quick-order/actions.ts +103 -0
  186. package/dist/assets/storefront/src/app/[locale]/account/quick-order/file-upload-tab.tsx +148 -0
  187. package/dist/assets/storefront/src/app/[locale]/account/quick-order/manual-entry-tab.tsx +112 -0
  188. package/dist/assets/storefront/src/app/[locale]/account/quick-order/page.tsx +26 -0
  189. package/dist/assets/storefront/src/app/[locale]/account/quick-order/preview-table.tsx +170 -0
  190. package/dist/assets/storefront/src/app/[locale]/account/quick-order/quick-order-form.tsx +243 -0
  191. package/dist/assets/storefront/src/app/[locale]/account/quick-order/save-to-list-dialog.tsx +153 -0
  192. package/dist/assets/storefront/src/app/[locale]/account/quick-order/sku-autocomplete.tsx +118 -0
  193. package/dist/assets/storefront/src/app/[locale]/account/quick-order/text-input-tab.tsx +40 -0
  194. package/dist/assets/storefront/src/app/[locale]/account/quotes/[id]/page.tsx +260 -0
  195. package/dist/assets/storefront/src/app/[locale]/account/quotes/actions.ts +253 -0
  196. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/new-quote-form.tsx +28 -0
  197. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/page.tsx +51 -0
  198. package/dist/assets/storefront/src/app/[locale]/account/quotes/page.tsx +248 -0
  199. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/loading.tsx +44 -0
  200. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/page.tsx +51 -0
  201. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/shopping-list-detail-client.tsx +562 -0
  202. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/actions.ts +235 -0
  203. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/create-shopping-list-form.tsx +86 -0
  204. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/loading.tsx +48 -0
  205. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/page.tsx +176 -0
  206. package/dist/assets/storefront/src/app/[locale]/account/store-credits/actions.ts +31 -0
  207. package/dist/assets/storefront/src/app/[locale]/account/store-credits/claim-form.tsx +41 -0
  208. package/dist/assets/storefront/src/app/[locale]/account/store-credits/page.tsx +190 -0
  209. package/dist/assets/storefront/src/app/[locale]/account/store-credits/reveal-code.tsx +38 -0
  210. package/dist/assets/storefront/src/app/[locale]/account/verify-email/page.tsx +117 -0
  211. package/dist/assets/storefront/src/app/[locale]/cart/actions.ts +128 -0
  212. package/dist/assets/storefront/src/app/[locale]/cart/cart-items.tsx +228 -0
  213. package/dist/assets/storefront/src/app/[locale]/cart/cart-line-actions.tsx +55 -0
  214. package/dist/assets/storefront/src/app/[locale]/cart/cart-quantity-control.tsx +158 -0
  215. package/dist/assets/storefront/src/app/[locale]/cart/cart-remove-button.tsx +36 -0
  216. package/dist/assets/storefront/src/app/[locale]/cart/cart.tsx +151 -0
  217. package/dist/assets/storefront/src/app/[locale]/cart/code-input.tsx +49 -0
  218. package/dist/assets/storefront/src/app/[locale]/cart/loading.tsx +10 -0
  219. package/dist/assets/storefront/src/app/[locale]/cart/order-summary.tsx +178 -0
  220. package/dist/assets/storefront/src/app/[locale]/cart/page.tsx +33 -0
  221. package/dist/assets/storefront/src/app/[locale]/cart/promotion-code.tsx +142 -0
  222. package/dist/assets/storefront/src/app/[locale]/cart/reapproval-confirm.tsx +76 -0
  223. package/dist/assets/storefront/src/app/[locale]/cart/request-quote-button.tsx +80 -0
  224. package/dist/assets/storefront/src/app/[locale]/checkout/actions.ts +192 -0
  225. package/dist/assets/storefront/src/app/[locale]/checkout/cancel-quote-checkout-button.tsx +30 -0
  226. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-flow.tsx +214 -0
  227. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-provider.tsx +181 -0
  228. package/dist/assets/storefront/src/app/[locale]/checkout/loading.tsx +90 -0
  229. package/dist/assets/storefront/src/app/[locale]/checkout/order-summary.tsx +160 -0
  230. package/dist/assets/storefront/src/app/[locale]/checkout/page.tsx +154 -0
  231. package/dist/assets/storefront/src/app/[locale]/checkout/steps/delivery-step.tsx +107 -0
  232. package/dist/assets/storefront/src/app/[locale]/checkout/steps/payment-step.tsx +110 -0
  233. package/dist/assets/storefront/src/app/[locale]/checkout/steps/review-step.tsx +180 -0
  234. package/dist/assets/storefront/src/app/[locale]/checkout/steps/shipping-address-step.tsx +518 -0
  235. package/dist/assets/storefront/src/app/[locale]/checkout/types.ts +7 -0
  236. package/dist/assets/storefront/src/app/[locale]/error.tsx +28 -0
  237. package/dist/assets/storefront/src/app/[locale]/forgot-password/actions.ts +28 -0
  238. package/dist/assets/storefront/src/app/[locale]/forgot-password/forgot-password-form.tsx +128 -0
  239. package/dist/assets/storefront/src/app/[locale]/forgot-password/page.tsx +24 -0
  240. package/dist/assets/storefront/src/app/[locale]/globals.css +72 -0
  241. package/dist/assets/storefront/src/app/[locale]/layout.tsx +202 -0
  242. package/dist/assets/storefront/src/app/[locale]/not-found.tsx +26 -0
  243. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/order-confirmation.tsx +296 -0
  244. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/page.tsx +18 -0
  245. package/dist/assets/storefront/src/app/[locale]/page.tsx +125 -0
  246. package/dist/assets/storefront/src/app/[locale]/register/actions.ts +50 -0
  247. package/dist/assets/storefront/src/app/[locale]/register/page.tsx +82 -0
  248. package/dist/assets/storefront/src/app/[locale]/register/registration-form.tsx +237 -0
  249. package/dist/assets/storefront/src/app/[locale]/register-company/actions.ts +40 -0
  250. package/dist/assets/storefront/src/app/[locale]/register-company/page.tsx +43 -0
  251. package/dist/assets/storefront/src/app/[locale]/register-company/registration-form.tsx +48 -0
  252. package/dist/assets/storefront/src/app/[locale]/reset-password/actions.ts +40 -0
  253. package/dist/assets/storefront/src/app/[locale]/reset-password/page.tsx +32 -0
  254. package/dist/assets/storefront/src/app/[locale]/reset-password/reset-password-form.tsx +96 -0
  255. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/add-to-cart-button.tsx +31 -0
  256. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/loading.tsx +29 -0
  257. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/page.tsx +157 -0
  258. package/dist/assets/storefront/src/app/[locale]/sign-in/actions.ts +76 -0
  259. package/dist/assets/storefront/src/app/[locale]/sign-in/login-form.tsx +177 -0
  260. package/dist/assets/storefront/src/app/[locale]/sign-in/page.tsx +81 -0
  261. package/dist/assets/storefront/src/app/[locale]/verify/actions.ts +41 -0
  262. package/dist/assets/storefront/src/app/[locale]/verify/page.tsx +40 -0
  263. package/dist/assets/storefront/src/app/[locale]/verify/verify-content.tsx +127 -0
  264. package/dist/assets/storefront/src/app/[locale]/verify-pending/page.tsx +67 -0
  265. package/dist/assets/storefront/src/app/api/clear-company-context/route.ts +26 -0
  266. package/dist/assets/storefront/src/app/api/draft/disable/route.ts +12 -0
  267. package/dist/assets/storefront/src/app/api/draft/route.ts +17 -0
  268. package/dist/assets/storefront/src/app/api/revalidate/route.ts +110 -0
  269. package/dist/assets/storefront/src/app/api/search-analytics/route.ts +16 -0
  270. package/dist/assets/storefront/src/app/favicon.ico +0 -0
  271. package/dist/assets/storefront/src/components/commerce/account-nav-items.ts +56 -0
  272. package/dist/assets/storefront/src/components/commerce/account-sidebar.tsx +112 -0
  273. package/dist/assets/storefront/src/components/commerce/active-filters.tsx +107 -0
  274. package/dist/assets/storefront/src/components/commerce/approval-decision-form.tsx +70 -0
  275. package/dist/assets/storefront/src/components/commerce/approval-status-badge.tsx +37 -0
  276. package/dist/assets/storefront/src/components/commerce/business-unit-switcher.tsx +56 -0
  277. package/dist/assets/storefront/src/components/commerce/catalog-search-bar.tsx +83 -0
  278. package/dist/assets/storefront/src/components/commerce/category-product-section.tsx +69 -0
  279. package/dist/assets/storefront/src/components/commerce/category-sidebar.tsx +133 -0
  280. package/dist/assets/storefront/src/components/commerce/collection-hero-banner.tsx +36 -0
  281. package/dist/assets/storefront/src/components/commerce/company-state-badge.tsx +32 -0
  282. package/dist/assets/storefront/src/components/commerce/company-switcher.tsx +58 -0
  283. package/dist/assets/storefront/src/components/commerce/configurator-form.tsx +606 -0
  284. package/dist/assets/storefront/src/components/commerce/facet-filters.tsx +286 -0
  285. package/dist/assets/storefront/src/components/commerce/gift-card-pdp.tsx +43 -0
  286. package/dist/assets/storefront/src/components/commerce/gift-card-product-info.tsx +137 -0
  287. package/dist/assets/storefront/src/components/commerce/highlighted-text.tsx +30 -0
  288. package/dist/assets/storefront/src/components/commerce/instant-search-dropdown.tsx +377 -0
  289. package/dist/assets/storefront/src/components/commerce/order-status-badge.tsx +41 -0
  290. package/dist/assets/storefront/src/components/commerce/packaging-unit-selector.tsx +146 -0
  291. package/dist/assets/storefront/src/components/commerce/permission-gate.tsx +20 -0
  292. package/dist/assets/storefront/src/components/commerce/price-range-filter.tsx +111 -0
  293. package/dist/assets/storefront/src/components/commerce/price-tiers.tsx +98 -0
  294. package/dist/assets/storefront/src/components/commerce/price.tsx +29 -0
  295. package/dist/assets/storefront/src/components/commerce/product-card-list.tsx +121 -0
  296. package/dist/assets/storefront/src/components/commerce/product-card.tsx +89 -0
  297. package/dist/assets/storefront/src/components/commerce/product-carousel.tsx +42 -0
  298. package/dist/assets/storefront/src/components/commerce/product-grid.tsx +54 -0
  299. package/dist/assets/storefront/src/components/commerce/product-image-carousel.tsx +127 -0
  300. package/dist/assets/storefront/src/components/commerce/product-info.tsx +525 -0
  301. package/dist/assets/storefront/src/components/commerce/product-list-expansion.tsx +393 -0
  302. package/dist/assets/storefront/src/components/commerce/product-list-view.tsx +34 -0
  303. package/dist/assets/storefront/src/components/commerce/product-sidebar.tsx +175 -0
  304. package/dist/assets/storefront/src/components/commerce/product-view-switcher.tsx +107 -0
  305. package/dist/assets/storefront/src/components/commerce/quote-action-buttons.tsx +235 -0
  306. package/dist/assets/storefront/src/components/commerce/quote-activity-timeline.tsx +320 -0
  307. package/dist/assets/storefront/src/components/commerce/quote-comment-form.tsx +52 -0
  308. package/dist/assets/storefront/src/components/commerce/quote-csv-export-button.tsx +97 -0
  309. package/dist/assets/storefront/src/components/commerce/quote-product-search.tsx +139 -0
  310. package/dist/assets/storefront/src/components/commerce/quote-request-form.tsx +252 -0
  311. package/dist/assets/storefront/src/components/commerce/quote-status-badge.tsx +41 -0
  312. package/dist/assets/storefront/src/components/commerce/quote-validity-indicator.tsx +33 -0
  313. package/dist/assets/storefront/src/components/commerce/quote-version-comparison.tsx +88 -0
  314. package/dist/assets/storefront/src/components/commerce/related-products.tsx +56 -0
  315. package/dist/assets/storefront/src/components/commerce/shop-by-category.tsx +59 -0
  316. package/dist/assets/storefront/src/components/commerce/shopping-list-toggle.tsx +158 -0
  317. package/dist/assets/storefront/src/components/commerce/sort-dropdown.tsx +51 -0
  318. package/dist/assets/storefront/src/components/commerce/store-credit-summary.tsx +45 -0
  319. package/dist/assets/storefront/src/components/commerce/subcollection-tiles.tsx +56 -0
  320. package/dist/assets/storefront/src/components/layout/auth-page-shell.tsx +15 -0
  321. package/dist/assets/storefront/src/components/layout/draft-mode-action.ts +8 -0
  322. package/dist/assets/storefront/src/components/layout/draft-mode-indicator.tsx +54 -0
  323. package/dist/assets/storefront/src/components/layout/draft-mode-link.tsx +29 -0
  324. package/dist/assets/storefront/src/components/layout/footer.tsx +168 -0
  325. package/dist/assets/storefront/src/components/layout/navbar/actions.ts +33 -0
  326. package/dist/assets/storefront/src/components/layout/navbar/cart-icon.tsx +50 -0
  327. package/dist/assets/storefront/src/components/layout/navbar/channel-picker-wrapper.tsx +19 -0
  328. package/dist/assets/storefront/src/components/layout/navbar/channel-picker.tsx +53 -0
  329. package/dist/assets/storefront/src/components/layout/navbar/currency-picker-wrapper.tsx +21 -0
  330. package/dist/assets/storefront/src/components/layout/navbar/currency-picker.tsx +52 -0
  331. package/dist/assets/storefront/src/components/layout/navbar/language-picker.tsx +51 -0
  332. package/dist/assets/storefront/src/components/layout/navbar/login-button.tsx +34 -0
  333. package/dist/assets/storefront/src/components/layout/navbar/mobile-nav.tsx +74 -0
  334. package/dist/assets/storefront/src/components/layout/navbar/nav-menu-items.tsx +51 -0
  335. package/dist/assets/storefront/src/components/layout/navbar/navbar-cart.tsx +5 -0
  336. package/dist/assets/storefront/src/components/layout/navbar/navbar-collections.tsx +291 -0
  337. package/dist/assets/storefront/src/components/layout/navbar/navbar-link.tsx +28 -0
  338. package/dist/assets/storefront/src/components/layout/navbar/navbar-user.tsx +147 -0
  339. package/dist/assets/storefront/src/components/layout/navbar/theme-switcher.tsx +39 -0
  340. package/dist/assets/storefront/src/components/layout/navbar.tsx +117 -0
  341. package/dist/assets/storefront/src/components/layout/search-input.tsx +71 -0
  342. package/dist/assets/storefront/src/components/providers/awaiting-approval-banner.tsx +58 -0
  343. package/dist/assets/storefront/src/components/providers/cart-count-server.tsx +31 -0
  344. package/dist/assets/storefront/src/components/providers/company-context-guard.tsx +47 -0
  345. package/dist/assets/storefront/src/components/providers/company-permissions-server.tsx +14 -0
  346. package/dist/assets/storefront/src/components/providers/theme-provider.tsx +16 -0
  347. package/dist/assets/storefront/src/components/shared/breadcrumbs.tsx +39 -0
  348. package/dist/assets/storefront/src/components/shared/catalog-sidebar-skeleton.tsx +21 -0
  349. package/dist/assets/storefront/src/components/shared/country-select.tsx +83 -0
  350. package/dist/assets/storefront/src/components/shared/error-state.tsx +16 -0
  351. package/dist/assets/storefront/src/components/shared/pagination.tsx +119 -0
  352. package/dist/assets/storefront/src/components/shared/prefetch-link.tsx +36 -0
  353. package/dist/assets/storefront/src/components/shared/product-grid-skeleton.tsx +26 -0
  354. package/dist/assets/storefront/src/components/shared/scenario-paused.tsx +80 -0
  355. package/dist/assets/storefront/src/components/shared/skeletons/cart-skeleton.tsx +48 -0
  356. package/dist/assets/storefront/src/components/shared/skeletons/navbar-user-skeleton.tsx +9 -0
  357. package/dist/assets/storefront/src/components/shared/skeletons/search-input-skeleton.tsx +7 -0
  358. package/dist/assets/storefront/src/components/shared/skeletons/search-results-skeleton.tsx +17 -0
  359. package/dist/assets/storefront/src/components/ui/accordion.tsx +66 -0
  360. package/dist/assets/storefront/src/components/ui/alert-dialog.tsx +157 -0
  361. package/dist/assets/storefront/src/components/ui/alert.tsx +66 -0
  362. package/dist/assets/storefront/src/components/ui/aspect-ratio.tsx +11 -0
  363. package/dist/assets/storefront/src/components/ui/avatar.tsx +53 -0
  364. package/dist/assets/storefront/src/components/ui/badge.tsx +46 -0
  365. package/dist/assets/storefront/src/components/ui/breadcrumb.tsx +109 -0
  366. package/dist/assets/storefront/src/components/ui/button.tsx +58 -0
  367. package/dist/assets/storefront/src/components/ui/calendar.tsx +213 -0
  368. package/dist/assets/storefront/src/components/ui/card.tsx +92 -0
  369. package/dist/assets/storefront/src/components/ui/carousel.tsx +241 -0
  370. package/dist/assets/storefront/src/components/ui/chart.tsx +357 -0
  371. package/dist/assets/storefront/src/components/ui/checkbox.tsx +32 -0
  372. package/dist/assets/storefront/src/components/ui/collapsible.tsx +33 -0
  373. package/dist/assets/storefront/src/components/ui/command.tsx +184 -0
  374. package/dist/assets/storefront/src/components/ui/context-menu.tsx +252 -0
  375. package/dist/assets/storefront/src/components/ui/dialog.tsx +143 -0
  376. package/dist/assets/storefront/src/components/ui/drawer.tsx +135 -0
  377. package/dist/assets/storefront/src/components/ui/dropdown-menu.tsx +257 -0
  378. package/dist/assets/storefront/src/components/ui/empty-state.tsx +37 -0
  379. package/dist/assets/storefront/src/components/ui/field.tsx +244 -0
  380. package/dist/assets/storefront/src/components/ui/form.tsx +167 -0
  381. package/dist/assets/storefront/src/components/ui/hover-card.tsx +44 -0
  382. package/dist/assets/storefront/src/components/ui/input-otp.tsx +77 -0
  383. package/dist/assets/storefront/src/components/ui/input.tsx +21 -0
  384. package/dist/assets/storefront/src/components/ui/kbd-shortcut.tsx +20 -0
  385. package/dist/assets/storefront/src/components/ui/label.tsx +24 -0
  386. package/dist/assets/storefront/src/components/ui/menubar.tsx +276 -0
  387. package/dist/assets/storefront/src/components/ui/navigation-menu.tsx +168 -0
  388. package/dist/assets/storefront/src/components/ui/pagination.tsx +127 -0
  389. package/dist/assets/storefront/src/components/ui/popover.tsx +48 -0
  390. package/dist/assets/storefront/src/components/ui/progress.tsx +31 -0
  391. package/dist/assets/storefront/src/components/ui/radio-group.tsx +45 -0
  392. package/dist/assets/storefront/src/components/ui/resizable.tsx +56 -0
  393. package/dist/assets/storefront/src/components/ui/scroll-area.tsx +58 -0
  394. package/dist/assets/storefront/src/components/ui/select.tsx +185 -0
  395. package/dist/assets/storefront/src/components/ui/separator.tsx +28 -0
  396. package/dist/assets/storefront/src/components/ui/sheet.tsx +139 -0
  397. package/dist/assets/storefront/src/components/ui/sidebar.tsx +728 -0
  398. package/dist/assets/storefront/src/components/ui/skeleton.tsx +13 -0
  399. package/dist/assets/storefront/src/components/ui/slider.tsx +63 -0
  400. package/dist/assets/storefront/src/components/ui/sonner.tsx +25 -0
  401. package/dist/assets/storefront/src/components/ui/switch.tsx +31 -0
  402. package/dist/assets/storefront/src/components/ui/table.tsx +116 -0
  403. package/dist/assets/storefront/src/components/ui/tabs.tsx +66 -0
  404. package/dist/assets/storefront/src/components/ui/textarea.tsx +18 -0
  405. package/dist/assets/storefront/src/components/ui/toggle-group.tsx +73 -0
  406. package/dist/assets/storefront/src/components/ui/toggle.tsx +47 -0
  407. package/dist/assets/storefront/src/components/ui/tooltip.tsx +61 -0
  408. package/dist/assets/storefront/src/config/branding.ts +4 -0
  409. package/dist/assets/storefront/src/config/scenario-meta.ts +46 -0
  410. package/dist/assets/storefront/src/config/scenario.ts +313 -0
  411. package/dist/assets/storefront/src/contexts/auth-context.tsx +35 -0
  412. package/dist/assets/storefront/src/graphql.ts +14 -0
  413. package/dist/assets/storefront/src/hooks/use-mobile.ts +19 -0
  414. package/dist/assets/storefront/src/i18n/locale-utils.ts +33 -0
  415. package/dist/assets/storefront/src/i18n/locales.ts +18 -0
  416. package/dist/assets/storefront/src/i18n/navigation.ts +35 -0
  417. package/dist/assets/storefront/src/i18n/request.ts +19 -0
  418. package/dist/assets/storefront/src/i18n/routing.ts +19 -0
  419. package/dist/assets/storefront/src/i18n/server.ts +16 -0
  420. package/dist/assets/storefront/src/lib/actions/switch-channel.ts +32 -0
  421. package/dist/assets/storefront/src/lib/actions/switch-currency.ts +25 -0
  422. package/dist/assets/storefront/src/lib/auth.ts +18 -0
  423. package/dist/assets/storefront/src/lib/backend-health.ts +38 -0
  424. package/dist/assets/storefront/src/lib/cart-count-context.tsx +59 -0
  425. package/dist/assets/storefront/src/lib/cart-guard-utils.ts +10 -0
  426. package/dist/assets/storefront/src/lib/cart-guard.ts +104 -0
  427. package/dist/assets/storefront/src/lib/channel-server.ts +28 -0
  428. package/dist/assets/storefront/src/lib/channel.ts +2 -0
  429. package/dist/assets/storefront/src/lib/company-context.ts +35 -0
  430. package/dist/assets/storefront/src/lib/company-permissions-context.tsx +40 -0
  431. package/dist/assets/storefront/src/lib/currency-server.ts +20 -0
  432. package/dist/assets/storefront/src/lib/currency.ts +2 -0
  433. package/dist/assets/storefront/src/lib/format.ts +48 -0
  434. package/dist/assets/storefront/src/lib/metadata.ts +85 -0
  435. package/dist/assets/storefront/src/lib/quantity.test.js +20 -0
  436. package/dist/assets/storefront/src/lib/quantity.ts +20 -0
  437. package/dist/assets/storefront/src/lib/search-bar-context.tsx +45 -0
  438. package/dist/assets/storefront/src/lib/search-helpers.ts +69 -0
  439. package/dist/assets/storefront/src/lib/use-recent-searches.ts +55 -0
  440. package/dist/assets/storefront/src/lib/utils.ts +6 -0
  441. package/dist/assets/storefront/src/lib/vendure/actions.ts +96 -0
  442. package/dist/assets/storefront/src/lib/vendure/api.ts +164 -0
  443. package/dist/assets/storefront/src/lib/vendure/approval-utils.ts +21 -0
  444. package/dist/assets/storefront/src/lib/vendure/cached.ts +71 -0
  445. package/dist/assets/storefront/src/lib/vendure/fragments.ts +213 -0
  446. package/dist/assets/storefront/src/lib/vendure/instant-search-action.ts +104 -0
  447. package/dist/assets/storefront/src/lib/vendure/mutations.ts +1136 -0
  448. package/dist/assets/storefront/src/lib/vendure/queries.ts +1406 -0
  449. package/dist/assets/storefront/src/middleware.ts +11 -0
  450. package/dist/assets/storefront/src/scenarios/b2b-wholesale/branding.ts +180 -0
  451. package/dist/assets/storefront/src/scenarios/b2b-wholesale/hero.tsx +122 -0
  452. package/dist/assets/storefront/src/scenarios/b2b-wholesale/index.ts +21 -0
  453. package/dist/assets/storefront/src/scenarios/b2b-wholesale/meta.ts +3 -0
  454. package/dist/assets/storefront/src/scenarios/default/branding.ts +148 -0
  455. package/dist/assets/storefront/src/scenarios/default/hero.tsx +107 -0
  456. package/dist/assets/storefront/src/scenarios/default/index.ts +12 -0
  457. package/dist/assets/storefront/src/scenarios/default/meta.ts +3 -0
  458. package/dist/assets/storefront/src/scenarios/kaminpro/auth-gate.tsx +36 -0
  459. package/dist/assets/storefront/src/scenarios/kaminpro/branding.ts +238 -0
  460. package/dist/assets/storefront/src/scenarios/kaminpro/cart-items.tsx +359 -0
  461. package/dist/assets/storefront/src/scenarios/kaminpro/hero.tsx +123 -0
  462. package/dist/assets/storefront/src/scenarios/kaminpro/index.ts +50 -0
  463. package/dist/assets/storefront/src/scenarios/kaminpro/meta.ts +9 -0
  464. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/banners.tsx +21 -0
  465. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/bom-basket.tsx +221 -0
  466. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/btn.tsx +38 -0
  467. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/chip.tsx +35 -0
  468. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/config-header.tsx +72 -0
  469. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/field-row.tsx +126 -0
  470. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/info-dot.tsx +38 -0
  471. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/login-notice.tsx +81 -0
  472. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/module-panel.tsx +144 -0
  473. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/quote-dialog.tsx +110 -0
  474. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/schematic.tsx +674 -0
  475. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/components/why-panel.tsx +66 -0
  476. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/configurator-pdp.tsx +43 -0
  477. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/configurator-shell.tsx +320 -0
  478. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/lib/data.ts +150 -0
  479. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/lib/types.ts +30 -0
  480. package/dist/assets/storefront/src/scenarios/kaminpro/pdp/styles.css +104 -0
  481. package/dist/assets/storefront/src/scenarios/kaminpro/shop-by-system.tsx +97 -0
  482. package/dist/assets/storefront/src/scenarios/kaminpro/system-finder/decision-tree.ts +261 -0
  483. package/dist/assets/storefront/src/scenarios/kaminpro/system-finder/page.tsx +21 -0
  484. package/dist/assets/storefront/src/scenarios/kaminpro/system-finder/wizard.tsx +600 -0
  485. package/dist/assets/storefront/src/schema.graphql.placeholder +5 -0
  486. package/dist/assets/storefront/tsconfig.json +37 -0
  487. package/dist/assets/templates/CLAUDE.md.hbs +63 -0
  488. package/dist/assets/templates/README.md.hbs +53 -0
  489. package/dist/assets/templates/custom-populate.ts.hbs +28 -0
  490. package/dist/assets/templates/docker-compose.yml.hbs +29 -0
  491. package/dist/assets/templates/env.hbs +44 -0
  492. package/dist/assets/templates/environment.d.ts.hbs +32 -0
  493. package/dist/assets/templates/gitignore.hbs +7 -0
  494. package/dist/assets/templates/index.ts.hbs +16 -0
  495. package/dist/assets/templates/npmrc.hbs +1 -0
  496. package/dist/assets/templates/populate.ts.hbs +27 -0
  497. package/dist/assets/templates/root-package.json.hbs +17 -0
  498. package/dist/assets/templates/server-package.json.hbs +31 -0
  499. package/dist/assets/templates/tsconfig.dashboard.json.hbs +17 -0
  500. package/dist/assets/templates/tsconfig.root.json.hbs +16 -0
  501. package/dist/assets/templates/tsconfig.server.json.hbs +20 -0
  502. package/dist/assets/templates/vendure-config.ts.hbs +80 -0
  503. package/dist/assets/templates/vite.config.mts.hbs +27 -0
  504. package/dist/bin/run.d.ts +2 -0
  505. package/dist/bin/run.js +79 -0
  506. package/dist/bin/run.js.map +1 -0
  507. package/dist/cli.d.ts +6 -0
  508. package/dist/cli.js +154 -0
  509. package/dist/cli.js.map +1 -0
  510. package/dist/git-init.d.ts +4 -0
  511. package/dist/git-init.js +60 -0
  512. package/dist/git-init.js.map +1 -0
  513. package/dist/index.d.ts +4 -0
  514. package/dist/index.js +13 -0
  515. package/dist/index.js.map +1 -0
  516. package/dist/plugin-registry.d.ts +10 -0
  517. package/dist/plugin-registry.js +485 -0
  518. package/dist/plugin-registry.js.map +1 -0
  519. package/dist/scaffolder.d.ts +10 -0
  520. package/dist/scaffolder.js +218 -0
  521. package/dist/scaffolder.js.map +1 -0
  522. package/dist/storefront-copier.d.ts +6 -0
  523. package/dist/storefront-copier.js +68 -0
  524. package/dist/storefront-copier.js.map +1 -0
  525. package/dist/template-renderer.d.ts +30 -0
  526. package/dist/template-renderer.js +177 -0
  527. package/dist/template-renderer.js.map +1 -0
  528. package/dist/types.d.ts +60 -0
  529. package/dist/types.js +3 -0
  530. package/dist/types.js.map +1 -0
  531. package/package.json +48 -0
@@ -0,0 +1,66 @@
1
+ 'use client';
2
+
3
+ import type { EvaluatedExecutedRule } from '../lib/types';
4
+
5
+ interface WhyPanelProps {
6
+ executedRules: EvaluatedExecutedRule[];
7
+ open: boolean;
8
+ onToggle: () => void;
9
+ }
10
+
11
+ export function WhyPanel({ executedRules, open, onToggle }: WhyPanelProps) {
12
+ const matched = executedRules.filter(r => r.matched);
13
+ const skipped = executedRules.filter(r => !r.matched);
14
+
15
+ return (
16
+ <div className="border-t border-[color:var(--line)] bg-[color:var(--panel)] shrink-0">
17
+ <button
18
+ type="button"
19
+ onClick={onToggle}
20
+ className="w-full px-6 h-10 flex items-center gap-2 text-left hover:bg-[color:var(--panel-2)]"
21
+ >
22
+ <span className="caps text-[color:var(--muted)]">Warum diese Teile?</span>
23
+ <span className="mono text-[10px] text-[color:var(--muted-2)]">{matched.length} Regeln angewendet</span>
24
+ <span className="ml-auto mono text-[11px] text-[color:var(--muted)]">{open ? '−' : '+'}</span>
25
+ </button>
26
+ {open && (
27
+ <div className="px-6 pb-4 max-h-[180px] overflow-y-auto scroll-slim">
28
+ <div className="grid grid-cols-2 gap-4">
29
+ <div>
30
+ <div className="caps text-[color:var(--muted-2)] mb-2">Angewendet</div>
31
+ <div className="space-y-1">
32
+ {matched.length === 0 && <div className="mono text-[11px] text-[color:var(--muted-2)]">— keine —</div>}
33
+ {matched.map(r => (
34
+ <div key={r.ruleId} className="flex items-start gap-2">
35
+ <span className="mono text-[10px] text-[#a3e635] mt-0.5">●</span>
36
+ <div className="flex-1 min-w-0">
37
+ <div className="mono text-[11px] text-[color:var(--ink)]">{r.ruleName}</div>
38
+ <div className="mono text-[10px] text-[color:var(--muted-2)]">{r.phaseKey}</div>
39
+ </div>
40
+ </div>
41
+ ))}
42
+ </div>
43
+ </div>
44
+ <div>
45
+ <div className="caps text-[color:var(--muted-2)] mb-2">Übersprungen</div>
46
+ <div className="space-y-1">
47
+ {skipped.length === 0 && <div className="mono text-[11px] text-[color:var(--muted-2)]">— keine —</div>}
48
+ {skipped.map(r => (
49
+ <div key={r.ruleId} className="flex items-start gap-2">
50
+ <span className="mono text-[10px] text-[color:var(--muted-2)] mt-0.5">○</span>
51
+ <div className="flex-1 min-w-0">
52
+ <div className="mono text-[11px] text-[color:var(--muted)]">{r.ruleName}</div>
53
+ {r.skipReason && (
54
+ <div className="mono text-[10px] text-[color:var(--muted-2)]">{r.skipReason}</div>
55
+ )}
56
+ </div>
57
+ </div>
58
+ ))}
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ )}
64
+ </div>
65
+ );
66
+ }
@@ -0,0 +1,43 @@
1
+ import type { PdpPageProps } from '@/config/scenario';
2
+ import {
3
+ addConfigurationToOrder,
4
+ evaluateConfiguration,
5
+ } from '@/app/[locale]/(catalog)/product/[slug]/actions';
6
+ import { AuthGate } from '../auth-gate';
7
+ import { ConfiguratorShell } from './configurator-shell';
8
+
9
+ /**
10
+ * KaminPro configurator PDP — scenario-level full-page override.
11
+ *
12
+ * Only engages for configurable products (gated by `shouldApply` in the
13
+ * scenario config). Unauthenticated visitors hit the shared `AuthGate`
14
+ * which renders the LoginNotice; authenticated partners see the three-
15
+ * column configurator shell driven by the live `ConfiguratorSystem`
16
+ * fetched in the host `page.tsx`.
17
+ *
18
+ * The host page.tsx is responsible for rendering the breadcrumb row; this
19
+ * override only contributes the main content area.
20
+ */
21
+ export async function KaminProConfiguratorPdp({ product, configuratorSystem }: PdpPageProps) {
22
+ // Belt-and-braces — the `shouldApply` predicate on the scenario override
23
+ // means we should never reach this override without a system. Fall back
24
+ // gracefully rather than crashing.
25
+ if (!configuratorSystem) {
26
+ return (
27
+ <div className="container mx-auto px-4 py-12 text-sm text-muted-foreground">
28
+ Konfigurator nicht verfügbar.
29
+ </div>
30
+ );
31
+ }
32
+
33
+ return (
34
+ <AuthGate>
35
+ <ConfiguratorShell
36
+ system={configuratorSystem}
37
+ initialConfigName={`Konfiguration — ${product.name}`}
38
+ evaluateAction={evaluateConfiguration}
39
+ addToOrderAction={addConfigurationToOrder}
40
+ />
41
+ </AuthGate>
42
+ );
43
+ }
@@ -0,0 +1,320 @@
1
+ 'use client';
2
+
3
+ import { cn } from '@/lib/utils';
4
+ import { useRouter } from '@/i18n/navigation';
5
+ import { isRedirectError } from 'next/dist/client/components/redirect-error';
6
+ import { toast } from 'sonner';
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ import { requestQuoteWithItems } from '@/app/[locale]/account/quotes/actions';
9
+ import './styles.css';
10
+
11
+ import { buildFieldRef, fmtEuro } from './lib/data';
12
+ import type {
13
+ ConfigurationEvaluation,
14
+ ConfiguratorSystem,
15
+ Values,
16
+ } from './lib/types';
17
+
18
+ import { BomBasket, type CtaAction } from './components/bom-basket';
19
+ import { WarnBanner } from './components/banners';
20
+ import { Chip } from './components/chip';
21
+ import { ConfigHeader } from './components/config-header';
22
+ import { ModulePanel } from './components/module-panel';
23
+ import { QuoteDialog } from './components/quote-dialog';
24
+ import { Schematic } from './components/schematic';
25
+ import { WhyPanel } from './components/why-panel';
26
+
27
+ type EvaluateAction = (
28
+ systemId: string,
29
+ values: { fieldRef: string; value: string }[],
30
+ ) => Promise<{ data?: ConfigurationEvaluation; error?: string }>;
31
+
32
+ type AddToOrderAction = (
33
+ systemId: string,
34
+ values: { fieldRef: string; value: string }[],
35
+ name?: string,
36
+ ) => Promise<{ success: boolean; error?: string }>;
37
+
38
+ interface ConfiguratorShellProps {
39
+ system: ConfiguratorSystem;
40
+ initialConfigName?: string;
41
+ evaluateAction: EvaluateAction;
42
+ addToOrderAction: AddToOrderAction;
43
+ }
44
+
45
+ export function ConfiguratorShell({
46
+ system,
47
+ initialConfigName = 'Neue Konfiguration',
48
+ evaluateAction,
49
+ addToOrderAction,
50
+ }: ConfiguratorShellProps) {
51
+ // Seed values from the backend field defaults so the first-render state
52
+ // is complete and the schematic/BOM populate immediately.
53
+ const [values, setValues] = useState<Values>(() => {
54
+ const initial: Values = {};
55
+ for (const mod of system.modules) {
56
+ for (const field of mod.fields) {
57
+ if (field.defaultValue) {
58
+ initial[buildFieldRef(mod.code, field.code)] = field.defaultValue;
59
+ }
60
+ }
61
+ }
62
+ return initial;
63
+ });
64
+
65
+ const [configName, setConfigName] = useState(initialConfigName);
66
+ const [activeModuleId, setActiveModuleId] = useState(system.modules[0]?.code ?? '');
67
+ const [whyOpen, setWhyOpen] = useState(false);
68
+ const [warnDismissed, setWarnDismissed] = useState(false);
69
+ // Collapsible module panel — when collapsed the schematic column claims
70
+ // the freed width and the SVG scales up proportionally (meet-fit).
71
+ const [panelCollapsed, setPanelCollapsed] = useState(false);
72
+
73
+ const [evaluation, setEvaluation] = useState<ConfigurationEvaluation | null>(null);
74
+ const [isEvaluating, setIsEvaluating] = useState(false);
75
+ const [cartState, setCartState] = useState<'idle' | 'adding' | 'added'>('idle');
76
+ const [quoteState, setQuoteState] = useState<'idle' | 'saving'>('idle');
77
+ const [quoteDialogOpen, setQuoteDialogOpen] = useState(false);
78
+ const evalTimer = useRef<ReturnType<typeof setTimeout>>(undefined);
79
+ const router = useRouter();
80
+
81
+ const fieldValueEntries = useCallback(() => {
82
+ return Object.entries(values)
83
+ .filter(([, v]) => v !== '')
84
+ .map(([fieldRef, value]) => ({ fieldRef, value }));
85
+ }, [values]);
86
+
87
+ // 300ms debounced evaluate — mirrors the generic ConfiguratorForm pattern.
88
+ useEffect(() => {
89
+ clearTimeout(evalTimer.current);
90
+ evalTimer.current = setTimeout(async () => {
91
+ const entries = fieldValueEntries();
92
+ if (entries.length === 0) return;
93
+ setIsEvaluating(true);
94
+ const result = await evaluateAction(system.id, entries);
95
+ setIsEvaluating(false);
96
+ if (result.data) setEvaluation(result.data);
97
+ if (result.error) toast.error(result.error);
98
+ }, 300);
99
+ return () => clearTimeout(evalTimer.current);
100
+ }, [values, system.id, evaluateAction, fieldValueEntries]);
101
+
102
+ const handleFieldChange = (moduleCode: string, fieldCode: string, value: string) => {
103
+ setValues(prev => ({ ...prev, [buildFieldRef(moduleCode, fieldCode)]: value }));
104
+ };
105
+
106
+ // Aggregate errors: system-level + per-field error messages.
107
+ const { errorCount, warnCount, allErrors } = useMemo(() => {
108
+ const sys = evaluation?.errors ?? [];
109
+ const fieldIssues: { fieldName: string; message: string; type: string }[] = [];
110
+ for (const mod of system.modules) {
111
+ for (const field of mod.fields) {
112
+ const ref = buildFieldRef(mod.code, field.code);
113
+ const ef = evaluation?.fields.find(f => f.fieldRef === ref);
114
+ if (ef?.hidden) continue;
115
+ for (const msg of ef?.messages ?? []) {
116
+ if (msg.type === 'error' || msg.type === 'warning') {
117
+ fieldIssues.push({ fieldName: field.name, message: msg.message, type: msg.type });
118
+ }
119
+ }
120
+ }
121
+ }
122
+ const errs = [...sys.map(e => e.message), ...fieldIssues.filter(i => i.type === 'error').map(i => `${i.fieldName}: ${i.message}`)];
123
+ return {
124
+ errorCount: errs.length,
125
+ warnCount: fieldIssues.filter(i => i.type === 'warning').length,
126
+ allErrors: errs,
127
+ };
128
+ }, [evaluation, system.modules]);
129
+
130
+ const lines = evaluation?.lines ?? [];
131
+
132
+ const handleCta = async (action: CtaAction) => {
133
+ if (action === 'cart') {
134
+ setCartState('adding');
135
+ const entries = fieldValueEntries();
136
+ const result = await addToOrderAction(system.id, entries, configName);
137
+ if (result.success) {
138
+ const total = lines.reduce(
139
+ (s, l) => s + l.productVariant.priceWithTax * l.quantity,
140
+ 0,
141
+ ) / 100;
142
+ setCartState('added');
143
+ toast.success('In den Warenkorb gelegt', {
144
+ description: `${configName} · ${evaluation?.totals.lineCount ?? 0} Positionen · ${fmtEuro(total)}`,
145
+ duration: 6000,
146
+ action: {
147
+ label: 'Zur Kasse',
148
+ onClick: () => router.push('/checkout'),
149
+ },
150
+ });
151
+ // Refresh server components so the nav cart-count updates
152
+ // immediately, and reset the CTA back to idle after the
153
+ // user has had time to see the confirmation.
154
+ router.refresh();
155
+ window.setTimeout(() => setCartState('idle'), 2500);
156
+ } else {
157
+ setCartState('idle');
158
+ toast.error(result.error || 'Konnte Konfiguration nicht in den Warenkorb legen');
159
+ }
160
+ } else if (action === 'quote') {
161
+ if (lines.length === 0) return;
162
+ setQuoteDialogOpen(true);
163
+ }
164
+ };
165
+
166
+ const handleQuoteSubmit = async (userMessage: string) => {
167
+ if (lines.length === 0) return;
168
+ setQuoteState('saving');
169
+ // Each evaluated BOM line becomes a quote line item. The note
170
+ // combines the configuration name (for the /account/quotes list
171
+ // view) with the partner's free-text message (their discount
172
+ // request, liefertermin, etc.) so the account manager sees both.
173
+ const lineItems = lines.map(l => ({
174
+ productVariantId: l.productVariant.id,
175
+ quantity: l.quantity,
176
+ }));
177
+ const note = userMessage
178
+ ? `${configName}\n\n${userMessage}`
179
+ : configName;
180
+ try {
181
+ const result = await requestQuoteWithItems(lineItems, note);
182
+ // Reached only on failure — success path redirects to
183
+ // /account/quotes/<id> and never returns.
184
+ if (result && !result.success) {
185
+ setQuoteState('idle');
186
+ toast.error(result.message || 'Konnte Angebot nicht speichern');
187
+ }
188
+ } catch (err) {
189
+ if (isRedirectError(err)) throw err;
190
+ setQuoteState('idle');
191
+ toast.error('Konnte Angebot nicht speichern');
192
+ }
193
+ };
194
+
195
+ const totalPriceCents = lines.reduce(
196
+ (s, l) => s + l.productVariant.priceWithTax * l.quantity,
197
+ 0,
198
+ );
199
+
200
+ const rightChip = (
201
+ <>
202
+ {errorCount > 0 && <Chip tone="err">{errorCount} Fehler</Chip>}
203
+ {warnCount > 0 && <Chip tone="warn">{warnCount} Warnung</Chip>}
204
+ {isEvaluating ? (
205
+ <span className="mono text-[10.5px] text-[color:var(--muted)] flex items-center gap-1.5">
206
+ <span className="w-1.5 h-1.5 rounded-full bg-[color:var(--fire)] pulse-dot" />
207
+ Berechne…
208
+ </span>
209
+ ) : (
210
+ <span className="mono text-[10.5px] text-[color:var(--muted-2)]">Aktualisiert · gerade eben</span>
211
+ )}
212
+ </>
213
+ );
214
+
215
+ return (
216
+ <div className="kp-pdp flex-1 h-[calc(100vh-var(--page-top-offset)-90px)] flex flex-col overflow-hidden">
217
+ <ConfigHeader
218
+ systemName={system.name}
219
+ systemSub={system.description ?? ''}
220
+ configName={configName}
221
+ onRename={setConfigName}
222
+ rightChip={rightChip}
223
+ />
224
+
225
+ {warnCount > 0 && !warnDismissed && (
226
+ <WarnBanner count={warnCount} onDismiss={() => setWarnDismissed(true)} />
227
+ )}
228
+
229
+ {allErrors.length > 0 && (
230
+ <div className="px-6 py-2 bg-[#2a0a0a] border-b border-[#4a1818] flex flex-col gap-1">
231
+ {allErrors.map(err => (
232
+ <div key={err} className="text-[12px] text-[#fca5a5]">
233
+ <span className="mono text-[10px] px-1.5 py-0.5 rounded-sm bg-[#4a1818] text-[#fecaca] uppercase tracking-wider mr-2">
234
+ Fehler
235
+ </span>
236
+ {err}
237
+ </div>
238
+ ))}
239
+ </div>
240
+ )}
241
+
242
+ <div
243
+ className={cn(
244
+ 'flex-1 min-h-0 grid',
245
+ 'grid-cols-1',
246
+ panelCollapsed
247
+ ? 'lg:grid-cols-[56px_minmax(0,1fr)_380px]'
248
+ : 'lg:grid-cols-[270px_minmax(0,1fr)_380px]',
249
+ )}
250
+ >
251
+ {/* LEFT — module panel */}
252
+ <aside className="border-b lg:border-b-0 lg:border-r border-[color:var(--line)] overflow-hidden">
253
+ <ModulePanel
254
+ system={system}
255
+ values={values}
256
+ evaluation={evaluation}
257
+ activeId={activeModuleId}
258
+ collapsed={panelCollapsed}
259
+ onActivate={code => {
260
+ setActiveModuleId(code);
261
+ // Auto-expand when the user picks a module from
262
+ // the rail — collapsed-rail clicks expect to
263
+ // reveal field rows, not stay minimized.
264
+ if (panelCollapsed) setPanelCollapsed(false);
265
+ }}
266
+ onToggleCollapsed={() => setPanelCollapsed(v => !v)}
267
+ onChange={handleFieldChange}
268
+ />
269
+ </aside>
270
+
271
+ {/* CENTER — schematic + why */}
272
+ <section className="flex flex-col min-h-[520px] overflow-hidden">
273
+ <div className="flex-1 min-h-[520px] paper-bg relative overflow-hidden">
274
+ <Schematic system={system} evaluation={evaluation} />
275
+
276
+ <div className="absolute left-4 bottom-4 mono text-[10px] text-[color:var(--muted-2)] flex items-center gap-3">
277
+ <span>SCHEMA · AUTOMATISCH GENERIERT</span>
278
+ <span className="w-px h-3 bg-[color:var(--line)]" />
279
+ <span>{evaluation?.totals.lineCount ?? 0} Positionen</span>
280
+ <span className="w-px h-3 bg-[color:var(--line)]" />
281
+ <span>{evaluation?.totals.totalQuantity ?? 0} Teile</span>
282
+ </div>
283
+ </div>
284
+
285
+ <WhyPanel
286
+ executedRules={evaluation?.executedRules ?? []}
287
+ open={whyOpen}
288
+ onToggle={() => setWhyOpen(v => !v)}
289
+ />
290
+ </section>
291
+
292
+ {/* RIGHT — BOM */}
293
+ <aside className="border-t lg:border-t-0 lg:border-l border-[color:var(--line)] overflow-hidden">
294
+ <BomBasket
295
+ evaluation={evaluation}
296
+ hasErrors={errorCount > 0}
297
+ cartState={cartState}
298
+ quoteState={quoteState}
299
+ onCta={handleCta}
300
+ />
301
+ </aside>
302
+ </div>
303
+
304
+ <QuoteDialog
305
+ open={quoteDialogOpen}
306
+ onOpenChange={open => {
307
+ // Don't allow closing while the submit is in flight —
308
+ // the redirect will move the user away on success.
309
+ if (quoteState === 'saving' && !open) return;
310
+ setQuoteDialogOpen(open);
311
+ }}
312
+ configName={configName}
313
+ lineCount={evaluation?.totals.lineCount ?? 0}
314
+ totalPriceCents={totalPriceCents}
315
+ submitting={quoteState === 'saving'}
316
+ onSubmit={handleQuoteSubmit}
317
+ />
318
+ </div>
319
+ );
320
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * KaminPro configurator — chrome utilities.
3
+ *
4
+ * The system definition, catalogue, and rule engine all live in the backend
5
+ * (`libs/scenario-kaminpro/src/configurator-data.ts` +
6
+ * `@vendure-platform/configurator` plugin). This module only carries the small
7
+ * frontend-owned affordances: currency formatting, classification ordering
8
+ * for the BOM groups, and the `buildFieldRef` helper.
9
+ */
10
+ import type {
11
+ ConfiguratorField,
12
+ ConfiguratorModule,
13
+ ConfigurationEvaluation,
14
+ EvaluatedLine,
15
+ Values,
16
+ } from './types';
17
+
18
+ /**
19
+ * Build the `"moduleCode.fieldCode"` ref the backend expects as input and
20
+ * returns as keys in its evaluation output. Mirrors
21
+ * `apps/storefront/src/components/commerce/configurator-form.tsx:32` — keep
22
+ * them aligned so the two configurator PDPs speak the same dialect.
23
+ */
24
+ export const buildFieldRef = (moduleCode: string, fieldCode: string): string =>
25
+ `${moduleCode}.${fieldCode}`;
26
+
27
+ /**
28
+ * Canonical BOM grouping order. The backend catalogue tags every part with a
29
+ * `classification` facet value; this array gives the chrome its render order.
30
+ *
31
+ * Unknown/missing classifications bucket into `"Sonstiges"` and render last —
32
+ * adding a new classification facet value to the catalogue is safe and just
33
+ * appears at the end until this list is updated.
34
+ */
35
+ export const CLASSIFICATION_ORDER: string[] = [
36
+ 'tConnector', // T-Stück — the install anchor
37
+ 'baseParts', // Fußteil
38
+ 'Rohrstück', // main stack
39
+ 'wallBracket', // Wandkonsole
40
+ 'roofDuct', // Dachdurchführung
41
+ 'rainHood', // Regenhaube
42
+ 'outflowCone', // Abstromkonus
43
+ 'bracingSetThreePoint', // 3-point bracing
44
+ 'gasket', // Dichtung
45
+ ];
46
+
47
+ export const CLASSIFICATION_FALLBACK = 'Sonstiges';
48
+
49
+ /**
50
+ * Read the `classification` facet value off an evaluated BOM line. Returns
51
+ * `CLASSIFICATION_FALLBACK` if none present so the UI never produces an
52
+ * empty group heading.
53
+ */
54
+ export function getLineClassification(line: EvaluatedLine): string {
55
+ const facetValues = line.productVariant?.facetValues ?? [];
56
+ const match = facetValues.find(fv => fv.facet?.code === 'classification');
57
+ return match?.code ?? CLASSIFICATION_FALLBACK;
58
+ }
59
+
60
+ /**
61
+ * Human-readable label for a classification code. German-first; unknowns
62
+ * pass through verbatim so new codes in the catalogue don't break the UI.
63
+ */
64
+ const CLASSIFICATION_LABELS: Record<string, string> = {
65
+ tConnector: 'T-Stück',
66
+ baseParts: 'Fußteil',
67
+ Rohrstück: 'Rohrstück',
68
+ wallBracket: 'Wandkonsole',
69
+ roofDuct: 'Dachdurchführung',
70
+ rainHood: 'Regenhaube',
71
+ outflowCone: 'Abstromkonus',
72
+ bracingSetThreePoint: 'Abspannung',
73
+ gasket: 'Dichtung',
74
+ [CLASSIFICATION_FALLBACK]: 'Sonstiges',
75
+ };
76
+
77
+ export function classificationLabel(code: string): string {
78
+ return CLASSIFICATION_LABELS[code] ?? code;
79
+ }
80
+
81
+ /** Currency formatter pinned to de-AT / EUR — KaminPro is single-market. */
82
+ export function fmtEuro(n: number | null | undefined): string {
83
+ return new Intl.NumberFormat('de-AT', {
84
+ style: 'currency',
85
+ currency: 'EUR',
86
+ minimumFractionDigits: 2,
87
+ }).format(n ?? 0);
88
+ }
89
+
90
+ /**
91
+ * Resolve an option label from a backend field definition. Used by the
92
+ * schematic for annotations (e.g. "Regenhaube"). Falls back to the raw
93
+ * value when no matching option exists (numeric fields, or values that
94
+ * were narrowed out of options by a constrain rule).
95
+ */
96
+ export function labelForOption(field: ConfiguratorField | undefined, value: string | undefined): string {
97
+ if (!value) return '';
98
+ const opt = field?.options?.find(o => o.code === value);
99
+ return opt?.label ?? value;
100
+ }
101
+
102
+ export function moduleStats(
103
+ mod: ConfiguratorModule,
104
+ values: Values,
105
+ evaluation: ConfigurationEvaluation | null,
106
+ ): { total: number; filled: number; invalid: number } {
107
+ let total = 0;
108
+ let filled = 0;
109
+ let invalid = 0;
110
+ for (const f of mod.fields) {
111
+ const ref = buildFieldRef(mod.code, f.code);
112
+ const evalField = evaluation?.fields.find(ef => ef.fieldRef === ref);
113
+ if (evalField?.hidden) continue;
114
+ total++;
115
+ const v = values[ref];
116
+ if (v !== undefined && v !== '') filled++;
117
+ if (evalField?.messages.some(m => m.type === 'error')) invalid++;
118
+ }
119
+ return { total, filled, invalid };
120
+ }
121
+
122
+ /**
123
+ * Find the backend's field definition for a given `moduleCode.fieldCode`
124
+ * ref. Returns `undefined` when the field has been removed from the
125
+ * backend schema — consumers (notably the schematic) should treat
126
+ * `undefined` as "render the neutral default".
127
+ */
128
+ export function getFieldDefinition(
129
+ system: { modules: ConfiguratorModule[] },
130
+ ref: string,
131
+ ): ConfiguratorField | undefined {
132
+ const [moduleCode, fieldCode] = ref.split('.');
133
+ if (!moduleCode || !fieldCode) return undefined;
134
+ const mod = system.modules.find(m => m.code === moduleCode);
135
+ return mod?.fields.find(f => f.code === fieldCode);
136
+ }
137
+
138
+ /**
139
+ * Read a field's current evaluated value from the ConfigurationEvaluation.
140
+ * Returns `fallback` when the field isn't present in the evaluation —
141
+ * makes UI consumers (particularly the schematic) resilient to backend
142
+ * config changes.
143
+ */
144
+ export function getEvaluatedValue(
145
+ evaluation: ConfigurationEvaluation | null,
146
+ ref: string,
147
+ fallback = '',
148
+ ): string {
149
+ return evaluation?.fields.find(f => f.fieldRef === ref)?.value ?? fallback;
150
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * KaminPro configurator — domain types.
3
+ *
4
+ * Re-exported from gql.tada so the specialized PDP is driven by the same
5
+ * shapes the backend `@vendure-platform/configurator` plugin returns. This keeps
6
+ * the chrome thin and the backend authoritative — a new field, option or
7
+ * rule appears in the UI without a frontend code change.
8
+ *
9
+ * The only exception is the technical schematic SVG
10
+ * (`components/schematic.tsx`), which reads specific `moduleCode.fieldCode`
11
+ * refs to drive geometry. That coupling is documented at the top of the
12
+ * schematic file.
13
+ */
14
+
15
+ export type {
16
+ ConfiguratorSystem,
17
+ ConfiguratorModule,
18
+ ConfiguratorField,
19
+ ConfigurationEvaluation,
20
+ EvaluatedField,
21
+ EvaluatedLine,
22
+ EvaluatedExecutedRule,
23
+ } from '@/lib/vendure/queries';
24
+
25
+ /**
26
+ * Configurator values keyed by `${moduleCode}.${fieldCode}` — matches the
27
+ * input shape for `evaluateProductConfiguration` and the `fieldRef` keys the
28
+ * backend returns on evaluation results.
29
+ */
30
+ export type Values = Record<string, string>;