@propeller-commerce/propeller-v2-vue-ui 0.3.14

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 (129) hide show
  1. package/CHANGELOG.md +549 -0
  2. package/LICENSE +21 -0
  3. package/MIGRATION.md +178 -0
  4. package/README.md +282 -0
  5. package/STYLING.md +119 -0
  6. package/dist/ProductVideos.vue_vue_type_script_setup_true_lang-BSXOpWBD.js +1706 -0
  7. package/dist/ProductVideos.vue_vue_type_script_setup_true_lang-BSXOpWBD.js.map +1 -0
  8. package/dist/ProductVideos.vue_vue_type_script_setup_true_lang-cfRT3L_k.cjs +1705 -0
  9. package/dist/ProductVideos.vue_vue_type_script_setup_true_lang-cfRT3L_k.cjs.map +1 -0
  10. package/dist/__mocks__/decorators.d.ts +17 -0
  11. package/dist/__mocks__/fixtures.d.ts +43 -0
  12. package/dist/__mocks__/mockServices.d.ts +7 -0
  13. package/dist/components/AccountIconAndMenu.vue.d.ts +152 -0
  14. package/dist/components/ActionCode.vue.d.ts +29 -0
  15. package/dist/components/AddToCart.vue.d.ts +122 -0
  16. package/dist/components/AddToFavorite.vue.d.ts +19 -0
  17. package/dist/components/AddressCard.vue.d.ts +169 -0
  18. package/dist/components/AddressSelector.vue.d.ts +30 -0
  19. package/dist/components/Breadcrumbs.vue.d.ts +69 -0
  20. package/dist/components/CartBonusItems.vue.d.ts +21 -0
  21. package/dist/components/CartCarriers.vue.d.ts +24 -0
  22. package/dist/components/CartIconAndSidebar.vue.d.ts +104 -0
  23. package/dist/components/CartItem.vue.d.ts +178 -0
  24. package/dist/components/CartOverview.vue.d.ts +41 -0
  25. package/dist/components/CartPaymethods.vue.d.ts +23 -0
  26. package/dist/components/CartSummary.vue.d.ts +58 -0
  27. package/dist/components/CategoryDescription.vue.d.ts +29 -0
  28. package/dist/components/CategoryShortDescription.vue.d.ts +18 -0
  29. package/dist/components/ClusterCard.vue.d.ts +251 -0
  30. package/dist/components/ClusterConfigurator.vue.d.ts +41 -0
  31. package/dist/components/ClusterInfo.vue.d.ts +73 -0
  32. package/dist/components/ClusterJsonLd.vue.d.ts +10 -0
  33. package/dist/components/ClusterOptions.vue.d.ts +44 -0
  34. package/dist/components/CompanySwitcher.vue.d.ts +18 -0
  35. package/dist/components/DeliveryDate.vue.d.ts +27 -0
  36. package/dist/components/FavoriteListDetails.vue.d.ts +94 -0
  37. package/dist/components/FavoriteListItem.vue.d.ts +141 -0
  38. package/dist/components/FavoriteLists.vue.d.ts +73 -0
  39. package/dist/components/ForgotPassword.vue.d.ts +35 -0
  40. package/dist/components/GridFilters.vue.d.ts +64 -0
  41. package/dist/components/GridPagination.vue.d.ts +34 -0
  42. package/dist/components/GridTitle.vue.d.ts +22 -0
  43. package/dist/components/GridToolbar.vue.d.ts +117 -0
  44. package/dist/components/ItemListJsonLd.vue.d.ts +10 -0
  45. package/dist/components/ItemStock.vue.d.ts +31 -0
  46. package/dist/components/ItemsOverview.vue.d.ts +40 -0
  47. package/dist/components/LoginForm.vue.d.ts +139 -0
  48. package/dist/components/Menu.vue.d.ts +73 -0
  49. package/dist/components/OrderActions.vue.d.ts +25 -0
  50. package/dist/components/OrderBonusItems.vue.d.ts +19 -0
  51. package/dist/components/OrderItemCard.vue.d.ts +47 -0
  52. package/dist/components/OrderList.vue.d.ts +66 -0
  53. package/dist/components/OrderShipments.vue.d.ts +11 -0
  54. package/dist/components/OrderSummary.vue.d.ts +49 -0
  55. package/dist/components/OrderTotals.vue.d.ts +34 -0
  56. package/dist/components/PriceToggle.vue.d.ts +24 -0
  57. package/dist/components/ProductBulkPrices.vue.d.ts +35 -0
  58. package/dist/components/ProductBundles.vue.d.ts +88 -0
  59. package/dist/components/ProductCard.vue.d.ts +332 -0
  60. package/dist/components/ProductDescription.vue.d.ts +30 -0
  61. package/dist/components/ProductDownloads.vue.d.ts +22 -0
  62. package/dist/components/ProductGallery.vue.d.ts +25 -0
  63. package/dist/components/ProductGrid.vue.d.ts +290 -0
  64. package/dist/components/ProductInfo.vue.d.ts +179 -0
  65. package/dist/components/ProductJsonLd.vue.d.ts +10 -0
  66. package/dist/components/ProductPrice.vue.d.ts +42 -0
  67. package/dist/components/ProductShortDescription.vue.d.ts +18 -0
  68. package/dist/components/ProductSlider.vue.d.ts +176 -0
  69. package/dist/components/ProductSpecifications.vue.d.ts +37 -0
  70. package/dist/components/ProductTabs.vue.d.ts +83 -0
  71. package/dist/components/ProductVideos.vue.d.ts +22 -0
  72. package/dist/components/PropellerProvider.vue.d.ts +40 -0
  73. package/dist/components/PurchaseAuthorizationConfigurator.vue.d.ts +44 -0
  74. package/dist/components/PurchaseAuthorizationRequests.vue.d.ts +50 -0
  75. package/dist/components/QuoteActions.vue.d.ts +22 -0
  76. package/dist/components/RegisterForm.vue.d.ts +87 -0
  77. package/dist/components/SearchBar.vue.d.ts +71 -0
  78. package/dist/components/UserDetails.vue.d.ts +44 -0
  79. package/dist/components/defaults/DefaultProductBadges.vue.d.ts +3 -0
  80. package/dist/components/defaults/DefaultProductImage.vue.d.ts +3 -0
  81. package/dist/components/defaults/DefaultProductSurcharges.vue.d.ts +3 -0
  82. package/dist/composables/shared/usePagination.d.ts +19 -0
  83. package/dist/composables/shared/useServiceFetch.d.ts +9 -0
  84. package/dist/composables/shared/useUserIdentity.d.ts +13 -0
  85. package/dist/composables/shared/utils/cartInit.d.ts +18 -0
  86. package/dist/composables/shared/utils/fetchActiveCart.d.ts +10 -0
  87. package/dist/composables/shared/utils/mergeAnonymousCart.d.ts +12 -0
  88. package/dist/composables/vue/useAddress.d.ts +50 -0
  89. package/dist/composables/vue/useAuth.d.ts +80 -0
  90. package/dist/composables/vue/useCart.d.ts +64 -0
  91. package/dist/composables/vue/useCheckout.d.ts +41 -0
  92. package/dist/composables/vue/useClusterConfigurator.d.ts +26 -0
  93. package/dist/composables/vue/useCompany.d.ts +31 -0
  94. package/dist/composables/vue/useFavorites.d.ts +39 -0
  95. package/dist/composables/vue/useInfraProps.d.ts +27 -0
  96. package/dist/composables/vue/useMenu.d.ts +24 -0
  97. package/dist/composables/vue/useOrders.d.ts +64 -0
  98. package/dist/composables/vue/useProductBundles.d.ts +37 -0
  99. package/dist/composables/vue/useProductInfo.d.ts +33 -0
  100. package/dist/composables/vue/useProductSearch.d.ts +49 -0
  101. package/dist/composables/vue/useProductSlider.d.ts +31 -0
  102. package/dist/composables/vue/useProductSpecs.d.ts +24 -0
  103. package/dist/composables/vue/usePurchaseAuthorization.d.ts +102 -0
  104. package/dist/composables/vue/useResolvedProps.d.ts +42 -0
  105. package/dist/composables/vue/useServices.d.ts +13 -0
  106. package/dist/context/ProductGridContext.d.ts +59 -0
  107. package/dist/context/PropellerContext.d.ts +51 -0
  108. package/dist/index-BN8nyGRL.js +518 -0
  109. package/dist/index-BN8nyGRL.js.map +1 -0
  110. package/dist/index-CrrZsxTR.cjs +517 -0
  111. package/dist/index-CrrZsxTR.cjs.map +1 -0
  112. package/dist/index.cjs +20086 -0
  113. package/dist/index.cjs.map +1 -0
  114. package/dist/index.d.ts +109 -0
  115. package/dist/index.js +20088 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/plugin.d.ts +67 -0
  118. package/dist/pure.cjs +16 -0
  119. package/dist/pure.cjs.map +1 -0
  120. package/dist/pure.d.ts +37 -0
  121. package/dist/pure.js +16 -0
  122. package/dist/pure.js.map +1 -0
  123. package/dist/shared.cjs +50 -0
  124. package/dist/shared.cjs.map +1 -0
  125. package/dist/shared.d.ts +14 -0
  126. package/dist/shared.js +50 -0
  127. package/dist/shared.js.map +1 -0
  128. package/dist/styles.css +2 -0
  129. package/package.json +91 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/context/ProductGridContext.ts","../src/composables/vue/useAddress.ts","../src/composables/vue/useAuth.ts","../src/composables/shared/utils/cartInit.ts","../src/composables/vue/useCart.ts","../src/composables/vue/useCheckout.ts","../src/composables/vue/useClusterConfigurator.ts","../src/composables/vue/useCompany.ts","../src/composables/vue/useFavorites.ts","../src/composables/vue/useMenu.ts","../src/composables/shared/usePagination.ts","../src/composables/vue/useOrders.ts","../src/composables/vue/useProductBundles.ts","../src/composables/vue/useProductInfo.ts","../src/composables/vue/useProductSearch.ts","../src/composables/vue/useProductSlider.ts","../src/composables/vue/useProductSpecs.ts","../src/composables/vue/usePurchaseAuthorization.ts","../src/composables/vue/useResolvedProps.ts","../src/composables/vue/useServices.ts","../src/composables/shared/utils/fetchActiveCart.ts","../src/composables/shared/utils/mergeAnonymousCart.ts","../src/components/PropellerProvider.vue","../src/components/LoginForm.vue","../src/components/AccountIconAndMenu.vue","../src/components/ActionCode.vue","../src/components/AddToCart.vue","../src/components/AddToFavorite.vue","../src/components/AddressCard.vue","../src/components/AddressSelector.vue","../src/components/CartBonusItems.vue","../src/components/CartCarriers.vue","../src/components/defaults/DefaultProductSurcharges.vue","../src/components/CartItem.vue","../src/components/CartIconAndSidebar.vue","../src/components/CartOverview.vue","../src/components/CartPaymethods.vue","../src/components/CartSummary.vue","../src/components/CategoryDescription.vue","../src/components/defaults/DefaultProductImage.vue","../src/components/defaults/DefaultProductBadges.vue","../src/components/ClusterCard.vue","../src/components/ClusterConfigurator.vue","../src/components/ClusterInfo.vue","../src/components/ClusterJsonLd.vue","../src/components/ClusterOptions.vue","../src/components/CompanySwitcher.vue","../src/components/DeliveryDate.vue","../src/components/FavoriteListItem.vue","../src/components/GridPagination.vue","../src/components/FavoriteListDetails.vue","../src/components/FavoriteLists.vue","../src/components/ForgotPassword.vue","../src/components/GridFilters.vue","../src/components/GridToolbar.vue","../src/components/ItemListJsonLd.vue","../src/components/ItemsOverview.vue","../src/components/Menu.vue","../src/components/OrderActions.vue","../src/components/OrderBonusItems.vue","../src/components/OrderList.vue","../src/components/OrderShipments.vue","../src/components/PriceToggle.vue","../src/components/ProductBundles.vue","../src/components/ProductCard.vue","../src/components/ProductDescription.vue","../src/components/ProductGallery.vue","../src/components/ProductGrid.vue","../src/components/ProductInfo.vue","../src/components/ProductJsonLd.vue","../src/components/ProductSlider.vue","../src/components/ProductSpecifications.vue","../src/components/ProductTabs.vue","../src/components/PurchaseAuthorizationConfigurator.vue","../src/components/PurchaseAuthorizationRequests.vue","../src/components/QuoteActions.vue","../src/components/RegisterForm.vue","../src/components/SearchBar.vue","../src/components/UserDetails.vue"],"sourcesContent":["import { provide, inject, type InjectionKey, type Component } from 'vue';\nimport type { Cart, CartMainItem, Product, Cluster } from '@propeller-commerce/propeller-sdk-v2';\n\n/**\n * Tier 2 grid config context. Collapses the feature-flag / display and\n * callback props that `ProductGrid` otherwise cascades through\n * `ProductCard` / `ClusterCard` down to `AddToCart` / `ItemStock`.\n * `ProductGrid` is the provider; the card subtree consumes via\n * `useProductGridConfig()` instead of receiving ~20 threaded props.\n */\nexport interface ProductGridConfig {\n // Feature / display\n columns: number;\n showPrice?: boolean;\n showStock?: boolean;\n showAvailability?: boolean;\n enableAddFavorite?: boolean;\n allowAddToCart?: boolean;\n createCart?: boolean;\n showModal?: boolean;\n allowIncrDecr?: boolean;\n enableStockValidation?: boolean;\n cartId?: string;\n childItems?: number[];\n notes?: string;\n price?: number;\n stockLabels?: Record<string, string>;\n priceLabels?: Record<string, string>;\n addToCartLabels?: Record<string, string>;\n\n // Callbacks\n onCartCreated?: (cart: Cart) => void;\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n onProceedToCheckout?: () => void;\n onRequestQuoteClick?: (cart: Cart) => void;\n onToggleFavorite?: (item: Product | Cluster, isFavorite: boolean) => void;\n onProductClick?: (product: Product) => void;\n onClusterClick?: (cluster: Cluster) => void;\n\n // ───── Component-slot injection (extension API) ─────\n // Mirror of React's ProductGridConfig slot keys. Vue uses `Component`\n // (runtime component type) since prop-shape typing through `<component :is>`\n // is weaker than React's `ComponentType<P>`.\n priceComponent?: Component;\n stockComponent?: Component;\n addToCartComponent?: Component;\n imageComponent?: Component;\n badgesComponent?: Component;\n favoriteComponent?: Component;\n bundlesComponent?: Component;\n bulkPricesComponent?: Component;\n surchargesComponent?: Component;\n\n productCardComponent?: Component;\n clusterCardComponent?: Component;\n}\n\n/** Injection key for the Tier 2 grid config. Symbol-keyed, collision-free. */\nexport const ProductGridInjectionKey: InjectionKey<ProductGridConfig> =\n Symbol('propeller-product-grid');\n\n/**\n * Install the grid config for the card subtree. `ProductGrid` calls this in\n * its `setup()`; `ProductCard` / `ClusterCard` and their children read it.\n */\nexport function provideProductGridConfig(value: ProductGridConfig): void {\n provide(ProductGridInjectionKey, value);\n}\n\n/**\n * Non-throwing: `ProductCard` / `ClusterCard` used outside a grid\n * (`ProductSlider`, standalone, tests) get `null` and fall back to explicit\n * props / defaults.\n */\nexport function useProductGridConfig(): ProductGridConfig | null {\n return inject(ProductGridInjectionKey, null);\n}\n","/**\n * useAddress (Vue) — Address display and CRUD.\n *\n * Covers: AddressCard component.\n *\n * Uses proper SDK types for all address service calls.\n * CompanyAddressUpdateInput / CustomerAddressUpdateInput do not have a `type` field —\n * the address type is only set on creation.\n */\n\nimport { ref, type Ref } from 'vue';\nimport { AddressType, Gender, YesNo } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Address,\n CompanyAddressCreateInput,\n CustomerAddressCreateInput,\n CompanyAddressUpdateInput,\n CustomerAddressUpdateInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport type { AnyUser } from '@propeller-commerce/propeller-v2-core-ui';\nimport { isContact, isCustomer } from '@propeller-commerce/propeller-v2-core-ui';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface AddressInput {\n type?: AddressType;\n firstName?: string;\n lastName?: string;\n middleName?: string;\n company?: string;\n street: string;\n number?: string;\n numberExtension?: string;\n postalCode: string;\n city: string;\n country: string;\n email?: string;\n phone?: string;\n mobile?: string;\n gender?: Gender;\n isDefault?: YesNo;\n notes?: string;\n}\n\nexport interface UseAddressOptions {\n graphqlClient: GraphQLClient;\n user: Ref<AnyUser>;\n companyId?: Ref<number | undefined>;\n}\n\nexport interface UseAddressReturn {\n loading: Ref<boolean>;\n error: Ref<string | null>;\n createAddress: (input: AddressInput) => Promise<{ success: boolean; address?: Address; error?: string }>;\n updateAddress: (addressId: number, input: Partial<AddressInput>) => Promise<{ success: boolean; address?: Address; error?: string }>;\n deleteAddress: (addressId: number) => Promise<{ success: boolean; error?: string }>;\n setDefaultAddress: (addressId: number) => Promise<{ success: boolean; error?: string }>;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useAddress(options: UseAddressOptions): UseAddressReturn {\n const { graphqlClient, user } = options;\n const companyIdRef = options.companyId ?? ref<number | undefined>(undefined);\n\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n function resolveIds(): { companyId?: number; customerId?: number } {\n const u = user.value;\n if (!u) return {};\n if (isContact(u)) return { companyId: companyIdRef.value ?? u.company?.companyId };\n if (isCustomer(u)) return { customerId: u.customerId };\n return {};\n }\n\n // ── Create address ────────────────────────────────────────────────────────\n\n async function createAddress(input: AddressInput): Promise<{ success: boolean; address?: Address; error?: string }> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).address;\n const ids = resolveIds();\n let address: Address;\n\n if (ids.companyId) {\n const createInput: CompanyAddressCreateInput = {\n street: input.street,\n postalCode: input.postalCode,\n city: input.city,\n country: input.country,\n type: input.type ?? AddressType.invoice,\n companyId: ids.companyId,\n ...(input.firstName && { firstName: input.firstName }),\n ...(input.lastName && { lastName: input.lastName }),\n ...(input.middleName && { middleName: input.middleName }),\n ...(input.company && { company: input.company }),\n ...(input.number && { number: input.number }),\n ...(input.numberExtension && { numberExtension: input.numberExtension }),\n ...(input.email && { email: input.email }),\n ...(input.phone && { phone: input.phone }),\n ...(input.mobile && { mobile: input.mobile }),\n ...(input.gender && { gender: input.gender }),\n ...(input.isDefault && { isDefault: input.isDefault }),\n ...(input.notes && { notes: input.notes }),\n };\n address = await service.createCompanyAddress(createInput);\n } else if (ids.customerId) {\n const createInput: CustomerAddressCreateInput = {\n street: input.street,\n postalCode: input.postalCode,\n city: input.city,\n country: input.country,\n type: input.type ?? AddressType.delivery,\n customerId: ids.customerId,\n ...(input.firstName && { firstName: input.firstName }),\n ...(input.lastName && { lastName: input.lastName }),\n ...(input.middleName && { middleName: input.middleName }),\n ...(input.number && { number: input.number }),\n ...(input.numberExtension && { numberExtension: input.numberExtension }),\n ...(input.email && { email: input.email }),\n ...(input.phone && { phone: input.phone }),\n ...(input.mobile && { mobile: input.mobile }),\n ...(input.gender && { gender: input.gender }),\n ...(input.isDefault && { isDefault: input.isDefault }),\n ...(input.notes && { notes: input.notes }),\n };\n address = await service.createCustomerAddress(createInput);\n } else {\n return { success: false, error: 'No user context for address creation' };\n }\n\n return { success: true, address };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Failed to create address';\n error.value = msg;\n return { success: false, error: msg };\n } finally {\n loading.value = false;\n }\n }\n\n // ── Update address ────────────────────────────────────────────────────────\n // Note: SDK update inputs do not have a `type` field; type is fixed at creation.\n\n async function updateAddress(addressId: number, input: Partial<AddressInput>): Promise<{ success: boolean; address?: Address; error?: string }> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).address;\n const ids = resolveIds();\n let address: Address;\n\n if (ids.companyId) {\n const updateInput: CompanyAddressUpdateInput = {\n id: addressId,\n companyId: ids.companyId,\n ...(input.firstName && { firstName: input.firstName }),\n ...(input.lastName && { lastName: input.lastName }),\n ...(input.middleName && { middleName: input.middleName }),\n ...(input.company && { company: input.company }),\n ...(input.street && { street: input.street }),\n ...(input.number !== undefined && { number: input.number }),\n ...(input.numberExtension && { numberExtension: input.numberExtension }),\n ...(input.postalCode && { postalCode: input.postalCode }),\n ...(input.city && { city: input.city }),\n ...(input.country && { country: input.country }),\n ...(input.email && { email: input.email }),\n ...(input.phone && { phone: input.phone }),\n ...(input.mobile && { mobile: input.mobile }),\n ...(input.gender && { gender: input.gender }),\n ...(input.isDefault && { isDefault: input.isDefault }),\n ...(input.notes && { notes: input.notes }),\n };\n address = await service.updateCompanyAddress(updateInput);\n } else if (ids.customerId) {\n const updateInput: CustomerAddressUpdateInput = {\n id: addressId,\n customerId: ids.customerId,\n ...(input.firstName && { firstName: input.firstName }),\n ...(input.lastName && { lastName: input.lastName }),\n ...(input.middleName && { middleName: input.middleName }),\n ...(input.street && { street: input.street }),\n ...(input.number !== undefined && { number: input.number }),\n ...(input.numberExtension && { numberExtension: input.numberExtension }),\n ...(input.postalCode && { postalCode: input.postalCode }),\n ...(input.city && { city: input.city }),\n ...(input.country && { country: input.country }),\n ...(input.email && { email: input.email }),\n ...(input.phone && { phone: input.phone }),\n ...(input.mobile && { mobile: input.mobile }),\n ...(input.gender && { gender: input.gender }),\n ...(input.isDefault && { isDefault: input.isDefault }),\n ...(input.notes && { notes: input.notes }),\n };\n address = await service.updateCustomerAddress(updateInput);\n } else {\n return { success: false, error: 'No user context for address update' };\n }\n\n return { success: true, address };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Failed to update address';\n error.value = msg;\n return { success: false, error: msg };\n } finally {\n loading.value = false;\n }\n }\n\n // ── Delete address ────────────────────────────────────────────────────────\n\n async function deleteAddress(addressId: number): Promise<{ success: boolean; error?: string }> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).address;\n const ids = resolveIds();\n if (ids.companyId) {\n await service.deleteCompanyAddress({ id: addressId, companyId: ids.companyId });\n } else if (ids.customerId) {\n await service.deleteCustomerAddress({ id: addressId, customerId: ids.customerId });\n } else {\n return { success: false, error: 'No user context for address deletion' };\n }\n return { success: true };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Failed to delete address';\n error.value = msg;\n return { success: false, error: msg };\n } finally {\n loading.value = false;\n }\n }\n\n async function setDefaultAddress(addressId: number): Promise<{ success: boolean; error?: string }> {\n return updateAddress(addressId, { isDefault: YesNo.Y });\n }\n\n return { loading, error, createAddress, updateAddress, deleteAddress, setDefaultAddress };\n}\n","/**\n * useAuth (Vue) — Login, registration, and forgot-password flows.\n *\n * Covers: LoginForm, RegisterForm, ForgotPassword components.\n *\n * Responsibilities:\n * - login: LoginService + getViewer for session token + user\n * - registerContact: createCompany → registerContact (ContactRegisterInput wrapper) → createCompanyAddress\n * - registerCustomer: registerCustomer (CustomerRegisterInput wrapper) → login → createCustomerAddress\n * - forgotPassword: UserService.sendPasswordResetEmail\n */\n\nimport { ref, type Ref } from 'vue';\nimport { AddressType, Gender, LoginService, UserService, YesNo } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Contact,\n Customer,\n CreateCompanyInput,\n CompanyAddressCreateInput,\n CustomerAddressCreateInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n ViewerInput,\n ContactRegisterInput,\n CustomerRegisterInput,\n PasswordResetInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { isCustomer, ok, err, type Result } from '@propeller-commerce/propeller-v2-core-ui';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\n/**\n * Success payload for login / registerContact / registerCustomer.\n *\n * `user` + tokens are optional: the `autoLogin: false` branches of the\n * register flows complete server-side but deliberately drop the session,\n * yielding an `ok({})`.\n */\nexport interface AuthSuccess {\n user?: Contact | Customer;\n accessToken?: string;\n refreshToken?: string;\n expiresAt?: string;\n}\n\n/** Backwards-friendly alias kept for the public `UseAuth*` type re-exports. */\nexport type LoginResult = Result<AuthSuccess, string>;\n\nexport interface RegisterContactInput {\n email: string;\n password: string;\n firstName: string;\n middleName?: string;\n lastName: string;\n phone?: string;\n gender?: Gender;\n companyName?: string;\n vatNumber?: string;\n cocNumber?: string;\n street?: string;\n number?: string;\n numberExtension?: string;\n postalCode?: string;\n city?: string;\n country?: string;\n deliveryStreet?: string;\n deliveryNumber?: string;\n deliveryNumberExtension?: string;\n deliveryPostalCode?: string;\n deliveryCity?: string;\n deliveryCountry?: string;\n sameDeliveryAsBilling?: boolean;\n}\n\nexport interface RegisterCustomerInput {\n email: string;\n password: string;\n firstName: string;\n middleName?: string;\n lastName: string;\n phone?: string;\n gender?: Gender;\n street?: string;\n number?: string;\n numberExtension?: string;\n postalCode?: string;\n city?: string;\n country?: string;\n deliveryStreet?: string;\n deliveryNumber?: string;\n deliveryNumberExtension?: string;\n deliveryPostalCode?: string;\n deliveryCity?: string;\n deliveryCountry?: string;\n sameDeliveryAsBilling?: boolean;\n}\n\nexport interface UseAuthOptions {\n graphqlClient: GraphQLClient;\n language?: string;\n onAuthHeaderUpdate?: (token: string) => void;\n configuration?: any;\n}\n\nexport interface UseAuthReturn {\n loading: Ref<boolean>;\n error: Ref<string | null>;\n login: (\n email: string,\n password: string,\n onLoginSubmit?: (email: string, password: string) => Promise<Contact | Customer>,\n ) => Promise<Result<AuthSuccess, string>>;\n registerContact: (\n input: RegisterContactInput,\n preferredLanguage?: string,\n autoLogin?: boolean,\n ) => Promise<Result<AuthSuccess, string>>;\n registerCustomer: (\n input: RegisterCustomerInput,\n preferredLanguage?: string,\n autoLogin?: boolean,\n ) => Promise<Result<AuthSuccess, string>>;\n forgotPassword: (email: string) => Promise<Result<void, string>>;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useAuth(options: UseAuthOptions): UseAuthReturn {\n const { graphqlClient, language = 'NL', onAuthHeaderUpdate, configuration } = options;\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n // ── Login ─────────────────────────────────────────────────────────────────\n\n async function login(\n email: string,\n password: string,\n onLoginSubmit?: (email: string, password: string) => Promise<Contact | Customer>,\n ): Promise<Result<AuthSuccess, string>> {\n loading.value = true;\n error.value = null;\n try {\n if (onLoginSubmit) {\n const user = await onLoginSubmit(email, password);\n return ok({ user });\n }\n const loginService = createServices(graphqlClient).login;\n const loginResult = await loginService.login({ email, password });\n const session = loginResult?.session;\n const accessToken = session?.accessToken;\n const refreshToken = session?.refreshToken;\n const expiresAt = session?.expirationTime;\n if (accessToken) {\n graphqlClient.setAccessToken(accessToken);\n onAuthHeaderUpdate?.(accessToken);\n }\n const userService = createServices(graphqlClient).user;\n const viewerInput: ViewerInput = {\n ...(configuration?.contactTrackAttributes?.length && {\n contactAttributesInput: { attributeDescription: { names: configuration.contactTrackAttributes } },\n }),\n ...(configuration?.customerTrackAttributes?.length && {\n customerAttributesInput: { attributeDescription: { names: configuration.customerTrackAttributes } },\n }),\n ...(configuration?.companyTrackAttributes?.length && {\n companyAttributesInput: { attributeDescription: { names: configuration.companyTrackAttributes } },\n }),\n ...(configuration?.contactPAConfigInput && {\n contactPAConfigInput: configuration.contactPAConfigInput,\n }),\n };\n const viewer = await userService.getViewer(viewerInput);\n const user = viewer as Contact | Customer;\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('userLoggedIn', { detail: { user } }));\n }\n return ok({ user, accessToken, refreshToken, expiresAt });\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Login failed';\n error.value = msg;\n return err(msg);\n } finally {\n loading.value = false;\n }\n }\n\n // ── Register contact ──────────────────────────────────────────────────────\n // Contact registration path:\n // createCompany → registerContact (ContactRegisterInput) → createCompanyAddress(es)\n\n async function registerContact(\n input: RegisterContactInput,\n preferredLanguage = language,\n autoLogin = true,\n ): Promise<Result<AuthSuccess, string>> {\n loading.value = true;\n error.value = null;\n try {\n const userService = createServices(graphqlClient).user;\n const companyService = createServices(graphqlClient).company;\n const addressService = createServices(graphqlClient).address;\n\n let companyId: number | undefined;\n if (input.companyName) {\n const companyInput: CreateCompanyInput = {\n name: input.companyName,\n ...(input.vatNumber && { taxNumber: input.vatNumber }),\n ...(input.cocNumber && { cocNumber: input.cocNumber }),\n email: input.email,\n ...(input.phone && { phone: input.phone }),\n };\n const company = await companyService.createCompany({\n input: companyInput,\n contactPAConfigInput: { page: 1, offset: 10 },\n companyAttributesInput: {},\n contactSearchArguments: { page: 1, offset: 10 },\n });\n companyId = company.companyId;\n }\n\n const contactInput: ContactRegisterInput = {\n contactRegisterInput: {\n email: input.email,\n password: input.password,\n firstName: input.firstName,\n ...(input.middleName && { middleName: input.middleName }),\n lastName: input.lastName,\n ...(input.phone && { phone: input.phone }),\n ...(input.gender && { gender: input.gender }),\n primaryLanguage: preferredLanguage,\n parentId: companyId as number,\n },\n companyAttributesInput: {},\n contactAttributesInput: {},\n contactPAConfigInput: { page: 1, offset: 10 },\n };\n // The contact-register response carries the new contact's id AND a freshly\n // issued `session` (accessToken/refreshToken/expirationTime) — the backend\n // logs the contact in as part of registration. We capture both here.\n //\n // The response also includes a `favoriteLists` sub-selection that the\n // FavoriteListsV2 service rejects with FORBIDDEN for newly-created contacts.\n // That's a *partial* error: the SDK's executeMutation returns `data`\n // alongside the error (it only throws when `data` is null), so\n // `registerResult` — including `session` — is still returned. The try/catch\n // is defensive in case a future SDK change starts throwing on partials.\n let registeredContactId: number | undefined;\n let registerAccessToken: string | undefined;\n try {\n const registerResult = await userService.registerContact(contactInput);\n registeredContactId = (registerResult?.contact as unknown as Contact | undefined)?.contactId;\n registerAccessToken = registerResult?.session?.accessToken;\n } catch {\n // Swallow: contact creation succeeded server-side; the only failing\n // sub-selection is the favoriteLists field, which is empty for new users.\n }\n\n // Authenticate company-address creation with the token from the register\n // response — NOT with a separate login(). `companyAddressCreate` is a\n // company-scoped mutation the backend authorizes against the logged-in\n // contact; called anonymously (API key only) it returns FORBIDDEN. Set the\n // register-session token on graphqlClient so the address calls are\n // authenticated. login() below is a separate concern, run only to\n // establish the real user session when autoLogin is requested.\n if (registerAccessToken) {\n graphqlClient.setAccessToken(registerAccessToken);\n onAuthHeaderUpdate?.(registerAccessToken);\n }\n\n if (input.street && companyId) {\n const invoiceAddress: CompanyAddressCreateInput = {\n firstName: input.firstName,\n lastName: input.lastName,\n ...(input.gender && { gender: input.gender }),\n street: input.street,\n number: input.number,\n numberExtension: input.numberExtension,\n postalCode: input.postalCode ?? '',\n city: input.city ?? '',\n country: input.country ?? 'NL',\n type: AddressType.invoice,\n isDefault: YesNo.Y,\n companyId,\n };\n await addressService.createCompanyAddress(invoiceAddress);\n\n // Determine the delivery-address payload:\n // - If \"same as billing\" is checked, copy the billing fields and only\n // change `type` to `delivery` so Propeller has a dedicated delivery\n // record for the contact.\n // - Otherwise, use the separately-entered delivery fields (skip if the\n // user left them empty).\n if (input.sameDeliveryAsBilling) {\n const deliveryAddress: CompanyAddressCreateInput = {\n ...invoiceAddress,\n type: AddressType.delivery,\n };\n await addressService.createCompanyAddress(deliveryAddress);\n } else if (input.deliveryStreet) {\n const deliveryAddress: CompanyAddressCreateInput = {\n firstName: input.firstName,\n lastName: input.lastName,\n ...(input.gender && { gender: input.gender }),\n street: input.deliveryStreet,\n number: input.deliveryNumber,\n numberExtension: input.deliveryNumberExtension,\n postalCode: input.deliveryPostalCode ?? '',\n city: input.deliveryCity ?? '',\n country: input.deliveryCountry ?? 'NL',\n type: AddressType.delivery,\n isDefault: YesNo.Y,\n companyId,\n };\n await addressService.createCompanyAddress(deliveryAddress);\n }\n }\n\n if (registeredContactId) {\n try {\n await userService.triggerContactSendWelcomeEmailEvent({\n contactId: registeredContactId,\n language: preferredLanguage,\n ...(configuration?.channelId && { channelId: configuration.channelId }),\n });\n } catch (e) {\n console.error('Failed to send welcome email to contact', e);\n }\n }\n\n if (!autoLogin) {\n // Address creation used the register-session token (set above). The\n // caller asked not to stay logged in, so drop it: setAccessToken('')\n // clears the token and we notify the host to drop it.\n graphqlClient.setAccessToken('');\n onAuthHeaderUpdate?.('');\n return ok({});\n }\n\n // Separate concern: establish the real user session. login() re-issues a\n // session (overwriting the register-session token) and returns the viewer\n // + token for the host to persist via its afterLogin/afterRegistration.\n return await login(input.email, input.password);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Registration failed';\n error.value = msg;\n return err(msg);\n } finally {\n loading.value = false;\n }\n }\n\n // ── Register customer ──────────────────────────────────────────────────\n // Customer registration path:\n // registerCustomer (CustomerRegisterInput) → login → createCustomerAddress\n\n async function registerCustomer(\n input: RegisterCustomerInput,\n preferredLanguage = language,\n autoLogin = true,\n ): Promise<Result<AuthSuccess, string>> {\n loading.value = true;\n error.value = null;\n try {\n const userService = createServices(graphqlClient).user;\n const addressService = createServices(graphqlClient).address;\n\n const customerInput: CustomerRegisterInput = {\n customerRegisterInput: {\n email: input.email,\n password: input.password,\n firstName: input.firstName,\n ...(input.middleName && { middleName: input.middleName }),\n lastName: input.lastName,\n ...(input.phone && { phone: input.phone }),\n ...(input.gender && { gender: input.gender }),\n primaryLanguage: preferredLanguage,\n },\n customerAttributesInput: {},\n };\n await userService.registerCustomer(customerInput);\n\n const loginResult = await login(input.email, input.password);\n if (!loginResult.ok) return loginResult;\n const loggedInUser = loginResult.data.user;\n\n let addressesCreated = false;\n if (input.street && isCustomer(loggedInUser ?? null)) {\n const customer = loggedInUser as Customer;\n const invoiceAddress: CustomerAddressCreateInput = {\n firstName: input.firstName,\n lastName: input.lastName,\n ...(input.gender && { gender: input.gender }),\n street: input.street,\n number: input.number,\n numberExtension: input.numberExtension,\n postalCode: input.postalCode ?? '',\n city: input.city ?? '',\n country: input.country ?? 'NL',\n type: AddressType.invoice,\n isDefault: YesNo.Y,\n customerId: customer.customerId,\n };\n await addressService.createCustomerAddress(invoiceAddress);\n addressesCreated = true;\n\n // As with the contact flow: when \"same as billing\" is checked, copy the\n // billing fields into a delivery-typed record so Propeller has a\n // dedicated default delivery address. Otherwise, use the separately\n // entered delivery fields (skip if the user left them empty).\n if (input.sameDeliveryAsBilling) {\n const deliveryAddress: CustomerAddressCreateInput = {\n ...invoiceAddress,\n type: AddressType.delivery,\n };\n await addressService.createCustomerAddress(deliveryAddress);\n } else if (input.deliveryStreet) {\n const deliveryAddress: CustomerAddressCreateInput = {\n firstName: input.firstName,\n lastName: input.lastName,\n ...(input.gender && { gender: input.gender }),\n street: input.deliveryStreet,\n number: input.deliveryNumber,\n numberExtension: input.deliveryNumberExtension,\n postalCode: input.deliveryPostalCode ?? '',\n city: input.deliveryCity ?? '',\n country: input.deliveryCountry ?? 'NL',\n type: AddressType.delivery,\n isDefault: YesNo.Y,\n customerId: customer.customerId,\n };\n await addressService.createCustomerAddress(deliveryAddress);\n }\n }\n\n if (isCustomer(loggedInUser ?? null)) {\n try {\n await userService.triggerCustomerSendWelcomeEmailEvent({\n customerId: (loggedInUser as Customer).customerId,\n language: preferredLanguage,\n ...(configuration?.channelId && { channelId: configuration.channelId }),\n });\n } catch (e) {\n console.error('Failed to send welcome email to customer', e);\n }\n }\n\n if (!autoLogin) {\n // Address creation needed the customerId from login(); now drop the\n // session so the caller doesn't see this as a logged-in flow.\n graphqlClient.setAccessToken('');\n onAuthHeaderUpdate?.('');\n return ok({});\n }\n\n // Re-fetch the viewer so the returned user includes the just-created\n // addresses. The user object captured by login() above is a snapshot\n // taken before the addresses existed, and consumers that store it\n // (authStore, dashboard, /account/addresses) would otherwise see no\n // addresses until the next page load.\n if (addressesCreated) {\n try {\n const viewerInput: ViewerInput = {\n ...(configuration?.customerTrackAttributes?.length && {\n customerAttributesInput: { attributeDescription: { names: configuration.customerTrackAttributes } },\n }),\n };\n const refreshedViewer = await userService.getViewer(viewerInput);\n const refreshedUser = refreshedViewer as Contact | Customer;\n return ok({ ...loginResult.data, user: refreshedUser });\n } catch {\n // Fall through to original loginResult — addresses still exist\n // server-side; only the local snapshot is stale.\n }\n }\n return loginResult;\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Registration failed';\n error.value = msg;\n return err(msg);\n } finally {\n loading.value = false;\n }\n }\n\n // ── Forgot password ───────────────────────────────────────────────────────\n\n async function forgotPassword(email: string): Promise<Result<void, string>> {\n loading.value = true;\n error.value = null;\n try {\n const userService = createServices(graphqlClient).user;\n const resetInput: PasswordResetInput = { email };\n await userService.sendPasswordResetEmail(resetInput);\n return ok(undefined);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Failed to send reset email';\n error.value = msg;\n return err(msg);\n } finally {\n loading.value = false;\n }\n }\n\n return { loading, error, login, registerContact, registerCustomer, forgotPassword };\n}\n","/**\n * cartInit — 3-step cart initialisation shared by useCart and useProductBundles.\n *\n * Step 1: Search for an existing OPEN cart for this user.\n * Step 2: If none found, create a new cart via startCart.\n * Step 3: Assign default invoice and delivery addresses to the new cart.\n *\n * Framework-agnostic async function.\n */\n\nimport { CartAddressType, CartService, CartStatus, Gender } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n Cart,\n CartSearchInput,\n CartStartInput,\n CartStartVariables,\n CartUpdateAddressInput,\n Address,\n GraphQLClient,\n MediaImageProductSearchInput,\n TransformationsInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { isContact, isCustomer, getAddresses, type AnyUser } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface CartInitConfig {\n graphqlClient: GraphQLClient;\n user: AnyUser;\n /** Active company ID — overrides user's default company for cart lookup and creation */\n companyId?: number;\n language?: string;\n imageSearchFilters?: MediaImageProductSearchInput;\n imageVariantFilters?: TransformationsInput;\n onCartCreated?: (cart: Cart) => void;\n}\n\n/**\n * Resolves the active cart for the current user.\n * Returns an existing OPEN cart if one exists, otherwise creates and\n * initialises a new cart with default addresses.\n */\nexport async function initCart(config: CartInitConfig): Promise<Cart> {\n const {\n graphqlClient,\n user,\n companyId,\n language = 'NL',\n imageSearchFilters,\n imageVariantFilters,\n onCartCreated,\n } = config;\n\n const cartService = new CartService(graphqlClient);\n\n // ── Step 1: Look for an existing open cart ────────────────────────────────\n if (user) {\n try {\n const searchInput: CartSearchInput = {\n offset: 100,\n statuses: [CartStatus.OPEN],\n };\n\n if (isContact(user) && user.contactId) {\n searchInput.contactIds = [user.contactId];\n const resolvedCompanyId = companyId ?? user.company?.companyId;\n if (resolvedCompanyId) {\n searchInput.companyIds = [resolvedCompanyId];\n }\n } else if (isCustomer(user) && user.customerId) {\n searchInput.customerIds = [user.customerId];\n }\n\n const carts = await cartService.getCarts(searchInput);\n\n if (carts?.items && carts.items.length > 0) {\n const existingCartId = carts.items[carts.items.length - 1].cartId;\n const cart = await cartService.getCart({\n cartId: existingCartId,\n imageSearchFilters: imageSearchFilters as MediaImageProductSearchInput,\n imageVariantFilters: imageVariantFilters as TransformationsInput,\n language,\n });\n onCartCreated?.(cart);\n return cart;\n }\n } catch (e) {\n console.error('[cartInit] Failed to fetch existing carts:', e);\n }\n }\n\n // ── Step 2: Create a new cart ─────────────────────────────────────────────\n const startInput: CartStartInput = { language };\n\n if (user) {\n if (isContact(user) && user.contactId) {\n startInput.contactId = user.contactId;\n const resolvedCompanyId = companyId ?? user.company?.companyId;\n if (resolvedCompanyId) {\n startInput.companyId = resolvedCompanyId;\n }\n } else if (isCustomer(user) && user.customerId) {\n startInput.customerId = user.customerId;\n }\n }\n\n const startVars: CartStartVariables = {\n input: startInput,\n imageSearchFilters: imageSearchFilters as MediaImageProductSearchInput,\n imageVariantFilters: imageVariantFilters as TransformationsInput,\n language,\n };\n\n let cart = await cartService.startCart(startVars);\n\n // ── Step 3: Assign default addresses ─────────────────────────────────────\n if (cart && user) {\n const addresses = getAddresses(user);\n\n const defaultInvoice = addresses.find(\n (addr: Address) => addr.isDefault === 'Y' && addr.type === 'invoice'\n );\n const defaultDelivery = addresses.find(\n (addr: Address) => addr.isDefault === 'Y' && addr.type === 'delivery'\n );\n\n const addressBase = (addr: Address): Omit<CartUpdateAddressInput, 'type'> => {\n const base: Omit<CartUpdateAddressInput, 'type'> = {\n firstName: addr.firstName || '',\n lastName: addr.lastName || '',\n street: addr.street || '',\n postalCode: addr.postalCode || '',\n city: addr.city || '',\n country: addr.country || 'NL',\n gender: addr.gender || Gender.U,\n };\n if (addr.middleName) base.middleName = addr.middleName;\n if (addr.number) base.number = String(addr.number);\n if (addr.numberExtension) base.numberExtension = String(addr.numberExtension);\n if (addr.company) base.company = addr.company;\n if (addr.email) base.email = addr.email;\n if (addr.mobile) base.mobile = addr.mobile;\n if (addr.phone) base.phone = addr.phone;\n if (addr.notes) base.notes = addr.notes;\n return base;\n };\n\n if (defaultInvoice) {\n try {\n cart = await cartService.updateCartAddress({\n id: cart.cartId,\n input: { type: CartAddressType.INVOICE, ...addressBase(defaultInvoice) },\n imageSearchFilters: imageSearchFilters as MediaImageProductSearchInput,\n imageVariantFilters: imageVariantFilters as TransformationsInput,\n language,\n });\n } catch {\n // Address update is best-effort; cart still works without it\n // and the user can set the address at checkout.\n }\n }\n\n if (defaultDelivery) {\n try {\n cart = await cartService.updateCartAddress({\n id: cart.cartId,\n input: { type: CartAddressType.DELIVERY, ...addressBase(defaultDelivery) },\n imageSearchFilters: imageSearchFilters as MediaImageProductSearchInput,\n imageVariantFilters: imageVariantFilters as TransformationsInput,\n language,\n });\n } catch {\n // Address update is best-effort; cart still works without it\n // and the user can set the address at checkout.\n }\n }\n }\n\n onCartCreated?.(cart);\n return cart;\n}\n","/**\n * useCart (Vue) — Cart management composable.\n *\n * Covers: AddToCart, CartItem, CartSummary, ActionCode, CartIconAndSidebar.\n */\n\nimport { ref, computed, unref, type Ref, type ComputedRef } from 'vue';\nimport { CartStatus, CrossupsellType, PurchaseRole } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Cart,\n CartMainItem,\n CartSearchInput,\n Product,\n Cluster,\n Contact,\n Customer,\n MediaImageProductSearchInput,\n TransformationsInput,\n PurchaseAuthorizationConfig,\n Crossupsell,\n CrossupsellsQueryVariables,\n CrossupsellSearchInput,\n CartProcessResponse,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { initCart, type CartInitConfig } from '../shared/utils/cartInit';\nimport {\n isContact,\n isCustomer,\n createServices,\n ok,\n err,\n type AnyUser,\n type Result,\n} from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface UseCartOptions {\n graphqlClient: GraphQLClient;\n user: Ref<AnyUser>;\n /** Initial cart id. Accepts a plain string or a (computed) ref. */\n cartId?: string | Ref<string | undefined>;\n companyId?: Ref<number | undefined>;\n language?: Ref<string>;\n configuration: {\n language?: string;\n imageSearchFiltersGrid: MediaImageProductSearchInput;\n imageVariantFiltersSmall: TransformationsInput;\n };\n onCartCreated?: (cart: Cart) => void;\n}\n\nexport interface AddItemOptions {\n product: Product;\n cluster?: Cluster;\n childItems?: number[];\n quantity: number;\n notes?: string;\n price?: number;\n onAddToCart?: (product: Product, clusterId?: number, quantity?: number, childItems?: { productId: number; quantity: number }[], notes?: string, price?: number) => Cart;\n afterAddToCart?: (cart: Cart, item: CartMainItem | null) => void;\n enableStockValidation?: boolean;\n cartId?: string;\n createCart?: boolean;\n}\n\nexport interface GetCrossupsellsOptions {\n productId?: number;\n clusterId?: number;\n types?: string[];\n taxZone?: string;\n imageVariantFilters?: TransformationsInput;\n}\n\nexport interface UseCartReturn {\n cart: Ref<Cart | null>;\n cartId: Ref<string>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n checkoutAllowed: ComputedRef<boolean>;\n resolveCart: () => Promise<Cart>;\n fetchActiveCart: () => Promise<Cart | null>;\n addItem: (\n options: AddItemOptions,\n ) => Promise<Result<{ cart: Cart; item: CartMainItem | null }, string>>;\n updateItemQuantity: (cartItemId: string, quantity: number) => Promise<Cart | undefined>;\n updateItemNotes: (cartItemId: string, notes: string, debounceMs?: number) => void;\n deleteItem: (cartItemId: string) => Promise<Cart | undefined>;\n addActionCode: (code: string) => Promise<Cart | undefined>;\n removeActionCode: (code: string) => Promise<Cart | undefined>;\n requestAuthorization: () => Promise<Result<void, string>>;\n processCart: (orderStatus?: string) => Promise<Result<CartProcessResponse, string>>;\n getCrossupsells: (options: GetCrossupsellsOptions) => Promise<Crossupsell[]>;\n getMinQuantity: (product: Product | null | undefined) => number;\n getStep: (product: Product | null | undefined) => number;\n}\n\nexport function useCart(options: UseCartOptions): UseCartReturn {\n const { graphqlClient, user, configuration, onCartCreated } = options;\n const companyIdRef = options.companyId ?? ref<number | undefined>(undefined);\n const languageRef = options.language ?? ref('NL');\n\n const cart = ref<Cart | null>(null) as Ref<Cart | null>;\n const cartId = ref(unref(options.cartId) || '');\n const loading = ref(false);\n const error = ref<string | null>(null);\n let notesTimers: Record<string, ReturnType<typeof setTimeout>> = {};\n\n const checkoutAllowed = computed<boolean>(() => {\n const u = user.value;\n if (!u || !('contactId' in u)) return true;\n if (!companyIdRef.value) return true;\n if (!cart.value) return true;\n // Read tolerantly: the SDK can serialize class instances with leading\n // underscores on private fields. The auth store sanitizes on setUser, but\n // any data path that bypasses the store (or stale localStorage from a\n // previous session) can leave the user in the underscored shape. Use the\n // same defensive pattern as CartIconAndSidebar so cart and sidebar agree.\n const pacData: any = (u as any).purchaseAuthorizationConfigs ?? (u as any)._purchaseAuthorizationConfigs;\n const items: any[] = pacData?.items ?? pacData?._items ?? [];\n const purchaserPac = items.find((pac: any) => {\n const role = pac.purchaseRole ?? pac._purchaseRole;\n const pacCompanyId =\n pac.company?.companyId\n ?? pac.company?._companyId\n ?? pac._company?.companyId\n ?? pac._company?._companyId;\n return role === PurchaseRole.PURCHASER && pacCompanyId === companyIdRef.value;\n });\n if (!purchaserPac) return true;\n const limit = (purchaserPac as any).authorizationLimit ?? (purchaserPac as any)._authorizationLimit ?? 0;\n const totalGross = (cart.value as any)?.total?.totalGross ?? (cart.value as any)?._total?._totalGross ?? 0;\n return totalGross <= limit;\n });\n\n function getMinQuantity(product: Product | null | undefined): number {\n const min = product?.minimumQuantity;\n return min && min > 0 ? min : 1;\n }\n\n function getStep(product: Product | null | undefined): number {\n const unit = product?.unit;\n return unit && unit > 0 ? unit : 1;\n }\n\n async function resolveCart(): Promise<Cart> {\n const config: CartInitConfig = {\n graphqlClient, user: user.value, companyId: companyIdRef.value,\n language: languageRef.value || configuration.language || 'NL',\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n onCartCreated: (c) => { cart.value = c; cartId.value = c.cartId; onCartCreated?.(c); },\n };\n const resolved = await initCart(config);\n cart.value = resolved;\n cartId.value = resolved.cartId;\n return resolved;\n }\n\n async function addItem(\n opts: AddItemOptions,\n ): Promise<Result<{ cart: Cart; item: CartMainItem | null }, string>> {\n loading.value = true; error.value = null;\n try {\n if (opts.enableStockValidation) {\n const available = opts.product.inventory?.totalQuantity ?? 0;\n if (available < opts.quantity) return err('Insufficient stock available');\n }\n const childItemInputs = opts.childItems?.map((id) => ({ productId: id, quantity: opts.quantity }));\n\n if (opts.onAddToCart) {\n const resultCart = opts.onAddToCart(opts.product, opts.cluster?.clusterId, opts.quantity, childItemInputs, opts.notes, opts.price);\n cart.value = resultCart; cartId.value = resultCart.cartId;\n const addedItem = resultCart.items?.find((i: CartMainItem) => i.productId === opts.product.productId) ?? null;\n opts.afterAddToCart?.(resultCart, addedItem);\n return ok({ cart: resultCart, item: addedItem });\n }\n\n let resolvedCartId = opts.cartId || cartId.value;\n if (!resolvedCartId) {\n if (opts.createCart) { const c = await resolveCart(); resolvedCartId = c.cartId; }\n else return err('No cart ID provided');\n }\n\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const resultCart = await service.addItemToCart({\n id: resolvedCartId,\n input: {\n productId: opts.product.productId, quantity: opts.quantity,\n ...(opts.cluster?.clusterId !== undefined && { clusterId: opts.cluster.clusterId }),\n ...(childItemInputs && { childItems: childItemInputs }),\n ...(opts.notes && { notes: opts.notes }),\n ...(opts.price !== undefined && { price: opts.price }),\n },\n language, imageSearchFilters: configuration.imageSearchFiltersGrid, imageVariantFilters: configuration.imageVariantFiltersSmall,\n });\n cart.value = resultCart; cartId.value = resultCart.cartId;\n const addedItem = (resultCart as any).items?.find((i: any) => i.productId === opts.product.productId) ?? null;\n opts.afterAddToCart?.(resultCart, addedItem);\n return ok({ cart: resultCart, item: addedItem });\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Failed to add item to cart';\n error.value = msg;\n return err(msg);\n } finally { loading.value = false; }\n }\n\n async function updateItemQuantity(cartItemId: string, quantity: number): Promise<Cart | undefined> {\n if (!cartId.value) return undefined; loading.value = true;\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const updated = await service.updateCartItem({ id: cartId.value, itemId: cartItemId, input: { quantity }, language, imageSearchFilters: configuration.imageSearchFiltersGrid, imageVariantFilters: configuration.imageVariantFiltersSmall });\n cart.value = updated;\n return updated;\n } catch (e: unknown) { error.value = e instanceof Error ? e.message : 'Failed to update quantity'; }\n finally { loading.value = false; }\n }\n\n function updateItemNotes(cartItemId: string, notes: string, debounceMs = 500): void {\n if (notesTimers[cartItemId]) clearTimeout(notesTimers[cartItemId]);\n notesTimers[cartItemId] = setTimeout(async () => {\n if (!cartId.value) return;\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const updated = await service.updateCartItem({ id: cartId.value, itemId: cartItemId, input: { notes }, language, imageSearchFilters: configuration.imageSearchFiltersGrid, imageVariantFilters: configuration.imageVariantFiltersSmall });\n cart.value = updated;\n } catch (e: unknown) { error.value = e instanceof Error ? e.message : 'Failed to update notes'; }\n }, debounceMs);\n }\n\n async function deleteItem(cartItemId: string): Promise<Cart | undefined> {\n if (!cartId.value) return undefined; loading.value = true;\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const updated = await service.deleteCartItem({ id: cartId.value, input: { itemId: cartItemId }, language, imageSearchFilters: configuration.imageSearchFiltersGrid, imageVariantFilters: configuration.imageVariantFiltersSmall });\n cart.value = updated;\n return updated;\n } catch (e: unknown) { error.value = e instanceof Error ? e.message : 'Failed to delete item'; }\n finally { loading.value = false; }\n }\n\n async function addActionCode(code: string): Promise<Cart | undefined> {\n if (!cartId.value) return undefined;\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const updated = await service.addActionCodeToCart({ id: cartId.value, input: { actionCode: code }, language, imageSearchFilters: configuration.imageSearchFiltersGrid, imageVariantFilters: configuration.imageVariantFiltersSmall });\n cart.value = updated;\n return updated;\n } catch (e: unknown) { error.value = e instanceof Error ? e.message : 'Failed to add action code'; }\n }\n\n async function removeActionCode(code: string): Promise<Cart | undefined> {\n if (!cartId.value) return undefined;\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const updated = await service.removeActionCodeFromCart({ id: cartId.value, input: { actionCode: code }, language, imageSearchFilters: configuration.imageSearchFiltersGrid, imageVariantFilters: configuration.imageVariantFiltersSmall });\n cart.value = updated;\n return updated;\n } catch (e: unknown) { error.value = e instanceof Error ? e.message : 'Failed to remove action code'; }\n }\n\n async function requestAuthorization(): Promise<Result<void, string>> {\n if (!cartId.value) return err('No cart');\n try {\n const service = createServices(graphqlClient).cart;\n await service.requestPurchaseAuthorization({ id: cartId.value });\n return ok(undefined);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : 'Failed to request authorization');\n }\n }\n\n async function processCart(orderStatus = 'COMPLETE'): Promise<Result<CartProcessResponse, string>> {\n if (!cartId.value) return err('No cart');\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const response = await service.processCart({ id: cartId.value, input: { orderStatus, language } });\n return ok(response);\n } catch (e: unknown) {\n return err(e instanceof Error ? e.message : 'Failed to process cart');\n }\n }\n\n async function fetchActiveCart(): Promise<Cart | null> {\n const u = user.value;\n if (!u) return null;\n try {\n const service = createServices(graphqlClient).cart;\n const language = languageRef.value || configuration.language || 'NL';\n const searchInput: CartSearchInput = {\n offset: 100,\n statuses: [CartStatus.OPEN],\n };\n if (isContact(u)) {\n searchInput.contactIds = [(u as Contact).contactId];\n if (companyIdRef.value) searchInput.companyIds = [companyIdRef.value];\n } else if (isCustomer(u)) {\n searchInput.customerIds = [(u as Customer).customerId];\n }\n const carts = await service.getCarts(searchInput);\n if (carts?.items?.length) {\n const existingCartId = carts.items[carts.items.length - 1].cartId;\n const activeCart = await service.getCart({\n cartId: existingCartId,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n language,\n });\n if (activeCart) {\n cart.value = activeCart;\n cartId.value = activeCart.cartId;\n }\n return activeCart ?? null;\n }\n return null;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch active cart';\n return null;\n }\n }\n\n async function getCrossupsells(opts: GetCrossupsellsOptions): Promise<Crossupsell[]> {\n const { productId, clusterId, types, taxZone, imageVariantFilters } = opts;\n if (!productId && !clusterId) return [];\n try {\n const service = createServices(graphqlClient).crossupsell;\n const language = languageRef.value || configuration.language || 'NL';\n const u = user.value;\n const variables: CrossupsellsQueryVariables = {\n input: {\n types: (types ?? [CrossupsellType.ACCESSORIES]) as CrossupsellSearchInput['types'],\n page: 1,\n offset: 50,\n ...(productId && !clusterId && { productIdsFrom: [productId] }),\n ...(clusterId && { clusterIdsFrom: [clusterId] }),\n },\n language,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: imageVariantFilters ?? configuration.imageVariantFiltersSmall,\n priceCalculateProductInput: {\n taxZone: taxZone || 'NL',\n ...(u && 'company' in u && { companyId: (u as Contact)?.company?.companyId }),\n ...(u && 'contactId' in u && { contactId: (u as Contact)?.contactId }),\n ...(u && 'customerId' in u && { customerId: (u as Customer)?.customerId }),\n },\n };\n const result = await service.getCrossupsells(variables);\n return result?.items ?? [];\n } catch { return []; }\n }\n\n return { cart, cartId, loading, error, checkoutAllowed, resolveCart, fetchActiveCart, addItem, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };\n}\n","/**\n * useCheckout (Vue) — Checkout flow: address updates, cart settings, order placement.\n *\n * Covers: CheckoutView.\n *\n * Responsibilities:\n * - updateCartAddress: save invoice or delivery address to cart\n * - updateCartSettings: save payment method, carrier, delivery date, reference, notes\n * - placeOrder: processCart → setOrderStatus → optional triggerQuoteSendRequest\n * - getUserDefaultAddress: resolve pre-fill address from user profile\n * - buildAddressInput: normalize address data to CartUpdateAddressInput\n */\n\nimport { ref, type Ref } from 'vue';\nimport { CartAddressType, PaymentStatuses } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Cart,\n CartUpdateAddressInput,\n MediaImageProductSearchInput,\n TransformationsInput,\n Address,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport {\n getDefaultInvoiceAddress,\n getDefaultDeliveryAddress,\n createServices,\n ok,\n err,\n type AnyUser,\n type Result,\n} from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface UseCheckoutOptions {\n graphqlClient: GraphQLClient;\n user: Ref<AnyUser>;\n companyId?: Ref<number | undefined>;\n language?: Ref<string>;\n configuration: {\n imageSearchFiltersGrid: MediaImageProductSearchInput;\n imageVariantFiltersSmall: TransformationsInput;\n };\n}\n\nexport interface CartSettingsInput {\n paymentMethod?: string;\n carrier?: string;\n requestDate?: string;\n reference?: string;\n notes?: string;\n}\n\nexport interface PlaceOrderOptions {\n isQuoteMode?: boolean;\n reference?: string;\n notes?: string;\n}\n\n/** Backwards-friendly alias kept for the public `UseCheckout*` type re-exports. */\nexport type PlaceOrderResult = Result<{ orderId: number }, string>;\n\nexport interface UseCheckoutReturn {\n loading: Ref<boolean>;\n error: Ref<string | null>;\n updateCartAddress: (cartId: string, type: 'INVOICE' | 'DELIVERY', address: any) => Promise<Cart | null>;\n updateCartSettings: (cartId: string, input: CartSettingsInput) => Promise<Cart | null>;\n placeOrder: (\n cartId: string,\n options?: PlaceOrderOptions,\n ) => Promise<Result<{ orderId: number }, string>>;\n getUserDefaultAddress: (type: 'invoice' | 'delivery') => Address | undefined;\n buildAddressInput: (type: 'INVOICE' | 'DELIVERY', addr: any) => CartUpdateAddressInput;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn {\n const { graphqlClient, user, configuration } = options;\n const languageRef = options.language ?? ref('NL');\n\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n function buildAddressInput(type: 'INVOICE' | 'DELIVERY', addr: any): CartUpdateAddressInput {\n return {\n type: type === 'INVOICE' ? CartAddressType.INVOICE : CartAddressType.DELIVERY,\n firstName: addr.firstName || '',\n lastName: addr.lastName || '',\n street: addr.street || '',\n postalCode: addr.postalCode || '',\n city: addr.city || '',\n company: addr.company,\n gender: addr.gender,\n middleName: addr.middleName,\n number: addr.number,\n numberExtension: addr.numberExtension,\n country: addr.country,\n email: addr.email,\n mobile: addr.mobile,\n phone: addr.phone,\n notes: addr.notes,\n icp: addr.icp,\n };\n }\n\n function getUserDefaultAddress(type: 'invoice' | 'delivery'): Address | undefined {\n const u = user.value;\n if (!u) return undefined;\n return type === 'invoice'\n ? getDefaultInvoiceAddress(u)\n : getDefaultDeliveryAddress(u);\n }\n\n async function updateCartAddress(cartId: string, type: 'INVOICE' | 'DELIVERY', address: any): Promise<Cart | null> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).cart;\n const input = buildAddressInput(type, address);\n const updated = await service.updateCartAddress({\n id: cartId,\n input,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n language: languageRef.value || 'NL',\n });\n return updated;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to save address';\n return null;\n } finally {\n loading.value = false;\n }\n }\n\n async function updateCartSettings(cartId: string, input: CartSettingsInput): Promise<Cart | null> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).cart;\n const cartInput: Record<string, any> = {};\n if (input.paymentMethod) cartInput.paymentData = { method: input.paymentMethod };\n if (input.carrier || input.requestDate) {\n cartInput.postageData = {};\n if (input.carrier) cartInput.postageData.carrier = input.carrier;\n if (input.requestDate) cartInput.postageData.requestDate = input.requestDate;\n }\n if (input.reference !== undefined) cartInput.reference = input.reference || undefined;\n if (input.notes !== undefined) cartInput.notes = input.notes || undefined;\n\n const updated = await service.updateCart({\n id: cartId,\n input: cartInput,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n language: languageRef.value || 'NL',\n });\n return updated;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to update cart';\n return null;\n } finally {\n loading.value = false;\n }\n }\n\n async function placeOrder(\n cartId: string,\n opts: PlaceOrderOptions = {},\n ): Promise<Result<{ orderId: number }, string>> {\n loading.value = true;\n error.value = null;\n try {\n const cartService = createServices(graphqlClient).cart;\n const orderService = createServices(graphqlClient).order;\n const language = languageRef.value || 'NL';\n\n // Update reference/notes if provided\n if (opts.reference || opts.notes) {\n await cartService.updateCart({\n id: cartId,\n input: {\n reference: opts.reference || undefined,\n notes: opts.notes || undefined,\n },\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n language,\n });\n }\n\n const orderStatus = opts.isQuoteMode ? 'REQUEST' : 'NEW';\n const response = await cartService.processCart({\n id: cartId,\n input: { orderStatus, language },\n });\n\n if (!response?.cartOrderId) throw new Error('No Order ID returned');\n\n const orderId = response.cartOrderId;\n\n await orderService.setOrderStatus({\n orderId,\n status: orderStatus,\n payStatus: PaymentStatuses.OPEN,\n sendOrderConfirmationEmail: !opts.isQuoteMode,\n addPDFAttachment: !opts.isQuoteMode,\n triggerOrderSendConfirmEvent: !opts.isQuoteMode,\n deleteCart: true,\n });\n\n if (opts.isQuoteMode) {\n await (orderService as any).triggerQuoteSendRequest?.({ orderId, language });\n }\n\n return ok({ orderId });\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : 'Failed to place order';\n error.value = msg;\n return err(msg);\n } finally {\n loading.value = false;\n }\n }\n\n return {\n loading,\n error,\n updateCartAddress,\n updateCartSettings,\n placeOrder,\n getUserDefaultAddress,\n buildAddressInput,\n };\n}\n","/**\n * useClusterConfigurator (Vue) — Cascading attribute selection state machine.\n *\n * Covers: ClusterConfigurator component (most complex, no SDK calls).\n *\n * Responsibilities:\n * - selectedAttributes state (only reactive field)\n * - getSortedSettings() — settings sorted by priority\n * - getAvailableValuesForIndex(name, index, selections) — drilldown filtering\n * - handleAttributeSelect(name, value) — cascade reset + auto-fill + match\n * - initFromProduct(product) — pre-populate from defaultProduct on mount\n * - Delegates attribute extraction to shared attributeExtractor utility\n */\n\nimport { ref, computed, type Ref, type ComputedRef } from 'vue';\nimport type {\n Product,\n AttributeResult,\n ClusterConfig,\n ClusterConfigSetting,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport {\n attributeNameMatches,\n extractAttributeValues,\n filterProductsBySelections,\n collectAttributeValues,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { getAttributeDisplayName } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface ConfiguredSetting {\n id: number;\n name: string;\n displayType: string;\n priority: string;\n displayName: string;\n availableValues: string[];\n selectedValue: string;\n disabled: boolean;\n}\n\nexport interface UseClusterConfiguratorOptions {\n products: Ref<Product[]>;\n config: Ref<ClusterConfig>;\n language?: Ref<string>;\n onConfigurationChange?: (product: Product) => void;\n}\n\nexport interface UseClusterConfiguratorReturn {\n selectedAttributes: Ref<Record<string, string>>;\n settingsWithValues: ComputedRef<ConfiguredSetting[]>;\n handleAttributeSelect: (settingName: string, value: string) => void;\n initFromProduct: (product: Product) => void;\n reset: () => void;\n}\n\nexport function useClusterConfigurator(\n options: UseClusterConfiguratorOptions\n): UseClusterConfiguratorReturn {\n const { products, config, onConfigurationChange } = options;\n const languageRef = options.language ?? ref('NL');\n\n const selectedAttributes = ref<Record<string, string>>({});\n\n // ── Sorted settings ───────────────────────────────────────────────────────\n\n function getSortedSettings(): ClusterConfigSetting[] {\n const settings = config.value?.settings;\n if (!settings?.length) return [];\n return settings\n .slice()\n .sort((a: ClusterConfigSetting, b: ClusterConfigSetting) => parseInt(a.priority) - parseInt(b.priority));\n }\n\n // ── Available values for a setting at a given index with explicit selections ─\n\n function getAvailableValuesForIndexWithSelections(\n attributeName: string,\n settingIndex: number,\n selections: Record<string, string>\n ): string[] {\n if (settingIndex === 0) {\n return collectAttributeValues(products.value, attributeName);\n }\n\n const sortedSettings = getSortedSettings();\n const previousSelections: Record<string, string> = {};\n for (let i = 0; i < settingIndex; i++) {\n const prev = sortedSettings[i];\n if (selections[prev.name]) previousSelections[prev.name] = selections[prev.name];\n }\n\n const matching = filterProductsBySelections(products.value, previousSelections);\n return collectAttributeValues(matching, attributeName);\n }\n\n // ── Computed settings with values ─────────────────────────────────────────\n\n const settingsWithValues = computed<ConfiguredSetting[]>(() => {\n const sortedSettings = getSortedSettings();\n const sel = selectedAttributes.value;\n const language = languageRef.value || 'NL';\n\n return sortedSettings.map((setting, index) => {\n const availableValues = getAvailableValuesForIndexWithSelections(setting.name, index, sel);\n const selectedValue = sel[setting.name] || '';\n const isPreviousMissing =\n index > 0 && sortedSettings.slice(0, index).some((prev) => !sel[prev.name]);\n const isDisabled = availableValues.length === 0 || isPreviousMissing;\n\n // Resolve display name from first product attributes\n let displayName = setting.name;\n const firstProduct = products.value[0];\n if (firstProduct) {\n const items = firstProduct.attributes?.items as AttributeResult[] | undefined;\n if (items) {\n const match = items.find((a) => attributeNameMatches(a, setting.name));\n if (match) displayName = getAttributeDisplayName(match, language) || setting.name;\n }\n }\n\n return {\n id: setting.id,\n name: setting.name,\n displayType: setting.displayType as string,\n priority: setting.priority,\n displayName,\n availableValues,\n selectedValue,\n disabled: isDisabled,\n };\n });\n });\n\n // ── Handle attribute selection ─────────────────────────────────────────────\n\n function handleAttributeSelect(settingName: string, value: string): void {\n const sortedSettings = getSortedSettings();\n const changedIndex = sortedSettings.findIndex((s) => s.name === settingName);\n if (changedIndex < 0) return;\n\n const newSelections: Record<string, string> = { ...selectedAttributes.value };\n newSelections[settingName] = value;\n\n // Clear subsequent selections\n for (let i = changedIndex + 1; i < sortedSettings.length; i++) {\n delete newSelections[sortedSettings[i].name];\n }\n\n // Auto-fill: pre-select first available value for each subsequent setting\n for (let i = changedIndex + 1; i < sortedSettings.length; i++) {\n const next = sortedSettings[i];\n const available = getAvailableValuesForIndexWithSelections(next.name, i, newSelections);\n if (available.length > 0) {\n newSelections[next.name] = available[0];\n } else {\n break;\n }\n }\n\n selectedAttributes.value = newSelections;\n\n // Fire callback if all settings have selections\n const allSelected = sortedSettings.every((s) => !!newSelections[s.name]);\n if (allSelected) {\n const matching = filterProductsBySelections(products.value, newSelections);\n if (matching.length > 0 && onConfigurationChange) {\n onConfigurationChange(matching[0]);\n }\n }\n }\n\n // ── Init from default product ─────────────────────────────────────────────\n\n function initFromProduct(product: Product): void {\n const sortedSettings = getSortedSettings();\n if (!sortedSettings.length) return;\n\n const initial: Record<string, string> = {};\n const attrItems = product.attributes?.items as AttributeResult[] | undefined;\n\n if (!attrItems) return;\n\n for (const setting of sortedSettings) {\n const match = attrItems.find((a) => attributeNameMatches(a, setting.name));\n if (match) {\n const values = extractAttributeValues(match);\n if (values.length) initial[setting.name] = values[0];\n }\n }\n\n if (!Object.keys(initial).length) return;\n selectedAttributes.value = initial;\n\n const allSelected = sortedSettings.every((s) => !!initial[s.name]);\n if (allSelected && onConfigurationChange) {\n const matching = filterProductsBySelections(products.value, initial);\n if (matching.length > 0) onConfigurationChange(matching[0]);\n }\n }\n\n function reset(): void {\n selectedAttributes.value = {};\n }\n\n return {\n selectedAttributes,\n settingsWithValues,\n handleAttributeSelect,\n initFromProduct,\n reset,\n };\n}\n","/**\n * useCompany (Vue) — Company switcher and Purchase Authorization Configurator.\n *\n * Covers: CompanySwitcher, PurchaseAuthorizationConfigurator, PurchaseAuthorizationRequests.\n *\n * Responsibilities:\n * - fetchCompany: CompanyService.getCompany() with correctly-typed CompanyVariables\n * - fetchPendingCarts: CartService.getCarts() with CartStatus.PENDING_PURCHASE_AUTHORIZATION\n * - createPac / updatePac / deletePac: PurchaseAuthorizationConfigService with proper input types\n * - acceptCartRequest: CartService.acceptPurchaseAuthorizationRequest()\n */\n\nimport { ref, type Ref } from 'vue';\nimport { CartService, CartStatus, CompanyService, PurchaseAuthorizationConfigService } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Company,\n Cart,\n CompanyVariables,\n ContactSearchArguments,\n ContactPurchaseAuthorizationConfigSearchInput,\n AttributeResultSearchInput,\n PurchaseAuthorizationConfigCreateInput,\n PurchaseAuthorizationConfigUpdateInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface UseCompanyOptions {\n graphqlClient: GraphQLClient;\n language?: Ref<string>;\n}\n\nexport interface UseCompanyReturn {\n company: Ref<Company | null>;\n pendingCarts: Ref<Cart[]>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n fetchCompany: (companyId: number, overrides?: Partial<Omit<CompanyVariables, 'id'>>) => Promise<void>;\n fetchPendingCarts: (companyId: number) => Promise<void>;\n createPac: (input: PurchaseAuthorizationConfigCreateInput) => Promise<{ success: boolean; error?: string }>;\n updatePac: (pacId: string, input: PurchaseAuthorizationConfigUpdateInput) => Promise<{ success: boolean; error?: string }>;\n deletePac: (pacId: string) => Promise<{ success: boolean; error?: string }>;\n acceptCartRequest: (cartId: string) => Promise<{ success: boolean; error?: string }>;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useCompany(options: UseCompanyOptions): UseCompanyReturn {\n const { graphqlClient } = options;\n\n const company = ref<Company | null>(null) as Ref<Company | null>;\n const pendingCarts = ref<Cart[]>([]) as Ref<Cart[]>;\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n // ── Fetch company ─────────────────────────────────────────────────────────\n // loadCompany() query arguments:\n // - contactSearchArguments: { page: 1, offset: 50 }\n // - contactPAConfigInput: { companyIds: [companyId], page: 1, offset: 100 }\n // - companyAttributesInput: {}\n\n async function fetchCompany(companyId: number, overrides?: Partial<Omit<CompanyVariables, 'id'>>): Promise<void> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).company;\n const contactSearchArguments: ContactSearchArguments = { page: 1, offset: 50 };\n const contactPAConfigInput: ContactPurchaseAuthorizationConfigSearchInput = {\n companyIds: [companyId],\n page: 1,\n offset: 100,\n };\n const companyAttributesInput: AttributeResultSearchInput = {};\n const variables: CompanyVariables = {\n id: companyId,\n contactSearchArguments: overrides?.contactSearchArguments ?? contactSearchArguments,\n contactPAConfigInput: overrides?.contactPAConfigInput ?? contactPAConfigInput,\n companyAttributesInput: overrides?.companyAttributesInput ?? companyAttributesInput,\n };\n const result = await service.getCompany(variables);\n company.value = result;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch company';\n } finally {\n loading.value = false;\n }\n }\n\n // ── Fetch pending carts ───────────────────────────────────────────────────\n // Query arguments:\n // - statuses: [CartStatus.PENDING_PURCHASE_AUTHORIZATION]\n\n async function fetchPendingCarts(companyId: number): Promise<void> {\n loading.value = true;\n try {\n const service = createServices(graphqlClient).cart;\n const result = await service.getCarts({\n companyIds: [companyId],\n statuses: [CartStatus.PENDING_PURCHASE_AUTHORIZATION],\n offset: 50,\n });\n pendingCarts.value = result.items ?? [];\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch pending carts';\n } finally {\n loading.value = false;\n }\n }\n\n // ── PAC CRUD ──────────────────────────────────────────────────────────────\n\n async function createPac(\n input: PurchaseAuthorizationConfigCreateInput,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const service = createServices(graphqlClient).purchaseAuthConfig;\n await service.createPurchaseAuthorizationConfig(input);\n return { success: true };\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to create PAC' };\n }\n }\n\n async function updatePac(\n pacId: string,\n input: PurchaseAuthorizationConfigUpdateInput,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const service = createServices(graphqlClient).purchaseAuthConfig;\n await service.updatePurchaseAuthorizationConfig(pacId, input);\n return { success: true };\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to update PAC' };\n }\n }\n\n async function deletePac(pacId: string): Promise<{ success: boolean; error?: string }> {\n try {\n const service = createServices(graphqlClient).purchaseAuthConfig;\n await service.deletePurchaseAuthorizationConfig(pacId);\n return { success: true };\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to delete PAC' };\n }\n }\n\n async function acceptCartRequest(cartId: string): Promise<{ success: boolean; error?: string }> {\n try {\n const service = createServices(graphqlClient).cart;\n await service.acceptPurchaseAuthorizationRequest({ id: cartId });\n return { success: true };\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to accept request' };\n }\n }\n\n return {\n company,\n pendingCarts,\n loading,\n error,\n fetchCompany,\n fetchPendingCarts,\n createPac,\n updatePac,\n deletePac,\n acceptCartRequest,\n };\n}\n","/**\n * useFavorites (Vue) — Favorite list CRUD with optimistic updates.\n *\n * Covers: FavoriteLists, FavoriteListDetails, AddToFavorite components.\n *\n * Responsibilities:\n * - fetchLists: read favoriteLists from Contact/Customer (no separate SDK call needed)\n * - createList: FavoriteListService.createFavoriteList with contactId/customerId from user\n * - updateList / deleteList: FavoriteListService CRUD\n * - addToList / removeFromList: FavoriteListService item management\n * - isProductInList: check products.items for a given productId\n */\n\nimport { ref, computed, watch, type Ref, type ComputedRef } from 'vue';\nimport { FavoriteListService } from '@propeller-commerce/propeller-sdk-v2';\nimport type { GraphQLClient, FavoriteList, FavoriteListsCreateInput, Product } from '@propeller-commerce/propeller-sdk-v2';\nimport type { AnyUser } from '@propeller-commerce/propeller-v2-core-ui';\nimport { isContact, isCustomer } from '@propeller-commerce/propeller-v2-core-ui';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface FavoriteListFormData {\n name: string;\n isDefault: boolean;\n}\n\nexport interface UseFavoritesOptions {\n graphqlClient: GraphQLClient;\n user: Ref<AnyUser>;\n language?: Ref<string>;\n onCreate?: (data: FavoriteListFormData) => void;\n onEdit?: (id: string, data: FavoriteListFormData) => void;\n onDelete?: (id: string) => void;\n onListChanged?: () => void;\n}\n\nexport interface UseFavoritesReturn {\n lists: Ref<FavoriteList[]>;\n loading: Ref<boolean>;\n saving: Ref<boolean>;\n error: Ref<string | null>;\n editingListId: Ref<string | null>;\n editListName: Ref<string>;\n editSetAsDefault: Ref<boolean>;\n newListName: Ref<string>;\n newSetAsDefault: Ref<boolean>;\n listToDelete: Ref<FavoriteList | null>;\n fetchLists: () => void;\n startEdit: (list: FavoriteList) => void;\n cancelEdit: () => void;\n updateList: (listId: string) => Promise<void>;\n confirmDelete: (list: FavoriteList) => void;\n deleteList: () => Promise<void>;\n createList: (name: string, isDefault: boolean) => Promise<void>;\n addToList: (listId: string, productId?: number, clusterId?: number) => Promise<void>;\n removeFromList: (\n listId: string,\n productId?: number | number[],\n clusterId?: number | number[],\n ) => Promise<void>;\n isProductInList: (listId: string, productId: number) => ComputedRef<boolean>;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useFavorites(options: UseFavoritesOptions): UseFavoritesReturn {\n const { graphqlClient, user, onCreate, onEdit, onDelete, onListChanged } = options;\n\n const lists = ref<FavoriteList[]>([]) as Ref<FavoriteList[]>;\n const loading = ref(false);\n const saving = ref(false);\n const error = ref<string | null>(null);\n const editingListId = ref<string | null>(null);\n const editListName = ref('');\n const editSetAsDefault = ref(false);\n const newListName = ref('');\n const newSetAsDefault = ref(false);\n const listToDelete = ref<FavoriteList | null>(null) as Ref<FavoriteList | null>;\n\n // ── Fetch lists ───────────────────────────────────────────────────────────\n // Reads favoriteLists from the user object directly.\n\n function fetchLists(): void {\n const u = user.value;\n if (!u) { lists.value = []; return; }\n lists.value = u.favoriteLists?.items ?? [];\n }\n\n // Auto-sync lists whenever user (or their favoriteLists) changes.\n watch(\n () => user.value?.favoriteLists?.items,\n () => fetchLists(),\n { immediate: true }\n );\n\n // ── Edit state helpers ────────────────────────────────────────────────────\n\n function startEdit(list: FavoriteList): void {\n editingListId.value = String(list.id);\n editListName.value = list.name;\n editSetAsDefault.value = list.isDefault || false;\n }\n\n function cancelEdit(): void {\n editingListId.value = null;\n editListName.value = '';\n editSetAsDefault.value = false;\n }\n\n // ── Update list ───────────────────────────────────────────────────────────\n\n async function updateList(listId: string): Promise<void> {\n const data: FavoriteListFormData = { name: editListName.value, isDefault: editSetAsDefault.value };\n if (onEdit) { onEdit(listId, data); cancelEdit(); onListChanged?.(); return; }\n saving.value = true;\n try {\n const service = createServices(graphqlClient).favoriteList;\n if (data.isDefault) {\n const currentDefault = lists.value.find((l: FavoriteList) => l.isDefault && String(l.id) !== listId);\n if (currentDefault) {\n await service.updateFavoriteList(String(currentDefault.id), { name: currentDefault.name, isDefault: false });\n }\n }\n const updated = await service.updateFavoriteList(listId, { name: data.name, isDefault: data.isDefault });\n lists.value = lists.value.map((l: FavoriteList) => String(l.id) === listId ? updated : l);\n cancelEdit();\n onListChanged?.();\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to update list';\n } finally {\n saving.value = false;\n }\n }\n\n // ── Delete list ───────────────────────────────────────────────────────────\n\n function confirmDelete(list: FavoriteList): void { listToDelete.value = list; }\n\n async function deleteList(): Promise<void> {\n if (!listToDelete.value) return;\n const list = listToDelete.value;\n const listId = String(list.id);\n if (onDelete) { onDelete(listId); listToDelete.value = null; onListChanged?.(); return; }\n saving.value = true;\n lists.value = lists.value.filter((l: FavoriteList) => String(l.id) !== listId);\n listToDelete.value = null;\n try {\n const service = createServices(graphqlClient).favoriteList;\n await service.deleteFavoriteList(listId);\n onListChanged?.();\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to delete list';\n if (list) lists.value = [...lists.value, list];\n } finally {\n saving.value = false;\n }\n }\n\n // ── Create list ───────────────────────────────────────────────────────────\n // Passes contactId/customerId from the user.\n\n async function createList(name: string, isDefault: boolean): Promise<void> {\n const data: FavoriteListFormData = { name, isDefault };\n if (onCreate) { onCreate(data); onListChanged?.(); return; }\n saving.value = true;\n try {\n const service = createServices(graphqlClient).favoriteList;\n if (isDefault) {\n const currentDefault = lists.value.find((l: FavoriteList) => l.isDefault);\n if (currentDefault) {\n await service.updateFavoriteList(String(currentDefault.id), { name: currentDefault.name, isDefault: false });\n }\n }\n const u = user.value;\n const createInput: FavoriteListsCreateInput = { name, isDefault };\n if (isContact(u)) createInput.contactId = u.contactId;\n if (isCustomer(u)) createInput.customerId = u.customerId;\n const created = await service.createFavoriteList(createInput);\n lists.value = [...lists.value, created];\n onListChanged?.();\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to create list';\n } finally {\n saving.value = false;\n }\n }\n\n // ── Add / remove items ────────────────────────────────────────────────────\n\n async function addToList(listId: string, productId?: number, clusterId?: number): Promise<void> {\n try {\n const service = createServices(graphqlClient).favoriteList;\n const updated = await service.addFavoriteListItems(listId, {\n ...(productId && { productIds: [productId] }),\n ...(clusterId && { clusterIds: [clusterId] }),\n });\n lists.value = lists.value.map((l: FavoriteList) => String(l.id) === listId ? updated : l);\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to add to list';\n }\n }\n\n async function removeFromList(\n listId: string,\n productId?: number | number[],\n clusterId?: number | number[],\n ): Promise<void> {\n const productIds = productId === undefined ? [] : Array.isArray(productId) ? productId : [productId];\n const clusterIds = clusterId === undefined ? [] : Array.isArray(clusterId) ? clusterId : [clusterId];\n if (productIds.length === 0 && clusterIds.length === 0) return;\n try {\n const service = createServices(graphqlClient).favoriteList;\n const updated = await service.removeFavoriteListItems(listId, {\n ...(productIds.length && { productIds }),\n ...(clusterIds.length && { clusterIds }),\n });\n lists.value = lists.value.map((l: FavoriteList) => String(l.id) === listId ? updated : l);\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to remove from list';\n }\n }\n\n // ── Check product in list ─────────────────────────────────────────────────\n // list.products is ProductsResponse; items are IBaseProduct but runtime Product.\n\n function isProductInList(listId: string, productId: number): ComputedRef<boolean> {\n return computed(() => {\n const list = lists.value.find((l: FavoriteList) => String(l.id) === listId);\n if (!list) return false;\n return (list.products?.items ?? []).some((p) => (p as Product).productId === productId);\n });\n }\n\n return {\n lists, loading, saving, error,\n editingListId, editListName, editSetAsDefault,\n newListName, newSetAsDefault, listToDelete,\n fetchLists, startEdit, cancelEdit,\n updateList, confirmDelete, deleteList, createList,\n addToList, removeFromList, isProductInList,\n };\n}\n","/**\n * useMenu (Vue) — Category tree fetch with depth-configurable recursive GraphQL query.\n *\n * Covers: Menu component.\n *\n * Responsibilities:\n * - Dynamic recursive GraphQL category query (depth-configurable, default 3)\n * - localStorage cache with 12h TTL, user-specific cache key\n * - Maps LocalizedString arrays to flat name/slug strings per language\n */\n\nimport { ref, type Ref } from 'vue';\nimport type { GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\n/** Raw category shape returned by the recursive GraphQL query */\ninterface MenuCategoryRaw {\n categoryId: number;\n hidden?: boolean | 'Y' | 'N' | string | null;\n name: Array<{ value: string; language: string }>;\n slug: Array<{ value: string }>;\n categories?: MenuCategoryRaw[];\n}\nfunction isHidden(raw: MenuCategoryRaw): boolean {\n return raw.hidden === true || raw.hidden === 'Y';\n}\n\nexport interface MenuCategory {\n categoryId: number;\n name: string;\n slug: string;\n children: MenuCategory[];\n}\n\nexport interface UseMenuOptions {\n graphqlClient: GraphQLClient;\n language?: Ref<string>;\n /** Nesting depth for the category tree. Default: 3. */\n depth?: number;\n /** Cache TTL in milliseconds. Default: 12h. */\n cacheTtlMs?: number;\n}\n\nexport interface UseMenuReturn {\n categories: Ref<MenuCategory[]>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n fetchMenu: (rootCategoryId: number, userKey?: string) => Promise<void>;\n clearCache: (rootCategoryId: number, language: string, userKey?: string) => void;\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────────\n\nconst CACHE_TTL_DEFAULT = 12 * 60 * 60 * 1000; // 12h\n\n// Module-level inflight dedup map — prevents two concurrent fetchMenu calls for\n// the same key (e.g. Menu + HomeFallback both mounting at the same time) from\n// both hitting the API. The second caller awaits the promise and reads from cache.\nconst inflightFetches = new Map<string, Promise<void>>();\n\n// ── Pure helpers (module-level, no reactive deps) ─────────────────────────────\n\n/**\n * Builds recursive `categories { ... }` fragment string for the GraphQL query.\n */\nfunction buildCategoriesQuery(depth: number): string {\n if (depth === 0) return '';\n return `\n categories {\n categoryId\n hidden\n name(language: $language) { value language }\n slug(language: $language) { value }\n ${buildCategoriesQuery(depth - 1)}\n }\n `;\n}\n\n/**\n * Maps a raw SDK category (LocalizedString arrays) to a flat MenuCategory.\n * Picks the entry matching `language`, falls back to first entry.\n */\nfunction mapCategory(raw: MenuCategoryRaw, language: string): MenuCategory {\n const nameEntry = raw.name?.find(n => n.language === language) ?? raw.name?.[0];\n const slugEntry = raw.slug?.[0];\n return {\n categoryId: raw.categoryId,\n name: nameEntry?.value ?? '',\n slug: slugEntry?.value ?? '',\n children: (raw.categories ?? [])\n .filter(child => !isHidden(child))\n .map(child => mapCategory(child, language)),\n };\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useMenu(options: UseMenuOptions): UseMenuReturn {\n const { graphqlClient } = options;\n const languageRef = options.language ?? ref('NL');\n const depth = options.depth ?? 3;\n const cacheTtlMs = options.cacheTtlMs ?? CACHE_TTL_DEFAULT;\n\n const categories = ref<MenuCategory[]>([]) as Ref<MenuCategory[]>;\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n // ── Cache helpers ──────────────────────────────────────────────────────────\n\n function cacheKey(categoryId: number, lang: string, userKey = ''): string {\n return `propeller_menu_${categoryId}_${lang}${userKey ? `_${userKey}` : ''}`;\n }\n\n function getFromCache(key: string): MenuCategory[] | null {\n if (typeof window === 'undefined') return null;\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n const parsed: { data: MenuCategory[]; expiresAt: number } = JSON.parse(raw);\n // Reject stale format (old Menu.tsx stored { data: Category, expires: ... })\n if (!Array.isArray(parsed.data)) { localStorage.removeItem(key); return null; }\n if (Date.now() > parsed.expiresAt) { localStorage.removeItem(key); return null; }\n return parsed.data;\n } catch { return null; }\n }\n\n function saveToCache(key: string, data: MenuCategory[]): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(key, JSON.stringify({ data, expiresAt: Date.now() + cacheTtlMs }));\n } catch { /* localStorage quota exceeded — silently ignore */ }\n }\n\n function clearCache(rootCategoryId: number, lang: string, userKey = ''): void {\n if (typeof window === 'undefined') return;\n try { localStorage.removeItem(cacheKey(rootCategoryId, lang, userKey)); } catch {}\n }\n\n // ── Fetch ──────────────────────────────────────────────────────────────────\n\n async function fetchMenu(rootCategoryId: number, userKey = ''): Promise<void> {\n const lang = languageRef.value || 'NL';\n const key = cacheKey(rootCategoryId, lang, userKey);\n const cached = getFromCache(key);\n if (cached) { categories.value = cached; return; }\n\n // Piggyback on an in-flight fetch for the same key instead of firing a\n // duplicate request (e.g. Menu + HomeFallback both mounting simultaneously).\n if (inflightFetches.has(key)) {\n loading.value = true;\n await inflightFetches.get(key);\n loading.value = false;\n const fresh = getFromCache(key);\n if (fresh) categories.value = fresh;\n return;\n }\n\n loading.value = true;\n error.value = null;\n\n let resolve!: () => void;\n const promise = new Promise<void>(res => { resolve = res; });\n inflightFetches.set(key, promise);\n\n try {\n // Build recursive query via buildCategoriesQuery() + the query string\n const gql = `\n query Menu($categoryId: Float, $language: String) {\n category(categoryId: $categoryId) {\n categoryId\n hidden\n name(language: $language) { value language }\n slug(language: $language) { value }\n ${buildCategoriesQuery(depth)}\n }\n }\n `;\n const variables: Record<string, unknown> = { categoryId: rootCategoryId, language: lang };\n\n // graphqlClient.query() extracts .data and throws on GraphQL errors\n const data = await graphqlClient.query<{ category: MenuCategoryRaw }>(gql, variables);\n const root = data?.category ?? null;\n\n // Return subcategories of root (L1 items) via getSubCategories(rootCategory)\n const items: MenuCategory[] = root\n ? (root.categories ?? [])\n .filter(cat => !isHidden(cat))\n .map(cat => mapCategory(cat, lang))\n : [];\n\n categories.value = items;\n if (items.length > 0) saveToCache(key, items);\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch menu';\n } finally {\n inflightFetches.delete(key);\n resolve();\n loading.value = false;\n }\n }\n\n return { categories, loading, error, fetchMenu, clearCache };\n}\n","/**\n * usePagination (Vue) — Shared pagination logic.\n *\n * Used by useOrders, useProductSearch, useFavorites, and any composable\n * with paged API results.\n */\n\nimport { ref, computed, type Ref, type ComputedRef } from 'vue';\n\nexport interface PaginationState {\n currentPage: Ref<number>;\n totalPages: Ref<number>;\n totalItems: Ref<number>;\n itemsPerPage: Ref<number>;\n hasNextPage: ComputedRef<boolean>;\n hasPreviousPage: ComputedRef<boolean>;\n goToPage: (page: number) => void;\n nextPage: () => void;\n previousPage: () => void;\n setFromResponse: (response: { itemsFound?: number; pages?: number; offset?: number }) => void;\n reset: () => void;\n}\n\nexport function usePagination(initialItemsPerPage = 10): PaginationState {\n const currentPage = ref(1);\n const totalPages = ref(1);\n const totalItems = ref(0);\n const itemsPerPage = ref(initialItemsPerPage);\n\n const hasNextPage = computed(() => currentPage.value < totalPages.value);\n const hasPreviousPage = computed(() => currentPage.value > 1);\n\n function goToPage(page: number) {\n if (page >= 1) {\n currentPage.value = page;\n }\n }\n\n function nextPage() {\n if (hasNextPage.value) currentPage.value++;\n }\n\n function previousPage() {\n if (hasPreviousPage.value) currentPage.value--;\n }\n\n function setFromResponse(response: { itemsFound?: number; pages?: number; offset?: number }) {\n totalItems.value = response.itemsFound ?? 0;\n totalPages.value =\n response.pages ??\n Math.ceil((response.itemsFound ?? 0) / (response.offset ?? itemsPerPage.value));\n if (response.offset) {\n itemsPerPage.value = response.offset;\n }\n }\n\n function reset() {\n currentPage.value = 1;\n totalPages.value = 1;\n totalItems.value = 0;\n }\n\n return {\n currentPage,\n totalPages,\n totalItems,\n itemsPerPage,\n hasNextPage,\n hasPreviousPage,\n goToPage,\n nextPage,\n previousPage,\n setFromResponse,\n reset,\n };\n}\n","/**\n * useOrders (Vue) — Order list, search, PDF download and reorder flow.\n *\n * Covers: OrderList, OrderActions, QuoteActions components.\n *\n * Responsibilities:\n * - Paginated order fetch with search/filter\n * - PDF download (base64/Uint8Array → blob → browser download)\n * - Reorder: parent-item filtering, cluster detection, sequential addItemToCart\n * - Quote status update (QuoteActions)\n */\n\nimport { ref, markRaw, watch, type Ref } from 'vue';\nimport { OrderItemClass, OrderSearchFields, OrderType, YesNo } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Order,\n OrderItem,\n Cart,\n OrderSearchArguments,\n DateSearchInput,\n DecimalSearchInput,\n OrderSortInput,\n Base64File,\n CartAddItemVariables,\n MediaImageProductSearchInput,\n TransformationsInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { usePagination } from '../shared/usePagination';\nimport { initCart } from '../shared/utils/cartInit';\nimport type { AnyUser } from '@propeller-commerce/propeller-v2-core-ui';\nimport { isContact, isCustomer } from '@propeller-commerce/propeller-v2-core-ui';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface OrderSearchForm {\n term?: string;\n createdAt?: DateSearchInput;\n lastModifiedAt?: DateSearchInput;\n price?: DecimalSearchInput;\n sortInput?: Partial<OrderSortInput>;\n type?: OrderType;\n}\n\nexport interface UseOrdersOptions {\n graphqlClient: GraphQLClient;\n user: Ref<AnyUser>;\n companyId?: Ref<number | undefined>;\n language?: Ref<string>;\n itemsPerPage?: number;\n /** Default statuses to filter by */\n orderStatuses?: string[];\n termFields?: OrderSearchFields[];\n configuration?: {\n imageSearchFiltersGrid?: MediaImageProductSearchInput;\n imageVariantFiltersSmall?: TransformationsInput;\n };\n channelIds?: number[];\n onCartCreated?: (cart: Cart) => void;\n afterReorder?: (cart: Cart) => void;\n}\n\nexport interface UseOrdersReturn {\n // Order list\n orders: Ref<Order[]>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n searchForm: Ref<OrderSearchForm>;\n\n // Single order\n currentOrder: Ref<Order | null>;\n orderLoading: Ref<boolean>;\n\n // Pagination (from usePagination)\n currentPage: Ref<number>;\n totalPages: Ref<number>;\n totalItems: Ref<number>;\n itemsPerPage: Ref<number>;\n\n // Actions\n fetchOrders: (page?: number) => Promise<void>;\n fetchOrder: (orderId: number) => Promise<Order | null>;\n goToPage: (page: number) => void;\n resetSearch: () => void;\n downloadPdf: (order: Order) => Promise<{ success: boolean; error?: string }>;\n downloadQuotePdf: (quoteId: number) => Promise<{ success: boolean; error?: string }>;\n reorder: (order: Order, cartId?: string) => Promise<{ success: boolean; cart?: Cart; error?: string }>;\n setQuoteStatus: (\n orderId: number,\n flags: { status?: string }\n ) => Promise<{ success: boolean; error?: string }>;\n}\n\nexport function useOrders(options: UseOrdersOptions): UseOrdersReturn {\n const {\n graphqlClient,\n user,\n orderStatuses = ['NEW', 'CONFIRMED', 'VALIDATED', 'ORDER'],\n configuration = {},\n onCartCreated,\n afterReorder,\n } = options;\n\n const companyIdRef = options.companyId ?? ref<number | undefined>(undefined);\n const languageRef = options.language ?? ref('NL');\n\n const orders = ref<Order[]>([]) as Ref<Order[]>;\n const loading = ref(false);\n const error = ref<string | null>(null);\n const searchForm = ref<OrderSearchForm>({});\n const currentOrder = ref<Order | null>(null) as Ref<Order | null>;\n const orderLoading = ref(false);\n\n const termFields = options.termFields ?? [\n OrderSearchFields.REFERENCE,\n OrderSearchFields.ITEM_SKU,\n OrderSearchFields.ID,\n OrderSearchFields.ITEM_NAME,\n OrderSearchFields.REMARKS,\n ];\n\n const pagination = usePagination(options.itemsPerPage ?? 10);\n\n // ── Fetch orders ──────────────────────────────────────────────────────────\n\n async function fetchOrders(page = 1): Promise<void> {\n const u = user.value;\n if (!u) return;\n\n loading.value = true;\n error.value = null;\n\n try {\n const service = createServices(graphqlClient).order;\n\n const userId: number = isContact(u) ? u.contactId : isCustomer(u) ? u.customerId : 0;\n const companyId = companyIdRef.value ?? (isContact(u) ? u.company?.companyId : null);\n\n const searchArgs: OrderSearchArguments = {\n status: orderStatuses,\n userId: [userId!],\n ...(companyId && { companyIds: [companyId] }),\n page,\n offset: pagination.itemsPerPage.value,\n term: searchForm.value.term || '',\n termFields,\n ...(searchForm.value.createdAt && { createdAt: searchForm.value.createdAt }),\n ...(searchForm.value.lastModifiedAt && { lastModifiedAt: searchForm.value.lastModifiedAt }),\n ...(searchForm.value.price && { price: searchForm.value.price }),\n ...(searchForm.value.sortInput && { sortInputs: [searchForm.value.sortInput as OrderSortInput] }),\n ...(searchForm.value.type && { type: [searchForm.value.type] }),\n ...(options.channelIds?.length && { channelIds: options.channelIds }),\n };\n\n const response = await service.getOrders(searchArgs);\n orders.value = response.items || [];\n pagination.setFromResponse(response);\n pagination.currentPage.value = page;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch orders';\n orders.value = [];\n } finally {\n loading.value = false;\n }\n }\n\n function resetSearch(): void {\n searchForm.value = {};\n fetchOrders(1);\n }\n\n // ── Watch user + companyId for re-fetch ───────────────────────────────────\n\n watch(\n [user, companyIdRef, pagination.currentPage],\n ([u]: [AnyUser, number | undefined, number]) => { if (u) fetchOrders(pagination.currentPage.value); },\n { immediate: true }\n );\n\n // ── Fetch single order ────────────────────────────────────────────────────\n\n async function fetchOrder(orderId: number): Promise<Order | null> {\n orderLoading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).order;\n const result = await service.getOrder({\n orderId,\n language: languageRef.value || 'NL',\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n });\n currentOrder.value = result ? markRaw(result) : null;\n return currentOrder.value;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch order';\n currentOrder.value = null;\n return null;\n } finally {\n orderLoading.value = false;\n }\n }\n\n // ── PDF blob download helper ──────────────────────────────────────────────\n\n function triggerBlobDownload(pdfResponse: Base64File | string, fallbackFileName: string): { success: boolean; error?: string } {\n let byteArray: Uint8Array;\n let contentType = 'application/pdf';\n let fileName = fallbackFileName;\n\n if (typeof pdfResponse === 'object' && (pdfResponse as Base64File).base64) {\n const r = pdfResponse as Base64File;\n const chars = atob(r.base64);\n byteArray = new Uint8Array(chars.length);\n for (let i = 0; i < chars.length; i++) byteArray[i] = chars.charCodeAt(i);\n contentType = r.contentType || contentType;\n fileName = r.fileName || fileName;\n } else if (typeof pdfResponse === 'string') {\n const chars = atob(pdfResponse);\n byteArray = new Uint8Array(chars.length);\n for (let i = 0; i < chars.length; i++) byteArray[i] = chars.charCodeAt(i);\n } else {\n return { success: false, error: 'Unrecognised PDF format' };\n }\n\n const blob = new Blob([byteArray.buffer as ArrayBuffer], { type: contentType });\n const url = window.URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n window.URL.revokeObjectURL(url);\n return { success: true };\n }\n\n // ── PDF download ──────────────────────────────────────────────────────────\n\n async function downloadPdf(order: Order): Promise<{ success: boolean; error?: string }> {\n if (!order?.id) return { success: false, error: 'No order ID' };\n try {\n const service = createServices(graphqlClient).order;\n const pdfResponse = await service.getOrderPDF(order.id);\n if (!pdfResponse) return { success: false, error: 'No PDF response' };\n return triggerBlobDownload(pdfResponse as Base64File | string, `order-${order.id}-confirmation.pdf`);\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to download PDF' };\n }\n }\n\n async function downloadQuotePdf(quoteId: number): Promise<{ success: boolean; error?: string }> {\n if (!quoteId) return { success: false, error: 'No quote ID' };\n try {\n const service = createServices(graphqlClient).order;\n const pdfResponse = await service.getQuotePDF(quoteId);\n if (!pdfResponse) return { success: false, error: 'No PDF response' };\n return triggerBlobDownload(pdfResponse as Base64File | string, `quote-${quoteId}.pdf`);\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to download quote PDF' };\n }\n }\n\n // ── Reorder ───────────────────────────────────────────────────────────────\n\n async function reorder(\n order: Order,\n existingCartId?: string\n ): Promise<{ success: boolean; cart?: Cart; error?: string }> {\n if (!order?.items) return { success: false, error: 'No order items' };\n\n try {\n // Resolve cart\n let resolvedCartId = existingCartId;\n if (!resolvedCartId) {\n const lang = languageRef.value || 'NL';\n const c = await initCart({\n graphqlClient,\n user: user.value,\n companyId: companyIdRef.value,\n language: lang,\n imageSearchFilters: configuration.imageSearchFiltersGrid!,\n imageVariantFilters: configuration.imageVariantFiltersSmall!,\n onCartCreated,\n });\n resolvedCartId = c.cartId;\n }\n\n const cartService = createServices(graphqlClient).cart;\n const language = languageRef.value || 'NL';\n\n // Filter to product parent items (exclude bonuses and children)\n const allProducts = order.items.filter(\n (item: OrderItem) => item.class === OrderItemClass.product && item.isBonus === YesNo.N\n );\n const parentItems = allProducts.filter((item: OrderItem) => !item.parentOrderItemId);\n\n // Build child map\n const childMap = new Map<number, OrderItem[]>();\n allProducts\n .filter((item: OrderItem) => item.parentOrderItemId)\n .forEach((item: OrderItem) => {\n const arr = childMap.get(item.parentOrderItemId!) || [];\n arr.push(item);\n childMap.set(item.parentOrderItemId!, arr);\n });\n\n let lastCart: Cart | null = null;\n\n for (const item of parentItems) {\n if (!item.productId) continue;\n\n const isCluster =\n item.product?.cluster && typeof item.product.cluster === 'object';\n const children = childMap.get(item.id) || [];\n let clusterId: number | undefined;\n let childItems: { productId: number; quantity: number }[] | undefined;\n\n if (isCluster && item.product!.cluster) {\n clusterId = item.product!.cluster.clusterId;\n if (children.length > 0) {\n childItems = children\n .filter((c) => c.productId)\n .map((c) => ({ productId: c.productId!, quantity: c.quantity || item.quantity || 1 }));\n }\n }\n\n const addVars: CartAddItemVariables = {\n id: resolvedCartId,\n input: {\n productId: item.productId,\n quantity: item.quantity || 1,\n ...(clusterId !== undefined && { clusterId }),\n ...(childItems && { childItems }),\n },\n language,\n imageSearchFilters: configuration.imageSearchFiltersGrid!,\n imageVariantFilters: configuration.imageVariantFiltersSmall!,\n };\n\n lastCart = await cartService.addItemToCart(addVars);\n }\n\n if (lastCart) {\n afterReorder?.(lastCart);\n return { success: true, cart: lastCart };\n }\n return { success: false, error: 'No items were added' };\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Reorder failed' };\n }\n }\n\n // ── Quote status ──────────────────────────────────────────────────────────\n\n async function setQuoteStatus(\n orderId: number,\n flags: { status?: string }\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const service = createServices(graphqlClient).order;\n await service.setOrderStatus({ orderId, ...flags });\n return { success: true };\n } catch (e: unknown) {\n return { success: false, error: e instanceof Error ? e.message : 'Failed to update status' };\n }\n }\n\n return {\n orders,\n loading,\n error,\n searchForm,\n currentOrder,\n orderLoading,\n currentPage: pagination.currentPage,\n totalPages: pagination.totalPages,\n totalItems: pagination.totalItems,\n itemsPerPage: pagination.itemsPerPage,\n fetchOrders,\n fetchOrder,\n goToPage: pagination.goToPage,\n resetSearch,\n downloadPdf,\n downloadQuotePdf,\n reorder,\n setQuoteStatus,\n };\n}\n","/**\n * useProductBundles (Vue) — Bundle fetching and add-to-cart flow.\n *\n * Covers: ProductBundles component.\n *\n * Responsibilities:\n * - BundleService.getBundles for a given product\n * - 3-step cart init (reuses shared cartInit utility)\n * - CartService.addBundleToCart\n * - Bundle discount calculation\n */\n\nimport { ref, type Ref } from 'vue';\nimport type {\n GraphQLClient,\n Cart,\n Bundle,\n MediaImageProductSearchInput,\n TransformationsInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { initCart } from '../shared/utils/cartInit';\nimport type { AnyUser } from '@propeller-commerce/propeller-v2-core-ui';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface UseProductBundlesOptions {\n graphqlClient: GraphQLClient;\n user: Ref<AnyUser>;\n companyId?: Ref<number | undefined>;\n language?: Ref<string>;\n configuration: {\n language?: string;\n imageSearchFiltersGrid: MediaImageProductSearchInput;\n imageVariantFiltersSmall: TransformationsInput;\n };\n onCartCreated?: (cart: Cart) => void;\n}\n\n/**\n * A bundle as the component consumes it. `BundleService.getBundles`\n * returns `BundlesResponse` whose `items` are SDK `Bundle` objects\n * (`id`, `name`, `description`, `condition`, `price`, `items`), so this\n * is an alias of the SDK type.\n */\nexport type BundleItem = Bundle;\n\nexport interface UseProductBundlesReturn {\n bundles: Ref<BundleItem[]>;\n loading: Ref<boolean>;\n adding: Ref<boolean>;\n error: Ref<string | null>;\n cartId: Ref<string>;\n fetchBundles: (productId: number) => Promise<void>;\n addBundleToCart: (bundleId: string, existingCartId?: string) => Promise<{ success: boolean; cart?: Cart; error?: string }>;\n calcDiscountPercent: (original: number, discounted: number) => number;\n}\n\nexport function useProductBundles(options: UseProductBundlesOptions): UseProductBundlesReturn {\n const { graphqlClient, user, configuration, onCartCreated } = options;\n const companyIdRef = options.companyId ?? ref<number | undefined>(undefined);\n const languageRef = options.language ?? ref('NL');\n\n const bundles = ref<BundleItem[]>([]) as Ref<BundleItem[]>;\n const loading = ref(false);\n const adding = ref(false);\n const error = ref<string | null>(null);\n const cartId = ref('');\n\n async function fetchBundles(productId: number): Promise<void> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).bundle;\n const language = languageRef.value || configuration.language || 'NL';\n const result = await service.getBundles({\n input: { productIds: [productId], page: 1, offset: 100 },\n language,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n });\n bundles.value = ((result as any)?.items || []) as BundleItem[];\n } catch (e: any) {\n error.value = e?.message || 'Failed to fetch bundles';\n } finally {\n loading.value = false;\n }\n }\n\n async function addBundleToCart(\n bundleId: string,\n existingCartId?: string\n ): Promise<{ success: boolean; cart?: Cart; error?: string }> {\n adding.value = true;\n error.value = null;\n try {\n const language = languageRef.value || configuration.language || 'NL';\n\n // Resolve cart ID\n let resolvedCartId = existingCartId || cartId.value;\n if (!resolvedCartId) {\n const cart = await initCart({\n graphqlClient,\n user: user.value,\n companyId: companyIdRef.value,\n language,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n onCartCreated: (c) => {\n cartId.value = c.cartId;\n onCartCreated?.(c);\n },\n });\n resolvedCartId = cart.cartId;\n cartId.value = resolvedCartId;\n }\n\n const cartService = createServices(graphqlClient).cart;\n const cart = await cartService.addBundleToCart({\n id: resolvedCartId,\n input: { bundleId: String(bundleId) },\n language,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersSmall,\n });\n\n return { success: true, cart };\n } catch (e: any) {\n const msg = e?.message || 'Failed to add bundle to cart';\n error.value = msg;\n return { success: false, error: msg };\n } finally {\n adding.value = false;\n }\n }\n\n function calcDiscountPercent(original: number, discounted: number): number {\n if (!original || original === 0) return 0;\n return Math.round(((original - discounted) / original) * 100);\n }\n\n return {\n bundles,\n loading,\n adding,\n error,\n cartId,\n fetchBundles,\n addBundleToCart,\n calcDiscountPercent,\n };\n}\n","/**\n * useProductInfo (Vue) — Sequential product/cluster data fetching.\n *\n * Covers: ProductInfo, ClusterInfo, ProductCard, ClusterCard components.\n *\n * Responsibilities:\n * - ProductInfo: getOrderlists → getProduct (sequential; orderlists needed for price tier)\n * - ClusterInfo: getClusterConfig → getCluster (sequential; config drives attribute names)\n * - priceCalculateProductInput + userBulkPriceProductInput for correct per-user pricing\n * - Cluster fallback chain: cluster → defaultProduct for name/sku/price/image\n */\n\nimport { ref, computed, type Ref, type ComputedRef } from 'vue';\nimport {\n ProductService,\n ClusterService,\n OrderlistService,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Product,\n Cluster,\n Contact,\n Customer,\n LocalizedString,\n ClusterConfigSetting,\n ProductVariables,\n ClusterVariables,\n PriceCalculateProductInput,\n UserBulkPriceProductInput,\n AttributeResultSearchInput,\n MediaImageProductSearchInput,\n TransformationsInput,\n OrderlistSearchInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface UseProductInfoOptions {\n graphqlClient: GraphQLClient;\n language?: Ref<string>;\n taxZone?: string;\n user?: Ref<Contact | Customer | null>;\n companyId?: Ref<number | undefined>;\n /** Attribute names to include in attributeResultSearchInput (productTrackAttributes). */\n productTrackAttributes?: string[];\n configuration?: {\n imageSearchFiltersGrid?: MediaImageProductSearchInput;\n /** Used for products (ProductInfo). */\n imageVariantFiltersLarge?: TransformationsInput;\n /** Used for clusters (ClusterInfo). */\n imageVariantFiltersMedium?: TransformationsInput;\n /** Alias: some configs use imageVariantFiltersSmall for product images. */\n imageVariantFiltersSmall?: TransformationsInput;\n };\n}\n\nexport interface UseProductInfoReturn {\n product: Ref<Product | null>;\n cluster: Ref<Cluster | null>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n fetchProduct: (productId: number, imageSearchFilters?: MediaImageProductSearchInput, imageVariantFilters?: TransformationsInput) => Promise<void>;\n fetchCluster: (clusterId: number, imageSearchFilters?: MediaImageProductSearchInput, imageVariantFilters?: TransformationsInput) => Promise<void>;\n // Cluster display helpers (fallback chain: cluster → defaultProduct)\n clusterName: ComputedRef<string>;\n clusterSku: ComputedRef<string>;\n clusterPrice: ComputedRef<number | null>;\n clusterImageUrl: ComputedRef<string>;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useProductInfo(options: UseProductInfoOptions): UseProductInfoReturn {\n const { graphqlClient, configuration = {} } = options;\n const languageRef = options.language ?? ref('NL');\n const taxZone = options.taxZone ?? 'NL';\n\n const product = ref<Product | null>(null) as Ref<Product | null>;\n const cluster = ref<Cluster | null>(null) as Ref<Cluster | null>;\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n // ── Shared price input builders ───────────────────────────────────────────\n\n function buildPriceInput(): PriceCalculateProductInput {\n const user = options.user?.value ?? null;\n const companyId = options.companyId?.value;\n const input: PriceCalculateProductInput = { taxZone };\n if (companyId) input.companyId = companyId;\n if (user && 'contactId' in user) input.contactId = (user as Contact).contactId;\n if (user && 'customerId' in user) input.customerId = (user as Customer).customerId;\n return input;\n }\n\n function buildBulkPriceInput(): UserBulkPriceProductInput {\n const user = options.user?.value ?? null;\n const companyId = options.companyId?.value;\n const input: UserBulkPriceProductInput = { taxZone };\n if (companyId) input.companyId = companyId;\n if (user && 'contactId' in user) input.contactId = (user as Contact).contactId;\n if (user && 'customerId' in user) input.customerId = (user as Customer).customerId;\n return input;\n }\n\n function buildAttributeInput(): AttributeResultSearchInput | undefined {\n const names = options.productTrackAttributes;\n if (!names || names.length === 0) return undefined;\n return { attributeDescription: { names } };\n }\n\n // ── Fetch product ─────────────────────────────────────────────────────────\n // getOrderlists first (if user+companyId), then getProduct.\n\n async function fetchProduct(\n productId: number,\n imageSearchFilters?: MediaImageProductSearchInput,\n imageVariantFilters?: TransformationsInput,\n ): Promise<void> {\n loading.value = true;\n error.value = null;\n try {\n const lang = languageRef.value || 'NL';\n const user = options.user?.value ?? null;\n const companyId = options.companyId?.value;\n\n // Step 1: resolve orderlist IDs\n let orderlistIds: number[] = [];\n if (user && companyId) {\n const orderlistService = createServices(graphqlClient).orderlist;\n const searchInput: OrderlistSearchInput = { companyIds: [companyId] };\n const orderlists = await orderlistService.getOrderlists(searchInput);\n orderlistIds = (orderlists?.items ?? []).map((ol) => ol.id);\n }\n\n // Step 2: fetch product with full inputs\n const service = createServices(graphqlClient).product;\n const attributeInput = buildAttributeInput();\n\n const variables: ProductVariables = {\n productId,\n language: lang,\n applyOrderlists: true,\n orderlistIds,\n imageSearchFilters: imageSearchFilters ?? configuration.imageSearchFiltersGrid,\n imageVariantFilters: (imageVariantFilters ?? configuration.imageVariantFiltersLarge ?? configuration.imageVariantFiltersSmall) as TransformationsInput,\n priceCalculateProductInput: buildPriceInput(),\n userBulkPriceProductInput: buildBulkPriceInput(),\n ...(attributeInput && { attributeResultSearchInput: attributeInput }),\n };\n\n const result = await service.getProduct(variables);\n product.value = result;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch product';\n } finally {\n loading.value = false;\n }\n }\n\n // ── Fetch cluster ─────────────────────────────────────────────────────────\n // getClusterConfig first, then getCluster with attributeNames.\n\n async function fetchCluster(\n clusterId: number,\n imageSearchFilters?: MediaImageProductSearchInput,\n imageVariantFilters?: TransformationsInput,\n ): Promise<void> {\n loading.value = true;\n error.value = null;\n try {\n const lang = languageRef.value || 'NL';\n const service = createServices(graphqlClient).cluster;\n\n // Step 1: get cluster config to extract attribute names\n const clusterConfig = await service.getClusterConfig(clusterId);\n const attributeNames: string[] =\n (clusterConfig?.config?.settings ?? []).map(\n (setting: ClusterConfigSetting) => setting.name\n );\n\n // Step 2: fetch cluster with full inputs\n const variables: ClusterVariables = {\n clusterId,\n language: lang,\n imageSearchFilters: imageSearchFilters ?? configuration.imageSearchFiltersGrid,\n imageVariantFilters: (imageVariantFilters ?? configuration.imageVariantFiltersMedium) as TransformationsInput,\n priceCalculateProductInput: buildPriceInput(),\n ...(attributeNames.length > 0 && {\n attributeResultSearchInput: {\n attributeDescription: { names: attributeNames },\n } as AttributeResultSearchInput,\n }),\n };\n\n const result = await service.getCluster(variables);\n cluster.value = result;\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch cluster';\n } finally {\n loading.value = false;\n }\n }\n\n // ── Cluster display helpers (fallback chain: cluster → defaultProduct) ────\n\n const clusterName = computed<string>(() => {\n const c = cluster.value;\n if (!c) return '';\n const lang = languageRef.value || 'NL';\n const names: LocalizedString[] = c.names ?? [];\n if (names.length) {\n const match = names.find(n => n.language === lang);\n return match?.value ?? names[0]?.value ?? '';\n }\n const dp = c.defaultProduct;\n const dpNames: LocalizedString[] = dp?.names ?? [];\n const dpMatch = dpNames.find(n => n.language === lang);\n return dpMatch?.value ?? dpNames[0]?.value ?? '';\n });\n\n const clusterSku = computed<string>(() => {\n const c = cluster.value;\n if (!c) return '';\n return c.sku || c.defaultProduct?.sku || '';\n });\n\n const clusterPrice = computed<number | null>(() => {\n const c = cluster.value;\n if (!c) return null;\n const dp = c.defaultProduct;\n return dp?.price?.gross ?? null;\n });\n\n const clusterImageUrl = computed<string>(() => {\n const c = cluster.value;\n if (!c) return '';\n const dp = c.defaultProduct;\n return dp?.media?.images?.items?.[0]?.imageVariants?.[0]?.url ?? '';\n });\n\n return {\n product,\n cluster,\n loading,\n error,\n fetchProduct,\n fetchCluster,\n clusterName,\n clusterSku,\n clusterPrice,\n clusterImageUrl,\n };\n}\n","/**\n * useProductSearch (Vue) — Product fetching, filtering, race condition prevention.\n *\n * Covers: ProductGrid, GridFilters, GridToolbar, SearchBar components.\n *\n * Responsibilities:\n * - CategoryService query building\n * - Race condition prevention (fetchId counter)\n * - Language-based product filtering (untranslated excluded)\n * - Dual-mode: controlled (external products prop) vs uncontrolled (internal fetch)\n * - Sort, page size, text filters, price range, pagination\n * - Debounced search bar (300ms)\n */\n\nimport { ref, computed, watch, type Ref, type ComputedRef } from 'vue';\nimport { CategoryService, ProductSearchableField, ProductSortField, ProductStatus, SortOrder } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Product,\n Cluster,\n Contact,\n Customer,\n ProductsResponse,\n AttributeFilter,\n ProductTextFilterInput,\n Category,\n CategoryQueryVariables,\n CategoryProductSearchInput,\n ProductSortInput,\n SearchFieldsInput,\n ProductPriceFilterInput,\n PriceCalculateProductInput,\n FilterAvailableAttributeInput,\n MediaImageProductSearchInput,\n TransformationsInput,\n ProductsQueryVariables,\n ProductSearchInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { usePagination } from '../shared/usePagination';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface UseProductSearchOptions {\n graphqlClient?: GraphQLClient;\n /** Controlled mode: pass products in, skip internal fetch */\n products?: Ref<(Product | Cluster)[] | undefined>;\n categoryId?: Ref<number | undefined>;\n term?: Ref<string | undefined>;\n brand?: Ref<string | undefined>;\n language?: Ref<string>;\n taxZone?: string;\n user?: Ref<Contact | Customer | null>;\n companyId?: Ref<number | undefined>;\n textFilters?: Ref<ProductTextFilterInput[] | undefined>;\n priceFilterMin?: Ref<number | undefined>;\n priceFilterMax?: Ref<number | undefined>;\n sortField?: Ref<string | undefined>;\n sortOrder?: Ref<string | undefined>;\n page?: Ref<number | undefined>;\n pageSize?: Ref<number>;\n configuration: {\n baseCategoryId?: number;\n imageSearchFiltersGrid?: MediaImageProductSearchInput;\n imageVariantFiltersMedium?: TransformationsInput;\n };\n onFiltersChange?: (filters: AttributeFilter[]) => void;\n onPriceBoundsChange?: (min: number, max: number) => void;\n onItemsFoundChange?: (count: number) => void;\n onPageChange?: (page: number) => void;\n onProductsResponse?: (products: ProductsResponse) => void;\n onCategoryChange?: (category: Category) => void;\n}\n\nexport interface UseProductSearchReturn {\n displayProducts: ComputedRef<(Product | Cluster)[]>;\n itemsFound: Ref<number>;\n isLoading: ComputedRef<boolean>;\n currentSortField: Ref<string>;\n currentSortOrder: Ref<string>;\n currentPage: Ref<number>;\n totalPages: Ref<number>;\n // Search bar\n searchTerm: Ref<string>;\n searchResults: Ref<(Product | Cluster)[]>;\n searchItemsFound: Ref<number>;\n searchLoading: Ref<boolean>;\n // Actions\n fetchProducts: () => Promise<void>;\n search: (term: string) => void;\n goToPage: (page: number) => void;\n}\n\nexport function useProductSearch(options: UseProductSearchOptions): UseProductSearchReturn {\n const {\n graphqlClient,\n configuration,\n onFiltersChange,\n onPriceBoundsChange,\n onItemsFoundChange,\n onProductsResponse,\n onCategoryChange,\n } = options;\n\n const languageRef = options.language ?? ref('NL');\n const taxZone = options.taxZone || 'NL';\n const textFiltersRef = options.textFilters ?? ref<ProductTextFilterInput[] | undefined>(undefined);\n const priceMinRef = options.priceFilterMin ?? ref<number | undefined>(undefined);\n const priceMaxRef = options.priceFilterMax ?? ref<number | undefined>(undefined);\n const sortFieldRef = options.sortField ?? ref<string | undefined>(undefined);\n const sortOrderRef = options.sortOrder ?? ref<string | undefined>(undefined);\n const pageSizeRef = options.pageSize ?? ref(12);\n const userRef = options.user ?? ref(null);\n const companyIdRef = options.companyId ?? ref<number | undefined>(undefined);\n\n // ── Internal state ────────────────────────────────────────────────────────\n const internalProducts = ref<(Product | Cluster)[]>([]) as Ref<(Product | Cluster)[]>;\n const internalLoading = ref(false);\n let fetchId = 0;\n\n // Search bar state\n const searchTerm = ref('');\n const searchResults = ref<(Product | Cluster)[]>([]) as Ref<(Product | Cluster)[]>;\n const searchItemsFound = ref(0);\n const searchLoading = ref(false);\n let searchTimer: ReturnType<typeof setTimeout> | null = null;\n\n const pagination = usePagination(pageSizeRef.value);\n\n // Controlled vs uncontrolled — check the ref's VALUE, not the ref object itself.\n // ProductGrid always passes a computed ref (even when props.products is undefined),\n // so checking options.products !== undefined is always true and would break fetching.\n const isControlled = computed(() => options.products?.value !== undefined);\n\n const displayProducts = computed<(Product | Cluster)[]>(() => {\n if (isControlled.value) return options.products!.value ?? [];\n return internalProducts.value;\n });\n\n const isLoading = computed(() => !isControlled.value && internalLoading.value);\n\n const itemsFound = ref(0);\n const currentSortField = ref(options.sortField?.value ?? ProductSortField.RELEVANCE);\n const currentSortOrder = ref(options.sortOrder?.value ?? 'DESC');\n\n // ── Language filter ───────────────────────────────────────────────────────\n\n function filterByLanguage(products: (Product | Cluster)[], lang: string): (Product | Cluster)[] {\n if (!lang) return products;\n return products.filter((p) => {\n const names = (p as Product).names || (p as Cluster).names || [];\n if (!names || names.length === 0) return true;\n return names.some((n: { language?: string }) => n.language === lang);\n });\n }\n\n // ── Fetch products ────────────────────────────────────────────────────────\n\n async function fetchProducts(): Promise<void> {\n if (!graphqlClient || isControlled.value) return;\n\n // Bail out when nothing to fetch: no categoryId, term, or brand.\n // This prevents components like SearchBar (which only use `search()`) from\n // triggering a spurious category fetch on mount via the baseCategoryId fallback.\n if (!options.categoryId?.value && !options.term?.value && !options.brand?.value) return;\n\n const thisId = ++fetchId;\n internalLoading.value = true;\n\n try {\n const service = createServices(graphqlClient).category;\n const lang = languageRef.value || 'NL';\n const isWideSearch = !!(options.term?.value) || !!(options.brand?.value);\n const catId = isWideSearch\n ? (configuration?.baseCategoryId ?? 0)\n : (options.categoryId?.value ?? configuration?.baseCategoryId ?? 0);\n\n if (!catId) return;\n\n const activeSortField = (sortFieldRef.value ?? currentSortField.value) as ProductSortField;\n const activeSortOrder = (sortOrderRef.value ?? currentSortOrder.value) as SortOrder;\n\n // Build sort inputs\n const sortInputs: ProductSortInput[] = activeSortField\n ? [{ field: activeSortField, order: activeSortOrder }]\n : [];\n\n // Build search fields with boost when searching by term\n const searchFields: SearchFieldsInput[] = options.term?.value\n ? [\n {\n fieldNames: [\n ProductSearchableField.NAME,\n ProductSearchableField.KEYWORDS,\n ProductSearchableField.SKU,\n ProductSearchableField.CUSTOM_KEYWORDS,\n ],\n boost: 5,\n },\n {\n fieldNames: [\n ProductSearchableField.DESCRIPTION,\n ProductSearchableField.MANUFACTURER,\n ProductSearchableField.MANUFACTURER_CODE,\n ProductSearchableField.EAN_CODE,\n ProductSearchableField.BAR_CODE,\n ProductSearchableField.CLUSTER_ID,\n ProductSearchableField.CUSTOM_KEYWORDS,\n ProductSearchableField.PRODUCT_ID,\n ProductSearchableField.SHORT_DESCRIPTION,\n ProductSearchableField.SUPPLIER,\n ProductSearchableField.SUPPLIER_CODE,\n ],\n boost: 1,\n },\n ]\n : [];\n\n // Build price filter\n const priceFilter: ProductPriceFilterInput | undefined =\n priceMinRef.value !== undefined || priceMaxRef.value !== undefined\n ? { from: priceMinRef.value ?? 0, to: priceMaxRef.value ?? 999999 }\n : undefined;\n\n // Resolve user IDs\n const user = userRef.value;\n const userId: number | undefined =\n user && 'contactId' in user\n ? (user as Contact).contactId\n : user && 'customerId' in user\n ? (user as Customer).customerId\n : undefined;\n\n const contactId: number | undefined =\n user && 'contactId' in user ? (user as Contact).contactId : undefined;\n\n const customerId: number | undefined =\n user && 'customerId' in user ? (user as Customer).customerId : undefined;\n\n const categoryProductSearchInput: CategoryProductSearchInput = {\n language: lang,\n page: pagination.currentPage.value,\n offset: pageSizeRef.value,\n statuses: [\n ProductStatus.A,\n ProductStatus.P,\n ProductStatus.T,\n ProductStatus.S,\n ],\n hidden: false,\n ...(options.term?.value && { term: options.term.value, searchFields }),\n ...(options.brand?.value && { manufacturers: [options.brand.value] }),\n ...(textFiltersRef.value?.length && { textFilters: textFiltersRef.value }),\n ...(priceFilter && { price: priceFilter }),\n ...(sortInputs.length && { sortInputs }),\n ...(companyIdRef.value && { companyId: companyIdRef.value }),\n ...(userId !== undefined && { userId }),\n };\n\n const priceCalculateProductInput: PriceCalculateProductInput = {\n taxZone,\n ...(companyIdRef.value && { companyId: companyIdRef.value }),\n ...(contactId !== undefined && { contactId }),\n ...(customerId !== undefined && { customerId }),\n };\n\n const filterAvailableAttributeInput: FilterAvailableAttributeInput = {\n isSearchable: true,\n };\n\n const variables: CategoryQueryVariables = {\n categoryId: catId,\n language: lang,\n categoryProductSearchInput,\n priceCalculateProductInput,\n filterAvailableAttributeInput,\n imageSearchFilters: configuration?.imageSearchFiltersGrid,\n imageVariantFilters: configuration?.imageVariantFiltersMedium,\n };\n\n const response = await service.getCategory(variables);\n\n // Ignore stale responses\n if (thisId !== fetchId) return;\n\n const productsResponse = response?.products as ProductsResponse | undefined;\n const rawProducts = (productsResponse?.items ?? []) as (Product | Cluster)[];\n const filtered = filterByLanguage(rawProducts, lang);\n\n internalProducts.value = filtered;\n\n const untranslatedCount = rawProducts.length - filtered.length;\n const apiTotal = productsResponse?.itemsFound ?? rawProducts.length;\n const found = Math.max(0, apiTotal - untranslatedCount);\n\n itemsFound.value = found;\n onItemsFoundChange?.(found);\n\n if (productsResponse) {\n pagination.setFromResponse({\n itemsFound: found,\n pages: productsResponse.pages ?? 1,\n offset: productsResponse.offset ?? pageSizeRef.value,\n });\n onProductsResponse?.(productsResponse);\n }\n\n if (productsResponse?.filters) {\n onFiltersChange?.(productsResponse.filters);\n }\n\n // Price-slider bounds. The API's aggregated `minPrice`/`maxPrice` are\n // populated for anonymous catalog reads, but come back as 0 for a\n // logged-in (contact/company-priced) request — which would make the slider\n // fall back to a bogus 9999 cap. When the aggregate max is missing or 0,\n // derive the bounds from the resolved per-item prices in THIS result set\n // instead (the items carry the contact price). Uses `gross` (the catalog\n // filter scale; same field the API aggregate reflects), falling back to\n // `net`. Note: derived bounds reflect the current result page, not the\n // whole catalog — but that is strictly better than no/9999 bound, and the\n // anonymous path still uses the true catalog aggregate.\n const aggMin = productsResponse?.minPrice;\n const aggMax = productsResponse?.maxPrice;\n if (aggMax !== undefined && aggMax > 0) {\n onPriceBoundsChange?.(aggMin ?? 0, aggMax);\n } else {\n const prices = ((productsResponse?.items ?? []) as Product[])\n .map((p) => (p?.price?.gross ?? p?.price?.net))\n .filter((n): n is number => typeof n === 'number' && n > 0);\n if (prices.length) {\n onPriceBoundsChange?.(Math.floor(Math.min(...prices)), Math.ceil(Math.max(...prices)));\n }\n }\n\n if (response) {\n onCategoryChange?.(response as Category);\n }\n } catch (e) {\n console.error('[useProductSearch] fetchProducts error:', e);\n if (thisId === fetchId) internalProducts.value = [];\n } finally {\n if (thisId === fetchId) internalLoading.value = false;\n }\n }\n\n // ── Search bar (debounced, 300ms) ─────────────────────────────────────────\n\n function search(term: string): void {\n searchTerm.value = term;\n if (searchTimer) clearTimeout(searchTimer);\n if (!term.trim()) {\n searchResults.value = [];\n searchItemsFound.value = 0;\n return;\n }\n searchTimer = setTimeout(async () => {\n if (!graphqlClient) return;\n searchLoading.value = true;\n try {\n const service = createServices(graphqlClient).product;\n const lang = languageRef.value || 'NL';\n const input: ProductSearchInput = {\n term,\n language: lang,\n page: 1,\n offset: 10,\n statuses: [\n ProductStatus.A,\n ProductStatus.P,\n ProductStatus.T,\n ProductStatus.S,\n ],\n sortInputs: [{ field: ProductSortField.RELEVANCE, order: SortOrder.DESC }],\n searchFields: [\n {\n fieldNames: [\n ProductSearchableField.NAME,\n ProductSearchableField.KEYWORDS,\n ProductSearchableField.SKU,\n ProductSearchableField.CUSTOM_KEYWORDS,\n ],\n boost: 5,\n },\n {\n fieldNames: [\n ProductSearchableField.DESCRIPTION,\n ProductSearchableField.MANUFACTURER,\n ProductSearchableField.MANUFACTURER_CODE,\n ProductSearchableField.EAN_CODE,\n ProductSearchableField.BAR_CODE,\n ProductSearchableField.CLUSTER_ID,\n ProductSearchableField.CUSTOM_KEYWORDS,\n ProductSearchableField.PRODUCT_ID,\n ProductSearchableField.SHORT_DESCRIPTION,\n ProductSearchableField.SUPPLIER,\n ProductSearchableField.SUPPLIER_CODE,\n ],\n boost: 1,\n },\n ],\n };\n const variables: ProductsQueryVariables = {\n input,\n language: lang,\n imageVariantFilters: configuration?.imageVariantFiltersMedium as TransformationsInput,\n };\n const result = await service.getProducts(variables);\n searchResults.value = (result?.items ?? []) as (Product | Cluster)[];\n searchItemsFound.value = (result as any)?.itemsFound ?? searchResults.value.length;\n } catch {\n searchResults.value = [];\n searchItemsFound.value = 0;\n } finally {\n searchLoading.value = false;\n }\n }, 300);\n }\n\n // ── Watchers ──────────────────────────────────────────────────────────────\n\n // Sync externally-controlled page prop → internal pagination\n if (options.page) {\n watch(options.page, (newPage) => {\n if (newPage !== undefined && newPage !== pagination.currentPage.value) {\n pagination.currentPage.value = newPage;\n }\n });\n }\n\n watch(\n [\n () => options.categoryId?.value,\n () => options.term?.value,\n () => options.brand?.value,\n languageRef,\n textFiltersRef,\n priceMinRef,\n priceMaxRef,\n sortFieldRef,\n sortOrderRef,\n pageSizeRef,\n companyIdRef,\n userRef,\n pagination.currentPage,\n // Track the controlled flag so a parent that flips OUT of controlled\n // mode (e.g. on SPA navigation between categories, when the new route\n // has no SSR seed and the boilerplate sets :products=\"undefined\")\n // re-fires this watcher with the new uncontrolled state. Without this\n // dependency, the watcher had already fired when `categoryId` updated\n // but bailed because `isControlled.value` was still `true` from the\n // previous route; once the parent flipped controlled mode off, no\n // input the watcher tracks had changed again, so the fetch that\n // should run for the new category never started — the grid stayed\n // stuck on the previous category's items (or empty) until F5.\n isControlled,\n ],\n () => {\n if (!isControlled.value) fetchProducts();\n },\n { immediate: true }\n );\n\n return {\n displayProducts,\n itemsFound,\n isLoading,\n currentSortField,\n currentSortOrder,\n currentPage: pagination.currentPage,\n totalPages: pagination.totalPages,\n searchTerm,\n searchResults,\n searchItemsFound,\n searchLoading,\n fetchProducts,\n search,\n goToPage: pagination.goToPage,\n };\n}\n","/**\n * useProductSlider (Vue) — Crossupsell/product fetch + DOM scroll tracking.\n *\n * Covers: ProductSlider component.\n *\n * Responsibilities:\n * - fetchCrossupsells: CrossupsellService with priceCalculateProductInput + extract productTo/clusterTo\n * - fetchProducts: ProductService.getProducts() batch call (NOT per-item getProduct())\n * with statuses filter and filterAvailableAttributeInput\n * - Scroll position tracking for responsive sliding\n */\n\nimport { ref, type Ref } from 'vue';\nimport { CrossupsellService, CrossupsellType, ProductService, ProductStatus } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Product,\n Cluster,\n Contact,\n Customer,\n Crossupsell,\n CrossupsellsQueryVariables,\n ProductsQueryVariables,\n ProductSearchInput,\n PriceCalculateProductInput,\n FilterAvailableAttributeInput,\n MediaImageProductSearchInput,\n TransformationsInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface FetchCrossupsellsInput {\n productId?: number;\n clusterId?: number;\n types?: CrossupsellType[];\n}\n\nexport interface UseProductSliderOptions {\n graphqlClient: GraphQLClient;\n language?: Ref<string>;\n taxZone?: string;\n user?: Ref<Contact | Customer | null>;\n companyId?: Ref<number | undefined>;\n configuration?: {\n imageSearchFiltersGrid?: MediaImageProductSearchInput;\n imageVariantFiltersMedium?: TransformationsInput;\n };\n}\n\nexport interface UseProductSliderReturn {\n products: Ref<(Product | Cluster)[]>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n canScrollLeft: Ref<boolean>;\n canScrollRight: Ref<boolean>;\n fetchCrossupsells: (input: FetchCrossupsellsInput) => Promise<void>;\n fetchProducts: (productIds: number[], clusterIds?: number[]) => Promise<void>;\n scrollLeft: (containerEl: HTMLElement, itemWidth?: number) => void;\n scrollRight: (containerEl: HTMLElement, itemWidth?: number) => void;\n onScroll: (containerEl: HTMLElement) => void;\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useProductSlider(options: UseProductSliderOptions): UseProductSliderReturn {\n const { graphqlClient, configuration = {} } = options;\n const languageRef = options.language ?? ref('NL');\n const taxZone = options.taxZone ?? 'NL';\n\n const products = ref<(Product | Cluster)[]>([]) as Ref<(Product | Cluster)[]>;\n const loading = ref(false);\n const error = ref<string | null>(null);\n const canScrollLeft = ref(false);\n const canScrollRight = ref(false);\n\n // ── Price input builder ───────────────────────────────────────────────────\n\n function buildPriceInput(): PriceCalculateProductInput {\n const user = options.user?.value ?? null;\n const companyId = options.companyId?.value;\n const input: PriceCalculateProductInput = { taxZone };\n if (companyId) input.companyId = companyId;\n if (user && 'contactId' in user) input.contactId = (user as Contact).contactId;\n if (user && 'customerId' in user) input.customerId = (user as Customer).customerId;\n return input;\n }\n\n // ── Assortment filter ───────────────────────────────────────────────────\n // Resolves crossupsell items against the user's assortment via the same\n // `getProducts` query the listings use, and returns only the items that come\n // back (preserving the input order). Products outside the contact's\n // assortment are dropped — the backend simply omits them, exactly as it does\n // on the catalog/search pages (which scope by userId/companyId). On a query\n // failure we return the input unchanged so the slider isn't blanked.\n\n function resolveUserId(): number | undefined {\n const user = options.user?.value ?? null;\n if (user && 'contactId' in user) return (user as Contact).contactId;\n if (user && 'customerId' in user) return (user as Customer).customerId;\n return undefined;\n }\n\n function resolveCompanyId(): number | undefined {\n if (options.companyId?.value) return options.companyId.value;\n const user = options.user?.value ?? null;\n if (user && 'contactId' in user) return (user as Contact).company?.companyId;\n return undefined;\n }\n\n async function filterToAssortment(items: (Product | Cluster)[]): Promise<(Product | Cluster)[]> {\n if (!items.length) return items;\n\n const productIds: number[] = [];\n const clusterIds: number[] = [];\n for (const item of items) {\n if ('productId' in item && (item as Product).productId !== undefined) {\n productIds.push((item as Product).productId);\n } else if ('clusterId' in item && (item as Cluster).clusterId !== undefined) {\n clusterIds.push((item as Cluster).clusterId);\n }\n }\n if (!productIds.length && !clusterIds.length) return items;\n\n const lang = languageRef.value || 'NL';\n const userId = resolveUserId();\n const companyId = resolveCompanyId();\n const searchInput: ProductSearchInput = {\n ...(productIds.length && { productIds }),\n ...(clusterIds.length && { clusterIds }),\n language: lang,\n page: 1,\n offset: 50,\n statuses: [ProductStatus.A, ProductStatus.P, ProductStatus.T, ProductStatus.S],\n ...(userId !== undefined && { userId }),\n ...(companyId !== undefined && { companyId }),\n };\n const filterAvailableAttributeInput: FilterAvailableAttributeInput = { isSearchable: true };\n const variables: ProductsQueryVariables = {\n input: searchInput,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersMedium as TransformationsInput,\n filterAvailableAttributeInput,\n };\n\n try {\n const response = await createServices(graphqlClient).product.getProducts(variables);\n const resolved = (response?.items ?? []) as (Product | Cluster)[];\n const allowed = new Set<number>();\n for (const r of resolved) {\n const id = (r as Product).productId ?? (r as Cluster).clusterId;\n if (id !== undefined) allowed.add(id);\n }\n return items.filter((item) => {\n const id = (item as Product).productId ?? (item as Cluster).clusterId;\n return id !== undefined && allowed.has(id);\n });\n } catch {\n // Verification failed — don't blank the slider; show the raw crossupsells.\n return items;\n }\n }\n\n // ── Fetch crossupsells ────────────────────────────────────────────────────\n // fetchCrossUpsells():\n // - includes priceCalculateProductInput\n // - extracts productTo / clusterTo from each Crossupsell\n\n async function fetchCrossupsells(input: FetchCrossupsellsInput): Promise<void> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).crossupsell;\n const lang = languageRef.value || 'NL';\n const variables: CrossupsellsQueryVariables = {\n input: {\n page: 1,\n offset: 50,\n ...(input.types && input.types.length > 0 && { types: input.types }),\n ...(input.productId && { productIdsFrom: [input.productId] }),\n ...(input.clusterId && { clusterIdsFrom: [input.clusterId] }),\n },\n language: lang,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersMedium as TransformationsInput,\n priceCalculateProductInput: buildPriceInput(),\n };\n\n const result = await service.getCrossupsells(variables);\n const crossupsells: Crossupsell[] = result?.items ?? [];\n\n const items: (Product | Cluster)[] = [];\n for (const cu of crossupsells) {\n if (cu.productTo) items.push(cu.productTo as Product);\n else if (cu.clusterTo) items.push(cu.clusterTo as Cluster);\n }\n\n // Crossupsell relationships are NOT scoped to the user's assortment —\n // they can reference products/clusters the signed-in contact may not\n // order or even open (the PDP returns \"not found\"). Re-resolve the\n // extracted ids through the assortment-aware `getProducts` query (the\n // same one `fetchProducts` uses, scoped by userId/companyId like the\n // catalog/search listings) and keep only the items that come back, in\n // the original crossupsell order. If this verification call fails we\n // fall back to the raw items so a transient error doesn't blank the\n // slider.\n products.value = await filterToAssortment(items);\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch crossupsells';\n products.value = [];\n } finally {\n loading.value = false;\n }\n }\n\n // ── Fetch products (batch) ────────────────────────────────────────────────\n // fetchItems():\n // - uses ProductService.getProducts() (batch), NOT per-item getProduct()\n // - includes statuses filter and filterAvailableAttributeInput\n\n async function fetchProducts(productIds: number[], clusterIds: number[] = []): Promise<void> {\n if (!productIds.length && !clusterIds.length) return;\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).product;\n const lang = languageRef.value || 'NL';\n\n const searchInput: ProductSearchInput = {\n productIds,\n clusterIds,\n language: lang,\n page: 1,\n offset: 50,\n statuses: [\n ProductStatus.A,\n ProductStatus.P,\n ProductStatus.T,\n ProductStatus.S,\n ],\n };\n\n const filterAvailableAttributeInput: FilterAvailableAttributeInput = { isSearchable: true };\n\n const variables: ProductsQueryVariables = {\n input: searchInput,\n imageSearchFilters: configuration.imageSearchFiltersGrid,\n imageVariantFilters: configuration.imageVariantFiltersMedium as TransformationsInput,\n filterAvailableAttributeInput,\n };\n\n const response = await service.getProducts(variables);\n products.value = (response?.items ?? []) as (Product | Cluster)[];\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch products';\n products.value = [];\n } finally {\n loading.value = false;\n }\n }\n\n // ── Scroll helpers ────────────────────────────────────────────────────────\n\n function onScroll(containerEl: HTMLElement): void {\n canScrollLeft.value = containerEl.scrollLeft > 0;\n canScrollRight.value =\n containerEl.scrollLeft + containerEl.clientWidth < containerEl.scrollWidth - 1;\n }\n\n function scrollLeft(containerEl: HTMLElement, itemWidth = 280): void {\n containerEl.scrollBy({ left: -itemWidth, behavior: 'smooth' });\n }\n\n function scrollRight(containerEl: HTMLElement, itemWidth = 280): void {\n containerEl.scrollBy({ left: itemWidth, behavior: 'smooth' });\n }\n\n return {\n products,\n loading,\n error,\n canScrollLeft,\n canScrollRight,\n fetchCrossupsells,\n fetchProducts,\n scrollLeft,\n scrollRight,\n onScroll,\n };\n}\n","/**\n * useProductSpecs (Vue) — Product attribute fetch and grouping.\n *\n * Covers: ProductSpecifications component.\n *\n * Responsibilities:\n * - AttributeService.getAttributeResultByProductId\n * - Type-based value extraction (reuses attributeExtractor utility)\n * - Group attributes by category/group\n */\n\nimport { ref, type Ref } from 'vue';\nimport type { GraphQLClient, AttributeResult, AttributeResultSearchInput } from '@propeller-commerce/propeller-sdk-v2';\nimport {\n extractAttributeValues,\n getAttributeDisplayName,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface AttributeGroup {\n name: string;\n attributes: AttributeDisplayItem[];\n}\n\nexport interface AttributeDisplayItem {\n name: string;\n displayName: string;\n values: string[];\n type: string;\n}\n\nexport interface UseProductSpecsOptions {\n graphqlClient: GraphQLClient;\n language?: Ref<string>;\n}\n\nexport interface UseProductSpecsReturn {\n attributes: Ref<AttributeResult[]>;\n groupedAttributes: Ref<AttributeGroup[]>;\n loading: Ref<boolean>;\n error: Ref<string | null>;\n fetchSpecs: (productId: number) => Promise<void>;\n}\n\nexport function useProductSpecs(options: UseProductSpecsOptions): UseProductSpecsReturn {\n const { graphqlClient } = options;\n const languageRef = options.language ?? ref('NL');\n\n const attributes = ref<AttributeResult[]>([]) as Ref<AttributeResult[]>;\n const groupedAttributes = ref<AttributeGroup[]>([]) as Ref<AttributeGroup[]>;\n const loading = ref(false);\n const error = ref<string | null>(null);\n\n function buildGroups(attrs: AttributeResult[], language: string): AttributeGroup[] {\n const ungrouped: AttributeDisplayItem[] = [];\n const groupMap: Record<string, AttributeDisplayItem[]> = {};\n\n for (const attr of attrs) {\n const values = extractAttributeValues(attr);\n if (!values.length) continue;\n\n const displayName = getAttributeDisplayName(attr, language);\n const item: AttributeDisplayItem = {\n name: attr.attributeDescription?.name || '',\n displayName,\n values,\n type: attr.value?.type || 'TEXT',\n };\n\n const groupName = attr.attributeDescription?.group || '';\n if (groupName) {\n if (!groupMap[groupName]) groupMap[groupName] = [];\n groupMap[groupName].push(item);\n } else {\n ungrouped.push(item);\n }\n }\n\n const groups: AttributeGroup[] = Object.entries(groupMap).map(([name, attributes]) => ({\n name,\n attributes,\n }));\n\n if (ungrouped.length) {\n groups.push({ name: '', attributes: ungrouped });\n }\n\n return groups;\n }\n\n async function fetchSpecs(productId: number): Promise<void> {\n loading.value = true;\n error.value = null;\n try {\n const service = createServices(graphqlClient).product;\n const language = languageRef.value || 'NL';\n // Query arguments: isPublic: true, page: 1, offset: 2000\n const searchInput: AttributeResultSearchInput = {\n attributeDescription: { isPublic: true },\n page: 1,\n offset: 2000,\n };\n const result = await service.getAttributeResultByProductId(productId, searchInput);\n const items: AttributeResult[] = result?.items ?? [];\n attributes.value = items;\n groupedAttributes.value = buildGroups(items, language);\n } catch (e: unknown) {\n error.value = e instanceof Error ? e.message : 'Failed to fetch specifications';\n } finally {\n loading.value = false;\n }\n }\n\n return {\n attributes,\n groupedAttributes,\n loading,\n error,\n fetchSpecs,\n };\n}\n","/**\n * usePurchaseAuthorization (Vue) — Purchase Authorization Configurator + Requests.\n *\n * Covers: PurchaseAuthorizationConfigurator, PurchaseAuthorizationRequests.\n */\n\nimport { ref, computed, watch, type Ref, type ComputedRef } from 'vue';\nimport { CartStatus, Gender, PurchaseRole } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n GraphQLClient,\n Company,\n Cart,\n CartMainItem,\n Contact,\n Customer,\n PurchaseAuthorizationConfig,\n PurchaseAuthorizationConfigCreateInput,\n RegisterContactInput,\n AttributeResultSearchInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { useCompany } from './useCompany';\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\n// ── Shared types ──────────────────────────────────────────────────────────────\n\nexport interface RowEdit {\n role: string;\n limit: number | undefined;\n dirty: boolean;\n}\n\nexport interface AddContactFormState {\n gender: string;\n email: string;\n firstName: string;\n middleName: string;\n lastName: string;\n phone: string;\n}\n\nconst EMPTY_CONTACT_FORM: AddContactFormState = {\n gender: '', email: '', firstName: '', middleName: '', lastName: '', phone: '',\n};\n\n/** Checks if a user is an authorization manager for the given company. Works on plain objects from localStorage. */\nfunction checkIsAuthManager(user: Contact | Customer | null | undefined, companyId: number): boolean {\n if (!user || !('contactId' in user)) return false;\n const pacData = (user as any).purchaseAuthorizationConfigs;\n const items: any[] = pacData?.items ?? pacData?._items ?? [];\n return items.some((pac: any) => {\n const role = pac.purchaseRole ?? pac._purchaseRole;\n const pacCompanyId = pac.company?.companyId ?? pac.company?._companyId ?? pac._company?.companyId ?? pac._company?._companyId;\n return role === PurchaseRole.AUTHORIZATION_MANAGER && Number(pacCompanyId) === Number(companyId);\n });\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// usePurchaseAuthorizationConfigurator\n// ══════════════════════════════════════════════════════════════════════════════\n\nexport interface UsePurchaseAuthorizationConfiguratorOptions {\n graphqlClient: GraphQLClient;\n user: Ref<Contact | Customer | null>;\n companyId: Ref<number>;\n /** Rows per page (default 10) */\n pageOffset?: number;\n beforeContactCreate?: (input: RegisterContactInput) => void;\n onContactCreate?: (input: RegisterContactInput) => void;\n afterContactCreate?: (contact: Contact) => void;\n onPurchaseAuthorizationCreate?: (pac: PurchaseAuthorizationConfigCreateInput) => void;\n afterPurchaseAuthorizationCreate?: (pac: PurchaseAuthorizationConfig) => void;\n onPurchaseAuthorizationUpdate?: (pac: PurchaseAuthorizationConfig) => void;\n afterPurchaseAuthorizationUpdate?: (pac: PurchaseAuthorizationConfig) => void;\n onPurchaseAuthorizationDelete?: (pac: PurchaseAuthorizationConfig) => void;\n afterPurchaseAuthorizationDelete?: (deleted: boolean) => void;\n}\n\nexport interface UsePurchaseAuthorizationConfiguratorReturn {\n // Data\n company: Ref<Company | null>;\n loading: Ref<boolean>;\n contacts: ComputedRef<Contact[]>;\n totalPages: ComputedRef<number>;\n currentPage: Ref<number>;\n // Derived\n isAuthManager: ComputedRef<boolean>;\n // Per-row state\n rowEdits: Ref<Record<number, RowEdit>>;\n pacMap: Ref<Record<number, PurchaseAuthorizationConfig>>;\n actionLoading: Ref<Record<number, boolean>>;\n // Add-contact modal state\n showAddContactModal: Ref<boolean>;\n addContactForm: Ref<AddContactFormState>;\n addContactLoading: Ref<boolean>;\n addContactError: Ref<string>;\n // Per-row helpers\n hasPac: (contactId: number) => boolean;\n isCurrentUser: (contactId: number) => boolean;\n isRowDirty: (contactId: number) => boolean;\n getRowRole: (contactId: number) => string;\n getRowLimit: (contactId: number) => number | undefined;\n isRowLoading: (contactId: number) => boolean;\n // Handlers\n loadCompany: (page: number) => Promise<void>;\n handleRoleChange: (contactId: number, role: string) => void;\n handleLimitChange: (contactId: number, value: string) => void;\n handleCreate: (contactId: number) => Promise<void>;\n handleSave: (contactId: number) => Promise<void>;\n handleDelete: (contactId: number) => Promise<void>;\n handlePageChange: (page: number) => void;\n openAddContactModal: () => void;\n closeAddContactModal: () => void;\n handleAddContactSubmit: () => Promise<void>;\n}\n\nexport function usePurchaseAuthorizationConfigurator(\n options: UsePurchaseAuthorizationConfiguratorOptions,\n): UsePurchaseAuthorizationConfiguratorReturn {\n const { graphqlClient, user, companyId, pageOffset = 10 } = options;\n\n const { company, loading, fetchCompany, createPac, updatePac, deletePac } = useCompany({ graphqlClient });\n\n const currentPage = ref(1);\n const rowEdits = ref<Record<number, RowEdit>>({});\n const pacMap = ref<Record<number, PurchaseAuthorizationConfig>>({});\n const actionLoading = ref<Record<number, boolean>>({});\n const showAddContactModal = ref(false);\n const addContactForm = ref<AddContactFormState>({ ...EMPTY_CONTACT_FORM });\n const addContactLoading = ref(false);\n const addContactError = ref('');\n\n const isAuthManager = computed(() => checkIsAuthManager(user.value, companyId.value));\n\n const contacts = computed<Contact[]>(() => (company.value as Company)?.contacts?.items ?? []);\n\n const totalPages = computed<number>(() => (company.value as any)?.contacts?.pages ?? 0);\n\n function buildMaps(contactList: Contact[]): void {\n const newPacMap: Record<number, PurchaseAuthorizationConfig> = {};\n const newRowEdits: Record<number, RowEdit> = {};\n contactList.forEach((contact: Contact) => {\n const cId = contact.contactId;\n const pacItems: PurchaseAuthorizationConfig[] = contact.purchaseAuthorizationConfigs?.items ?? [];\n if (pacItems.length > 0) newPacMap[cId] = pacItems[0];\n const pac = newPacMap[cId];\n newRowEdits[cId] = {\n role: pac ? pac.purchaseRole : '',\n limit: pac ? pac.authorizationLimit : undefined,\n dirty: false,\n };\n });\n pacMap.value = newPacMap;\n rowEdits.value = newRowEdits;\n }\n\n async function loadCompany(page: number): Promise<void> {\n if (!graphqlClient || !companyId.value) return;\n await fetchCompany(companyId.value, {\n contactSearchArguments: { page, offset: pageOffset },\n contactPAConfigInput: { companyIds: [companyId.value], page: 1, offset: 100 },\n companyAttributesInput: {} as AttributeResultSearchInput,\n });\n buildMaps((company.value as Company)?.contacts?.items ?? []);\n }\n\n // Reload when companyId or currentPage changes\n watch(\n [companyId, currentPage],\n () => {\n if (graphqlClient && companyId.value) {\n loadCompany(currentPage.value);\n }\n },\n { immediate: true },\n );\n\n function hasPac(contactId: number): boolean { return !!pacMap.value[contactId]; }\n function isCurrentUser(contactId: number): boolean { return (user.value as Contact)?.contactId === contactId; }\n function isRowDirty(contactId: number): boolean { return !!rowEdits.value[contactId]?.dirty; }\n function getRowRole(contactId: number): string { return rowEdits.value[contactId]?.role ?? ''; }\n function getRowLimit(contactId: number): number | undefined { return rowEdits.value[contactId]?.limit; }\n function isRowLoading(contactId: number): boolean { return !!actionLoading.value[contactId]; }\n\n function handleRoleChange(contactId: number, role: string): void {\n const current = rowEdits.value[contactId] ?? { role: '', limit: undefined, dirty: false };\n rowEdits.value = { ...rowEdits.value, [contactId]: { ...current, role, dirty: true } };\n }\n\n function handleLimitChange(contactId: number, value: string): void {\n const limit = value === '' ? undefined : Number(value);\n const current = rowEdits.value[contactId] ?? { role: '', limit: undefined, dirty: false };\n rowEdits.value = { ...rowEdits.value, [contactId]: { ...current, limit, dirty: true } };\n }\n\n async function handleCreate(contactId: number): Promise<void> {\n actionLoading.value = { ...actionLoading.value, [contactId]: true };\n try {\n const edit = rowEdits.value[contactId] ?? { role: PurchaseRole.PURCHASER, limit: undefined, dirty: false };\n const input: PurchaseAuthorizationConfigCreateInput = {\n contactId,\n companyId: companyId.value,\n purchaseRole: (edit.role || PurchaseRole.PURCHASER) as PurchaseRole,\n authorizationLimit: edit.limit,\n };\n if (options.onPurchaseAuthorizationCreate) {\n options.onPurchaseAuthorizationCreate(input);\n } else {\n const result = await createPac(input);\n if (result.success) await loadCompany(currentPage.value);\n }\n } finally {\n actionLoading.value = { ...actionLoading.value, [contactId]: false };\n }\n }\n\n async function handleSave(contactId: number): Promise<void> {\n const pac = pacMap.value[contactId];\n if (!pac) return;\n actionLoading.value = { ...actionLoading.value, [contactId]: true };\n try {\n const edit = rowEdits.value[contactId];\n if (options.onPurchaseAuthorizationUpdate) {\n options.onPurchaseAuthorizationUpdate(pac);\n } else {\n const result = await updatePac(pac.id, {\n purchaseRole: (edit.role || pac.purchaseRole) as PurchaseRole,\n authorizationLimit: edit.limit,\n });\n if (result.success) await loadCompany(currentPage.value);\n }\n } finally {\n actionLoading.value = { ...actionLoading.value, [contactId]: false };\n }\n }\n\n async function handleDelete(contactId: number): Promise<void> {\n const pac = pacMap.value[contactId];\n if (!pac) return;\n actionLoading.value = { ...actionLoading.value, [contactId]: true };\n try {\n if (options.onPurchaseAuthorizationDelete) {\n options.onPurchaseAuthorizationDelete(pac);\n } else {\n const result = await deletePac(pac.id);\n if (result.success) {\n if (options.afterPurchaseAuthorizationDelete) {\n options.afterPurchaseAuthorizationDelete(true);\n } else {\n await loadCompany(currentPage.value);\n }\n }\n }\n } finally {\n actionLoading.value = { ...actionLoading.value, [contactId]: false };\n }\n }\n\n function handlePageChange(page: number): void {\n currentPage.value = page;\n }\n\n function openAddContactModal(): void {\n addContactError.value = '';\n showAddContactModal.value = true;\n }\n\n function closeAddContactModal(): void {\n showAddContactModal.value = false;\n addContactError.value = '';\n addContactForm.value = { ...EMPTY_CONTACT_FORM };\n }\n\n async function handleAddContactSubmit(): Promise<void> {\n addContactLoading.value = true;\n addContactError.value = '';\n try {\n const input: RegisterContactInput = {\n parentId: companyId.value,\n gender: addContactForm.value.gender as Gender,\n email: addContactForm.value.email,\n firstName: addContactForm.value.firstName,\n middleName: addContactForm.value.middleName,\n lastName: addContactForm.value.lastName,\n phone: addContactForm.value.phone,\n };\n if (options.beforeContactCreate) options.beforeContactCreate(input);\n if (options.onContactCreate) {\n options.onContactCreate(input);\n } else {\n const userService = createServices(graphqlClient).user;\n const result = await userService.registerContact({ contactRegisterInput: input });\n if (options.afterContactCreate) {\n options.afterContactCreate(result.contact as Contact);\n } else {\n await loadCompany(currentPage.value);\n }\n }\n closeAddContactModal();\n } catch (err: any) {\n addContactError.value = err?.message || 'Failed to create contact';\n } finally {\n addContactLoading.value = false;\n }\n }\n\n return {\n company: company as Ref<Company | null>,\n loading,\n contacts,\n totalPages,\n currentPage,\n isAuthManager,\n rowEdits,\n pacMap,\n actionLoading,\n showAddContactModal,\n addContactForm,\n addContactLoading,\n addContactError,\n hasPac,\n isCurrentUser,\n isRowDirty,\n getRowRole,\n getRowLimit,\n isRowLoading,\n loadCompany,\n handleRoleChange,\n handleLimitChange,\n handleCreate,\n handleSave,\n handleDelete,\n handlePageChange,\n openAddContactModal,\n closeAddContactModal,\n handleAddContactSubmit,\n };\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// usePurchaseAuthorizationRequests\n// ══════════════════════════════════════════════════════════════════════════════\n\nexport interface UsePurchaseAuthorizationRequestsOptions {\n graphqlClient: GraphQLClient;\n user: Ref<Contact | Customer | null>;\n companyId: Ref<number>;\n configuration?: {\n language?: string;\n imageSearchFiltersGrid?: any;\n imageVariantFiltersSmall?: any;\n };\n onAcceptRequest?: (cartId: string) => void;\n afterAcceptRequest?: (cart: Cart) => void;\n /**\n * Called BEFORE deleting; receives the cart id. Lets the host short-circuit\n * the SDK call and run its own deletion logic, following the same pattern as\n * onAcceptRequest.\n */\n onDeleteRequest?: (cartId: string) => void;\n /** Called AFTER a successful delete. Receives the deleted cart's id. */\n afterDeleteRequest?: (cartId: string) => void;\n onError?: (err: Error) => void;\n}\n\nexport interface UsePurchaseAuthorizationRequestsReturn {\n carts: Ref<Cart[]>;\n loading: Ref<boolean>;\n selectedCart: Ref<Cart | null>;\n modalLoading: Ref<boolean>;\n acceptLoading: Ref<boolean>;\n deleteLoading: Ref<boolean>;\n isAuthManager: ComputedRef<boolean>;\n getTotalQuantity: (cart: Cart) => number;\n getContactName: (contact: Contact | null | undefined) => string;\n getModalItems: () => CartMainItem[];\n loadCarts: () => Promise<void>;\n handleViewCart: (cart: Cart) => Promise<void>;\n handleAcceptRequest: () => Promise<void>;\n handleDeleteRequest: () => Promise<void>;\n closeModal: () => void;\n}\n\nexport function usePurchaseAuthorizationRequests(\n options: UsePurchaseAuthorizationRequestsOptions,\n): UsePurchaseAuthorizationRequestsReturn {\n const { graphqlClient, user, companyId, configuration } = options;\n\n const carts = ref<Cart[]>([]) as Ref<Cart[]>;\n const loading = ref(true);\n const selectedCart = ref<Cart | null>(null) as Ref<Cart | null>;\n const modalLoading = ref(false);\n const acceptLoading = ref(false);\n const deleteLoading = ref(false);\n\n const isAuthManager = computed(() => checkIsAuthManager(user.value, companyId.value));\n\n function getTotalQuantity(cart: Cart): number {\n return (cart?.items || []).reduce((sum: number, item: CartMainItem) => sum + (item.quantity || 0), 0);\n }\n\n function getContactName(contact: Contact | null | undefined): string {\n if (!contact) return '';\n return [contact.firstName ?? '', contact.middleName ?? '', contact.lastName ?? ''].filter(Boolean).join(' ');\n }\n\n function getModalItems(): CartMainItem[] {\n return selectedCart.value?.items || [];\n }\n\n async function loadCarts(): Promise<void> {\n if (!graphqlClient || !companyId.value) return;\n loading.value = true;\n try {\n const service = createServices(graphqlClient).cart;\n const response = await service.getCarts({\n statuses: [CartStatus.PENDING_PURCHASE_AUTHORIZATION],\n companyIds: [companyId.value],\n });\n carts.value = response?.items || [];\n } catch (err: any) {\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n loading.value = false;\n }\n }\n\n async function handleViewCart(cart: Cart): Promise<void> {\n selectedCart.value = cart;\n modalLoading.value = true;\n try {\n const service = createServices(graphqlClient).cart;\n const fullCart = await service.getCart({\n cartId: cart.cartId,\n language: configuration?.language || 'NL',\n imageSearchFilters: configuration?.imageSearchFiltersGrid,\n imageVariantFilters: configuration?.imageVariantFiltersSmall,\n });\n selectedCart.value = fullCart;\n } catch (err: any) {\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n modalLoading.value = false;\n }\n }\n\n async function handleAcceptRequest(): Promise<void> {\n if (!selectedCart.value) return;\n acceptLoading.value = true;\n const cartId = selectedCart.value.cartId;\n try {\n let cartForCallback: Cart = selectedCart.value;\n if (options.onAcceptRequest) {\n options.onAcceptRequest(cartId);\n } else {\n const service = createServices(graphqlClient).cart;\n cartForCallback = await service.acceptPurchaseAuthorizationRequest({\n id: cartId,\n input: { contactId: (user.value as Contact)?.contactId },\n imageSearchFilters: configuration?.imageSearchFiltersGrid,\n imageVariantFilters: configuration?.imageVariantFiltersSmall,\n language: configuration?.language || 'NL',\n });\n }\n options.afterAcceptRequest?.(cartForCallback);\n selectedCart.value = null;\n await loadCarts();\n } catch (err: any) {\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n acceptLoading.value = false;\n }\n }\n\n async function handleDeleteRequest(): Promise<void> {\n if (!selectedCart.value) return;\n deleteLoading.value = true;\n const cartId = selectedCart.value.cartId;\n try {\n if (options.onDeleteRequest) {\n options.onDeleteRequest(cartId);\n } else {\n const service = createServices(graphqlClient).cart;\n await service.deleteCart({ id: cartId });\n }\n options.afterDeleteRequest?.(cartId);\n selectedCart.value = null;\n await loadCarts();\n } catch (err: any) {\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\n } finally {\n deleteLoading.value = false;\n }\n }\n\n function closeModal(): void {\n selectedCart.value = null;\n }\n\n // Reload when companyId changes\n watch(\n companyId,\n () => {\n if (graphqlClient && companyId.value) {\n loadCarts();\n }\n },\n { immediate: true },\n );\n\n return {\n carts, loading, selectedCart, modalLoading, acceptLoading, deleteLoading, isAuthManager,\n getTotalQuantity, getContactName, getModalItems,\n loadCarts, handleViewCart, handleAcceptRequest, handleDeleteRequest, closeModal,\n };\n}\n","import { useInfraProps } from './useInfraProps';\nimport { useProductGridConfig, type ProductGridConfig } from '../../context/ProductGridContext';\nimport type { PropellerInfra } from '../../context/PropellerContext';\n\n/**\n * Declarative resolver for the two-tier prop precedence used by\n * `ProductCard` / `ClusterCard`:\n *\n * explicit prop > ProductGrid context (Tier 2) > Propeller infra (Tier 1) > default\n *\n * Without this, each card hand-writes a ~25–40 line object literal of\n * `props.x ?? grid?.x ?? infra.x ?? d` lines — easy to get the precedence\n * order wrong per key and impossible to scan. This collapses it to a spec\n * table. It internally calls the same non-throwing `useInfraProps` and\n * `useProductGridConfig`, so standalone usage (no provider) still works.\n *\n * Spec per key:\n * - `infra` : fall back to PropellerInfra[key] (Tier 1)\n * - `grid` : fall back to ProductGridConfig[key] (Tier 2)\n * - `default`: final fallback when nothing else resolved\n * - `transform(gridValue)`: when the grid value needs wrapping before use\n *\n * A key absent from the spec passes through unchanged.\n */\n\ntype InfraKey = keyof PropellerInfra;\ntype GridKey = keyof ProductGridConfig;\n\ninterface ResolveSpecEntry {\n /** Tier-1 infra key to fall back to (after the explicit prop). */\n infra?: InfraKey;\n /** Tier-2 grid-config key to fall back to (after the explicit prop). */\n grid?: GridKey;\n /** Final fallback when neither explicit prop nor context resolved a value. */\n default?: unknown;\n /** Optional adapter applied to the grid value when it is the one chosen. */\n transform?: (gridValue: NonNullable<ProductGridConfig[GridKey]>) => unknown;\n}\n\nexport type ResolveSpec<P> = Partial<Record<keyof P, ResolveSpecEntry>>;\n\n/**\n * Resolve `rawProps` against the spec. Call inside `setup()` (it injects the\n * grid + infra contexts). Wrap the call in a `computed` if the resolved\n * result must track prop changes.\n */\nexport function useResolvedProps<P extends object>(rawProps: P, spec: ResolveSpec<P>): P {\n const grid = useProductGridConfig();\n const infra = useInfraProps(rawProps as Record<string, unknown>) as Record<string, unknown> &\n Partial<PropellerInfra>;\n\n const resolved = { ...rawProps } as Record<string, unknown>;\n const rawRecord = rawProps as Record<string, unknown>;\n\n for (const key of Object.keys(spec)) {\n const entry = (spec as Record<string, ResolveSpecEntry>)[key];\n const explicit = rawRecord[key];\n if (explicit !== undefined && explicit !== null) {\n // Explicit prop always wins — keep the spread value.\n continue;\n }\n\n // Tier 2: ProductGrid config.\n if (entry.grid && grid) {\n const gridValue = grid[entry.grid];\n if (gridValue !== undefined && gridValue !== null) {\n resolved[key] = entry.transform\n ? entry.transform(gridValue as NonNullable<ProductGridConfig[GridKey]>)\n : gridValue;\n continue;\n }\n }\n\n // Tier 1: Propeller infra.\n if (entry.infra) {\n const infraValue = (infra as Partial<PropellerInfra>)[entry.infra];\n if (infraValue !== undefined && infraValue !== null) {\n resolved[key] = infraValue;\n continue;\n }\n }\n\n // Final default.\n if (entry.default !== undefined) {\n resolved[key] = entry.default;\n }\n }\n\n return resolved as P;\n}\n","import { usePropellerDeps } from '../../plugin';\nimport type { Services } from '@propeller-commerce/propeller-v2-core-ui';\n\n/**\n * Read the SDK services bundle from the Propeller plugin.\n *\n * The package ships no default `graphqlClient` / `services`. The consumer\n * constructs both at app startup and installs them via\n * `app.use(propellerVue, { graphqlClient, services, ... })`. Anything in\n * the app tree calls `useServices()` to get the bundle.\n *\n * Throws when the plugin wasn't installed — that's an integration error the\n * consumer fixes at app startup, not something to paper over with a singleton.\n */\nexport function useServices(): Services {\n return usePropellerDeps().services;\n}\n","/**\n * fetchActiveCart — fetches the user's existing OPEN cart filtered by user/company.\n *\n * Framework-agnostic helper extracted from the Vue/React login flows so\n * login/register pages can call it directly with the freshly-authenticated\n * user, without going through a reactive composable whose internal user ref\n * may still be stale at the moment of invocation.\n */\n\nimport { CartService, CartStatus } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n Cart,\n CartSearchInput,\n Contact,\n Customer,\n GraphQLClient,\n MediaImageProductSearchInput,\n TransformationsInput,\n} from '@propeller-commerce/propeller-sdk-v2';\n\nexport interface FetchActiveCartConfig {\n graphqlClient: GraphQLClient;\n user: Contact | Customer;\n companyId?: number;\n language: string;\n imageSearchFilters: MediaImageProductSearchInput;\n imageVariantFilters: TransformationsInput;\n}\n\nexport async function fetchActiveCart(\n cfg: FetchActiveCartConfig,\n): Promise<Cart | null> {\n const cartService = new CartService(cfg.graphqlClient);\n try {\n const searchInput: CartSearchInput = {\n offset: 100,\n statuses: [CartStatus.OPEN],\n };\n let scopedByCompany = false;\n if ('contactId' in cfg.user && cfg.user.contactId) {\n searchInput.contactIds = [cfg.user.contactId];\n if (cfg.companyId) {\n searchInput.companyIds = [cfg.companyId];\n scopedByCompany = true;\n }\n } else if ('customerId' in cfg.user && cfg.user.customerId) {\n searchInput.customerIds = [cfg.user.customerId];\n }\n\n // The backend authorizes the `companyIds` cart filter against the contact's\n // memberships; a `companyId` the contact doesn't belong to (e.g. a stale\n // selection left from a previous session) makes the whole query fail with\n // \"Unauthorized use of companyIds\". Drop the company narrowing and retry on\n // the contact alone — that returns the same cart and never 403s. The caller\n // is expected to reconcile the bad selection separately.\n let carts;\n try {\n carts = await cartService.getCarts(searchInput);\n } catch (companyScopedErr) {\n if (!scopedByCompany) throw companyScopedErr;\n console.warn(\n '[fetchActiveCart] company-scoped cart lookup failed; retrying without companyIds:',\n companyScopedErr,\n );\n delete searchInput.companyIds;\n carts = await cartService.getCarts(searchInput);\n }\n\n if (carts?.items?.length) {\n const existingCartId = carts.items[carts.items.length - 1].cartId;\n return (\n (await cartService.getCart({\n cartId: existingCartId,\n imageSearchFilters: cfg.imageSearchFilters,\n imageVariantFilters: cfg.imageVariantFilters,\n language: cfg.language,\n })) ?? null\n );\n }\n return null;\n } catch (e) {\n console.error('[fetchActiveCart] Failed to fetch active cart:', e);\n return null;\n }\n}\n","/**\n * mergeAnonymousCart — copies items from an anonymous cart into a target\n * (authenticated) cart by calling CartService.addItemToCart per item.\n *\n * Framework-agnostic: contains no framework-specific dependencies.\n */\n\nimport { CartService } from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n Cart,\n CartMainItem,\n GraphQLClient,\n MediaImageProductSearchInput,\n TransformationsInput,\n} from '@propeller-commerce/propeller-sdk-v2';\n\nexport interface MergeAnonymousCartConfig {\n graphqlClient: GraphQLClient;\n /** The authenticated user's cart that anonymous items will be added to. */\n targetCartId: string;\n /** The anonymous cart from the store/state captured before authentication. */\n anonymousCart: Cart | null;\n language: string;\n imageSearchFilters: MediaImageProductSearchInput;\n imageVariantFilters: TransformationsInput;\n}\n\nexport async function mergeAnonymousCart(\n cfg: MergeAnonymousCartConfig,\n): Promise<Cart | null> {\n const items = cfg.anonymousCart?.items ?? [];\n if (!items.length) return null;\n // Skip if anonymous cart IS the target — guards against self-merge.\n if (\n cfg.anonymousCart?.cartId &&\n cfg.anonymousCart.cartId === cfg.targetCartId\n ) {\n return null;\n }\n\n const service = new CartService(cfg.graphqlClient);\n let result: Cart | null = null;\n\n // Serial iteration: each call returns the full cart, so parallel races.\n for (const item of items as CartMainItem[]) {\n if (!item.productId || !item.quantity) continue;\n\n // Resolve clusterId from either the top-level field or the nested cluster\n // object — depending on how the item was originally added (PDP vs. cluster\n // page) and how the cart was serialised, the field can live in either spot.\n const itemAny = item as any;\n const resolvedClusterId =\n itemAny.clusterId ??\n itemAny.cluster?.clusterId ??\n itemAny._clusterId ??\n itemAny._cluster?._clusterId ??\n itemAny._cluster?.clusterId;\n\n const childItems = item.childItems\n ?.filter((c: any) => c.productId)\n .map((c: any) => ({\n productId: c.productId,\n quantity: c.quantity ?? item.quantity,\n }));\n\n try {\n result = await service.addItemToCart({\n id: cfg.targetCartId,\n input: {\n productId: item.productId,\n quantity: item.quantity,\n ...(resolvedClusterId !== undefined &&\n resolvedClusterId !== null && { clusterId: resolvedClusterId }),\n ...(childItems && childItems.length > 0 && { childItems }),\n ...(item.notes && { notes: item.notes }),\n },\n language: cfg.language,\n imageSearchFilters: cfg.imageSearchFilters,\n imageVariantFilters: cfg.imageVariantFilters,\n });\n } catch (e) {\n console.error(\n '[mergeAnonymousCart] addItemToCart failed for productId=' +\n item.productId,\n e,\n );\n }\n }\n\n return result;\n}\n","<script setup lang=\"ts\">\nimport { computed, provide, reactive } from 'vue';\nimport type { Contact, Customer } from '@propeller-commerce/propeller-sdk-v2';\nimport { PropellerScopeKey, type PropellerScope } from '../context/PropellerContext';\n\n/**\n * Provides Tier 2 per-scope state (user / companyId / language / includeTax /\n * portalMode) to package components and composables. Tier 1 deps come from\n * the `propellerVue` plugin installed at app startup.\n *\n * Nestable: deeper providers replace the outer scope for their subtree, which\n * is how multi-cart / impersonation / language-widget patterns work without\n * polluting the rest of the page.\n */\nconst props = withDefaults(\n defineProps<{\n user?: Contact | Customer | null;\n companyId?: number;\n language?: string;\n includeTax?: boolean;\n portalMode?: string;\n }>(),\n {\n user: null,\n companyId: undefined,\n language: 'EN',\n includeTax: false,\n portalMode: 'open',\n },\n);\n\n// `reactive` + getters: props are already reactive, but the injection contract\n// is a stable object reference whose fields update in place. Without the\n// getters, child components would see a frozen snapshot at provide-time.\nconst scope = reactive({\n get user() {\n return props.user ?? null;\n },\n get companyId() {\n return props.companyId;\n },\n get language() {\n return props.language;\n },\n get includeTax() {\n return props.includeTax;\n },\n get portalMode() {\n return props.portalMode;\n },\n}) as unknown as PropellerScope;\n\nprovide(PropellerScopeKey, scope);\n\n// Pacify the \"unused\" linter on the computed import in some setups — kept\n// available for downstream tooling.\nvoid computed;\n</script>\n\n<template>\n <slot />\n</template>\n","<template>\n <div\n class=\"propeller-login-form\"\n :data-loading=\"isLoading ? 'true' : 'false'\"\n :data-variant=\"accountHeaderLoginForm ? 'compact' : 'full'\"\n >\n <template v-if=\"resolvedTitle\">\n <div class=\"propeller-login-form__header space-y-1 text-center mb-6\">\n <h2 class=\"propeller-login-form__title text-2xl font-bold\">{{ resolvedTitle }}</h2>\n <template v-if=\"subtitle\">\n <p class=\"propeller-login-form__subtitle text-sm text-muted-foreground\">{{ subtitle }}</p>\n </template>\n </div>\n </template>\n\n <form class=\"propeller-login-form__form space-y-4\" @submit=\"async (e) => handleSubmit(e)\">\n <slot\n name=\"emailField\"\n :email=\"email\"\n :onEmailChange=\"(value: string) => { email = value; }\"\n :labels=\"labels\"\n >\n <div class=\"propeller-login-form__field space-y-2\">\n <label for=\"login-email\" class=\"propeller-login-form__label text-sm font-medium leading-none\">{{ emailLabel }}</label\n ><input\n type=\"email\"\n id=\"login-email\"\n name=\"email\"\n class=\"propeller-login-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"email\"\n @input=\"\n async (e) => {\n email = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"emailPlaceholder\"\n :required=\"true\"\n :disabled=\"isLoading\"\n />\n </div>\n </slot>\n <slot\n name=\"passwordField\"\n :password=\"password\"\n :onPasswordChange=\"(value: string) => { password = value; }\"\n :labels=\"labels\"\n :displayForgotPassword=\"displayForgotPasswordLink !== false && !accountHeaderLoginForm\"\n >\n <div class=\"propeller-login-form__field space-y-2\">\n <div class=\"flex items-center justify-between\">\n <label for=\"login-password\" class=\"propeller-login-form__label text-sm font-medium leading-none\">{{\n passwordLabel\n }}</label>\n <template v-if=\"showForgotPassword && !accountHeaderLoginForm\">\n <button\n type=\"button\"\n class=\"propeller-login-form__forgot-link text-sm text-primary hover:underline\"\n @click=\"\n async (event) => {\n if (onForgotPasswordClick) onForgotPasswordClick();\n }\n \"\n >\n {{ forgotPasswordText }}\n </button>\n </template>\n </div>\n <input\n type=\"password\"\n id=\"login-password\"\n name=\"password\"\n class=\"propeller-login-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"password\"\n @input=\"\n async (e) => {\n password = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"passwordPlaceholder\"\n :required=\"true\"\n :disabled=\"isLoading\"\n />\n </div>\n </slot>\n <slot\n v-if=\"!!errorMessage\"\n name=\"errorMessage\"\n :error=\"errorMessage\"\n >\n <div class=\"propeller-login-form__error text-sm text-destructive bg-destructive/10 p-3 rounded-[var(--radius-control)]\">\n {{ errorMessage }}\n </div>\n </slot>\n\n <slot\n name=\"submitButton\"\n :isLoading=\"isLoading\"\n :buttonText=\"resolvedButtonText\"\n :labels=\"labels\"\n >\n <button\n type=\"submit\"\n class=\"propeller-login-form__submit inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-[var(--radius-control)] hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"isLoading\"\n >\n <template v-if=\"isLoading\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-login-form__spinner animate-spin -ml-1 mr-2 h-4 w-4 text-primary-foreground\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n class=\"opacity-25\"\n ></circle>\n <path\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n class=\"opacity-75\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"isLoading\"> {{ getLabel('loggingIn', 'Logging in...') }} </template>\n\n <template v-else>\n {{ resolvedButtonText }}\n </template>\n </button>\n </slot>\n </form>\n <template v-if=\"(showRegister || showGuestCheckout) && !accountHeaderLoginForm\">\n <div class=\"propeller-login-form__footer mt-6 border-t pt-6 space-y-3\">\n <slot\n v-if=\"displayRegisterLink !== false\"\n name=\"registerLink\"\n :onClick=\"(e: any) => onRegisterClick?.(e)\"\n :labels=\"labels\"\n >\n <div class=\"propeller-login-form__register text-center\">\n <p class=\"propeller-login-form__register-prompt text-sm text-muted-foreground mb-2\">{{ registerText }}</p>\n <button\n type=\"button\"\n class=\"propeller-login-form__register-btn inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font-medium border border-input rounded-[var(--radius-control)] hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n @click=\"\n async (event) => {\n if (onRegisterClick) onRegisterClick();\n }\n \"\n >\n {{ registerLinkText }}\n </button>\n </div>\n </slot>\n\n <slot\n v-if=\"displayGuestCheckoutLink !== false\"\n name=\"guestCheckoutButton\"\n :onClick=\"(e: any) => onGuestCheckoutClick?.(e)\"\n :labels=\"labels\"\n >\n <div class=\"propeller-login-form__guest text-center\">\n <button\n type=\"button\"\n class=\"propeller-login-form__guest-btn text-sm text-primary hover:underline\"\n @click=\"\n async (event) => {\n if (onGuestCheckoutClick) onGuestCheckoutClick();\n }\n \"\n >\n {{ guestCheckoutLinkText }}\n </button>\n </div>\n </slot>\n </div>\n </template>\n\n <template v-if=\"accountHeaderLoginForm\">\n <div class=\"propeller-login-form__footer flex flex-col gap-2 text-sm pt-3 text-center\">\n <slot\n v-if=\"displayForgotPasswordLink !== false\"\n name=\"forgotPasswordLink\"\n :onClick=\"(e: any) => onForgotPasswordClick?.(e)\"\n :labels=\"labels\"\n >\n <button\n type=\"button\"\n class=\"propeller-login-form__forgot-link text-secondary hover:underline text-xs\"\n @click=\"\n async (event) => {\n if (onForgotPasswordClick) onForgotPasswordClick();\n }\n \"\n >\n {{ getLabel('forgotPassword', 'Forgot Password?') }}\n </button>\n </slot>\n <div class=\"propeller-login-form__register text-xs text-muted-foreground\">\n {{ getLabel('noAccount', \"Don't have an account?\")\n }}<slot\n v-if=\"displayRegisterLink !== false\"\n name=\"registerLink\"\n :onClick=\"(e: any) => onRegisterClick?.(e)\"\n :labels=\"labels\"\n >\n <button\n type=\"button\"\n class=\"propeller-login-form__register-btn text-secondary hover:underline font-medium\"\n @click=\"\n async (event) => {\n if (onRegisterClick) onRegisterClick();\n }\n \"\n >\n {{ getLabel('registerLink', 'Register') }}\n </button>\n </slot>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport type { Cart, Contact, Customer, GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';\nimport { useAuth } from '../composables/vue/useAuth';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\n\n\n\n export interface LoginFormProps {\n /**\n * GraphQL client for self-contained login.\n * When provided (and onLoginSubmit is not), the component handles\n * authentication internally via LoginService + UserService.\n */\n graphqlClient?: GraphQLClient;\n\n /** Title of the login form\n * @default \"Log in\"\n */\n title?: string;\n\n /** Subtitle of the login form\n * @default \"\"\n */\n subtitle?: string;\n\n /** Show/hide the password reset link\n * @default true\n */\n displayForgotPasswordLink?: boolean;\n\n /** Action for the password reset link click */\n onForgotPasswordClick?: (event?: any) => void;\n\n /** Show/hide the registration link\n * @default true\n */\n displayRegisterLink?: boolean;\n\n /** Action for the registration link click */\n onRegisterClick?: (event?: any) => void;\n\n /** Show/hide the guest checkout link\n * @default true\n */\n displayGuestCheckoutLink?: boolean;\n\n /** Action for the guest checkout link click */\n onGuestCheckoutClick?: (event?: any) => void;\n\n /** Label for the submit button\n * @default \"Login\"\n */\n buttonText?: string;\n\n /**\n * Labels for the login form fields.\n *\n * Available keys:\n * - email: Email field label (default: \"Email\")\n * - password: Password field label (default: \"Password\")\n * - emailPlaceholder: Email input placeholder (default: \"name@example.com\")\n * - passwordPlaceholder: Password input placeholder (default: \"••••••••\")\n * - forgotPassword: Forgot password link text (default: \"Forgot password?\")\n * - registerText: Text before register link (default: \"Don't have an account?\")\n * - registerLink: Register link text (default: \"Create an Account\")\n * - guestCheckoutLink: Guest checkout link text (default: \"Continue as Guest\")\n */\n labels?: Record<string, string>;\n\n /**\n * Fires when login form is submitted (delegation mode).\n * When provided, the component does NOT call the SDK — the parent handles authentication.\n * When absent and graphqlClient is provided, the component handles login internally.\n */\n onLoginSubmit?: (email: string, password: string) => void;\n\n /** Whether login is currently in progress (shows loading state on button).\n * Used in delegation mode. Ignored in self-contained mode.\n * @default false\n */\n loginLoading?: boolean;\n\n /** Error message to display in the form.\n * Used in delegation mode. In self-contained mode the component manages its own error.\n */\n loginError?: string;\n\n /** Callback before the login process starts */\n beforeLogin?: () => void;\n\n /** Callback after successful login with user data.\n * `anonymousCart` is the cart held in the parent's store/state at the moment of submission,\n * forwarded so the parent can merge it into the authenticated user's cart.\n */\n afterLogin?: (user: Contact | Customer, accessToken?: string, refreshToken?: string, expiresAt?: string, anonymousCart?: Cart | null) => void;\n\n /** Anonymous cart snapshot from the parent's store/state — forwarded to `afterLogin`. */\n cart?: Cart | null;\n\n /**\n * Show login form in dropdown for immediate login when user is not logged in.\n * @default true\n */\n accountHeaderLoginForm?: boolean;\n\n /** Config object providing imageSearchFiltersGrid and imageVariantFiltersSmall. */\n configuration?: any;\n}\nconst props = withDefaults(defineProps<LoginFormProps>(), {\n displayForgotPasswordLink: true,\n displayRegisterLink: true,\n displayGuestCheckoutLink: true,\n});\n// Resolve graphqlClient + configuration from the propellerVue plugin scope when\n// the consumer doesn't pass them explicitly — host pages embed LoginForm via\n// AccountIconAndMenu's dropdown without threading deps through every prop.\nconst infra = useInfraProps(props);\nconst email = ref('');\nconst password = ref('');\n\nconst { loading, error, login } = useAuth({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n configuration: infra.configuration,\n});\n\n\n\n\n\n\n\n\n\n\nconst emailLabel = computed(() => {\n return props.labels?.email || 'Email';\n});\nconst passwordLabel = computed(() => {\n return props.labels?.password || 'Password';\n});\nconst emailPlaceholder = computed(() => {\nreturn props.labels?.emailPlaceholder || 'name@example.com';\n})\nconst passwordPlaceholder = computed(() => {\nreturn props.labels?.passwordPlaceholder || '••••••••';\n})\nconst forgotPasswordText = computed(() => {\nreturn props.labels?.forgotPassword || 'Forgot password?';\n})\nconst registerText = computed(() => {\nreturn props.labels?.registerText || \"Don't have an account?\";\n})\nconst registerLinkText = computed(() => {\nreturn props.labels?.registerLink || 'Create an Account';\n})\nconst guestCheckoutLinkText = computed(() => {\nreturn props.labels?.guestCheckoutLink || 'Continue as Guest';\n})\nconst resolvedTitle = computed(() => {\nreturn props.title !== undefined ? props.title : 'Log in';\n})\nconst resolvedButtonText = computed(() => {\nreturn props.buttonText || 'Login';\n})\nconst showForgotPassword = computed(() => {\nreturn props.displayForgotPasswordLink !== false;\n})\nconst showRegister = computed(() => {\nreturn props.displayRegisterLink !== false;\n})\nconst showGuestCheckout = computed(() => {\nreturn props.displayGuestCheckoutLink !== false;\n})\nconst isLoading = computed(() => {\n if (props.onLoginSubmit) {\n return props.loginLoading === true;\n }\n return loading.value;\n});\n// Surface a friendly fixed message for any login failure — server-side error\n// strings can be cryptic (\"HTTP 401\", GraphQL \"Unauthorized\", etc.) and aren't\n// safe to show to end users. Override via the `labels.invalidCredentials` prop\n// if a specific copy is needed.\nconst errorMessage = computed(() => {\n const raw = props.onLoginSubmit ? props.loginError : error.value;\n if (!raw) return '';\n return getLabel(\n 'invalidCredentials',\n \"The credentials you entered don't match our records. Please try again.\",\n );\n});\n\n\n\n\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nasync function handleSubmit(e: any) {\n e.preventDefault();\n if (props.beforeLogin) {\n props.beforeLogin();\n }\n if (props.onLoginSubmit) {\n // Delegation mode: parent handles authentication\n props.onLoginSubmit(email.value, password.value);\n return;\n }\n if (!infra.graphqlClient) return;\n if (loading.value) return;\n\n const result = await login(email.value, password.value);\n if (result.ok && result.data.user) {\n email.value = '';\n password.value = '';\n if (props.afterLogin) {\n props.afterLogin(\n result.data.user as Contact | Customer,\n result.data.accessToken,\n result.data.refreshToken,\n result.data.expiresAt,\n props.cart ?? null,\n );\n }\n }\n}\n</script>\n","<template>\n <div\n class=\"propeller-account-menu relative\"\n data-account-menu\n :data-variant=\"isSidebar ? 'sidebar' : 'dropdown'\"\n :data-authenticated=\"user ? 'true' : 'false'\"\n @click.stop\n >\n <template v-if=\"isSidebar\">\n <div class=\"propeller-account-menu__sidebar flex flex-col\">\n <template v-if=\"!!user\">\n <div\n class=\"propeller-account-menu__user px-4 py-3 border-b border-border\"\n >\n <p\n class=\"propeller-account-menu__user-label text-xs text-muted-foreground uppercase tracking-wider font-semibold mb-1\"\n >\n {{ getLabel(\"signedInAs\", \"Signed in as\") }}\n </p>\n <p\n class=\"propeller-account-menu__user-name font-medium text-foreground truncate\"\n >\n {{ getUserName() }}\n </p>\n </div>\n <nav class=\"propeller-account-menu__nav py-2\">\n <ul class=\"propeller-account-menu__list space-y-0.5\">\n <template\n :key=\"link.href\"\n v-for=\"(link, index) in getMenuLinks()\"\n >\n <li class=\"propeller-account-menu__item\">\n <button\n type=\"button\"\n @click=\"async (event) => handleMenuItemClick(link.href)\"\n :data-active=\"isActiveLink(link.href) ? 'true' : 'false'\"\n :class=\"`propeller-account-menu__link flex w-full items-center gap-3 px-4 py-2.5 text-sm font-medium transition-colors ${\n isActiveLink(link.href)\n ? 'bg-secondary/5 text-secondary border-l-2 border-secondary'\n : 'text-muted-foreground hover:bg-surface-hover hover:text-foreground'\n }`\"\n >\n {{ link.label }}\n </button>\n </li>\n </template>\n </ul>\n </nav>\n <div\n class=\"propeller-account-menu__logout-wrapper px-4 py-3 border-t border-border\"\n >\n <button\n type=\"button\"\n class=\"propeller-account-menu__logout-btn flex w-full items-center gap-3 px-3 py-2 text-sm font-medium text-primary hover:bg-secondary/5 rounded-[var(--radius-control)] transition-colors\"\n @click=\"async (event) => handleLogoutClick()\"\n >\n {{ getLabel(\"logoutLabel\", \"Log Out\") }}\n </button>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"!isSidebar\">\n <button\n type=\"button\"\n @click=\"handleIconClick\"\n :aria-label=\"getLabel('accountLabel', 'Account')\"\n :data-open=\"menuOpen ? 'true' : 'false'\"\n :class=\"`propeller-account-menu__trigger inline-flex items-center gap-2 px-3 py-2 rounded-[var(--radius-control)] text-sm font-medium transition-colors text-white hover:bg-white/10${\n iconClassName ? ' ' + iconClassName : ''\n }`\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-account-menu__icon w-5 h-5\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z\"\n ></path>\n </svg>\n <template v-if=\"isMounted\">\n <template v-if=\"user\">\n <span\n class=\"propeller-account-menu__greeting hidden md:block font-normal\"\n >\n Hi, {{ getUserName() }}</span\n >\n </template>\n\n <template v-if=\"!user\">\n <span\n class=\"propeller-account-menu__greeting hidden md:block font-normal\"\n >{{ getLabel(\"accountLabel\", \"Account\") }}</span\n >\n </template>\n </template>\n </button>\n\n <template v-if=\"menuOpen\">\n <div\n :class=\"`propeller-account-menu__popover absolute right-0 top-full mt-1 w-80 bg-card text-foreground rounded-[var(--radius-container)] shadow-lg border border-border py-4 px-5 z-[9999]${\n menuClassName ? ' ' + menuClassName : ''\n }`\"\n >\n <template v-if=\"isMounted\">\n <template v-if=\"!!user\">\n <div\n class=\"propeller-account-menu__user pb-3 mb-3 border-b border-border\"\n >\n <p\n class=\"propeller-account-menu__user-label text-xs text-muted-foreground uppercase tracking-wider font-semibold mb-1\"\n >\n {{ getLabel(\"signedInAs\", \"Signed in as\") }}\n </p>\n <p\n class=\"propeller-account-menu__user-name font-medium text-foreground truncate\"\n >\n {{ getUserName() }}\n </p>\n </div>\n <nav class=\"propeller-account-menu__nav\">\n <ul class=\"propeller-account-menu__list space-y-0.5\">\n <template\n :key=\"link.href\"\n v-for=\"(link, index) in getMenuLinks()\"\n >\n <li class=\"propeller-account-menu__item\">\n <button\n type=\"button\"\n class=\"propeller-account-menu__link flex w-full items-center gap-3 px-3 py-2 text-sm font-medium rounded-[var(--radius-control)] text-muted-foreground hover:bg-surface-hover hover:text-foreground transition-colors\"\n @click=\"async (event) => handleMenuItemClick(link.href)\"\n >\n {{ link.label }}\n </button>\n </li>\n </template>\n </ul>\n </nav>\n <div\n class=\"propeller-account-menu__logout-wrapper mt-3 pt-3 border-t border-border\"\n >\n <button\n type=\"button\"\n class=\"propeller-account-menu__logout-btn flex w-full items-center gap-3 px-3 py-2 text-sm font-medium text-primary hover:bg-secondary/5 rounded-[var(--radius-control)] transition-colors\"\n @click=\"async (event) => handleLogoutClick()\"\n >\n {{ getLabel(\"logoutLabel\", \"Log Out\") }}\n </button>\n </div>\n </template>\n\n <template v-if=\"!user\">\n <template v-if=\"accountHeaderLoginForm !== false\">\n <component\n :is=\"LoginFormImpl\"\n :graphqlClient=\"infra.graphqlClient\"\n :cart=\"cart\"\n :title=\"\n loginFormTitle ?? getLabel('loginTitle', 'Welcome Back')\n \"\n :subtitle=\"loginFormSubtitle ?? getLabel('loginSubtitle', '')\"\n :buttonText=\"\n loginButtonText ?? getLabel('loginButton', 'Log In')\n \"\n :displayForgotPasswordLink=\"displayForgotPasswordLink\"\n :displayRegisterLink=\"displayRegisterLink\"\n :displayGuestCheckoutLink=\"displayGuestCheckoutLink\"\n :labels=\"props.loginFormLabels\"\n :onLoginSubmit=\"onLoginSubmit\"\n :loginLoading=\"loginLoading\"\n :loginError=\"loginError\"\n :beforeLogin=\"beforeLogin\"\n :afterLogin=\"afterLogin\"\n :onForgotPasswordClick=\"\n (event: any) => handleForgotPasswordClick()\n \"\n :onRegisterClick=\"(event: any) => handleRegisterClick()\"\n :onGuestCheckoutClick=\"(event: any) => handleGuestCheckoutClick()\"\n :accountHeaderLoginForm=\"accountHeaderLoginForm\"\n ></component>\n </template>\n\n <template v-if=\"accountHeaderLoginForm === false\">\n <div class=\"propeller-account-menu__login-cta text-center py-4\">\n <h4\n class=\"propeller-account-menu__login-title text-lg font-semibold mb-2\"\n >\n {{ getMenuTitle() }}\n </h4>\n <p\n class=\"propeller-account-menu__login-subtitle text-sm text-muted-foreground mb-4\"\n >\n {{\n getLabel(\"loginSubtitle\", \"Login to access your account\")\n }}\n </p>\n <button\n type=\"button\"\n class=\"propeller-account-menu__login-btn w-full inline-flex justify-center items-center px-4 py-2 rounded-[var(--radius-control)] bg-secondary text-primary-foreground text-sm font-medium hover:bg-secondary/90 transition-colors\"\n @click=\"\n async (event) => {\n closeMenu();\n if (onAccountIconClick) onAccountIconClick();\n }\n \"\n >\n {{ getLabel(\"loginButton\", \"Log In\") }}\n </button>\n </div>\n </template>\n </template>\n </template>\n </div>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, ref, watch, type Component } from \"vue\";\n\nimport { Cart, Contact, Customer, GraphQLClient } from \"@propeller-commerce/propeller-sdk-v2\";\nimport DefaultLoginForm from \"./LoginForm.vue\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface AccountMenuLink {\n /** Display label for the link */\n label: string;\n /** URL path for the link */\n href: string;\n /** Optional icon name */\n icon?: string;\n}\nexport interface AccountIconAndMenuProps {\n /**\n * Contact/Customer that this component will operate with.\n * When present, shows account navigation. When null, shows login form.\n */\n user?: Contact | Customer | null;\n\n /**\n * Icon for the account icon in header.\n * @default 'default-account-icon'\n */\n icon?: string;\n\n /**\n * Show account dropdown at the bottom of the icon when account icon is clicked.\n * If false, fires onAccountIconClick() instead.\n * @default true\n */\n showAccountMenuOnClick?: boolean;\n\n /**\n * Title for the account dropdown menu.\n * @default 'My account'\n */\n accountMenuTitle?: string;\n\n /**\n * Show login form in dropdown for immediate login when user is not logged in.\n * @default true\n */\n accountHeaderLoginForm?: boolean;\n\n // ── LoginForm pass-through props ────────────────────────────────────────\n\n /**\n * GraphQL client for self-contained login.\n * When provided (and onLoginSubmit is not), LoginForm handles authentication internally.\n */\n graphqlClient?: GraphQLClient;\n\n /**\n * Title displayed inside the login form.\n * @default 'Welcome Back'\n */\n loginFormTitle?: string;\n\n /** Subtitle displayed inside the login form. */\n loginFormSubtitle?: string;\n\n /**\n * Label for the login submit button.\n * @default 'Log In'\n */\n loginButtonText?: string;\n\n /** Translated labels forwarded to the embedded `<LoginForm>` shown\n * in the dropdown when no user is signed in.\n * See `LoginFormProps.labels` for slugs (email, password, forgotPassword,\n * registerText, registerLink, noAccount, loggingIn, etc.). */\n loginFormLabels?: Record<string, string>;\n\n /**\n * Show/hide the forgot password link inside the login form.\n * @default true\n */\n displayForgotPasswordLink?: boolean;\n\n /**\n * Show/hide the register link inside the login form.\n * @default true\n */\n displayRegisterLink?: boolean;\n\n /**\n * Show/hide the guest checkout link inside the login form.\n * @default false\n */\n displayGuestCheckoutLink?: boolean;\n\n /** Fires when the guest checkout link is clicked. */\n onGuestCheckoutClick?: () => void;\n\n /**\n * Error message shown inside the login form.\n * Used in delegation mode (when onLoginSubmit is provided).\n */\n loginError?: string;\n\n /** Callback fired before the login process starts. */\n beforeLogin?: () => void;\n\n /**\n * Callback fired after successful self-contained login.\n * Not called in delegation mode — the parent handles the result there.\n */\n afterLogin?: (\n user: Contact | Customer,\n accessToken?: string,\n refreshToken?: string,\n expiresAt?: string,\n anonymousCart?: Cart | null,\n ) => void;\n\n /** Anonymous cart snapshot — forwarded to the embedded `LoginForm` so its `afterLogin` receives it. */\n cart?: Cart | null;\n\n // ── Existing callbacks ──────────────────────────────────────────────────\n\n /**\n * Fires when login form is submitted (delegation mode).\n * Parent should handle actual authentication.\n */\n onLoginSubmit?: (email: string, password: string) => void;\n\n /**\n * Fires when account icon is clicked and showAccountMenuOnClick is false.\n */\n onAccountIconClick?: () => void;\n\n /**\n * Fires when a menu item is clicked. Receives the href.\n */\n onMenuItemClick?: (href: string) => void;\n\n /**\n * Fires when logout is clicked.\n */\n onLogoutClick?: () => void;\n\n /**\n * Fires when \"Forgot Password\" link is clicked.\n */\n onForgotPasswordClick?: () => void;\n\n /**\n * Fires when \"Register\" link is clicked.\n */\n onRegisterClick?: () => void;\n\n /**\n * Whether login is currently in progress (shows loading state on button).\n * @default false\n */\n loginLoading?: boolean;\n\n /**\n * Account navigation links shown when user is authenticated.\n * @default [{ label: 'Dashboard', href: '/account' }, ...]\n */\n menuLinks?: AccountMenuLink[];\n\n /**\n * Labels for the menu UI.\n * Available keys: accountLabel, loginTitle, loginSubtitle, loginButton,\n * signedInAs, logoutLabel, accountMenuTitle.\n * To translate the embedded LoginForm, use `loginFormLabels` instead.\n */\n labels?: Record<string, string>;\n\n /** Additional class name for the account icon button. */\n iconClassName?: string;\n\n /** Additional class name for the dropdown menu. */\n menuClassName?: string;\n\n /**\n * Component variant.\n * - 'dropdown' (default): Header icon with popup menu\n * - 'sidebar': Always-visible vertical navigation for account layout\n */\n variant?: \"dropdown\" | \"sidebar\";\n\n /**\n * Current route path, used in sidebar variant to highlight the active link.\n */\n currentPath?: string;\n\n // ───── Extension API ─────\n // Replaces the embedded LoginForm when the consumer is signed out.\n loginFormComponent?: Component;\n}\ninterface AccountIconAndMenuState {\n isMounted: boolean;\n menuOpen: boolean;\n isSidebar: boolean;\n getUserName: () => string;\n getLabel: (key: string, fallback: string) => string;\n getMenuTitle: () => string;\n getMenuLinks: () => AccountMenuLink[];\n isActiveLink: (href: string) => boolean;\n handleIconClick: () => void;\n handleMenuItemClick: (href: string) => void;\n handleLogoutClick: () => void;\n handleForgotPasswordClick: () => void;\n handleRegisterClick: () => void;\n handleGuestCheckoutClick: () => void;\n closeMenu: () => void;\n}\n\nconst props = withDefaults(defineProps<AccountIconAndMenuProps>(), {\n showAccountMenuOnClick: true,\n});\n// Pick up graphqlClient AND the signed-in user from the propellerVue plugin\n// scope + <PropellerProvider> so the host doesn't have to thread them in.\n// Direct prop access still wins via the precedence in useInfraProps.\nconst infra = useInfraProps(props);\n// Resolved, reactive user — the template and helpers read THIS, not props.user.\n// Consumers like propeller-vue mount this component without a :user prop and\n// rely on the provider. Reading props.user directly left the menu permanently\n// in its signed-out state (header showed the login form after login; the\n// account-page sidebar rendered empty). infra.user pierces through to the\n// provider's reactive scope, so login/logout now flips the UI.\nconst user = computed<Contact | Customer | null>(\n () => (infra.user as Contact | Customer | null) ?? null,\n);\nconst LoginFormImpl = computed(() => props.loginFormComponent ?? DefaultLoginForm);\nconst isMounted = ref<AccountIconAndMenuState[\"isMounted\"]>(false);\nconst menuOpen = ref<AccountIconAndMenuState[\"menuOpen\"]>(false);\nfunction _onDocumentClick() {\n menuOpen.value = false;\n}\nonMounted(() => document.addEventListener(\"click\", _onDocumentClick));\nonUnmounted(() => document.removeEventListener(\"click\", _onDocumentClick));\n\nonMounted(() => {\n isMounted.value = true;\n});\n\nconst isSidebar = computed(() => {\n return props.variant === \"sidebar\";\n});\n\nwatch(\n () => user.value,\n () => {\n // Close menu when user logs in (user resolves from null to truthy)\n if (user.value && menuOpen.value) {\n menuOpen.value = false;\n }\n },\n { immediate: true },\n);\nfunction getUserName(): ReturnType<AccountIconAndMenuState[\"getUserName\"]> {\n const u = user.value as Contact | Customer;\n if (!u) return \"\";\n const parts = [u.firstName, u.lastName].filter(Boolean);\n if (parts.length > 0) return parts.join(\" \");\n if (u.firstName) return u.firstName;\n if (u.email) return u.email;\n return \"User\";\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<AccountIconAndMenuState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getMenuTitle(): ReturnType<AccountIconAndMenuState[\"getMenuTitle\"]> {\n return (\n props.accountMenuTitle ||\n (props.labels as Record<string, string>)?.[\"accountMenuTitle\"] ||\n \"My account\"\n );\n}\nfunction isActiveLink(\n href: string,\n): ReturnType<AccountIconAndMenuState[\"isActiveLink\"]> {\n if (!props.currentPath) return false;\n if (href.endsWith(\"/account\")) return props.currentPath === href;\n return props.currentPath.startsWith(href);\n}\nfunction getMenuLinks(): ReturnType<AccountIconAndMenuState[\"getMenuLinks\"]> {\n if (props.menuLinks && (props.menuLinks as AccountMenuLink[]).length > 0) {\n return props.menuLinks as AccountMenuLink[];\n }\n return [\n {\n label: \"Dashboard\",\n href: \"/account\",\n },\n {\n label: \"Orders\",\n href: \"/account/orders\",\n },\n {\n label: \"Addresses\",\n href: \"/account/addresses\",\n },\n {\n label: \"Quotes\",\n href: \"/account/quotes\",\n },\n {\n label: \"Invoices\",\n href: \"/account/invoices\",\n },\n {\n label: \"Favorites\",\n href: \"/account/favorites\",\n },\n ] as AccountMenuLink[];\n}\nfunction handleIconClick(): ReturnType<\n AccountIconAndMenuState[\"handleIconClick\"]\n> {\n if (props.showAccountMenuOnClick !== false) {\n menuOpen.value = !menuOpen.value;\n } else {\n if (props.onAccountIconClick) props.onAccountIconClick();\n }\n}\nfunction handleMenuItemClick(\n href: string,\n): ReturnType<AccountIconAndMenuState[\"handleMenuItemClick\"]> {\n menuOpen.value = false;\n if (props.onMenuItemClick) props.onMenuItemClick(href);\n}\nfunction handleLogoutClick(): ReturnType<\n AccountIconAndMenuState[\"handleLogoutClick\"]\n> {\n menuOpen.value = false;\n if (props.onLogoutClick) props.onLogoutClick();\n}\nfunction handleForgotPasswordClick(): ReturnType<\n AccountIconAndMenuState[\"handleForgotPasswordClick\"]\n> {\n menuOpen.value = false;\n if (props.onForgotPasswordClick) props.onForgotPasswordClick();\n}\nfunction handleRegisterClick(): ReturnType<\n AccountIconAndMenuState[\"handleRegisterClick\"]\n> {\n menuOpen.value = false;\n if (props.onRegisterClick) props.onRegisterClick();\n}\nfunction handleGuestCheckoutClick(): ReturnType<\n AccountIconAndMenuState[\"handleGuestCheckoutClick\"]\n> {\n menuOpen.value = false;\n if (props.onGuestCheckoutClick) props.onGuestCheckoutClick();\n}\nfunction closeMenu(): ReturnType<AccountIconAndMenuState[\"closeMenu\"]> {\n menuOpen.value = false;\n}\n</script>\n","<template>\n <div class=\"propeller-action-code w-full bg-card p-6 rounded-[var(--radius-container)] shadow space-y-3\">\n <h2 class=\"text-lg font-bold\">{{ title }}</h2>\n <template v-if=\"isMounted\">\n <template v-if=\"hasAppliedCode\">\n <div\n class=\"flex items-center justify-between bg-secondary/5 border border-secondary/20 rounded-[var(--radius-control)] px-3 py-2\"\n >\n <div class=\"flex items-center gap-2\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"w-4 h-4 text-secondary\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n ></path></svg\n ><span class=\"text-sm font-medium text-secondary\">{{ appliedCode }}</span>\n </div>\n <template v-if=\"showRemoveCode\">\n <button\n type=\"button\"\n class=\"text-secondary hover:text-secondary text-sm font-medium transition-colors disabled:opacity-50\"\n @click=\"async (event) => handleRemove()\"\n :disabled=\"loading\"\n >\n {{ getLabel('remove', 'Remove') }}\n </button>\n </template>\n </div>\n </template>\n\n <template v-if=\"!hasAppliedCode\">\n <div class=\"flex gap-2\">\n <input\n type=\"text\"\n class=\"propeller-action-code__input flex-1 text-sm border border-input rounded-[var(--radius-control)] px-3 py-2 focus:ring-2 focus:ring-secondary focus:border-transparent disabled:opacity-50\"\n :value=\"code\"\n @change=\"\n async (e) => {\n code = (e.target as HTMLInputElement).value;\n }\n \"\n @keydown=\"async (e) => handleKeyDown(e)\"\n :placeholder=\"getLabel('placeholder', 'Enter action code')\"\n :disabled=\"loading\"\n /><button\n type=\"button\"\n class=\"propeller-action-code__submit bg-secondary text-primary-foreground text-sm font-medium px-4 py-2 rounded-[var(--radius-control)] hover:bg-secondary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap\"\n @click=\"async (event) => handleApply()\"\n :disabled=\"loading || !code.trim()\"\n >\n <template v-if=\"loading\">\n {{ getLabel('applying', 'Applying...') }}\n </template>\n\n <template v-if=\"!loading\">\n {{ getLabel('apply', 'Apply') }}\n </template>\n </button>\n </div>\n </template>\n\n <template v-if=\"!!error\">\n <p class=\"propeller-action-code__error text-sm text-destructive\">{{ errorMessage }}</p>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from \"vue\";\n\nimport { GraphQLClient, Cart } from '@propeller-commerce/propeller-sdk-v2';\nimport { useCart } from '../composables/vue/useCart';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface ActionCodeProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** The shopping cart used to populate the cart summary data */\n cart: Cart;\n\n /** Action code block title */\n title?: string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** Display the option to remove the action code of the shopping cart. Defaults to true. */\n showRemoveCode?: boolean;\n\n /** Action handler when action code is added to the cart */\n onActionCodeApply?: (code: string, cart: Cart) => void;\n\n /** Action handler when action code is removed from the cart */\n onActionCodeRemove?: (code: string, cart: Cart) => void;\n\n /** Action callback method after action code is applied */\n afterActionCodeApply?: (cart: Cart) => void;\n\n /** Action callback method after action code is removed */\n afterActionCodeRemove?: (cart: Cart) => void;\n\n /** Configuration object for image filters */\n configuration?: any;\n\n /** Language code for CartService operations. Defaults to 'NL'. */\n language?: string;\n}\ninterface ActionCodeState {\n code: string;\n isMounted: boolean;\n getLabel: (key: string, fallback: string) => string;\n title: string;\n showRemoveCode: boolean;\n appliedCode: string;\n hasAppliedCode: boolean;\n handleApply: () => Promise<void>;\n handleRemove: () => Promise<void>;\n handleKeyDown: (e: any) => void;\n}\n\nconst props = withDefaults(defineProps<ActionCodeProps>(), {\n showRemoveCode: true,\n});\nconst infra = useInfraProps(props);\nconst code = ref<ActionCodeState['code']>('');\nconst isMounted = ref<ActionCodeState['isMounted']>(false);\n\nconst userRef = computed(() => null as any);\nconst { loading, error, addActionCode, removeActionCode } = useCart({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n cartId: props.cart?.cartId,\n configuration: {\n imageSearchFiltersGrid: infra.configuration?.imageSearchFiltersGrid ?? ({} as any),\n imageVariantFiltersSmall: infra.configuration?.imageVariantFiltersSmall ?? ({} as any),\n },\n});\n\n\nonMounted(() => {\n isMounted.value = true;\n});\n\nconst title = computed(() => {\n return props.title || 'Action code';\n});\nconst showRemoveCode = computed(() => {\n return props.showRemoveCode !== undefined ? props.showRemoveCode : true;\n});\nconst appliedCode = computed(() => {\n return props.cart?.actionCode || '';\n});\nconst hasAppliedCode = computed(() => {\n return !!props.cart?.actionCode;\n});\n\nfunction getLabel(key: string, fallback: string): ReturnType<ActionCodeState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\n\n// Surface a friendly fixed message for any action-code failure — server-side\n// error strings can be cryptic (\"Code not found\", GraphQL \"Bad Request\", etc.)\n// and aren't safe to show to end users. Override via `labels.invalidActionCode`\n// if a specific copy is needed.\nconst errorMessage = computed(() => {\n if (!error.value) return '';\n return getLabel(\n 'invalidActionCode',\n 'This action code is not found. Please add a valid action code.',\n );\n});\nasync function handleApply(): ReturnType<ActionCodeState['handleApply']> {\n if (!code.value.trim() || loading.value) return;\n error.value = '';\n if (props.onActionCodeApply) {\n props.onActionCodeApply(code.value.trim(), props.cart);\n return;\n }\n const updatedCart = await addActionCode(code.value.trim());\n if (updatedCart) {\n code.value = '';\n if (props.afterActionCodeApply) {\n props.afterActionCodeApply(updatedCart);\n }\n } else if (!error.value) {\n error.value = getLabel('errorApply', 'Failed to apply action code. Please try again.');\n }\n}\nasync function handleRemove(): ReturnType<ActionCodeState['handleRemove']> {\n if (loading.value || !hasAppliedCode.value) return;\n error.value = '';\n const currentCode = appliedCode.value;\n if (props.onActionCodeRemove) {\n props.onActionCodeRemove(currentCode, props.cart);\n return;\n }\n const updatedCart = await removeActionCode(currentCode);\n if (updatedCart) {\n if (props.afterActionCodeRemove) {\n props.afterActionCodeRemove(updatedCart);\n }\n } else if (!error.value) {\n error.value = getLabel('errorRemove', 'Failed to remove action code. Please try again.');\n }\n}\nfunction handleKeyDown(e: any): ReturnType<ActionCodeState['handleKeyDown']> {\n if (e.key === 'Enter') {\n handleApply();\n }\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-add-to-cart ${className || ''}`\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <div class=\"propeller-add-to-cart__controls flex items-center gap-2 w-full\">\n <template v-if=\"allowIncrDecr !== false\">\n <div\n class=\"propeller-add-to-cart__stepper flex items-center border border-input rounded-[var(--radius-control)] bg-card h-10\"\n >\n <button\n type=\"button\"\n class=\"propeller-add-to-cart__decrement px-3 h-full text-muted-foreground hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed transition-colors rounded-l-[var(--radius-control)] select-none\"\n @click=\"async (event) => decrement()\"\n :disabled=\"quantity <= getMinQuantity(props.product) || loading\"\n >\n -</button\n ><input\n type=\"number\"\n class=\"propeller-add-to-cart__quantity w-12 text-center text-sm bg-transparent border-none focus:ring-0 focus:outline-none h-full [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n :min=\"getMinQuantity(props.product)\"\n :step=\"getStep(props.product)\"\n :value=\"quantity\"\n @change=\"\n async (e) => {\n const val = parseInt((e.target as HTMLInputElement).value, 10);\n const min = getMinQuantity(props.product);\n const step = getStep(props.product);\n if (!isNaN(val) && val >= min) {\n quantity = Math.round((val - min) / step) * step + min;\n }\n }\n \"\n /><button\n type=\"button\"\n class=\"propeller-add-to-cart__increment px-3 h-full text-muted-foreground hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed transition-colors rounded-r-[var(--radius-control)] select-none\"\n @click=\"async (event) => increment()\"\n :disabled=\"loading\"\n >\n +\n </button>\n </div>\n </template>\n\n <template v-if=\"allowIncrDecr === false\">\n <input\n type=\"number\"\n class=\"propeller-add-to-cart__quantity w-16 h-10 text-center text-sm border border-input rounded-[var(--radius-control)] focus:ring-2 focus:ring-secondary focus:border-transparent [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n :min=\"getMinQuantity(props.product)\"\n :step=\"getStep(props.product)\"\n :value=\"quantity\"\n @change=\"\n async (e) => {\n const val = parseInt((e.target as HTMLInputElement).value, 10);\n const min = getMinQuantity(props.product);\n const step = getStep(props.product);\n if (!isNaN(val) && val >= min) {\n quantity = Math.round((val - min) / step) * step + min;\n }\n }\n \"\n />\n </template>\n\n <button\n type=\"button\"\n class=\"propeller-add-to-cart__submit flex-1 inline-flex justify-center items-center h-10 px-6 border border-transparent text-sm font-medium rounded-[var(--radius-control)] text-primary-foreground bg-secondary hover:bg-secondary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-secondary disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n @click=\"async (event) => handleAddToCart()\"\n :disabled=\"loading\"\n >\n <template v-if=\"loading\">\n {{ getLabel(\"adding\", \"Adding...\") }}\n </template>\n\n <template v-if=\"!loading\">\n {{ getLabel(\"add\", \"Add\") }}\n </template>\n </button>\n </div>\n <template v-if=\"toastVisible\">\n <div\n :class=\"`propeller-add-to-cart__toast fixed top-4 right-4 z-50 flex items-start gap-3 w-80 rounded-[var(--radius-container)] shadow-lg p-4 ${\n toastType === 'success'\n ? 'bg-success border border-success text-success-foreground'\n : 'bg-destructive border border-destructive text-destructive-foreground'\n }`\"\n :data-toast-type=\"toastType\"\n >\n <div\n :class=\"`propeller-add-to-cart__toast-icon flex-shrink-0 w-5 h-5 mt-0.5 ${\n toastType === 'success' ? 'text-success-foreground' : 'text-destructive-foreground'\n }`\"\n >\n <template v-if=\"toastType === 'success'\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"toastType === 'error'\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z\"\n ></path>\n </svg>\n </template>\n </div>\n <p\n :class=\"`propeller-add-to-cart__toast-message flex-1 text-sm font-medium ${\n toastType === 'success' ? 'text-success-foreground' : 'text-destructive-foreground'\n }`\"\n >\n {{ toastMessage }}\n </p>\n <button\n type=\"button\"\n @click=\"async (event) => dismissToast()\"\n :class=\"`propeller-add-to-cart__toast-close flex-shrink-0 rounded focus:outline-none ${\n toastType === 'success'\n ? 'text-success-foreground hover:text-success-foreground/80'\n : 'text-destructive-foreground hover:text-destructive-foreground/80'\n }`\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-4 w-4\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n </template>\n\n <template v-if=\"modalVisible\">\n <div\n class=\"propeller-add-to-cart__modal fixed inset-0 z-50 flex items-center justify-center px-4\"\n >\n <div\n class=\"propeller-add-to-cart__modal-backdrop fixed inset-0 bg-foreground/20\"\n @click=\"async (event) => closeModal()\"\n ></div>\n <div\n class=\"propeller-add-to-cart__modal-content relative w-full max-w-lg bg-card rounded-[var(--radius-container)] shadow-2xl overflow-hidden\"\n >\n <div\n class=\"propeller-add-to-cart__modal-header flex items-center gap-3 px-6 py-4 border-b border-border-subtle\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"propeller-add-to-cart__modal-success-icon h-5 w-5 flex-shrink-0 text-success\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n <h3\n class=\"propeller-add-to-cart__modal-title flex-1 text-base font-semibold text-foreground\"\n >\n {{ getLabel(\"modalTitle\", \"Added to cart\") }}\n </h3>\n <button\n type=\"button\"\n class=\"propeller-add-to-cart__modal-close flex-shrink-0 text-foreground-subtle hover:text-muted-foreground focus:outline-none\"\n @click=\"async (event) => closeModal()\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-5 w-5\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n <div class=\"propeller-add-to-cart__modal-body px-6 py-5\">\n <div\n class=\"propeller-add-to-cart__modal-product flex items-start gap-4\"\n >\n <template v-if=\"!!getModalImageUrl()\">\n <img\n class=\"propeller-add-to-cart__modal-image w-16 h-16 object-contain rounded border border-border-subtle flex-shrink-0\"\n :src=\"getModalImageUrl()\"\n :alt=\"getModalName()\"\n />\n </template>\n\n <template v-if=\"!getModalImageUrl()\">\n <div\n class=\"propeller-add-to-cart__modal-image-placeholder w-16 h-16 flex items-center justify-center rounded border border-border-subtle flex-shrink-0 bg-surface-hover\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"w-8 h-8 text-foreground-subtle\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z\"\n ></path>\n </svg>\n </div>\n </template>\n\n <div class=\"flex-1 min-w-0\">\n <a\n class=\"propeller-add-to-cart__modal-product-title text-sm font-medium text-secondary leading-tight hover:underline line-clamp-2\"\n :href=\"getProductUrl()\"\n >{{ getModalName() }}</a\n >\n <template v-if=\"!!getModalSku()\">\n <p\n class=\"propeller-add-to-cart__modal-sku text-xs text-foreground-subtle mt-0.5\"\n >\n SKU: {{ getModalSku() }}\n </p>\n </template>\n <template v-if=\"getModalSurcharges().length > 0\">\n <div\n class=\"propeller-add-to-cart__modal-surcharges mt-1 text-xs text-muted-foreground\"\n >\n <span class=\"font-medium\">{{ getLabel(\"surcharges\", \"Additional surcharges:\") }}</span>\n <ul class=\"propeller-add-to-cart__modal-surcharges-list mt-0.5\">\n <li\n v-for=\"(line, idx) in getModalSurcharges()\"\n :key=\"idx\"\n class=\"propeller-add-to-cart__modal-surcharge\"\n >\n {{ line }}\n </li>\n </ul>\n </div>\n </template>\n </div>\n <div class=\"flex-shrink-0 text-right\">\n <p\n class=\"propeller-add-to-cart__modal-quantity text-xs text-muted-foreground\"\n >\n {{ getLabel(\"quantity\", \"Quantity\") }}: {{ quantity }}\n </p>\n <template v-if=\"!!getModalPrice()\">\n <component\n v-if=\"props.priceComponent\"\n :is=\"PriceImpl\"\n :price=\"addedCartItem?.product?.price ?? product.price\"\n :include-tax=\"resolvedIncludeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n />\n <p\n v-else\n class=\"propeller-add-to-cart__modal-price text-sm font-semibold text-foreground mt-0.5\"\n >\n {{ getModalPrice() }}\n </p>\n </template>\n </div>\n </div>\n <template v-if=\"getChildItems().length > 0\">\n <div\n class=\"propeller-add-to-cart__modal-children mt-3 ml-20 space-y-1 border-l-2 border-border-subtle pl-2\"\n >\n <template :key=\"idx\" v-for=\"(child, idx) in getChildItems()\">\n <div\n class=\"propeller-add-to-cart__modal-child flex justify-between items-center text-xs text-muted-foreground\"\n >\n <span class=\"line-clamp-1\">{{\n child.product?.names?.[0]?.value || \"Option\"\n }}</span\n ><span\n class=\"text-foreground-subtle whitespace-nowrap ml-2\"\n >{{ getChildItemPrice(child) }}</span\n >\n </div>\n </template>\n </div>\n </template>\n </div>\n <div\n class=\"propeller-add-to-cart__modal-actions flex gap-3 px-6 py-4 border-t border-border-subtle\"\n >\n <button\n type=\"button\"\n class=\"propeller-add-to-cart__modal-continue flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-input bg-card px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2\"\n @click=\"async (event) => closeModal()\"\n >\n {{ getLabel(\"continueShopping\", \"Continue shopping\") }}\n </button>\n <template\n v-if=\"checkoutAllowed && !!onRequestQuoteClick && !!user && 'contactId' in user\"\n >\n <button\n type=\"button\"\n class=\"propeller-add-to-cart__modal-quote flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-secondary bg-card px-4 py-2 text-sm font-medium text-secondary hover:bg-secondary/5 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2\"\n @click=\"\n async (event) => {\n closeModal();\n if (onRequestQuoteClick && cart) onRequestQuoteClick(cart);\n }\n \"\n >\n {{ getLabel(\"requestQuoteButton\", \"Request a Quote\") }}\n </button>\n </template>\n\n <template v-if=\"checkoutAllowed\">\n <button\n type=\"button\"\n class=\"propeller-add-to-cart__modal-checkout flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-transparent bg-secondary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-secondary/90 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2\"\n @click=\"\n async (event) => {\n closeModal();\n if (onProceedToCheckout) onProceedToCheckout();\n }\n \"\n >\n {{ getLabel(\"proceedToCheckout\", \"Proceed to checkout\") }}\n </button>\n </template>\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, ref, computed, type Component } from \"vue\";\n\nimport { CartChildItemInput, GraphQLClient, Product, Cart, Contact, Customer, TransformationsInput, MediaImageProductSearchInput, CartMainItem, CartBaseItem, Cluster, PurchaseAuthorizationConfig } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useCart } from \"../composables/vue/useCart\";\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n getProductImageUrl as _getProductImageUrl,\n getProductSku as _getProductSku,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice, formatSurcharge as _formatSurcharge } from '@propeller-commerce/propeller-v2-core-ui';\nimport DefaultProductPrice from './ProductPrice.vue';\n\nexport interface AddToCartProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** The authenticated user (Contact or Customer) */\n user: Contact | Customer | null;\n\n /** The product to be added to cart */\n product: Product;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** Cart ID — required when onAddToCart is not provided */\n cartId?: string;\n\n /** The cluster to be added to cart */\n cluster?: Cluster;\n\n /** IDs of the cluster child items, e.g. cluster options */\n childItems?: number[];\n\n /** Called before adding to cart. Return false to abort (e.g. failed validation). */\n beforeAddToCart?: () => boolean;\n\n /** Notes for the cart item */\n notes?: string;\n\n /** Custom price for the product (overrides calculated price) */\n price?: number;\n\n /** Label overrides for UI strings\n *\n * available labels:\n * - outOfStock\n * - noCartId\n * - errorAdding\n * - addedToCart\n * - modalTitle\n * - quantity\n * - continueShopping\n * - proceedToCheckout\n * - requestQuoteButton\n * - add\n * - adding\n */\n labels?: Record<string, string>;\n\n /**\n * If true a new cart is created if no cart ID is provided.\n * Defaults to false.\n */\n createCart?: boolean;\n\n /**\n * Callback to handle a new cart being created.\n * WARNING: If not provided the component create new carts on every add-to-cart.\n */\n onCartCreated?: (cart: Cart) => void;\n\n /**\n * Callback to handle adding the product to cart.\n * If not provided the component calls CartService.addItemToCart internally.\n */\n onAddToCart?: (\n product: Product,\n clusterId?: number,\n quantity?: number,\n childItems?: CartChildItemInput[],\n notes?: string,\n price?: number,\n showModal?: boolean,\n ) => Cart;\n\n /**\n * Callback triggered after adding the product to cart.\n */\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n\n /**\n * When true a modal popup is shown after a successful add-to-cart\n * with buttons to continue shopping or proceed to checkout.\n * Defaults to false (only a brief inline success message is shown).\n */\n showModal?: boolean;\n\n /**\n * Renders − and + buttons beside the quantity input.\n * Defaults to true.\n */\n allowIncrDecr?: boolean;\n\n /**\n * Validates available stock via InventoryService before adding.\n * Defaults to false.\n */\n enableStockValidation?: boolean;\n\n /** Language code passed to CartService operations. Defaults to 'en'. */\n language?: string;\n\n /** Additional CSS class for the root element */\n className?: string;\n\n /** Callback fired when the \"Proceed to checkout\" modal button is clicked */\n onProceedToCheckout?: () => void;\n\n /** Callback fired when the \"Request a Quote\" modal button is clicked */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /** Configuration object passed to the component */\n configuration?: {\n language?: string;\n imageSearchFiltersGrid?: MediaImageProductSearchInput;\n imageVariantFiltersSmall?: TransformationsInput;\n urls?: { getProductUrl: (product: Product, language?: string) => string };\n };\n\n /** Active company ID from the company switcher. Overrides user's default company for cart creation and lookup. */\n companyId?: number;\n\n /**\n * When true, tax-inclusive price (net) is shown.\n * When false, tax-exclusive price (gross) is shown.\n * Defaults to false.\n */\n includeTax?: boolean;\n\n // ───── Extension API ─────\n // Render branded price/stock in the success modal. AddToCart itself is\n // the component being injected upstream by other hosts, so it does NOT\n // accept an addToCartComponent prop here.\n priceComponent?: Component;\n stockComponent?: Component; // Reserved — modal doesn't render stock today\n}\n\n/**\n * Cart query variables interface Variables for the cart query\n */\n/**\n * Cart query variables interface Variables for the cart query\n */\nexport interface CartQueryVariables {\n /** Cart ID to fetch */\n cartId: string;\n /** Language for localized content */\n language: string;\n /** Image search filters */\n imageSearchFilters: MediaImageProductSearchInput;\n /** Image transformation filters */\n imageVariantFilters: TransformationsInput;\n}\n/**\n * Cart query variables interface Variables for the cart query\n */\n\ninterface AddToCartState {\n quantity: number;\n loading: boolean;\n success: boolean;\n modalVisible: boolean;\n activeCartId: string;\n toastMessage: string;\n toastType: string;\n toastVisible: boolean;\n includeTax: boolean;\n priceListener: any;\n getMinQuantity: () => number;\n getStep: () => number;\n increment: () => void;\n decrement: () => void;\n showToast: (message: string, type: string) => void;\n dismissToast: () => void;\n getProductName: () => string;\n getProductUrl: () => string;\n getProductImageUrl: () => string;\n getProductSku: () => string;\n getProductPrice: () => string;\n addedCartItem: CartMainItem | null;\n activeFullCart: Cart | null;\n checkoutAllowed: () => boolean;\n getModalImageUrl: () => string;\n getModalName: () => string;\n getModalPrice: () => string;\n getModalSku: () => string;\n getChildItems: () => CartBaseItem[];\n getChildItemPrice: (child: CartBaseItem) => string;\n initCart: () => Promise<string>;\n handleAddToCart: () => Promise<void>;\n closeModal: () => void;\n getLabel: (key: string, fallback: string) => string;\n}\n\nconst props = withDefaults(defineProps<AddToCartProps>(), {\n allowIncrDecr: true,\n});\n\n// Fall back to the propellerVue plugin scope when the host doesn't pass\n// graphqlClient/user/companyId/configuration explicitly. Direct prop access\n// still wins via useInfraProps' precedence.\nconst infra = useInfraProps(props);\n\n// stockComponent is a reserved slot — the success modal does not render\n// stock today (stock errors surface as toasts pre-add), so consumers passing\n// stockComponent have no effect until/unless the modal grows a stock display.\nconst PriceImpl = computed(() => props.priceComponent ?? DefaultProductPrice);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\n\nconst { cart, loading, checkoutAllowed, addItem, getMinQuantity, getStep } =\n useCart({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n user: userRef,\n companyId: companyRef,\n cartId: props.cartId,\n configuration: {\n imageSearchFiltersGrid:\n infra.configuration?.imageSearchFiltersGrid ?? ({} as any),\n imageVariantFiltersSmall:\n infra.configuration?.imageVariantFiltersSmall ?? ({} as any),\n language: infra.configuration?.language,\n },\n onCartCreated: props.onCartCreated,\n });\n\nconst quantity = ref<AddToCartState[\"quantity\"]>(1);\nconst success = ref<AddToCartState[\"success\"]>(false);\nconst modalVisible = ref<AddToCartState[\"modalVisible\"]>(false);\nconst toastMessage = ref<AddToCartState[\"toastMessage\"]>(\"\");\nconst toastType = ref<AddToCartState[\"toastType\"]>(\"\");\nconst toastVisible = ref<AddToCartState[\"toastVisible\"]>(false);\nconst addedCartItem = ref<AddToCartState[\"addedCartItem\"]>(null);\nconst includeTax = ref<AddToCartState[\"includeTax\"]>(false);\nconst priceListener = ref<AddToCartState[\"priceListener\"]>(null);\n\n// Mirrors getModalPrice()'s resolution: props.includeTax overrides the local\n// ref. Used when injecting a priceComponent into the success modal.\nconst resolvedIncludeTax = computed<boolean>(() =>\n props.includeTax !== undefined ? !!props.includeTax : includeTax.value,\n);\n\nonMounted(() => {\n quantity.value = getMinQuantity(props.product);\n});\n\nfunction increment(): ReturnType<AddToCartState[\"increment\"]> {\n quantity.value = quantity.value + getStep(props.product);\n}\nfunction decrement(): ReturnType<AddToCartState[\"decrement\"]> {\n const min = getMinQuantity(props.product);\n const step = getStep(props.product);\n if (quantity.value - step >= min) {\n quantity.value = quantity.value - step;\n }\n}\nfunction showToast(\n message: string,\n type: string,\n): ReturnType<AddToCartState[\"showToast\"]> {\n toastMessage.value = message;\n toastType.value = type;\n toastVisible.value = true;\n setTimeout(() => {\n toastVisible.value = false;\n }, 3000);\n}\nfunction dismissToast(): ReturnType<AddToCartState[\"dismissToast\"]> {\n toastVisible.value = false;\n}\nfunction getProductName(): ReturnType<AddToCartState[\"getProductName\"]> {\n return (props.product as Product)?.names?.[0]?.value || \"Product\";\n}\nfunction getProductUrl(): ReturnType<AddToCartState[\"getProductUrl\"]> {\n return (\n props.configuration?.urls?.getProductUrl(props.product, props.language) ??\n \"#\"\n );\n}\nfunction getProductImageUrl(): ReturnType<\n AddToCartState[\"getProductImageUrl\"]\n> {\n return _getProductImageUrl(props.product as Product);\n}\nfunction getProductSku(): ReturnType<AddToCartState[\"getProductSku\"]> {\n return _getProductSku(props.product as Product);\n}\nfunction getProductPrice(): ReturnType<AddToCartState[\"getProductPrice\"]> {\n const price =\n props.price !== undefined\n ? props.price\n : (props.product as Product)?.price?.gross;\n if (!price && price !== 0) return \"\";\n return _formatPrice(Number(price), { symbol: props.currency ?? \"€\" });\n}\nasync function handleAddToCart(): ReturnType<\n AddToCartState[\"handleAddToCart\"]\n> {\n if (!infra.graphqlClient) return;\n if (props.beforeAddToCart && !props.beforeAddToCart()) return;\n success.value = false;\n const result = await addItem({\n product: props.product,\n cluster: props.cluster,\n childItems: props.childItems,\n quantity: quantity.value,\n notes: props.notes,\n price: props.price,\n cartId: props.cartId,\n enableStockValidation: props.enableStockValidation,\n onAddToCart: props.onAddToCart as any,\n createCart: props.createCart,\n afterAddToCart: (resultCart, item) => {\n addedCartItem.value = resolveAddedItem(resultCart, item ?? null);\n props.afterAddToCart?.(resultCart, item ?? undefined);\n },\n });\n if (!result.ok) {\n showToast(\n getLabel(\n result.error === \"Insufficient stock available\"\n ? \"outOfStock\"\n : \"errorAdding\",\n result.error || \"Failed to add item to cart\",\n ),\n \"error\",\n );\n return;\n }\n success.value = true;\n if (props.showModal) {\n modalVisible.value = true;\n } else {\n showToast(\n `${getProductName()} ${getLabel(\"addedToCart\", \"added to cart\")}`,\n \"success\",\n );\n }\n}\nfunction getModalImageUrl(): ReturnType<AddToCartState[\"getModalImageUrl\"]> {\n if (addedCartItem.value) {\n const img =\n addedCartItem.value.product?.media?.images?.items?.[0]?.imageVariants?.[0]\n ?.url;\n if (img) return img;\n }\n return getProductImageUrl();\n}\nfunction getModalName(): ReturnType<AddToCartState[\"getModalName\"]> {\n if (addedCartItem.value) {\n return addedCartItem.value.product?.names?.[0]?.value || getProductName();\n }\n return getProductName();\n}\nfunction getModalPrice(): ReturnType<AddToCartState[\"getModalPrice\"]> {\n if (addedCartItem.value) {\n const useTax: boolean =\n props.includeTax !== undefined ? !!props.includeTax : includeTax.value;\n const price = useTax\n ? addedCartItem.value.totalSumNet\n : addedCartItem.value.totalSum;\n return _formatPrice(Number(price), { symbol: props.currency ?? \"€\" });\n }\n return getProductPrice();\n}\nfunction getModalSku(): ReturnType<AddToCartState[\"getModalSku\"]> {\n if (addedCartItem.value) return addedCartItem.value.product?.sku || \"\";\n return getProductSku();\n}\nfunction getModalSurcharges(): string[] {\n // Prefer the cart item's own surcharges (CartItemSurcharge: localized `names`,\n // may carry their own quantity); fall back to the product's surcharges\n // (Surcharge: `name`) for the pre-add state. Quantity is the line quantity.\n type SurchargeLike = {\n name?: { value?: string; language?: string }[];\n names?: { value?: string; language?: string }[];\n type?: string;\n value?: number;\n quantity?: number;\n enabled?: boolean;\n };\n const cartSurcharges = (addedCartItem.value?.surcharges ?? []) as SurchargeLike[];\n const source: SurchargeLike[] =\n cartSurcharges.length > 0\n ? cartSurcharges\n : ((props.product?.surcharges ?? []) as SurchargeLike[]);\n return source\n .filter((s: SurchargeLike) => s.enabled !== false)\n .map((s: SurchargeLike) =>\n _formatSurcharge(s, {\n quantity: s.quantity ?? quantity.value,\n language: props.language,\n currency: props.currency ?? \"€\",\n }),\n )\n .filter((line: string) => line.length > 0);\n}\nfunction getChildItems(): ReturnType<AddToCartState[\"getChildItems\"]> {\n const children = addedCartItem.value?.childItems;\n if (!children || !Array.isArray(children)) return [];\n return children;\n}\n/**\n * Resolve the cart line to show in the success modal for THIS add-to-cart.\n *\n * `addItem` returns the first cart item whose `productId` matches the added\n * product. That's wrong when the cart also holds a bundle whose leader is the\n * same product (same SKU/productId): the bundle's main item matches first, so\n * the modal would render the bundle's members as this product's child items.\n * Re-resolve to the standalone (non-bundle) line for the product — preferring\n * the most recent match — and ignore bundle items. Falls back to `addItem`'s\n * item when no standalone line is found.\n */\nfunction resolveAddedItem(\n resultCart: Cart | undefined,\n fallback: CartMainItem | null,\n): CartMainItem | null {\n const items = resultCart?.items;\n if (!items || !Array.isArray(items)) return fallback;\n const productId = props.product?.productId;\n const standalone = items.filter(\n (i: CartMainItem) => i.productId === productId && !i.bundle && !i.bundleId,\n );\n return standalone.length > 0 ? standalone[standalone.length - 1] : fallback;\n}\nfunction getChildItemPrice(\n child: CartBaseItem,\n): ReturnType<AddToCartState[\"getChildItemPrice\"]> {\n const useTax: boolean =\n props.includeTax !== undefined ? !!props.includeTax : includeTax.value;\n const value = useTax ? child.totalSumNet : child.totalSum;\n return _formatPrice(Number(value ?? 0), { symbol: props.currency ?? \"€\" });\n}\nfunction closeModal(): ReturnType<AddToCartState[\"closeModal\"]> {\n modalVisible.value = false;\n success.value = false;\n addedCartItem.value = null;\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<AddToCartState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\n</script>\n","<template>\n <template v-if=\"user\">\n <div\n class=\"propeller-add-to-favorite relative inline-block\"\n :data-favorited=\"isFavorited ? 'true' : 'false'\"\n >\n <button\n type=\"button\"\n @click=\"async (event) => toggleModal()\"\n :title=\"\n isFavorited\n ? getLabel('removeFromFavorites', 'Remove from favorites')\n : getLabel('addToFavorites', 'Add to favorites')\n \"\n :class=\"`propeller-add-to-favorite__btn inline-flex items-center justify-center rounded-[var(--radius-control)] border p-2.5 transition-colors ${\n isFavorited\n ? 'border-primary/30 bg-primary/5 text-primary hover:bg-primary/10'\n : 'border-border bg-card text-foreground-subtle hover:text-primary hover:border-primary/30 hover:bg-primary/5'\n } ${className || ''}`\"\n >\n <template v-if=\"isFavorited\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path\n d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3.332.67-4.5 2.17C10.832 3.67 9.26 3 7.5 3A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"!isFavorited\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path\n d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3.332.67-4.5 2.17C10.832 3.67 9.26 3 7.5 3A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\"\n ></path>\n </svg>\n </template>\n </button>\n <template v-if=\"showModal && _isMounted\">\n <div\n class=\"propeller-add-to-favorite__modal fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\"\n >\n <div\n class=\"propeller-add-to-favorite__modal-content bg-card rounded-[var(--radius-container)] max-w-md w-full shadow-lg border\"\n >\n <div\n class=\"propeller-add-to-favorite__modal-header flex justify-between items-center p-6 pb-4\"\n >\n <h3\n class=\"propeller-add-to-favorite__modal-title text-xl font-bold\"\n >\n {{ getLabel(\"modalTitle\", \"Favorite product?\") }}\n </h3>\n <button\n type=\"button\"\n class=\"propeller-add-to-favorite__modal-close h-8 w-8 p-0 inline-flex items-center justify-center rounded-[var(--radius-control)] text-muted-foreground hover:text-muted-foreground hover:bg-surface-hover\"\n @click=\"async (event) => closeModal()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\"></path>\n <path d=\"m6 6 12 12\"></path>\n </svg>\n </button>\n </div>\n <div\n class=\"propeller-add-to-favorite__modal-body px-6 pb-6 space-y-4\"\n >\n <template v-if=\"getMemberLists().length > 0\">\n <div class=\"propeller-add-to-favorite__member-lists space-y-2\">\n <template\n :key=\"list.id\"\n v-for=\"(list, index) in getMemberLists()\"\n >\n <button\n type=\"button\"\n class=\"propeller-add-to-favorite__member-list-item flex items-center gap-2 py-2 w-full text-left hover:bg-surface-hover rounded-[var(--radius-control)] px-1 transition-colors disabled:opacity-50\"\n @click=\"\n async (event) => handleRemoveFromList(String(list.id))\n \"\n :disabled=\"removeLoading\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"text-primary flex-shrink-0\"\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"></rect>\n <path d=\"m9 12 2 2 4-4\"></path></svg\n ><span class=\"text-sm font-medium\">{{ list.name }}</span>\n </button> </template\n ><button\n type=\"button\"\n class=\"propeller-add-to-favorite__submit-btn w-full py-2.5 px-4 text-sm font-medium text-primary-foreground bg-primary hover:bg-primary/80 rounded-[var(--radius-control)] transition-colors disabled:opacity-50\"\n @click=\"\n async (event) => {\n const memberLists = getMemberLists();\n if (memberLists.length > 0) {\n handleRemoveFromList(String(memberLists[0].id));\n }\n }\n \"\n :disabled=\"removeLoading\"\n >\n <template v-if=\"removeLoading\">\n {{ getLabel(\"removing\", \"Removing...\") }}\n </template>\n\n <template v-else>\n {{\n getLabel(\"removeFromFavorites\", \"Remove from favorites\")\n }}\n </template>\n </button>\n </div>\n <div\n class=\"propeller-add-to-favorite__divider border-t border-border\"\n ></div>\n </template>\n\n <template v-if=\"getNonMemberLists().length > 0\">\n <div class=\"propeller-add-to-favorite__add-form space-y-3\">\n <div class=\"space-y-1\">\n <label\n class=\"propeller-add-to-favorite__select-label text-xs text-muted-foreground\"\n >{{\n getLabel(\"chooseList\", \"Choose a favorites list*\")\n }}</label\n ><select\n class=\"propeller-add-to-favorite__select block w-full rounded-[var(--radius-control)] border border-input px-3 py-2.5 text-sm focus:border-primary focus:ring-primary\"\n :value=\"selectedListId\"\n @change=\"\n async (e) => {\n selectedListId = (e.target as HTMLInputElement).value;\n }\n \"\n >\n <template\n :key=\"list.id\"\n v-for=\"(list, index) in getNonMemberLists()\"\n >\n <option :value=\"String(list.id)\">\n {{ list.name }}\n </option>\n </template>\n </select>\n </div>\n <button\n type=\"button\"\n class=\"propeller-add-to-favorite__submit-btn w-full py-2.5 px-4 text-sm font-medium text-primary-foreground bg-primary hover:bg-primary/80 rounded-[var(--radius-control)] transition-colors disabled:opacity-50\"\n @click=\"async (event) => handleAddToList()\"\n :disabled=\"!selectedListId || addLoading\"\n >\n <template v-if=\"addLoading\">\n {{ getLabel(\"adding\", \"Adding...\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"addToFavorites\", \"Add to favorites\") }}\n </template>\n </button>\n </div>\n </template>\n\n <template\n v-if=\"\n getMemberLists().length === 0 &&\n getNonMemberLists().length === 0\n \"\n >\n <div\n class=\"propeller-add-to-favorite__empty py-4 text-center text-muted-foreground text-sm\"\n >\n {{\n getLabel(\n \"noLists\",\n \"You have no favorite lists. Create one in your account first.\",\n )\n }}\n </div>\n </template>\n </div>\n </div>\n </div>\n </template>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from \"vue\";\n\nimport {\n FavoriteList,\n GraphQLClient,\n Contact,\n Customer,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useFavorites } from \"../composables/vue/useFavorites\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface AddToFavoriteProps {\n /** The initialized GraphQL Client instance */\n graphqlClient: GraphQLClient;\n\n /** The authenticated user */\n user: Contact | Customer | null;\n\n /** Product ID to add/remove from favorites (for products) */\n productId?: number;\n\n /** Cluster ID to add/remove from favorites (for clusters) */\n clusterId?: number;\n\n /** Extra CSS class applied to the root button */\n className?: string;\n\n /** UI string overrides */\n labels?: Record<string, string>;\n\n /** Called after a favorite list mutation (add/remove) succeeds */\n onFavoriteChanged?: () => void;\n}\ninterface AddToFavoriteState {\n /** IDs of lists that contain this product/cluster (optimistic local tracking) */\n memberListIds: Set<string>;\n showModal: boolean;\n selectedListId: string;\n addLoading: boolean;\n removeLoading: boolean;\n _isMounted: boolean;\n isFavorited: boolean;\n isProduct: boolean;\n itemId: number;\n toggleModal: () => void;\n closeModal: () => void;\n handleAddToList: () => Promise<void>;\n handleRemoveFromList: (listId: string) => Promise<void>;\n getLabel: (key: string, fallback: string) => string;\n getMemberLists: () => FavoriteList[];\n getNonMemberLists: () => FavoriteList[];\n}\n\nconst props = defineProps<AddToFavoriteProps>();\nconst infra = useInfraProps(props);\n// Template binds `user` bare (v-if=\"user\"). Expose the resolved value so\n// omitting the prop still lets the provider supply it.\nconst user = computed(() => infra.user);\n\nconst userRef = computed(() => infra.user ?? null);\n\nconst { addToList, removeFromList } = useFavorites({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n});\n\nconst memberListIds = ref<AddToFavoriteState[\"memberListIds\"]>(\n new Set<string>(),\n);\nconst showModal = ref<AddToFavoriteState[\"showModal\"]>(false);\nconst selectedListId = ref<AddToFavoriteState[\"selectedListId\"]>(\"\");\nconst addLoading = ref<AddToFavoriteState[\"addLoading\"]>(false);\nconst removeLoading = ref<AddToFavoriteState[\"removeLoading\"]>(false);\nconst _isMounted = ref<AddToFavoriteState[\"_isMounted\"]>(false);\n\nonMounted(() => {\n _isMounted.value = true;\n});\n\nconst isFavorited = computed(() => {\n return memberListIds.value.size > 0;\n});\nconst isProduct = computed(() => {\n return !!props.productId;\n});\nconst itemId = computed(() => {\n return (props.productId || props.clusterId || 0) as number;\n});\n\nwatch(\n () => [infra.user, props.productId, props.clusterId],\n () => {\n if (!infra.user || !itemId.value) return;\n const currentItemId = itemId.value;\n const currentIsProduct = isProduct.value;\n const userLists = (infra.user as any)?.favoriteLists?.items as\n | FavoriteList[]\n | undefined;\n const memberIds = new Set<string>();\n (userLists || []).forEach((list: FavoriteList) => {\n const productsRef = list?.products as\n | {\n items?: {\n productId?: number;\n clusterId?: number;\n }[];\n }\n | undefined;\n const clustersRef = list?.clusters as\n | {\n items?: {\n clusterId?: number;\n }[];\n }\n | undefined;\n if (currentIsProduct) {\n if (productsRef?.items?.some((item) => item.productId === currentItemId)) {\n memberIds.add(String(list.id));\n }\n } else {\n const inProducts = productsRef?.items?.some(\n (item) => item.clusterId === currentItemId,\n );\n const inClusters = clustersRef?.items?.some(\n (item) => item.clusterId === currentItemId,\n );\n if (inProducts || inClusters) {\n memberIds.add(String(list.id));\n }\n }\n });\n memberListIds.value = memberIds;\n },\n { immediate: true },\n);\nfunction toggleModal(): ReturnType<AddToFavoriteState[\"toggleModal\"]> {\n if (!infra.user) return;\n if (!showModal.value) {\n const nonMember = getNonMemberLists();\n if (nonMember.length > 0 && !selectedListId.value) {\n selectedListId.value = String(nonMember[0].id);\n }\n }\n showModal.value = !showModal.value;\n}\nfunction closeModal(): ReturnType<AddToFavoriteState[\"closeModal\"]> {\n showModal.value = false;\n}\nasync function handleAddToList(): ReturnType<\n AddToFavoriteState[\"handleAddToList\"]\n> {\n if (!selectedListId.value || addLoading.value) return;\n addLoading.value = true;\n try {\n const pid = isProduct.value ? (itemId.value as number) : undefined;\n const cid = !isProduct.value ? (itemId.value as number) : undefined;\n await addToList(selectedListId.value, pid, cid);\n const newMemberIds = new Set(memberListIds.value);\n newMemberIds.add(String(selectedListId.value));\n memberListIds.value = newMemberIds;\n selectedListId.value = \"\";\n showModal.value = false;\n if (props.onFavoriteChanged) props.onFavoriteChanged();\n } catch (error) {\n console.error(\"Error adding to favorite list:\", error);\n } finally {\n addLoading.value = false;\n }\n}\nasync function handleRemoveFromList(\n listId: string,\n): ReturnType<AddToFavoriteState[\"handleRemoveFromList\"]> {\n if (removeLoading.value) return;\n removeLoading.value = true;\n try {\n const pid = isProduct.value ? (itemId.value as number) : undefined;\n const cid = !isProduct.value ? (itemId.value as number) : undefined;\n await removeFromList(listId, pid, cid);\n const newMemberIds = new Set(memberListIds.value);\n newMemberIds.delete(String(listId));\n memberListIds.value = newMemberIds;\n selectedListId.value = \"\";\n showModal.value = false;\n if (props.onFavoriteChanged) props.onFavoriteChanged();\n } catch (error) {\n console.error(\"Error removing from favorite list:\", error);\n } finally {\n removeLoading.value = false;\n }\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<AddToFavoriteState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getMemberLists(): ReturnType<AddToFavoriteState[\"getMemberLists\"]> {\n const userLists = (infra.user as any)?.favoriteLists?.items as\n | FavoriteList[]\n | undefined;\n return (userLists || []).filter((list: FavoriteList) =>\n memberListIds.value.has(String(list.id)),\n );\n}\nfunction getNonMemberLists(): ReturnType<\n AddToFavoriteState[\"getNonMemberLists\"]\n> {\n const userLists = (infra.user as any)?.favoriteLists?.items as\n | FavoriteList[]\n | undefined;\n return (userLists || []).filter(\n (list: FavoriteList) => !memberListIds.value.has(String(list.id)),\n );\n}\n</script>\n","<template>\n <div class=\"propeller-address-card\">\n <template v-if=\"showCard\">\n <div\n class=\"propeller-address-card__card bg-card p-4 rounded-[var(--radius-container)] shadow-sm border border-border h-full flex flex-col\"\n :data-default=\"addr?.isDefault === 'Y' ? 'true' : 'false'\"\n :data-type=\"addr?.type || ''\"\n >\n <div class=\"propeller-address-card__body flex-grow\">\n <slot\n v-if=\"addressType\"\n name=\"typeBadge\"\n :address=\"addr\"\n :addressType=\"addressType\"\n :addressTypeLabel=\"getLabel('addressType:' + addressType, addressType)\"\n >\n <span\n class=\"propeller-address-card__type-badge inline-block rounded bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground mb-2\"\n >\n {{ getLabel('addressType:' + addressType, addressType) }}\n </span>\n </slot>\n\n <template v-if=\"showCompanyName !== false && addr?.company\">\n <div class=\"propeller-address-card__company font-bold text-lg mb-1\">\n {{ addr?.company }}\n </div>\n </template>\n\n <slot\n v-if=\"showFullName !== false && (addr?.firstName || addr?.lastName)\"\n name=\"name\"\n :address=\"addr\"\n :fullName=\"[\n props.showSalutation !== false\n ? addr?.gender === 'M'\n ? 'Mr.'\n : addr?.gender === 'F'\n ? 'Mrs.'\n : null\n : null,\n addr?.firstName,\n addr?.middleName,\n addr?.lastName,\n ].filter(Boolean).join(' ')\"\n :salutation=\"addr?.gender\"\n >\n <div class=\"propeller-address-card__name font-medium mb-1\">\n {{\n [\n props.showSalutation !== false\n ? addr?.gender === \"M\"\n ? \"Mr.\"\n : addr?.gender === \"F\"\n ? \"Mrs.\"\n : null\n : null,\n addr?.firstName,\n addr?.middleName,\n addr?.lastName,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </div>\n </slot>\n\n <slot\n name=\"addressLines\"\n :address=\"addr\"\n :streetLine=\"[\n addr?.street,\n showNumberExtension !== false ? addr?.number : null,\n showNumberExtension !== false ? addr?.numberExtension : null,\n ].filter(Boolean).join(' ')\"\n :cityLine=\"[\n showPostalCode !== false ? addr?.postalCode : null,\n showCity !== false ? addr?.city : null,\n ].filter(Boolean).join(' ')\"\n >\n <template v-if=\"showStreet !== false && addr?.street\">\n <div class=\"propeller-address-card__street text-muted-foreground\">\n {{\n [\n addr?.street,\n showNumberExtension !== false ? addr?.number : null,\n showNumberExtension !== false ? addr?.numberExtension : null,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </div>\n </template>\n\n <template\n v-if=\"\n (showPostalCode !== false && addr?.postalCode) ||\n (showCity !== false && addr?.city)\n \"\n >\n <div class=\"propeller-address-card__city text-muted-foreground\">\n {{\n [\n showPostalCode !== false ? addr?.postalCode : null,\n showCity !== false ? addr?.city : null,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </div>\n </template>\n </slot>\n\n <slot\n v-if=\"showCountry !== false && addr?.country\"\n name=\"country\"\n :address=\"addr\"\n :countryName=\"getCountryName(addr?.country)\"\n >\n <div class=\"propeller-address-card__country text-muted-foreground\">\n {{ getCountryName(addr?.country) }}\n </div>\n </slot>\n\n <template v-if=\"!!showEmail && addr?.email\">\n <div class=\"propeller-address-card__email text-muted-foreground\">\n {{ addr?.email }}\n </div>\n </template>\n\n <template v-if=\"!!showPhone && addr?.phone\">\n <div class=\"propeller-address-card__phone text-muted-foreground\">\n {{ addr?.phone }}\n </div>\n </template>\n\n <slot\n v-if=\"showDefaultBadge === true && addr?.isDefault === 'Y'\"\n name=\"defaultBadge\"\n :address=\"addr\"\n :isDefault=\"true\"\n :addressType=\"addr?.type\"\n >\n <div class=\"mt-2\">\n <span\n class=\"propeller-address-card__default-badge bg-secondary/10 text-secondary text-xs px-2 py-1 rounded-full\"\n >\n Default {{ addr?.type }} Address\n </span>\n </div>\n </slot>\n </div>\n <slot\n v-if=\"enableActions !== false\"\n name=\"actions\"\n :address=\"addr\"\n :onEdit=\"openEditModal\"\n :onDelete=\"() => { showDeleteConfirm = true; }\"\n :onSetDefault=\"handleSetDefault\"\n :saving=\"saving\"\n >\n <div\n class=\"propeller-address-card__actions mt-4 pt-4 border-t border-border-subtle flex flex-wrap gap-2\"\n >\n <template v-if=\"enableEdit !== false\">\n <button\n class=\"propeller-address-card__edit-btn text-primary hover:text-primary/80 text-sm font-medium\"\n @click=\"async (event) => openEditModal()\"\n >\n {{ getLabel(\"edit\", \"Edit\") }}\n </button>\n </template>\n\n <template v-if=\"enableDelete !== false\">\n <button\n class=\"propeller-address-card__delete-btn text-muted-foreground hover:text-foreground text-sm font-medium\"\n @click=\"\n async (event) => {\n showDeleteConfirm = true;\n }\n \"\n >\n {{ getLabel(\"delete\", \"Delete\") }}\n </button>\n </template>\n\n <template\n v-if=\"enableSetDefault !== false && addr?.isDefault !== 'Y'\"\n >\n <button\n class=\"propeller-address-card__default-btn text-primary hover:text-primary/80 text-sm font-medium ml-auto\"\n @click=\"async (event) => handleSetDefault()\"\n >\n {{ getLabel(\"setDefault\", \"Set Default\") }}\n </button>\n </template>\n </div>\n </slot>\n </div>\n </template>\n\n <template v-if=\"inline && showEditModal\">\n <div\n class=\"propeller-address-card__form bg-card p-6 rounded-[var(--radius-container)] border\"\n >\n <form @submit=\"async (e) => handleSaveEdit(e)\">\n <template v-if=\"!!formTitle\">\n <h3 class=\"text-xl font-bold mb-4\">{{ formTitle }}</h3>\n </template>\n\n <div class=\"space-y-4\">\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"gender\", \"Gender\")\n }}</label\n ><select\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input bg-card\"\n :value=\"editGender\"\n @change=\"\n async (e) => {\n editGender = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value as Gender;\n }\n \"\n >\n <option value=\"M\">\n {{ getLabel(\"genderMale\", \"Male\") }}\n </option>\n <option value=\"F\">\n {{ getLabel(\"genderFemale\", \"Female\") }}\n </option>\n <option value=\"U\">\n {{ getLabel(\"genderOther\", \"Other\") }}\n </option>\n </select>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"company\", \"Company\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editCompany\"\n @change=\"\n async (e) => {\n editCompany = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-3 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"firstName\", \"First Name\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editFirstName\"\n @change=\"\n async (e) => {\n editFirstName = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"middleName\", \"Middle Name\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editMiddleName\"\n @change=\"\n async (e) => {\n editMiddleName = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"lastName\", \"Last Name\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editLastName\"\n @change=\"\n async (e) => {\n editLastName = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-12 gap-4\">\n <div class=\"col-span-8\">\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"street\", \"Street\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editStreet\"\n @change=\"\n async (e) => {\n editStreet = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div class=\"col-span-2\">\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"number\", \"Number\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editNumber\"\n @change=\"\n async (e) => {\n editNumber = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div class=\"col-span-2\">\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"numberExtension\", \"Ext\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editNumberExtension\"\n @change=\"\n async (e) => {\n editNumberExtension = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"postalCode\", \"Postal Code\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editPostalCode\"\n @change=\"\n async (e) => {\n editPostalCode = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"city\", \"City\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editCity\"\n @change=\"\n async (e) => {\n editCity = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"country\", \"Country\") }} *</label\n ><select\n class=\"w-full h-10 px-3 rounded-[var(--radius-control)] border border-input bg-card\"\n :value=\"editCountry\"\n @change=\"\n async (e) => {\n editCountry = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n >\n <option value=\"\">\n {{ getLabel(\"selectCountry\", \"Select country\") }}\n </option>\n <template :key=\"c.code\" v-for=\"(c, index) in countries || []\">\n <option :value=\"c.code\">{{ c.name }}</option>\n </template>\n </select>\n </div>\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"email\", \"Email\") }} *</label\n ><input\n type=\"email\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editEmail\"\n @change=\"\n async (e) => {\n editEmail = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"phone\", \"Phone\")\n }}</label\n ><input\n type=\"tel\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editPhone\"\n @change=\"\n async (e) => {\n editPhone = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n </div>\n <template v-if=\"!!showIcp\">\n <div class=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"icp-inline\"\n class=\"propeller-address-card__checkbox h-4 w-4 rounded border-input text-primary focus:ring-primary\"\n :checked=\"editIcp === YesNo.Y\"\n @change=\"\n async (e) => {\n editIcp = (e.target as HTMLInputElement).checked\n ? YesNo.Y\n : YesNo.N;\n }\n \"\n /><label for=\"icp-inline\" class=\"text-sm font-medium\">{{\n getLabel(\"icp\", \"ICP/ICS (Intra-Community Supply)\")\n }}</label>\n </div>\n </template>\n </div>\n <div class=\"flex justify-end gap-3 pt-4 mt-4 border-t\">\n <template v-if=\"!isNew\">\n <button\n type=\"button\"\n class=\"propeller-address-card__cancel-btn px-4 py-2 border rounded hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => closeEditModal()\"\n :disabled=\"saving\"\n >\n {{ getLabel(\"cancel\", \"Cancel\") }}\n </button>\n </template>\n\n <template v-if=\"isNew && !!onCancel\">\n <button\n type=\"button\"\n class=\"propeller-address-card__cancel-btn px-4 py-2 border rounded hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => closeEditModal()\"\n :disabled=\"saving\"\n >\n {{ getLabel(\"cancel\", \"Cancel\") }}\n </button>\n </template>\n\n <button\n type=\"submit\"\n class=\"propeller-address-card__submit-btn px-4 py-2 bg-primary text-primary-foreground rounded hover:bg-primary/90 disabled:opacity-50\"\n :disabled=\"saving\"\n >\n <template v-if=\"saving\">\n {{ getLabel(\"saving\", \"Saving...\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"save\", \"Save\") }}\n </template>\n </button>\n </div>\n </form>\n </div>\n </template>\n\n <template v-if=\"!inline && showEditModal\">\n <div\n class=\"propeller-address-card__modal fixed inset-0 bg-black/50 flex items-center justify-center z-50 overflow-y-auto py-10\"\n >\n <div\n class=\"propeller-address-card__modal-content bg-card p-6 rounded-[var(--radius-container)] max-w-2xl w-full mx-4 shadow-xl\"\n >\n <form @submit=\"async (e) => handleSaveEdit(e)\">\n <div class=\"flex justify-between items-center mb-4\">\n <h3 class=\"text-xl font-bold\">{{ formTitle }}</h3>\n <button\n type=\"button\"\n class=\"propeller-address-card__modal-close text-muted-foreground hover:text-muted-foreground text-xl leading-none\"\n @click=\"async (event) => closeEditModal()\"\n >\n &times;\n </button>\n </div>\n <div class=\"space-y-4\">\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"gender\", \"Gender\")\n }}</label\n ><select\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input bg-card\"\n :value=\"editGender\"\n @change=\"\n async (e) => {\n editGender = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value as Gender;\n }\n \"\n >\n <option value=\"M\">\n {{ getLabel(\"genderMale\", \"Male\") }}\n </option>\n <option value=\"F\">\n {{ getLabel(\"genderFemale\", \"Female\") }}\n </option>\n <option value=\"U\">\n {{ getLabel(\"genderOther\", \"Other\") }}\n </option>\n </select>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"company\", \"Company\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editCompany\"\n @change=\"\n async (e) => {\n editCompany = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-3 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"firstName\", \"First Name\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editFirstName\"\n @change=\"\n async (e) => {\n editFirstName = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"middleName\", \"Middle Name\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editMiddleName\"\n @change=\"\n async (e) => {\n editMiddleName = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"lastName\", \"Last Name\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editLastName\"\n @change=\"\n async (e) => {\n editLastName = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-12 gap-4\">\n <div class=\"col-span-8\">\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"street\", \"Street\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editStreet\"\n @change=\"\n async (e) => {\n editStreet = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div class=\"col-span-2\">\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"number\", \"Number\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editNumber\"\n @change=\"\n async (e) => {\n editNumber = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div class=\"col-span-2\">\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"numberExtension\", \"Ext\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editNumberExtension\"\n @change=\"\n async (e) => {\n editNumberExtension = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"postalCode\", \"Postal Code\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editPostalCode\"\n @change=\"\n async (e) => {\n editPostalCode = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"city\", \"City\") }} *</label\n ><input\n type=\"text\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editCity\"\n @change=\"\n async (e) => {\n editCity = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"country\", \"Country\") }} *</label\n ><select\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input bg-card\"\n :value=\"editCountry\"\n @change=\"\n async (e) => {\n editCountry = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n >\n <option value=\"\">\n {{ getLabel(\"selectCountry\", \"Select country\") }}\n </option>\n <template :key=\"c.code\" v-for=\"(c, index) in countries || []\">\n <option :value=\"c.code\">{{ c.name }}</option>\n </template>\n </select>\n </div>\n <div class=\"grid grid-cols-2 gap-4\">\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"email\", \"Email\") }} *</label\n ><input\n type=\"email\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editEmail\"\n @change=\"\n async (e) => {\n editEmail = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n :required=\"true\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"phone\", \"Phone\")\n }}</label\n ><input\n type=\"tel\"\n class=\"propeller-address-card__input w-full h-10 px-3 rounded-[var(--radius-control)] border border-input\"\n :value=\"editPhone\"\n @change=\"\n async (e) => {\n editPhone = (\n e.target as HTMLInputElement | HTMLSelectElement\n ).value;\n }\n \"\n />\n </div>\n </div>\n <template v-if=\"!!showIcp\">\n <div class=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"icp-modal\"\n class=\"propeller-address-card__checkbox h-4 w-4 rounded border-input text-primary focus:ring-primary\"\n :checked=\"editIcp === YesNo.Y\"\n @change=\"\n async (e) => {\n editIcp = (e.target as HTMLInputElement).checked\n ? YesNo.Y\n : YesNo.N;\n }\n \"\n /><label for=\"icp-modal\" class=\"text-sm font-medium\">{{\n getLabel(\"icp\", \"ICP/ICS (Intra-Community Supply)\")\n }}</label>\n </div>\n </template>\n </div>\n <div class=\"flex justify-end gap-3 pt-4 mt-4 border-t\">\n <button\n type=\"button\"\n class=\"propeller-address-card__cancel-btn px-4 py-2 border rounded hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => closeEditModal()\"\n :disabled=\"saving\"\n >\n {{ getLabel(\"cancel\", \"Cancel\") }}</button\n ><button\n type=\"submit\"\n class=\"propeller-address-card__submit-btn px-4 py-2 bg-primary text-primary-foreground rounded hover:bg-primary/90 disabled:opacity-50\"\n :disabled=\"saving\"\n >\n <template v-if=\"saving\">\n {{ getLabel(\"saving\", \"Saving...\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"save\", \"Save\") }}\n </template>\n </button>\n </div>\n </form>\n </div>\n </div>\n </template>\n\n <template v-if=\"showDeleteConfirm\">\n <div\n class=\"propeller-address-card__delete-modal fixed inset-0 bg-black/50 flex items-center justify-center z-50\"\n >\n <div\n class=\"propeller-address-card__delete-modal-content bg-card p-6 rounded-[var(--radius-container)] max-w-sm w-full mx-4\"\n >\n <h3 class=\"text-xl font-bold mb-4\">\n {{ getLabel(\"confirmDeleteTitle\", \"Confirm Delete\") }}\n </h3>\n <p\n class=\"propeller-address-card__delete-message mb-6 text-muted-foreground\"\n >\n {{\n getLabel(\n \"confirmDeleteMessage\",\n \"Are you sure you want to delete this address?\",\n )\n }}\n </p>\n <div class=\"flex justify-end gap-4\">\n <button\n class=\"propeller-address-card__cancel-btn px-4 py-2 border rounded hover:bg-surface-hover\"\n @click=\"\n async (event) => {\n showDeleteConfirm = false;\n }\n \"\n >\n {{ getLabel(\"cancel\", \"Cancel\") }}</button\n ><button\n class=\"propeller-address-card__confirm-btn px-4 py-2 bg-primary text-primary-foreground rounded hover:bg-primary/80\"\n @click=\"async (event) => confirmDelete()\"\n >\n {{ getLabel(\"delete\", \"Delete\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from \"vue\";\n\nimport { Address, CartAddress, Gender, GraphQLClient, OrderAddress, WarehouseAddress, YesNo } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getCountryName as _getCountryName } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface AddressCardProps {\n /** GraphQL client for the Propeller SDK (only needed when editing) */\n graphqlClient?: GraphQLClient;\n\n /** The address to display (Address | CartAddress | WarehouseAddress | OrderAddress) */\n address: Address | CartAddress | WarehouseAddress | OrderAddress | null;\n\n /** Display company name @default true */\n showCompanyName?: boolean;\n\n /** Display salutation (Mr./Mrs.) @default true */\n showSalutation?: boolean;\n\n /** Display full name @default true */\n showFullName?: boolean;\n\n /** Display street @default true */\n showStreet?: boolean;\n\n /** Display house number and extension @default true */\n showNumberExtension?: boolean;\n\n /** Display postal code @default true */\n showPostalCode?: boolean;\n\n /** Display city @default true */\n showCity?: boolean;\n\n /** Display country name @default true */\n showCountry?: boolean;\n\n /** Display email @default false */\n showEmail?: boolean;\n\n /** Display phone @default false */\n showPhone?: boolean;\n\n /** Display action buttons (edit, delete, set default) @default true */\n enableActions?: boolean;\n\n /** Display Edit button @default true */\n enableEdit?: boolean;\n\n /** Display Delete button @default true */\n enableDelete?: boolean;\n\n /** Display Set Default button @default true */\n enableSetDefault?: boolean;\n\n /** Display the \"Default ... Address\" badge @default false */\n showDefaultBadge?: boolean;\n\n /** Called when address is edited; receives the updated address object */\n onEdit?: (address: Address) => void | Promise<void>;\n\n /** Called after address edit completes */\n afterEdit?: (address: Address) => void | Promise<void>;\n\n /** Called when address is deleted; receives the address ID */\n onDelete?: (addressId: Address) => void;\n\n /** Called after address deletion completes */\n afterDelete?: (addressId: Address) => void;\n\n /** Called when address is set as default */\n onSetDefault?: (address: Address) => void;\n\n /** Called after address is set as default */\n afterSetDefault?: (address: Address) => void;\n\n /** List of countries for the country dropdown [{code: 'NL', name: 'Netherlands'}, ...] */\n countries?: {\n code: string;\n name: string;\n }[];\n\n /** When true, renders in \"new address\" mode: auto-opens the edit form, hides the card body */\n isNew?: boolean;\n\n /** Called when the form is cancelled in new mode */\n onCancel?: () => void;\n\n /** When true, renders the form inline instead of in a modal overlay. @default false */\n inline?: boolean;\n\n /** Address type for new addresses (e.g., 'DELIVERY', 'INVOICE'). Used when creating, not editing. */\n addressType?: string;\n\n /** Show ICP/ICS (intra-community supply) checkbox. @default false */\n showIcp?: boolean;\n\n /** Title for the form or section */\n title?: string;\n\n /** Labels for form fields and buttons */\n labels?: Record<string, string>;\n\n /** Called before save starts */\n beforeSave?: () => void;\n}\ninterface AddressCardState {\n showEditModal: boolean;\n showDeleteConfirm: boolean;\n localAddress: any;\n editCompany: string;\n editGender: Gender;\n editFirstName: string;\n editMiddleName: string;\n editLastName: string;\n editStreet: string;\n editNumber: string;\n editNumberExtension: string;\n editPostalCode: string;\n editCity: string;\n editCountry: string;\n editEmail: string;\n editPhone: string;\n editNotes: string;\n editIcp: YesNo;\n saving: boolean;\n getLabel: (key: string, fallback: string) => string;\n getCountryName: (code: string) => string;\n addr: any;\n showCard: boolean;\n formTitle: string;\n openEditModal: () => void;\n handleSaveEdit: (e: any) => Promise<void>;\n confirmDelete: () => void;\n handleSetDefault: () => void;\n closeEditModal: () => void;\n}\n\nconst props = withDefaults(defineProps<AddressCardProps>(), {\n showCompanyName: true,\n showSalutation: true,\n showFullName: true,\n showStreet: true,\n showNumberExtension: true,\n showPostalCode: true,\n showCity: true,\n showCountry: true,\n showEmail: false,\n showPhone: false,\n enableActions: true,\n enableEdit: true,\n enableDelete: true,\n enableSetDefault: true,\n showDefaultBadge: false,\n isNew: false,\n inline: false,\n showIcp: false,\n});\nconst showEditModal = ref<AddressCardState[\"showEditModal\"]>(false);\nconst showDeleteConfirm = ref<AddressCardState[\"showDeleteConfirm\"]>(false);\nconst saving = ref<AddressCardState[\"saving\"]>(false);\nconst localAddress = ref<AddressCardState[\"localAddress\"]>(null);\nconst editCompany = ref<AddressCardState[\"editCompany\"]>(\"\");\nconst editGender = ref<AddressCardState[\"editGender\"]>(Gender.U);\nconst editFirstName = ref<AddressCardState[\"editFirstName\"]>(\"\");\nconst editMiddleName = ref<AddressCardState[\"editMiddleName\"]>(\"\");\nconst editLastName = ref<AddressCardState[\"editLastName\"]>(\"\");\nconst editStreet = ref<AddressCardState[\"editStreet\"]>(\"\");\nconst editNumber = ref<AddressCardState[\"editNumber\"]>(\"\");\nconst editNumberExtension = ref<AddressCardState[\"editNumberExtension\"]>(\"\");\nconst editPostalCode = ref<AddressCardState[\"editPostalCode\"]>(\"\");\nconst editCity = ref<AddressCardState[\"editCity\"]>(\"\");\nconst editCountry = ref<AddressCardState[\"editCountry\"]>(\"\");\nconst editEmail = ref<AddressCardState[\"editEmail\"]>(\"\");\nconst editPhone = ref<AddressCardState[\"editPhone\"]>(\"\");\nconst editNotes = ref<AddressCardState[\"editNotes\"]>(\"\");\nconst editIcp = ref<AddressCardState[\"editIcp\"]>(YesNo.N);\n\nonMounted(() => {\n if (props.isNew || (props.inline && !props.address)) {\n openEditModal();\n }\n});\n\nconst addr = computed(() => {\n return localAddress.value || props.address;\n});\nconst showCard = computed(() => {\n if (props.isNew) return false;\n if (props.inline && !props.address) return false;\n return true;\n});\nconst formTitle = computed(() => {\n if (props.title) return props.title;\n if (props.isNew) return getLabel(\"newTitle\", \"New Address\");\n return getLabel(\"editTitle\", \"Edit Address\");\n});\n\nwatch(\n () => [props.address],\n () => {\n localAddress.value = null;\n },\n { immediate: true },\n);\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<AddressCardState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getCountryName(\n code: string,\n): ReturnType<AddressCardState[\"getCountryName\"]> {\n return _getCountryName(code, props.countries);\n}\nfunction openEditModal(): ReturnType<AddressCardState[\"openEditModal\"]> {\n const a = addr.value;\n editCompany.value = a?.company || \"\";\n editGender.value = a?.gender || \"M\";\n editFirstName.value = a?.firstName || \"\";\n editMiddleName.value = a?.middleName || \"\";\n editLastName.value = a?.lastName || \"\";\n editStreet.value = a?.street || \"\";\n editNumber.value = a?.number || \"\";\n editNumberExtension.value = a?.numberExtension || \"\";\n editPostalCode.value = a?.postalCode || \"\";\n editCity.value = a?.city || \"\";\n editCountry.value = a?.country || \"\";\n editEmail.value = a?.email || \"\";\n editPhone.value = a?.phone || \"\";\n editNotes.value = a?.notes || \"\";\n editIcp.value = a?.icp || YesNo.N;\n showEditModal.value = true;\n}\nasync function handleSaveEdit(\n e: any,\n): ReturnType<AddressCardState[\"handleSaveEdit\"]> {\n e.preventDefault();\n if (saving.value) return;\n saving.value = true;\n if (props.beforeSave) {\n props.beforeSave();\n }\n const editedAddress = {\n id: addr.value?.id,\n type: addr.value?.type || props.addressType || \"\",\n isDefault: addr.value?.isDefault,\n company: editCompany.value,\n gender: editGender.value,\n firstName: editFirstName.value,\n middleName: editMiddleName.value,\n lastName: editLastName.value,\n street: editStreet.value,\n number: editNumber.value,\n numberExtension: editNumberExtension.value,\n postalCode: editPostalCode.value,\n city: editCity.value,\n country: editCountry.value,\n email: editEmail.value,\n phone: editPhone.value,\n notes: editNotes.value,\n icp: editIcp.value as YesNo,\n } as unknown as Address;\n localAddress.value = editedAddress;\n try {\n if (props.onEdit) {\n await props.onEdit(editedAddress);\n }\n showEditModal.value = false;\n if (props.afterEdit) {\n await props.afterEdit(editedAddress);\n }\n } finally {\n saving.value = false;\n }\n}\nfunction confirmDelete(): ReturnType<AddressCardState[\"confirmDelete\"]> {\n const id = addr.value?.id;\n if (id != null) {\n if (props.onDelete) {\n props.onDelete(addr.value);\n }\n showDeleteConfirm.value = false;\n if (props.afterDelete) {\n props.afterDelete(addr.value);\n }\n } else {\n showDeleteConfirm.value = false;\n }\n}\nfunction handleSetDefault(): ReturnType<AddressCardState[\"handleSetDefault\"]> {\n if (props.onSetDefault) {\n props.onSetDefault(addr.value);\n }\n if (props.afterSetDefault) {\n props.afterSetDefault(addr.value);\n }\n}\nfunction closeEditModal(): ReturnType<AddressCardState[\"closeEditModal\"]> {\n showEditModal.value = false;\n if (props.isNew && props.onCancel) {\n props.onCancel();\n }\n}\n</script>\n","<template>\n <div :class=\"`propeller-address-selector ${className || ''}`\">\n <button\n type=\"button\"\n class=\"propeller-address-selector__trigger inline-flex items-center gap-2 px-4 py-2 border border-input rounded-[var(--radius-control)] text-sm font-medium text-muted-foreground bg-card hover:bg-surface-hover transition-colors\"\n @click=\"\n async (event) => {\n showModal = true;\n }\n \"\n >\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" class=\"w-4 h-4\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z\"\n :strokeWidth=\"2\"\n ></path>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M15 11a3 3 0 11-6 0 3 3 0 016 0z\"\n :strokeWidth=\"2\"\n ></path></svg\n >{{ getLabel('chooseAddress', 'Choose address') }}\n </button>\n <template v-if=\"showModal\">\n <div\n class=\"propeller-address-selector__modal fixed inset-0 bg-black/50 flex items-start justify-center z-50 overflow-y-auto py-10\"\n >\n <div class=\"propeller-address-selector__modal-content bg-card p-6 rounded-[var(--radius-container)] max-w-2xl w-full mx-4 shadow-xl\">\n <div class=\"propeller-address-selector__modal-header flex justify-between items-center mb-6\">\n <h3 class=\"propeller-address-selector__modal-title text-xl font-bold\">\n {{ getLabel('modalTitle', 'Choose an address') }}\n </h3>\n <button\n type=\"button\"\n class=\"propeller-address-selector__modal-close text-muted-foreground hover:text-muted-foreground text-xl leading-none\"\n @click=\"\n async (event) => {\n showModal = false;\n }\n \"\n >\n &times;\n </button>\n </div>\n <template v-if=\"getAddresses().length === 0\">\n <p class=\"propeller-address-selector__empty text-muted-foreground italic\">\n {{ getLabel('noAddresses', 'No addresses found.') }}\n </p>\n </template>\n\n <template v-if=\"getAddresses().length > 0\">\n <div class=\"propeller-address-selector__list grid grid-cols-2 gap-4\">\n <template :key=\"address.id\" v-for=\"(address, index) in getAddresses()\">\n <div\n @click=\"async (event) => handleTileClick(address)\"\n :data-selected=\"selectedAddress?.id === address.id ? 'true' : 'false'\"\n :class=\"`propeller-address-selector__option cursor-pointer rounded-[var(--radius-container)] transition-all ring-2 ${\n selectedAddress?.id === address.id\n ? 'ring-primary'\n : 'ring-transparent hover:ring-primary/40'\n }`\"\n >\n <component\n :is=\"AddressCardImpl\"\n :address=\"address\"\n :enableActions=\"false\"\n :countries=\"countries\"\n :showFullName=\"true\"\n :showStreet=\"true\"\n :showPostalCode=\"true\"\n :showCity=\"true\"\n :showCountry=\"true\"\n :showNumberExtension=\"true\"\n ></component>\n </div>\n </template>\n </div>\n <div class=\"propeller-address-selector__modal-actions flex justify-end mt-6 pt-4 border-t border-border-subtle\">\n <button\n type=\"button\"\n class=\"propeller-address-selector__confirm-btn inline-flex items-center gap-2 px-5 py-2.5 bg-primary text-primary-foreground rounded-[var(--radius-control)] text-sm font-medium hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n :disabled=\"!selectedAddress || isLoading\"\n @click=\"async (event) => handleConfirm()\"\n >\n <template v-if=\"isLoading\">\n <svg fill=\"none\" viewBox=\"0 0 24 24\" class=\"w-4 h-4 animate-spin\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n class=\"opacity-25\"\n ></circle>\n <path\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n class=\"opacity-75\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"isLoading\">\n {{ getLabel('updating', 'Updating...') }}\n </template>\n\n <template v-else>\n {{ getLabel('useThisAddress', 'Use this address') }}\n </template>\n </button>\n </div>\n </template>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, type Component } from 'vue';\n\nimport { Address, AddressType, Company, Contact, Customer } from '@propeller-commerce/propeller-sdk-v2';\nimport DefaultAddressCard from './AddressCard.vue';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface AddressSelectorProps {\n /** Authenticated user — addresses are derived from their profile. */\n user: Contact | Customer | null;\n\n /**\n * Active company ID (for Contact users).\n * Pass the value from the company switcher so the correct company's addresses are listed.\n */\n companyId?: number;\n\n /**\n * Filter addresses to this type.\n * Defaults to AddressType.delivery.\n */\n addressType?: string;\n\n /** Called when the user picks an address from the modal. Supports async. */\n onAddressSelected?: (address: Address) => void | Promise<void>;\n\n /** Country list forwarded to AddressCard [{code: 'NL', name: 'Netherlands'}, ...] */\n countries?: {\n code: string;\n name: string;\n }[];\n\n /** Label overrides. Keys: chooseAddress, modalTitle, noAddresses */\n labels?: Record<string, string>;\n\n /** Extra CSS class on the root element. */\n className?: string;\n\n // ───── Extension API ─────\n // Replaces each <AddressCard> rendered inside the selector list.\n addressCardComponent?: Component;\n}\ninterface AddressSelectorState {\n showModal: boolean;\n selectedAddress: Address | null;\n isLoading: boolean;\n getLabel: (key: string, fallback: string) => string;\n getActiveCompany: () => Company | null;\n getAddresses: () => Address[];\n handleTileClick: (address: Address) => void;\n handleConfirm: () => Promise<void>;\n}\n\nconst props = defineProps<AddressSelectorProps>();\nconst showModal = ref<AddressSelectorState['showModal']>(false);\nconst selectedAddress = ref<AddressSelectorState['selectedAddress']>(null);\nconst isLoading = ref<AddressSelectorState['isLoading']>(false);\nconst AddressCardImpl = computed(() => props.addressCardComponent ?? DefaultAddressCard);\n\nfunction getLabel(key: string, fallback: string): ReturnType<AddressSelectorState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getActiveCompany(): ReturnType<AddressSelectorState['getActiveCompany']> {\n const user = props.user as Contact | Customer | null;\n if (!user || !('contactId' in user)) return null;\n const contact = user as Contact;\n const cid = props.companyId as number;\n if (cid) {\n const companiesRaw = (contact as any).companies;\n const items = (companiesRaw?.items ?? companiesRaw) as Company[] | undefined;\n if (Array.isArray(items)) {\n for (let i = 0; i < items.length; i++) {\n if (items[i].companyId === cid) return items[i];\n }\n }\n if ((contact.company as Company)?.companyId === cid) return contact.company as Company;\n }\n return (contact.company as Company | undefined) ?? null;\n}\nfunction getAddresses(): ReturnType<AddressSelectorState['getAddresses']> {\n const user = props.user as Contact | Customer | null;\n if (!user) return [];\n const type = (props.addressType as string) || AddressType.delivery;\n let all: Address[] = [];\n if ('contactId' in user) {\n const company = getActiveCompany();\n all = ((company as any)?.addresses || []) as Address[];\n } else if ('customerId' in user) {\n all = ((user as Customer).addresses || []) as Address[];\n }\n return all.filter((a: Address) => a.type === type);\n}\nfunction handleTileClick(address: Address): ReturnType<AddressSelectorState['handleTileClick']> {\n selectedAddress.value = address;\n}\nasync function handleConfirm(): ReturnType<AddressSelectorState['handleConfirm']> {\n if (!selectedAddress.value || isLoading.value) return;\n isLoading.value = true;\n try {\n if (props.onAddressSelected) {\n await props.onAddressSelected(selectedAddress.value as Address);\n }\n showModal.value = false;\n selectedAddress.value = null as any;\n } finally {\n isLoading.value = false;\n }\n}\n</script>\n","<template>\n <!--\n Cart bonus items — free items added through incentives — as a read-only\n list (image, name, SKU, quantity, total price). No quantity stepper, delete\n or cross-sells: bonus items aren't directly editable. Renders nothing when\n empty, so it's safe to drop into any cart surface unconditionally.\n -->\n <div\n v-if=\"bonusItems.length > 0\"\n :class=\"`propeller-cart-bonus-items ${className || 'mt-2'}`\"\n >\n <h2 class=\"propeller-cart-bonus-items__title text-lg font-semibold mb-3\">\n {{ getLabel(\"title\", \"Bonus items\") }}\n </h2>\n <div class=\"propeller-cart-bonus-items__list space-y-4\">\n <div\n v-for=\"item in bonusItems\"\n :key=\"item.itemId\"\n class=\"propeller-cart-bonus-item flex items-center gap-4 bg-card p-4 rounded-[var(--radius-container)] shadow-sm border border-border\"\n >\n <div\n class=\"propeller-cart-bonus-item__media w-20 h-20 flex-shrink-0 bg-surface-hover rounded-[var(--radius-control)] overflow-hidden flex items-center justify-center\"\n >\n <img\n v-if=\"getItemImageUrl(item)\"\n class=\"propeller-cart-bonus-item__image w-full h-full object-contain p-1\"\n :src=\"getItemImageUrl(item)\"\n :alt=\"getItemName(item)\"\n />\n <svg\n v-else\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"propeller-cart-bonus-item__image-placeholder w-8 h-8 text-foreground-subtle\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z\"\n ></path>\n </svg>\n </div>\n <div class=\"propeller-cart-bonus-item__body flex-1 min-w-0\">\n <p\n v-if=\"item.product?.sku\"\n class=\"propeller-cart-bonus-item__sku font-mono text-xs text-foreground-subtle\"\n >\n {{ getLabel(\"sku\", \"SKU\") }}: {{ item.product.sku }}\n </p>\n <p\n class=\"propeller-cart-bonus-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2\"\n >\n {{ getItemName(item) }}\n </p>\n </div>\n <div\n class=\"propeller-cart-bonus-item__qty text-sm text-muted-foreground whitespace-nowrap\"\n >\n {{ item.quantity }} &times;\n </div>\n <div\n class=\"propeller-cart-bonus-item__price font-semibold text-foreground whitespace-nowrap\"\n >\n {{ getItemTotal(item) }}\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { Cart, CartBaseItem } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getLocalizedValue as _getLocalizedValue } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\n\nexport interface CartBonusItemsProps {\n /** Cart whose `bonusItems` (free items added via incentives) are displayed. */\n cart?: Cart | null;\n /** Pre-resolved bonus items. When omitted, `cart.bonusItems` is used. */\n bonusItems?: CartBaseItem[];\n /** When true, the tax-inclusive total (`totalPriceNet`) is shown. Resolved from the Propeller provider when omitted; defaults to false. */\n includeTax?: boolean;\n /** Currency symbol for prices. Resolved from the Propeller provider when omitted; defaults to '€'. */\n currency?: string;\n /** Active language for localized product names. Resolved from the Propeller provider when omitted. */\n language?: string;\n /** Additional CSS class for the root element. */\n className?: string;\n /** Label overrides. Keys: `title` ('Bonus items'), `sku` ('SKU'). */\n labels?: Record<string, string>;\n}\n\nconst props = withDefaults(defineProps<CartBonusItemsProps>(), {\n cart: null,\n});\n\n// Resolve currency / includeTax / language from the Propeller provider when\n// not passed explicitly (explicit props still win). Computed so it stays\n// reactive to provider changes (e.g. VAT toggle, language switch).\nconst infra = useInfraProps(props);\n\nconst bonusItems = computed<CartBaseItem[]>(\n () => props.bonusItems ?? props.cart?.bonusItems ?? [],\n);\n\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getItemName(item: CartBaseItem): string {\n return _getLocalizedValue(item.product?.names, infra.language as string, \"Product\");\n}\nfunction getItemImageUrl(item: CartBaseItem): string {\n return item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || \"\";\n}\nfunction getItemTotal(item: CartBaseItem): string {\n const total = infra.includeTax ? item.totalPriceNet : item.totalPrice;\n return _formatPrice(Number(total ?? 0), { symbol: infra.currency ?? \"€\" });\n}\n</script>\n","<template>\n <div :class=\"`propeller-cart-carriers ${containerClass}`\">\n <template v-if=\"carriers.length > 0\">\n <div\n class=\"propeller-cart-carriers__grid grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\"\n >\n <template\n :key=\"`${carrier.name}-${index}`\"\n v-for=\"(carrier, index) in carriers\"\n >\n <div\n @click=\"async (event) => handleSelect(carrier)\"\n :data-selected=\"selectedName === carrier.name ? 'true' : 'false'\"\n :class=\"`propeller-cart-carriers__carrier cursor-pointer border border-border rounded-[var(--radius-container)] p-4 flex flex-col gap-2 transition-all ${\n selectedName === carrier.name\n ? 'border-secondary bg-secondary/5 shadow-sm'\n : 'hover:border-secondary/30'\n }`\"\n >\n <div\n class=\"propeller-cart-carriers__carrier-row flex justify-between items-center\"\n >\n <div class=\"flex items-center gap-2\">\n <template v-if=\"showLogo && getLogoUrl(carrier)\">\n <img\n class=\"propeller-cart-carriers__carrier-logo h-6 w-auto\"\n :src=\"getLogoUrl(carrier)\"\n :alt=\"carrier.name\"\n />\n </template>\n\n <span\n class=\"propeller-cart-carriers__carrier-name font-medium\"\n >{{ carrier.name }}</span\n >\n </div>\n <template v-if=\"showPrice !== false\">\n <span\n class=\"propeller-cart-carriers__carrier-price text-xs bg-surface-hover text-muted-foreground px-2 py-1 rounded-full\"\n >{{ formatCarrierPrice(carrier.price) }}</span\n >\n </template>\n </div>\n <template v-if=\"carrier.deliveryDeadline\">\n <p\n class=\"propeller-cart-carriers__carrier-deadline text-xs text-muted-foreground\"\n >\n {{ getLabel(\"deliveryDeadline\", \"Delivery deadline:\")\n }}{{ carrier.deliveryDeadline }}\n </p>\n </template>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"carriers.length === 0\">\n <p class=\"propeller-cart-carriers__empty text-muted-foreground italic\">\n {{ getLabel(\"noCarriers\", \"No carriers available.\") }}\n </p>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\n\nimport { Cart, CartCarrier } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface CartCarriersProps {\n /** Shopping cart object from which the carriers will be displayed */\n cart: Cart;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** The CSS class for the carriers container */\n carriersContainerClass?: string;\n\n /** Display the carrier logo */\n showCarrierLogo?: boolean;\n\n /** Action when a carrier is selected */\n onCarrierSelect?: (carrier: CartCarrier) => void;\n\n /** Custom price formatting function */\n formatPrice?: (price: number) => string;\n\n /** Show carrier price (default: true) */\n showPrice?: boolean;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n}\ninterface CartCarriersState {\n selectedName: string;\n containerClass: string;\n showLogo: boolean;\n carriers: CartCarrier[];\n getLabel: (key: string, fallback: string) => string;\n formatCarrierPrice: (price: number) => string;\n getLogoUrl: (carrier: CartCarrier) => string;\n handleSelect: (carrier: CartCarrier) => void;\n}\n\nconst props = withDefaults(defineProps<CartCarriersProps>(), {\n showCarrierLogo: true,\n showPrice: true,\n});\nconst infra = useInfraProps(props);\nconst selectedName = ref<CartCarriersState[\"selectedName\"]>(\"\");\n\nconst containerClass = computed(() => {\n return props.carriersContainerClass || \"cart-carriers\";\n});\nconst showLogo = computed(() => {\n return props.showCarrierLogo !== undefined ? props.showCarrierLogo : true;\n});\nconst carriers = computed(() => {\n return props.cart?.carriers || [];\n});\n\nwatch(\n () => [props.cart],\n () => {\n if (!selectedName.value && props.cart?.postageData?.carrier) {\n selectedName.value = props.cart.postageData.carrier as string;\n if (props.onCarrierSelect) {\n const match = carriers.value.find(\n (c: CartCarrier) => c.name === selectedName.value,\n );\n if (match) props.onCarrierSelect(match);\n }\n }\n },\n { immediate: true },\n);\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<CartCarriersState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatCarrierPrice(\n price: number,\n): ReturnType<CartCarriersState[\"formatCarrierPrice\"]> {\n if (props.formatPrice) {\n return props.formatPrice(price);\n }\n return _formatPrice(price || 0, { symbol: infra.currency ?? \"€\" });\n}\nfunction getLogoUrl(\n carrier: CartCarrier,\n): ReturnType<CartCarriersState[\"getLogoUrl\"]> {\n return carrier.logo || \"\";\n}\nfunction handleSelect(\n carrier: CartCarrier,\n): ReturnType<CartCarriersState[\"handleSelect\"]> {\n selectedName.value = carrier.name;\n if (props.onCarrierSelect) {\n props.onCarrierSelect(carrier);\n }\n}\n</script>\n","<template>\n <ul v-if=\"surcharges.length > 0\" :class=\"className ?? 'text-xs text-foreground-subtle space-y-0.5'\">\n <li v-for=\"(s, idx) in surcharges\" :key=\"s?.id ?? idx\">\n {{ getLabelFor(s) }}: {{ formatSurcharge(s as never, includeTax as never) }}\n </li>\n </ul>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { formatSurcharge, getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport type { ProductSurchargesComponentProps } from '@propeller-commerce/propeller-v2-core-ui';\n\nconst props = defineProps<ProductSurchargesComponentProps>();\n\nconst surcharges = computed(() => {\n const src =\n (props.cartItem as { surcharges?: unknown[] } | undefined)?.surcharges ??\n (props.product as { surcharges?: unknown[] } | undefined)?.surcharges ??\n [];\n return src as Array<{\n id?: string | number;\n code?: string;\n name?: string;\n description?: string;\n }>;\n});\n\nconst includeTax = computed(() => props.includeTax);\nconst className = computed(() => props.className);\n\nfunction getLabelFor(s: { code?: string; name?: string; description?: string }): string {\n const labelKey = s?.code ?? 'surcharge';\n const fallback = s?.description ?? s?.name ?? 'Surcharge';\n return getLabel(props.labels, labelKey, fallback);\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-cart-item flex flex-wrap md:flex-nowrap items-center gap-4 ${cardFrame === false ? '' : 'bg-card p-4 rounded-[var(--radius-container)] shadow-sm border border-border'} ${\n className || ''\n }`\"\n :data-bundle=\"isBundleItem() ? 'true' : 'false'\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <slot\n name=\"image\"\n :cartItem=\"cartItem\"\n :imageUrl=\"getProductImageUrl()\"\n :productUrl=\"getProductUrl()\"\n :name=\"getProductName()\"\n >\n <div\n class=\"propeller-cart-item__media w-20 h-20 md:w-24 md:h-24 flex-shrink-0 bg-surface-hover flex items-center justify-center overflow-hidden relative\"\n >\n <template v-if=\"!!getProductImageUrl()\">\n <img\n class=\"propeller-cart-item__image w-full h-full object-contain p-1\"\n :src=\"getProductImageUrl()\"\n :alt=\"getProductName()\"\n />\n </template>\n\n <template v-if=\"!getProductImageUrl()\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"propeller-cart-item__image-placeholder w-8 h-8 text-foreground-subtle\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z\"\n ></path>\n </svg>\n </template>\n </div>\n </slot>\n <div class=\"propeller-cart-item__body flex-1 min-w-0\">\n <slot\n v-if=\"!isBundleItem() && showSku !== false && !!getProductSku()\"\n name=\"sku\"\n :cartItem=\"cartItem\"\n :sku=\"getProductSku()\"\n >\n <p\n class=\"propeller-cart-item__sku font-mono text-xs text-foreground-subtle\"\n >\n {{ getProductSku() }}\n </p>\n </slot>\n\n <slot\n name=\"title\"\n :cartItem=\"cartItem\"\n :isBundle=\"isBundleItem()\"\n :name=\"getProductName()\"\n :bundleName=\"getBundleName()\"\n :productUrl=\"getProductUrl()\"\n :linkable=\"titleLinkable\"\n :handleTitleClick=\"(e: any) => onTitleClick?.(e, cartItem)\"\n >\n <template v-if=\"isBundleItem()\">\n <span\n class=\"propeller-cart-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2\"\n >{{ getBundleName() }}</span\n >\n </template>\n\n <template v-if=\"!isBundleItem()\">\n <template v-if=\"titleLinkable !== false\">\n <a\n class=\"propeller-cart-item__title font-semibold text-sm md:text-base text-foreground hover:text-foreground transition-colors line-clamp-2\"\n :href=\"getProductUrl()\"\n @click=\"(e: MouseEvent) => onTitleClick?.(e, cartItem)\"\n >{{ getProductName() }}</a\n >\n </template>\n\n <template v-if=\"titleLinkable === false\">\n <span\n class=\"propeller-cart-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2\"\n >{{ getProductName() }}</span\n >\n </template>\n </template>\n </slot>\n\n <slot\n v-if=\"!isBundleItem()\"\n name=\"surcharges\"\n :cartItem=\"cartItem\"\n :surcharges=\"getSurcharges()\"\n :includeTax=\"includeTax\"\n :labels=\"labels\"\n >\n <component\n v-if=\"props.surchargesComponent\"\n :is=\"SurchargesImpl\"\n :cart-item=\"cartItem\"\n :include-tax=\"includeTax\"\n :labels=\"labels\"\n />\n <div\n v-else-if=\"getSurcharges().length > 0\"\n class=\"propeller-cart-item__surcharges mt-1 text-xs text-muted-foreground\"\n >\n <span class=\"font-medium\">{{ getLabel(\"surcharges\", \"Additional surcharges:\") }}</span>\n <ul class=\"propeller-cart-item__surcharges-list mt-0.5\">\n <li\n v-for=\"(line, idx) in getSurcharges()\"\n :key=\"idx\"\n class=\"propeller-cart-item__surcharge\"\n >\n {{ line }}\n </li>\n </ul>\n </div>\n </slot>\n\n <slot\n v-if=\"showStockComponent === true && !!getInventory()\"\n name=\"stock\"\n :cartItem=\"cartItem\"\n :inventory=\"getInventory()\"\n :labels=\"labels\"\n >\n <div class=\"mt-1\">\n <component\n :is=\"StockImpl\"\n :inventory=\"cartItem?.product?.inventory\"\n :show-stock=\"true\"\n :show-availability=\"true\"\n :labels=\"labels\"\n />\n </div>\n </slot>\n\n <slot\n v-if=\"isBundleItem()\"\n name=\"bundleItems\"\n :cartItem=\"cartItem\"\n :leaderName=\"getBundleLeaderName()\"\n :leaderPrice=\"getBundleLeaderPrice()\"\n :nonLeaders=\"getBundleNonLeaders()\"\n >\n <div\n class=\"propeller-cart-item__bundle mt-3 space-y-1.5 border-l-2 border-border pl-3\"\n >\n <template v-if=\"!!getBundleLeaderName()\">\n <div\n class=\"propeller-cart-item__bundle-leader flex flex-wrap gap-x-2 text-sm text-muted-foreground\"\n >\n <span class=\"font-semibold text-foreground\">{{\n getBundleLeaderName()\n }}</span>\n <template v-if=\"!!getBundleLeaderPrice()\">\n <div\n class=\"flex-1 border-b border-dotted border-input mx-1 mb-1\"\n ></div>\n <span class=\"font-semibold text-foreground\">{{\n getBundleLeaderPrice()\n }}</span>\n </template>\n </div>\n </template>\n\n <template\n :key=\"idx\"\n v-for=\"(bundleItem, idx) in getBundleNonLeaders()\"\n >\n <div\n class=\"propeller-cart-item__bundle-item flex flex-wrap gap-x-2 text-sm text-muted-foreground\"\n >\n <span class=\"font-medium\">{{\n getBundleItemName(bundleItem)\n }}</span>\n <template v-if=\"!!getBundleItemPrice(bundleItem)\">\n <div\n class=\"flex-1 border-b border-dotted border-input mx-1 mb-1\"\n ></div>\n <span class=\"font-semibold text-foreground\">{{\n getBundleItemPrice(bundleItem)\n }}</span>\n </template>\n </div>\n </template>\n </div>\n </slot>\n\n <slot\n v-if=\"\n !!cartItem.clusterId &&\n !!cartItem.childItems &&\n cartItem.childItems.length > 0\n \"\n name=\"childItems\"\n :cartItem=\"cartItem\"\n :childItems=\"cartItem.childItems\"\n >\n <div\n class=\"propeller-cart-item__options mt-3 space-y-1.5 border-l-2 border-border pl-3\"\n >\n <p\n class=\"propeller-cart-item__options-label text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1\"\n >\n {{ getLabel(\"includedOptions\", \"Included Options:\") }}\n </p>\n <template\n :key=\"idx\"\n v-for=\"(child, idx) in cartItem.childItems || []\"\n >\n <div\n class=\"propeller-cart-item__option flex flex-wrap gap-x-2 text-sm text-muted-foreground\"\n >\n <span class=\"font-medium\">{{\n child.product.names?.[0]?.value || \"Option\"\n }}</span\n ><span class=\"text-foreground-subtle hidden sm:inline\">-</span\n ><span class=\"text-foreground-subtle text-xs self-center\">{{\n child.product.sku\n }}</span>\n <div\n class=\"flex-1 border-b border-dotted border-input mx-1 mb-1\"\n ></div>\n <span class=\"font-semibold text-foreground\"\n >{{ getChildItemPrice(child) }}</span\n >\n </div>\n </template>\n </div>\n </slot>\n\n <slot\n v-if=\"showCartItemNotesField === true\"\n name=\"notes\"\n :cartItem=\"cartItem\"\n :notes=\"notes\"\n :onNoteChange=\"(value: any) => handleNoteChange(value)\"\n >\n <div class=\"propeller-cart-item__notes mt-3\">\n <label\n class=\"propeller-cart-item__notes-label text-xs font-medium text-muted-foreground block mb-1\"\n >{{ getLabel(\"notes\", \"Notes\") }}</label\n ><textarea\n class=\"propeller-cart-item__notes-input w-full text-sm border border-input rounded-[var(--radius-control)] px-3 py-2 focus:ring-2 focus:ring-secondary focus:border-transparent resize-none\"\n :value=\"notes\"\n @change=\"async (e) => handleNoteChange((e.target as HTMLInputElement).value)\"\n :placeholder=\"\n getLabel('notesPlaceholder', 'Add a note for this item...')\n \"\n :rows=\"2\"\n ></textarea>\n </div>\n </slot>\n\n <slot\n v-if=\"getVisibleCrossupsells().length > 0\"\n name=\"crossupsells\"\n :cartItem=\"cartItem\"\n :crossupsells=\"getVisibleCrossupsells()\"\n >\n <div\n class=\"propeller-cart-item__crossupsells mt-3 pt-3 border-t border-border\"\n >\n <p\n class=\"propeller-cart-item__crossupsells-label text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2\"\n >\n {{ getLabel(\"crossupsellTitle\", \"You might also like\") }}\n </p>\n <div class=\"flex flex-col gap-2\">\n <template\n :key=\"idx\"\n v-for=\"(item, idx) in getVisibleCrossupsells()\"\n >\n <div\n class=\"propeller-cart-item__crossupsell flex items-center gap-2 p-2 rounded-[var(--radius-control)] border border-border hover:border-input hover:bg-surface-hover transition-colors\"\n >\n <a\n class=\"propeller-cart-item__crossupsell-link flex items-center gap-2 flex-1 min-w-0\"\n :href=\"getCrossupsellUrl(item)\"\n @click=\"\n async (e) => {\n if (onCrossupsellClick) {\n e.preventDefault();\n onCrossupsellClick(\n (item.productTo || item.clusterTo) as Product | Cluster,\n );\n }\n }\n \"\n >\n <template v-if=\"!!getCrossupsellImageUrl(item)\">\n <img\n class=\"propeller-cart-item__crossupsell-image w-10 h-10 object-contain rounded flex-shrink-0\"\n :src=\"getCrossupsellImageUrl(item)\"\n :alt=\"getCrossupsellName(item)\"\n />\n </template>\n\n <div class=\"min-w-0\">\n <span\n class=\"propeller-cart-item__crossupsell-title text-xs font-medium text-muted-foreground line-clamp-2\"\n >{{ getCrossupsellName(item) }}</span\n >\n <template v-if=\"!!getCrossupsellPrice(item)\">\n <span\n class=\"propeller-cart-item__crossupsell-price text-xs font-bold text-foreground block\"\n >{{ getCrossupsellPrice(item) }}</span\n >\n </template>\n </div></a\n ><button\n type=\"button\"\n class=\"propeller-cart-item__crossupsell-btn flex-shrink-0 inline-flex items-center justify-center h-7 w-7 rounded-[var(--radius-control)] bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50\"\n :title=\"getLabel('addToCart', 'Add to cart')\"\n :disabled=\"\n addingCrossupsellId === getCrossupsellProductId(item)\n \"\n @click=\"\n async (e) => {\n e.stopPropagation();\n handleAddCrossupsellToCart(item);\n }\n \"\n >\n <template\n v-if=\"addingCrossupsellId === getCrossupsellProductId(item)\"\n >\n <div\n class=\"w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin\"\n ></div>\n </template>\n\n <template\n v-if=\"addingCrossupsellId !== getCrossupsellProductId(item)\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"8\" cy=\"21\" r=\"1\"></circle>\n <circle cx=\"19\" cy=\"21\" r=\"1\"></circle>\n <path\n d=\"M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12\"\n ></path>\n </svg>\n </template>\n </button>\n </div>\n </template>\n </div>\n </div>\n </slot>\n </div>\n <div\n class=\"propeller-cart-item__footer w-full md:w-auto flex items-center gap-3 md:gap-4 border-t md:border-t-0 border-border-subtle pt-2 md:pt-0 flex-shrink-0\"\n >\n <slot\n name=\"price\"\n :cartItem=\"cartItem\"\n :isBundle=\"isBundleItem()\"\n :price=\"cartItem.product?.price\"\n :formattedPrice=\"getFormattedPrice()\"\n :bundlePrice=\"getBundlePrice()\"\n :includeTax=\"includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n >\n <template v-if=\"isBundleItem() && !!getBundlePrice()\">\n <p\n class=\"propeller-cart-item__price text-sm md:text-base font-bold text-foreground whitespace-nowrap\"\n >\n {{ getBundlePrice() }}\n </p>\n </template>\n\n <template v-if=\"!isBundleItem()\">\n <!--\n Contract-vs-data note: the default path shows the line-item total\n (`cartItem.totalSum`/`totalSumNet`). The injected component receives\n the closest contract match — the product's catalog price\n (`cartItem.product.price`). The injected price will not include\n line-level surcharges or totals.\n -->\n <p\n class=\"propeller-cart-item__price text-sm md:text-base font-bold text-foreground whitespace-nowrap\"\n >\n <component\n v-if=\"props.priceComponent\"\n :is=\"PriceImpl\"\n :price=\"cartItem?.product?.price\"\n :include-tax=\"includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n />\n <template v-else>{{ getFormattedPrice() }}</template>\n </p>\n </template>\n </slot>\n\n <slot\n name=\"quantity\"\n :cartItem=\"cartItem\"\n :quantity=\"quantity\"\n :readOnly=\"readOnlyQuantity\"\n :minQuantity=\"minQuantity\"\n :step=\"step\"\n :onChange=\"(newQty: any) => handleQuantityChange(newQty)\"\n :labels=\"labels\"\n >\n <template v-if=\"readOnlyQuantity\">\n <div class=\"text-sm text-foreground-subtle\">\n {{ getLabel('qtyPrefix', 'Qty:') }} {{ quantity }}\n </div>\n </template>\n\n <template v-else-if=\"enableIncrementDecrement !== false\">\n <div\n class=\"propeller-cart-item__stepper flex items-center border border-input rounded-[var(--radius-control)] bg-card h-9\"\n >\n <button\n type=\"button\"\n class=\"propeller-cart-item__decrement px-2.5 h-full text-muted-foreground hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed transition-colors rounded-l-[var(--radius-control)] select-none\"\n @click=\"async (event) => handleQuantityChange(quantity - step)\"\n :disabled=\"quantity <= minQuantity || loading\"\n >\n -</button\n ><input\n type=\"number\"\n class=\"propeller-cart-item__quantity w-10 text-center text-sm bg-transparent border-x border-input h-full focus:ring-0 focus:outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n :min=\"minQuantity\"\n :step=\"step\"\n :value=\"quantity\"\n @change=\"\n async (e) => {\n const val = parseInt((e.target as HTMLInputElement).value, 10);\n if (!isNaN(val) && val >= minQuantity) {\n handleQuantityChange(Math.round((val - minQuantity) / step) * step + minQuantity);\n }\n }\n \"\n /><button\n type=\"button\"\n class=\"propeller-cart-item__increment px-2.5 h-full text-muted-foreground hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed transition-colors rounded-r-[var(--radius-control)] select-none\"\n @click=\"async (event) => handleQuantityChange(quantity + step)\"\n :disabled=\"loading\"\n >\n +\n </button>\n </div>\n </template>\n\n <template v-else>\n <input\n type=\"number\"\n class=\"propeller-cart-item__quantity w-14 h-9 text-center text-sm border border-input rounded-[var(--radius-control)] focus:ring-2 focus:ring-primary focus:border-transparent [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n :min=\"minQuantity\"\n :step=\"step\"\n :value=\"quantity\"\n @change=\"\n async (e) => {\n const val = parseInt((e.target as HTMLInputElement).value, 10);\n if (!isNaN(val) && val >= minQuantity) {\n handleQuantityChange(Math.round((val - minQuantity) / step) * step + minQuantity);\n }\n }\n \"\n />\n </template>\n </slot>\n\n <template v-if=\"loading\">\n <span\n class=\"propeller-cart-item__updating text-xs text-foreground-subtle\"\n >{{ getLabel(\"updating\", \"Updating...\") }}</span\n >\n </template>\n\n <slot\n v-if=\"showDelete !== false\"\n name=\"delete\"\n :cartItem=\"cartItem\"\n :deleting=\"deleting\"\n :onDelete=\"handleDelete\"\n :labels=\"labels\"\n >\n <button\n type=\"button\"\n class=\"propeller-cart-item__delete h-8 w-8 p-0 ml-auto inline-flex items-center justify-center rounded-[var(--radius-control)] text-foreground-subtle hover:text-destructive hover:bg-destructive/10 transition-colors disabled:opacity-50\"\n @click=\"async (event) => handleDelete()\"\n :disabled=\"deleting\"\n >\n <template v-if=\"deleting\">\n <div\n class=\"w-4 h-4 border-2 border-input border-t-transparent rounded-full animate-spin\"\n ></div>\n </template>\n\n <template v-if=\"!deleting\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 6h18\"></path>\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"></path>\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"></path>\n </svg>\n </template>\n </button>\n </slot>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, ref, watch, computed, type Component } from \"vue\";\nimport { BundleItem, Cart, CartBaseItem, CartMainItem, Cluster, Contact, Crossupsell, type CrossupsellSearchInput, type CrossupsellsQueryVariables, CrossupsellType, Customer, GraphQLClient, type MediaImageProductSearchInput, Product, ProductInventory, type TransformationsInput, YesNo } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useCart } from \"../composables/vue/useCart\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n getProductImageUrl as _getProductImageUrl,\n getProductSku as _getProductSku,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice, formatSurcharge as _formatSurcharge } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useResolvedProps, type ResolveSpec } from '../composables/vue/useResolvedProps';\nimport DefaultProductPrice from './ProductPrice.vue';\nimport DefaultItemStock from './ItemStock.vue';\nimport DefaultProductSurcharges from './defaults/DefaultProductSurcharges.vue';\n\nexport interface CartItemProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** The shopping cart unique identifier */\n cartId: string;\n\n /** Tax zone for price calculations */\n taxZone?: string;\n\n /** Authenticated user for cart operations */\n user?: Contact | Customer | null;\n\n /** A shopping cart item */\n cartItem: CartMainItem;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** Should the item title be a link to the PDP. Defaults to true. */\n titleLinkable?: boolean;\n\n /** Should the stock be displayed in the cart item. Defaults to false. */\n showStockComponent?: boolean;\n\n /** Display the SKU of the cart item beneath the item name. Defaults to true. */\n showSku?: boolean;\n\n /** +/- buttons on left and right of quantity input. Defaults to true. */\n enableIncrementDecrement?: boolean;\n\n /** Should the cart item notes field be displayed. Defaults to false. */\n showCartItemNotesField?: boolean;\n\n /** Action callback when a cart item quantity is changed */\n onQuantityChange?: (item: CartMainItem, quantity: number) => void;\n\n /** Action callback when a cart item note is changed */\n onNoteChange?: (item: CartMainItem, note: string) => void;\n\n /** Action callback when a cart item is deleted */\n onDelete?: (item: CartMainItem) => void;\n\n /** Callback with the updated cart after any cart mutation */\n afterCartUpdate?: (cart: Cart) => void;\n\n /** Label overrides for UI strings\n *\n * Available keys: remove, notes, notesPlaceholder, includedOptions, updating, deleting\n */\n labels?: Record<string, string>;\n\n /** Language code for CartService operations. Defaults to 'NL'. */\n language?: string;\n\n /** Configuration object for image filters and URL generation */\n configuration?: {\n language?: string;\n imageSearchFiltersGrid?: MediaImageProductSearchInput;\n imageVariantFiltersSmall?: TransformationsInput;\n imageVariantFiltersMedium?: TransformationsInput;\n urls?: { getProductUrl: (product: Product, language?: string) => string };\n };\n\n /** Show cross-sell/upsell product suggestions below the item. Defaults to false. */\n showCrossupsells?: boolean;\n\n /** Which cross-sell types to fetch. Defaults to ['ACCESSORIES']. Values: 'ACCESSORIES', 'ALTERNATIVES', 'OPTIONS', 'PARTS', 'RELATED' */\n crossupsellTypes?: string[];\n\n /** Maximum number of cross-sell products to display. Defaults to 3. */\n crossupsellLimit?: number;\n\n /** Callback when a cross-sell product is clicked */\n onCrossupsellClick?: (product: Product | Cluster) => void;\n\n /** Additional CSS class for the root element */\n className?: string;\n\n /** Include tax in price. Defaults to false. */\n includeTax?: boolean;\n\n /** Active company ID for PAC lookup. */\n companyId?: number;\n\n // ───── Extension API ─────\n // Per-row overrides for sub-components.\n priceComponent?: Component;\n stockComponent?: Component;\n surchargesComponent?: Component;\n\n /** When false, root element drops the card frame\n * ('bg-card p-4 rounded-[var(--radius-container)] shadow-sm border border-border'),\n * leaving only the flex layout. Default: true. Used by drawer / summary\n * widgets. */\n cardFrame?: boolean;\n\n /** When false, the delete button (and #delete slot in compound mode)\n * returns null. Default: true. */\n showDelete?: boolean;\n\n /** When true, quantity renders as 'Qty: {n}' text — no stepper, no\n * input. Default: false. Independent from enableIncrementDecrement. */\n readOnlyQuantity?: boolean;\n\n /** Optional title click callback. Fires BEFORE default navigation; the\n * consumer may call event.preventDefault() to suppress nav. Used by\n * the cart drawer to close the sidebar on title click. */\n onTitleClick?: (event: MouseEvent, item: CartMainItem) => void;\n}\ninterface CartItemState {\n quantity: number;\n notes: string;\n loading: boolean;\n deleting: boolean;\n notesTimeout: any;\n crossupsells: Crossupsell[];\n crossupsellsLoading: boolean;\n getLabel: (key: string, fallback: string) => string;\n getProductName: () => string;\n getProductUrl: () => string;\n getProductImageUrl: () => string;\n getProductSku: () => string;\n getInventory: () => ProductInventory | null;\n getFormattedPrice: () => string;\n getChildItemPrice: (child: CartBaseItem) => string;\n isBundleItem: () => boolean;\n getBundleName: () => string;\n getBundlePrice: () => string;\n getBundleLeaderName: () => string;\n getBundleLeaderPrice: () => string;\n getBundleNonLeaders: () => BundleItem[];\n getBundleItemName: (bundleItem: BundleItem) => string;\n getBundleItemPrice: (bundleItem: BundleItem) => string;\n handleQuantityChange: (newQuantity: number) => void;\n handleNoteChange: (note: string) => void;\n handleDelete: () => void;\n fetchCrossupsells: () => void;\n getCrossupsellName: (item: Crossupsell) => string;\n getCrossupsellImageUrl: (item: Crossupsell) => string;\n getCrossupsellUrl: (item: Crossupsell) => string;\n getVisibleCrossupsells: () => Crossupsell[];\n getCrossupsellProductId: (item: Crossupsell) => number | undefined;\n getCrossupsellPrice: (item: Crossupsell) => string;\n addingCrossupsellId: number | null;\n handleAddCrossupsellToCart: (item: Crossupsell) => void;\n}\n\nconst props = withDefaults(defineProps<CartItemProps>(), {\n showSku: true,\n titleLinkable: true,\n enableIncrementDecrement: true,\n});\n\n// ───── Extension API ─────\n// Resolve infra deps (graphqlClient + scope) AND sub-component slots from:\n// explicit props → ProductGrid context → PropellerProvider.\nconst RESOLVE_SPEC: ResolveSpec<CartItemProps> = {\n graphqlClient: { infra: 'graphqlClient' },\n user: { infra: 'user' },\n companyId: { infra: 'companyId' },\n configuration: { infra: 'configuration' },\n language: { infra: 'language', default: 'NL' },\n currency: { infra: 'currency', default: '€' },\n includeTax: { infra: 'includeTax' },\n priceComponent: { grid: 'priceComponent' },\n stockComponent: { grid: 'stockComponent' },\n surchargesComponent: { grid: 'surchargesComponent' },\n};\n\nconst resolved = computed(() => useResolvedProps(props, RESOLVE_SPEC));\n\nconst PriceImpl = computed(() => resolved.value.priceComponent ?? DefaultProductPrice);\nconst StockImpl = computed(() => resolved.value.stockComponent ?? DefaultItemStock);\nconst SurchargesImpl = computed(() => resolved.value.surchargesComponent ?? DefaultProductSurcharges);\n\nconst userRef = computed(() => resolved.value.user ?? null);\n\nconst {\n loading,\n updateItemQuantity,\n updateItemNotes,\n deleteItem,\n getCrossupsells,\n addItem,\n getMinQuantity,\n getStep,\n} = useCart({\n graphqlClient: resolved.value.graphqlClient as GraphQLClient,\n user: userRef,\n cartId: props.cartId,\n configuration: {\n imageSearchFiltersGrid:\n resolved.value.configuration?.imageSearchFiltersGrid ?? ({} as any),\n imageVariantFiltersSmall:\n resolved.value.configuration?.imageVariantFiltersSmall ?? ({} as any),\n },\n});\n\nconst quantity = ref<CartItemState[\"quantity\"]>(1);\nconst notes = ref<CartItemState[\"notes\"]>(\"\");\n\n// Order quantity rules from the product: `minimumQuantity` (floor) and `unit`\n// (step) — the stepper must honour the product's order rules, not hardcode 1\n// (e.g. a product sold per 6 steps 6/12/18, min 6).\nconst minQuantity = computed(() => getMinQuantity(props.cartItem.product));\nconst step = computed(() => getStep(props.cartItem.product));\nconst deleting = ref<CartItemState[\"deleting\"]>(false);\nconst crossupsells = ref<CartItemState[\"crossupsells\"]>([]);\nconst crossupsellsLoading = ref<CartItemState[\"crossupsellsLoading\"]>(false);\nconst addingCrossupsellId = ref<CartItemState[\"addingCrossupsellId\"]>(null);\n\nonMounted(() => {\n quantity.value = props.cartItem.quantity || 1;\n notes.value = props.cartItem.notes || \"\";\n fetchCrossupsells();\n});\n\nwatch(\n () => [props.cartItem],\n () => {\n quantity.value = props.cartItem.quantity || 1;\n notes.value = props.cartItem.notes || \"\";\n },\n { immediate: true },\n);\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<CartItemState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getProductName(): ReturnType<CartItemState[\"getProductName\"]> {\n return props.cartItem.product?.names?.[0]?.value || \"Product\";\n}\nfunction getProductUrl(): ReturnType<CartItemState[\"getProductUrl\"]> {\n if (props.configuration?.urls && props.cartItem.product) {\n return props.configuration.urls.getProductUrl(\n props.cartItem.product as Product,\n props.language,\n );\n }\n return \"#\";\n}\nfunction getProductImageUrl(): ReturnType<CartItemState[\"getProductImageUrl\"]> {\n return _getProductImageUrl(props.cartItem.product as Product);\n}\nfunction getProductSku(): ReturnType<CartItemState[\"getProductSku\"]> {\n return _getProductSku(props.cartItem.product as Product);\n}\nfunction getSurcharges(): string[] {\n // Cart-line surcharges (CartItemSurcharge: localized `names`, own quantity) —\n // `{qty} x € {value} (name)` for flat fees,\n // `{qty} x {value}% (name)` for percentages.\n type SurchargeLike = {\n name?: { value?: string; language?: string }[];\n names?: { value?: string; language?: string }[];\n type?: string;\n value?: number;\n quantity?: number;\n enabled?: boolean;\n };\n const list = ((props.cartItem.surcharges ?? []) as SurchargeLike[]).filter(\n (s: SurchargeLike) => s.enabled !== false,\n );\n return list\n .map((s: SurchargeLike) =>\n _formatSurcharge(s, {\n quantity: s.quantity ?? props.cartItem.quantity ?? 1,\n language: props.language,\n currency: props.currency ?? \"€\",\n }),\n )\n .filter((line: string) => line.length > 0);\n}\nfunction getInventory(): ReturnType<CartItemState[\"getInventory\"]> {\n const inv = props.cartItem.product?.inventory;\n return inv || null;\n}\nfunction getFormattedPrice(): ReturnType<CartItemState[\"getFormattedPrice\"]> {\n const item = props.cartItem;\n const price = props.includeTax ? item?.totalSumNet || 0 : item?.totalSum || 0;\n return _formatPrice(Number(price), { symbol: props.currency ?? \"€\" });\n}\nfunction getChildItemPrice(\n child: CartBaseItem,\n): ReturnType<CartItemState[\"getChildItemPrice\"]> {\n return _formatPrice(Number(child.totalSum ?? 0), {\n symbol: props.currency ?? \"€\",\n });\n}\nfunction isBundleItem(): ReturnType<CartItemState[\"isBundleItem\"]> {\n return !!props.cartItem.bundle;\n}\nfunction getBundleName(): ReturnType<CartItemState[\"getBundleName\"]> {\n return props.cartItem.bundle?.name || \"Bundle\";\n}\nfunction getBundlePrice(): ReturnType<CartItemState[\"getBundlePrice\"]> {\n const price = props.cartItem.bundle?.price?.net;\n if (price === undefined || price === null) return \"\";\n return _formatPrice(Number(price), { symbol: props.currency ?? \"€\" });\n}\nfunction getBundleLeaderName(): ReturnType<\n CartItemState[\"getBundleLeaderName\"]\n> {\n const items = props.cartItem.bundle?.items;\n if (!items) return \"\";\n const leader = items.find((bi: BundleItem) => bi.isLeader === YesNo.Y);\n if (!leader) return \"\";\n return leader.product.names?.[0]?.value || \"Product\";\n}\nfunction getBundleLeaderPrice(): ReturnType<\n CartItemState[\"getBundleLeaderPrice\"]\n> {\n const items = props.cartItem.bundle?.items;\n if (!items) return \"\";\n const leader = items.find((bi: BundleItem) => bi.isLeader === YesNo.Y);\n if (!leader) return \"\";\n const price = leader.price?.net;\n if (price === undefined || price === null) return \"\";\n return _formatPrice(Number(price), { symbol: props.currency ?? \"€\" });\n}\nfunction getBundleNonLeaders(): ReturnType<\n CartItemState[\"getBundleNonLeaders\"]\n> {\n const items = props.cartItem.bundle?.items;\n if (!items) return [];\n return items.filter((bi: BundleItem) => bi.isLeader !== YesNo.Y);\n}\nfunction getBundleItemName(\n bundleItem: BundleItem,\n): ReturnType<CartItemState[\"getBundleItemName\"]> {\n return bundleItem.product.names?.[0]?.value || \"Product\";\n}\nfunction getBundleItemPrice(\n bundleItem: BundleItem,\n): ReturnType<CartItemState[\"getBundleItemPrice\"]> {\n const price = bundleItem.price?.net;\n if (price === undefined || price === null) return \"\";\n return _formatPrice(Number(price), { symbol: props.currency ?? \"€\" });\n}\nasync function handleQuantityChange(\n newQuantity: number,\n): Promise<void> {\n if (newQuantity < 1 || loading.value) return;\n quantity.value = newQuantity;\n if (props.onQuantityChange) {\n props.onQuantityChange(props.cartItem, newQuantity);\n return;\n }\n const updatedCart = await updateItemQuantity(\n props.cartItem.itemId,\n newQuantity,\n );\n if (updatedCart && props.afterCartUpdate) {\n props.afterCartUpdate(updatedCart);\n }\n}\nfunction handleNoteChange(\n note: string,\n): ReturnType<CartItemState[\"handleNoteChange\"]> {\n notes.value = note;\n if (props.onNoteChange) {\n props.onNoteChange(props.cartItem, note);\n return;\n }\n updateItemNotes(props.cartItem.itemId, note, 500);\n}\nasync function handleDelete(): Promise<void> {\n if (deleting.value) return;\n deleting.value = true;\n if (props.onDelete) {\n props.onDelete(props.cartItem);\n deleting.value = false;\n return;\n }\n const updatedCart = await deleteItem(props.cartItem.itemId);\n deleting.value = false;\n if (updatedCart && props.afterCartUpdate) {\n props.afterCartUpdate(updatedCart);\n }\n}\nasync function fetchCrossupsells(): Promise<void> {\n if (!props.showCrossupsells) return;\n const productId = props.cartItem?.productId;\n const clusterId = props.cartItem?.clusterId;\n if (!productId && !clusterId) return;\n crossupsellsLoading.value = true;\n try {\n const items = await getCrossupsells({\n productId,\n clusterId,\n types: props.crossupsellTypes || [CrossupsellType.ACCESSORIES],\n taxZone: props.taxZone || \"NL\",\n imageVariantFilters: props.configuration?.imageVariantFiltersMedium,\n });\n crossupsells.value = items;\n } catch {\n crossupsells.value = [];\n } finally {\n crossupsellsLoading.value = false;\n }\n}\nfunction getVisibleCrossupsells(): ReturnType<\n CartItemState[\"getVisibleCrossupsells\"]\n> {\n const items = crossupsells.value || [];\n const limit = props.crossupsellLimit || 3;\n return items.slice(0, limit);\n}\nfunction getCrossupsellName(\n item: Crossupsell,\n): ReturnType<CartItemState[\"getCrossupsellName\"]> {\n const product = item?.productTo || item?.clusterTo;\n return product?.names?.[0]?.value || \"Product\";\n}\nfunction getCrossupsellImageUrl(\n item: Crossupsell,\n): ReturnType<CartItemState[\"getCrossupsellImageUrl\"]> {\n const product = (item?.productTo || item?.clusterTo) as Product | undefined;\n return product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || \"\";\n}\nfunction getCrossupsellUrl(\n item: Crossupsell,\n): ReturnType<CartItemState[\"getCrossupsellUrl\"]> {\n const product = item?.productTo || item?.clusterTo;\n if (props.configuration?.urls && product) {\n return props.configuration.urls.getProductUrl(\n product as Product,\n props.language,\n );\n }\n return \"#\";\n}\nfunction getCrossupsellProductId(\n item: Crossupsell,\n): ReturnType<CartItemState[\"getCrossupsellProductId\"]> {\n const product = (item?.productTo || item?.clusterTo) as Product | undefined;\n return (product as Product)?.productId || product?.id;\n}\nfunction getCrossupsellPrice(\n item: Crossupsell,\n): ReturnType<CartItemState[\"getCrossupsellPrice\"]> {\n const product = (item?.productTo || item?.clusterTo) as Product | undefined;\n const price = product?.price;\n if (!price) return \"\";\n const value = props.includeTax ? price.net : price.gross;\n if (value === undefined || value === null) return \"\";\n return _formatPrice(Number(value), { symbol: props.currency ?? \"€\" });\n}\nasync function handleAddCrossupsellToCart(\n item: Crossupsell,\n): Promise<void> {\n if (!props.cartId || addingCrossupsellId.value) return;\n const productId = getCrossupsellProductId(item);\n if (!productId) return;\n addingCrossupsellId.value = productId;\n const product = (item.productTo || item.clusterTo) as Product;\n const result = await addItem({\n product,\n quantity: 1,\n cartId: props.cartId,\n createCart: false,\n });\n addingCrossupsellId.value = null;\n if (result.ok && props.afterCartUpdate) {\n props.afterCartUpdate(result.data.cart);\n }\n}\n</script>\n","<template>\n <div\n class=\"propeller-cart-icon relative\"\n :data-sidebar-open=\"sidebarOpen ? 'true' : 'false'\"\n >\n <div\n class=\"propeller-cart-icon__trigger-wrapper relative\"\n @mouseenter=\"\n async (event) => {\n isHovered = true;\n }\n \"\n @mouseleave=\"\n async (event) => {\n isHovered = false;\n }\n \"\n >\n <button\n type=\"button\"\n @click=\"async (event) => handleIconClick()\"\n :aria-label=\"getLabel('cartIconLabel', 'Shopping cart')\"\n :class=\"`propeller-cart-icon__trigger relative inline-flex items-center justify-center p-2 rounded-[var(--radius-control)] transition-colors text-foreground${\n iconClassName ? ' ' + iconClassName : ''\n }`\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-cart-icon__icon w-6 h-6\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M15.75 10.5V6a3.75 3.75 0 10-7.5 0v4.5m11.356-1.993l1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 01-1.12-1.243l1.264-12A1.125 1.125 0 015.513 7.5h12.974c.576 0 1.059.435 1.119 1.007z\"\n ></path>\n </svg>\n <template\n v-if=\"isMounted && showBadge !== false && getTotalItems() > 0\"\n >\n <span\n class=\"propeller-cart-icon__badge absolute -top-1 -right-1 h-5 w-5 flex items-center justify-center rounded-full bg-primary text-primary-foreground text-[10px] font-bold pointer-events-none\"\n >{{ getTotalItems() }}</span\n >\n </template>\n </button>\n <template v-if=\"showTotals && isHovered && getTotalItems() > 0\">\n <div\n class=\"propeller-cart-icon__popover absolute top-full right-0 mt-1 z-40 bg-card border border-border rounded-[var(--radius-container)] shadow-lg px-3 py-2 min-w-[140px] text-sm whitespace-nowrap\"\n >\n <div class=\"flex justify-between gap-4\">\n <span\n class=\"propeller-cart-icon__popover-label text-muted-foreground\"\n >{{ getLabel(\"totalLabel\", \"Total\") }}</span\n ><span\n class=\"propeller-cart-icon__popover-total font-semibold text-foreground\"\n >{{ getTotalPrice() }}</span\n >\n </div>\n <div\n class=\"propeller-cart-icon__popover-count text-xs text-foreground-subtle mt-0.5\"\n >\n {{ getTotalItems() }}{{ getLabel(\"itemsLabel\", \"item(s)\") }}\n </div>\n </div>\n </template>\n </div>\n <template v-if=\"sidebarOpen\">\n <div\n aria-hidden=\"true\"\n class=\"propeller-cart-icon__backdrop fixed inset-0 bg-black/80 backdrop-blur-sm z-[70]\"\n @click=\"async (event) => closeSidebar()\"\n ></div>\n </template>\n\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"getSidebarTitle()\"\n :data-open=\"sidebarOpen ? 'true' : 'false'\"\n :class=\"`propeller-cart-icon__sidebar fixed inset-y-0 right-0 z-[70] w-full max-w-md bg-card shadow-2xl transform transition-transform duration-300 ease-in-out border-l border-border${\n sidebarOpen ? ' translate-x-0' : ' translate-x-full'\n }${sidebarClassName ? ' ' + sidebarClassName : ''}`\"\n >\n <div class=\"flex flex-col h-full\">\n <template v-if=\"isMounted\">\n <div\n class=\"propeller-cart-icon__sidebar-header flex items-center justify-between px-5 py-4 border-b border-border\"\n >\n <div class=\"flex items-center gap-2\">\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"w-5 h-5 text-muted-foreground\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M15.75 10.5V6a3.75 3.75 0 10-7.5 0v4.5m11.356-1.993l1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 01-1.12-1.243l1.264-12A1.125 1.125 0 015.513 7.5h12.974c.576 0 1.059.435 1.119 1.007z\"\n ></path>\n </svg>\n <h2\n class=\"propeller-cart-icon__sidebar-title text-base font-semibold text-foreground\"\n >\n {{ getSidebarTitle() }}\n </h2>\n <span\n class=\"propeller-cart-icon__sidebar-count inline-flex items-center justify-center h-5 min-w-[20px] px-1.5 rounded-full bg-secondary/10 text-secondary text-xs font-bold\"\n >{{ getTotalItems() }}</span\n >\n </div>\n <button\n type=\"button\"\n class=\"propeller-cart-icon__sidebar-close p-1 rounded-[var(--radius-control)] text-foreground-subtle hover:text-muted-foreground hover:bg-surface-hover transition-colors\"\n @click=\"async (event) => closeSidebar()\"\n :aria-label=\"getLabel('closeLabel', 'Close')\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"w-5 h-5\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n <div\n class=\"propeller-cart-icon__sidebar-body flex-1 overflow-y-auto px-5 py-4 space-y-4\"\n >\n <template v-if=\"getItems().length === 0\">\n <div\n class=\"propeller-cart-icon__empty flex flex-col items-center justify-center h-full text-center space-y-4 py-16\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-cart-icon__empty-icon w-12 h-12 text-foreground-subtle\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M15.75 10.5V6a3.75 3.75 0 10-7.5 0v4.5m11.356-1.993l1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 01-1.12-1.243l1.264-12A1.125 1.125 0 015.513 7.5h12.974c.576 0 1.059.435 1.119 1.007z\"\n ></path>\n </svg>\n <p\n class=\"propeller-cart-icon__empty-message text-sm text-muted-foreground\"\n >\n {{ getLabel(\"emptyCart\", \"Your cart is empty.\") }}\n </p>\n <button\n type=\"button\"\n class=\"propeller-cart-icon__empty-action text-sm text-secondary hover:underline\"\n @click=\"async (event) => closeSidebar()\"\n >\n {{ getLabel(\"continueShopping\", \"Continue Shopping\") }}\n </button>\n </div>\n </template>\n\n <template v-if=\"getItems().length > 0\">\n <template :key=\"item.itemId\" v-for=\"item in getItems()\">\n <component\n :is=\"CartItemImpl\"\n :cartItem=\"item\"\n :cartId=\"cart?.cartId\"\n :graphqlClient=\"graphqlClient\"\n :user=\"user\"\n :language=\"language\"\n :configuration=\"configuration\"\n :companyId=\"companyId\"\n :cardFrame=\"false\"\n :showDelete=\"false\"\n :readOnlyQuantity=\"true\"\n :onTitleClick=\"(_e: MouseEvent) => closeSidebar()\"\n :showCartItemNotesField=\"false\"\n :showCrossupsells=\"false\"\n :showStockComponent=\"false\"\n :includeTax=\"false\"\n className=\"propeller-cart-icon__item\"\n >\n <template #image=\"{ cartItem: rowCartItem }\">\n <div\n class=\"propeller-cart-icon__item-media w-20 h-20 flex-shrink-0 bg-surface-hover rounded-[var(--radius-control)] overflow-hidden border border-border-subtle flex items-center justify-center\"\n >\n <template\n v-if=\"\n !!(rowCartItem as CartMainItem).product?.media?.images\n ?.items?.[0]?.imageVariants?.[0]?.url\n \"\n >\n <img\n class=\"propeller-cart-icon__item-image w-full h-full object-contain p-2\"\n :src=\"(rowCartItem as CartMainItem).product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url\"\n :alt=\"(rowCartItem as CartMainItem).product?.names?.[0]?.value || 'Product'\"\n />\n </template>\n\n <template\n v-if=\"\n !(rowCartItem as CartMainItem).product?.media?.images\n ?.items?.[0]?.imageVariants?.[0]?.url\n \"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"w-8 h-8 text-foreground-subtle\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z\"\n ></path>\n </svg>\n </template>\n </div>\n </template>\n <template\n #title=\"{ isBundle, name, bundleName, productUrl }\"\n >\n <template v-if=\"isBundle\">\n <span\n class=\"propeller-cart-icon__item-name text-sm font-medium line-clamp-2\"\n >{{ bundleName }}</span\n >\n </template>\n <template v-if=\"!isBundle\">\n <a\n class=\"propeller-cart-icon__item-name text-sm font-medium hover:text-primary line-clamp-2\"\n :href=\"productUrl\"\n @click=\"(_e: MouseEvent) => closeSidebar()\"\n >{{ name }}</a\n >\n </template>\n </template>\n </component>\n </template>\n </template>\n\n <!-- Bonus items — free items added via incentives. Read-only.\n `includeTax` is pinned true so totals match the sidebar's net\n (incl-VAT) prices; currency/language resolve from the\n Propeller provider. -->\n <component\n :is=\"CartBonusItemsImpl\"\n :cart=\"cart\"\n :includeTax=\"true\"\n className=\"mt-4\"\n />\n </div>\n\n <template v-if=\"getItems().length > 0\">\n <div\n class=\"propeller-cart-icon__sidebar-footer px-5 py-4 border-t border-border space-y-3 bg-surface-hover\"\n >\n <div\n class=\"propeller-cart-icon__total-row flex justify-between items-center\"\n >\n <span\n class=\"propeller-cart-icon__total-label text-sm font-medium text-muted-foreground\"\n >{{ getLabel(\"total\", \"Total\") }}</span\n ><span\n class=\"propeller-cart-icon__total-value text-base font-bold text-foreground\"\n >{{ getTotalPrice() }}</span\n >\n </div>\n <template\n v-if=\"showCheckoutButton() && !showRequestAuthorizationButton()\"\n >\n <button\n type=\"button\"\n class=\"propeller-cart-icon__checkout-btn w-full inline-flex justify-center items-center px-4 py-2.5 rounded-[var(--radius-control)] bg-secondary text-primary-foreground text-sm font-medium hover:bg-secondary/90 transition-colors\"\n @click=\"async (event) => handleCheckoutClick()\"\n >\n {{ getLabel(\"checkoutButton\", \"Checkout\") }}\n </button>\n </template>\n\n <template v-if=\"showRequestAuthorizationButton()\">\n <button\n type=\"button\"\n class=\"propeller-cart-icon__authorization-btn w-full inline-flex justify-center items-center px-4 py-2.5 rounded-[var(--radius-control)] bg-secondary text-primary-foreground text-sm font-medium hover:bg-secondary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n @click=\"async (event) => handleRequestAuthorizationClick()\"\n :disabled=\"requestLoading\"\n >\n <template v-if=\"requestLoading\">\n {{ getLabel(\"requestingAuthorization\", \"Requesting...\") }}\n </template>\n\n <template v-if=\"!requestLoading\">\n {{\n getLabel(\n \"requestAuthorizationButton\",\n \"Request Authorization\",\n )\n }}\n </template>\n </button>\n </template>\n\n <template\n v-if=\"\n !showRequestAuthorizationButton() &&\n !!onRequestQuoteClick &&\n !!user &&\n 'contactId' in user\n \"\n >\n <button\n type=\"button\"\n class=\"propeller-cart-icon__quote-btn w-full inline-flex justify-center items-center px-4 py-2.5 rounded-[var(--radius-control)] border border-secondary bg-card text-secondary text-sm font-medium hover:bg-secondary/5 transition-colors\"\n @click=\"\n async (event) => {\n closeSidebar();\n onRequestQuoteClick && onRequestQuoteClick(cart as Cart);\n }\n \"\n >\n {{ getLabel(\"requestQuoteButton\", \"Request a Quote\") }}\n </button>\n </template>\n\n <template v-if=\"cartPageButton !== false\">\n <button\n type=\"button\"\n class=\"propeller-cart-icon__view-cart-btn w-full inline-flex justify-center items-center px-4 py-2.5 rounded-[var(--radius-control)] border border-input bg-card text-muted-foreground text-sm font-medium hover:bg-surface-hover transition-colors\"\n @click=\"async (event) => handleCartPageClick()\"\n >\n {{ getLabel(\"cartPageButton\", \"View Cart Details\") }}\n </button>\n </template>\n </div>\n </template>\n </template>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type Component } from \"vue\";\n\nimport { Cart, CartMainItem, Contact, Customer, GraphQLClient, PurchaseRole } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useCart } from \"../composables/vue/useCart\";\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport DefaultCartBonusItemsImpl from \"./CartBonusItems.vue\";\nimport DefaultCartItem from \"./CartItem.vue\";\n\nexport interface CartIconAndSidebarProps {\n /**\n * Shopping cart that this component will operate with.\n * Should be passed from a cart state.\n */\n cart: Cart | null;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /**\n * Icon for the cart icon in header.\n * @default 'default-cart-icon'\n */\n icon?: string;\n\n /**\n * Shows item count badge on the cart icon.\n * @default true\n */\n showBadge?: boolean;\n\n /**\n * Shows the totals of the shopping cart beneath the icon when hovered.\n * @default false\n */\n showTotals?: boolean;\n\n /**\n * Show cart sidebar at the right side of the screen when cart icon is clicked.\n * If false it will fire onCartIconClick() instead.\n * @default true\n */\n showCartSidebarOnClick?: boolean;\n\n /**\n * Fires a click event when showCartSidebarOnClick is set to false.\n */\n onCartIconClick?: (cart: Cart) => void;\n\n /**\n * Title for the shopping cart sidebar.\n * @default 'Shopping cart'\n */\n cartSidebarTitle?: string;\n\n /**\n * Show checkout button in cart sidebar for immediate checkout.\n * @default true\n */\n cartCheckoutButton?: boolean;\n\n /**\n * Fires a click event when the checkout button in the sidebar is clicked.\n */\n onCheckoutButtonClick?: (cart: Cart) => void;\n\n /**\n * Show shopping cart page button in cart sidebar.\n * @default true\n */\n cartPageButton?: boolean;\n\n /**\n * Fires a click event when the shopping cart button in the sidebar is clicked.\n */\n onCartPageButtonClick?: (cart: Cart) => void;\n\n /**\n * Labels for the component.\n * Available keys: cartIconLabel, totalLabel, itemsLabel, emptyCart,\n * continueShopping, qty, total, checkoutButton, cartPageButton, closeLabel\n */\n labels?: Record<string, string>;\n\n /** Logged-in user — used to determine purchaser role and authorization limit */\n user?: Contact | Customer;\n\n /** Active company ID — used to look up the user's PAC for this company */\n companyId?: number;\n\n /** Action handler when the \"Request a Quote\" button is clicked */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /** GraphQL client — used for internal CartService calls (e.g. purchase authorization) */\n graphqlClient?: GraphQLClient;\n\n /** Override the internal request purchase authorization call */\n onRequestAuthorization?: (cart: Cart) => void;\n\n /** Fires after a successful purchase authorization request with the updated cart */\n afterRequestAuthorization?: (cart: Cart) => void;\n\n /** Error handler for authorization request failures */\n onError?: (error: Error) => void;\n\n /**\n * Additional class name for the shopping cart icon.\n */\n iconClassName?: string;\n\n /**\n * Additional class name for the shopping cart sidebar.\n */\n sidebarClassName?: string;\n\n /** Configuration object for image filters */\n configuration?: any;\n\n /** Language used to build localized URLs for cart-item links. Defaults to 'NL'. */\n language?: string;\n\n // ───── Extension API ─────\n /**\n * Replaces each cart row rendered inside the drawer with a custom CartItem.\n * The drawer composes CartItem with cardFrame=false, showDelete=false,\n * readOnlyQuantity, and onTitleClick wired to close the sidebar.\n */\n cartItemComponent?: Component;\n // Replaces the embedded <CartBonusItems> bonus-line block. Active.\n cartBonusItemsComponent?: Component;\n}\ninterface CartIconAndSidebarState {\n isMounted: boolean;\n sidebarOpen: boolean;\n isHovered: boolean;\n getTotalItems: () => number;\n getTotalPrice: () => string;\n getItems: () => CartMainItem[];\n handleIconClick: () => void;\n openSidebar: () => void;\n closeSidebar: () => void;\n handleCheckoutClick: () => void;\n handleCartPageClick: () => void;\n getLabel: (key: string, fallback: string) => string;\n getSidebarTitle: () => string;\n showCheckoutButton: () => boolean;\n showRequestAuthorizationButton: () => boolean;\n requestLoading: boolean;\n handleRequestAuthorizationClick: () => Promise<void>;\n}\n\nconst props = withDefaults(defineProps<CartIconAndSidebarProps>(), {\n showBadge: true,\n cartPageButton: true,\n showCartSidebarOnClick: true,\n});\n// Resolve graphqlClient + user + companyId + configuration from the\n// propellerVue plugin scope when not passed explicitly. AppHeader / chrome\n// surfaces rely on the provider rather than threading deps through props.\nconst infra = useInfraProps(props);\nconst isMounted = ref<CartIconAndSidebarState[\"isMounted\"]>(false);\nconst sidebarOpen = ref<CartIconAndSidebarState[\"sidebarOpen\"]>(false);\nconst isHovered = ref<CartIconAndSidebarState[\"isHovered\"]>(false);\nconst requestLoading = ref<CartIconAndSidebarState[\"requestLoading\"]>(false);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\nconst cartIdRef = computed(() => props.cart?.cartId);\nconst { requestAuthorization } = useCart({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n user: userRef,\n cartId: cartIdRef,\n companyId: companyRef,\n configuration: {\n imageSearchFiltersGrid:\n infra.configuration?.imageSearchFiltersGrid ?? ({} as any),\n imageVariantFiltersSmall:\n infra.configuration?.imageVariantFiltersSmall ?? ({} as any),\n },\n});\n\nconst CartItemImpl = computed<Component>(\n () => props.cartItemComponent ?? DefaultCartItem,\n);\nconst CartBonusItemsImpl = computed<Component>(\n () => props.cartBonusItemsComponent ?? DefaultCartBonusItemsImpl,\n);\n\nonMounted(() => {\n isMounted.value = true;\n});\n\nfunction getCartItems(): CartMainItem[] {\n const cart = props.cart as any;\n return cart?.items ?? cart?.mainItems?.items ?? [];\n}\nfunction getTotalItems(): ReturnType<CartIconAndSidebarState[\"getTotalItems\"]> {\n return getCartItems().reduce((sum, item) => sum + (item.quantity || 0), 0);\n}\nfunction getTotalPrice(): ReturnType<CartIconAndSidebarState[\"getTotalPrice\"]> {\n const total = props.cart?.total?.totalNet;\n return _formatPrice(total ?? 0, { symbol: (infra.currency as string | undefined) ?? \"€\" });\n}\nfunction getItems(): ReturnType<CartIconAndSidebarState[\"getItems\"]> {\n return getCartItems().filter((item: CartMainItem) => item && item.product);\n}\nfunction handleIconClick(): ReturnType<\n CartIconAndSidebarState[\"handleIconClick\"]\n> {\n if (props.showCartSidebarOnClick !== false) {\n sidebarOpen.value = true;\n } else {\n if (props.onCartIconClick) props.onCartIconClick(props.cart as Cart);\n }\n}\nfunction openSidebar(): ReturnType<CartIconAndSidebarState[\"openSidebar\"]> {\n sidebarOpen.value = true;\n}\nfunction closeSidebar(): ReturnType<CartIconAndSidebarState[\"closeSidebar\"]> {\n sidebarOpen.value = false;\n}\nfunction handleCheckoutClick(): ReturnType<\n CartIconAndSidebarState[\"handleCheckoutClick\"]\n> {\n sidebarOpen.value = false;\n if (props.onCheckoutButtonClick)\n props.onCheckoutButtonClick(props.cart as Cart);\n}\nfunction handleCartPageClick(): ReturnType<\n CartIconAndSidebarState[\"handleCartPageClick\"]\n> {\n sidebarOpen.value = false;\n if (props.onCartPageButtonClick)\n props.onCartPageButtonClick(props.cart as Cart);\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<CartIconAndSidebarState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getSidebarTitle(): ReturnType<\n CartIconAndSidebarState[\"getSidebarTitle\"]\n> {\n return (\n props.cartSidebarTitle ||\n props.labels?.[\"cartSidebarTitle\"] ||\n \"Shopping cart\"\n );\n}\nfunction showCheckoutButton(): ReturnType<\n CartIconAndSidebarState[\"showCheckoutButton\"]\n> {\n if (props.cartCheckoutButton === false) return false;\n if (!infra.user || !(\"contactId\" in infra.user)) return true;\n if (!infra.companyId) return true;\n const pacData = (infra.user as Contact).purchaseAuthorizationConfigs;\n const items: any[] =\n (pacData as any)?.items ?? (pacData as any)?._items ?? [];\n const purchaserPAC = items.find((pac: any) => {\n const role = pac.purchaseRole ?? pac._purchaseRole;\n const pacCompanyId =\n pac.company?.companyId ??\n pac.company?._companyId ??\n pac._company?.companyId ??\n pac._company?._companyId;\n return (\n role === PurchaseRole.PURCHASER && pacCompanyId === infra.companyId\n );\n });\n if (!purchaserPAC) return true;\n const limit =\n purchaserPAC.authorizationLimit ?? purchaserPAC._authorizationLimit ?? 0;\n const totalGross = (props.cart as any)?.total?.totalGross ?? 0;\n return totalGross <= limit;\n}\nfunction showRequestAuthorizationButton(): ReturnType<\n CartIconAndSidebarState[\"showRequestAuthorizationButton\"]\n> {\n if (!infra.user || !(\"contactId\" in infra.user)) return false;\n if (!infra.companyId) return false;\n const pacData = (infra.user as Contact).purchaseAuthorizationConfigs;\n const items: any[] =\n (pacData as any)?.items ?? (pacData as any)?._items ?? [];\n const purchaserPAC = items.find((pac: any) => {\n const role = pac.purchaseRole ?? pac._purchaseRole;\n const pacCompanyId =\n pac.company?.companyId ??\n pac.company?._companyId ??\n pac._company?.companyId ??\n pac._company?._companyId;\n return (\n role === PurchaseRole.PURCHASER && pacCompanyId === infra.companyId\n );\n });\n if (!purchaserPAC) return false;\n const limit =\n purchaserPAC.authorizationLimit ?? purchaserPAC._authorizationLimit ?? 0;\n const totalGross = (props.cart as any)?.total?.totalGross ?? 0;\n return totalGross > limit;\n}\nasync function handleRequestAuthorizationClick(): ReturnType<\n CartIconAndSidebarState[\"handleRequestAuthorizationClick\"]\n> {\n requestLoading.value = true;\n try {\n if (props.onRequestAuthorization) {\n props.onRequestAuthorization(props.cart as Cart);\n } else {\n const result = await requestAuthorization();\n if (!result.ok && props.onError) {\n props.onError(\n new Error(result.error || \"Failed to request authorization\"),\n );\n }\n }\n if (props.afterRequestAuthorization) {\n props.afterRequestAuthorization(props.cart as Cart);\n }\n } catch (err: any) {\n if (props.onError) {\n props.onError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n requestLoading.value = false;\n }\n}\n</script>\n","<template>\n <div :class=\"`propeller-cart-overview ${containerClass}`\">\n <template v-if=\"title\">\n <h2 class=\"propeller-cart-overview__title text-xl font-bold mb-4\">\n {{ title }}\n </h2>\n </template>\n\n <div\n class=\"propeller-cart-overview__addresses grid grid-cols-1 md:grid-cols-2 gap-6 pb-5\"\n >\n <div\n class=\"propeller-cart-overview__address space-y-2\"\n data-address=\"invoice\"\n >\n <h3\n class=\"propeller-cart-overview__address-title text-sm font-semibold text-muted-foreground uppercase tracking-wide\"\n >\n {{ getLabel(\"invoiceAddress\", \"Invoice Address\") }}\n </h3>\n <template v-if=\"invoiceAddress && invoiceAddress.street\">\n <div class=\"text-sm space-y-1\">\n <template v-if=\"invoiceAddress.company\">\n <p class=\"font-medium\">{{ invoiceAddress.company }}</p>\n </template>\n\n <p>\n {{\n [\n invoiceAddress.firstName,\n invoiceAddress.middleName,\n invoiceAddress.lastName,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </p>\n <p>\n {{\n [\n invoiceAddress.street,\n invoiceAddress.number,\n invoiceAddress.numberExtension,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </p>\n <p>\n {{\n [invoiceAddress.postalCode, invoiceAddress.city]\n .filter(Boolean)\n .join(\" \")\n }}\n </p>\n <template v-if=\"invoiceAddress.country\">\n <p>{{ getCountryName(invoiceAddress.country) }}</p>\n </template>\n\n <template v-if=\"invoiceAddress.email\">\n <p\n class=\"propeller-cart-overview__address-email text-muted-foreground\"\n >\n {{ invoiceAddress.email }}\n </p>\n </template>\n </div>\n </template>\n </div>\n <div\n class=\"propeller-cart-overview__address space-y-2\"\n data-address=\"delivery\"\n >\n <h3\n class=\"propeller-cart-overview__address-title text-sm font-semibold text-muted-foreground uppercase tracking-wide\"\n >\n {{ getLabel(\"deliveryAddress\", \"Delivery Address\") }}\n </h3>\n <template v-if=\"deliveryAddress && deliveryAddress.street\">\n <div class=\"text-sm space-y-1\">\n <template v-if=\"deliveryAddress.company\">\n <p class=\"font-medium\">{{ deliveryAddress.company }}</p>\n </template>\n\n <p>\n {{\n [\n deliveryAddress.firstName,\n deliveryAddress.middleName,\n deliveryAddress.lastName,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </p>\n <p>\n {{\n [\n deliveryAddress.street,\n deliveryAddress.number,\n deliveryAddress.numberExtension,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </p>\n <p>\n {{\n [deliveryAddress.postalCode, deliveryAddress.city]\n .filter(Boolean)\n .join(\" \")\n }}\n </p>\n <template v-if=\"deliveryAddress.country\">\n <p>{{ getCountryName(deliveryAddress.country) }}</p>\n </template>\n\n <template v-if=\"deliveryAddress.email\">\n <p\n class=\"propeller-cart-overview__address-email text-muted-foreground\"\n >\n {{ deliveryAddress.email }}\n </p>\n </template>\n </div>\n </template>\n </div>\n </div>\n <div\n class=\"propeller-cart-overview__info-panel bg-surface-hover p-4 rounded-[var(--radius-control)] border border-border space-y-2 text-sm\"\n >\n <template v-if=\"paymentMethod\">\n <div class=\"flex justify-between\">\n <span class=\"font-medium\">{{ getLabel(\"payment\", \"Payment:\") }}</span\n ><span>{{ paymentMethod }}</span>\n </div>\n </template>\n\n <template v-if=\"carrierName\">\n <div class=\"flex justify-between\">\n <span class=\"font-medium\">{{ getLabel(\"carrier\", \"Carrier:\") }}</span\n ><span>{{ carrierName }}</span>\n </div>\n </template>\n\n <template v-if=\"requestDate\">\n <div class=\"flex justify-between\">\n <span class=\"font-medium\">{{\n getLabel(\"deliveryDate\", \"Delivery Date:\")\n }}</span\n ><span>{{ requestDate }}</span>\n </div>\n </template>\n </div>\n <div class=\"space-y-4 mt-6\">\n <template v-if=\"showReference\">\n <div class=\"space-y-2\">\n <label class=\"text-sm font-medium\">{{\n getLabel(\"referenceLabel\", \"Reference (Optional)\")\n }}</label\n ><input\n type=\"text\"\n class=\"propeller-cart-overview__input flex w-full rounded-[var(--radius-control)] border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-secondary\"\n :value=\"reference\"\n @change=\"\n async (event) =>\n handleReferenceChange(\n (event.target as HTMLInputElement | HTMLTextAreaElement)\n .value,\n )\n \"\n :placeholder=\"\n getLabel('referencePlaceholder', 'Your reference number')\n \"\n :maxLength=\"255\"\n />\n </div>\n </template>\n\n <template v-if=\"showNotes\">\n <div class=\"space-y-2\">\n <label class=\"text-sm font-medium\">{{\n getLabel(\"notesLabel\", \"Order Notes (Optional)\")\n }}</label\n ><textarea\n class=\"propeller-cart-overview__textarea flex w-full rounded-[var(--radius-control)] border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-1 focus:ring-secondary min-h-[80px]\"\n :value=\"notes\"\n @change=\"\n async (event) =>\n handleNotesChange(\n (event.target as HTMLInputElement | HTMLTextAreaElement)\n .value,\n )\n \"\n :placeholder=\"\n getLabel('notesPlaceholder', 'Special instructions or comments')\n \"\n :maxLength=\"255\"\n ></textarea>\n </div>\n </template>\n\n <template v-if=\"showTermsAndConditions\">\n <div class=\"flex items-center space-x-2 pt-2\">\n <input\n type=\"checkbox\"\n id=\"cart-overview-terms\"\n class=\"propeller-cart-overview__checkbox h-4 w-4 rounded border-input text-primary focus:ring-primary\"\n :checked=\"termsAccepted\"\n @change=\"\n async (event) =>\n handleTermsChange((event.target as HTMLInputElement).checked)\n \"\n /><label for=\"cart-overview-terms\" class=\"text-sm leading-none\"\n >{{ getLabel(\"termsPrefix\", \"I agree to the\")\n }}<a\n href=\"#\"\n class=\"text-primary hover:underline font-medium\"\n @click=\"async (event) => handleTermsLinkClick(event)\"\n >{{ getLabel(\"termsLink\", \"Terms and Conditions\") }}</a\n ></label\n >\n </div>\n </template>\n\n <template v-if=\"showPurchaseButton\">\n <button\n type=\"button\"\n class=\"propeller-cart-overview__submit flex items-center justify-center gap-2 w-full bg-primary text-primary-foreground text-center py-3 rounded-[var(--radius-container)] hover:bg-primary/80 transition font-semibold text-lg disabled:opacity-50 disabled:cursor-not-allowed mt-2\"\n @click=\"async (event) => handlePurchaseClick()\"\n :disabled=\"isPurchaseDisabled\"\n >\n <template v-if=\"loading\">\n <div\n class=\"propeller-cart-overview__spinner w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin\"\n ></div>\n </template>\n\n <template v-if=\"loading\">\n {{ getLabel(\"processing\", \"Processing...\") }}\n </template>\n\n <template v-if=\"!loading\">\n {{ getLabel(\"purchaseButton\", \"Place Order\") }}\n </template>\n </button>\n </template>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport { Cart, CartAddress, GraphQLClient } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getCountryName as _getCountryName } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface CartOverviewProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** Shopping cart object from which the cart overview will be displayed */\n cart: Cart;\n\n /** The CSS class for the cart overview container */\n overviewContainerClass?: string;\n\n /** Title of the cart overview */\n title?: string;\n\n /** Labels for the cart overview form fields and buttons */\n labels?: Record<string, string>;\n\n /** Show the notes field for the cart */\n showNotes?: boolean;\n\n /** Show the reference field for the cart */\n showReference?: boolean;\n\n /** Show the terms and conditions acceptance */\n showTermsAndConditions?: boolean;\n\n /** Action when the \"Terms and conditions\" link is clicked */\n onTermsAndConditionsClick?: () => void;\n\n /** Show the \"Purchase\" button for placing an order */\n showPurchaseButton?: boolean;\n\n /** Action when the purchase button is clicked. Receives cart, reference, and notes */\n onPurchaseButtonClick?: (\n cart: Cart,\n reference: string,\n notes: string,\n ) => void;\n\n /**\n * Optional list of countries used to resolve ISO codes (e.g. 'NL') to display\n * names (e.g. 'Netherlands') in the address blocks. When omitted, the shared\n * built-in COUNTRIES list is used as a fallback.\n */\n countries?: { code: string; name: string }[];\n}\ninterface CartOverviewState {\n reference: string;\n notes: string;\n termsAccepted: boolean;\n loading: boolean;\n containerClass: string;\n showNotes: boolean;\n showReference: boolean;\n showTermsAndConditions: boolean;\n showPurchaseButton: boolean;\n getLabel: (key: string, fallback: string) => string;\n invoiceAddress: CartAddress;\n deliveryAddress: CartAddress;\n formatAddress: (addr: CartAddress) => string;\n paymentMethod: string;\n carrierName: string;\n requestDate: string;\n handleReferenceChange: (value: string) => void;\n handleNotesChange: (value: string) => void;\n handleTermsChange: (checked: boolean) => void;\n handleTermsLinkClick: (event: Event) => void;\n isPurchaseDisabled: boolean;\n handlePurchaseClick: () => void;\n}\n\nconst props = withDefaults(defineProps<CartOverviewProps>(), {\n showNotes: true,\n showReference: true,\n showTermsAndConditions: true,\n showPurchaseButton: true,\n});\nconst reference = ref<CartOverviewState[\"reference\"]>(\"\");\nconst notes = ref<CartOverviewState[\"notes\"]>(\"\");\nconst termsAccepted = ref<CartOverviewState[\"termsAccepted\"]>(false);\nconst loading = ref<CartOverviewState[\"loading\"]>(false);\n\nconst containerClass = computed(() => {\n return props.overviewContainerClass || \"cart-overview\";\n});\nconst showNotes = computed(() => {\n return props.showNotes !== undefined ? props.showNotes : true;\n});\nconst showReference = computed(() => {\n return props.showReference !== undefined ? props.showReference : true;\n});\nconst showTermsAndConditions = computed(() => {\n return props.showTermsAndConditions !== undefined\n ? props.showTermsAndConditions\n : true;\n});\nconst showPurchaseButton = computed(() => {\n return props.showPurchaseButton !== undefined\n ? props.showPurchaseButton\n : true;\n});\nconst invoiceAddress = computed(() => {\n return props.cart?.invoiceAddress;\n});\nconst deliveryAddress = computed(() => {\n return props.cart?.deliveryAddress;\n});\nconst paymentMethod = computed(() => {\n return props.cart?.paymentData?.method || \"\";\n});\nconst carrierName = computed(() => {\n return props.cart?.postageData?.carrier || \"\";\n});\nconst requestDate = computed(() => {\n const date = props.cart?.postageData?.requestDate;\n if (!date) return \"\";\n try {\n return new Date(date).toLocaleDateString();\n } catch {\n return date;\n }\n});\nconst isPurchaseDisabled = computed(() => {\n if (showTermsAndConditions.value && !termsAccepted.value) return true;\n if (loading.value) return true;\n return false;\n});\n\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<CartOverviewState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatAddress(\n addr: CartAddress,\n): ReturnType<CartOverviewState[\"formatAddress\"]> {\n if (!addr || !addr.street) return \"\";\n const parts: string[] = [];\n if (addr.company) parts.push(addr.company);\n const nameParts: string[] = [];\n if (addr.firstName) nameParts.push(addr.firstName);\n if (addr.middleName) nameParts.push(addr.middleName);\n if (addr.lastName) nameParts.push(addr.lastName);\n if (nameParts.length > 0) parts.push(nameParts.join(\" \"));\n const streetLine = [addr.street, addr.number, addr.numberExtension]\n .filter(Boolean)\n .join(\" \");\n if (streetLine) parts.push(streetLine);\n const cityLine = [addr.postalCode, addr.city].filter(Boolean).join(\" \");\n if (cityLine) parts.push(cityLine);\n if (addr.country) parts.push(getCountryName(addr.country));\n return parts.join(\", \");\n}\n\nfunction getCountryName(code: string): string {\n return _getCountryName(code, props.countries);\n}\nfunction handleReferenceChange(\n value: string,\n): ReturnType<CartOverviewState[\"handleReferenceChange\"]> {\n reference.value = value.slice(0, 255);\n}\nfunction handleNotesChange(\n value: string,\n): ReturnType<CartOverviewState[\"handleNotesChange\"]> {\n notes.value = value.slice(0, 255);\n}\nfunction handleTermsChange(\n checked: boolean,\n): ReturnType<CartOverviewState[\"handleTermsChange\"]> {\n termsAccepted.value = checked;\n}\nfunction handleTermsLinkClick(\n event: Event,\n): ReturnType<CartOverviewState[\"handleTermsLinkClick\"]> {\n event.preventDefault();\n if (props.onTermsAndConditionsClick) {\n props.onTermsAndConditionsClick();\n }\n}\nfunction handlePurchaseClick(): ReturnType<\n CartOverviewState[\"handlePurchaseClick\"]\n> {\n if (isPurchaseDisabled.value) return;\n loading.value = true;\n if (props.onPurchaseButtonClick) {\n props.onPurchaseButtonClick(props.cart, reference.value, notes.value);\n }\n}\n</script>\n","<template>\n <div :class=\"`propeller-cart-paymethods ${containerClass}`\">\n <template v-if=\"payMethods.length > 0\">\n <div\n class=\"propeller-cart-paymethods__grid grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\"\n >\n <template :key=\"method.code\" v-for=\"(method, index) in payMethods\">\n <div\n @click=\"async (event) => handleSelect(method)\"\n :data-selected=\"selectedCode === method.code ? 'true' : 'false'\"\n :class=\"`propeller-cart-paymethods__method cursor-pointer border border-border rounded-[var(--radius-container)] p-4 flex flex-col gap-2 transition-all ${\n selectedCode === method.code\n ? 'border-secondary bg-secondary/5 shadow-sm'\n : 'hover:border-secondary/30'\n }`\"\n >\n <div\n class=\"propeller-cart-paymethods__method-row flex justify-between items-center\"\n >\n <div class=\"flex items-center gap-2\">\n <span\n class=\"propeller-cart-paymethods__method-name font-medium\"\n >{{ method.name || method.code }}</span\n >\n </div>\n <template v-if=\"method.price > 0\">\n <span\n class=\"propeller-cart-paymethods__method-price text-xs bg-surface-hover text-muted-foreground px-2 py-1 rounded-full\"\n >{{ formatMethodPrice(method.price) }}</span\n >\n </template>\n </div>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"payMethods.length === 0\">\n <p class=\"propeller-cart-paymethods__empty text-muted-foreground italic\">\n {{ getLabel(\"noMethods\", \"No payment methods available.\") }}\n </p>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\n\nimport { Cart, CartPaymethod, Contact, Customer } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface CartPaymethodsProps {\n /** Shopping cart object from which the payment methods will be displayed */\n cart: Cart;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** Authenticated user — used for cart creation / lookup. */\n user: Contact | Customer | null;\n\n /** The CSS class for the payment methods container */\n paymentsContainerClass?: string;\n\n /** Display the on account payment method for anonymous users */\n showOnAccountForGuests?: boolean;\n\n /** Action when a payment method is selected */\n onPaymethodSelect?: (paymethod: CartPaymethod) => void;\n\n /** Custom price formatting function */\n formatPrice?: (price: number) => string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n}\ninterface CartPaymethodsState {\n selectedCode: string;\n containerClass: string;\n showOnAccountForGuests: boolean;\n isGuest: boolean;\n payMethods: CartPaymethod[];\n isOnAccountMethod: (method: CartPaymethod) => boolean;\n getLabel: (key: string, fallback: string) => string;\n formatMethodPrice: (price: number) => string;\n handleSelect: (method: CartPaymethod) => void;\n}\n\nconst props = withDefaults(defineProps<CartPaymethodsProps>(), {\n showOnAccountForGuests: false,\n});\nconst infra = useInfraProps(props);\nconst selectedCode = ref<CartPaymethodsState[\"selectedCode\"]>(\"\");\n\nconst containerClass = computed(() => {\n return props.paymentsContainerClass || \"cart-paymethods\";\n});\nconst showOnAccountForGuests = computed(() => {\n return props.showOnAccountForGuests !== undefined\n ? props.showOnAccountForGuests\n : false;\n});\nconst isGuest = computed(() => {\n return !infra.user;\n});\nconst payMethods = computed(() => {\n const methods: CartPaymethod[] = props.cart?.payMethods || [];\n return methods.filter((m: CartPaymethod) => {\n if (!m?.code) return false;\n if (!showOnAccountForGuests && isGuest && isOnAccountMethod(m)) {\n return false;\n }\n return true;\n });\n});\n\nwatch(\n () => [props.cart],\n () => {\n if (!selectedCode.value && props.cart?.paymentData?.method) {\n selectedCode.value = props.cart.paymentData.method as string;\n if (props.onPaymethodSelect) {\n const match = payMethods.value.find(\n (m: CartPaymethod) => m.code === selectedCode.value,\n );\n if (match) props.onPaymethodSelect(match);\n }\n }\n },\n { immediate: true },\n);\nfunction isOnAccountMethod(\n method: CartPaymethod,\n): ReturnType<CartPaymethodsState[\"isOnAccountMethod\"]> {\n const code = (method.code || \"\").toLowerCase();\n return code === \"on_account\" || code === \"onaccount\" || code === \"on-account\";\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<CartPaymethodsState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatMethodPrice(\n price: number,\n): ReturnType<CartPaymethodsState[\"formatMethodPrice\"]> {\n if (props.formatPrice) {\n return props.formatPrice(price);\n }\n return _formatPrice(price || 0, { symbol: infra.currency ?? \"€\" });\n}\nfunction handleSelect(\n method: CartPaymethod,\n): ReturnType<CartPaymethodsState[\"handleSelect\"]> {\n selectedCode.value = method.code;\n if (props.onPaymethodSelect) {\n props.onPaymethodSelect(method);\n }\n}\n</script>\n","<template>\n <div class=\"propeller-cart-summary w-full bg-card space-y-3\">\n <h2 class=\"propeller-cart-summary__title text-xl font-bold mb-4\">{{ title }}</h2>\n <template v-if=\"showSubtotal\">\n <div class=\"propeller-cart-summary__row flex justify-between text-muted-foreground\" data-row=\"subtotal\">\n <span class=\"propeller-cart-summary__label\">{{ getLabel('subtotal', 'Subtotal:') }}</span\n ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(subtotal) }}</span>\n </div>\n </template>\n\n <template v-if=\"showDiscount && hasDiscount\">\n <div class=\"propeller-cart-summary__row flex justify-between text-success\" data-row=\"discount\">\n <span class=\"propeller-cart-summary__label\">{{ getLabel('discount', 'Discount:') }}</span\n ><span class=\"propeller-cart-summary__value\">-{{ formatItemPrice(discountAmount) }}</span>\n </div>\n </template>\n\n <template v-if=\"showShippingCosts && hasShippingCosts\">\n <div class=\"propeller-cart-summary__row flex justify-between text-muted-foreground\" data-row=\"shipping-costs\">\n <span class=\"propeller-cart-summary__label\">{{ getLabel('shippingCosts', 'Shipping costs:') }}</span\n ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(shippingCosts) }}</span>\n </div>\n </template>\n\n <template v-if=\"showTotalExclVat\">\n <div class=\"propeller-cart-summary__row flex justify-between text-muted-foreground pt-2 border-t\" data-row=\"total-excl-vat\">\n <span class=\"propeller-cart-summary__label\">{{ getLabel('totalExclVat', 'Total excl. VAT:') }}</span\n ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(totalExclVat) }}</span>\n </div>\n </template>\n\n <template v-if=\"showVATs && taxLevels.length > 0\">\n <template :key=\"index\" v-for=\"(tax, index) in taxLevels\">\n <div class=\"propeller-cart-summary__row flex justify-between text-muted-foreground text-sm\" data-row=\"vat-line\">\n <span class=\"propeller-cart-summary__label\">{{ tax.taxPercentage }}% {{ getLabel('vat', 'VAT') }}:</span\n ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(Number(tax.price)) }}</span>\n </div>\n </template>\n </template>\n\n <template v-if=\"showTotalVat && totalVat > 0\">\n <div class=\"propeller-cart-summary__row flex justify-between text-muted-foreground text-sm\" data-row=\"total-vat\">\n <span class=\"propeller-cart-summary__label\">{{ getLabel('totalVat', 'Total VAT:') }}</span\n ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(totalVat) }}</span>\n </div>\n </template>\n\n <div class=\"propeller-cart-summary__row propeller-cart-summary__row--total flex justify-between text-xl font-bold pt-4 border-t text-foreground mt-2\" data-row=\"total\">\n <span class=\"propeller-cart-summary__label\">{{ getLabel('total', 'Total:') }}</span\n ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(totalInclVat) }}</span>\n </div>\n <template v-if=\"showCheckoutButton && !showRequestAuthorizationButton\">\n <button\n type=\"button\"\n class=\"propeller-cart-summary__checkout-btn block w-full bg-secondary text-primary-foreground text-center py-3 rounded-[var(--radius-container)] hover:bg-secondary/90 transition font-semibold mt-4\"\n @click=\"async (event) => handleCheckoutClick()\"\n >\n {{ getLabel('checkoutButton', 'Continue to Checkout') }}\n </button>\n\n <template v-if=\"!!onRequestQuoteClick && !!user && 'contactId' in user\">\n <button\n type=\"button\"\n class=\"propeller-cart-summary__quote-btn block w-full bg-card border border-secondary text-secondary text-center py-3 rounded-[var(--radius-container)] hover:bg-secondary/5 transition font-semibold mt-2\"\n @click=\"async (event) => onRequestQuoteClick && onRequestQuoteClick(cart)\"\n >\n {{ getLabel('requestQuoteButton', 'Request a Quote') }}\n </button>\n </template>\n </template>\n\n <template v-if=\"showRequestAuthorizationButton\">\n <button\n type=\"button\"\n class=\"propeller-cart-summary__authorization-btn block w-full bg-secondary text-primary-foreground text-center py-3 rounded-[var(--radius-container)] hover:bg-secondary/90 transition font-semibold mt-4 disabled:opacity-50 disabled:cursor-not-allowed\"\n @click=\"async (event) => handleRequestAuthorizationClick()\"\n :disabled=\"requestLoading\"\n >\n <template v-if=\"requestLoading\">\n {{ getLabel('requestingAuthorization', 'Requesting...') }}\n </template>\n\n <template v-if=\"!requestLoading\">\n {{ getLabel('requestAuthorizationButton', 'Request Authorization') }}\n </template>\n </button>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport { Cart, Contact, Customer, GraphQLClient, PurchaseRole } from '@propeller-commerce/propeller-sdk-v2';\nimport { useCart } from '../composables/vue/useCart';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface CartSummaryProps {\n /** The shopping cart used to populate the cart summary data */\n cart: Cart;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** Cart summary block title */\n title?: string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** Display the subtotal of the shopping cart */\n showSubtotal?: boolean;\n\n /** Display the total discount of the shopping cart */\n showDiscount?: boolean;\n\n /** Display the shipping costs of the shopping cart */\n showShippingCosts?: boolean;\n\n /** Display all VATs of the shopping cart */\n showVATs?: boolean;\n\n /** Display the total of the shopping cart excluding the VAT */\n showTotalExclVat?: boolean;\n\n /** Display the total VAT of the shopping cart */\n showTotalVat?: boolean;\n\n /** Display the checkout button */\n showCheckoutButton?: boolean;\n\n /** Action handler when the checkout button is clicked */\n onCheckoutButtonClick?: (cart: Cart) => void;\n\n /** Custom price formatting function */\n formatPrice?: (price: number) => string;\n\n /** GraphQL client — required for the default requestPurchaseAuthorization handler */\n graphqlClient?: GraphQLClient;\n\n /** Logged-in user — used to determine purchaser role and authorization limit */\n user?: Contact | Customer;\n\n /** Active company ID — used to look up the user's PAC for this company */\n companyId?: number;\n\n /**\n * Override the default CartService.requestPurchaseAuthorization() call.\n * Note: when this override is used, afterRequestAuthorization receives the original cart.\n */\n onRequestAuthorization?: (cart: Cart) => void;\n\n /** Fires after authorization request is sent; receives the updated cart */\n afterRequestAuthorization?: (cart: Cart) => void;\n\n /** Called when requestPurchaseAuthorization fails; receives the error */\n onError?: (err: Error) => void;\n\n /** Action handler when the \"Request a Quote\" button is clicked */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /** Configuration object for image filters */\n configuration?: any;\n}\ninterface CartSummaryState {\n title: string;\n showSubtotal: boolean;\n showDiscount: boolean;\n showShippingCosts: boolean;\n showVATs: boolean;\n showTotalExclVat: boolean;\n showTotalVat: boolean;\n showCheckoutButton: boolean;\n showRequestAuthorizationButton: boolean;\n requestLoading: boolean;\n getLabel: (key: string, fallback: string) => string;\n formatItemPrice: (price: number) => string;\n subtotal: number;\n hasDiscount: boolean;\n discountAmount: number;\n hasShippingCosts: boolean;\n shippingCosts: number;\n totalExclVat: number;\n taxLevels: NonNullable<Cart['taxLevels']>;\n totalVat: number;\n totalInclVat: number;\n handleCheckoutClick: () => void;\n handleRequestAuthorizationClick: () => Promise<void>;\n}\n\nconst props = withDefaults(defineProps<CartSummaryProps>(), {\n showSubtotal: true,\n showDiscount: true,\n showShippingCosts: true,\n showTotalExclVat: true,\n showVATs: true,\n showTotalVat: true,\n showCheckoutButton: true,\n});\nconst infra = useInfraProps(props);\nconst requestLoading = ref<CartSummaryState['requestLoading']>(false);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\nconst { requestAuthorization } = useCart({\n graphqlClient: infra.graphqlClient!,\n user: userRef,\n cartId: props.cart?.cartId,\n companyId: companyRef,\n configuration: {\n imageSearchFiltersGrid: infra.configuration?.imageSearchFiltersGrid ?? ({} as any),\n imageVariantFiltersSmall: infra.configuration?.imageVariantFiltersSmall ?? ({} as any),\n },\n});\n\nconst title = computed(() => {\n return props.title || 'Order summary';\n});\nconst showSubtotal = computed(() => {\n return props.showSubtotal !== undefined ? props.showSubtotal : true;\n});\nconst showDiscount = computed(() => {\n return props.showDiscount !== undefined ? props.showDiscount : true;\n});\nconst showShippingCosts = computed(() => {\n return props.showShippingCosts !== undefined ? props.showShippingCosts : true;\n});\nconst showVATs = computed(() => {\n return props.showVATs !== undefined ? props.showVATs : true;\n});\nconst showTotalExclVat = computed(() => {\n return props.showTotalExclVat !== undefined ? props.showTotalExclVat : true;\n});\nconst showTotalVat = computed(() => {\n return props.showTotalVat !== undefined ? props.showTotalVat : true;\n});\nconst showCheckoutButton = computed(() => {\n return props.showCheckoutButton !== undefined ? props.showCheckoutButton : true;\n});\nconst subtotal = computed(() => {\n return props.cart?.total?.subTotal || 0;\n});\nconst hasDiscount = computed(() => {\n const total = props.cart?.total;\n return (total?.discount || 0) > 0;\n});\nconst discountAmount = computed(() => {\n return props.cart?.total?.discount || 0;\n});\nconst hasShippingCosts = computed(() => {\n return (props.cart?.postageData?.price || 0) > 0;\n});\nconst shippingCosts = computed(() => {\n return Number(props.cart?.postageData?.price || 0);\n});\nconst totalExclVat = computed(() => {\n return props.cart?.total?.totalGross || 0;\n});\nconst taxLevels = computed(() => {\n const levels = props.cart?.taxLevels || [];\n return levels.filter((t) => t.taxPercentage > 0 && t.price > 0);\n});\nconst totalVat = computed(() => {\n const net = props.cart?.total?.totalNet || 0;\n const gross = props.cart?.total?.totalGross || 0;\n return net - gross;\n});\nconst totalInclVat = computed(() => {\n return props.cart?.total?.totalNet || 0;\n});\n// Compute inline against props.cart instead of useCart.checkoutAllowed:\n// useCart's `cart` ref is internal to the composable instance and stays null\n// when CartSummary just consumes the computed (we never call addItem/resolveCart\n// here). That made checkoutAllowed always return true in CartView, putting the\n// \"Continue to Checkout\" button up even when the user was over their auth limit.\n// Uses the same field-tolerant lookup as CartIconAndSidebar so the cart page\n// and the header sidebar always agree.\nconst showRequestAuthorizationButton = computed(() => {\n const u = infra.user as any;\n if (!u || !('contactId' in u)) return false;\n if (!infra.companyId) return false;\n if (!props.cart) return false;\n const pacData = u.purchaseAuthorizationConfigs ?? u._purchaseAuthorizationConfigs;\n const items: any[] = pacData?.items ?? pacData?._items ?? [];\n const purchaserPac = items.find((pac: any) => {\n const role = pac.purchaseRole ?? pac._purchaseRole;\n const pacCompanyId =\n pac.company?.companyId\n ?? pac.company?._companyId\n ?? pac._company?.companyId\n ?? pac._company?._companyId;\n return role === PurchaseRole.PURCHASER && pacCompanyId === infra.companyId;\n });\n if (!purchaserPac) return false;\n const limit = (purchaserPac as any).authorizationLimit ?? (purchaserPac as any)._authorizationLimit ?? 0;\n const totalGross = (props.cart as any)?.total?.totalGross ?? (props.cart as any)?._total?._totalGross ?? 0;\n return totalGross > limit;\n});\n\nfunction getLabel(key: string, fallback: string): ReturnType<CartSummaryState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatItemPrice(price: number): ReturnType<CartSummaryState['formatItemPrice']> {\n if (props.formatPrice) {\n return props.formatPrice(price);\n }\n return _formatPrice(price || 0, { symbol: infra.currency ?? '€' });\n}\nfunction handleCheckoutClick(): ReturnType<CartSummaryState['handleCheckoutClick']> {\n if (props.onCheckoutButtonClick) {\n props.onCheckoutButtonClick(props.cart);\n }\n}\nasync function handleRequestAuthorizationClick(): ReturnType<\n CartSummaryState['handleRequestAuthorizationClick']\n> {\n requestLoading.value = true;\n try {\n if (props.onRequestAuthorization) {\n props.onRequestAuthorization(props.cart);\n props.afterRequestAuthorization?.(props.cart);\n } else {\n const result = await requestAuthorization();\n // Only proceed to the \"request sent\" flow (clear cart + navigate) when the\n // mutation actually succeeded. Throwing here routes the failure to onError\n // below instead of falsely confirming a request that was never created.\n if (!result.ok) {\n throw new Error(result.error || 'Failed to request authorization');\n }\n props.afterRequestAuthorization?.(props.cart);\n }\n } catch (err: any) {\n if (props.onError) {\n props.onError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n requestLoading.value = false;\n }\n}\n</script>\n","<template>\n <template v-if=\"!!html\">\n <div\n :class=\"`propeller-category-description mb-6 ${className || ''}`\"\n :data-expanded=\"expanded ? 'true' : 'false'\"\n :data-truncatable=\"shouldTruncate() ? 'true' : 'false'\"\n >\n <template v-if=\"!shouldTruncate() || expanded\">\n <div\n class=\"propeller-category-description__content prose prose-slate max-w-none text-muted-foreground\"\n v-html=\"html\"\n ></div>\n </template>\n\n <template v-if=\"shouldTruncate() && !expanded\">\n <p class=\"propeller-category-description__truncated text-muted-foreground\">{{ getTruncated() }}</p>\n </template>\n\n <template v-if=\"shouldTruncate()\">\n <button\n class=\"propeller-category-description__toggle mt-2 text-sm font-medium text-primary hover:underline\"\n @click=\"async (event) => toggle()\"\n >\n <template v-if=\"expanded\"> Read less </template>\n\n <template v-if=\"!expanded\"> Read more </template>\n </button>\n </template>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\n\nimport type { Category } from '@propeller-commerce/propeller-sdk-v2';\nimport { getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface CategoryDescriptionProps {\n // ── Required ────────────────────────────────────────────────────────────\n\n /**\n * Language code used to resolve the correct localised description\n * from `category.description`.\n */\n language: string;\n\n // ── Optional ────────────────────────────────────────────────────────────\n\n /**\n * Propeller Category object.\n * The component reads `category.description` (an array of LocalizedString)\n * and renders the matching language entry as HTML.\n */\n category?: Category | null;\n\n /**\n * When `true` (default), the description is truncated to `maxLength`\n * characters and a \"Read more\" / \"Read less\" toggle is shown.\n */\n collapsed?: boolean;\n\n /**\n * Maximum number of characters to display before truncating.\n * Only applies when `collapsed` is `true`.\n * Defaults to 200.\n */\n maxLength?: number;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\ninterface CategoryDescriptionState {\n expanded: boolean;\n /** Cached resolved HTML — updated via onUpdate whenever category/language changes. */\n html: string;\n getDescription(): string;\n getMaxLen(): number;\n shouldTruncate(): boolean;\n getTruncated(): string;\n toggle(): void;\n}\n\nconst props = defineProps<CategoryDescriptionProps>();\nconst infra = useInfraProps(props);\nconst expanded = ref<CategoryDescriptionState['expanded']>(false);\nconst html = ref<CategoryDescriptionState['html']>('');\n\nwatch(\n () => [props.category, infra.language],\n () => {\n html.value = getDescription();\n },\n { immediate: true }\n);\nfunction getDescription(): ReturnType<CategoryDescriptionState['getDescription']> {\n return getLanguageString(props.category?.description, infra.language || 'NL', '');\n}\nfunction getMaxLen(): ReturnType<CategoryDescriptionState['getMaxLen']> {\n return props.maxLength || 200;\n}\nfunction shouldTruncate(): ReturnType<CategoryDescriptionState['shouldTruncate']> {\n if (props.collapsed === false) return false;\n return html.value.length > getMaxLen();\n}\nfunction getTruncated(): ReturnType<CategoryDescriptionState['getTruncated']> {\n const plain = html.value.replace(/<[^>]*>/g, '');\n if (plain.length <= getMaxLen()) return html.value;\n const truncated = plain.substring(0, getMaxLen());\n return truncated.substring(0, truncated.lastIndexOf(' ')) + '…';\n}\nfunction toggle(): ReturnType<CategoryDescriptionState['toggle']> {\n expanded.value = !expanded.value;\n}\n</script>\n","<!-- src/components/defaults/DefaultProductImage.vue -->\n<template>\n <img\n v-if=\"url\"\n :src=\"url\"\n :alt=\"altText\"\n :class=\"className ?? 'h-full w-full object-contain'\"\n loading=\"lazy\"\n />\n <div\n v-else\n :class=\"className ?? 'propeller-default-image-placeholder flex items-center justify-center bg-surface-hover'\"\n aria-hidden=\"true\"\n >\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" class=\"h-12 w-12 text-foreground-subtle\">\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n :stroke-width=\"1\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport type { ImageComponentProps } from '@propeller-commerce/propeller-v2-core-ui';\n\n/**\n * Default product / cluster image renderer for the extension API.\n *\n * Vue mirror of React's DefaultProductImage. Picks the best image URL for the\n * consumer's language with a 4-step fallback chain:\n * 1. imageVariant matching target language\n * 2. originalUrl matching target language\n * 3. any imageVariant URL (any language)\n * 4. any originalUrl (any language)\n * Falls back to a placeholder SVG when no URL resolves.\n */\n\ninterface LocalizedImage {\n language?: string;\n originalUrl?: string;\n}\ninterface ImageVariant {\n language?: string;\n url?: string;\n name?: string;\n}\ninterface MediaItem {\n images?: LocalizedImage[];\n imageVariants?: ImageVariant[];\n}\n\nconst props = defineProps<ImageComponentProps>();\n\nfunction pickImageUrl(mediaItems: MediaItem[], target: string): string | null {\n if (!mediaItems || mediaItems.length === 0) return null;\n for (const m of mediaItems) {\n const match = m.imageVariants?.find((v) => v.language === target && v.url);\n if (match?.url) return match.url;\n }\n for (const m of mediaItems) {\n const match = m.images?.find((i) => i.language === target && i.originalUrl);\n if (match?.originalUrl) return match.originalUrl;\n }\n for (const m of mediaItems) {\n const first = m.imageVariants?.find((v) => v.url);\n if (first?.url) return first.url;\n }\n for (const m of mediaItems) {\n const first = m.images?.find((i) => i.originalUrl);\n if (first?.originalUrl) return first.originalUrl;\n }\n return null;\n}\n\nconst targetLanguage = computed(() => props.language ?? 'NL');\n\nconst mediaItems = computed<MediaItem[]>(() => {\n const target =\n props.product ??\n (props.cluster as { defaultProduct?: unknown } | undefined)?.defaultProduct ??\n props.cluster;\n return (\n (target as { media?: { images?: { items?: unknown[] } } } | undefined)?.media?.images?.items ?? []\n ) as MediaItem[];\n});\n\nconst url = computed(() => pickImageUrl(mediaItems.value, targetLanguage.value));\n\nconst altText = computed(() => {\n const target = props.product ?? props.cluster;\n if (!target) return '';\n const name = (target as { name?: unknown }).name;\n if (Array.isArray(name)) {\n return getLanguageString(name as never, targetLanguage.value, '') ?? '';\n }\n return typeof name === 'string' ? name : '';\n});\n\nconst className = computed(() => props.className);\n</script>\n","<template>\n <div v-if=\"labels.length > 0\" :class=\"className ?? 'pointer-events-none absolute left-2 top-2 flex flex-col gap-1'\">\n <span\n v-for=\"label in labels\"\n :key=\"label\"\n class=\"inline-block rounded bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground shadow-sm\"\n >\n {{ label }}\n </span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { collectAttributeValues } from '@propeller-commerce/propeller-v2-core-ui';\nimport type { BadgesComponentProps } from '@propeller-commerce/propeller-v2-core-ui';\n\nconst props = defineProps<BadgesComponentProps>();\n\nconst labels = computed(() => {\n const target = props.product ?? props.cluster;\n if (!target) return [] as string[];\n const attributes = (target as { attributes?: unknown[] }).attributes ?? [];\n return collectAttributeValues(attributes as never, 'imageLabel') ?? [];\n});\n\nconst className = computed(() => props.className);\n</script>\n","<template>\n <div\n :class=\"`propeller-cluster-card group relative flex h-full overflow-hidden rounded-[var(--radius-container)] border border-border bg-card shadow-sm transition-all duration-200 hover:shadow-md hover:border-secondary/20 ${\n isRow() ? 'flex-row flex-wrap md:flex-nowrap items-center' : 'flex-col'\n } ${className || ''}`\"\n :data-layout=\"isRow() ? 'row' : 'grid'\"\n >\n <template v-if=\"showImage !== false\">\n <!-- Injected imageComponent takes over the full image area\n (no auto-rendered badges/favorite around it). -->\n <component\n v-if=\"props.imageComponent\"\n :is=\"ImageImpl\"\n :cluster=\"cluster\"\n :language=\"language\"\n :image-search-filters=\"configuration?.imageSearchFiltersGrid\"\n :image-variant-filters=\"configuration?.imageVariantFiltersMedium\"\n :class=\"`propeller-cluster-card__media relative overflow-hidden bg-surface-hover ${\n isRow()\n ? 'w-20 h-20 flex-shrink-0 p-2'\n : 'aspect-[4/3] sm:aspect-square p-2 sm:p-4'\n }`\"\n />\n <!-- Default image area; consumer can override via #image slot.\n Slot default still renders the badges/favorite injection/slot blocks. -->\n <slot\n v-else\n name=\"image\"\n :cluster=\"cluster\"\n :language=\"language\"\n :imageUrl=\"getClusterImageUrl()\"\n :imageSearchFilters=\"configuration?.imageSearchFiltersGrid\"\n :imageVariantFilters=\"configuration?.imageVariantFiltersMedium\"\n :onNavigate=\"handleClusterClick\"\n >\n <div\n :class=\"`propeller-cluster-card__media relative overflow-hidden bg-surface-hover ${\n isRow()\n ? 'w-20 h-20 flex-shrink-0 p-2'\n : 'aspect-[4/3] sm:aspect-square p-2 sm:p-4'\n }`\"\n >\n <a\n class=\"block h-full w-full\"\n :href=\"getClusterUrl()\"\n @click=\"async (e) => handleClusterClick(e)\"\n >\n <template v-if=\"!!getClusterImageUrl()\">\n <img\n class=\"propeller-cluster-card__image h-full w-full object-contain transition-transform duration-300 group-hover:scale-105\"\n :src=\"getClusterImageUrl()\"\n :alt=\"getClusterName()\"\n />\n </template>\n\n <template v-if=\"!getClusterImageUrl()\">\n <div\n class=\"propeller-cluster-card__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-16 w-16\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n :strokeWidth=\"1\"\n ></path>\n </svg>\n </div>\n </template>\n </a>\n <!-- Injected badgesComponent takes precedence; otherwise #badges slot\n (default content is the inline badges block). -->\n <component\n v-if=\"props.badgesComponent\"\n :is=\"BadgesImpl\"\n :cluster=\"cluster\"\n :labels=\"labels\"\n />\n <slot\n v-else-if=\"\n !!imageLabels &&\n imageLabels.length > 0 &&\n computedImageLabels().length > 0\n \"\n name=\"badges\"\n :cluster=\"cluster\"\n :imageLabels=\"computedImageLabels()\"\n :labels=\"labels\"\n >\n <div\n class=\"propeller-cluster-card__badges pointer-events-none absolute left-2 top-2 flex flex-col gap-1\"\n >\n <template\n :key=\"index\"\n v-for=\"(label, index) in computedImageLabels()\"\n >\n <span\n class=\"propeller-cluster-card__badge inline-block rounded bg-secondary px-2 py-0.5 text-xs font-medium text-primary-foreground shadow-sm\"\n >{{ label }}</span\n >\n </template>\n </div>\n </slot>\n\n <!-- Injected favoriteComponent takes precedence; otherwise #favorite slot\n (default content is the inline heart button). -->\n <component\n v-if=\"props.favoriteComponent && enableAddFavorite\"\n :is=\"FavoriteImpl\"\n :cluster=\"cluster\"\n :on-toggle-favorite=\"onToggleFavorite\"\n :labels=\"labels\"\n />\n <slot\n v-else-if=\"enableAddFavorite\"\n name=\"favorite\"\n :cluster=\"cluster\"\n :isFavorite=\"isFavorite\"\n :toggle=\"handleToggleFavorite\"\n :labels=\"labels\"\n >\n <button\n type=\"button\"\n @click=\"async (e) => handleToggleFavorite(e)\"\n :aria-label=\"\n isFavorite\n ? getLabel('removeFromFavorites', 'Remove from favourites')\n : getLabel('addToFavorites', 'Add to favourites')\n \"\n :data-favorite=\"isFavorite ? 'true' : 'false'\"\n :class=\"`propeller-cluster-card__favorite-btn absolute right-2 top-2 rounded-full border bg-card p-1.5 shadow-sm transition-colors ${\n isFavorite\n ? 'border-destructive text-destructive'\n : 'border-border-subtle text-foreground-subtle hover:text-destructive'\n }`\"\n >\n <svg\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n :fill=\"isFavorite ? 'currentColor' : 'none'\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z\"\n ></path>\n </svg>\n </button>\n </slot>\n </div>\n </slot>\n </template>\n\n <template v-if=\"isRow()\">\n <div\n class=\"propeller-cluster-card__body flex flex-1 flex-row items-center gap-4 px-4 py-2 min-w-0\"\n >\n <div class=\"flex flex-col gap-0.5 flex-1 min-w-0\">\n <slot\n v-if=\"showSku !== false && !!getClusterSku()\"\n name=\"sku\"\n :cluster=\"cluster\"\n :sku=\"getClusterSku()\"\n >\n <div\n class=\"propeller-cluster-card__sku font-mono text-xs text-foreground-subtle\"\n >\n {{ getClusterSku() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showName !== false\"\n name=\"name\"\n :cluster=\"cluster\"\n :clusterUrl=\"getClusterUrl()\"\n :handleClusterClick=\"handleClusterClick\"\n :linkable=\"true\"\n :name=\"getClusterName()\"\n >\n <a\n class=\"propeller-cluster-card__title text-sm font-medium leading-tight text-foreground transition-colors hover:text-primary line-clamp-1\"\n :href=\"getClusterUrl()\"\n @click=\"async (e) => handleClusterClick(e)\"\n >{{ getClusterName() }}</a\n >\n </slot>\n\n <slot\n v-if=\"\n !!textLabels &&\n textLabels.length > 0 &&\n computedTextLabels().length > 0\n \"\n name=\"textLabels\"\n :cluster=\"cluster\"\n :values=\"computedTextLabels()\"\n >\n <div class=\"flex flex-col gap-0.5\">\n <template\n :key=\"index\"\n v-for=\"(item, index) in computedTextLabels()\"\n >\n <div\n class=\"propeller-cluster-card__label text-xs text-muted-foreground\"\n >\n {{ item.value }}\n </div>\n </template>\n </div>\n </slot>\n\n <slot\n v-if=\"showManufacturer && !!getClusterManufacturer()\"\n name=\"manufacturer\"\n :cluster=\"cluster\"\n :manufacturer=\"getClusterManufacturer()\"\n >\n <div\n class=\"propeller-cluster-card__manufacturer text-xs text-muted-foreground\"\n >\n {{ getClusterManufacturer() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showShortDescription && !!getClusterShortDescription()\"\n name=\"shortDescription\"\n :cluster=\"cluster\"\n :text=\"getClusterShortDescription()\"\n >\n <p\n class=\"propeller-cluster-card__description line-clamp-2 text-xs text-muted-foreground\"\n >\n {{ getClusterShortDescription() }}\n </p>\n </slot>\n </div>\n </div>\n <div\n class=\"propeller-cluster-card__footer w-full md:w-auto flex items-center gap-3 px-4 py-2 md:py-0 border-t md:border-t-0 border-border-subtle\"\n >\n <slot\n v-if=\"showStock && !!cluster.defaultProduct?.inventory\"\n name=\"stock\"\n :cluster=\"cluster\"\n :inventory=\"cluster.defaultProduct?.inventory\"\n :showAvailability=\"false\"\n :labels=\"stockLabels\"\n >\n <component\n v-if=\"props.stockComponent\"\n :is=\"StockImpl\"\n :inventory=\"cluster.defaultProduct?.inventory\"\n :show-availability=\"false\"\n :show-stock=\"true\"\n :labels=\"stockLabels\"\n />\n <ItemStock\n v-else\n :inventory=\"cluster.defaultProduct?.inventory\"\n :showAvailability=\"false\"\n :showStock=\"true\"\n :labels=\"stockLabels\"\n ></ItemStock>\n </slot>\n\n <slot\n v-if=\"!!getClusterPrice()\"\n name=\"price\"\n :cluster=\"cluster\"\n :price=\"cluster.defaultProduct?.price\"\n :includeTax=\"props.includeTax !== undefined ? !!props.includeTax : includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n >\n <component\n v-if=\"props.priceComponent\"\n :is=\"PriceImpl\"\n :price=\"cluster.defaultProduct?.price\"\n :include-tax=\"includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n />\n <span\n v-else\n class=\"propeller-cluster-card__price font-bold text-foreground text-sm whitespace-nowrap\"\n >{{ getClusterPrice() }}</span\n >\n </slot>\n\n <div class=\"propeller-cluster-card__cta flex-shrink-0 ml-auto\">\n <slot\n name=\"viewClusterLink\"\n :cluster=\"cluster\"\n :clusterUrl=\"getClusterUrl()\"\n :handleClusterClick=\"handleClusterClick\"\n :label=\"getLabel('viewCluster', 'View cluster')\"\n >\n <a\n class=\"propeller-cluster-card__cta-link flex w-full items-center justify-center rounded-[var(--radius-control)] bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n :href=\"getClusterUrl()\"\n @click=\"async (e) => handleClusterClick(e)\"\n >{{ getLabel(\"viewCluster\", \"View cluster\") }}</a\n >\n </slot>\n </div>\n </div>\n </template>\n\n <template v-if=\"!isRow()\">\n <div\n class=\"propeller-cluster-card__body flex flex-1 flex-col gap-1.5 p-3 sm:gap-2 sm:p-4\"\n >\n <slot\n v-if=\"showSku !== false && !!getClusterSku()\"\n name=\"sku\"\n :cluster=\"cluster\"\n :sku=\"getClusterSku()\"\n >\n <div\n class=\"propeller-cluster-card__sku font-mono text-xs text-foreground-subtle\"\n >\n {{ getClusterSku() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showName !== false\"\n name=\"name\"\n :cluster=\"cluster\"\n :clusterUrl=\"getClusterUrl()\"\n :handleClusterClick=\"handleClusterClick\"\n :linkable=\"true\"\n :name=\"getClusterName()\"\n >\n <a\n class=\"propeller-cluster-card__title text-sm font-medium leading-tight text-foreground transition-colors hover:text-primary line-clamp-2\"\n :href=\"getClusterUrl()\"\n @click=\"async (e) => handleClusterClick(e)\"\n >{{ getClusterName() }}</a\n >\n </slot>\n\n <slot\n v-if=\"showStock && !!cluster.defaultProduct?.inventory\"\n name=\"stock\"\n :cluster=\"cluster\"\n :inventory=\"cluster.defaultProduct?.inventory\"\n :showAvailability=\"showAvailability !== false\"\n :labels=\"stockLabels\"\n >\n <component\n v-if=\"props.stockComponent\"\n :is=\"StockImpl\"\n :inventory=\"cluster.defaultProduct?.inventory\"\n :show-availability=\"showAvailability !== false\"\n :show-stock=\"true\"\n :labels=\"stockLabels\"\n />\n <ItemStock\n v-else\n :inventory=\"cluster.defaultProduct?.inventory\"\n :showAvailability=\"showAvailability !== false\"\n :showStock=\"true\"\n :labels=\"stockLabels\"\n ></ItemStock>\n </slot>\n\n <slot\n v-if=\"\n !!textLabels &&\n textLabels.length > 0 &&\n computedTextLabels().length > 0\n \"\n name=\"textLabels\"\n :cluster=\"cluster\"\n :values=\"computedTextLabels()\"\n >\n <div class=\"propeller-cluster-card__labels flex flex-col gap-0.5\">\n <template\n :key=\"index\"\n v-for=\"(item, index) in computedTextLabels()\"\n >\n <div\n class=\"propeller-cluster-card__label text-xs text-muted-foreground\"\n >\n {{ item.value }}\n </div>\n </template>\n </div>\n </slot>\n\n <slot\n v-if=\"showManufacturer && !!getClusterManufacturer()\"\n name=\"manufacturer\"\n :cluster=\"cluster\"\n :manufacturer=\"getClusterManufacturer()\"\n >\n <div\n class=\"propeller-cluster-card__manufacturer text-xs text-muted-foreground\"\n >\n {{ getClusterManufacturer() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showShortDescription && !!getClusterShortDescription()\"\n name=\"shortDescription\"\n :cluster=\"cluster\"\n :text=\"getClusterShortDescription()\"\n >\n <p\n class=\"propeller-cluster-card__description line-clamp-2 text-xs text-muted-foreground\"\n >\n {{ getClusterShortDescription() }}\n </p>\n </slot>\n\n <slot\n v-if=\"!!getClusterPrice()\"\n name=\"price\"\n :cluster=\"cluster\"\n :price=\"cluster.defaultProduct?.price\"\n :includeTax=\"props.includeTax !== undefined ? !!props.includeTax : includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n >\n <div class=\"propeller-cluster-card__price mt-auto pt-1\">\n <component\n v-if=\"props.priceComponent\"\n :is=\"PriceImpl\"\n :price=\"cluster.defaultProduct?.price\"\n :include-tax=\"includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n />\n <span v-else class=\"font-bold text-foreground text-base sm:text-lg\">{{\n getClusterPrice()\n }}</span>\n </div>\n </slot>\n </div>\n <div class=\"propeller-cluster-card__cta px-3 pb-3 sm:px-4 sm:pb-4\">\n <slot\n name=\"viewClusterLink\"\n :cluster=\"cluster\"\n :clusterUrl=\"getClusterUrl()\"\n :handleClusterClick=\"handleClusterClick\"\n :label=\"getLabel('viewCluster', 'View cluster')\"\n >\n <a\n class=\"propeller-cluster-card__cta-link flex w-full items-center justify-center rounded-[var(--radius-control)] bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n :href=\"getClusterUrl()\"\n @click=\"async (e) => handleClusterClick(e)\"\n >{{ getLabel(\"viewCluster\", \"View cluster\") }}</a\n >\n </slot>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, type Component } from \"vue\";\n\nimport { Cluster, AttributeResult } from \"@propeller-commerce/propeller-sdk-v2\";\nimport ItemStock from \"./ItemStock.vue\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n getClusterImageUrl as _getClusterImageUrl,\n getClusterSku as _getClusterSku,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useResolvedProps, type ResolveSpec } from '../composables/vue/useResolvedProps';\nimport DefaultProductPrice from './ProductPrice.vue';\nimport DefaultItemStock from './ItemStock.vue';\nimport DefaultAddToFavorite from './AddToFavorite.vue';\nimport DefaultProductImage from './defaults/DefaultProductImage.vue';\nimport DefaultProductBadges from './defaults/DefaultProductBadges.vue';\n\nexport interface ClusterCardProps {\n // === Core ===\n\n /** The cluster object to display */\n cluster: Cluster;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n // === Display toggles ===\n\n /** Show the cluster name. Defaults to true. */\n showName?: boolean;\n\n /** Show the default product image. Defaults to true. */\n showImage?: boolean;\n\n /** Show the cluster short description. Defaults to false. */\n showShortDescription?: boolean;\n\n /**\n * Show the SKU. Displays the cluster SKU; falls back to the default product SKU\n * if the cluster SKU is empty. Defaults to true.\n */\n showSku?: boolean;\n\n /** Show the default product manufacturer. Defaults to false. */\n showManufacturer?: boolean;\n\n /**\n * Show default product stock information (quantity badge).\n * Reads `defaultProduct.inventory.totalQuantity`. Defaults to true.\n */\n showStock?: boolean;\n\n /**\n * Show only the availability indicator (Available / Not available) inside ItemStock.\n * Only relevant when `showStock` is true.\n * Defaults to true.\n */\n showAvailability?: boolean;\n\n /**\n * Show the price below the product name.\n * Defaults to true.\n */\n showPrice?: boolean;\n\n /**\n * Label overrides forwarded to the embedded ItemStock component.\n * Keys: inStock, outOfStock, lowStock, available, notAvailable, pieces\n */\n stockLabels?: Record<string, string>;\n\n // === Attribute labels ===\n\n /**\n * Attribute codes/names to look up on the default product and display as\n * badge overlays on the image. Resolved against\n * `defaultProduct.attributes.items[].attributeDescription.name`.\n * Attributes with no matching value are silently omitted.\n * Example: ['new', 'sale']\n */\n imageLabels?: string[];\n\n /**\n * Attribute codes/names to look up on the default product and display as\n * extra text rows below the cluster name. Resolved the same way as `imageLabels`.\n * Example: ['brand', 'color']\n */\n textLabels?: string[];\n\n // === Favourites ===\n\n /** Renders a heart-icon toggle button on the cluster image. Defaults to false. */\n enableAddFavorite?: boolean;\n\n /**\n * Called whenever the favourite state is toggled.\n * The second argument indicates the new state: `true` = added, `false` = removed.\n */\n onToggleFavorite?: (cluster: Cluster, isFavorite: boolean) => void;\n\n // === Navigation ===\n\n /**\n * Called when the cluster name, image, or \"View cluster\" button is clicked.\n * When provided, the default `<a>` navigation is prevented so the consumer\n * can use framework-specific routing (e.g. Next.js `router.push`).\n */\n onClusterClick?: (cluster: Cluster) => void;\n\n // === UI string overrides ===\n\n /**\n * Override any UI string.\n * Available keys: addToFavorites, removeFromFavorites, viewCluster,\n * inStock, lowStock, outOfStock\n */\n labels?: Record<string, string>;\n\n /** Number of grid columns — when 1 the card renders as a compact horizontal row. */\n columns?: number;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /** Configuration object passed to the component */\n configuration?: any;\n\n /** Include tax in the price display */\n includeTax?: boolean;\n\n /** Language code used to resolve localised names and slugs. Defaults to 'NL'. */\n language?: string;\n\n // ───── Extension API ─────\n // Per-card overrides for sub-components.\n // (No addToCartComponent — ClusterCard does not render AddToCart by default.)\n priceComponent?: Component;\n stockComponent?: Component;\n imageComponent?: Component;\n badgesComponent?: Component;\n favoriteComponent?: Component;\n}\ninterface ClusterCardState {\n isFavorite: boolean;\n includeTax: boolean;\n priceListener: any;\n isRow: () => boolean;\n getClusterName: () => string;\n getClusterSku: () => string;\n getClusterImageUrl: () => string;\n getClusterUrl: () => string;\n getClusterShortDescription: () => string;\n getClusterManufacturer: () => string;\n getStockQuantity: () => number;\n getStockStatusLabel: () => string;\n getStockStatusClass: () => string;\n getClusterPrice: () => string;\n getLabel: (key: string, fallback: string) => string;\n handleClusterClick: (e: any) => void;\n handleToggleFavorite: (e: any) => void;\n computedImageLabels: () => string[];\n computedTextLabels: () => {\n name: string;\n value: string;\n }[];\n}\n\nconst props = withDefaults(defineProps<ClusterCardProps>(), {\n showImage: true,\n showName: true,\n showSku: true,\n showPrice: true,\n showAvailability: true,\n showShortDescription: false,\n showManufacturer: false,\n showStock: false,\n enableAddFavorite: false,\n});\n\n// ───── Extension API ─────\n// Resolve sub-component slots from explicit props → ProductGrid context.\nconst RESOLVE_SPEC: ResolveSpec<ClusterCardProps> = {\n priceComponent: { grid: 'priceComponent' },\n stockComponent: { grid: 'stockComponent' },\n imageComponent: { grid: 'imageComponent' },\n badgesComponent: { grid: 'badgesComponent' },\n favoriteComponent: { grid: 'favoriteComponent' },\n};\n\nconst resolved = computed(() => useResolvedProps(props, RESOLVE_SPEC));\n\nconst PriceImpl = computed(() => resolved.value.priceComponent ?? DefaultProductPrice);\nconst StockImpl = computed(() => resolved.value.stockComponent ?? DefaultItemStock);\nconst ImageImpl = computed(() => resolved.value.imageComponent ?? DefaultProductImage);\nconst BadgesImpl = computed(() => resolved.value.badgesComponent ?? DefaultProductBadges);\nconst FavoriteImpl = computed(() => resolved.value.favoriteComponent ?? DefaultAddToFavorite);\n\nconst isFavorite = ref<ClusterCardState[\"isFavorite\"]>(false);\nconst includeTax = ref<ClusterCardState[\"includeTax\"]>(false);\nconst priceListener = ref<ClusterCardState[\"priceListener\"]>(null);\n\nfunction isRow(): ReturnType<ClusterCardState[\"isRow\"]> {\n return (props.columns as number) === 1;\n}\nfunction getClusterName(): ReturnType<ClusterCardState[\"getClusterName\"]> {\n const lang = (props.language as string) || \"NL\";\n const clusterName = getLanguageString(\n (props.cluster as Cluster)?.names,\n lang,\n \"\",\n );\n if (clusterName) return clusterName;\n return getLanguageString(\n (props.cluster as Cluster)?.defaultProduct?.names,\n lang,\n \"Cluster\",\n );\n}\nfunction getClusterSku(): ReturnType<ClusterCardState[\"getClusterSku\"]> {\n return _getClusterSku(props.cluster as Cluster);\n}\nfunction getClusterImageUrl(): ReturnType<\n ClusterCardState[\"getClusterImageUrl\"]\n> {\n return _getClusterImageUrl(props.cluster as Cluster);\n}\nfunction getClusterUrl(): ReturnType<ClusterCardState[\"getClusterUrl\"]> {\n return props.configuration?.urls?.getClusterUrl(props.cluster, props.language) ?? \"#\";\n}\nfunction getClusterShortDescription(): ReturnType<\n ClusterCardState[\"getClusterShortDescription\"]\n> {\n const lang = (props.language as string) || \"NL\";\n const desc = getLanguageString(\n (props.cluster as Cluster)?.shortDescriptions,\n lang,\n \"\",\n );\n if (desc) return desc;\n return getLanguageString(\n (props.cluster as Cluster)?.defaultProduct?.shortDescriptions,\n lang,\n \"\",\n );\n}\nfunction getClusterManufacturer(): ReturnType<\n ClusterCardState[\"getClusterManufacturer\"]\n> {\n return (props.cluster as Cluster)?.defaultProduct?.manufacturer || \"\";\n}\nfunction getStockQuantity(): ReturnType<ClusterCardState[\"getStockQuantity\"]> {\n const qty = (props.cluster as Cluster)?.defaultProduct?.inventory\n ?.totalQuantity;\n return qty !== undefined && qty !== null ? qty : -1;\n}\nfunction getStockStatusLabel(): ReturnType<\n ClusterCardState[\"getStockStatusLabel\"]\n> {\n const qty = getStockQuantity();\n if (qty < 0) return \"\";\n if (qty === 0) return getLabel(\"outOfStock\", \"Out of stock\");\n if (qty <= 5) return getLabel(\"lowStock\", \"Low stock\");\n return getLabel(\"inStock\", \"In stock\");\n}\nfunction getStockStatusClass(): ReturnType<\n ClusterCardState[\"getStockStatusClass\"]\n> {\n const qty = getStockQuantity();\n if (qty <= 0) return \"text-destructive bg-destructive/10\";\n if (qty <= 5) return \"text-warning bg-warning/10\";\n return \"text-success bg-success/10\";\n}\nfunction getClusterPrice(): ReturnType<ClusterCardState[\"getClusterPrice\"]> {\n if (!props.showPrice) return \"\";\n const priceObj = (props.cluster as Cluster)?.defaultProduct?.price;\n const useTax: boolean =\n props.includeTax !== undefined\n ? !!props.includeTax\n : includeTax.value;\n const value: number | undefined = useTax ? priceObj?.net : priceObj?.gross;\n if (!value && value !== 0) return \"\";\n return _formatPrice(Number(value), { symbol: props.currency ?? \"€\" });\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<ClusterCardState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction handleClusterClick(\n e: any,\n): ReturnType<ClusterCardState[\"handleClusterClick\"]> {\n if (props.onClusterClick) {\n e.preventDefault();\n props.onClusterClick(props.cluster);\n }\n}\nfunction handleToggleFavorite(\n e: any,\n): ReturnType<ClusterCardState[\"handleToggleFavorite\"]> {\n e.preventDefault();\n e.stopPropagation();\n isFavorite.value = !isFavorite.value;\n if (props.onToggleFavorite) {\n props.onToggleFavorite(props.cluster, isFavorite.value);\n }\n}\nfunction computedImageLabels(): ReturnType<\n ClusterCardState[\"computedImageLabels\"]\n> {\n if (!props.imageLabels || (props.imageLabels as string[]).length === 0)\n return [];\n const attrs =\n (props.cluster as Cluster)?.defaultProduct?.attributes?.items || [];\n return (props.imageLabels as string[])\n .map((code: string) => {\n const found = attrs.find(\n (a: AttributeResult) => a.attributeDescription?.name === code,\n );\n return found?.value?.value || \"\";\n })\n .filter((v: string) => v.length > 0);\n}\nfunction computedTextLabels(): ReturnType<\n ClusterCardState[\"computedTextLabels\"]\n> {\n if (!props.textLabels || (props.textLabels as string[]).length === 0)\n return [];\n const attrs =\n (props.cluster as Cluster)?.defaultProduct?.attributes?.items || [];\n return (props.textLabels as string[])\n .map((code: string) => {\n const found = attrs.find(\n (a: AttributeResult) => a.attributeDescription?.name === code,\n );\n return {\n name: code,\n value: found?.value?.value || \"\",\n };\n })\n .filter((item: { name: string; value: string }) => item.value.length > 0);\n}\n</script>\n","<template>\n <div :class=\"`propeller-cluster-configurator ${className || ''}`\">\n <template v-if=\"!!config?.settings?.length\">\n <div class=\"propeller-cluster-configurator__content flex flex-col gap-6\">\n <template\n :key=\"setting.id\"\n v-for=\"(setting, index) in getSettingsWithValues()\"\n >\n <div\n class=\"propeller-cluster-configurator__group\"\n :data-display-type=\"setting.displayType\"\n :data-disabled=\"setting.disabled ? 'true' : 'false'\"\n >\n <h4\n class=\"propeller-cluster-configurator__label font-semibold text-sm text-muted-foreground mb-3\"\n >\n {{ setting.displayName || setting.name }}\n </h4>\n <template v-if=\"setting.displayType === 'DROPDOWN'\">\n <select\n class=\"propeller-cluster-configurator__select w-full border border-border rounded-[var(--radius-container)] px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-secondary disabled:bg-surface-hover disabled:text-foreground-subtle cursor-pointer\"\n :value=\"setting.selectedValue\"\n :disabled=\"setting.disabled\"\n @change=\"\n async (e) =>\n handleAttributeSelect(\n setting.name,\n (e.target as HTMLSelectElement).value,\n )\n \"\n >\n <option value=\"\">\n {{ getLabel(\"selectOption\", \"— Select —\") }}\n </option>\n <template\n :key=\"val\"\n v-for=\"(val, index) in setting.availableValues\"\n >\n <option :value=\"val\">{{ val }}</option>\n </template>\n </select>\n </template>\n\n <template v-if=\"setting.displayType === 'RADIO'\">\n <div\n class=\"propeller-cluster-configurator__options flex flex-wrap gap-2\"\n >\n <template\n :key=\"val\"\n v-for=\"(val, index) in setting.availableValues\"\n >\n <label\n :data-selected=\"\n setting.selectedValue === val ? 'true' : 'false'\n \"\n :class=\"`propeller-cluster-configurator__radio flex items-center gap-2 px-3 py-1.5 rounded-[var(--radius-container)] border text-sm font-medium transition-colors select-none ${\n setting.disabled\n ? 'opacity-50 cursor-not-allowed border-border text-foreground-subtle'\n : setting.selectedValue === val\n ? 'border-secondary bg-secondary/5 text-secondary cursor-pointer'\n : 'border-border text-muted-foreground hover:border-secondary/30 cursor-pointer'\n }`\"\n ><input\n type=\"radio\"\n class=\"sr-only\"\n :name=\"`cluster-${clusterId}-${setting.name}`\"\n :value=\"val\"\n :checked=\"setting.selectedValue === val\"\n :disabled=\"setting.disabled\"\n @change=\"\n async (event) =>\n handleAttributeSelect(setting.name, val)\n \"\n />{{ val }}</label\n >\n </template>\n </div>\n </template>\n\n <!-- Only render colour swatches when the underlying attribute is\n actually typed COLOR. PIMs sometimes pair `displayType: 'COLOR'`\n with a TEXT attribute (colour-name strings, free text…) — in\n that case fall back to labelled chips so the value is readable. -->\n <template v-if=\"setting.displayType === 'COLOR' && setting.attributeType === 'COLOR'\">\n <div\n class=\"propeller-cluster-configurator__options flex flex-wrap gap-2\"\n >\n <template\n :key=\"val\"\n v-for=\"(val, index) in setting.availableValues\"\n >\n <button\n type=\"button\"\n :title=\"val\"\n :disabled=\"setting.disabled\"\n @click=\"\n async (event) => handleAttributeSelect(setting.name, val)\n \"\n :data-selected=\"\n setting.selectedValue === val ? 'true' : 'false'\n \"\n :style=\"{\n backgroundColor: val,\n }\"\n :class=\"`propeller-cluster-configurator__color w-8 h-8 rounded-full border-2 transition-all ${\n setting.disabled\n ? 'opacity-50 cursor-not-allowed'\n : 'cursor-pointer'\n } ${\n setting.selectedValue === val\n ? 'border-secondary ring-2 ring-secondary/30 ring-offset-1 scale-110'\n : 'border-input hover:scale-105'\n }`\"\n ></button>\n </template>\n </div>\n </template>\n\n <template v-if=\"setting.displayType === 'COLOR' && setting.attributeType !== 'COLOR'\">\n <div\n class=\"propeller-cluster-configurator__options flex flex-wrap gap-2\"\n >\n <template\n :key=\"val\"\n v-for=\"(val, index) in setting.availableValues\"\n >\n <button\n type=\"button\"\n :disabled=\"setting.disabled\"\n @click=\"\n async (event) => handleAttributeSelect(setting.name, val)\n \"\n :data-selected=\"\n setting.selectedValue === val ? 'true' : 'false'\n \"\n :class=\"`propeller-cluster-configurator__chip px-3 py-1.5 rounded-[var(--radius-container)] border text-sm font-medium transition-colors ${\n setting.disabled\n ? 'opacity-50 cursor-not-allowed border-border text-foreground-subtle'\n : setting.selectedValue === val\n ? 'border-secondary bg-secondary/5 text-secondary cursor-pointer'\n : 'border-border text-muted-foreground hover:border-secondary/30 cursor-pointer'\n }`\"\n >\n {{ val }}\n </button>\n </template>\n </div>\n </template>\n\n <template v-if=\"setting.displayType === 'IMAGE'\">\n <div\n class=\"propeller-cluster-configurator__options flex flex-wrap gap-3\"\n >\n <template\n :key=\"val\"\n v-for=\"(val, index) in setting.availableValues\"\n >\n <button\n type=\"button\"\n :disabled=\"setting.disabled\"\n @click=\"\n async (event) => handleAttributeSelect(setting.name, val)\n \"\n :data-selected=\"\n setting.selectedValue === val ? 'true' : 'false'\n \"\n :class=\"`propeller-cluster-configurator__image-swatch relative w-16 h-16 rounded-[var(--radius-container)] border-2 overflow-hidden transition-all ${\n setting.disabled\n ? 'opacity-50 cursor-not-allowed'\n : 'cursor-pointer'\n } ${\n setting.selectedValue === val\n ? 'border-secondary ring-2 ring-secondary/30 ring-offset-1'\n : 'border-border hover:border-secondary/30'\n }`\"\n >\n <img\n class=\"propeller-cluster-configurator__image w-full h-full object-cover\"\n :src=\"val\"\n :alt=\"val\"\n />\n <template v-if=\"setting.selectedValue === val\">\n <div\n class=\"propeller-cluster-configurator__image-check absolute inset-0 bg-secondary bg-opacity-20 flex items-center justify-center\"\n >\n <svg\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n class=\"w-5 h-5 text-secondary\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\"\n clipRule=\"evenodd\"\n ></path>\n </svg>\n </div>\n </template>\n </button>\n </template>\n </div>\n </template>\n\n <template\n v-if=\"\n setting.displayType !== 'DROPDOWN' &&\n setting.displayType !== 'RADIO' &&\n setting.displayType !== 'COLOR' &&\n setting.displayType !== 'IMAGE'\n \"\n >\n <div\n class=\"propeller-cluster-configurator__options flex flex-wrap gap-2\"\n >\n <template\n :key=\"val\"\n v-for=\"(val, index) in setting.availableValues\"\n >\n <button\n type=\"button\"\n :disabled=\"setting.disabled\"\n @click=\"\n async (event) => handleAttributeSelect(setting.name, val)\n \"\n :data-selected=\"\n setting.selectedValue === val ? 'true' : 'false'\n \"\n :class=\"`propeller-cluster-configurator__chip px-3 py-1.5 rounded-[var(--radius-container)] border text-sm font-medium transition-colors ${\n setting.disabled\n ? 'opacity-50 cursor-not-allowed border-border text-foreground-subtle'\n : setting.selectedValue === val\n ? 'border-secondary bg-secondary/5 text-secondary cursor-pointer'\n : 'border-border text-muted-foreground hover:border-secondary/30 cursor-pointer'\n }`\"\n >\n {{ val }}\n </button>\n </template>\n </div>\n </template>\n </div>\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, ref } from \"vue\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { AttributeResult, AttributeType, ClusterConfig, ClusterConfigSetting, Product } from \"@propeller-commerce/propeller-sdk-v2\";\n\n\n/**\n * A computed object containing a cluster config setting enriched with\n * its current UI state: available values for drilldown, the currently\n * selected value, and whether the selector should be disabled.\n */\ninterface ConfiguredSetting {\n id: number;\n name: string;\n /** String representation of ClusterConfigSettingDisplayType */\n displayType: string;\n /**\n * Underlying attribute type from the PIM (e.g. `COLOR`, `TEXT`). Source of\n * truth for swatch rendering — `displayType: 'COLOR'` is sometimes set on\n * settings whose attribute holds plain text.\n */\n attributeType?: string;\n priority: string;\n displayName: string;\n availableValues: string[];\n selectedValue: string;\n disabled: boolean;\n}\n/**\n * A computed object containing a cluster config setting enriched with\n * its current UI state: available values for drilldown, the currently\n * selected value, and whether the selector should be disabled.\n */\n\nexport interface ClusterConfiguratorProps {\n /**\n * The cluster ID this configurator belongs to.\n * @required\n */\n clusterId: number;\n\n /**\n * All products that belong to the cluster.\n * Used to derive available values per attribute and to match\n * the configured product when all selections are made.\n * @required\n */\n products: Product[];\n\n /**\n * Cluster configuration object (cluster.config).\n * Provides the ordered list of attribute settings.\n * @required\n */\n config: ClusterConfig;\n\n /**\n * Fired whenever the user completes a set of attribute selections\n * that uniquely identifies a cluster product.\n * Also fired whenever any selection changes and a matching product\n * can already be determined (e.g. only one setting exists).\n */\n onConfigurationChange?: (product: Product) => void;\n\n /** Default product to pre-populate the attribute selections on mount. */\n defaultProduct?: Product;\n\n /** Override any UI string. Available keys: selectOption */\n labels?: Record<string, string>;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\n/**\n * A computed object containing a cluster config setting enriched with\n * its current UI state: available values for drilldown, the currently\n * selected value, and whether the selector should be disabled.\n */\n\ninterface ClusterConfiguratorState {\n /** Current user selections: { [attributeName]: selectedValue } */\n selectedAttributes: Record<string, string>;\n getLabel: (key: string, fallback: string) => string;\n\n /**\n * Returns the cluster config settings sorted ascending by priority.\n */\n getSortedSettings: () => ClusterConfigSetting[];\n\n /**\n * Checks whether an AttributeResult matches a given target name,\n * looking at the SDK name field and all localised descriptions.\n */\n attributeNameMatches: (attr: AttributeResult, targetName: string) => boolean;\n\n /**\n * Extracts string values from an AttributeResult, supporting both\n * the legacy Propeller SDK format and the current type-based format.\n */\n extractAttributeValues: (attr: AttributeResult) => string[];\n\n /**\n * Returns the localised display name for an attribute by looking up\n * the matching attribute on the first product in the list.\n */\n getAttributeDisplayName: (attributeName: string) => string;\n\n /**\n * Returns all unique values for a given attribute name across all products.\n */\n getAttributeValues: (attributeName: string) => string[];\n\n /**\n * Returns the available values for a given attribute at a specific\n * position in the sorted settings list, filtered by all prior selections\n * (drilldown logic). For the first attribute (index 0) all values are returned.\n */\n getAvailableValuesForIndex: (\n attributeName: string,\n settingIndex: number,\n ) => string[];\n\n /** Same as getAvailableValuesForIndex but uses explicit selections instead of state. */\n getAvailableValuesForIndexWithSelections: (\n attributeName: string,\n settingIndex: number,\n selections: Record<string, string>,\n ) => string[];\n\n /**\n * Computes a derived list of ConfiguredSetting objects ready for rendering,\n * including available values, selected value and disabled state for each setting.\n */\n getSettingsWithValues: () => ConfiguredSetting[];\n\n /**\n * Finds the first product whose attributes match all key/value pairs in\n * the given selections object.\n */\n findMatchingProduct: (selections: Record<string, string>) => Product | null;\n\n /**\n * Handles a selection change for one attribute:\n * - Updates selectedAttributes (sets the new value, clears all subsequent ones).\n * - If all settings now have a selection, finds the matching product and calls\n * props.onConfigurationChange with it.\n */\n handleAttributeSelect: (settingName: string, value: string) => void;\n}\n\nconst props = defineProps<ClusterConfiguratorProps>();\nconst selectedAttributes = ref<ClusterConfiguratorState[\"selectedAttributes\"]>(\n {},\n);\n\nonMounted(() => {\n const defaultProduct = props.defaultProduct as Product;\n if (!defaultProduct) return;\n const sortedSettings = getSortedSettings();\n if (sortedSettings.length === 0) return;\n const initial: Record<string, string> = {};\n sortedSettings.forEach((setting: ClusterConfigSetting) => {\n const attrItems = defaultProduct.attributes?.items;\n if (!Array.isArray(attrItems)) return;\n const matchingAttr = (attrItems as AttributeResult[]).find(\n (attr: AttributeResult) => attributeNameMatches(attr, setting.name),\n );\n if (matchingAttr) {\n const values = extractAttributeValues(matchingAttr);\n if (values.length > 0) {\n initial[setting.name] = values[0];\n }\n }\n });\n if (Object.keys(initial).length === 0) return;\n selectedAttributes.value = initial;\n const allSelected = sortedSettings.every(\n (s: ClusterConfigSetting) => !!initial[s.name],\n );\n if (allSelected && props.onConfigurationChange) {\n const matchingProduct = findMatchingProduct(initial);\n if (matchingProduct) {\n props.onConfigurationChange(matchingProduct);\n }\n }\n});\n\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<ClusterConfiguratorState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getSortedSettings(): ReturnType<\n ClusterConfiguratorState[\"getSortedSettings\"]\n> {\n const settings = (props.config as ClusterConfig)?.settings;\n if (!settings || settings.length === 0) return [];\n return settings\n .slice()\n .sort(\n (a: ClusterConfigSetting, b: ClusterConfigSetting) =>\n parseInt(a.priority) - parseInt(b.priority),\n );\n}\nfunction attributeNameMatches(\n attr: AttributeResult,\n targetName: string,\n): ReturnType<ClusterConfiguratorState[\"attributeNameMatches\"]> {\n const attrName =\n attr.attributeDescription?.descriptions?.[0]?.value ||\n attr.attributeDescription?.name;\n return (\n attrName === targetName ||\n attr.attributeDescription?.name === targetName ||\n (attr.attributeDescription?.descriptions?.some(\n (desc: any) => desc.value === targetName,\n ) ??\n false)\n );\n}\nfunction extractAttributeValues(\n attr: AttributeResult,\n): ReturnType<ClusterConfiguratorState[\"extractAttributeValues\"]> {\n let extractedValues: string[] = [];\n\n // ── Legacy SDK format ────────────────────────────────────────────\n if ((attr.value as any)?.colorValue) {\n extractedValues.push((attr.value as any).colorValue);\n } else if (Array.isArray((attr.value as any)?.textValues)) {\n // `textValues` is a localized array; empty buckets are common (e.g.\n // FR present but unset). Picking `[0]` blindly returned `[]` and\n // silently hid every value for any attribute whose first language\n // slot was empty.\n const buckets = (attr.value as any).textValues as Array<{ values?: any[] }>;\n const firstNonEmpty = buckets.find(\n (entry) => Array.isArray(entry?.values) && entry.values.length > 0,\n );\n extractedValues = (firstNonEmpty?.values as string[] | undefined) ?? [];\n } else if ((attr.value as any)?.textValue) {\n extractedValues.push((attr.value as any).textValue);\n } else if ((attr.value as any)?.numericValue !== undefined) {\n extractedValues.push((attr.value as any).numericValue.toString());\n } else if ((attr.value as any)?.booleanValue !== undefined) {\n extractedValues.push((attr.value as any).booleanValue ? \"Yes\" : \"No\");\n }\n // ── Current SDK format (type-based) ──────────────────────────────\n else if (attr.value?.type === AttributeType.COLOR) {\n extractedValues.push(attr.value?.value);\n } else if (attr.value?.type === AttributeType.TEXT) {\n // Same first-non-empty pick as the legacy branch above.\n const buckets = (attr.value?.value?.textValues ?? []) as Array<{ values?: any[] }>;\n const firstNonEmpty = buckets.find(\n (entry) => Array.isArray(entry?.values) && entry.values.length > 0,\n );\n extractedValues = (firstNonEmpty?.values as string[] | undefined) ?? [];\n } else if (attr.value?.type === AttributeType.DECIMAL) {\n extractedValues.push(attr.value?.value?.toString());\n } else if (attr.value?.type === AttributeType.INT) {\n extractedValues.push(attr.value?.value?.toString());\n } else if (attr.value?.type === AttributeType.ENUM) {\n extractedValues.push(attr.value?.value);\n }\n // ── Fallback ─────────────────────────────────────────────────────\n else if (typeof attr.value === \"string\") {\n extractedValues.push(attr.value);\n } else if (attr.value && typeof attr.value === \"object\") {\n if (\n (attr.value as any).values &&\n Array.isArray((attr.value as any).values)\n ) {\n extractedValues = (attr.value as any).values.filter(\n (v: any) => typeof v === \"string\",\n );\n } else {\n const possibleValues = Object.values(attr.value).filter(\n (v: any) => typeof v === \"string\",\n );\n extractedValues = possibleValues as string[];\n }\n }\n return extractedValues.filter((val: string) => !!val);\n}\nfunction getAttributeDisplayName(\n attributeName: string,\n): ReturnType<ClusterConfiguratorState[\"getAttributeDisplayName\"]> {\n const products = (props.products as Product[]) || [];\n if (products.length === 0) return attributeName;\n const firstProduct = products[0];\n const attributeItems = firstProduct.attributes?.items;\n if (Array.isArray(attributeItems)) {\n const matchingAttr = (attributeItems as AttributeResult[]).find(\n (attr: AttributeResult) => attributeNameMatches(attr, attributeName),\n );\n if (matchingAttr?.attributeDescription?.descriptions?.[0]?.value) {\n return matchingAttr.attributeDescription.descriptions[0].value;\n }\n }\n return attributeName;\n}\nfunction getAttributeValues(\n attributeName: string,\n): ReturnType<ClusterConfiguratorState[\"getAttributeValues\"]> {\n const valSet = new Set<string>();\n const products = (props.products as Product[]) || [];\n products.forEach((product: Product) => {\n const attributeItems = product.attributes?.items;\n if (Array.isArray(attributeItems)) {\n (attributeItems as AttributeResult[]).forEach((attr: AttributeResult) => {\n if (attributeNameMatches(attr, attributeName)) {\n const extracted = extractAttributeValues(attr);\n extracted.forEach((val: string) => valSet.add(val));\n }\n });\n }\n });\n return Array.from(valSet);\n}\nfunction getAvailableValuesForIndex(\n attributeName: string,\n settingIndex: number,\n): ReturnType<ClusterConfiguratorState[\"getAvailableValuesForIndex\"]> {\n return getAvailableValuesForIndexWithSelections(\n attributeName,\n settingIndex,\n selectedAttributes.value as Record<string, string>,\n );\n}\nfunction getAvailableValuesForIndexWithSelections(\n attributeName: string,\n settingIndex: number,\n selections: Record<string, string>,\n): ReturnType<\n ClusterConfiguratorState[\"getAvailableValuesForIndexWithSelections\"]\n> {\n if (settingIndex === 0) {\n return getAttributeValues(attributeName);\n }\n const sortedSettings = getSortedSettings();\n const previousSelections: Record<string, string> = {};\n for (let i = 0; i < settingIndex; i++) {\n const prevSetting = sortedSettings[i];\n if (selections[prevSetting.name]) {\n previousSelections[prevSetting.name] = selections[prevSetting.name];\n }\n }\n const products = (props.products as Product[]) || [];\n const prevEntries = Object.entries(previousSelections);\n const matchingProducts = products.filter((product: Product) => {\n return prevEntries.every(([attrName, attrValue]: [string, string]) => {\n const attributeItems = product.attributes?.items;\n if (!Array.isArray(attributeItems)) return false;\n return (attributeItems as AttributeResult[]).some(\n (attr: AttributeResult) => {\n if (!attributeNameMatches(attr, attrName)) return false;\n return extractAttributeValues(attr).includes(attrValue);\n },\n );\n });\n });\n const availableSet = new Set<string>();\n matchingProducts.forEach((product: Product) => {\n const attributeItems = product.attributes?.items;\n if (Array.isArray(attributeItems)) {\n (attributeItems as AttributeResult[]).forEach((attr: AttributeResult) => {\n if (attributeNameMatches(attr, attributeName)) {\n extractAttributeValues(attr).forEach((val: string) =>\n availableSet.add(val),\n );\n }\n });\n }\n });\n return Array.from(availableSet);\n}\nfunction getAttributeType(attributeName: string): string | undefined {\n // Look across all products — variants may omit an attribute, and the first\n // product happens not to carry the type/description we need.\n const products = (props.products as Product[]) || [];\n for (const product of products) {\n const items = product.attributes?.items as AttributeResult[] | undefined;\n if (!Array.isArray(items)) continue;\n const match = items.find((attr) => attributeNameMatches(attr, attributeName));\n if (match) return (match.attributeDescription?.type ?? undefined) as string | undefined;\n }\n return undefined;\n}\nfunction getSettingsWithValues(): ReturnType<\n ClusterConfiguratorState[\"getSettingsWithValues\"]\n> {\n const sortedSettings = getSortedSettings();\n const sel = selectedAttributes.value as Record<string, string>;\n return sortedSettings.map((setting: ClusterConfigSetting, index: number) => {\n const availableValues = getAvailableValuesForIndex(setting.name, index);\n const selectedValue = sel[setting.name] || \"\";\n const isPreviousSelectionMissing =\n index > 0 &&\n sortedSettings\n .slice(0, index)\n .some((prev: ClusterConfigSetting) => !sel[prev.name]);\n const isDisabled =\n availableValues.length === 0 || isPreviousSelectionMissing;\n const displayName = getAttributeDisplayName(setting.name);\n const attributeType = getAttributeType(setting.name);\n return {\n id: setting.id,\n name: setting.name,\n displayType: setting.displayType as string,\n attributeType,\n priority: setting.priority,\n displayName,\n availableValues,\n selectedValue,\n disabled: isDisabled,\n };\n });\n}\nfunction findMatchingProduct(\n selections: Record<string, string>,\n): ReturnType<ClusterConfiguratorState[\"findMatchingProduct\"]> {\n const products = (props.products as Product[]) || [];\n const entries = Object.entries(selections);\n if (entries.length === 0) return null;\n const found = products.find((product: Product) => {\n const attrItems = product.attributes?.items;\n if (!Array.isArray(attrItems)) return false;\n return entries.every(([attrName, attrValue]: [string, string]) => {\n return (attrItems as AttributeResult[]).some((attr: AttributeResult) => {\n if (!attributeNameMatches(attr, attrName)) return false;\n const productValues = extractAttributeValues(attr);\n return productValues.includes(attrValue);\n });\n });\n });\n return found || null;\n}\nfunction handleAttributeSelect(\n settingName: string,\n value: string,\n): ReturnType<ClusterConfiguratorState[\"handleAttributeSelect\"]> {\n const sortedSettings = getSortedSettings();\n const changedIndex = sortedSettings.findIndex(\n (s: ClusterConfigSetting) => s.name === settingName,\n );\n\n // Build new selections: keep, update changed, remove subsequent\n const newSelections: Record<string, string> = {\n ...(selectedAttributes.value as Record<string, string>),\n };\n newSelections[settingName] = value;\n for (let i = changedIndex + 1; i < sortedSettings.length; i++) {\n delete newSelections[sortedSettings[i].name];\n }\n\n // Always pre-select the first available value for all subsequent settings\n for (let i = changedIndex + 1; i < sortedSettings.length; i++) {\n const nextSetting = sortedSettings[i];\n const available = getAvailableValuesForIndexWithSelections(\n nextSetting.name,\n i,\n newSelections,\n );\n if (available.length > 0) {\n newSelections[nextSetting.name] = available[0];\n } else {\n break;\n }\n }\n selectedAttributes.value = newSelections;\n\n // When all settings have a selection, resolve and report the product\n const allSelected = sortedSettings.every(\n (s: ClusterConfigSetting) => !!newSelections[s.name],\n );\n if (allSelected) {\n const matchingProduct = findMatchingProduct(newSelections);\n if (matchingProduct && props.onConfigurationChange) {\n props.onConfigurationChange(matchingProduct);\n }\n }\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-cluster-info ${className || ''}`\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <template v-if=\"loading && !cluster\">\n <div class=\"propeller-cluster-info__skeleton animate-pulse space-y-3\">\n <div class=\"propeller-cluster-info__skeleton-line h-4 bg-slate-100 rounded w-1/4\"></div>\n <div class=\"propeller-cluster-info__skeleton-line h-8 bg-slate-100 rounded w-3/4\"></div>\n </div>\n </template>\n\n <template v-if=\"!loading || !!cluster\">\n <template v-if=\"showSku !== false && !!getClusterSku()\">\n <div class=\"text-sm font-mono text-muted-foreground mb-2\">SKU: {{ getClusterSku() }}</div>\n </template>\n\n <template v-if=\"showTitle !== false && !!getClusterName()\">\n <h1 class=\"text-4xl font-bold tracking-tight text-foreground mb-4\">\n {{ getClusterName() }}\n </h1>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, watch } from \"vue\";\n\nimport {\n GraphQLClient,\n Cluster,\n LocalizedString,\n Contact,\n Customer,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { useProductInfo } from '../composables/vue/useProductInfo';\nimport { getLanguageString, getLanguageUri } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface ClusterInfoProps {\n // ── Data source ──────────────────────────────────────────────────────────\n /** The authenticated user (Contact or Customer) */\n user: Contact | Customer | null;\n /**\n * Pre-fetched cluster object to display.\n * When provided the component skips internal fetching.\n */\n cluster?: Cluster;\n\n /**\n * Cluster ID to fetch data for when no `cluster` prop is provided.\n * Requires `graphqlClient` to be set.\n */\n clusterId?: number;\n\n /**\n * Initialised Propeller SDK GraphQL client.\n * Required when `clusterId` is provided for internal data fetching.\n */\n graphqlClient?: GraphQLClient;\n\n /**\n * Called once the cluster data is loaded — either immediately (when\n * `cluster` prop is supplied) or after the internal fetch completes.\n * Use this to hydrate sibling components (configurator, price, gallery, etc.).\n */\n onClusterLoaded?: (cluster: Cluster) => void;\n\n // ── Display toggles ───────────────────────────────────────────────────────\n\n /** Show the cluster name. Defaults to true. */\n showTitle?: boolean;\n\n /** Show the cluster SKU. Defaults to true. */\n showSku?: boolean;\n\n // ── Locale ────────────────────────────────────────────────────────────────\n\n /** Language code used to resolve localised names. Defaults to 'NL'. */\n language?: string;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /**\n * Tax zone to use for price calculation.\n */\n taxZone?: string;\n\n /**\n * Image search filter passed to ProductService.getProduct().\n * Controls how many image items are returned.\n * Example: { page: 1, offset: 20 }\n */\n imageSearchFilters?: any;\n\n /**\n * Image variant transformation filter passed to ProductService.getProduct().\n * Controls image size/format variants returned with the product.\n * Example: imageVariantFiltersLarge from @/data/defaults\n * Defaults to { transformations: [] } when omitted.\n */\n imageVariantFilters?: any;\n\n /**\n * Config object providing imageSearchFiltersGrid and imageVariantFiltersSmall.\n */\n configuration?: any;\n\n /**\n * Attribute codes/names to look up and display as badge overlays on the product image.\n * Each code is resolved against `product.attributes.items[].attributeDescription.code`\n * (or `.name`). Attributes with no matching value are silently omitted.\n * Example: ['new', 'sale']\n */\n imageLabels?: string[];\n\n /**\n * Attribute codes/names to look up and display as extra text rows below the product name.\n * Resolved the same way as `imageLabels`.\n * Example: ['brand', 'color']\n */\n textLabels?: string[];\n}\n\nconst props = withDefaults(defineProps<ClusterInfoProps>(), {\n showTitle: true,\n showSku: true,\n});\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => infra.user ?? null);\nconst langRef = computed(() => infra.language || 'NL');\n\nconst { cluster, loading, error, fetchCluster } = useProductInfo({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n language: langRef,\n user: userRef,\n configuration: infra.configuration,\n});\n\nonMounted(() => {\n if (props.cluster) {\n if (props.onClusterLoaded) {\n props.onClusterLoaded(props.cluster);\n }\n return;\n }\n if (props.clusterId) {\n fetchCluster(\n props.clusterId,\n props.imageSearchFilters,\n props.imageVariantFilters,\n ).then(() => {\n if (cluster.value && props.onClusterLoaded) {\n props.onClusterLoaded(cluster.value);\n }\n });\n }\n});\n\nwatch(\n () => [props.clusterId, props.cluster],\n () => {\n if (props.cluster) {\n if (props.onClusterLoaded) {\n props.onClusterLoaded(props.cluster);\n }\n return;\n }\n if (!props.clusterId) return;\n fetchCluster(\n props.clusterId,\n props.imageSearchFilters,\n props.imageVariantFilters,\n ).then(() => {\n if (cluster.value && props.onClusterLoaded) {\n props.onClusterLoaded(cluster.value);\n }\n });\n }\n);\n\nfunction getDisplayCluster(): Cluster | null {\n return (props.cluster as Cluster) || cluster.value;\n}\nfunction getClusterName(): string {\n const c = getDisplayCluster();\n if (!c) return '';\n return getLanguageString(c.names, infra.language || 'NL', '');\n}\nfunction getClusterSku(): string {\n return getDisplayCluster()?.sku || '';\n}\n</script>\n","<template>\n <component\n :is=\"'script'\"\n v-if=\"payload\"\n type=\"application/ld+json\"\n v-html=\"payload\"\n />\n</template>\n\n<script setup lang=\"ts\">\n/**\n * Pure SSR-safe component. Emits a `<script type=\"application/ld+json\">` with\n * a schema.org Product payload representing the cluster (clusters use\n * `@type: \"Product\"` — schema.org has no Cluster type; the cluster's\n * `defaultProduct` supplies brand/SKU/price/image).\n *\n * See `ProductJsonLd.vue` for the dynamic-`script` rendering rationale.\n */\nimport { computed } from 'vue';\nimport type { Cluster } from '@propeller-commerce/propeller-sdk-v2';\nimport {\n buildClusterJsonLd,\n safeJsonStringify,\n type JsonLdContext,\n} from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface ClusterJsonLdProps {\n /** The cluster to describe. */\n cluster: Cluster;\n /** Per-request context: siteUrl, language, currency, portalMode, user, URL builders. */\n context: JsonLdContext;\n}\n\nconst props = defineProps<ClusterJsonLdProps>();\n\nconst payload = computed<string | null>(() => {\n const data = buildClusterJsonLd(props.cluster, props.context);\n return data ? safeJsonStringify(data) : null;\n});\n</script>\n","<template>\n <div :class=\"`propeller-cluster-options ${className || ''}`\">\n <template v-if=\"getOptionsForRender().length > 0\">\n <div class=\"propeller-cluster-options__content flex flex-col gap-6\">\n <template\n :key=\"option.id\"\n v-for=\"(option, index) in getOptionsForRender()\"\n >\n <div\n class=\"propeller-cluster-options__group\"\n :data-required=\"option.isRequired ? 'true' : 'false'\"\n :data-error=\"option.hasError ? 'true' : 'false'\"\n >\n <div\n class=\"propeller-cluster-options__label-row flex items-center gap-2 mb-2\"\n >\n <h4\n class=\"propeller-cluster-options__label font-semibold text-sm text-muted-foreground\"\n >\n {{ option.name }}\n </h4>\n <template v-if=\"option.isRequired\">\n <span\n class=\"propeller-cluster-options__required-badge inline-flex items-center rounded-full bg-destructive/10 px-2 py-0.5 text-xs font-medium text-destructive ring-1 ring-inset ring-destructive/10\"\n >{{ getLabel(\"required\", \"Required\") }}</span\n >\n </template>\n </div>\n <select\n :value=\"option.selectedProductId\"\n @change=\"\n async (e) => handleOptionChange(option.idStr, (e.target as HTMLInputElement).value)\n \"\n :class=\"`propeller-cluster-options__select w-full rounded-[var(--radius-container)] border px-3 py-2 text-sm focus:outline-none focus:ring-2 cursor-pointer ${\n option.hasError\n ? 'border-destructive focus:ring-destructive'\n : option.isRequired\n ? 'border-input focus:ring-secondary'\n : 'border-border focus:ring-secondary'\n }`\"\n >\n <option value=\"\">\n <template v-if=\"option.isRequired\">\n {{ getLabel(\"selectRequired\", \"— Select an option —\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"selectOptional\", \"— None (Optional) —\") }}\n </template>\n </option>\n <template\n :key=\"product.productId\"\n v-for=\"(product, index) in option.products\"\n >\n <option :value=\"product.productIdStr\">\n {{ product.label }}\n </option>\n </template>\n </select>\n <template v-if=\"option.hasError\">\n <p\n class=\"propeller-cluster-options__error mt-1 text-xs text-destructive\"\n >\n {{ getLabel(\"requiredError\", \"This option is required\") }}\n </p>\n </template>\n\n <template v-if=\"option.hasSelection\">\n <div\n class=\"propeller-cluster-options__preview mt-3 flex items-center gap-3 rounded-[var(--radius-container)] border border-border-subtle bg-surface-hover p-3\"\n >\n <template v-if=\"!!option.previewImageUrl\">\n <img\n class=\"propeller-cluster-options__preview-image h-12 w-12 flex-shrink-0 rounded border border-border-subtle bg-card object-contain\"\n :src=\"option.previewImageUrl\"\n :alt=\"option.previewName\"\n />\n </template>\n\n <template v-if=\"!option.previewImageUrl\">\n <div\n class=\"propeller-cluster-options__preview-image-placeholder flex h-12 w-12 flex-shrink-0 items-center justify-center rounded border border-border bg-surface-hover\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-5 w-5 text-foreground-subtle\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n :strokeWidth=\"1.5\"\n ></path>\n </svg>\n </div>\n </template>\n\n <div class=\"min-w-0 flex-1\">\n <p\n class=\"propeller-cluster-options__preview-name truncate text-sm font-medium text-foreground\"\n >\n {{ option.previewName }}\n </p>\n <p\n class=\"propeller-cluster-options__preview-price text-sm font-semibold text-secondary\"\n >\n {{ option.previewPrice }}\n </p>\n </div>\n </div>\n </template>\n </div>\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport { ClusterOption, Product, YesNo } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getProductImageUrl as _getProductImageUrl } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\n/**\n * Flattened render model for one product inside an option dropdown.\n */\ninterface RenderedOptionProduct {\n productId: number;\n productIdStr: string;\n /** Combined display label, e.g. \"Product Name — €10.00\" */\n label: string;\n}\n\n/**\n * Flattened render model for one cluster option group, precomputed\n * to avoid calling state methods with arguments inside JSX.\n */\n/**\n * Flattened render model for one product inside an option dropdown.\n */\n\n/**\n * Flattened render model for one cluster option group, precomputed\n * to avoid calling state methods with arguments inside JSX.\n */\ninterface RenderedOption {\n id: number;\n idStr: string;\n name: string;\n isRequired: boolean;\n selectedProductId: string;\n hasSelection: boolean;\n hasError: boolean;\n /** Image URL of the currently selected product (empty string if none). */\n previewImageUrl: string;\n previewName: string;\n previewPrice: string;\n products: RenderedOptionProduct[];\n}\n/**\n * Flattened render model for one product inside an option dropdown.\n */\n\n/**\n * Flattened render model for one cluster option group, precomputed\n * to avoid calling state methods with arguments inside JSX.\n */\n\nexport interface ClusterOptionsProps {\n /**\n * The cluster ID this options selector belongs to.\n * @required\n */\n clusterId: number;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /**\n * An array of options that belong to the cluster.\n * Hidden options (option.hidden === 'Y') are automatically filtered out.\n * @required\n */\n options: ClusterOption[];\n\n /**\n * Fired whenever the user selects a product within any option group.\n * Receives the full Product object of the chosen option product.\n * Usually used to trigger a price update on the parent page.\n */\n onOptionSelect?: (optionProduct: Product) => void;\n\n /**\n * Fired whenever the user clears an option (picks the empty/default entry\n * in a non-required dropdown). Receives the option's `id`. Parents should\n * remove that key from their `selectedOptionProducts` map so the price\n * display drops the option's add-on price.\n */\n onOptionClear?: (optionId: number) => void;\n\n /** Override any UI string. Available keys: required, selectRequired, selectOptional, requiredError */\n labels?: Record<string, string>;\n\n /** When true, required options with no selection are highlighted with a validation error. */\n showErrors?: boolean;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\n/**\n * Flattened render model for one product inside an option dropdown.\n */\n\n/**\n * Flattened render model for one cluster option group, precomputed\n * to avoid calling state methods with arguments inside JSX.\n */\n\ninterface ClusterOptionsState {\n selectedProductIds: Record<string, string>;\n getLabel: (key: string, fallback: string) => string;\n formatPrice: (price: number) => string;\n getProductName: (product: Product) => string;\n getProductImageUrl: (product: Product) => string;\n getOptionsForRender: () => RenderedOption[];\n handleOptionChange: (optionIdStr: string, productIdStr: string) => void;\n}\n\nconst props = defineProps<ClusterOptionsProps>();\nconst infra = useInfraProps(props);\nconst selectedProductIds = ref<ClusterOptionsState[\"selectedProductIds\"]>({});\n\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<ClusterOptionsState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatPrice(\n price: number,\n): ReturnType<ClusterOptionsState[\"formatPrice\"]> {\n return _formatPrice(price, { symbol: infra.currency ?? \"\\u20AC\" });\n}\nfunction getProductName(\n product: Product,\n): ReturnType<ClusterOptionsState[\"getProductName\"]> {\n return (\n (product as Product).names?.[0]?.value ||\n `Product ${(product as Product).productId}`\n );\n}\nfunction getProductImageUrl(\n product: Product,\n): ReturnType<ClusterOptionsState[\"getProductImageUrl\"]> {\n return _getProductImageUrl(product);\n}\nfunction getOptionsForRender(): ReturnType<\n ClusterOptionsState[\"getOptionsForRender\"]\n> {\n const options = (props.options as ClusterOption[]) || [];\n const sel = selectedProductIds.value as Record<string, string>;\n return options\n .filter((option: ClusterOption) => option.hidden !== YesNo.Y)\n .map((option: ClusterOption) => {\n const idStr = option.id.toString();\n const selectedProductId = sel[idStr] || \"\";\n const products = (option.products || []).map((p: Product) => ({\n productId: p.productId,\n productIdStr: p.productId.toString(),\n label: `${getProductName(p)} \\u2014 ${formatPrice(p.price?.gross || 0)}`,\n }));\n let previewImageUrl = \"\";\n let previewName = \"\";\n let previewPrice = \"\";\n if (selectedProductId) {\n const selectedProduct = (option.products || []).find(\n (p: Product) => p.productId.toString() === selectedProductId,\n );\n if (selectedProduct) {\n previewImageUrl = getProductImageUrl(selectedProduct);\n previewName = getProductName(selectedProduct);\n previewPrice = formatPrice(selectedProduct.price?.gross || 0);\n }\n }\n const isRequired = option.isRequired === YesNo.Y;\n return {\n id: option.id,\n idStr,\n name: option.names?.[0]?.value || `Option ${option.id}`,\n isRequired,\n selectedProductId,\n hasSelection: !!selectedProductId,\n hasError:\n isRequired && !selectedProductId && !!(props.showErrors as boolean),\n previewImageUrl,\n previewName,\n previewPrice,\n products,\n };\n });\n}\nfunction handleOptionChange(\n optionIdStr: string,\n productIdStr: string,\n): ReturnType<ClusterOptionsState[\"handleOptionChange\"]> {\n const newIds: Record<string, string> = {\n ...(selectedProductIds.value as Record<string, string>),\n };\n if (productIdStr) {\n newIds[optionIdStr] = productIdStr;\n } else {\n delete newIds[optionIdStr];\n }\n selectedProductIds.value = newIds;\n if (productIdStr && props.onOptionSelect) {\n const options = (props.options as ClusterOption[]) || [];\n const option = options.find(\n (o: ClusterOption) => o.id.toString() === optionIdStr,\n );\n const product = (option?.products || []).find(\n (p: Product) => p.productId.toString() === productIdStr,\n );\n if (product) {\n props.onOptionSelect(product);\n }\n } else if (!productIdStr && props.onOptionClear) {\n props.onOptionClear(parseInt(optionIdStr, 10));\n }\n}\n</script>\n","<template>\n <div\n class=\"propeller-company-switcher relative inline-block\"\n ref=\"containerRef\"\n :data-open=\"isOpen ? 'true' : 'false'\"\n >\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n :aria-label='getLabel(\"switchCompanyAriaLabel\", \"Switch company\")'\n class=\"propeller-company-switcher__trigger flex items-center gap-2 rounded-[var(--radius-control)] px-3 py-1.5 text-sm font-medium transition-colors hover:bg-white/10\"\n @click=\"async (event) => toggleDropdown()\"\n :aria-expanded=\"isOpen\"\n >\n <span\n aria-hidden=\"true\"\n :class=\"`propeller-company-switcher__icon icon-${getIcon()} flex-shrink-0`\"\n ></span\n ><span class=\"propeller-company-switcher__label truncate max-w-[160px]\">{{\n getActiveCompanyName()\n }}</span\n ><span\n aria-hidden=\"true\"\n :class=\"`propeller-company-switcher__chevron flex-shrink-0 transition-transform duration-200 ${\n isOpen ? 'rotate-180' : 'rotate-0'\n }`\"\n ><svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M2 4l4 4 4-4\"></path></svg\n ></span>\n </button>\n <template v-if=\"isOpen\">\n <ul\n role=\"listbox\"\n :aria-label='getLabel(\"companiesAriaLabel\", \"Companies\")'\n class=\"propeller-company-switcher__dropdown absolute left-0 top-full z-[60] mt-1 min-w-[220px] rounded-[var(--radius-control)] border border-border bg-popover text-popover-foreground shadow-lg py-1 animate-in fade-in zoom-in-95 duration-150\"\n >\n <template :key=\"String(company.companyId)\" v-for=\"(company, index) in getCompanies()\">\n <li\n role=\"option\"\n :aria-selected=\"isActive(company)\"\n @click=\"async (event) => selectCompany(company)\"\n :class=\"`propeller-company-switcher__option flex items-center gap-3 px-4 py-2.5 text-sm cursor-pointer transition-colors hover:bg-accent hover:text-accent-foreground ${\n isActive(company) ? 'font-semibold text-primary' : 'font-normal text-foreground'\n }`\"\n >\n <span class=\"propeller-company-switcher__option-name flex-1 truncate\">{{ company.name }}</span>\n <template v-if=\"isActive(company)\">\n <svg\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n class=\"propeller-company-switcher__option-check flex-shrink-0 w-4 h-4 text-primary\"\n >\n <path d=\"M2.5 8l4 4 7-7\"></path>\n </svg>\n </template>\n </li>\n </template>\n </ul>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nimport { Contact, Company } from '@propeller-commerce/propeller-sdk-v2';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface CompanySwitcherProps {\n /** The contact to whom the companies are assigned. Default company is user.company, all companies are in user.companies. Resolved from `<PropellerProvider>` when omitted. */\n user?: Contact;\n\n /** Icon identifier for the company switcher trigger button. @default 'default-company-switch-icon' */\n icon?: string;\n\n /** Currently selected company ID (from CompanyContext). Syncs the switcher with external state. */\n selectedCompanyId?: number;\n\n /** Callback fired when the user selects a company. */\n onCompanyChange: (company: Company) => void;\n\n /** Translated labels keyed by the slugs used inside the component (see\n * `getLabel` calls). Missing keys fall back to the English defaults. */\n labels?: Record<string, string>;\n}\ninterface CompanySwitcherState {\n isOpen: boolean;\n activeCompanyId: number | null;\n getCompanies: () => Company[];\n getActiveCompany: () => Company | null;\n getActiveCompanyName: () => string;\n getIcon: () => string;\n isActive: (company: Company) => boolean;\n toggleDropdown: () => void;\n selectCompany: (company: Company) => void;\n}\n\nconst props = defineProps<CompanySwitcherProps>();\n// Resolve `user` from the propellerVue plugin scope when the consumer doesn't\n// pass it explicitly. AppHeader / chrome surfaces typically rely on the\n// provider rather than wiring user through every prop.\nconst infra = useInfraProps(props);\nconst isOpen = ref<CompanySwitcherState['isOpen']>(false);\nconst activeCompanyId = ref<CompanySwitcherState['activeCompanyId']>(null);\n\nconst containerRef = ref<HTMLDivElement | null>(null);\n\nwatch(\n () => [isOpen.value],\n () => {\n if (!isOpen.value) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.value && !(containerRef.value as any).contains(e.target)) {\n isOpen.value = false;\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n },\n { immediate: true }\n);\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getCompanies(): ReturnType<CompanySwitcherState['getCompanies']> {\n const user = (infra.user ?? props.user) as Contact | undefined;\n if (!user) return [];\n // sanitizeUser in AuthContext is not recursive, so CompaniesResponse fields\n // may still have their raw _items key instead of the getter-based items.\n const companiesRaw = user.companies as any;\n const items = (companiesRaw?.items ?? companiesRaw?._items) as Company[] | undefined;\n if (Array.isArray(items) && items.length > 0) {\n return items;\n }\n const defaultCompany = user.company;\n if (defaultCompany) {\n return [defaultCompany];\n }\n return [];\n}\nfunction getActiveCompany(): ReturnType<CompanySwitcherState['getActiveCompany']> {\n const idToUse = activeCompanyId.value ?? (props.selectedCompanyId as number | undefined) ?? null;\n if (idToUse !== null) {\n const companies = getCompanies();\n const found = companies.find((c: Company) => c.companyId === idToUse);\n return found ?? null;\n }\n const user = (infra.user ?? props.user) as Contact | undefined;\n return (user?.company as Company | undefined) ?? null;\n}\nfunction getActiveCompanyName(): ReturnType<CompanySwitcherState['getActiveCompanyName']> {\n const company = getActiveCompany();\n return company ? company.name : 'Select company';\n}\nfunction getIcon(): ReturnType<CompanySwitcherState['getIcon']> {\n return props.icon ?? 'default-company-switch-icon';\n}\nfunction isActive(company: Company): ReturnType<CompanySwitcherState['isActive']> {\n const active = getActiveCompany();\n return active !== null && active.companyId === company.companyId;\n}\nfunction toggleDropdown(): ReturnType<CompanySwitcherState['toggleDropdown']> {\n isOpen.value = !isOpen.value;\n}\nfunction selectCompany(company: Company): ReturnType<CompanySwitcherState['selectCompany']> {\n activeCompanyId.value = company.companyId;\n isOpen.value = false;\n props.onCompanyChange(company);\n}\n</script>\n","<template>\n <div :class=\"`propeller-delivery-date ${containerClass}`\">\n <div\n class=\"propeller-delivery-date__grid grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3\"\n >\n <template :key=\"index\" v-for=\"(dateStr, index) in upcomingDates\">\n <div\n @click=\"async (event) => handleSelect(dateStr)\"\n :data-selected=\"selectedDayKey !== '' && upcomingDayKeys[index] === selectedDayKey ? 'true' : 'false'\"\n :class=\"`propeller-delivery-date__option cursor-pointer border border-border rounded-[var(--radius-container)] p-3 text-center transition-all ${\n selectedDayKey !== '' && upcomingDayKeys[index] === selectedDayKey\n ? 'border-secondary bg-secondary/5 shadow-sm'\n : 'hover:border-secondary/30'\n }`\"\n >\n <div class=\"propeller-delivery-date__option-label font-semibold\">\n {{ formatDisplay(dateStr) }}\n </div>\n </div>\n </template>\n <template v-if=\"showDatePicker\">\n <div\n @click=\"async (event) => openModal()\"\n :data-selected=\"isCustomDateSelected ? 'true' : 'false'\"\n data-custom=\"true\"\n :class=\"`propeller-delivery-date__option propeller-delivery-date__option--custom cursor-pointer border border-border rounded-[var(--radius-container)] p-3 text-center transition-all ${\n isCustomDateSelected\n ? 'border-secondary bg-secondary/5 shadow-sm'\n : 'hover:border-secondary/30'\n }`\"\n >\n <template v-if=\"isCustomDateSelected\">\n <div class=\"propeller-delivery-date__option-label font-semibold\">\n {{ formatDisplay(selectedDate) }}\n </div>\n </template>\n\n <template v-if=\"!isCustomDateSelected\">\n <div class=\"propeller-delivery-date__option-label font-semibold\">\n {{ getLabel(\"pickDate\", \"Other date...\") }}\n </div>\n </template>\n </div>\n </template>\n </div>\n <template v-if=\"modalOpen\">\n <div\n class=\"propeller-delivery-date__modal fixed inset-0 z-50 flex items-center justify-center bg-black/50\"\n @click=\"async (event) => handleBackdropClick(event)\"\n >\n <div\n class=\"propeller-delivery-date__modal-content bg-card rounded-xl shadow-xl p-6 w-full max-w-sm mx-4\"\n >\n <div\n class=\"propeller-delivery-date__modal-header flex justify-between items-center mb-4\"\n >\n <h3\n class=\"propeller-delivery-date__modal-title text-lg font-semibold\"\n >\n {{ getLabel(\"modalTitle\", \"Select a delivery date\") }}\n </h3>\n <button\n type=\"button\"\n class=\"propeller-delivery-date__modal-close text-foreground-subtle hover:text-muted-foreground transition-colors\"\n @click=\"async (event) => closeModal()\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth=\"2\"\n stroke=\"currentColor\"\n class=\"w-5 h-5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n <input\n type=\"date\"\n class=\"propeller-delivery-date__input w-full border border-input rounded-[var(--radius-container)] px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-secondary focus:border-secondary\"\n :class=\"customDateError ? 'border-destructive focus:ring-destructive focus:border-destructive' : ''\"\n :min=\"minDate\"\n :value=\"customDateValue\"\n @change=\"\n async (event) => handleCustomDateChange((event.target as HTMLInputElement).value)\n \"\n />\n <template v-if=\"customDateError\">\n <p\n class=\"propeller-delivery-date__input-error text-sm text-destructive mt-2\"\n role=\"alert\"\n >\n {{ customDateError }}\n </p>\n </template>\n <div\n class=\"propeller-delivery-date__modal-actions flex justify-end gap-3 mt-4\"\n >\n <button\n type=\"button\"\n class=\"propeller-delivery-date__cancel-btn px-4 py-2 text-sm font-medium text-muted-foreground bg-surface-hover rounded-[var(--radius-container)] hover:bg-accent transition-colors\"\n @click=\"async (event) => closeModal()\"\n >\n {{ getLabel(\"cancel\", \"Cancel\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\n\nimport { Cart } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface DeliveryDateProps {\n /** The cart to use for the delivery date */\n cart: Cart;\n\n /** Show the upcoming N days in the date selector */\n showUpcomingDays?: number;\n\n /** Skip weekends in the date selector */\n skipWeekends?: boolean;\n\n /** Show date picker as an option in the date selector */\n showDatePicker?: boolean;\n\n /** Action when a delivery date is selected */\n onDateSelect?: (date: string) => void;\n\n /** Custom date display formatting function */\n formatDateDisplay?: (date: string) => string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** The CSS class for the container */\n containerClass?: string;\n\n /** Pre-selected date from cart (e.g. cart.postageData.requestDate: \"2026-04-17T00:00:00.000Z\") */\n initialDate?: string;\n}\ninterface DeliveryDateState {\n selectedDate: string;\n modalOpen: boolean;\n customDateValue: string;\n upcomingDays: number;\n skipWeekends: boolean;\n showDatePicker: boolean;\n isCustomDateSelected: boolean;\n containerClass: string;\n upcomingDates: string[];\n minDate: string;\n getLabel: (key: string, fallback: string) => string;\n toApiDate: (date: Date) => string;\n formatDisplay: (isoDate: string) => string;\n handleSelect: (isoDate: string) => void;\n handleCustomDateChange: (value: string) => void;\n openModal: () => void;\n closeModal: () => void;\n handleBackdropClick: (event: Event) => void;\n}\n\nconst props = withDefaults(defineProps<DeliveryDateProps>(), {\n showUpcomingDays: 3,\n skipWeekends: true,\n showDatePicker: true,\n});\nconst selectedDate = ref<DeliveryDateState[\"selectedDate\"]>(\"\");\nconst modalOpen = ref<DeliveryDateState[\"modalOpen\"]>(false);\nconst customDateValue = ref<DeliveryDateState[\"customDateValue\"]>(\"\");\nconst customDateError = ref<string>(\"\");\n\nconst upcomingDays = computed(() => {\n return props.showUpcomingDays !== undefined ? props.showUpcomingDays : 3;\n});\nconst skipWeekends = computed(() => {\n return props.skipWeekends !== undefined ? props.skipWeekends : true;\n});\nconst showDatePicker = computed(() => {\n return props.showDatePicker !== undefined ? props.showDatePicker : true;\n});\n// Compare by local calendar day, not raw ISO string — see `toDayKey`. The\n// selected date counts as \"one of the tiles\" when its day matches a tile's day,\n// regardless of the time/offset the cart stored it with.\nconst selectedDayKey = computed(() => toDayKey(selectedDate.value));\nconst upcomingDayKeys = computed(() => upcomingDates.value.map(toDayKey));\nconst isCustomDateSelected = computed(() => {\n return (\n selectedDayKey.value !== \"\" &&\n upcomingDayKeys.value.indexOf(selectedDayKey.value) === -1\n );\n});\nconst containerClass = computed(() => {\n return props.containerClass || \"delivery-date\";\n});\nconst upcomingDates = computed(() => {\n const days: string[] = [];\n const today = new Date();\n const current = new Date(today);\n current.setDate(current.getDate() + 1);\n while (days.length < upcomingDays.value) {\n const dayOfWeek = current.getDay();\n if (!skipWeekends.value || (dayOfWeek !== 0 && dayOfWeek !== 6)) {\n days.push(toApiDate(current));\n }\n current.setDate(current.getDate() + 1);\n }\n return days;\n});\nconst minDate = computed(() => {\n const tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n const y = tomorrow.getFullYear();\n const m = String(tomorrow.getMonth() + 1).padStart(2, \"0\");\n const d = String(tomorrow.getDate()).padStart(2, \"0\");\n return y + \"-\" + m + \"-\" + d;\n});\n\nwatch(\n () => [props.initialDate, props.cart],\n () => {\n if (props.initialDate && !selectedDate.value) {\n // Normalize cart format \"2026-04-17T00:00:00.000Z\" → \"2026-04-17T00:00:00Z\"\n const dot = props.initialDate.lastIndexOf(\".\");\n const normalized =\n dot !== -1\n ? props.initialDate.substring(0, dot) + \"Z\"\n : props.initialDate;\n selectedDate.value = normalized;\n if (props.onDateSelect) {\n props.onDateSelect(normalized);\n }\n }\n },\n { immediate: true },\n);\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<DeliveryDateState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction toApiDate(date: Date): ReturnType<DeliveryDateState[\"toApiDate\"]> {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return y + \"-\" + m + \"-\" + d + \"T00:00:00Z\";\n}\n\n/**\n * Local calendar day (`YYYY-MM-DD`) of an ISO date, for comparing a selected /\n * cart date against the quick-pick tiles. Comparing the raw ISO strings is\n * wrong: the cart's `requestDate` carries its own time/offset/millis (e.g.\n * `...T00:00:00.000Z`, `...+02:00`), so a date that IS the same day as a tile\n * fails a string match and gets misclassified as a custom \"other\" date —\n * duplicating it into the picker tile. Keying by the LOCAL day matches how the\n * tile labels are rendered (`formatDisplay` uses local getDate). Empty/invalid → ''.\n */\nfunction toDayKey(iso: string): string {\n if (!iso) return \"\";\n const date = new Date(iso);\n if (isNaN(date.getTime())) return \"\";\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return y + \"-\" + m + \"-\" + d;\n}\nfunction formatDisplay(\n isoDate: string,\n): ReturnType<DeliveryDateState[\"formatDisplay\"]> {\n if (props.formatDateDisplay) {\n return props.formatDateDisplay(isoDate);\n }\n // Guard against bad input: invalid dates produce NaN/undefined and render\n // as \"undefined, undefined NaN\". Return an empty string so the caller can\n // decide what to show.\n if (!isoDate) return \"\";\n const date = new Date(isoDate);\n if (isNaN(date.getTime())) return \"\";\n const weekday = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"][\n date.getDay()\n ];\n const months = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n return weekday + \", \" + months[date.getMonth()] + \" \" + date.getDate();\n}\nfunction handleSelect(\n isoDate: string,\n): ReturnType<DeliveryDateState[\"handleSelect\"]> {\n selectedDate.value = isoDate;\n modalOpen.value = false;\n if (props.onDateSelect) {\n props.onDateSelect(isoDate);\n }\n}\nfunction handleCustomDateChange(\n value: string,\n): ReturnType<DeliveryDateState[\"handleCustomDateChange\"]> {\n // Validate before committing. The native date input doesn't reliably enforce\n // the `min` attribute on typed input across browsers, and historical or\n // out-of-range dates parse to a real Date that crashes downstream rendering\n // (\"undefined, undefined NaN\"). On any failure we keep the typed value in\n // the input so the user can fix it, and surface a single error message.\n customDateValue.value = value;\n if (!value) {\n customDateError.value = \"\";\n return;\n }\n const parsed = new Date(value + \"T00:00:00\");\n const year = parsed.getFullYear();\n const isParseable = !isNaN(parsed.getTime()) && year >= 1900 && year <= 9999;\n if (!isParseable) {\n customDateError.value = getLabel(\n \"invalidDate\",\n \"Please enter a valid date.\",\n );\n return;\n }\n // Reject anything earlier than minDate (tomorrow). String comparison works\n // because both sides are ISO-formatted YYYY-MM-DD.\n if (value < minDate.value) {\n customDateError.value = getLabel(\n \"pastDate\",\n \"Please select a date in the future.\",\n );\n return;\n }\n customDateError.value = \"\";\n const isoDate = toApiDate(parsed);\n handleSelect(isoDate);\n}\nfunction openModal(): ReturnType<DeliveryDateState[\"openModal\"]> {\n customDateError.value = \"\";\n modalOpen.value = true;\n}\nfunction closeModal(): ReturnType<DeliveryDateState[\"closeModal\"]> {\n customDateError.value = \"\";\n modalOpen.value = false;\n}\nfunction handleBackdropClick(\n event: Event,\n): ReturnType<DeliveryDateState[\"handleBackdropClick\"]> {\n if (event.target === event.currentTarget) {\n modalOpen.value = false;\n }\n}\n</script>\n","<template>\n <div\n @click=\"async (e) => handleItemClick(e)\"\n :data-type=\"isProduct() ? 'product' : 'cluster'\"\n :class=\"`propeller-favorite-list-item flex flex-row items-center gap-4 rounded-[var(--radius-container)] border border-border bg-card p-4 transition-colors hover:border-secondary/20 hover:shadow-sm cursor-pointer ${\n className || ''\n }`\"\n >\n <div\n class=\"propeller-favorite-list-item__media relative w-16 h-16 flex-shrink-0 overflow-hidden rounded-[var(--radius-control)] bg-surface-hover p-1\"\n >\n <slot\n name=\"image\"\n :item=\"item\"\n :imageUrl=\"getImageUrl()\"\n :itemUrl=\"getItemUrl()\"\n :name=\"getName()\"\n :linkable=\"titleLinkable !== false\"\n :handleItemClick=\"handleItemClick\"\n >\n <template v-if=\"titleLinkable !== false\">\n <a\n class=\"block h-full w-full\"\n :href=\"getItemUrl()\"\n @click=\"async (e) => handleItemClick(e)\"\n >\n <template v-if=\"!!getImageUrl()\">\n <img\n class=\"propeller-favorite-list-item__image h-full w-full object-contain\"\n :src=\"getImageUrl()\"\n :alt=\"getName()\"\n />\n </template>\n\n <template v-if=\"!getImageUrl()\">\n <div\n class=\"propeller-favorite-list-item__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-8 w-8\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n :strokeWidth=\"1\"\n ></path>\n </svg>\n </div>\n </template>\n </a>\n </template>\n\n <template v-if=\"titleLinkable === false\">\n <div class=\"block h-full w-full\">\n <template v-if=\"!!getImageUrl()\">\n <img\n class=\"propeller-favorite-list-item__image h-full w-full object-contain\"\n :src=\"getImageUrl()\"\n :alt=\"getName()\"\n />\n </template>\n\n <template v-if=\"!getImageUrl()\">\n <div\n class=\"propeller-favorite-list-item__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-8 w-8\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n :strokeWidth=\"1\"\n ></path>\n </svg>\n </div>\n </template>\n </div>\n </template>\n </slot>\n </div>\n <div\n class=\"propeller-favorite-list-item__body flex flex-col gap-0.5 min-w-0 flex-1\"\n >\n <slot\n v-if=\"showSku !== false && !!getSku()\"\n name=\"sku\"\n :item=\"item\"\n :sku=\"getSku()\"\n >\n <span\n class=\"propeller-favorite-list-item__sku font-mono text-xs text-foreground-subtle\"\n >{{ getSku() }}</span\n >\n </slot>\n\n <slot\n name=\"name\"\n :item=\"item\"\n :name=\"getName()\"\n :itemUrl=\"getItemUrl()\"\n :linkable=\"titleLinkable !== false\"\n :handleItemClick=\"handleItemClick\"\n >\n <template v-if=\"titleLinkable !== false\">\n <a\n class=\"propeller-favorite-list-item__title text-sm font-medium leading-tight text-foreground transition-colors hover:text-secondary line-clamp-1\"\n :href=\"getItemUrl()\"\n @click=\"async (e) => handleItemClick(e)\"\n >{{ getName() }}</a\n >\n </template>\n\n <template v-if=\"titleLinkable === false\">\n <span\n class=\"propeller-favorite-list-item__title text-sm font-medium leading-tight text-foreground line-clamp-1\"\n >{{ getName() }}</span\n >\n </template>\n </slot>\n </div>\n <slot\n v-if=\"showStockComponent !== false\"\n name=\"stock\"\n :item=\"item\"\n :isProduct=\"isProduct()\"\n :inventory=\"isProduct() ? getProduct()?.inventory : getCluster()?.defaultProduct?.inventory\"\n :labels=\"labels\"\n >\n <template v-if=\"isProduct() && !!getProduct().inventory\">\n <div class=\"flex-shrink-0\">\n <ItemStock\n :inventory=\"getProduct().inventory\"\n :showAvailability=\"showAvailability !== false\"\n :showStock=\"showStock !== false\"\n :labels=\"stockLabels\"\n ></ItemStock>\n </div>\n </template>\n\n <template v-if=\"!isProduct()\">\n <template\n v-if=\"\n getCluster()?.defaultProduct?.inventory?.totalQuantity !== undefined\n \"\n >\n <div class=\"propeller-favorite-list-item__stock flex-shrink-0\">\n <template\n v-if=\"\n (getCluster()?.defaultProduct?.inventory?.totalQuantity || 0) > 5\n \"\n >\n <span\n class=\"propeller-favorite-list-item__stock-badge inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium text-success bg-success/10\"\n data-stock=\"in\"\n >{{ getLabel(\"inStock\", \"In stock\") }}</span\n >\n </template>\n\n <template\n v-if=\"\n (getCluster()?.defaultProduct?.inventory?.totalQuantity || 0) >\n 0 &&\n (getCluster()?.defaultProduct?.inventory?.totalQuantity || 0) <= 5\n \"\n >\n <span\n class=\"propeller-favorite-list-item__stock-badge inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium text-warning bg-warning/10\"\n data-stock=\"low\"\n >{{ getLabel(\"lowStock\", \"Low stock\") }}</span\n >\n </template>\n\n <template\n v-if=\"\n (getCluster()?.defaultProduct?.inventory?.totalQuantity || 0) ===\n 0\n \"\n >\n <span\n class=\"propeller-favorite-list-item__stock-badge inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium text-destructive bg-destructive/10\"\n data-stock=\"out\"\n >{{ getLabel(\"outOfStock\", \"Out of stock\") }}</span\n >\n </template>\n </div>\n </template>\n </template>\n </slot>\n\n <slot\n v-if=\"!!getItemPrice()\"\n name=\"price\"\n :item=\"item\"\n :formattedPrice=\"getItemPrice()\"\n >\n <span\n class=\"propeller-favorite-list-item__price text-base font-bold text-foreground whitespace-nowrap flex-shrink-0\"\n >{{ getItemPrice() }}</span\n >\n </slot>\n\n <div\n class=\"propeller-favorite-list-item__actions flex items-center gap-2 flex-shrink-0\"\n @click=\"async (e) => e.stopPropagation()\"\n >\n <slot\n name=\"actions\"\n :item=\"item\"\n :isProduct=\"isProduct()\"\n :showDelete=\"showDelete\"\n :allowAddToCart=\"allowAddToCart\"\n :handleDelete=\"handleDelete\"\n :handleItemClick=\"handleItemClick\"\n :labels=\"labels\"\n >\n <template\n v-if=\"allowAddToCart !== false && isProduct() && !!graphqlClient\"\n >\n <AddToCart\n :graphqlClient=\"graphqlClient\"\n :user=\"user || null\"\n :product=\"getProduct()\"\n :cartId=\"cartId\"\n :configuration=\"configuration\"\n :createCart=\"createCart\"\n :onCartCreated=\"onCartCreated\"\n :onAddToCart=\"onAddToCart\"\n :afterAddToCart=\"afterAddToCart\"\n :showModal=\"showModal\"\n :allowIncrDecr=\"allowIncrDecr\"\n :enableStockValidation=\"enableStockValidation\"\n :language=\"language\"\n :onProceedToCheckout=\"onProceedToCheckout\"\n :onRequestQuoteClick=\"onRequestQuoteClick\"\n :labels=\"addToCartLabels\"\n ></AddToCart>\n </template>\n\n <template v-if=\"!isProduct()\">\n <a\n class=\"propeller-favorite-list-item__view-cluster inline-flex items-center justify-center rounded-[var(--radius-control)] bg-secondary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-secondary/90 whitespace-nowrap\"\n :href=\"getItemUrl()\"\n @click=\"async (e) => handleItemClick(e)\"\n >{{ getLabel(\"viewCluster\", \"View cluster\") }}</a\n >\n </template>\n\n <template v-if=\"showDelete !== false\">\n <button\n type=\"button\"\n class=\"propeller-favorite-list-item__delete-btn h-8 w-8 p-0 inline-flex items-center justify-center rounded-[var(--radius-control)] text-foreground-subtle hover:text-destructive hover:bg-destructive/10 transition-colors\"\n @click=\"async (event) => handleDelete()\"\n :title=\"getLabel('delete', 'Remove from list')\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 6h18\"></path>\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"></path>\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"></path>\n </svg>\n </button>\n </template>\n </slot>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport {\n Product,\n Cluster,\n GraphQLClient,\n Contact,\n Customer,\n Cart,\n CartMainItem,\n CartChildItemInput,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport AddToCart from \"./AddToCart.vue\";\nimport ItemStock from \"./ItemStock.vue\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n getProductImageUrl as _getProductImageUrl,\n getClusterImageUrl as _getClusterImageUrl,\n getProductSku as _getProductSku,\n getClusterSku as _getClusterSku,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface FavoriteListItemProps {\n /** Product or Cluster to be listed as a favorite list item */\n item: Product | Cluster;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** Should the item title be a link to the PDP (default: true) */\n titleLinkable?: boolean;\n\n /** Should the stock be displayed in the favorite list item (default: false) */\n showStockComponent?: boolean;\n\n /** Show availability status (e.g. \"In stock\") inside ItemStock (default: true) */\n showAvailability?: boolean;\n\n /** Show numeric stock quantity inside ItemStock (default: true) */\n showStock?: boolean;\n\n /** Display the SKU of the item beneath the item name (default: true) */\n showSku?: boolean;\n\n /** Enables the add to cart functionality for products. Clusters show a \"View cluster\" button instead (default: true) */\n allowAddToCart?: boolean;\n\n /** Display a delete button that removes the favorite list item from the list (default: true) */\n showDelete?: boolean;\n\n /** Action callback fired when a favorite list item is deleted from the list */\n onDelete?: (itemId: string) => void;\n\n /** Callback when the item title or image is clicked. Prevents default <a> navigation when provided */\n onItemClick?: (item: Product | Cluster) => void;\n\n /** Extra CSS class applied to the root element */\n className?: string;\n\n /** Configuration object for URL generation */\n configuration?: any;\n\n /** UI string overrides */\n labels?: Record<string, string>;\n\n /** Include tax in the price display. When provided, overrides the internal PriceToggle state */\n includeTax?: boolean;\n\n // === AddToCart pass-through props (only used for products) ===\n\n /** Initialised Propeller SDK GraphQL client (required by embedded AddToCart) */\n graphqlClient?: GraphQLClient;\n\n /** Authenticated user — used for cart creation / lookup */\n user?: Contact | Customer | null;\n\n /** ID of an existing cart to add items to */\n cartId?: string;\n\n /** When true and no cartId is available, AddToCart automatically creates a cart */\n createCart?: boolean;\n\n /** Called after a new cart is created internally by AddToCart */\n onCartCreated?: (cart: Cart) => void;\n\n /** Fully replaces the internal CartService.addItemToCart call */\n onAddToCart?: (\n product: Product,\n clusterId?: number,\n quantity?: number,\n childItems?: CartChildItemInput[],\n notes?: string,\n price?: number,\n showModal?: boolean,\n ) => Cart;\n\n /** Called after every successful add-to-cart */\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n\n /** Show modal after successful add (default: false) */\n showModal?: boolean;\n\n /** Renders increment/decrement buttons beside quantity input (default: true) */\n allowIncrDecr?: boolean;\n\n /** Validate stock before adding to cart (default: false) */\n enableStockValidation?: boolean;\n\n /** Language code forwarded to CartService (default: 'NL') */\n language?: string;\n\n /** Called when \"Proceed to checkout\" is clicked in AddToCart modal */\n onProceedToCheckout?: () => void;\n\n /** Called when \"Request a Quote\" is clicked in AddToCart modal */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /** Label overrides for AddToCart UI strings */\n addToCartLabels?: Record<string, string>;\n\n /** Label overrides for ItemStock UI strings */\n stockLabels?: Record<string, string>;\n}\ninterface FavoriteListItemState {\n isProduct: () => boolean;\n getProduct: () => Product;\n getCluster: () => Cluster;\n getName: () => string;\n getSku: () => string;\n getImageUrl: () => string;\n getItemUrl: () => string;\n getItemId: () => string;\n getItemPrice: () => string;\n getLabel: (key: string, fallback: string) => string;\n handleItemClick: (e: any) => void;\n handleDelete: () => void;\n}\n\nconst props = withDefaults(defineProps<FavoriteListItemProps>(), {\n titleLinkable: true,\n showSku: true,\n allowAddToCart: true,\n showDelete: true,\n showStockComponent: false,\n showAvailability: false,\n showStock: false,\n});\nconst infra = useInfraProps(props);\n\nfunction isProduct(): ReturnType<FavoriteListItemState[\"isProduct\"]> {\n return \"productId\" in props.item;\n}\nfunction getProduct(): ReturnType<FavoriteListItemState[\"getProduct\"]> {\n return props.item as Product;\n}\nfunction getCluster(): ReturnType<FavoriteListItemState[\"getCluster\"]> {\n return props.item as Cluster;\n}\nfunction getName(): ReturnType<FavoriteListItemState[\"getName\"]> {\n if (isProduct()) {\n return getProduct()?.names?.[0]?.value || \"Product\";\n }\n return (\n getCluster()?.names?.[0]?.value ||\n getCluster()?.defaultProduct?.names?.[0]?.value ||\n \"Cluster\"\n );\n}\nfunction getSku(): ReturnType<FavoriteListItemState[\"getSku\"]> {\n if (isProduct()) return _getProductSku(getProduct());\n return _getClusterSku(getCluster());\n}\nfunction getImageUrl(): ReturnType<FavoriteListItemState[\"getImageUrl\"]> {\n if (isProduct()) return _getProductImageUrl(getProduct());\n return _getClusterImageUrl(getCluster());\n}\nfunction getItemUrl(): ReturnType<FavoriteListItemState[\"getItemUrl\"]> {\n if (isProduct()) {\n return infra.configuration?.urls?.getProductUrl?.(props.item) || \"\";\n }\n return infra.configuration?.urls?.getClusterUrl?.(props.item) || \"\";\n}\nfunction getItemId(): ReturnType<FavoriteListItemState[\"getItemId\"]> {\n if (isProduct()) {\n return String(getProduct()?.productId || \"\");\n }\n return String(getCluster()?.clusterId || \"\");\n}\nfunction getItemPrice(): ReturnType<FavoriteListItemState[\"getItemPrice\"]> {\n const useTax: boolean =\n infra.includeTax !== undefined ? !!infra.includeTax : false;\n let priceObj: any = null;\n if (isProduct()) {\n priceObj = getProduct()?.price;\n } else {\n priceObj = getCluster()?.defaultProduct?.price;\n }\n if (!priceObj) return \"\";\n const value: number | undefined = useTax ? priceObj?.net : priceObj?.gross;\n if (!value && value !== 0) return \"\";\n return _formatPrice(Number(value), { symbol: infra.currency ?? \"€\" });\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<FavoriteListItemState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction handleItemClick(\n e: any,\n): ReturnType<FavoriteListItemState[\"handleItemClick\"]> {\n if (props.onItemClick) {\n e.preventDefault();\n props.onItemClick(props.item);\n } else if (getItemUrl()) {\n e.preventDefault();\n window.location.href = getItemUrl();\n }\n}\nfunction handleDelete(): ReturnType<FavoriteListItemState[\"handleDelete\"]> {\n if (props.onDelete) {\n props.onDelete(getItemId());\n }\n}\n</script>\n","<template>\n <div :class=\"`propeller-grid-pagination ${className || ''}`\" :data-variant=\"variant || 'compact'\">\n <template v-if=\"showPagination()\">\n <template v-if=\"(variant || 'compact') === 'compact'\">\n <div class=\"propeller-grid-pagination__compact flex justify-center items-center gap-2\">\n <button\n type=\"button\"\n class=\"propeller-grid-pagination__btn propeller-grid-pagination__btn--prev inline-flex items-center rounded-[var(--radius-control)] border border-input bg-card px-4 py-2 text-sm font-medium text-muted-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed\"\n :disabled=\"getCurrentPage() === 1\"\n @click=\"async (event) => handlePageChange(getCurrentPage() - 1)\"\n >\n {{ getLabel('previous') }}</button\n ><span class=\"propeller-grid-pagination__info px-2 text-sm font-medium text-muted-foreground\"\n >{{ getLabel('page') }}&nbsp;{{ getCurrentPage() }}&nbsp;{{ getLabel('of') }}&nbsp;{{\n getTotalPages()\n }}</span\n ><button\n type=\"button\"\n class=\"propeller-grid-pagination__btn propeller-grid-pagination__btn--next inline-flex items-center rounded-[var(--radius-control)] border border-input bg-card px-4 py-2 text-sm font-medium text-muted-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed\"\n :disabled=\"getCurrentPage() === getTotalPages()\"\n @click=\"async (event) => handlePageChange(getCurrentPage() + 1)\"\n >\n {{ getLabel('next') }}\n </button>\n </div>\n </template>\n\n <template v-if=\"(variant || 'compact') === 'full'\">\n <div class=\"propeller-grid-pagination__full flex justify-center items-center gap-1 flex-wrap\">\n <button\n type=\"button\"\n class=\"propeller-grid-pagination__btn propeller-grid-pagination__btn--prev inline-flex items-center rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm font-medium text-muted-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed\"\n :disabled=\"getCurrentPage() === 1\"\n @click=\"async (event) => handlePageChange(getCurrentPage() - 1)\"\n >\n {{ getLabel('previous') }}</button\n ><template\n :key=\"item.type === 'dots' ? `dots-${idx}` : `page-${item.value}`\"\n v-for=\"(item, idx) in getFullPages()\"\n >\n <div class=\"propeller-grid-pagination__page-wrapper inline-flex\">\n <template v-if=\"item.type === 'dots'\">\n <span\n class=\"propeller-grid-pagination__dots inline-flex items-center justify-center min-w-[2rem] px-1 py-2 text-sm text-muted-foreground select-none\"\n >\n ...\n </span>\n </template>\n\n <template v-if=\"item.type === 'page'\">\n <button\n type=\"button\"\n @click=\"async (event) => handlePageChange(item.value)\"\n :data-active=\"item.value === getCurrentPage() ? 'true' : 'false'\"\n :class=\"\n item.value === getCurrentPage()\n ? 'propeller-grid-pagination__page inline-flex items-center justify-center min-w-[2.25rem] rounded-[var(--radius-control)] border border-primary bg-primary px-3 py-2 text-sm font-semibold text-primary-foreground shadow-sm'\n : 'propeller-grid-pagination__page inline-flex items-center justify-center min-w-[2.25rem] rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm font-medium text-muted-foreground shadow-sm hover:bg-surface-hover'\n \"\n >\n {{ item.value }}\n </button>\n </template>\n </div> </template\n ><button\n type=\"button\"\n class=\"propeller-grid-pagination__btn propeller-grid-pagination__btn--next inline-flex items-center rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm font-medium text-muted-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed\"\n :disabled=\"getCurrentPage() === getTotalPages()\"\n @click=\"async (event) => handlePageChange(getCurrentPage() + 1)\"\n >\n {{ getLabel('next') }}\n </button>\n </div>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ProductsResponse } from '@propeller-commerce/propeller-sdk-v2';\n// Built-in label defaults (can be overridden via the labels prop).\nconst DEFAULT_LABELS: Record<string, string> = {\n previous: 'Previous',\n next: 'Next',\n page: 'Page',\n of: 'of',\n};\n\n// Built-in label defaults (can be overridden via the labels prop).\n\nexport interface GridPaginationProps {\n /**\n * A ProductsResponse object for populating the pagination component.\n * Reads `page` (current page), `pages` (total pages) from the response.\n */\n products: ProductsResponse;\n\n /**\n * Called when the user navigates to a different page.\n * Receives the newly selected page number (1-based).\n */\n onPageChange: (page: number) => void;\n\n /**\n * Pagination display variant.\n * 'compact' — Previous / \"Page X of Y\" / Next.\n * 'full' — numbered page buttons with ellipsis collapsing + Previous / Next.\n * Defaults to 'compact'.\n */\n variant?: string;\n\n /**\n * Number of visible page buttons rendered around the current page in 'full' style.\n * Defaults to 5.\n */\n siblingCount?: number;\n\n /**\n * Label overrides for the text inside the component.\n * Supported keys: previous, next, page, of\n */\n labels?: Record<string, string>;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\n\n/** Single item in the computed full-style page list. */\n// Built-in label defaults (can be overridden via the labels prop).\n\n/** Single item in the computed full-style page list. */\ninterface PageItem {\n /** 'page' renders a numbered button; 'dots' renders an ellipsis spacer. */\n type: string;\n /** Page number for 'page' items; negative unique sentinel for 'dots' items. */\n value: number;\n}\n// Built-in label defaults (can be overridden via the labels prop).\n\n/** Single item in the computed full-style page list. */\n\ninterface GridPaginationState {\n getLabel: (key: string) => string;\n getTotalPages: () => number;\n getCurrentPage: () => number;\n showPagination: () => boolean;\n getFullPages: () => PageItem[];\n handlePageChange: (page: number) => void;\n}\n\nconst props = defineProps<GridPaginationProps>();\n\nfunction getLabel(key: string): ReturnType<GridPaginationState['getLabel']> {\n const labels = (props.labels as Record<string, string>) || {};\n return labels[key] !== undefined ? labels[key] : DEFAULT_LABELS[key] || key;\n}\nfunction getTotalPages(): ReturnType<GridPaginationState['getTotalPages']> {\n return (props.products as ProductsResponse)?.pages || 1;\n}\nfunction getCurrentPage(): ReturnType<GridPaginationState['getCurrentPage']> {\n return (props.products as ProductsResponse)?.page || 1;\n}\nfunction showPagination(): ReturnType<GridPaginationState['showPagination']> {\n return getTotalPages() > 1;\n}\nfunction getFullPages(): ReturnType<GridPaginationState['getFullPages']> {\n const total = getTotalPages();\n const current = getCurrentPage();\n const sibling = (props.siblingCount as number) || 5;\n\n // All pages fit without collapsing — show them all.\n if (total <= sibling + 4) {\n const items: PageItem[] = [];\n for (let i = 1; i <= total; i++)\n items.push({\n type: 'page',\n value: i,\n });\n return items;\n }\n\n // Compute sibling window, always staying inside [2, total-1].\n const halfSib = Math.floor(sibling / 2);\n let rangeStart = Math.max(2, current - halfSib);\n let rangeEnd = Math.min(total - 1, current + halfSib);\n\n // Stretch the range to ensure exactly siblingCount slots when near an edge.\n if (rangeEnd - rangeStart + 1 < sibling) {\n if (rangeStart === 2) {\n rangeEnd = Math.min(total - 1, rangeStart + sibling - 1);\n } else {\n rangeStart = Math.max(2, rangeEnd - sibling + 1);\n }\n }\n const items: PageItem[] = [];\n\n // First page\n items.push({\n type: 'page',\n value: 1,\n });\n\n // Left ellipsis (value -1 is a unique sentinel)\n if (rangeStart > 2)\n items.push({\n type: 'dots',\n value: -1,\n });\n\n // Sibling window\n for (let i = rangeStart; i <= rangeEnd; i++) {\n items.push({\n type: 'page',\n value: i,\n });\n }\n\n // Right ellipsis (value -2 is a unique sentinel)\n if (rangeEnd < total - 1)\n items.push({\n type: 'dots',\n value: -2,\n });\n\n // Last page\n items.push({\n type: 'page',\n value: total,\n });\n return items;\n}\nfunction handlePageChange(page: number): ReturnType<GridPaginationState['handlePageChange']> {\n if (props.onPageChange) props.onPageChange(page);\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-favorite-list-details ${className || ''}`\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <template v-if=\"loading\">\n <div class=\"propeller-favorite-list-details__skeleton space-y-4\">\n <template :key=\"i\" v-for=\"(i, index) in [1, 2, 3]\">\n <div\n class=\"propeller-favorite-list-details__skeleton-row flex items-center gap-4 p-4 border-b border-border animate-pulse\"\n >\n <div\n class=\"w-20 h-20 bg-surface-hover rounded-[var(--radius-control)] flex-shrink-0\"\n ></div>\n <div class=\"flex-1 space-y-2\">\n <div class=\"h-4 w-1/4 bg-surface-hover rounded\"></div>\n <div class=\"h-5 w-1/2 bg-surface-hover rounded\"></div>\n <div class=\"h-4 w-1/6 bg-surface-hover rounded\"></div>\n </div>\n <div class=\"h-10 w-28 bg-surface-hover rounded\"></div>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"!loading && isMounted\">\n <template v-if=\"allItems.length > 0\">\n <div class=\"propeller-favorite-list-details__list space-y-3\">\n <div class=\"propeller-favorite-list-details__select-all flex items-center gap-2 pb-2\">\n <input\n id=\"favorite-list-select-all-top\"\n type=\"checkbox\"\n class=\"propeller-favorite-list-details__select-all-checkbox h-4 w-4 rounded border-border accent-secondary cursor-pointer\"\n :checked=\"isAllPageSelected()\"\n @change=\"togglePageSelectAll()\"\n />\n <label\n for=\"favorite-list-select-all-top\"\n class=\"propeller-favorite-list-details__select-all-label text-sm font-medium cursor-pointer select-none\"\n >\n {{ getLabel(\"selectAll\", \"Select all\") }}\n </label>\n </div>\n <template\n :key=\"\n 'productId' in item\n ? 'p-' + item.productId\n : 'c-' + item.clusterId\n \"\n v-for=\"(item, idx) in getPagedItems()\"\n >\n <div\n class=\"propeller-favorite-list-details__row flex items-center gap-3\"\n :data-selected=\"isRowSelected(item) ? 'true' : 'false'\"\n >\n <input\n type=\"checkbox\"\n class=\"propeller-favorite-list-details__row-checkbox h-4 w-4 flex-shrink-0 rounded border-border accent-secondary cursor-pointer\"\n :checked=\"isRowSelected(item)\"\n @change=\"toggleRow(item)\"\n :aria-label=\"getLabel('selectItem', 'Select item')\"\n />\n <div class=\"propeller-favorite-list-details__row-item flex-1 min-w-0\">\n <component\n :is=\"FavoriteListItemImpl\"\n :item=\"item\"\n :graphqlClient=\"graphqlClient\"\n :user=\"user\"\n :cartId=\"cartId\"\n :createCart=\"createCart\"\n :onCartCreated=\"onCartCreated\"\n :onAddToCart=\"onAddToCart\"\n :afterAddToCart=\"afterAddToCart\"\n :showModal=\"showModal\"\n :allowIncrDecr=\"allowIncrDecr\"\n :enableStockValidation=\"enableStockValidation\"\n :language=\"language\"\n :onProceedToCheckout=\"onProceedToCheckout\"\n :onRequestQuoteClick=\"onRequestQuoteClick\"\n :addToCartLabels=\"addToCartLabels\"\n :stockLabels=\"stockLabels\"\n :labels=\"itemLabels\"\n :configuration=\"configuration\"\n :titleLinkable=\"titleLinkable\"\n :showStockComponent=\"showStockComponent\"\n :showAvailability=\"showAvailability\"\n :showStock=\"showStock\"\n :showSku=\"showSku\"\n :allowAddToCart=\"allowAddToCart\"\n :showDelete=\"showDelete\"\n :onDelete=\"(itemId: any) => handleItemDelete(itemId)\"\n :onItemClick=\"onItemClick\"\n :includeTax=\"includeTax\"\n ></component>\n </div>\n </div>\n </template>\n <template v-if=\"showPagination !== false && getTotalPages() > 1\">\n <div class=\"propeller-favorite-list-details__pagination mt-6\">\n <component\n :is=\"GridPaginationImpl\"\n :products=\"getPaginationData() as unknown as ProductsResponse\"\n :onPageChange=\"(page: any) => handlePageChange(page)\"\n :variant=\"paginationVariant || 'compact'\"\n ></component>\n </div>\n </template>\n </div>\n </template>\n\n <div class=\"propeller-favorite-list-details__add-wrapper mt-6\">\n <button\n type=\"button\"\n class=\"propeller-favorite-list-details__add-btn inline-flex items-center justify-center rounded-[var(--radius-control)] bg-secondary px-4 py-2 text-sm font-medium text-secondary-foreground transition-colors hover:bg-secondary/90\"\n @click=\"showAddModal = true\"\n >\n {{ getLabel(\"addProductDirectly\", \"Add product directly to this wishlist\") }}\n </button>\n </div>\n\n <template v-if=\"allItems.length === 0\">\n <div\n class=\"propeller-favorite-list-details__empty border border-border rounded-[var(--radius-container)] p-12 text-center space-y-4\"\n >\n <div\n class=\"propeller-favorite-list-details__empty-icon-wrapper bg-surface-hover p-4 rounded-full w-16 h-16 flex items-center justify-center mx-auto\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"propeller-favorite-list-details__empty-icon text-foreground-subtle\"\n >\n <path\n d=\"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z\"\n ></path>\n </svg>\n </div>\n <div>\n <p\n class=\"propeller-favorite-list-details__empty-title text-lg font-medium\"\n >\n {{ getLabel(\"emptyTitle\", \"List is empty\") }}\n </p>\n <p\n class=\"propeller-favorite-list-details__empty-message text-muted-foreground\"\n >\n {{\n getLabel(\n \"emptyDescription\",\n \"You haven't added any products or clusters to this list yet.\",\n )\n }}\n </p>\n </div>\n </div>\n </template>\n </template>\n\n <template v-if=\"selectedIds.size > 0\">\n <div class=\"propeller-favorite-list-details__floating-bar fixed bottom-0 left-0 right-0 z-40 border-t border-border bg-card shadow-lg\">\n <div class=\"propeller-favorite-list-details__floating-bar-inner flex items-center justify-between gap-4 px-6 py-4\">\n <div class=\"propeller-favorite-list-details__floating-bar-status flex items-center gap-2\">\n <input\n id=\"favorite-list-select-all-floating\"\n type=\"checkbox\"\n class=\"h-4 w-4 rounded border-border accent-secondary cursor-pointer\"\n :checked=\"isAllPageSelected()\"\n @change=\"togglePageSelectAll()\"\n />\n <label\n for=\"favorite-list-select-all-floating\"\n class=\"text-sm font-medium cursor-pointer select-none\"\n >\n {{ getLabel(\"selectAll\", \"Select all\") }}\n </label>\n <span class=\"propeller-favorite-list-details__floating-bar-count text-sm text-foreground-subtle ml-3\">\n {{ selectedIds.size }} {{ getLabel(\"ofWord\", \"of\") }} {{ allItems.length }} {{ getLabel(\"itemsSelected\", \"items selected\") }}\n </span>\n </div>\n <div class=\"propeller-favorite-list-details__floating-bar-actions flex items-center gap-3\">\n <button\n type=\"button\"\n class=\"propeller-favorite-list-details__bulk-remove-btn inline-flex items-center justify-center rounded-[var(--radius-control)] border border-border bg-transparent px-4 py-2 text-sm font-medium text-secondary transition-colors hover:bg-surface-hover disabled:opacity-50\"\n :disabled=\"bulkBusy\"\n @click=\"handleBulkRemove()\"\n >\n {{ getLabel(\"removeFromList\", \"Remove from this list\") }}\n </button>\n <button\n type=\"button\"\n class=\"propeller-favorite-list-details__bulk-add-btn inline-flex items-center justify-center gap-2 rounded-[var(--radius-control)] bg-secondary px-6 py-2 text-sm font-medium text-secondary-foreground transition-colors hover:bg-secondary/90 disabled:opacity-50\"\n :disabled=\"bulkBusy || getSelectedProducts().length === 0\"\n @click=\"handleBulkAddToCart()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"9\" cy=\"21\" r=\"1\" />\n <circle cx=\"20\" cy=\"21\" r=\"1\" />\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\" />\n </svg>\n {{ getLabel(\"addToCart\", \"Add to cart\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n\n <template v-if=\"showAddModal\">\n <div\n class=\"propeller-favorite-list-details__modal-overlay fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n @click=\"closeAddModal()\"\n >\n <div\n class=\"propeller-favorite-list-details__modal w-full max-w-xl rounded-[var(--radius-container)] bg-card shadow-xl\"\n @click.stop\n >\n <div class=\"propeller-favorite-list-details__modal-header border-b border-border px-6 py-4\">\n <h2 class=\"propeller-favorite-list-details__modal-title text-lg font-bold\">\n {{ getLabel(\"addProductModalTitle\", \"Add product to list\") }}\n </h2>\n </div>\n <div class=\"propeller-favorite-list-details__modal-body px-6 py-4 space-y-4\">\n <div class=\"propeller-favorite-list-details__search-input-wrapper relative\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"absolute left-3 top-1/2 -translate-y-1/2 text-foreground-subtle\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <input\n type=\"text\"\n class=\"propeller-favorite-list-details__search-input w-full rounded-[var(--radius-control)] border border-border bg-card px-9 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-secondary\"\n :placeholder=\"getLabel('searchPlaceholder', 'Search for products...')\"\n :value=\"searchTerm\"\n @input=\"onSearchInput($event)\"\n autofocus\n />\n <button\n v-if=\"searchTerm\"\n type=\"button\"\n class=\"propeller-favorite-list-details__search-clear absolute right-3 top-1/2 -translate-y-1/2 text-foreground-subtle hover:text-foreground\"\n @click=\"search('')\"\n :aria-label='getLabel(\"clearSearchAriaLabel\", \"Clear search\")'\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n <div class=\"propeller-favorite-list-details__search-results max-h-80 overflow-y-auto\">\n <template v-if=\"searchLoading\">\n <div class=\"propeller-favorite-list-details__search-loading py-6 text-center text-sm text-foreground-subtle\">\n {{ getLabel(\"searching\", \"Searching...\") }}\n </div>\n </template>\n <template v-if=\"!searchLoading && searchTerm && searchResults.length === 0\">\n <div class=\"propeller-favorite-list-details__search-empty py-6 text-center text-sm text-foreground-subtle\">\n {{ getLabel(\"noResults\", \"No results\") }}\n </div>\n </template>\n <template v-if=\"!searchLoading && searchResults.length > 0\">\n <ul class=\"propeller-favorite-list-details__search-list divide-y divide-border\">\n <li\n v-for=\"item in searchResults\"\n :key=\"getRowKey(item)\"\n class=\"propeller-favorite-list-details__search-item flex items-center gap-3 py-3 cursor-pointer hover:bg-surface-hover transition-colors px-2 rounded-[var(--radius-control)]\"\n :data-adding=\"addingItemKey === getRowKey(item) ? 'true' : 'false'\"\n @click=\"handleAddItemFromSearch(item)\"\n >\n <div class=\"propeller-favorite-list-details__search-item-media h-14 w-14 flex-shrink-0 rounded-[var(--radius-control)] bg-surface-hover overflow-hidden flex items-center justify-center\">\n <img\n v-if=\"getSearchItemImage(item)\"\n :src=\"getSearchItemImage(item)\"\n :alt=\"getSearchItemName(item)\"\n class=\"h-full w-full object-contain\"\n />\n <svg\n v-else\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"text-foreground-subtle\"\n >\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n </div>\n <div class=\"propeller-favorite-list-details__search-item-body flex-1 min-w-0\">\n <p class=\"propeller-favorite-list-details__search-item-name text-sm font-medium line-clamp-2\">\n {{ getSearchItemName(item) }}\n </p>\n <p\n v-if=\"getSearchItemSku(item)\"\n class=\"propeller-favorite-list-details__search-item-sku font-mono text-xs text-foreground-subtle mt-0.5\"\n >\n SKU: {{ getSearchItemSku(item) }}\n </p>\n <p\n v-if=\"getSearchItemStockLabel(item)\"\n class=\"propeller-favorite-list-details__search-item-stock text-xs text-foreground-subtle mt-0.5\"\n >\n {{ getSearchItemStockLabel(item) }}\n </p>\n </div>\n <span\n v-if=\"addingItemKey === getRowKey(item)\"\n class=\"propeller-favorite-list-details__search-item-spinner text-xs text-foreground-subtle\"\n >\n {{ getLabel(\"adding\", \"Adding...\") }}\n </span>\n </li>\n </ul>\n </template>\n </div>\n </div>\n <div class=\"propeller-favorite-list-details__modal-footer border-t border-border px-6 py-4 flex justify-end\">\n <button\n type=\"button\"\n class=\"propeller-favorite-list-details__modal-close inline-flex items-center justify-center rounded-[var(--radius-control)] border border-border px-6 py-2 text-sm font-medium text-secondary transition-colors hover:bg-surface-hover\"\n @click=\"closeAddModal()\"\n >\n {{ getLabel(\"close\", \"Close\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, ref, watch, toRef, computed, type Component } from \"vue\";\n\nimport {\n Product,\n Cluster,\n FavoriteList,\n GraphQLClient,\n Contact,\n Customer,\n Cart,\n CartMainItem,\n CartChildItemInput,\n ProductsResponse,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport DefaultFavoriteListItem from \"./FavoriteListItem.vue\";\nimport DefaultGridPagination from \"./GridPagination.vue\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getProductImageUrl, getClusterImageUrl } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useFavorites } from \"../composables/vue/useFavorites\";\nimport { useProductSearch } from \"../composables/vue/useProductSearch\";\nimport { useCart } from \"../composables/vue/useCart\";\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\nimport { createServices } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface FavoriteListDetailsProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** The logged in user for which the favorite list is going to be displayed */\n user: Contact | Customer;\n\n /** The favorite list ID to display */\n favoriteListId: string;\n\n /** Action method for deleting a single favorite list item. If not provided, delete button is hidden */\n onItemDelete?: (itemId: string, itemType?: string) => void;\n\n /** Batched delete callback for the floating bar \"Remove\" action. When provided, it is called once with all selected items; otherwise the component falls back to calling `onItemDelete` per item */\n onItemsDelete?: (items: { id: string; type: \"product\" | \"cluster\" }[]) => void;\n\n /** Called after the favorite list is fetched, with the full list object */\n onListLoaded?: (list: FavoriteList) => void;\n\n /** Called after an item is added to the list from the in-list search modal.\n * Use this to refresh the source the lists overview reads from (e.g. the\n * user object), so the per-list count stays correct after navigating back. */\n onItemAdded?: (item: Product | Cluster) => void;\n\n /** Number of items to show per page (default: 12) */\n itemsPerPage?: number;\n\n /** Show pagination controls (default: true) */\n showPagination?: boolean;\n\n /** Pagination display variant: 'compact' or 'full' (default: 'compact') */\n paginationVariant?: string;\n\n /** Extra CSS class applied to the root element */\n className?: string;\n\n /** Configuration object for URL generation */\n configuration?: any;\n\n /** UI string overrides */\n labels?: Record<string, string>;\n\n // === FavoriteListItem display props ===\n\n /** Should item titles link to the PDP (default: true) */\n titleLinkable?: boolean;\n\n /** Show stock availability on items (default: false) */\n showStockComponent?: boolean;\n\n /** Show availability status (e.g. \"In stock\") inside ItemStock (default: true) */\n showAvailability?: boolean;\n\n /** Show numeric stock quantity inside ItemStock (default: true) */\n showStock?: boolean;\n\n /** Display the SKU beneath item names (default: true) */\n showSku?: boolean;\n\n /** Enable add to cart for products. Clusters show \"View cluster\" instead (default: true) */\n allowAddToCart?: boolean;\n\n /** Show delete button on each item (default: true) */\n showDelete?: boolean;\n\n /** Callback when an item title or image is clicked */\n onItemClick?: (item: Product | Cluster) => void;\n\n // === AddToCart pass-through props (products only) ===\n\n /** ID of an existing cart to add items to */\n cartId?: string;\n\n /** Auto-create cart if none exists */\n createCart?: boolean;\n\n /** Called after a new cart is created internally by AddToCart */\n onCartCreated?: (cart: Cart) => void;\n\n /** Fully replaces the internal CartService.addItemToCart call */\n onAddToCart?: (\n product: Product,\n clusterId?: number,\n quantity?: number,\n childItems?: CartChildItemInput[],\n notes?: string,\n price?: number,\n showModal?: boolean,\n ) => Cart;\n\n /** Called after every successful add-to-cart */\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n\n /** Show modal after successful add (default: false) */\n showModal?: boolean;\n\n /** Renders increment/decrement buttons beside quantity input (default: true) */\n allowIncrDecr?: boolean;\n\n /** Validate stock before adding to cart (default: false) */\n enableStockValidation?: boolean;\n\n /** Language code forwarded to CartService (default: 'NL') */\n language?: string;\n\n /** Called when \"Proceed to checkout\" is clicked in AddToCart modal */\n onProceedToCheckout?: () => void;\n\n /** Called when \"Request a Quote\" is clicked in AddToCart modal */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /** Label overrides for AddToCart UI strings */\n addToCartLabels?: Record<string, string>;\n\n /** Label overrides for ItemStock UI strings */\n stockLabels?: Record<string, string>;\n\n /** Label overrides for FavoriteListItem UI strings */\n itemLabels?: Record<string, string>;\n\n /** Include tax in prices. Pass from PriceContext's usePrice() */\n includeTax?: boolean;\n\n // ───── Extension API ─────\n favoriteListItemComponent?: Component;\n gridPaginationComponent?: Component;\n}\ninterface FavoriteListDetailsState {\n loading: boolean;\n favoriteList: FavoriteList | null;\n allItems: (Product | Cluster)[];\n currentPage: number;\n isMounted: boolean;\n prevListId: string;\n getLabel: (key: string, fallback: string) => string;\n getItemsPerPage: () => number;\n getTotalPages: () => number;\n getPagedItems: () => (Product | Cluster)[];\n getPaginationData: () => Record<string, number>;\n handlePageChange: (page: number) => void;\n buildFetchVariables: () => Record<string, unknown>;\n fetchList: () => Promise<void>;\n handleItemDelete: (itemId: string) => void;\n}\n\nconst props = withDefaults(defineProps<FavoriteListDetailsProps>(), {\n titleLinkable: true,\n showSku: true,\n allowAddToCart: true,\n showDelete: true,\n showPagination: true,\n showStockComponent: false,\n showAvailability: false,\n showStock: false,\n});\nconst infra = useInfraProps(props);\n\nconst FavoriteListItemImpl = computed(() => props.favoriteListItemComponent ?? DefaultFavoriteListItem);\nconst GridPaginationImpl = computed(() => props.gridPaginationComponent ?? DefaultGridPagination);\nconst loading = ref<FavoriteListDetailsState[\"loading\"]>(true);\nconst favoriteList = ref<FavoriteListDetailsState[\"favoriteList\"]>(null);\nconst allItems = ref<FavoriteListDetailsState[\"allItems\"]>([]);\nconst currentPage = ref<FavoriteListDetailsState[\"currentPage\"]>(1);\nconst isMounted = ref<FavoriteListDetailsState[\"isMounted\"]>(false);\nconst prevListId = ref<FavoriteListDetailsState[\"prevListId\"]>(\"\");\nconst selectedIds = ref<Set<string>>(new Set());\nconst bulkBusy = ref(false);\nconst showAddModal = ref(false);\nconst addingItemKey = ref(\"\");\n\nconst userRef = computed(() => (infra.user as Contact | Customer | null | undefined) ?? null) as any;\nconst languageRef = computed(() => (infra.language as string | undefined) || \"NL\");\nconst graphqlClientRef = computed(() => infra.graphqlClient as GraphQLClient | undefined);\nconst configurationRef = computed(() => (infra.configuration ?? props.configuration ?? {}) as any);\n\nconst { addToList } = useFavorites({\n graphqlClient: graphqlClientRef.value as GraphQLClient,\n user: userRef,\n language: languageRef,\n});\n\nconst { addItem } = useCart({\n graphqlClient: graphqlClientRef.value as GraphQLClient,\n user: userRef,\n cartId: props.cartId,\n language: languageRef,\n configuration: configurationRef.value,\n onCartCreated: props.onCartCreated,\n});\n\nconst { searchTerm, searchResults, searchLoading, search } = useProductSearch({\n graphqlClient: graphqlClientRef.value as GraphQLClient,\n language: languageRef,\n user: userRef,\n configuration: configurationRef.value,\n});\n\nfunction getRowKey(item: Product | Cluster): string {\n if (\"productId\" in item) return \"p-\" + String((item as Product).productId);\n return \"c-\" + String((item as Cluster).clusterId);\n}\n\nfunction isRowSelected(item: Product | Cluster): boolean {\n return selectedIds.value.has(getRowKey(item));\n}\n\nfunction toggleRow(item: Product | Cluster) {\n const next = new Set(selectedIds.value);\n const key = getRowKey(item);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n selectedIds.value = next;\n}\n\nfunction getPageRowKeys(): string[] {\n return getPagedItems().map((i) => getRowKey(i));\n}\n\nfunction isAllPageSelected(): boolean {\n const keys = getPageRowKeys();\n if (keys.length === 0) return false;\n return keys.every((k) => selectedIds.value.has(k));\n}\n\nfunction togglePageSelectAll() {\n const next = new Set(selectedIds.value);\n const keys = getPageRowKeys();\n const allSelected = keys.every((k) => next.has(k));\n if (allSelected) keys.forEach((k) => next.delete(k));\n else keys.forEach((k) => next.add(k));\n selectedIds.value = next;\n}\n\nfunction clearSelection() {\n selectedIds.value = new Set();\n}\n\nfunction getSelectedItems(): (Product | Cluster)[] {\n return allItems.value.filter((i) => selectedIds.value.has(getRowKey(i)));\n}\n\nfunction getSelectedProducts(): Product[] {\n return getSelectedItems().filter((i) => \"productId\" in i) as Product[];\n}\n\nasync function handleBulkRemove() {\n if (bulkBusy.value) return;\n const items = getSelectedItems();\n if (items.length === 0) return;\n bulkBusy.value = true;\n try {\n const entries: { id: string; type: \"product\" | \"cluster\" }[] = items.map((it) => ({\n id:\n \"productId\" in it\n ? String((it as Product).productId)\n : String((it as Cluster).clusterId),\n type: \"productId\" in it ? \"product\" : \"cluster\",\n }));\n const remaining = allItems.value.filter(\n (p) => !selectedIds.value.has(getRowKey(p))\n );\n allItems.value = remaining;\n clearSelection();\n const newTotalPages = Math.max(\n 1,\n Math.ceil(remaining.length / getItemsPerPage())\n );\n if (currentPage.value > newTotalPages) {\n currentPage.value = newTotalPages;\n }\n if (props.onItemsDelete) {\n props.onItemsDelete(entries);\n } else if (props.onItemDelete) {\n entries.forEach((entry) =>\n props.onItemDelete!(entry.id, entry.type)\n );\n }\n } finally {\n bulkBusy.value = false;\n }\n}\n\nasync function handleBulkAddToCart() {\n if (bulkBusy.value) return;\n const products = getSelectedProducts();\n if (products.length === 0) return;\n bulkBusy.value = true;\n try {\n for (const product of products) {\n await addItem({\n product,\n quantity:\n product.minimumQuantity && product.minimumQuantity > 0\n ? product.minimumQuantity\n : 1,\n cartId: props.cartId,\n createCart: props.createCart !== false,\n enableStockValidation: props.enableStockValidation,\n afterAddToCart: (resultCart, addedItem) => {\n props.afterAddToCart?.(resultCart, addedItem || undefined);\n },\n });\n }\n clearSelection();\n } finally {\n bulkBusy.value = false;\n }\n}\n\nasync function handleAddItemFromSearch(item: Product | Cluster) {\n const key = getRowKey(item);\n if (addingItemKey.value) return;\n // Already in the list — nothing to add (guards double-add + count drift).\n if (allItems.value.some((i) => getRowKey(i) === key)) return;\n addingItemKey.value = key;\n try {\n const productId =\n \"productId\" in item ? (item as Product).productId : undefined;\n const clusterId =\n \"clusterId\" in item ? (item as Cluster).clusterId : undefined;\n await addToList(props.favoriteListId, productId, clusterId);\n // Optimistic append — mirrors the optimistic remove paths. A refetch here\n // raced the just-written item (the read could return the pre-add snapshot)\n // and reset the page to 1, so the count appeared stale and the view\n // jumped. Updating local state keeps the count and page stable.\n if (!allItems.value.some((i) => getRowKey(i) === key)) {\n allItems.value = [...allItems.value, item];\n }\n // Let the host refresh whatever the lists overview reads from (the user\n // object), so the per-list count is correct after navigating back.\n props.onItemAdded?.(item);\n } finally {\n addingItemKey.value = \"\";\n }\n}\n\nfunction getSearchItemName(item: Product | Cluster): string {\n if (\"productId\" in item)\n return (item as Product).names?.[0]?.value || \"Product\";\n const cluster = item as Cluster;\n return (\n cluster.names?.[0]?.value ||\n cluster.defaultProduct?.names?.[0]?.value ||\n \"Cluster\"\n );\n}\n\nfunction getSearchItemSku(item: Product | Cluster): string {\n if (\"productId\" in item) return (item as Product).sku || \"\";\n const cluster = item as Cluster;\n return cluster.sku || cluster.defaultProduct?.sku || \"\";\n}\n\nfunction getSearchItemImage(item: Product | Cluster): string {\n if (\"productId\" in item) return getProductImageUrl(item as Product);\n return getClusterImageUrl(item as Cluster);\n}\n\nfunction getSearchItemStockLabel(item: Product | Cluster): string {\n const qty =\n \"productId\" in item\n ? (item as Product).inventory?.totalQuantity\n : (item as Cluster).defaultProduct?.inventory?.totalQuantity;\n if (qty === undefined || qty === null) return \"\";\n if (qty <= 0) return getLabel(\"outOfStock\", \"Out of stock\");\n if (qty <= 5) return getLabel(\"lowStock\", \"Low stock\");\n return getLabel(\"inStock\", \"In stock\");\n}\n\nfunction closeAddModal() {\n showAddModal.value = false;\n search(\"\");\n}\n\nfunction onSearchInput(event: Event) {\n const target = event.target as HTMLInputElement;\n search(target.value);\n}\n\nonMounted(() => {\n isMounted.value = true;\n prevListId.value = props.favoriteListId || \"\";\n fetchList();\n});\n\nwatch(\n () => [props.favoriteListId],\n () => {\n if (props.favoriteListId && props.favoriteListId !== prevListId.value) {\n prevListId.value = props.favoriteListId;\n fetchList();\n }\n },\n { immediate: true },\n);\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<FavoriteListDetailsState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getItemsPerPage(): ReturnType<\n FavoriteListDetailsState[\"getItemsPerPage\"]\n> {\n return props.itemsPerPage || 12;\n}\nfunction getTotalPages(): ReturnType<\n FavoriteListDetailsState[\"getTotalPages\"]\n> {\n return Math.max(1, Math.ceil(allItems.value.length / getItemsPerPage()));\n}\nfunction getPagedItems(): ReturnType<\n FavoriteListDetailsState[\"getPagedItems\"]\n> {\n const perPage = getItemsPerPage();\n const start = (currentPage.value - 1) * perPage;\n return allItems.value.slice(start, start + perPage);\n}\nfunction getPaginationData(): ReturnType<\n FavoriteListDetailsState[\"getPaginationData\"]\n> {\n return {\n page: currentPage.value,\n pages: getTotalPages(),\n itemsFound: allItems.value.length,\n offset: getItemsPerPage(),\n };\n}\nfunction handlePageChange(\n page: number,\n): ReturnType<FavoriteListDetailsState[\"handlePageChange\"]> {\n currentPage.value = page;\n}\nfunction buildFetchVariables(): ReturnType<\n FavoriteListDetailsState[\"buildFetchVariables\"]\n> {\n const priceInput: Record<string, unknown> = {\n taxZone: \"NL\",\n };\n const u = (infra.user ?? props.user) as Contact | Customer | null | undefined;\n if (u) {\n if (\"customerId\" in u) {\n const customer = u as Customer;\n if (customer.customerId) {\n priceInput.customerId = customer.customerId;\n }\n } else if (\"contactId\" in u) {\n const contact = u as Contact;\n if (contact.contactId) {\n priceInput.contactId = contact.contactId;\n }\n if (contact.company?.companyId) {\n priceInput.companyId = contact.company.companyId;\n }\n }\n }\n return {\n id: props.favoriteListId,\n language: (infra.language as string | undefined) || props.language || \"NL\",\n priceCalculateProductInput: priceInput,\n imageSearchFilters: {\n page: 1,\n offset: 1,\n },\n imageVariantFilters: {\n transformations: [\n {\n name: \"cart_thumb\",\n transformation: {\n format: \"WEBP\",\n height: 200,\n width: 200,\n fit: \"BOUNDS\",\n },\n },\n ],\n },\n };\n}\nasync function fetchList(): ReturnType<FavoriteListDetailsState[\"fetchList\"]> {\n const client = (infra.graphqlClient ?? props.graphqlClient) as GraphQLClient | undefined;\n if (!client || !props.favoriteListId) return;\n loading.value = true;\n try {\n const service = createServices(client).favoriteList;\n const list = await service.getFavoriteList(\n buildFetchVariables() as unknown as Parameters<typeof service.getFavoriteList>[0],\n );\n favoriteList.value = list;\n if (props.onListLoaded) {\n props.onListLoaded(list);\n }\n const items: (Product | Cluster)[] = [];\n const productsRef = list?.products as ProductsResponse;\n if (productsRef?.items && Array.isArray(productsRef.items)) {\n (productsRef.items as Product[]).forEach((item: Product) =>\n items.push(item),\n );\n }\n const clustersRef = list?.clusters as ProductsResponse;\n if (clustersRef?.items && Array.isArray(clustersRef.items)) {\n (clustersRef.items as Cluster[]).forEach((item: Cluster) =>\n items.push(item),\n );\n }\n allItems.value = items;\n currentPage.value = 1;\n } catch (error) {\n console.error(\"Error fetching favorite list:\", error);\n favoriteList.value = null;\n allItems.value = [];\n } finally {\n loading.value = false;\n }\n}\nfunction handleItemDelete(\n itemId: string,\n): ReturnType<FavoriteListDetailsState[\"handleItemDelete\"]> {\n /* Determine item type before removing from local state */\n const deletedItem = allItems.value.find((item: Product | Cluster) => {\n if (\"productId\" in item) return String(item.productId) === itemId;\n return String((item as Cluster).clusterId) === itemId;\n });\n const itemType: string =\n deletedItem && \"clusterId\" in deletedItem ? \"cluster\" : \"product\";\n /* Optimistic: remove from local state */\n allItems.value = allItems.value.filter((item: Product | Cluster) => {\n if (\"productId\" in item) return String(item.productId) !== itemId;\n return String((item as Cluster).clusterId) !== itemId;\n });\n /* Adjust current page if needed */\n if (currentPage.value > getTotalPages()) {\n currentPage.value = Math.max(1, getTotalPages());\n }\n /* Notify parent with type info */\n if (props.onItemDelete) {\n props.onItemDelete(itemId, itemType);\n }\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-favorite-lists ${className || ''}`\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <template\n v-if=\"\n allowFavoriteListCreate !== false &&\n !loading &&\n isMounted &&\n displayedLists.length > 0\n \"\n >\n <div class=\"propeller-favorite-lists__toolbar flex justify-end mb-4\">\n <button\n class=\"propeller-favorite-lists__create-btn inline-flex items-center px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] text-primary-foreground bg-primary hover:bg-primary/80\"\n @click=\"\n async (event) => {\n showCreateModal = true;\n }\n \"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"mr-2\"\n >\n <path d=\"M5 12h14\"></path>\n <path d=\"M12 5v14\"></path></svg\n >{{ getLabel(\"createButton\", \"Create New List\") }}\n </button>\n </div>\n </template>\n\n <template v-if=\"loading\">\n <div class=\"space-y-4\">\n <div\n class=\"propeller-favorite-lists__skeleton border border-border rounded-[var(--radius-container)] p-6 animate-pulse\"\n >\n <div class=\"flex justify-between items-start\">\n <div class=\"space-y-2 flex-1\">\n <div class=\"h-6 w-1/3 bg-surface-hover rounded\"></div>\n <div class=\"h-4 w-1/4 bg-surface-hover rounded\"></div>\n <div class=\"h-4 w-1/2 bg-surface-hover rounded\"></div>\n </div>\n </div>\n </div>\n <div\n class=\"propeller-favorite-lists__skeleton border border-border rounded-[var(--radius-container)] p-6 animate-pulse\"\n >\n <div class=\"flex justify-between items-start\">\n <div class=\"space-y-2 flex-1\">\n <div class=\"h-6 w-1/3 bg-surface-hover rounded\"></div>\n <div class=\"h-4 w-1/4 bg-surface-hover rounded\"></div>\n <div class=\"h-4 w-1/2 bg-surface-hover rounded\"></div>\n </div>\n </div>\n </div>\n </div>\n </template>\n\n <template v-if=\"!loading && isMounted\">\n <template v-if=\"displayedLists.length > 0\">\n <div class=\"propeller-favorite-lists__list space-y-4\">\n <template :key=\"list.id\" v-for=\"(list, index) in displayedLists\">\n <div\n @click=\"\n async (event) => {\n if (editingListId !== String(list.id) && onListClick) {\n onListClick(list.id);\n }\n }\n \"\n :data-editing=\"\n editingListId === String(list.id) ? 'true' : 'false'\n \"\n :data-default=\"list.isDefault ? 'true' : 'false'\"\n :class=\"\n 'propeller-favorite-lists__item border border-border rounded-[var(--radius-container)] p-6 hover:bg-surface-hover transition-colors' +\n (editingListId !== String(list.id) && onListClick\n ? ' cursor-pointer'\n : '')\n \"\n >\n <div class=\"flex justify-between items-start\">\n <div class=\"flex-1\">\n <template v-if=\"editingListId === String(list.id)\">\n <div class=\"propeller-favorite-lists__edit space-y-4\">\n <div class=\"space-y-2\">\n <input\n type=\"text\"\n :placeholder='getLabel(\"createPlaceholder\", \"Enter list name\")'\n class=\"propeller-favorite-lists__input max-w-md block w-full rounded-[var(--radius-control)] border border-input px-3 py-2 text-sm focus:border-primary focus:ring-primary\"\n :value=\"editListName\"\n @change=\"\n async (e) => {\n editListName = (e.target as HTMLInputElement).value;\n }\n \"\n />\n </div>\n <div class=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n class=\"propeller-favorite-lists__checkbox rounded border-input\"\n :id=\"`default-edit-${list.id}`\"\n :checked=\"editSetAsDefault\"\n @change=\"\n async (e) => {\n editSetAsDefault = (e.target as HTMLInputElement).checked;\n }\n \"\n /><label\n class=\"propeller-favorite-lists__checkbox-label text-sm text-muted-foreground\"\n :for=\"`default-edit-${list.id}`\"\n >{{ getLabel(\"makeDefault\", \"Make default\") }}</label\n >\n </div>\n <div class=\"flex gap-2\">\n <button\n class=\"propeller-favorite-lists__save-btn inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-[var(--radius-control)] text-primary-foreground bg-primary hover:bg-primary/80 disabled:opacity-50\"\n @click=\"\n async (event) => handleUpdateList(String(list.id))\n \"\n :disabled=\"!editListName.trim()\"\n >\n {{ getLabel(\"editSave\", \"Save\") }}</button\n ><button\n class=\"propeller-favorite-lists__cancel-btn inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-[var(--radius-control)] border border-input text-muted-foreground bg-card hover:bg-surface-hover\"\n @click=\"async (event) => handleCancelEdit()\"\n >\n {{ getLabel(\"editCancel\", \"Cancel\") }}\n </button>\n </div>\n </div>\n </template>\n\n <template v-if=\"editingListId !== String(list.id)\">\n <div class=\"propeller-favorite-lists__display space-y-2\">\n <div class=\"flex items-center gap-2\">\n <span\n class=\"propeller-favorite-lists__name text-xl font-semibold\"\n >{{ list.name }}</span\n >\n <template\n v-if=\"\n showDefaultIndicator !== false && list.isDefault\n \"\n >\n <span\n class=\"propeller-favorite-lists__default-badge inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-primary/10 text-primary\"\n >{{ getLabel(\"defaultBadge\", \"Default\") }}</span\n >\n </template>\n </div>\n <div\n class=\"propeller-favorite-lists__meta flex items-center gap-4 text-sm text-muted-foreground\"\n >\n <template v-if=\"showLastModified !== false\">\n <div class=\"flex items-center gap-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"18\"\n height=\"18\"\n x=\"3\"\n y=\"4\"\n rx=\"2\"\n ry=\"2\"\n ></rect>\n <line x1=\"16\" x2=\"16\" y1=\"2\" y2=\"6\"></line>\n <line x1=\"8\" x2=\"8\" y1=\"2\" y2=\"6\"></line>\n <line x1=\"3\" x2=\"21\" y1=\"10\" y2=\"10\"></line></svg\n >{{ getLabel(\"lastModified\", \"Last modified\") }}:\n {{ formatDate(list.updatedAt) }}\n </div>\n </template>\n\n <template v-if=\"showItemsCount !== false\">\n <div class=\"flex items-center gap-1\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M16.5 9.4 7.55 4.24\"></path>\n <path\n d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"\n ></path>\n <polyline\n points=\"3.29 7 12 12 20.71 7\"\n ></polyline>\n <line x1=\"12\" x2=\"12\" y1=\"22\" y2=\"12\"></line></svg\n >{{ getTotalCount(list) }}&nbsp;{{\n getLabel(\"items\", \"items\")\n }}\n </div>\n </template>\n </div>\n </div>\n </template>\n </div>\n <template\n v-if=\"\n showActions !== false && editingListId !== String(list.id)\n \"\n >\n <div class=\"propeller-favorite-lists__actions flex gap-2\">\n <button\n :title='getLabel(\"editTooltip\", \"Edit\")'\n class=\"propeller-favorite-lists__edit-btn h-8 w-8 p-0 inline-flex items-center justify-center rounded-[var(--radius-control)] text-muted-foreground hover:text-muted-foreground hover:bg-surface-hover\"\n @click=\"\n async (e) => {\n e.stopPropagation();\n handleEditList(list);\n }\n \"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path\n d=\"M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z\"\n ></path>\n <path d=\"m15 5 4 4\"></path>\n </svg></button\n ><button\n :title='getLabel(\"deleteTooltip\", \"Delete\")'\n class=\"propeller-favorite-lists__delete-btn h-8 w-8 p-0 inline-flex items-center justify-center rounded-[var(--radius-control)] text-destructive hover:text-destructive hover:bg-destructive/10\"\n @click=\"\n async (e) => {\n e.stopPropagation();\n handleDeleteList(list);\n }\n \"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 6h18\"></path>\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\"></path>\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\"></path>\n </svg>\n </button>\n </div>\n </template>\n </div>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"displayedLists.length === 0\">\n <div\n class=\"propeller-favorite-lists__empty border border-border rounded-[var(--radius-container)] p-12 text-center space-y-4\"\n >\n <div\n class=\"propeller-favorite-lists__empty-icon-wrapper bg-surface-hover p-4 rounded-full w-16 h-16 flex items-center justify-center mx-auto\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"propeller-favorite-lists__empty-icon text-foreground-subtle\"\n >\n <path\n d=\"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3.332.67-4.5 2.17C10.832 3.67 9.26 3 7.5 3A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\"\n ></path>\n </svg>\n </div>\n <div>\n <p\n class=\"propeller-favorite-lists__empty-title text-lg font-medium\"\n >\n {{ getLabel(\"noLists\", \"No favorite lists\") }}\n </p>\n <p\n class=\"propeller-favorite-lists__empty-message text-muted-foreground\"\n >\n {{\n getLabel(\n \"noListsDescription\",\n \"Start by creating a new list to save your items.\",\n )\n }}\n </p>\n </div>\n <template v-if=\"allowFavoriteListCreate !== false\">\n <button\n class=\"propeller-favorite-lists__create-btn inline-flex items-center px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] text-primary-foreground bg-primary hover:bg-primary/80\"\n @click=\"\n async (event) => {\n showCreateModal = true;\n }\n \"\n >\n {{ getLabel(\"createFirstList\", \"Create your first list\") }}\n </button>\n </template>\n </div>\n </template>\n </template>\n\n <template v-if=\"showCreateModal\">\n <div\n class=\"propeller-favorite-lists__create-modal fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\"\n >\n <div\n class=\"propeller-favorite-lists__create-modal-content bg-card p-6 rounded-[var(--radius-container)] max-w-md w-full shadow-lg border\"\n >\n <div class=\"flex justify-between items-center mb-4\">\n <h3\n class=\"propeller-favorite-lists__create-modal-title text-xl font-bold\"\n >\n {{ getLabel(\"createTitle\", \"Create New List\") }}\n </h3>\n <button\n class=\"propeller-favorite-lists__create-modal-close h-8 w-8 p-0 inline-flex items-center justify-center rounded-[var(--radius-control)] text-muted-foreground hover:text-muted-foreground hover:bg-surface-hover\"\n @click=\"\n async (event) => {\n closeCreateModal();\n }\n \"\n >\n ×\n </button>\n </div>\n <div class=\"space-y-4\">\n <div class=\"space-y-2\">\n <label\n class=\"propeller-favorite-lists__input-label text-sm font-medium\"\n >{{ getLabel(\"nameLabel\", \"Name\") }}</label\n ><input\n type=\"text\"\n class=\"propeller-favorite-lists__input block w-full rounded-[var(--radius-control)] border border-input px-3 py-2 text-sm focus:border-primary focus:ring-primary\"\n :value=\"newListName\"\n @change=\"\n async (e) => {\n newListName = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"getLabel('createPlaceholder', 'Enter list name')\"\n />\n </div>\n <div class=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"create-set-default\"\n class=\"propeller-favorite-lists__checkbox rounded border-input\"\n :checked=\"newSetAsDefault\"\n @change=\"\n async (e) => {\n newSetAsDefault = (e.target as HTMLInputElement).checked;\n }\n \"\n /><label\n for=\"create-set-default\"\n class=\"propeller-favorite-lists__checkbox-label text-sm text-muted-foreground\"\n >{{\n getLabel(\"setAsDefault\", \"Set as default favorite list\")\n }}</label\n >\n </div>\n <div class=\"flex justify-end gap-3 pt-2\">\n <button\n class=\"propeller-favorite-lists__cancel-btn inline-flex items-center px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] border border-input text-muted-foreground bg-card hover:bg-surface-hover\"\n @click=\"\n async (event) => {\n closeCreateModal();\n }\n \"\n >\n {{ getLabel(\"cancelButton\", \"Cancel\") }}</button\n ><button\n class=\"propeller-favorite-lists__save-btn inline-flex items-center px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] text-primary-foreground bg-primary hover:bg-primary/80 disabled:opacity-50\"\n @click=\"async (event) => handleCreateList()\"\n :disabled=\"!newListName.trim()\"\n >\n {{ getLabel(\"saveButton\", \"Save\") }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </template>\n\n <template v-if=\"showDeleteModal && listToDelete\">\n <div\n class=\"propeller-favorite-lists__delete-modal fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4\"\n >\n <div\n class=\"propeller-favorite-lists__delete-modal-content bg-card p-6 rounded-[var(--radius-container)] max-w-md w-full shadow-lg border\"\n >\n <div class=\"flex justify-between items-center mb-4\">\n <h3\n class=\"propeller-favorite-lists__delete-modal-title text-xl font-bold\"\n >\n {{ getLabel(\"deleteTitle\", \"Delete Favorite List\") }}\n </h3>\n <button\n class=\"propeller-favorite-lists__delete-modal-close h-8 w-8 p-0 inline-flex items-center justify-center rounded-[var(--radius-control)] text-muted-foreground hover:text-muted-foreground hover:bg-surface-hover\"\n @click=\"async (event) => handleCancelDelete()\"\n >\n ×\n </button>\n </div>\n <div class=\"space-y-4\">\n <p class=\"propeller-favorite-lists__delete-prompt\">\n {{ getLabel(\"deleteConfirm\", \"Are you sure you want to delete\")\n }}<strong>&quot;{{ listToDelete?.name }}&quot;</strong>?\n </p>\n <p\n class=\"propeller-favorite-lists__delete-warning text-sm text-destructive\"\n >\n {{ getLabel(\"deleteWarning\", \"This action cannot be undone.\") }}\n </p>\n </div>\n <div class=\"flex justify-end gap-3 pt-6\">\n <button\n class=\"propeller-favorite-lists__cancel-btn inline-flex items-center px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] border border-input text-muted-foreground bg-card hover:bg-surface-hover\"\n @click=\"async (event) => handleCancelDelete()\"\n >\n {{ getLabel(\"cancelButton\", \"Cancel\") }}</button\n ><button\n class=\"propeller-favorite-lists__confirm-delete-btn inline-flex items-center px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] text-destructive-foreground bg-destructive hover:bg-destructive/90\"\n @click=\"async (event) => handleConfirmDelete()\"\n >\n {{ getLabel(\"deleteButton\", \"Delete\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from \"vue\";\n\nimport {\n FavoriteList,\n GraphQLClient,\n Contact,\n Customer,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useFavorites } from \"../composables/vue/useFavorites\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface FavoriteListFormData {\n name: string;\n isDefault: boolean;\n}\nexport interface FavoriteListsProps {\n /** The authenticated user (Contact or Customer) */\n user: Contact | Customer | null;\n\n /** The initialized GraphQL Client instance */\n graphqlClient: GraphQLClient;\n\n /** Callback when a list is clicked (navigate to detail) */\n onListClick?: (listId: string | number) => void;\n\n /** Limit the number of lists shown (e.g. 3 = last 3 modified). undefined = show all */\n limit?: number;\n\n /** Displays the \"Default\" badge on the favorite list (default: true) */\n showDefaultIndicator?: boolean;\n\n /** Displays the last modified date on the favorite list (default: true) */\n showLastModified?: boolean;\n\n /** Displays number of products and clusters contained in the favorite list (default: true) */\n showItemsCount?: boolean;\n\n /** Displays edit/delete action buttons on each list (default: true) */\n showActions?: boolean;\n\n /** Displays create new favorite list button (default: true) */\n allowFavoriteListCreate?: boolean;\n\n /** Custom class name */\n className?: string;\n\n /** Format date function override. If not provided, dates are formatted as dd/mm/YYYY */\n formatDate?: (dateString: string) => string;\n\n /** Localization labels */\n labels?: {\n lastModified?: string;\n items?: string;\n products?: string;\n clusters?: string;\n defaultBadge?: string;\n editSave?: string;\n editCancel?: string;\n makeDefault?: string;\n deleteTitle?: string;\n deleteConfirm?: string;\n deleteWarning?: string;\n deleteButton?: string;\n cancelButton?: string;\n createTitle?: string;\n createButton?: string;\n createPlaceholder?: string;\n setAsDefault?: string;\n saveButton?: string;\n noLists?: string;\n noListsDescription?: string;\n createFirstList?: string;\n loading?: string;\n nameLabel?: string;\n editTooltip?: string;\n deleteTooltip?: string;\n };\n\n /** Action function triggered when creating a new favorite list. If not provided, the default action is executed */\n onCreate?: (favoriteListData: FavoriteListFormData) => void;\n\n /** Action function triggered when editing a favorite list. If not provided, the default action is executed */\n onEdit?: (\n favoriteListId: string,\n favoriteListData: FavoriteListFormData,\n ) => void;\n\n /** Action function triggered when deleting a favorite list. If not provided, the default action is executed */\n onDelete?: (favoriteListId: string) => void;\n\n /** Called after any list mutation (create, edit, delete) succeeds */\n onListChanged?: () => void;\n}\ninterface FavoriteListsState {\n lists: FavoriteList[];\n loading: boolean;\n editingListId: string | null;\n editListName: string;\n editSetAsDefault: boolean;\n showDeleteModal: boolean;\n listToDelete: FavoriteList | null;\n showCreateModal: boolean;\n newListName: string;\n newSetAsDefault: boolean;\n isMounted: boolean;\n saving: boolean;\n fetchLists: () => void;\n handleEditList: (list: FavoriteList) => void;\n handleCancelEdit: () => void;\n handleUpdateList: (listId: string) => Promise<void>;\n handleDeleteList: (list: FavoriteList) => void;\n handleConfirmDelete: () => Promise<void>;\n handleCancelDelete: () => void;\n closeCreateModal: () => void;\n handleCreateList: () => Promise<void>;\n formatDate: (dateString: string) => string;\n getTotalCount: (list: FavoriteList) => number;\n getProductCount: (list: FavoriteList) => number;\n getClusterCount: (list: FavoriteList) => number;\n getLabel: (key: string, fallback: string) => string;\n displayedLists: FavoriteList[];\n}\n\nconst props = withDefaults(defineProps<FavoriteListsProps>(), {\n showDefaultIndicator: true,\n showLastModified: true,\n showItemsCount: true,\n showActions: true,\n allowFavoriteListCreate: true,\n});\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => infra.user ?? null);\n\nconst {\n lists,\n loading,\n saving,\n editingListId,\n editListName,\n editSetAsDefault,\n newListName,\n newSetAsDefault,\n listToDelete,\n fetchLists,\n startEdit,\n cancelEdit,\n updateList,\n confirmDelete,\n deleteList,\n createList,\n} = useFavorites({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n onCreate: props.onCreate,\n onEdit: props.onEdit,\n onDelete: props.onDelete,\n onListChanged: props.onListChanged,\n});\n\n// Local UI state not managed by composable\nconst showDeleteModal = ref<FavoriteListsState[\"showDeleteModal\"]>(false);\nconst showCreateModal = ref<FavoriteListsState[\"showCreateModal\"]>(false);\nconst isMounted = ref<FavoriteListsState[\"isMounted\"]>(false);\n\nonMounted(() => {\n isMounted.value = true;\n fetchLists();\n});\n\nconst displayedLists = computed(() => {\n if (props.limit && props.limit > 0) {\n // Sort by updatedAt descending, then take the first N\n const sorted = [...lists.value].sort((a: FavoriteList, b: FavoriteList) => {\n const dateA = new Date(a.updatedAt || \"\").getTime();\n const dateB = new Date(b.updatedAt || \"\").getTime();\n return dateB - dateA;\n });\n return sorted.slice(0, props.limit);\n }\n return lists.value;\n});\n\nfunction handleEditList(\n list: FavoriteList,\n): ReturnType<FavoriteListsState[\"handleEditList\"]> {\n startEdit(list);\n}\nfunction handleCancelEdit(): ReturnType<\n FavoriteListsState[\"handleCancelEdit\"]\n> {\n cancelEdit();\n}\nasync function handleUpdateList(\n listId: string,\n): ReturnType<FavoriteListsState[\"handleUpdateList\"]> {\n if (!editListName.value.trim() || saving.value) return;\n await updateList(listId);\n}\nfunction handleDeleteList(\n list: FavoriteList,\n): ReturnType<FavoriteListsState[\"handleDeleteList\"]> {\n confirmDelete(list);\n showDeleteModal.value = true;\n}\nasync function handleConfirmDelete(): ReturnType<\n FavoriteListsState[\"handleConfirmDelete\"]\n> {\n await deleteList();\n showDeleteModal.value = false;\n}\nfunction handleCancelDelete(): ReturnType<\n FavoriteListsState[\"handleCancelDelete\"]\n> {\n showDeleteModal.value = false;\n listToDelete.value = null;\n}\nfunction closeCreateModal(): ReturnType<\n FavoriteListsState[\"closeCreateModal\"]\n> {\n showCreateModal.value = false;\n}\nasync function handleCreateList(): ReturnType<\n FavoriteListsState[\"handleCreateList\"]\n> {\n if (!newListName.value.trim() || saving.value) return;\n await createList(newListName.value, newSetAsDefault.value);\n newListName.value = \"\";\n newSetAsDefault.value = false;\n closeCreateModal();\n}\nfunction formatDate(\n dateString: string,\n): ReturnType<FavoriteListsState[\"formatDate\"]> {\n if (props.formatDate) return props.formatDate(dateString);\n if (!dateString) return \"-\";\n const d = new Date(dateString);\n const day = String(d.getDate()).padStart(2, \"0\");\n const month = String(d.getMonth() + 1).padStart(2, \"0\");\n const year = d.getFullYear();\n return `${day}/${month}/${year}`;\n}\nfunction getProductCount(\n list: FavoriteList,\n): ReturnType<FavoriteListsState[\"getProductCount\"]> {\n const products = list.products;\n if (!products) return 0;\n if (products.itemsFound !== undefined) return products.itemsFound;\n if (products.items) return products.items.length;\n return 0;\n}\nfunction getClusterCount(\n list: FavoriteList,\n): ReturnType<FavoriteListsState[\"getClusterCount\"]> {\n const clusters = list.clusters;\n if (!clusters) return 0;\n if (clusters.itemsFound !== undefined) return clusters.itemsFound;\n if (clusters.items) return clusters.items.length;\n return 0;\n}\nfunction getTotalCount(\n list: FavoriteList,\n): ReturnType<FavoriteListsState[\"getTotalCount\"]> {\n return getProductCount(list) + getClusterCount(list);\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<FavoriteListsState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\n</script>\n","<template>\n <div class=\"propeller-forgot-password forgot-password-form\" :data-loading=\"loading ? 'true' : 'false'\" :data-submitted=\"submitted ? 'true' : 'false'\">\n <template v-if=\"resolvedTitle\">\n <div class=\"propeller-forgot-password__header space-y-1 text-center mb-6\">\n <h2 class=\"propeller-forgot-password__title text-2xl font-bold\">{{ resolvedTitle }}</h2>\n <template v-if=\"subtitle\">\n <p class=\"propeller-forgot-password__subtitle text-sm text-muted-foreground\">{{ subtitle }}</p>\n </template>\n </div>\n </template>\n\n <template v-if=\"!submitted\">\n <form class=\"propeller-forgot-password__form space-y-4\" @submit=\"async (e) => handleSubmit(e)\">\n <div class=\"propeller-forgot-password__field space-y-2\">\n <label for=\"forgot-password-email\" class=\"propeller-forgot-password__label text-sm font-medium leading-none\">{{\n emailLabel\n }}</label\n ><input\n type=\"email\"\n id=\"forgot-password-email\"\n name=\"email\"\n class=\"propeller-forgot-password__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"email\"\n @change=\"\n async (e) => {\n email = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"emailPlaceholder\"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <template v-if=\"errorMessage\">\n <div class=\"text-sm text-destructive bg-destructive/10 p-3 rounded-[var(--radius-control)]\">\n {{ errorMessage }}\n </div>\n </template>\n\n <button\n type=\"submit\"\n class=\"propeller-forgot-password__submit inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-[var(--radius-control)] hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"loading\"\n >\n <template v-if=\"loading\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-forgot-password__spinner animate-spin -ml-1 mr-2 h-4 w-4 text-primary-foreground\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n class=\"opacity-25\"\n ></circle>\n <path\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n class=\"opacity-75\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"loading\"> {{ props.labels?.sending || 'Sending...' }} </template>\n\n <template v-else>\n {{ resolvedButtonText }}\n </template>\n </button>\n </form>\n </template>\n\n <template v-if=\"submitted\">\n <div class=\"propeller-forgot-password__success text-center space-y-4\">\n <div class=\"flex justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n class=\"propeller-forgot-password__success-icon h-12 w-12 text-success\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n ></path>\n </svg>\n </div>\n <p class=\"propeller-forgot-password__success-message text-sm text-muted-foreground\">{{ resolvedResponseMessage }}</p>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport type { GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';\nimport { useAuth } from '../composables/vue/useAuth';\n\nexport interface ForgotPasswordProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** Title of the forgot password form\n * @default \"Forgot password?\"\n */\n title?: string;\n\n /** Subtitle of the forgot password form\n * @default \"\"\n */\n subtitle?: string;\n\n /** Label for the submit button\n * @default \"Reset\"\n */\n buttonText?: string;\n\n /** Message displayed after successful submission\n * @default \"If an account exists with this email, you will receive a password reset link shortly.\"\n */\n responseMessage?: string;\n\n /**\n * Labels for the forgot password form fields.\n *\n * Available keys:\n * - email: Email field label (default: \"Email\")\n * - emailPlaceholder: Email input placeholder (default: \"name@example.com\")\n */\n labels?: Record<string, string>;\n\n /** Callback before the forgot password process starts */\n beforeForgotPassword?: () => void;\n\n /** Callback after the user has requested a password reset */\n afterForgotPassword?: (result: boolean) => void;\n}\n\nconst props = defineProps<ForgotPasswordProps>();\nconst email = ref('');\nconst submitted = ref(false);\n\nconst { loading, error, forgotPassword } = useAuth({\n graphqlClient: props.graphqlClient,\n});\n\n\n\n\n\n\n\nconst resolvedTitle = computed(() => {\n return props.title !== undefined ? props.title : 'Forgot password?';\n});\nconst resolvedButtonText = computed(() => {\n return props.buttonText || 'Reset';\n});\nconst resolvedResponseMessage = computed(() => {\n return props.responseMessage || 'If an account exists with this email, you will receive a password reset link shortly.';\n});\nconst emailLabel = computed(() => {\n return props.labels?.email || 'Email';\n});\nconst emailPlaceholder = computed(() => {\n return props.labels?.emailPlaceholder || 'name@example.com';\n});\n// Surface a friendly fixed message for any forgot-password failure — server\n// errors can be cryptic (HTTP 4xx / GraphQL \"Unauthorized\" / etc.) and aren't\n// safe to show to end users. Override via `labels.emailNotFound` if needed.\nconst errorMessage = computed(() => {\n if (!error.value) return '';\n return (\n props.labels?.emailNotFound ||\n \"We couldn't find an account with that email address. Please double-check and try again. If you don't receive an email within a few minutes, please check that you entered the correct email address and try again.\"\n );\n});\n\nasync function handleSubmit(e: any) {\n e.preventDefault();\n if (loading.value) return;\n if (props.beforeForgotPassword) {\n props.beforeForgotPassword();\n }\n const result = await forgotPassword(email.value);\n if (result.ok) {\n submitted.value = true;\n if (props.afterForgotPassword) {\n props.afterForgotPassword(true);\n }\n } else {\n if (props.afterForgotPassword) {\n props.afterForgotPassword(false);\n }\n }\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-grid-filters space-y-4 ${isMobile ? 'pb-8' : 'sticky top-24'} ${\n isPending ? 'opacity-50 pointer-events-none' : ''\n } ${className || ''}`\"\n :data-mobile=\"isMobile ? 'true' : 'false'\"\n :data-pending=\"isPending ? 'true' : 'false'\"\n >\n <template\n v-if=\"\n showPriceFilter() && (priceMin !== undefined || priceMax !== undefined)\n \"\n >\n <div class=\"propeller-grid-filters__price space-y-3\">\n <h3\n class=\"propeller-grid-filters__price-title text-xs font-semibold uppercase tracking-wide text-muted-foreground\"\n >\n {{ getLabel(\"priceRange\", \"Price Range\") }}\n </h3>\n <div class=\"flex items-center gap-2\">\n <div class=\"relative flex-1\">\n <span\n class=\"propeller-grid-filters__price-currency absolute left-2.5 top-1/2 -translate-y-1/2 text-xs text-foreground-subtle pointer-events-none\"\n >€</span\n ><input\n type=\"number\"\n class=\"propeller-grid-filters__price-input w-full pl-6 pr-2 h-8 rounded-[var(--radius-control)] border border-border bg-card text-sm focus:outline-none focus:ring-1 focus:ring-secondary\"\n :value=\"minInput\"\n :min=\"getMinBound()\"\n :max=\"getMaxBound()\"\n @input=\"(e) => (minInput = (e.target as HTMLInputElement).value)\"\n @blur=\"async (event) => commitMinInput()\"\n @keyup.enter=\"(e) => (e.target as HTMLInputElement).blur()\"\n />\n </div>\n <span\n class=\"propeller-grid-filters__price-separator text-foreground-subtle text-sm select-none\"\n >–</span\n >\n <div class=\"relative flex-1\">\n <span\n class=\"propeller-grid-filters__price-currency absolute left-2.5 top-1/2 -translate-y-1/2 text-xs text-foreground-subtle pointer-events-none\"\n >€</span\n ><input\n type=\"number\"\n class=\"propeller-grid-filters__price-input w-full pl-6 pr-2 h-8 rounded-[var(--radius-control)] border border-border bg-card text-sm focus:outline-none focus:ring-1 focus:ring-secondary\"\n :value=\"maxInput\"\n :min=\"getMinBound()\"\n :max=\"getMaxBound()\"\n @input=\"(e) => (maxInput = (e.target as HTMLInputElement).value)\"\n @blur=\"async (event) => commitMaxInput()\"\n @keyup.enter=\"(e) => (e.target as HTMLInputElement).blur()\"\n />\n </div>\n </div>\n <div class=\"propeller-grid-filters__price-slider relative h-4 pt-1\">\n <input\n type=\"range\"\n class=\"propeller-grid-filters__price-slider-thumb absolute w-full h-1.5 bg-transparent appearance-none pointer-events-none [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-secondary [&::-webkit-slider-thumb]:cursor-pointer z-20\"\n :min=\"getMinBound()\"\n :max=\"getMaxBound()\"\n :value=\"currentMin\"\n @input=\"(e) => handleMinChange(parseFloat((e.target as HTMLInputElement).value))\"\n @pointerup=\"applyPrice()\"\n @touchend=\"applyPrice()\"\n @keyup.enter=\"applyPrice()\"\n /><input\n type=\"range\"\n class=\"propeller-grid-filters__price-slider-thumb absolute w-full h-1.5 bg-transparent appearance-none pointer-events-none [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-secondary [&::-webkit-slider-thumb]:cursor-pointer z-20\"\n :min=\"getMinBound()\"\n :max=\"getMaxBound()\"\n :value=\"currentMax\"\n @input=\"(e) => handleMaxChange(parseFloat((e.target as HTMLInputElement).value))\"\n @pointerup=\"applyPrice()\"\n @touchend=\"applyPrice()\"\n @keyup.enter=\"applyPrice()\"\n />\n <div\n class=\"propeller-grid-filters__price-slider-track absolute top-1.5 left-0 right-0 h-1.5 bg-surface-hover rounded z-10\"\n ></div>\n </div>\n </div>\n <div class=\"propeller-grid-filters__divider h-px bg-surface-hover\"></div>\n </template>\n\n <template v-if=\"filters.length === 0\">\n <p\n class=\"propeller-grid-filters__empty text-sm text-foreground-subtle italic\"\n >\n {{ getLabel(\"noFiltersAvailable\", \"No filters available\") }}\n </p>\n </template>\n\n <template\n :key=\"getFilterName(filter)\"\n v-for=\"(filter, index) in getFilteredFilters()\"\n >\n <div\n class=\"propeller-grid-filters__group border-b border-border-subtle pb-3 last:border-b-0\"\n :data-expanded=\"isExpanded(getFilterName(filter)) ? 'true' : 'false'\"\n >\n <button\n type=\"button\"\n class=\"propeller-grid-filters__group-toggle w-full flex items-center justify-between gap-2 text-left py-1 hover:text-secondary transition-colors\"\n @click=\"async (event) => toggleAccordion(getFilterName(filter))\"\n >\n <span\n class=\"propeller-grid-filters__group-title text-sm font-semibold text-muted-foreground truncate\"\n >{{ getFilterTitle(filter) }}</span\n ><svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n :class=\"`propeller-grid-filters__chevron h-4 w-4 flex-shrink-0 text-foreground-subtle transition-transform duration-200 ${\n isExpanded(getFilterName(filter)) ? 'rotate-180' : ''\n }`\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M19 9l-7 7-7-7\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </button>\n <template v-if=\"isExpanded(getFilterName(filter))\">\n <div class=\"propeller-grid-filters__options pt-2 space-y-1.5\">\n <template\n :key=\"option.value\"\n v-for=\"(option, index) in getValidOptions(filter)\"\n >\n <label\n class=\"propeller-grid-filters__option flex items-center gap-2 cursor-pointer group\"\n ><input\n type=\"checkbox\"\n class=\"propeller-grid-filters__checkbox h-4 w-4 rounded border-input text-secondary focus:ring-secondary cursor-pointer flex-shrink-0\"\n :checked=\"isSelected(getFilterName(filter), option.value)\"\n @change=\"\n async (e) =>\n handleCheckbox(filter, option.value, (e.target as HTMLInputElement).checked)\n \"\n /><span\n class=\"propeller-grid-filters__option-label flex-1 text-sm text-muted-foreground leading-none select-none group-hover:text-foreground\"\n >{{ option.value\n }}<span\n class=\"propeller-grid-filters__option-count ml-1 text-xs text-foreground-subtle\"\n >\n ({{ getCount(option) }})\n </span></span\n ></label\n >\n </template>\n </div>\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from \"vue\";\n\nimport { Contact, Customer, AttributeFilter } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from \"@propeller-commerce/propeller-v2-core-ui\";\n\nexport interface GridFiltersProps {\n /**\n * Attribute filter definitions from the ProductGrid API response.\n * Each entry describes one filterable attribute (e.g. colour, brand, size).\n */\n filters: AttributeFilter[];\n\n /**\n * Price bounds { min, max } from the current product set.\n * When absent the price section is hidden.\n */\n priceMin?: number;\n priceMax?: number;\n\n /** Language code. Defaults to 'NL'. */\n language?: string;\n\n /** Notification called after every filter change. */\n getSelectedFilters?: () => void;\n\n /**\n * Called on every checkbox toggle.\n * `filter` is the AttributeFilter; `value` is the toggled option string.\n */\n onFilterChange: (filter: AttributeFilter, value: string | number) => void;\n\n /**\n * Called when the price range changes (on blur / slider release).\n */\n onPriceChange?: (minPrice: number, maxPrice: number) => void;\n\n /** Called when \"Clear all\" is clicked. */\n onClearFilters?: () => void;\n\n /** Enable mobile-specific behaviour (drops sticky positioning). */\n isMobile?: boolean;\n\n /**\n * 'open' — show price filter for all users.\n * 'semi-closed' — hide price filter for unauthenticated users.\n */\n portalMode?: string;\n\n /** Authenticated user — price filter visibility depends on this in semi-closed mode. */\n user?: Contact | Customer | null;\n\n /**\n * Whether filter accordions start collapsed.\n * Defaults to true.\n */\n collapsed?: boolean;\n\n /** Increment this counter to reset all selected filters and price inputs externally. */\n clearSignal?: number;\n\n /** Currently active text filters (URL-driven). Syncs internal checkbox state when filters are removed externally. */\n activeTextFilters?: Record<string, string[]>;\n\n /** Currently active price filter range (URL-driven). When undefined, resets price inputs to bounds. */\n activePriceMin?: number;\n activePriceMax?: number;\n\n /**\n * When true, all checkboxes and price inputs are disabled.\n * Wire to ProductGrid's `onLoadingChange` to block rapid re-clicks while a fetch is in flight.\n */\n isLoading?: boolean;\n\n /** Extra CSS class on the root element. */\n className?: string;\n\n /** Translated labels keyed by the slugs used inside the component (see\n * `getLabel` calls). Missing keys fall back to the English defaults. */\n labels?: Record<string, string>;\n}\ninterface GridFiltersState {\n selectedFilters: Record<string, string[]>;\n currentMin: number;\n currentMax: number;\n expandedFilters: Record<string, boolean>;\n isPending: boolean;\n showPriceFilter: () => boolean;\n getFilterName: (filter: AttributeFilter) => string;\n getFilterTitle: (filter: AttributeFilter) => string;\n getFilteredFilters: () => AttributeFilter[];\n getValidOptions: (filter: AttributeFilter) => any[];\n getSelectedCount: () => number;\n hasActiveFilters: () => boolean;\n isSelected: (filterName: string, value: string) => boolean;\n isExpanded: (filterName: string) => boolean;\n toggleAccordion: (filterName: string) => void;\n handleCheckbox: (\n filter: AttributeFilter,\n value: string,\n checked: boolean,\n ) => void;\n handleMinChange: (value: number) => void;\n handleMaxChange: (value: number) => void;\n applyPrice: () => void;\n clearAll: () => void;\n getCount: (option: any) => number;\n getMinBound: () => number;\n getMaxBound: () => number;\n}\n\nconst props = withDefaults(defineProps<GridFiltersProps>(), {\n collapsed: true,\n});\nconst selectedFilters = ref<GridFiltersState[\"selectedFilters\"]>({});\nconst currentMin = ref<GridFiltersState[\"currentMin\"]>(0);\nconst currentMax = ref<GridFiltersState[\"currentMax\"]>(9999);\n// Raw text-input buffers (strings) so the user can clear a field and type a\n// fresh value. The numeric currentMin/currentMax (shared with the sliders) are\n// only committed on blur/Enter — binding the inputs to the numbers forced an\n// empty field back to 0 on every keystroke, making them impossible to edit.\nconst minInput = ref<string>(\"0\");\nconst maxInput = ref<string>(\"9999\");\nconst expandedFilters = ref<GridFiltersState[\"expandedFilters\"]>({});\nconst isPending = ref<GridFiltersState[\"isPending\"]>(false);\n// Last range pushed to the parent — guards applyPrice against no-op re-applies\n// that would leave isPending (panel blur/disable) stuck on.\nconst appliedMin = ref<number | undefined>(undefined);\nconst appliedMax = ref<number | undefined>(undefined);\n\nwatch(\n () => [props.filters],\n () => {\n const currentExp = expandedFilters.value as Record<string, boolean>;\n const open = props.collapsed === false;\n const nextExp: Record<string, boolean> = {\n ...currentExp,\n };\n let changed = false;\n ((props.filters as AttributeFilter[]) || []).forEach(\n (f: AttributeFilter) => {\n const n = f?.attributeDescription?.name;\n if (n && nextExp[n] === undefined) {\n nextExp[n] = open;\n changed = true;\n }\n },\n );\n const sel = selectedFilters.value as Record<string, string[]>;\n Object.keys(nextExp).forEach((k: string) => {\n if (nextExp[k] && !(sel[k] || []).length) {\n nextExp[k] = false;\n changed = true;\n }\n });\n if (changed) expandedFilters.value = nextExp;\n },\n { immediate: true },\n);\nwatch(\n () => [props.priceMin, props.priceMax],\n () => {\n currentMin.value = (props.priceMin as number) || 0;\n currentMax.value = (props.priceMax as number) || 9999;\n },\n { immediate: true },\n);\nwatch(\n () => [props.clearSignal],\n () => {\n if (props.clearSignal === undefined) return;\n selectedFilters.value = {};\n currentMin.value = (props.priceMin as number) || 0;\n currentMax.value = (props.priceMax as number) || 9999;\n expandedFilters.value = {};\n },\n { immediate: true },\n);\nwatch(\n () => [props.activeTextFilters],\n () => {\n if (!props.activeTextFilters) return;\n selectedFilters.value = props.activeTextFilters as Record<string, string[]>;\n },\n { immediate: true },\n);\nwatch(\n () => [props.activePriceMin, props.activePriceMax],\n () => {\n if (\n props.activePriceMin === undefined &&\n props.activePriceMax === undefined\n ) {\n currentMin.value = (props.priceMin as number) || 0;\n currentMax.value = (props.priceMax as number) || 9999;\n }\n },\n { immediate: true },\n);\nwatch(\n () => [props.isLoading],\n () => {\n if (!props.isLoading) isPending.value = false;\n },\n { immediate: true },\n);\n\n// Keep the price text-input buffers in step with the numeric source of truth\n// (slider drags, prop-driven resets). User keystrokes only touch the buffers,\n// so this never fights typing — it only re-seeds them when the number moves.\nwatch(\n () => [currentMin.value, currentMax.value],\n () => {\n minInput.value = String(currentMin.value);\n maxInput.value = String(currentMax.value);\n },\n);\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction showPriceFilter(): ReturnType<GridFiltersState[\"showPriceFilter\"]> {\n const mode = (props.portalMode as string) || \"open\";\n if (mode === \"open\") return true;\n return !!props.user;\n}\nfunction getFilterName(\n filter: AttributeFilter,\n): ReturnType<GridFiltersState[\"getFilterName\"]> {\n return (filter as AttributeFilter)?.attributeDescription?.name || \"\";\n}\nfunction getFilterTitle(\n filter: AttributeFilter,\n): ReturnType<GridFiltersState[\"getFilterTitle\"]> {\n return (\n (filter as AttributeFilter)?.attributeDescription?.descriptions?.[0]\n ?.value ||\n (filter as AttributeFilter)?.attributeDescription?.name ||\n \"\"\n );\n}\nfunction getFilteredFilters(): ReturnType<\n GridFiltersState[\"getFilteredFilters\"]\n> {\n const list = (props.filters as AttributeFilter[]) || [];\n return list.filter((f: AttributeFilter) => {\n const opts = (f?.textFilters as any[]) || [];\n return opts.some(\n (o: any) => (o?.count || 0) > 0 || (o?.countActive || 0) > 0,\n );\n });\n}\nfunction getValidOptions(\n filter: AttributeFilter,\n): ReturnType<GridFiltersState[\"getValidOptions\"]> {\n return (((filter as AttributeFilter)?.textFilters as any[]) || []).filter(\n (o: any) => (o?.count || 0) > 0 || (o?.countActive || 0) > 0,\n );\n}\nfunction getSelectedCount(): ReturnType<GridFiltersState[\"getSelectedCount\"]> {\n let n = 0;\n const sel = selectedFilters.value as Record<string, string[]>;\n Object.keys(sel).forEach((k: string) => {\n n += (sel[k] || []).length;\n });\n return n;\n}\nfunction hasActiveFilters(): ReturnType<GridFiltersState[\"hasActiveFilters\"]> {\n const sel = selectedFilters.value as Record<string, string[]>;\n return Object.keys(sel).some((k: string) => (sel[k] || []).length > 0);\n}\nfunction isSelected(\n filterName: string,\n value: string,\n): ReturnType<GridFiltersState[\"isSelected\"]> {\n return (\n (selectedFilters.value as Record<string, string[]>)[filterName] || []\n ).includes(value);\n}\nfunction isExpanded(\n filterName: string,\n): ReturnType<GridFiltersState[\"isExpanded\"]> {\n const stored = (expandedFilters.value as Record<string, boolean>)[filterName];\n if (stored === undefined) return props.collapsed === false;\n return !!stored;\n}\nfunction toggleAccordion(\n filterName: string,\n): ReturnType<GridFiltersState[\"toggleAccordion\"]> {\n const cur = !!(expandedFilters.value as Record<string, boolean>)[filterName];\n expandedFilters.value = {\n ...expandedFilters.value,\n [filterName]: !cur,\n };\n}\nfunction handleCheckbox(\n filter: AttributeFilter,\n value: string,\n checked: boolean,\n): ReturnType<GridFiltersState[\"handleCheckbox\"]> {\n const name = (filter as AttributeFilter)?.attributeDescription?.name || \"\";\n const cur = (selectedFilters.value as Record<string, string[]>)[name] || [];\n const next = checked\n ? [...cur, value]\n : cur.filter((v: string) => v !== value);\n selectedFilters.value = {\n ...selectedFilters.value,\n [name]: next,\n };\n if (next.length === 0) {\n expandedFilters.value = {\n ...expandedFilters.value,\n [name]: false,\n };\n }\n isPending.value = true;\n props.onFilterChange(filter, value);\n if (props.getSelectedFilters) props.getSelectedFilters();\n}\nfunction handleMinChange(\n value: number,\n): ReturnType<GridFiltersState[\"handleMinChange\"]> {\n const n = value > currentMax.value ? currentMax.value : value;\n currentMin.value = n;\n minInput.value = String(n);\n}\nfunction handleMaxChange(\n value: number,\n): ReturnType<GridFiltersState[\"handleMaxChange\"]> {\n const n = value < currentMin.value ? currentMin.value : value;\n currentMax.value = n;\n maxInput.value = String(n);\n}\n// Commit the raw text buffers on blur/Enter. Empty / non-numeric falls back to\n// the bound; the value is clamped into the valid range.\nfunction commitMinInput(): void {\n const parsed = parseFloat(minInput.value);\n const value = isNaN(parsed) ? getMinBound() : parsed;\n const n = Math.min(Math.max(value, getMinBound()), currentMax.value);\n currentMin.value = n;\n minInput.value = String(n);\n applyPrice(n, currentMax.value);\n}\nfunction commitMaxInput(): void {\n const parsed = parseFloat(maxInput.value);\n const value = isNaN(parsed) ? getMaxBound() : parsed;\n const n = Math.min(Math.max(value, currentMin.value), getMaxBound());\n currentMax.value = n;\n maxInput.value = String(n);\n applyPrice(currentMin.value, n);\n}\n// Apply only when the committed range differs from what's already applied —\n// re-applying an unchanged range produced no parent loading cycle, so isPending\n// (which blurs/disables the whole panel) never cleared.\nfunction applyPrice(\n min: number = currentMin.value,\n max: number = currentMax.value,\n): ReturnType<GridFiltersState[\"applyPrice\"]> {\n if (min === appliedMin.value && max === appliedMax.value) return;\n appliedMin.value = min;\n appliedMax.value = max;\n isPending.value = true;\n if (props.onPriceChange) props.onPriceChange(min, max);\n if (props.getSelectedFilters) props.getSelectedFilters();\n}\nfunction clearAll(): ReturnType<GridFiltersState[\"clearAll\"]> {\n selectedFilters.value = {};\n currentMin.value = (props.priceMin as number) || 0;\n currentMax.value = (props.priceMax as number) || 9999;\n if (props.onClearFilters) props.onClearFilters();\n if (props.getSelectedFilters) props.getSelectedFilters();\n}\nfunction getCount(option: any): ReturnType<GridFiltersState[\"getCount\"]> {\n const c = option?.count || 0;\n const ca = option?.countActive || 0;\n return c === 0 && ca > 0 ? ca : c;\n}\nfunction getMinBound(): ReturnType<GridFiltersState[\"getMinBound\"]> {\n return (props.priceMin as number) || 0;\n}\nfunction getMaxBound(): ReturnType<GridFiltersState[\"getMaxBound\"]> {\n return (props.priceMax as number) || 9999;\n}\n</script>\n","<template>\n <div :class=\"`propeller-grid-toolbar ${className || ''}`\" :data-view-mode=\"currentViewMode\">\n <div class=\"propeller-grid-toolbar__bar flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-4\">\n <div class=\"propeller-grid-toolbar__count text-sm text-muted-foreground font-medium\">\n <template v-if=\"itemsFound !== undefined && itemsFound > 0\">\n <span>{{ itemsFound }}{{ getLabel('products') }}</span>\n </template>\n </div>\n <div class=\"propeller-grid-toolbar__controls flex flex-wrap items-center gap-3\">\n <select\n class=\"propeller-grid-toolbar__select propeller-grid-toolbar__select--offset h-9 rounded-[var(--radius-control)] border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n :value=\"currentOffset\"\n @change=\"async (e) => handleOffsetChange(parseInt((e.target as HTMLSelectElement).value))\"\n >\n <template :key=\"n\" v-for=\"(n, index) in getOffsetOptions()\">\n <option :value=\"n\">{{ n }}{{ getLabel('perPage') }}</option>\n </template>\n </select>\n <div class=\"propeller-grid-toolbar__divider h-4 w-px bg-border hidden sm:block\"></div>\n <select\n class=\"propeller-grid-toolbar__select propeller-grid-toolbar__select--sort-field h-9 rounded-[var(--radius-control)] border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n :value=\"currentSortField\"\n @change=\"async (e) => handleSortFieldChange((e.target as HTMLSelectElement).value)\"\n >\n <template :key=\"field\" v-for=\"(field, index) in getSortOptions()\">\n <option :value=\"field\" :disabled=\"field === 'PRICE' && isPriceSortDisabled()\">\n {{ getLabel(field) }}\n </option>\n </template></select\n ><select\n class=\"propeller-grid-toolbar__select propeller-grid-toolbar__select--sort-order h-9 rounded-[var(--radius-control)] border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n :value=\"currentSortOrder\"\n @change=\"async (e) => handleSortOrderChange((e.target as HTMLSelectElement).value)\"\n >\n <option :value=\"SortOrder.ASC\">{{ getLabel('ASC') }}</option>\n <option :value=\"SortOrder.DESC\">\n {{ getLabel('DESC') }}\n </option></select\n ><button\n type=\"button\"\n class=\"propeller-grid-toolbar__view-toggle h-9 w-9 flex items-center justify-center rounded-[var(--radius-control)] border border-input bg-transparent hover:bg-accent hover:text-accent-foreground transition-colors\"\n @click=\"async (event) => handleViewChange()\"\n :title=\"currentViewMode === 'grid' ? getLabel('switchToList') : getLabel('switchToGrid')\"\n >\n <template v-if=\"currentViewMode === 'grid'\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"></line>\n </svg>\n </template>\n\n <template v-if=\"currentViewMode === 'list'\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect>\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect>\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>\n </svg>\n </template>\n </button>\n </div>\n </div>\n <template v-if=\"hasActiveFilters()\">\n <div class=\"propeller-grid-toolbar__active-filters flex flex-wrap gap-2 mb-4\">\n <button\n type=\"button\"\n class=\"propeller-grid-toolbar__clear-all h-7 px-2 text-xs rounded-[var(--radius-control)] hover:bg-accent hover:text-accent-foreground transition-colors\"\n @click=\"\n async (event) => {\n if (onClearFilters) onClearFilters();\n }\n \"\n >\n {{ getLabel('clearAll') }}\n </button>\n <template v-if=\"priceFilterMin !== undefined || priceFilterMax !== undefined\">\n <span\n class=\"propeller-grid-toolbar__filter-badge propeller-grid-toolbar__filter-badge--price inline-flex items-center gap-1 cursor-pointer px-2.5 py-0.5 rounded-full text-xs font-semibold border border-input bg-background hover:bg-primary hover:text-destructive-foreground hover:border-primary transition-colors\"\n @click=\"\n async (event) => {\n if (onPriceFilterRemove) onPriceFilterRemove();\n }\n \"\n >{{ getLabel('price') }}: € {{ priceFilterMin ?? 0 }} – €{{ priceFilterMax ?? '∞'\n }}<span class=\"propeller-grid-toolbar__filter-badge-remove\">×</span></span\n >\n </template>\n\n <template\n :key=\"`${badge.key}-${badge.value}`\"\n v-for=\"(badge, index) in getActiveFilterBadges()\"\n >\n <span\n class=\"propeller-grid-toolbar__filter-badge inline-flex items-center gap-1 cursor-pointer px-2.5 py-0.5 rounded-full text-xs font-semibold border border-input bg-background hover:bg-primary hover:text-destructive-foreground hover:border-primary transition-colors\"\n :data-filter-key=\"badge.key\"\n @click=\"\n async (event) => {\n if (onFilterRemove) onFilterRemove(badge.key, badge.value);\n }\n \"\n >{{ badge.value }}<span class=\"propeller-grid-toolbar__filter-badge-remove\">×</span></span\n >\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\n\nimport { Contact, Customer, ProductSortField, SortOrder } from '@propeller-commerce/propeller-sdk-v2';\n// Default sort field keys shown in the dropdown when sortOptions is not provided.\nconst ALL_SORT_FIELDS: string[] = [\n ProductSortField.CATEGORY_ORDER,\n ProductSortField.NAME,\n ProductSortField.PRICE,\n ProductSortField.SKU,\n ProductSortField.SUPPLIER_CODE,\n ProductSortField.CREATED_AT,\n ProductSortField.LAST_MODIFIED_AT,\n ProductSortField.RELEVANCE,\n ProductSortField.PRIORITY,\n];\n\n// Built-in label defaults (can be overridden via the labels prop).\n// Built-in label defaults (can be overridden via the labels prop).\nconst DEFAULT_LABELS: Record<string, string> = {\n [ProductSortField.CATEGORY_ORDER]: 'Default Sorting',\n [ProductSortField.NAME]: 'Name',\n [ProductSortField.PRICE]: 'Price',\n [ProductSortField.SKU]: 'SKU',\n [ProductSortField.SUPPLIER_CODE]: 'Supplier Code',\n [ProductSortField.CREATED_AT]: 'Created Date',\n [ProductSortField.LAST_MODIFIED_AT]: 'Last Modified Date',\n [ProductSortField.RELEVANCE]: 'Relevance',\n [ProductSortField.PRIORITY]: 'Priority',\n [SortOrder.ASC]: 'Low to High',\n [SortOrder.DESC]: 'High to Low',\n clearAll: 'Clear All',\n products: ' Products',\n from: 'from',\n results: 'results',\n perPage: ' per page',\n price: 'Price',\n switchToList: 'Switch to list view',\n switchToGrid: 'Switch to grid view',\n};\n\n// Default sort field keys shown in the dropdown when sortOptions is not provided.\n\nexport interface GridToolbarProps {\n /**\n * Sort field keys to show in the sort dropdown.\n * Accepts keys of the ProductSortField enum (e.g. 'NAME', 'PRICE').\n * Defaults to all available sort fields.\n */\n sortOptions?: string[];\n\n /**\n * Active sort — first element is used.\n * Defaults to [{ field: 'CATEGORY_ORDER', order: 'DESC' }].\n */\n defaultSort?: {\n field: string;\n order: string;\n }[];\n\n /**\n * Layout mode: 'grid' or 'list'.\n * Controls which icon the view-toggle button shows.\n * Defaults to 'grid'.\n */\n viewMode?: string;\n\n /**\n * Available page-size options shown in the per-page dropdown.\n * Defaults to [12, 24, 48].\n */\n offset?: number[];\n\n /**\n * Initially selected page size.\n * Defaults to 12.\n */\n defaultOffset?: number;\n\n /**\n * Called when the sort field or sort direction changes.\n * Receives the new field key and direction ('ASC'|'DESC').\n */\n onSortChange?: (field: string, order: string) => void;\n\n /**\n * Called when the user selects a different per-page value.\n * Receives the new page size number.\n */\n onOffsetChange?: (offset: number) => void;\n\n /**\n * Called when the user clicks the view-mode toggle button.\n * Receives the new mode: 'grid' or 'list'.\n */\n onViewChange?: (mode: string) => void;\n\n /**\n * Total products found — displayed as a result count on the left side.\n * Pass 0 or undefined to hide the count.\n */\n itemsFound?: number;\n\n /**\n * Current page number. Used together with `pageSize` and `itemsFound`\n * to display a range indicator (e.g. \"1–10 from 594 results\").\n * When omitted the component falls back to a simple total count.\n */\n page?: number;\n\n /**\n * Items per page. Used together with `page` and `itemsFound`\n * to compute the result range. Defaults to 12.\n */\n pageSize?: number;\n\n /**\n * Actual number of items visible on the current page.\n * When provided, overrides `pageSize` for the range end calculation.\n */\n pageItemCount?: number;\n\n /**\n * Currently active attribute filter selections.\n * Key = attribute name, value = array of selected values.\n * Used to render removable filter badges.\n */\n activeTextFilters?: Record<string, string[]>;\n\n /**\n * Currently active price filter lower bound.\n * When defined (together with or without priceFilterMax), renders a price badge.\n */\n priceFilterMin?: number;\n\n /**\n * Currently active price filter upper bound.\n */\n priceFilterMax?: number;\n\n /**\n * Called when an attribute filter badge × is clicked.\n * Receives the attribute name and the specific value to remove.\n */\n onFilterRemove?: (filterName: string, value: string) => void;\n\n /**\n * Called when the price filter badge × is clicked.\n */\n onPriceFilterRemove?: () => void;\n\n /**\n * Called when \"Clear All\" is clicked.\n */\n onClearFilters?: () => void;\n\n /**\n * Label overrides. Supply any subset of DEFAULT_LABELS keys plus\n * any of the ProductSortField key strings to customise display text.\n */\n labels?: Record<string, string>;\n\n /**\n * Portal visibility mode.\n * 'open' — price sorting is available for all users.\n * 'semi-closed' — price sorting is disabled for unauthenticated users.\n */\n portalMode?: string;\n\n /**\n * Authenticated user object.\n * When null/undefined in semi-closed mode the PRICE sort option is disabled.\n */\n user?: Contact | Customer | null;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\n\n/** Flat badge item used when rendering the active-filters bar. */\n// Default sort field keys shown in the dropdown when sortOptions is not provided.\n\n/** Flat badge item used when rendering the active-filters bar. */\ninterface FilterBadge {\n key: string;\n value: string;\n}\n// Default sort field keys shown in the dropdown when sortOptions is not provided.\n\n/** Flat badge item used when rendering the active-filters bar. */\n\ninterface GridToolbarState {\n currentSortField: string;\n currentSortOrder: string;\n currentOffset: number;\n currentViewMode: string;\n getLabel: (key: string) => string;\n getSortOptions: () => string[];\n getOffsetOptions: () => number[];\n hasActiveFilters: () => boolean;\n getActiveFilterBadges: () => FilterBadge[];\n isPriceSortDisabled: () => boolean;\n handleSortFieldChange: (field: string) => void;\n handleSortOrderChange: (order: string) => void;\n handleOffsetChange: (offset: number) => void;\n handleViewChange: () => void;\n}\n\nconst props = defineProps<GridToolbarProps>();\nconst currentSortField = ref<GridToolbarState['currentSortField']>(\n ProductSortField.CATEGORY_ORDER\n);\nconst currentSortOrder = ref<GridToolbarState['currentSortOrder']>(SortOrder.DESC);\nconst currentOffset = ref<GridToolbarState['currentOffset']>(12);\nconst currentViewMode = ref<GridToolbarState['currentViewMode']>('grid');\n\nwatch(\n () => [props.defaultSort],\n () => {\n const sort =\n (props.defaultSort as {\n field: string;\n order: string;\n }[]) || [];\n currentSortField.value =\n sort.length > 0\n ? sort[0].field || ProductSortField.CATEGORY_ORDER\n : ProductSortField.CATEGORY_ORDER;\n currentSortOrder.value =\n sort.length > 0 ? sort[0].order || SortOrder.DESC : SortOrder.DESC;\n },\n { immediate: true }\n);\nwatch(\n () => [props.defaultOffset],\n () => {\n currentOffset.value = (props.defaultOffset as number) || 12;\n },\n { immediate: true }\n);\nwatch(\n () => [props.viewMode],\n () => {\n if (props.viewMode) {\n currentViewMode.value = props.viewMode as string;\n }\n },\n { immediate: true }\n);\nfunction getLabel(key: string): ReturnType<GridToolbarState['getLabel']> {\n const labels = (props.labels as Record<string, string>) || {};\n return labels[key] !== undefined ? labels[key] : DEFAULT_LABELS[key] || key;\n}\nfunction getSortOptions(): ReturnType<GridToolbarState['getSortOptions']> {\n const opts = (props.sortOptions as string[]) || [];\n return opts.length > 0 ? opts : ALL_SORT_FIELDS;\n}\nfunction getOffsetOptions(): ReturnType<GridToolbarState['getOffsetOptions']> {\n const opts = (props.offset as number[]) || [];\n return opts.length > 0 ? opts : [12, 24, 48];\n}\nfunction hasActiveFilters(): ReturnType<GridToolbarState['hasActiveFilters']> {\n const text = (props.activeTextFilters as Record<string, string[]>) || {};\n const hasText = Object.keys(text).some((k) => (text[k] || []).length > 0);\n const hasPrice = props.priceFilterMin !== undefined || props.priceFilterMax !== undefined;\n return hasText || hasPrice;\n}\nfunction getActiveFilterBadges(): ReturnType<GridToolbarState['getActiveFilterBadges']> {\n const text = (props.activeTextFilters as Record<string, string[]>) || {};\n const badges: FilterBadge[] = [];\n Object.entries(text)\n .filter(([, values]) => (values || []).length > 0)\n .forEach(([key, values]) => {\n (values || []).forEach((value: string) => {\n badges.push({\n key,\n value,\n });\n });\n });\n return badges;\n}\nfunction isPriceSortDisabled(): ReturnType<GridToolbarState['isPriceSortDisabled']> {\n return (props.portalMode as string) === 'semi-closed' && !props.user;\n}\nfunction handleSortFieldChange(\n field: string\n): ReturnType<GridToolbarState['handleSortFieldChange']> {\n currentSortField.value = field;\n if (props.onSortChange) props.onSortChange(field, currentSortOrder.value);\n}\nfunction handleSortOrderChange(\n order: string\n): ReturnType<GridToolbarState['handleSortOrderChange']> {\n currentSortOrder.value = order;\n if (props.onSortChange) props.onSortChange(currentSortField.value, order);\n}\nfunction handleOffsetChange(offset: number): ReturnType<GridToolbarState['handleOffsetChange']> {\n currentOffset.value = offset;\n if (props.onOffsetChange) props.onOffsetChange(offset);\n}\nfunction handleViewChange(): ReturnType<GridToolbarState['handleViewChange']> {\n const next = currentViewMode.value === 'grid' ? 'list' : 'grid';\n currentViewMode.value = next;\n if (props.onViewChange) props.onViewChange(next);\n}\n</script>\n","<template>\n <component\n :is=\"'script'\"\n v-if=\"payload\"\n type=\"application/ld+json\"\n v-html=\"payload\"\n />\n</template>\n\n<script setup lang=\"ts\">\n/**\n * Pure SSR-safe component. Emits a single `<script type=\"application/ld+json\">`\n * containing a schema.org `ItemList` of `Product` items, one per element in\n * the `products` array. Scope is first-page only — caller passes whatever\n * array is present in the initial SSR HTML; client-side filter/sort/page\n * navigation does NOT update the script tag.\n *\n * See `ProductJsonLd.vue` for the dynamic-`script` rendering rationale.\n */\nimport { computed } from 'vue';\nimport type { Product } from '@propeller-commerce/propeller-sdk-v2';\nimport {\n buildItemListJsonLd,\n safeJsonStringify,\n type JsonLdContext,\n} from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface ItemListJsonLdProps {\n /** First-page products (from server-side fetch). */\n products: ReadonlyArray<Product>;\n /** Per-request context: siteUrl, language, currency, portalMode, user, URL builders. */\n context: JsonLdContext;\n}\n\nconst props = defineProps<ItemListJsonLdProps>();\n\nconst payload = computed<string | null>(() => {\n const data = buildItemListJsonLd(props.products, props.context);\n return data ? safeJsonStringify(data) : null;\n});\n</script>\n","<template>\n <div :class=\"`propeller-items-overview ${containerClass}`\">\n <template v-if=\"title\">\n <h2 class=\"propeller-items-overview__title text-lg font-bold mb-4\">\n {{ title }}\n </h2>\n </template>\n\n <div class=\"propeller-items-overview__list space-y-4\">\n <template :key=\"item.itemId || index\" v-for=\"(item, index) in items\">\n <div\n class=\"propeller-items-overview__item flex gap-3 pb-3 border-b border-border last:border-b-0 last:pb-0\"\n :data-bundle=\"isBundleItem(item) ? 'true' : 'false'\"\n >\n <template v-if=\"showImage\">\n <div\n class=\"propeller-items-overview__item-media w-16 h-16 flex-shrink-0 bg-surface-hover rounded-[var(--radius-control)] overflow-hidden border border-border-subtle flex items-center justify-center\"\n >\n <template v-if=\"getItemImageUrl(item)\">\n <img\n class=\"propeller-items-overview__item-image w-full h-full object-contain p-1.5\"\n :src=\"getItemImageUrl(item)\"\n :alt=\"getItemName(item)\"\n />\n </template>\n\n <template v-if=\"!getItemImageUrl(item)\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n class=\"propeller-items-overview__item-image-placeholder w-6 h-6 text-foreground-subtle\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z\"\n ></path>\n </svg>\n </template>\n </div>\n </template>\n\n <div class=\"propeller-items-overview__item-body flex-1 min-w-0\">\n <template v-if=\"isBundleItem(item)\">\n <div>\n <div class=\"flex justify-between items-start gap-2\">\n <span\n class=\"propeller-items-overview__item-title text-sm font-medium leading-tight text-foreground line-clamp-2\"\n >{{ getBundleName(item) }}</span\n >\n <template v-if=\"showPrice && !!getBundlePrice(item)\">\n <span\n class=\"propeller-items-overview__item-price font-semibold text-sm text-foreground whitespace-nowrap\"\n >{{ getBundlePrice(item) }}</span\n >\n </template>\n </div>\n <div\n class=\"propeller-items-overview__item-bundle mt-1.5 space-y-1 border-l-2 border-secondary/10 pl-2\"\n >\n <template v-if=\"!!getBundleLeaderName(item)\">\n <div\n class=\"propeller-items-overview__item-bundle-leader flex justify-between items-center text-xs\"\n >\n <span class=\"font-medium text-muted-foreground\">{{\n getBundleLeaderName(item)\n }}</span>\n <template v-if=\"!!getBundleLeaderPrice(item)\">\n <span\n class=\"text-muted-foreground whitespace-nowrap ml-2\"\n >{{ getBundleLeaderPrice(item) }}</span\n >\n </template>\n </div>\n </template>\n\n <template\n :key=\"idx\"\n v-for=\"(bundleItem, idx) in getBundleNonLeaders(item)\"\n >\n <div\n class=\"propeller-items-overview__item-bundle-item flex justify-between items-center text-xs text-muted-foreground\"\n >\n <span class=\"line-clamp-1\">{{\n getBundleItemName(bundleItem)\n }}</span>\n <template v-if=\"!!getBundleItemPrice(bundleItem)\">\n <span\n class=\"text-foreground-subtle whitespace-nowrap ml-2\"\n >{{ getBundleItemPrice(bundleItem) }}</span\n >\n </template>\n </div>\n </template>\n </div>\n </div>\n <div\n class=\"propeller-items-overview__item-qty flex items-center text-xs text-foreground-subtle mt-1\"\n >\n <span\n >{{ getLabel(\"quantity\", \"Qty:\") }}{{ item.quantity }}</span\n >\n </div>\n </template>\n\n <template v-if=\"!isBundleItem(item)\">\n <div>\n <div class=\"flex justify-between items-start gap-2\">\n <template v-if=\"itemNameClickable\">\n <p\n class=\"propeller-items-overview__item-title font-medium text-sm leading-tight cursor-pointer hover:text-secondary transition-colors line-clamp-2\"\n @click=\"async (event) => handleItemNameClick(item)\"\n >\n {{ getItemName(item) }}\n </p>\n </template>\n\n <template v-if=\"!itemNameClickable\">\n <p\n class=\"propeller-items-overview__item-title font-medium text-sm leading-tight line-clamp-2\"\n >\n {{ getItemName(item) }}\n </p>\n </template>\n\n <template v-if=\"showPrice\">\n <span\n class=\"propeller-items-overview__item-price font-semibold text-sm text-foreground whitespace-nowrap\"\n >{{ formatItemPrice(getItemTotalPrice(item)) }}</span\n >\n </template>\n </div>\n <template v-if=\"showSku && getItemSku(item)\">\n <p\n class=\"propeller-items-overview__item-sku text-xs text-muted-foreground mt-0.5\"\n >\n SKU: {{ getItemSku(item) }}\n </p>\n </template>\n\n <template v-if=\"getItemSurcharges(item).length > 0\">\n <div class=\"propeller-items-overview__item-surcharges mt-1 text-xs text-muted-foreground\">\n <span class=\"font-medium\">{{ getLabel(\"surcharges\", \"Additional surcharges:\") }}</span>\n <ul class=\"propeller-items-overview__item-surcharges-list mt-0.5\">\n <li\n v-for=\"(line, idx) in getItemSurcharges(item)\"\n :key=\"idx\"\n class=\"propeller-items-overview__item-surcharge\"\n >\n {{ line }}\n </li>\n </ul>\n </div>\n </template>\n\n <template v-if=\"getItemChildItems(item).length > 0\">\n <div\n class=\"propeller-items-overview__item-options mt-1.5 space-y-1 border-l-2 border-border-subtle pl-2\"\n >\n <template\n :key=\"idx\"\n v-for=\"(child, idx) in getItemChildItems(item)\"\n >\n <div\n class=\"propeller-items-overview__item-option flex justify-between items-center text-xs text-muted-foreground\"\n >\n <span class=\"line-clamp-1\">{{\n child.product?.names?.[0]?.value || \"Option\"\n }}</span\n ><span\n class=\"text-foreground-subtle whitespace-nowrap ml-2\"\n >{{ formatItemPrice(child.totalSum || 0) }}</span\n >\n </div>\n </template>\n </div>\n </template>\n </div>\n <div\n class=\"propeller-items-overview__item-qty flex items-center text-xs text-foreground-subtle mt-1\"\n >\n <span\n >{{ getLabel(\"quantity\", \"Qty:\") }}{{ item.quantity }}</span\n >\n <template v-if=\"showAvailability && getItemAvailability(item)\">\n <span\n :class=\"`propeller-items-overview__item-availability ml-2 ${isInStock(item) ? 'text-success' : 'text-destructive'}`\"\n :data-in-stock=\"isInStock(item) ? 'true' : 'false'\"\n >{{ getItemAvailability(item) }}</span\n >\n </template>\n </div>\n </template>\n </div>\n </div>\n </template>\n </div>\n <template v-if=\"items.length === 0\">\n <p\n class=\"propeller-items-overview__empty text-muted-foreground italic text-sm\"\n >\n {{ getLabel(\"noItems\", \"No items in cart.\") }}\n </p>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport { BundleItem, Cart, CartBaseItem, CartMainItem, YesNo } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice, formatSurcharge as _formatSurcharge } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface ItemsOverviewProps {\n /** Shopping cart object from which the cart items overview will be displayed */\n cart: Cart;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** Active language for localized surcharge names. */\n language?: string;\n\n /** The CSS class for the cart items overview container */\n itemsOverviewContainerClass?: string;\n\n /** Title of the cart items overview */\n title?: string;\n\n /** The cart items names are clickable links */\n itemNameClickable?: boolean;\n\n /** Action when a cart item's name is clicked */\n onCartItemNameClick?: (item: CartMainItem) => void;\n\n /** Show the quantity of the cart item */\n showQuantity?: boolean;\n\n /** Show the availability of the cart item */\n showAvailability?: boolean;\n\n /** Show the SKU of the cart item */\n showSku?: boolean;\n\n /** Show a small image of the cart item */\n showImage?: boolean;\n\n /** Show the price of the cart item */\n showPrice?: boolean;\n\n /** Custom price formatting function */\n formatPrice?: (price: number) => string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n}\ninterface ItemsOverviewState {\n containerClass: string;\n itemNameClickable: boolean;\n showQuantity: boolean;\n showAvailability: boolean;\n showSku: boolean;\n showImage: boolean;\n showPrice: boolean;\n getLabel: (key: string, fallback: string) => string;\n formatItemPrice: (price: number) => string;\n items: any[];\n getItemName: (item: any) => string;\n getItemSku: (item: any) => string;\n getItemImageUrl: (item: any) => string;\n getItemTotalPrice: (item: any) => number;\n getItemAvailability: (item: any) => string;\n isInStock: (item: any) => boolean;\n handleItemNameClick: (item: any) => void;\n getItemChildItems: (item: any) => any[];\n isBundleItem: (item: any) => boolean;\n getBundleName: (item: any) => string;\n getBundlePrice: (item: any) => string;\n getBundleLeaderName: (item: any) => string;\n getBundleLeaderPrice: (item: any) => string;\n getBundleNonLeaders: (item: any) => any[];\n getBundleItemName: (bundleItem: any) => string;\n getBundleItemPrice: (bundleItem: any) => string;\n}\n\nconst props = withDefaults(defineProps<ItemsOverviewProps>(), {\n itemNameClickable: true,\n showQuantity: true,\n showAvailability: true,\n showSku: true,\n showImage: true,\n showPrice: true,\n});\nconst infra = useInfraProps(props);\n\nconst containerClass = computed(() => {\n return props.itemsOverviewContainerClass || \"cart-items-overview\";\n});\nconst itemNameClickable = computed(() => {\n return props.itemNameClickable !== undefined ? props.itemNameClickable : true;\n});\nconst showQuantity = computed(() => {\n return props.showQuantity !== undefined ? props.showQuantity : true;\n});\nconst showAvailability = computed(() => {\n return props.showAvailability !== undefined ? props.showAvailability : true;\n});\nconst showSku = computed(() => {\n return props.showSku !== undefined ? props.showSku : true;\n});\nconst showImage = computed(() => {\n return props.showImage !== undefined ? props.showImage : true;\n});\nconst showPrice = computed(() => {\n return props.showPrice !== undefined ? props.showPrice : true;\n});\nconst items = computed(() => {\n return (props.cart as any)?.items || [];\n});\n\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<ItemsOverviewState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatItemPrice(\n price: number,\n): ReturnType<ItemsOverviewState[\"formatItemPrice\"]> {\n if (props.formatPrice) {\n return props.formatPrice(price);\n }\n return _formatPrice(price || 0, { symbol: infra.currency ?? \"€\" });\n}\nfunction getItemName(item: any): ReturnType<ItemsOverviewState[\"getItemName\"]> {\n return item.product?.names?.[0]?.value || \"Product\";\n}\nfunction getItemSku(item: any): ReturnType<ItemsOverviewState[\"getItemSku\"]> {\n return item.product?.sku || \"\";\n}\nfunction getItemImageUrl(\n item: any,\n): ReturnType<ItemsOverviewState[\"getItemImageUrl\"]> {\n const url = item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url;\n if (url && typeof url === \"string\" && url.startsWith(\"http\")) {\n return url;\n }\n return \"\";\n}\nfunction getItemTotalPrice(\n item: any,\n): ReturnType<ItemsOverviewState[\"getItemTotalPrice\"]> {\n return (item.price || 0) * (item.quantity || 1);\n}\nfunction getItemAvailability(\n item: any,\n): ReturnType<ItemsOverviewState[\"getItemAvailability\"]> {\n const stock = item.product?.inventory?.totalQuantity;\n if (stock === undefined || stock === null) return \"\";\n if (stock > 0) return props.labels?.[\"inStock\"] || \"In stock\";\n return props.labels?.[\"outOfStock\"] || \"Out of stock\";\n}\nfunction isInStock(item: any): ReturnType<ItemsOverviewState[\"isInStock\"]> {\n const stock = item.product?.inventory?.totalQuantity;\n return stock !== undefined && stock !== null && stock > 0;\n}\nfunction handleItemNameClick(\n item: any,\n): ReturnType<ItemsOverviewState[\"handleItemNameClick\"]> {\n if (\n (props.itemNameClickable !== undefined ? props.itemNameClickable : true) &&\n props.onCartItemNameClick\n ) {\n props.onCartItemNameClick(item as CartMainItem);\n }\n}\nfunction getItemChildItems(\n item: any,\n): ReturnType<ItemsOverviewState[\"getItemChildItems\"]> {\n const children = item.childItems;\n if (!children || !Array.isArray(children)) return [];\n return children;\n}\nfunction getItemSurcharges(item: any): string[] {\n // Cart-line surcharges (CartItemSurcharge: localized `names`, own quantity).\n // Format: `{qty} x € {value} (name)` / `{qty} x {value}% (name)`.\n type SurchargeLike = {\n name?: { value?: string; language?: string }[];\n names?: { value?: string; language?: string }[];\n type?: string;\n value?: number;\n quantity?: number;\n enabled?: boolean;\n };\n const list = ((item.surcharges ?? []) as SurchargeLike[]).filter(\n (s: SurchargeLike) => s.enabled !== false,\n );\n return list\n .map((s: SurchargeLike) =>\n _formatSurcharge(s, {\n quantity: s.quantity ?? item.quantity ?? 1,\n language: infra.language,\n currency: infra.currency ?? \"€\",\n }),\n )\n .filter((line: string) => line.length > 0);\n}\nfunction isBundleItem(\n item: any,\n): ReturnType<ItemsOverviewState[\"isBundleItem\"]> {\n return !!item.bundle;\n}\nfunction getBundleName(\n item: any,\n): ReturnType<ItemsOverviewState[\"getBundleName\"]> {\n return item.bundle?.name || \"Bundle\";\n}\nfunction getBundlePrice(\n item: any,\n): ReturnType<ItemsOverviewState[\"getBundlePrice\"]> {\n const price = item.bundle?.price?.net;\n if (price === undefined || price === null) return \"\";\n return _formatPrice(Number(price), { symbol: infra.currency ?? \"€\" });\n}\nfunction getBundleLeaderName(\n item: any,\n): ReturnType<ItemsOverviewState[\"getBundleLeaderName\"]> {\n const items = item.bundle?.items;\n if (!items) return \"\";\n const leader = items.find((bi: BundleItem) => bi.isLeader === YesNo.Y);\n if (!leader) return \"\";\n return leader.product.names?.[0]?.value || \"Product\";\n}\nfunction getBundleLeaderPrice(\n item: any,\n): ReturnType<ItemsOverviewState[\"getBundleLeaderPrice\"]> {\n const items = item.bundle?.items;\n if (!items) return \"\";\n const leader = items.find((bi: BundleItem) => bi.isLeader === YesNo.Y);\n if (!leader) return \"\";\n const price = leader.price?.net;\n if (price === undefined || price === null) return \"\";\n return _formatPrice(Number(price), { symbol: infra.currency ?? \"€\" });\n}\nfunction getBundleNonLeaders(\n item: any,\n): ReturnType<ItemsOverviewState[\"getBundleNonLeaders\"]> {\n const items = item.bundle?.items;\n if (!items) return [];\n return items.filter((bi: BundleItem) => bi.isLeader !== YesNo.Y);\n}\nfunction getBundleItemName(\n bundleItem: any,\n): ReturnType<ItemsOverviewState[\"getBundleItemName\"]> {\n return bundleItem.product?.names?.[0]?.value || \"Product\";\n}\nfunction getBundleItemPrice(\n bundleItem: any,\n): ReturnType<ItemsOverviewState[\"getBundleItemPrice\"]> {\n const price = bundleItem.price?.net;\n if (price === undefined || price === null) return \"\";\n return _formatPrice(Number(price), { symbol: infra.currency ?? \"€\" });\n}\n</script>\n","<template>\n <div :class=\"`propeller-menu ${className || ''}`\" :data-variant=\"getMenuStyle()\" :data-loading=\"isLoading ? 'true' : 'false'\">\n <template v-if=\"isLoading\">\n <div class=\"propeller-menu__loading flex items-center gap-2 px-4 py-3 text-sm text-muted-foreground\">\n <div\n class=\"w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin\"\n ></div>\n <span>{{ getLabel('loading', 'Loading menu...') }}</span>\n </div>\n </template>\n\n <template v-if=\"!isLoading && hasError\">\n <div class=\"propeller-menu__error px-4 py-3 text-sm text-destructive\">\n {{ getLabel('error', 'Failed to load menu') }}\n </div>\n </template>\n\n <template\n v-if=\"\n !isLoading &&\n !hasError &&\n menuCategories.length === 0\n \"\n >\n <div class=\"propeller-menu__empty px-4 py-3 text-sm text-muted-foreground\">\n {{ getLabel('empty', 'No categories found') }}\n </div>\n </template>\n\n <template\n v-if=\"\n !isLoading &&\n !hasError &&\n menuCategories.length > 0 &&\n getMenuStyle() === 'dropdown-vertical'\n \"\n >\n <nav :class=\"`propeller-menu__nav propeller-menu-dropdown hidden md:block ${menuClass || ''}`\">\n <div class=\"flex bg-popover border border-border shadow-lg\">\n <ul class=\"propeller-menu__list w-64 py-1 border-r border-border flex-shrink-0\" data-level=\"1\">\n <template\n :key=\"`l1-${l1.categoryId}-${idx}`\"\n v-for=\"(l1, idx) in menuCategories\"\n >\n <li class=\"propeller-menu__item\" data-level=\"1\" :data-active=\"hoveredL1Id === l1.categoryId ? 'true' : 'false'\" @mouseenter=\"async (event) => setHoveredL1(l1.categoryId)\">\n <a\n :href=\"getCategoryUrl(l1)\"\n @click=\"async (e) => handleItemClick(l1, e)\"\n :class=\"`propeller-menu__link flex items-center justify-between px-4 py-2.5 text-sm transition-colors ${\n hoveredL1Id === l1.categoryId\n ? 'bg-accent text-accent-foreground'\n : 'text-foreground hover:bg-accent/50'\n }`\"\n ><span class=\"propeller-menu__label font-medium truncate\">{{ getCategoryName(l1) }}</span>\n <template v-if=\"getSubCategories(l1).length > 0\">\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-menu__chevron w-4 h-4 text-muted-foreground\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 5l7 7-7 7\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </template>\n </a>\n </li>\n </template>\n </ul>\n <template :key=\"idx\" v-for=\"(l1, idx) in menuCategories\">\n <template v-if=\"hoveredL1Id === l1.categoryId && getSubCategories(l1).length > 0\">\n <ul class=\"propeller-menu__list w-64 py-1 border-r border-border flex-shrink-0\" data-level=\"2\">\n <template :key=\"`l2-${l2.categoryId}-${idx2}`\" v-for=\"(l2, idx2) in getSubCategories(l1)\">\n <li class=\"propeller-menu__item\" data-level=\"2\" :data-active=\"hoveredL2Id === l2.categoryId ? 'true' : 'false'\" @mouseenter=\"async (event) => setHoveredL2(l2.categoryId)\">\n <a\n :href=\"getCategoryUrl(l2)\"\n @click=\"async (e) => handleItemClick(l2, e)\"\n :class=\"`propeller-menu__link flex items-center justify-between px-4 py-2.5 text-sm transition-colors ${\n hoveredL2Id === l2.categoryId\n ? 'bg-accent text-accent-foreground'\n : 'text-foreground hover:bg-accent/50'\n }`\"\n ><span class=\"propeller-menu__label truncate\">{{ getCategoryName(l2) }}</span>\n <template v-if=\"getSubCategories(l2).length > 0\">\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-menu__chevron w-4 h-4 text-muted-foreground\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 5l7 7-7 7\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </template>\n </a>\n </li>\n </template>\n </ul>\n </template> </template\n ><template :key=\"index\" v-for=\"(l1, index) in menuCategories\">\n <template v-if=\"hoveredL1Id === l1.categoryId\">\n <template :key=\"index\" v-for=\"(l2, index) in getSubCategories(l1)\">\n <template v-if=\"hoveredL2Id === l2.categoryId && getSubCategories(l2).length > 0\">\n <ul class=\"propeller-menu__list w-64 py-1 flex-shrink-0\" data-level=\"3\">\n <template\n :key=\"`l3-${l3.categoryId}-${idx3}`\"\n v-for=\"(l3, idx3) in getSubCategories(l2)\"\n >\n <li class=\"propeller-menu__item\" data-level=\"3\">\n <a\n class=\"propeller-menu__link block px-4 py-2.5 text-sm text-foreground hover:bg-accent/50 transition-colors\"\n :href=\"getCategoryUrl(l3)\"\n @click=\"async (e) => handleItemClick(l3, e)\"\n ><span class=\"propeller-menu__label\">{{ getCategoryName(l3) }}</span></a\n >\n </li>\n </template>\n </ul>\n </template>\n </template>\n </template>\n </template>\n </div>\n </nav>\n </template>\n\n <template\n v-if=\"\n !isLoading &&\n !hasError &&\n\n menuCategories.length > 0 &&\n getMenuStyle() === 'jumbotron'\n \"\n >\n <nav :class=\"`propeller-menu__nav propeller-menu-jumbotron hidden md:block ${menuClass || ''}`\">\n <div class=\"propeller-menu__tabs flex items-center border-b border-border\">\n <template :key=\"`l1-${l1.categoryId}-${idx}`\" v-for=\"(l1, idx) in menuCategories\">\n <button\n data-level=\"1\"\n :data-active=\"hoveredL1Id === l1.categoryId ? 'true' : 'false'\"\n @mouseenter=\"async (event) => setHoveredL1(l1.categoryId)\"\n @click=\"async (e) => handleItemClick(l1, e)\"\n :class=\"`propeller-menu__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 ${\n hoveredL1Id === l1.categoryId\n ? 'border-primary text-primary'\n : 'border-transparent text-foreground hover:text-primary hover:border-primary/50'\n }`\"\n >\n <span class=\"propeller-menu__label\">{{ getCategoryName(l1) }}</span>\n </button>\n </template>\n </div>\n <template :key=\"idx\" v-for=\"(l1, idx) in menuCategories\">\n <template v-if=\"hoveredL1Id === l1.categoryId && getSubCategories(l1).length > 0\">\n <div\n class=\"propeller-menu__panel bg-popover border border-border border-t-0 shadow-lg p-6\"\n @mouseenter=\"async (event) => setHoveredL1(l1.categoryId)\"\n @mouseleave=\"async (event) => setHoveredL1(null)\"\n >\n <div class=\"propeller-menu__panel-grid grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6\">\n <template :key=\"`l2-${l2.categoryId}-${idx2}`\" v-for=\"(l2, idx2) in getSubCategories(l1)\">\n <div class=\"propeller-menu__group\" data-level=\"2\">\n <a\n class=\"propeller-menu__link text-sm font-semibold text-foreground hover:text-primary transition-colors\"\n :href=\"getCategoryUrl(l2)\"\n @click=\"async (e) => handleItemClick(l2, e)\"\n ><span class=\"propeller-menu__label\">{{ getCategoryName(l2) }}</span></a\n >\n <template v-if=\"getSubCategories(l2).length > 0\">\n <ul class=\"propeller-menu__list mt-2 space-y-1\" data-level=\"3\">\n <template\n :key=\"`l3-${l3.categoryId}-${idx3}`\"\n v-for=\"(l3, idx3) in getSubCategories(l2)\"\n >\n <li class=\"propeller-menu__item\" data-level=\"3\">\n <a\n class=\"propeller-menu__link text-sm text-muted-foreground hover:text-primary transition-colors\"\n :href=\"getCategoryUrl(l3)\"\n @click=\"async (e) => handleItemClick(l3, e)\"\n ><span class=\"propeller-menu__label\">{{ getCategoryName(l3) }}</span></a\n >\n </li>\n </template>\n </ul>\n </template>\n </div>\n </template>\n </div>\n </div>\n </template>\n </template>\n </nav>\n </template>\n\n <template\n v-if=\"\n !isLoading &&\n !hasError &&\n\n menuCategories.length > 0\n \"\n >\n <nav :class=\"`propeller-menu__nav propeller-menu-mobile md:hidden ${menuClass || ''}`\">\n <ul class=\"propeller-menu__list divide-y divide-border\" data-level=\"1\">\n <template :key=\"`l1-mobile-${l1.categoryId}-${idx}`\" v-for=\"(l1, idx) in menuCategories\">\n <li class=\"propeller-menu__item\" data-level=\"1\" :data-expanded=\"expandedL1 === l1.categoryId ? 'true' : 'false'\">\n <div class=\"flex items-center\">\n <a\n class=\"propeller-menu__link flex-1 px-4 py-3 text-sm font-medium text-foreground\"\n :href=\"getCategoryUrl(l1)\"\n @click=\"async (e) => handleItemClick(l1, e)\"\n ><span class=\"propeller-menu__label\">{{ getCategoryName(l1) }}</span></a\n >\n <template v-if=\"getSubCategories(l1).length > 0\">\n <button\n type=\"button\"\n class=\"propeller-menu__toggle px-4 py-3 text-muted-foreground\"\n @click=\"\n async (event) => {\n expandedL1 = expandedL1 === l1.categoryId ? null : l1.categoryId;\n }\n \"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n :class=\"`propeller-menu__chevron w-4 h-4 transition-transform ${\n expandedL1 === l1.categoryId ? 'rotate-180' : ''\n }`\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m6 9 6 6 6-6\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </button>\n </template>\n </div>\n <template v-if=\"expandedL1 === l1.categoryId && getSubCategories(l1).length > 0\">\n <ul class=\"propeller-menu__list bg-accent/30\" data-level=\"2\">\n <template :key=\"`l2-mobile-${l2.categoryId}-${idx2}`\" v-for=\"(l2, idx2) in getSubCategories(l1)\">\n <li class=\"propeller-menu__item\" data-level=\"2\" :data-expanded=\"expandedL2 === l2.categoryId ? 'true' : 'false'\">\n <div class=\"flex items-center\">\n <a\n class=\"propeller-menu__link flex-1 pl-8 pr-4 py-2.5 text-sm text-foreground\"\n :href=\"getCategoryUrl(l2)\"\n @click=\"async (e) => handleItemClick(l2, e)\"\n ><span class=\"propeller-menu__label\">{{ getCategoryName(l2) }}</span></a\n >\n <template v-if=\"getSubCategories(l2).length > 0\">\n <button\n type=\"button\"\n class=\"propeller-menu__toggle px-4 py-2.5 text-muted-foreground\"\n @click=\"\n async (event) => {\n expandedL2 = expandedL2 === l2.categoryId ? null : l2.categoryId;\n }\n \"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n :class=\"`propeller-menu__chevron w-3.5 h-3.5 transition-transform ${\n expandedL2 === l2.categoryId ? 'rotate-180' : ''\n }`\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m6 9 6 6 6-6\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </button>\n </template>\n </div>\n <template\n v-if=\"expandedL2 === l2.categoryId && getSubCategories(l2).length > 0\"\n >\n <ul class=\"propeller-menu__list bg-accent/20\" data-level=\"3\">\n <template\n :key=\"`l3-mobile-${l3.categoryId}-${idx3}`\"\n v-for=\"(l3, idx3) in getSubCategories(l2)\"\n >\n <li class=\"propeller-menu__item\" data-level=\"3\">\n <a\n class=\"propeller-menu__link block pl-12 pr-4 py-2 text-sm text-muted-foreground hover:text-foreground transition-colors\"\n :href=\"getCategoryUrl(l3)\"\n @click=\"async (e) => handleItemClick(l3, e)\"\n ><span class=\"propeller-menu__label\">{{ getCategoryName(l3) }}</span></a\n >\n </li>\n </template>\n </ul>\n </template>\n </li>\n </template>\n </ul>\n </template>\n </li>\n </template>\n </ul>\n </nav>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from \"vue\";\nimport type { Category, Contact, Customer, GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';\nimport { useMenu, type MenuCategory } from '../composables/vue/useMenu';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface MenuProps {\n /**\n * Initialised Propeller SDK GraphQL client.\n * Used internally to fetch the category hierarchy.\n */\n graphqlClient: GraphQLClient;\n\n /**\n * Base category ID for fetching all categories.\n * This is the root of the menu tree.\n */\n categoryId: number;\n\n /**\n * Language code for fetching localised category names and slugs.\n */\n language: string;\n\n /**\n * Maximum nesting depth of the menu hierarchy.\n * Defaults to 3.\n */\n depth?: number;\n\n /**\n * CSS class applied to the menu container element.\n */\n menuClass?: string;\n\n /**\n * Main menu display type.\n * - 'dropdown-vertical': nested flyout panels on hover (default)\n * - 'jumbotron': full-width mega-menu panel showing all subcategories\n */\n menuStyle?: string;\n\n /**\n * URL pattern for category links.\n * Use `{categoryId}` and `{slug}` as placeholders.\n * Defaults to 'category/{categoryId}/{slug}'.\n */\n menuLinkFormat?: string;\n\n /**\n * Called when a menu item is clicked.\n * Use for SPA-style routing instead of full-page navigation.\n */\n onMenuItemClick: (category: Category) => void;\n\n /**\n * Override any UI string.\n * Available keys: loading, error, empty\n */\n labels?: Record<string, string>;\n\n /**\n * Authenticated user object. When user changes (login/logout),\n * the menu cache is cleared and the menu is re-fetched.\n */\n user?: Contact | Customer | null;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /** Configuration object passed to the component */\n configuration?: any;\n\n /**\n * Pre-fetched menu tree. When provided, the component skips its internal\n * `useMenu` fetch entirely and renders the tree directly — following the\n * same opt-in pattern as `ProductGrid.products`. Lets host apps fetch the\n * category tree server-side (e.g. in `entry-server.ts`'s always-on prefetch)\n * and have\n * the menu HTML land in the initial response, with no client-side\n * roundtrip after hydration.\n *\n * Omitting the prop preserves the legacy client-side fetch behaviour —\n * no breaking change for consumers that haven't migrated.\n */\n tree?: MenuCategory[];\n}\nconst props = defineProps<MenuProps>();\nconst infra = useInfraProps(props);\n\n// An empty array IS NOT a successful pre-fetch — `lib/server.ts`'s\n// `fetchMenu` returns `[]` on failure (swallowed error) by design, so an\n// empty `:tree` from the consumer should fall back to the internal\n// client-side fetch rather than locking the component into the empty\n// state. A legitimately-empty backend still renders the empty state\n// because the client fetch returns `[]` too.\nconst hasPrefetchedTree = computed(\n () => Array.isArray(props.tree) && (props.tree as MenuCategory[]).length > 0,\n);\n\nconst languageRef = computed(() => infra.language || 'NL');\nconst { categories: fetchedCategories, loading: fetchedLoading, error: menuError, fetchMenu } = useMenu({\n graphqlClient: infra.graphqlClient,\n language: languageRef,\n depth: props.depth,\n});\n\n// Source-of-truth for what the template renders. When the host pre-fetched\n// the tree, use it directly; otherwise fall back to the internal fetch\n// result.\nconst menuCategories = computed<MenuCategory[]>(() =>\n hasPrefetchedTree.value ? (props.tree as MenuCategory[]) : fetchedCategories.value,\n);\nconst isLoading = computed(() => (hasPrefetchedTree.value ? false : fetchedLoading.value));\nconst hasError = computed(() => !hasPrefetchedTree.value && menuError.value !== null);\n\n// UI interaction state\nconst hoveredL1Id = ref<number | null>(null);\nconst hoveredL2Id = ref<number | null>(null);\nconst expandedL1 = ref<number | null>(null);\nconst expandedL2 = ref<number | null>(null);\n\nfunction getUserKey(): string {\n if (!infra.user) return '';\n if ('contactId' in (infra.user as any)) return `c${(infra.user as Contact).contactId}`;\n return `u${(infra.user as Customer).customerId}`;\n}\n\nwatch(\n () => [hasPrefetchedTree.value, infra.graphqlClient, props.categoryId, infra.language, getUserKey()],\n () => {\n // When the host pre-fetched the tree, skip the internal fetch entirely\n // — re-fetching would defeat the server-side cache and cause an\n // avoidable client-side request after hydration.\n if (hasPrefetchedTree.value) return;\n if (infra.graphqlClient && props.categoryId) {\n fetchMenu(props.categoryId, getUserKey());\n }\n },\n { immediate: true }\n);\nfunction getCategoryName(cat: MenuCategory): string {\n return cat.name;\n}\nfunction getCategoryUrl(cat: MenuCategory): string {\n const lang = infra.language || 'NL';\n return infra.configuration?.urls?.getCategoryUrl(\n { categoryId: cat.categoryId, slug: [{ value: cat.slug, language: lang }] } as Category,\n lang\n ) ?? '#';\n}\nfunction getSubCategories(cat: MenuCategory): MenuCategory[] {\n return (cat.children || []).filter(sub => sub.name && sub.slug);\n}\nfunction handleItemClick(cat: MenuCategory, e: any): void {\n if (props.onMenuItemClick) {\n e.preventDefault();\n const lang = infra.language || 'NL';\n props.onMenuItemClick({\n categoryId: cat.categoryId,\n name: [{ value: cat.name, language: lang }] as any,\n slug: [{ value: cat.slug, language: lang }] as any,\n } as Category);\n }\n}\nfunction setHoveredL1(id: number | null): void {\n hoveredL1Id.value = id;\n hoveredL2Id.value = null;\n}\nfunction setHoveredL2(id: number | null): void {\n hoveredL2Id.value = id;\n}\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getMenuStyle(): string {\n return (props.menuStyle as string) || 'dropdown-vertical';\n}\n</script>\n","<template>\n <div :class=\"`propeller-order-actions ${className || ''}`\">\n <div class=\"propeller-order-actions__actions flex flex-row items-center gap-3 flex-shrink-0\">\n <button\n type=\"button\"\n class=\"propeller-order-actions__pdf-btn text-primary hover:text-primary/80 text-sm font-medium hover:underline disabled:opacity-50 disabled:cursor-not-allowed\"\n @click=\"async (event) => handleDownloadPDF()\"\n :disabled=\"downloading\"\n >\n <template v-if=\"downloading\">\n {{ getLabel('downloadingPdf', 'Downloading...') }}\n </template>\n\n <template v-if=\"!downloading\">\n {{ getLabel('downloadPdf', 'Order confirmation (PDF)') }}\n </template></button\n ><button\n type=\"button\"\n class=\"propeller-order-actions__reorder-btn text-primary hover:text-primary/80 text-sm font-medium hover:underline disabled:opacity-50 disabled:cursor-not-allowed\"\n @click=\"async (event) => handleReorder()\"\n :disabled=\"reordering\"\n >\n <template v-if=\"reordering\">\n {{ getLabel('reordering', 'Adding items...') }}\n </template>\n\n <template v-if=\"!reordering\">\n {{ getLabel('reorder', 'Order again') }}\n </template>\n </button>\n </div>\n <template v-if=\"toastVisible\">\n <div\n :class=\"`propeller-order-actions__toast fixed top-4 right-4 z-50 flex items-start gap-3 w-80 rounded-[var(--radius-container)] shadow-lg p-4 ${\n toastType === 'success'\n ? 'bg-success border border-success text-success-foreground'\n : 'bg-destructive border border-destructive text-destructive-foreground'\n }`\"\n :data-toast-type=\"toastType\"\n >\n <div\n :class=\"`propeller-order-actions__toast-icon flex-shrink-0 w-5 h-5 mt-0.5 ${\n toastType === 'success' ? 'text-success-foreground' : 'text-destructive-foreground'\n }`\"\n >\n <template v-if=\"toastType === 'success'\">\n <svg fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" :strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\"></path>\n </svg>\n </template>\n\n <template v-if=\"toastType === 'error'\">\n <svg fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" :strokeWidth=\"2\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z\"\n ></path>\n </svg>\n </template>\n </div>\n <p\n :class=\"`propeller-order-actions__toast-message flex-1 text-sm font-medium ${\n toastType === 'success' ? 'text-success-foreground' : 'text-destructive-foreground'\n }`\"\n >\n {{ toastMessage }}\n </p>\n <button\n type=\"button\"\n @click=\"async (event) => dismissToast()\"\n :class=\"`propeller-order-actions__toast-close flex-shrink-0 rounded focus:outline-none ${\n toastType === 'success'\n ? 'text-success-foreground hover:text-success-foreground/80'\n : 'text-destructive-foreground hover:text-destructive-foreground/80'\n }`\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-4 w-4\"\n :strokeWidth=\"2\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"></path>\n </svg>\n </button>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from \"vue\";\n\nimport {\n GraphQLClient,\n Order,\n Cart,\n Contact,\n Customer,\n} from '@propeller-commerce/propeller-sdk-v2';\n\nimport { useOrders } from '../composables/vue/useOrders';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface OrderActionsProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n /** The order to act upon */\n order: Order;\n /** The authenticated user */\n user: Contact | Customer | null;\n /** Cart ID — if provided, re-order adds items to this cart */\n cartId?: string;\n /** Active company ID from the company switcher */\n companyId?: number;\n /** Configuration object (imageSearchFiltersGrid, imageVariantFiltersSmall, etc.) */\n configuration?: any;\n /** Label overrides for UI strings */\n labels?: Record<string, string>;\n /** Additional CSS class for the root element */\n className?: string;\n /** Callback when a new cart is created during re-order */\n onCartCreated?: (cart: Cart) => void;\n /** Callback fired after all re-order items have been added */\n afterReorder?: (cart: Cart) => void;\n}\n\ninterface OrderActionsState {\n reordering: boolean;\n downloading: boolean;\n toastMessage: string;\n toastType: string;\n toastVisible: boolean;\n showToast: (message: string, type: string) => void;\n dismissToast: () => void;\n getLabel: (key: string, fallback: string) => string;\n handleDownloadPDF: () => Promise<void>;\n handleReorder: () => Promise<void>;\n}\n\nconst props = defineProps<OrderActionsProps>();\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\n\nconst { downloadPdf, reorder } = useOrders({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n companyId: companyRef,\n configuration: infra.configuration,\n onCartCreated: props.onCartCreated,\n afterReorder: props.afterReorder,\n});\n\nconst reordering = ref<OrderActionsState['reordering']>(false);\nconst downloading = ref<OrderActionsState['downloading']>(false);\nconst toastMessage = ref<OrderActionsState['toastMessage']>('');\nconst toastType = ref<OrderActionsState['toastType']>('');\nconst toastVisible = ref<OrderActionsState['toastVisible']>(false);\n\nfunction showToast(message: string, type: string): ReturnType<OrderActionsState['showToast']> {\n toastMessage.value = message;\n toastType.value = type;\n toastVisible.value = true;\n setTimeout(() => {\n toastVisible.value = false;\n }, 3000);\n}\nfunction dismissToast(): ReturnType<OrderActionsState['dismissToast']> {\n toastVisible.value = false;\n}\nfunction getLabel(key: string, fallback: string): ReturnType<OrderActionsState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\nasync function handleDownloadPDF(): ReturnType<OrderActionsState['handleDownloadPDF']> {\n if (!props.order?.id) return;\n downloading.value = true;\n try {\n const result = await downloadPdf(props.order);\n if (result.success) {\n showToast(getLabel('pdfSuccess', 'PDF downloaded successfully'), 'success');\n } else {\n showToast(getLabel('pdfError', 'Failed to download PDF'), 'error');\n }\n } catch (error) {\n console.error('Error downloading PDF:', error);\n showToast(getLabel('pdfError', 'Failed to download PDF'), 'error');\n } finally {\n downloading.value = false;\n }\n}\nasync function handleReorder(): ReturnType<OrderActionsState['handleReorder']> {\n if (!props.order?.items) return;\n reordering.value = true;\n try {\n const result = await reorder(props.order, props.cartId);\n if (result.success) {\n showToast(getLabel('reorderSuccess', 'All items added to cart'), 'success');\n } else {\n showToast(getLabel('reorderError', result.error || 'Failed to add items to cart'), 'error');\n }\n } catch (error) {\n console.error('Error during re-order:', error);\n showToast(getLabel('reorderError', 'Failed to add items to cart'), 'error');\n } finally {\n reordering.value = false;\n }\n}\n</script>\n","<template>\n <!--\n An order's bonus items — free items added through incentives — as a\n read-only \"Bonus items\" section (heading + table of OrderItemCard rows).\n Bonus items are order items of class 'product' with isBonus === 'Y' (whether\n standalone or grouped by the backend under an incentive via parentOrderItemId).\n Renders nothing when empty, so it's safe to drop into any order surface.\n -->\n <div\n v-if=\"bonusItems.length > 0\"\n :class=\"`propeller-order-bonus-items ${className || 'mb-8'}`\"\n >\n <h3\n class=\"propeller-order-bonus-items__title text-lg font-bold mb-3 text-foreground\"\n >\n {{ getLabel(\"title\", \"Bonus items\") }}\n </h3>\n <div\n class=\"propeller-order-bonus-items__table bg-card rounded-[var(--radius-container)] shadow overflow-hidden\"\n >\n <table class=\"w-full\">\n <component\n :is=\"OrderItemCardImpl\"\n v-for=\"item in bonusItems\"\n :key=\"item.id\"\n :orderItem=\"item\"\n :titleLinkable=\"false\"\n :currency=\"resolvedCurrency\"\n />\n </table>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, type Component } from \"vue\";\nimport { Order, OrderItem, OrderItemClass, YesNo } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\nimport DefaultOrderItemCard from \"./OrderItemCard.vue\";\n\nexport interface OrderBonusItemsProps {\n /** Order whose bonus items are displayed. When omitted, pass `items` directly. */\n order?: Order | null;\n /** Pre-resolved order items. When omitted, `order.items` is used. */\n items?: OrderItem[];\n /** Currency symbol for prices, forwarded to OrderItemCard. Resolved from the Propeller provider when omitted; defaults to '€'. */\n currency?: string;\n /** Additional CSS class for the root element. */\n className?: string;\n /** Label overrides. Keys: `title` ('Bonus items'). */\n labels?: Record<string, string>;\n // ───── Extension API ─────\n orderItemCardComponent?: Component;\n}\n\nconst props = withDefaults(defineProps<OrderBonusItemsProps>(), {\n order: null,\n});\n\nconst OrderItemCardImpl = computed(() => props.orderItemCardComponent ?? DefaultOrderItemCard);\n\n// `currency` resolves from the Propeller provider when not passed explicitly.\nconst resolvedCurrency = computed(() => useInfraProps(props).currency);\n\nconst bonusItems = computed<OrderItem[]>(() => {\n const all = props.items ?? props.order?.items ?? [];\n return all.filter(\n (item: OrderItem) =>\n item.class === OrderItemClass.product && item.isBonus === YesNo.Y,\n );\n});\n\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-order-list ${className || ''}`\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <template v-if=\"enableSearch && searchFields.length > 0\">\n <div\n class=\"propeller-order-list__filters mb-6 bg-card p-4 rounded-[var(--radius-container)] shadow space-y-4\"\n >\n <template v-if=\"searchFields.includes('term')\">\n <div class=\"propeller-order-list__search-field w-full\">\n <label\n class=\"propeller-order-list__filter-label block text-sm font-medium text-muted-foreground capitalize mb-1\"\n >{{ getColumnLabel(\"term\") }}</label\n ><input\n type=\"text\"\n :placeholder='getLabel(\"searchPlaceholder\", \"Search...\")'\n class=\"propeller-order-list__search-input block w-full rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"searchForm.term || ''\"\n @input=\"\n async (e) => {\n searchForm = {\n ...searchForm,\n term: (e.target as HTMLInputElement).value,\n };\n }\n \"\n @keydown=\"\n async (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n searchForm = {\n ...searchForm,\n term: (e.target as HTMLInputElement).value,\n };\n fetchOrders(1);\n }\n }\n \"\n />\n </div>\n </template>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-4\">\n <template\n :key=\"field\"\n v-for=\"(field, index) in searchFields.filter((f) => f !== 'term')\"\n >\n <div class=\"space-y-1\">\n <label\n class=\"propeller-order-list__filter-label block text-sm font-medium text-muted-foreground capitalize\"\n >{{ getColumnLabel(field) }}</label\n >\n <template v-if=\"field === 'createdAt'\">\n <div class=\"flex space-x-2 w-full\">\n <input\n type=\"date\"\n :placeholder='getLabel(\"dateFromPlaceholder\", \"From\")'\n :min=\"dateMin\"\n :max=\"dateMax\"\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"\n searchForm.createdAt?.greaterThan\n ? searchForm.createdAt.greaterThan.split('T')[0]\n : ''\n \"\n @change=\"\n async (e) => {\n const current = searchForm.createdAt || {};\n const sanitized = sanitizeDateInput((e.target as HTMLInputElement).value);\n if ((e.target as HTMLInputElement).value && !sanitized) {\n (e.target as HTMLInputElement).value = current.greaterThan\n ? current.greaterThan.split('T')[0]\n : '';\n return;\n }\n searchForm = {\n ...searchForm,\n createdAt: {\n ...current,\n greaterThan: sanitized ? `${sanitized}T00:00:00Z` : undefined,\n },\n };\n }\n \"\n /><input\n type=\"date\"\n :placeholder='getLabel(\"dateToPlaceholder\", \"To\")'\n :min=\"dateMin\"\n :max=\"dateMax\"\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"\n searchForm.createdAt?.lessThan\n ? searchForm.createdAt.lessThan.split('T')[0]\n : ''\n \"\n @change=\"\n async (e) => {\n const current = searchForm.createdAt || {};\n const sanitized = sanitizeDateInput((e.target as HTMLInputElement).value);\n if ((e.target as HTMLInputElement).value && !sanitized) {\n (e.target as HTMLInputElement).value = current.lessThan\n ? current.lessThan.split('T')[0]\n : '';\n return;\n }\n searchForm = {\n ...searchForm,\n createdAt: {\n ...current,\n lessThan: sanitized ? `${sanitized}T23:59:59Z` : undefined,\n },\n };\n }\n \"\n />\n </div>\n </template>\n\n <template v-if=\"field === 'lastModifiedAt'\">\n <div class=\"flex space-x-2 w-full\">\n <input\n type=\"date\"\n :placeholder='getLabel(\"dateFromPlaceholder\", \"From\")'\n :min=\"dateMin\"\n :max=\"dateMax\"\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"\n searchForm.lastModifiedAt?.greaterThan\n ? searchForm.lastModifiedAt.greaterThan.split('T')[0]\n : ''\n \"\n @change=\"\n async (e) => {\n const current = searchForm.lastModifiedAt || {};\n const sanitized = sanitizeDateInput((e.target as HTMLInputElement).value);\n if ((e.target as HTMLInputElement).value && !sanitized) {\n (e.target as HTMLInputElement).value = current.greaterThan\n ? current.greaterThan.split('T')[0]\n : '';\n return;\n }\n searchForm = {\n ...searchForm,\n lastModifiedAt: {\n ...current,\n greaterThan: sanitized ? `${sanitized}T00:00:00Z` : undefined,\n },\n };\n }\n \"\n /><input\n type=\"date\"\n :placeholder='getLabel(\"dateToPlaceholder\", \"To\")'\n :min=\"dateMin\"\n :max=\"dateMax\"\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"\n searchForm.lastModifiedAt?.lessThan\n ? searchForm.lastModifiedAt.lessThan.split('T')[0]\n : ''\n \"\n @change=\"\n async (e) => {\n const current = searchForm.lastModifiedAt || {};\n const sanitized = sanitizeDateInput((e.target as HTMLInputElement).value);\n if ((e.target as HTMLInputElement).value && !sanitized) {\n (e.target as HTMLInputElement).value = current.lessThan\n ? current.lessThan.split('T')[0]\n : '';\n return;\n }\n searchForm = {\n ...searchForm,\n lastModifiedAt: {\n ...current,\n lessThan: sanitized ? `${sanitized}T23:59:59Z` : undefined,\n },\n };\n }\n \"\n />\n </div>\n </template>\n\n <template v-if=\"field === 'price'\">\n <div class=\"flex space-x-2 w-full\">\n <input\n type=\"number\"\n :placeholder='getLabel(\"priceMinPlaceholder\", \"Min\")'\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"searchForm.price?.greaterThan || ''\"\n @change=\"\n async (e) => {\n const current = searchForm.price || {};\n searchForm = {\n ...searchForm,\n price: {\n ...current,\n greaterThan: parseFloat((e.target as HTMLInputElement).value),\n },\n };\n }\n \"\n /><input\n type=\"number\"\n :placeholder='getLabel(\"priceMaxPlaceholder\", \"Max\")'\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"searchForm.price?.lessThan || ''\"\n @change=\"\n async (e) => {\n const current = searchForm.price || {};\n searchForm = {\n ...searchForm,\n price: {\n ...current,\n lessThan: parseFloat((e.target as HTMLInputElement).value),\n },\n };\n }\n \"\n />\n </div>\n </template>\n\n <template v-if=\"field === 'sortInput'\">\n <div class=\"flex space-x-2 w-full\">\n <select\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"searchForm.sortInput?.field || ''\"\n @change=\"\n async (e) => {\n const current = searchForm.sortInput || {};\n searchForm = {\n ...searchForm,\n sortInput: {\n ...current,\n field: (e.target as HTMLInputElement).value as OrderSortField,\n },\n };\n }\n \"\n >\n <option value=\"\">{{ getLabel(\"sortFieldOption\", \"Sort Field\") }}</option>\n <template\n :key=\"sortField\"\n v-for=\"(sortField, index) in Object.values(\n OrderSortField,\n )\"\n >\n <option :value=\"sortField\">{{ getLabel(sortField, sortField) }}</option>\n </template></select\n ><select\n class=\"propeller-order-list__filter-input block w-0 flex-1 min-w-0 rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"searchForm.sortInput?.order || ''\"\n @change=\"\n async (e) => {\n const current = searchForm.sortInput || {};\n searchForm = {\n ...searchForm,\n sortInput: {\n ...current,\n order: (e.target as HTMLInputElement).value as SortOrder,\n },\n };\n }\n \"\n >\n <option value=\"\">{{ getLabel(\"sortOrderOption\", \"Order\") }}</option>\n <template\n :key=\"order\"\n v-for=\"(order, index) in Object.values(SortOrder)\"\n >\n <option :value=\"order\">{{ getLabel(order, order) }}</option>\n </template>\n </select>\n </div>\n </template>\n\n <template v-if=\"field === 'type'\">\n <div class=\"flex space-x-2\">\n <select\n class=\"propeller-order-list__filter-input block w-full rounded-[var(--radius-control)] border-input shadow-sm focus:border-primary focus:ring-primary sm:text-sm p-2 border\"\n :value=\"searchForm.type || ''\"\n @change=\"\n async (e) => {\n searchForm = {\n ...searchForm,\n type: (e.target as HTMLInputElement).value as OrderType,\n };\n }\n \"\n >\n <option value=\"\">{{ getLabel(\"typeOption\", \"Type\") }}</option>\n <template\n :key=\"type\"\n v-for=\"(type, index) in Object.values(OrderType)\"\n >\n <option :value=\"type\">{{ getLabel(type, type) }}</option>\n </template>\n </select>\n </div>\n </template>\n </div>\n </template>\n </div>\n <div\n class=\"propeller-order-list__filter-actions flex justify-end space-x-2\"\n >\n <button\n class=\"propeller-order-list__clear-btn inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-[var(--radius-control)] shadow-sm text-muted-foreground bg-card hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary\"\n @click=\"\n async (event) => {\n resetSearch();\n }\n \"\n >\n {{ getLabel(\"clearButton\", \"Clear\") }}</button\n ><button\n class=\"propeller-order-list__search-btn inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-[var(--radius-control)] shadow-sm text-primary-foreground bg-primary hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary\"\n @click=\"async (event) => fetchOrders(1)\"\n >\n {{ getLabel(\"searchButton\", \"Search\") }}\n </button>\n </div>\n </div>\n </template>\n\n <template v-if=\"!loading || orders.length > 0\">\n <template v-if=\"orders.length > 0\">\n <div\n class=\"propeller-order-list__results bg-card rounded-[var(--radius-container)] shadow overflow-hidden\"\n >\n <div class=\"overflow-x-auto\">\n <table\n class=\"propeller-order-list__table min-w-full divide-y divide-gray-200\"\n >\n <thead class=\"propeller-order-list__thead bg-surface-hover\">\n <tr>\n <template :key=\"col\" v-for=\"(col, index) in columns\">\n <th\n :data-column=\"col\"\n :class=\"`propeller-order-list__th px-6 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider ${\n col === 'action' || col === 'total' ? 'text-right' : ''\n }`\"\n >\n {{ getColumnLabel(col) }}\n </th>\n </template>\n </tr>\n </thead>\n <tbody\n class=\"propeller-order-list__tbody bg-card divide-y divide-gray-200\"\n >\n <template :key=\"order.id\" v-for=\"(order, index) in orders\">\n <tr\n class=\"propeller-order-list__row hover:bg-surface-hover\"\n :data-clickable=\"rowsClickable ? 'true' : 'false'\"\n @click=\"\n async (event) => rowsClickable && onOrderClick(order.id)\n \"\n >\n <template :key=\"col\" v-for=\"(col, index) in columns\">\n <td\n :data-column=\"col\"\n :class=\"`propeller-order-list__cell px-6 py-4 whitespace-nowrap text-sm ${\n col === 'id' || col === 'action'\n ? 'font-medium'\n : 'text-muted-foreground'\n } ${col === 'action' || col === 'total' ? 'text-right' : ''}`\"\n >\n <template v-if=\"col === 'id'\">\n <span\n class=\"propeller-order-list__order-id text-foreground\"\n >{{ order.id }}</span\n >\n </template>\n\n <template v-if=\"col === 'date'\">\n {{ formatDate((order as unknown as Record<string, string>).date || order.createdAt || \"\") }}\n </template>\n\n <template v-if=\"col === 'status'\">\n <span\n :data-status=\"order.status\"\n :class=\"`propeller-order-list__status px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${getStatusColor(\n order.status,\n )}`\"\n >{{ order.status }}</span\n >\n </template>\n\n <template v-if=\"col === 'total'\">\n {{ formatPrice(order.total?.net) }}\n </template>\n\n <template v-if=\"col === 'action' && !rowsClickable\">\n <button\n class=\"propeller-order-list__action-btn text-primary hover:text-primary/70 cursor-pointer\"\n @click=\"\n async (event) => {\n event.preventDefault();\n onOrderClick(order.id);\n }\n \"\n >\n {{ getLabel(\"view\", \"View\") }}\n </button>\n </template>\n\n <template v-if=\"col === 'validUntil'\">\n {{ formatDate(order.validUntil || \"\") }}\n </template>\n\n <template\n v-if=\"\n ![\n 'id',\n 'date',\n 'status',\n 'total',\n 'action',\n 'validUntil',\n ].includes(col)\n \"\n >\n {{ (order as unknown as Record<string, unknown>)[col] }}\n </template>\n </td>\n </template>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n <template v-if=\"!hidePagination && totalPages > 1\">\n <div\n class=\"propeller-order-list__pagination bg-card px-4 py-3 flex items-center justify-between border-t border-border sm:px-6\"\n >\n <div\n class=\"propeller-order-list__pagination-mobile flex-1 flex justify-between sm:hidden\"\n >\n <button\n class=\"propeller-order-list__pagination-btn relative inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-[var(--radius-control)] text-muted-foreground bg-card hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => goToPage(currentPage - 1)\"\n :disabled=\"currentPage === 1\"\n >\n {{ getLabel(\"previous\", \"Previous\") }}</button\n ><button\n class=\"propeller-order-list__pagination-btn ml-3 relative inline-flex items-center px-4 py-2 border border-input text-sm font-medium rounded-[var(--radius-control)] text-muted-foreground bg-card hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => goToPage(currentPage + 1)\"\n :disabled=\"currentPage === totalPages\"\n >\n {{ getLabel(\"next\", \"Next\") }}\n </button>\n </div>\n <div\n class=\"propeller-order-list__pagination-desktop hidden sm:flex-1 sm:flex sm:items-center sm:justify-between\"\n >\n <div>\n <p\n class=\"propeller-order-list__pagination-summary text-sm text-muted-foreground\"\n >\n {{ getLabel(\"showingPage\", \"Showing page\") }}&nbsp;<span\n class=\"font-medium\"\n >{{ currentPage }}</span\n >&nbsp;{{ getLabel(\"of\", \"of\") }}&nbsp;<span\n class=\"font-medium\"\n >{{ totalPages }}</span\n >\n </p>\n </div>\n <div>\n <nav\n :aria-label='getLabel(\"paginationAriaLabel\", \"Pagination\")'\n class=\"propeller-order-list__pagination-nav relative z-0 inline-flex rounded-[var(--radius-control)] shadow-sm -space-x-px\"\n >\n <button\n class=\"propeller-order-list__pagination-btn relative inline-flex items-center px-2 py-2 rounded-l-[var(--radius-control)] border border-input bg-card text-sm font-medium text-muted-foreground hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => goToPage(currentPage - 1)\"\n :disabled=\"currentPage === 1\"\n >\n {{ getLabel(\"previous\", \"Previous\") }}</button\n ><button\n class=\"propeller-order-list__pagination-btn relative inline-flex items-center px-2 py-2 rounded-r-[var(--radius-control)] border border-input bg-card text-sm font-medium text-muted-foreground hover:bg-surface-hover disabled:opacity-50\"\n @click=\"async (event) => goToPage(currentPage + 1)\"\n :disabled=\"currentPage === totalPages\"\n >\n {{ getLabel(\"next\", \"Next\") }}\n </button>\n </nav>\n </div>\n </div>\n </div>\n </template>\n </div>\n </template>\n\n <template v-else>\n <div\n class=\"propeller-order-list__empty bg-card rounded-[var(--radius-container)] shadow p-8 text-center\"\n >\n <p class=\"text-muted-foreground mb-4\">\n {{ getLabel(\"noOrders\", \"No orders found.\") }}\n </p>\n </div>\n </template>\n </template>\n\n <template v-else>\n <div\n class=\"propeller-order-list__loading p-8 text-center text-muted-foreground\"\n >\n {{ getLabel(\"loading\", \"Loading orders...\") }}\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport { Contact, Customer, GraphQLClient, Order, OrderSortField, OrderType, SortOrder } from \"@propeller-commerce/propeller-sdk-v2\";\n\nimport { useOrders } from \"../composables/vue/useOrders\";\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface OrderListProps {\n /** The authenticated user (Contact or Customer) */\n user: Contact | Customer | null;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** The initialized GraphQL Client instance */\n graphqlClient: GraphQLClient;\n\n /** Callback when an order is clicked */\n onOrderClick: (orderId: number) => void;\n\n /** Columns to display. Defaults to ['id', 'date', 'status', 'total', 'action'] */\n columns?: string[];\n\n /** Label mapping for columns */\n columnConfig?: Record<string, string>;\n\n /** Enable searching */\n enableSearch?: boolean;\n\n /** Fields enabled for searching (UI inputs) */\n searchFields?: string[];\n\n /** Term fields configuration (backend) */\n termFields?: any[]; // Using any[] to avoid strict enum import issues for now, effectively OrderSearchFields[]\n\n /** Override company ID for order filtering (respects company switcher) */\n companyId?: number;\n\n /** Filter orders by these statuses */\n orderStatus?: string[];\n\n /** Override base styles */\n className?: string;\n\n /** Items per page default */\n initialItemsPerPage?: number;\n\n /** Rows are clickable */\n rowsClickable?: boolean;\n\n /** Show company orders */\n showCompanyOrders?: boolean;\n\n /** Hide pagination controls. Defaults to false. */\n hidePagination?: boolean;\n\n /** Filter orders by channel IDs */\n channelIds?: number[];\n\n /** Format price */\n formatPrice?: (price: number) => string;\n\n /** Format date */\n formatDate?: (dateString: string) => string;\n\n /** Get status color */\n getStatusColor?: (status: string) => string;\n\n /** Localization labels */\n labels?: {\n view?: string;\n previous?: string;\n next?: string;\n showingPage?: string;\n of?: string;\n noOrders?: string;\n loading?: string;\n order?: string;\n date?: string;\n status?: string;\n total?: string;\n action?: string;\n };\n\n /** Callback when a new cart is created during re-order */\n onCartCreated?: (cart: any) => void;\n\n /** Callback fired after all re-order items have been added */\n afterReorder?: (cart: any) => void;\n\n /** Configuration object (imageSearchFiltersGrid, imageVariantFiltersSmall, etc.) */\n configuration?: any;\n}\n\ninterface OrderListState {\n columns: string[];\n rowsClickable: boolean;\n searchFields: string[];\n formatDate: (dateString: string) => string;\n formatPrice: (price: any) => string;\n getStatusColor: (status: string) => string;\n getColumnLabel: (col: string) => string;\n getLabel: (key: string, fallback: string) => string;\n}\n\nconst props = defineProps<OrderListProps>();\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\n\nconst {\n orders,\n loading,\n error,\n searchForm,\n currentPage,\n totalPages,\n totalItems,\n itemsPerPage,\n fetchOrders,\n goToPage,\n resetSearch,\n} = useOrders({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n companyId: companyRef,\n itemsPerPage: props.initialItemsPerPage,\n orderStatuses: props.orderStatus,\n configuration: infra.configuration,\n channelIds: props.channelIds,\n onCartCreated: props.onCartCreated,\n afterReorder: props.afterReorder,\n});\n\nconst columns = ref<OrderListState[\"columns\"]>(\n props.columns || [\"id\", \"date\", \"status\", \"total\"],\n);\nconst rowsClickable = ref<OrderListState[\"rowsClickable\"]>(\n props.rowsClickable || false,\n);\n\nconst searchFields = computed(() => {\n const fields = props.searchFields || [];\n if (props.enableSearch && !(fields as string[]).includes(\"term\")) {\n return [\"term\", ...fields] as string[];\n }\n return fields;\n});\n\nconst dateMin = \"1970-01-01\";\nconst dateMax = computed(() => new Date().toISOString().split(\"T\")[0]);\n\n// Returns a YYYY-MM-DD string only when the input value is a valid date in the\n// allowed range; otherwise returns null. Native <input type=\"date\"> happily\n// accepts year-6 inputs (\"0006-05-04\") via keyboard, so we guard at the model layer.\nfunction sanitizeDateInput(value: string): string | null {\n if (!value) return null;\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!match) return null;\n const year = Number(match[1]);\n if (year < 1970 || year > new Date().getFullYear()) return null;\n const date = new Date(`${value}T00:00:00Z`);\n if (Number.isNaN(date.getTime())) return null;\n return value;\n}\n\nfunction formatDate(\n dateString: string,\n): ReturnType<OrderListState[\"formatDate\"]> {\n if (props.formatDate) return props.formatDate(dateString);\n if (!dateString) return \"-\";\n return new Date(dateString).toLocaleDateString();\n}\nfunction formatPrice(price: number): ReturnType<OrderListState[\"formatPrice\"]> {\n if (props.formatPrice) return props.formatPrice(price);\n if (!price) return \"-\";\n return _formatPrice(price, { symbol: infra.currency ?? \"€\" });\n}\nfunction getStatusColor(\n status: string,\n): ReturnType<OrderListState[\"getStatusColor\"]> {\n if (props.getStatusColor) return props.getStatusColor(status);\n switch (status) {\n case \"COMPLETE\":\n case \"QUOTE_ACCEPTED\":\n return \"bg-secondary/10 text-secondary\";\n case \"CANCELLED\":\n case \"QUOTE_REJECTED\":\n return \"bg-destructive/10 text-destructive\";\n default:\n return \"bg-warning/10 text-warning\";\n }\n}\nfunction getColumnLabel(\n col: string,\n): ReturnType<OrderListState[\"getColumnLabel\"]> {\n if (props.columnConfig && props.columnConfig[col]) {\n return props.columnConfig[col];\n }\n // Translatable: consult labels with key 'col<Capitalized>'.\n const capitalized = col.charAt(0).toUpperCase() + col.slice(1);\n return _getLabel(props.labels, `col${capitalized}`, capitalized);\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<OrderListState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\n</script>\n","<template>\n <div :class=\"`order-shipments ${className || ''}`\">\n <template v-if=\"shipments.length > 0\">\n <div class=\"space-y-4\">\n <h2 class=\"text-xl font-semibold\">\n {{ getLabel(\"title\", \"Shipping details\") }}\n </h2>\n <div\n class=\"overflow-x-auto rounded-[var(--radius-container)] border border-border bg-card shadow-sm\"\n >\n <table class=\"w-full text-sm\">\n <thead class=\"bg-surface-hover/50 border-b border-border\">\n <tr>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colStatus\", \"Status\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colCreatedAt\", \"Date\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colExpectedDelivery\", \"Expected delivery\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colItems\", \"Items\") }}\n </th>\n <th\n class=\"text-right px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colActions\", \"Actions\") }}\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-border\">\n <template :key=\"index\" v-for=\"(shipment, index) in shipments\">\n <tr class=\"hover:bg-surface-hover/30 transition-colors\">\n <td class=\"px-4 py-3\">\n <template v-if=\"!!shipment.status\">\n <span\n class=\"propeller-order-shipments__status inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary/10 text-primary\"\n >{{ shipment.status }}</span\n >\n </template>\n\n <template v-if=\"!shipment.status\">\n <span class=\"text-muted-foreground\">-</span>\n </template>\n </td>\n <td class=\"px-4 py-3 text-muted-foreground\">\n {{ formatDate(shipment.createdAt) }}\n </td>\n <td class=\"px-4 py-3 text-muted-foreground\">\n <template v-if=\"!!shipment.expectedDeliveryAt\">\n {{ formatDate(shipment.expectedDeliveryAt) }}\n </template>\n\n <template v-if=\"!shipment.expectedDeliveryAt\"> - </template>\n </td>\n <td class=\"px-4 py-3 text-muted-foreground\">\n {{ (shipment.items || []).length }}\n </td>\n <td class=\"px-4 py-3 text-right\">\n <button\n type=\"button\"\n class=\"text-primary hover:text-primary/80 text-sm font-medium hover:underline\"\n @click=\"async (event) => openModal(shipment)\"\n >\n {{ getLabel(\"details\", \"Details\") }}\n </button>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </div>\n </template>\n\n <template v-if=\"!!activeShipment\">\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center p-4\"\n @click=\"async (event) => closeModal()\"\n >\n <div\n class=\"propeller-order-shipments__modal-backdrop absolute inset-0 bg-black/50\"\n ></div>\n <div\n class=\"propeller-order-shipments__modal-content relative z-10 w-full max-w-2xl max-h-[80vh] overflow-y-auto bg-card rounded-[var(--radius-container)] shadow-xl\"\n @click=\"async (e) => e.stopPropagation()\"\n >\n <div class=\"flex items-center justify-between px-6 py-4 border-b\">\n <h3 class=\"text-lg font-semibold\">\n {{ getLabel(\"modalTitle\", \"Shipment details\") }}\n </h3>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:text-foreground transition-colors\"\n @click=\"async (event) => closeModal()\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-5 w-5\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n <div class=\"px-6 py-4 space-y-4\">\n <div class=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <span class=\"font-medium text-muted-foreground\">{{\n getLabel(\"labelStatus\", \"Status\")\n }}</span>\n <p class=\"mt-0.5\">\n <template v-if=\"!!activeShipment?.status\">\n <span\n class=\"propeller-order-shipments__status inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary/10 text-primary\"\n >{{ activeShipment?.status }}</span\n >\n </template>\n\n <template v-if=\"!activeShipment?.status\">\n <span>-</span>\n </template>\n </p>\n </div>\n <div>\n <span class=\"font-medium text-muted-foreground\">{{\n getLabel(\"labelExpectedDelivery\", \"Expected delivery\")\n }}</span>\n <p class=\"mt-0.5\">\n <template v-if=\"!!activeShipment?.expectedDeliveryAt\">\n {{ formatDate(activeShipment?.expectedDeliveryAt) }}\n </template>\n\n <template v-if=\"!activeShipment?.expectedDeliveryAt\">\n -\n </template>\n </p>\n </div>\n </div>\n <div>\n <h4 class=\"text-sm font-semibold mb-2\">\n {{ getLabel(\"itemsTitle\", \"Items\") }}\n </h4>\n <template v-if=\"(activeShipment?.items || []).length > 0\">\n <div\n class=\"rounded-[var(--radius-container)] border border-border overflow-hidden\"\n >\n <table class=\"w-full text-sm\">\n <thead class=\"bg-surface-hover/50 border-b border-border\">\n <tr>\n <th\n class=\"text-left px-4 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colProduct\", \"Product\") }}\n </th>\n <th\n class=\"text-left px-4 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colSku\", \"SKU\") }}\n </th>\n <th\n class=\"text-center px-4 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colQuantity\", \"Qty\") }}\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-border\">\n <template\n :key=\"idx\"\n v-for=\"(shipmentItem, idx) in activeShipment?.items ||\n []\"\n >\n <tr class=\"hover:bg-surface-hover/20\">\n <td class=\"px-4 py-2\">\n <template v-if=\"!!shipmentItem.name\">\n {{ shipmentItem.name }}\n </template>\n\n <template v-if=\"!shipmentItem.name\">\n <template\n v-if=\"\n !!getOrderItemForShipmentItem(\n shipmentItem as ShipmentItem,\n )\n \"\n >\n {{\n getOrderItemForShipmentItem(\n shipmentItem as ShipmentItem,\n )?.name || \"-\"\n }}\n </template>\n\n <template\n v-if=\"\n !getOrderItemForShipmentItem(\n shipmentItem as ShipmentItem,\n )\n \"\n >\n -\n </template>\n </template>\n </td>\n <td class=\"px-4 py-2 text-muted-foreground\">\n <template v-if=\"!!shipmentItem.sku\">\n {{ shipmentItem.sku }}\n </template>\n\n <template v-if=\"!shipmentItem.sku\">\n <template\n v-if=\"\n !!getOrderItemForShipmentItem(\n shipmentItem as ShipmentItem,\n )\n \"\n >\n {{\n getOrderItemForShipmentItem(\n shipmentItem as ShipmentItem,\n )?.product?.sku || \"-\"\n }}\n </template>\n\n <template\n v-if=\"\n !getOrderItemForShipmentItem(\n shipmentItem as ShipmentItem,\n )\n \"\n >\n -\n </template>\n </template>\n </td>\n <td class=\"px-4 py-2 text-center\">\n {{ shipmentItem.quantity || \"-\" }}\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </template>\n\n <template v-if=\"(activeShipment?.items || []).length === 0\">\n <p class=\"text-sm text-muted-foreground\">\n {{ getLabel(\"noItems\", \"No items in this shipment\") }}\n </p>\n </template>\n </div>\n <template v-if=\"(activeShipment?.trackAndTraces || []).length > 0\">\n <div>\n <h4 class=\"text-sm font-semibold mb-2\">\n {{ getLabel(\"trackAndTraceTitle\", \"Track & Trace\") }}\n </h4>\n <div class=\"flex flex-wrap gap-2\">\n <template\n :key=\"tatIdx\"\n v-for=\"(tat, tatIdx) in activeShipment?.trackAndTraces ||\n []\"\n >\n <template v-if=\"!!tat.carrier?.trackAndTraceURL\">\n <a\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"inline-flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-control)] border border-primary text-primary text-sm font-medium hover:bg-primary/5 transition-colors\"\n :href=\"buildTrackAndTraceUrl(tat as TrackAndTrace)\"\n ><svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-4 w-4\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2\"\n ></path>\n </svg>\n <template v-if=\"!!tat.carrier?.name\">\n {{ getLabel(\"trackAndTrace\", \"Track & Trace\") }}\n -\n {{ tat.carrier?.name }}\n </template>\n\n <template v-if=\"!tat.carrier?.name\">\n {{ getLabel(\"trackAndTrace\", \"Track & Trace\") }}\n (\n {{ tat.code }}\n )\n </template>\n </a>\n </template>\n </template>\n </div>\n </div>\n </template>\n </div>\n <div class=\"flex justify-end px-6 py-4 border-t\">\n <button\n type=\"button\"\n class=\"px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] border border-border hover:bg-surface-hover transition-colors\"\n @click=\"async (event) => closeModal()\"\n >\n {{ getLabel(\"close\", \"Close\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport {\n Order,\n Shipment,\n ShipmentItem,\n TrackAndTrace,\n OrderItem,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface OrderShipmentsProps {\n /** The current order the user is viewing */\n order: Order;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** Additional CSS class for the root element */\n className?: string;\n}\ninterface OrderShipmentsState {\n activeShipment: Shipment | null;\n getLabel: (key: string, fallback: string) => string;\n openModal: (shipment: Shipment) => void;\n closeModal: () => void;\n formatDate: (dateStr: string) => string;\n getOrderItemForShipmentItem: (shipmentItem: ShipmentItem) => OrderItem | null;\n buildTrackAndTraceUrl: (tat: TrackAndTrace) => string;\n}\n\nconst props = defineProps<OrderShipmentsProps>();\nconst activeShipment = ref<OrderShipmentsState[\"activeShipment\"]>(null);\nconst shipments = computed(() => props.order.shipments || []);\n\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<OrderShipmentsState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction openModal(\n shipment: Shipment,\n): ReturnType<OrderShipmentsState[\"openModal\"]> {\n activeShipment.value = shipment;\n}\nfunction closeModal(): ReturnType<OrderShipmentsState[\"closeModal\"]> {\n activeShipment.value = null;\n}\nfunction formatDate(\n dateStr: string,\n): ReturnType<OrderShipmentsState[\"formatDate\"]> {\n if (!dateStr) return \"-\";\n const d = new Date(dateStr);\n return `${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()}`;\n}\nfunction getOrderItemForShipmentItem(\n shipmentItem: ShipmentItem,\n): ReturnType<OrderShipmentsState[\"getOrderItemForShipmentItem\"]> {\n if (!props.order?.items || !shipmentItem.orderItemId) return null;\n return (\n (props.order.items as OrderItem[]).find(\n (oi: OrderItem) => oi.id === shipmentItem.orderItemId,\n ) || null\n );\n}\nfunction buildTrackAndTraceUrl(\n tat: TrackAndTrace,\n): ReturnType<OrderShipmentsState[\"buildTrackAndTraceUrl\"]> {\n const baseUrl = tat.carrier?.trackAndTraceURL || \"\";\n const code = tat.code || \"\";\n return `${baseUrl}${code}`;\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-price-toggle flex items-center gap-2 ${className || ''}`\"\n :data-state=\"isOn ? 'on' : 'off'\"\n >\n <span class=\"propeller-price-toggle__label hidden sm:inline text-xs\">{{ getLabel() }}</span\n ><button\n type=\"button\"\n role=\"switch\"\n class=\"propeller-price-toggle__switch hover:opacity-80 transition-opacity text-xs font-medium\"\n :aria-checked=\"isOn\"\n @click=\"async (event) => handleToggle()\"\n >\n {{ getStatusText() }}\n </button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, ref } from 'vue';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface PriceToggleProps {\n /**\n * Label text shown beside the toggle.\n * Defaults to 'Prices:'.\n */\n label?: string;\n\n /** Translated labels keyed by the slugs used inside the component\n * (`pricesLabel`, `inclVat`, `exclVat`). Missing keys fall back to English. */\n labels?: Record<string, string>;\n\n /**\n * Initial state of the toggle.\n * Defaults to true (incl. VAT).\n */\n initialState?: boolean;\n\n /**\n * Required callback fired when the toggle is switched.\n * Receives the new state: true = incl. VAT, false = excl. VAT.\n */\n inclExclVatSwitched: (on: boolean) => void;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\ninterface PriceToggleState {\n isOn: boolean;\n getLabel: () => string;\n getStatusText: () => string;\n handleToggle: () => void;\n}\n\nconst props = defineProps<PriceToggleProps>();\nconst isOn = ref<PriceToggleState['isOn']>(props.initialState ?? true);\n\nonMounted(() => {\n if (typeof window !== 'undefined') {\n isOn.value = props.initialState ?? true;\n }\n});\n\nfunction getLabel(): ReturnType<PriceToggleState['getLabel']> {\n return (props.label as string) || _getLabel(props.labels, 'pricesLabel', 'Prices:');\n}\nfunction getStatusText(): ReturnType<PriceToggleState['getStatusText']> {\n return isOn.value\n ? _getLabel(props.labels, 'inclVat', 'Incl. VAT')\n : _getLabel(props.labels, 'exclVat', 'Excl. VAT');\n}\nfunction handleToggle(): ReturnType<PriceToggleState['handleToggle']> {\n const newValue = !isOn.value;\n isOn.value = newValue;\n if (props.inclExclVatSwitched) {\n props.inclExclVatSwitched(newValue);\n }\n window.dispatchEvent(\n new CustomEvent('priceToggleChanged', {\n detail: newValue,\n })\n );\n}\n</script>\n","<template>\n <template v-if=\"isMounted && !isLoading && bundles.length > 0\">\n <div :class=\"`propeller-product-bundles ${className || 'mb-12'}`\">\n <template\n :key=\"bundle.id || bundleIdx\"\n v-for=\"(bundle, bundleIdx) in bundles\"\n >\n <div\n class=\"propeller-product-bundles__bundle border border-border rounded-xl bg-card shadow-sm mb-6 p-6\"\n :data-layout=\"getLayout()\"\n >\n <div class=\"flex flex-col lg:flex-row items-center gap-6\">\n <template\n v-if=\"\n getShowItems() &&\n getLayout() !== 'compact' &&\n bundle.items &&\n bundle.items.length > 0\n \"\n >\n <div\n class=\"propeller-product-bundles__items flex flex-wrap items-center justify-center gap-2 flex-1\"\n >\n <template\n :key=\"item.productId + '-' + idx\"\n v-for=\"(item, idx) in bundle.items\"\n >\n <div\n class=\"propeller-product-bundles__item flex items-center gap-2\"\n >\n <template v-if=\"idx > 0\">\n <div\n class=\"propeller-product-bundles__plus flex-shrink-0 w-8 h-8 rounded-full bg-success flex items-center justify-center\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"w-5 h-5 text-success-foreground\"\n :strokeWidth=\"2.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 4.5v15m7.5-7.5h-15\"\n ></path>\n </svg>\n </div>\n </template>\n\n <div class=\"flex flex-col items-center text-center w-40\">\n <div\n class=\"propeller-product-bundles__item-media w-32 h-32 bg-surface-hover rounded-[var(--radius-container)] overflow-hidden flex-shrink-0 mb-2\"\n >\n <template v-if=\"getProductImage(item.product)\">\n <img\n class=\"propeller-product-bundles__item-image w-full h-full object-contain p-2\"\n :src=\"getProductImage(item.product)\"\n :alt=\"getProductName(item.product)\"\n />\n </template>\n </div>\n <div\n class=\"propeller-product-bundles__item-name text-sm font-medium text-muted-foreground leading-tight mb-1\"\n >\n {{\n getProductName(item.product) ||\n \"Product \" + item.productId\n }}\n </div>\n <template v-if=\"!getHidePrices() && item.price\">\n <div\n class=\"propeller-product-bundles__item-price text-sm font-semibold text-foreground\"\n >\n {{ formatPrice(getItemPrice(item))\n }}<span\n class=\"text-xs font-normal text-muted-foreground ml-1\"\n >\n <template v-if=\"getIncludeTax()\">\n {{ getLabel(\"inclTax\", \"incl. VAT\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"exclTax\", \"excl. VAT\") }}\n </template>\n </span>\n </div>\n </template>\n </div>\n </div>\n </template>\n </div>\n </template>\n\n <div\n class=\"propeller-product-bundles__equals flex-shrink-0 w-8 h-8 rounded-full bg-success flex items-center justify-center\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"w-5 h-5 text-success-foreground\"\n :strokeWidth=\"2.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M3.75 12h16.5M3.75 7.5h16.5\"\n ></path>\n </svg>\n </div>\n <div\n class=\"propeller-product-bundles__summary flex-shrink-0 w-full lg:w-72 pl-0 lg:pl-6\"\n >\n <h3\n class=\"propeller-product-bundles__title text-xl font-bold text-foreground mb-1\"\n >\n {{ bundle.name || getLabel(\"title\", \"Combo deal\") }}\n </h3>\n <template v-if=\"bundle.description\">\n <p\n class=\"propeller-product-bundles__description text-sm text-muted-foreground mb-3\"\n >\n {{ bundle.description }}\n </p>\n </template>\n\n <template v-if=\"bundle.condition\">\n <p\n class=\"propeller-product-bundles__condition text-xs text-muted-foreground mb-3\"\n >\n <template\n v-if=\"bundle.condition === BundleCondition.ALL\"\n >\n {{ getLabel(\"condition_ALL\", \"Discount on all items\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"condition_EP\", \"Discount on extra items\") }}\n </template>\n </p>\n </template>\n\n <template v-if=\"!getHidePrices()\">\n <div class=\"propeller-product-bundles__pricing mb-3\">\n <template v-if=\"hasDiscount(bundle)\">\n <span\n class=\"propeller-product-bundles__original-price text-foreground-subtle line-through text-sm\"\n >{{ formatPrice(getOriginalPrice(bundle)) }}</span\n >\n </template>\n\n <div class=\"flex items-baseline gap-2\">\n <span\n class=\"propeller-product-bundles__price text-2xl font-bold text-foreground\"\n >{{ formatPrice(getBundlePrice(bundle)) }}</span\n ><span class=\"text-xs text-muted-foreground\">\n <template v-if=\"getIncludeTax()\">\n {{ getLabel(\"inclTax\", \"incl. VAT\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"exclTax\", \"excl. VAT\") }}\n </template>\n </span>\n </div>\n <template v-if=\"hasDiscount(bundle)\">\n <div\n class=\"propeller-product-bundles__savings mt-2 inline-block bg-success/10 text-success text-sm font-medium px-3 py-1 rounded-[var(--radius-control)]\"\n >\n {{ getLabel(\"youSave\", \"Your savings: \")\n }}{{\n formatPrice(\n getOriginalPrice(bundle) - getBundlePrice(bundle),\n )\n }}\n </div>\n </template>\n </div>\n <button\n class=\"propeller-product-bundles__submit w-full px-6 py-3 bg-primary text-primary-foreground rounded-[var(--radius-container)] font-semibold hover:bg-primary/90 transition disabled:opacity-50 disabled:cursor-not-allowed text-base\"\n @click=\"async (event) => handleAddToCart(bundle)\"\n :disabled=\"addingBundleId === bundle.id\"\n :data-loading=\"\n addingBundleId === bundle.id ? 'true' : 'false'\n \"\n >\n <template v-if=\"addingBundleId === bundle.id\">\n {{ getLabel(\"adding\", \"Adding...\") }}\n </template>\n\n <template v-else>\n {{ getLabel(\"addToCart\", \"In cart\") }}\n </template>\n </button>\n </template>\n\n <template v-if=\"getHidePrices()\">\n <div\n class=\"propeller-product-bundles__login-prompt text-center text-sm text-muted-foreground py-2\"\n >\n {{\n getLabel(\n \"loginToSeePrices\",\n \"Log in to see prices and add to cart\",\n )\n }}\n </div>\n </template>\n </div>\n </div>\n </div>\n </template>\n <template v-if=\"toastVisible\">\n <div\n :class=\"`propeller-product-bundles__toast fixed top-4 right-4 z-50 flex items-start gap-3 w-80 rounded-[var(--radius-container)] shadow-lg p-4 ${\n toastType === 'success'\n ? 'bg-success border border-success text-success-foreground'\n : 'bg-destructive border border-destructive text-destructive-foreground'\n }`\"\n :data-toast-type=\"toastType\"\n >\n <div\n :class=\"`propeller-product-bundles__toast-icon flex-shrink-0 w-5 h-5 mt-0.5 ${\n toastType === 'success' ? 'text-success-foreground' : 'text-destructive-foreground'\n }`\"\n >\n <template v-if=\"toastType === 'success'\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"toastType === 'error'\">\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 9v2m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z\"\n ></path>\n </svg>\n </template>\n </div>\n <p\n :class=\"`propeller-product-bundles__toast-message flex-1 text-sm font-medium ${\n toastType === 'success' ? 'text-success-foreground' : 'text-destructive-foreground'\n }`\"\n >\n {{ toastMessage }}\n </p>\n <button\n type=\"button\"\n @click=\"async (event) => dismissToast()\"\n :class=\"`propeller-product-bundles__toast-close flex-shrink-0 rounded focus:outline-none ${\n toastType === 'success'\n ? 'text-success-foreground hover:text-success-foreground/80'\n : 'text-destructive-foreground hover:text-destructive-foreground/80'\n }`\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-4 w-4\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n </template>\n\n <template v-if=\"modalVisible\">\n <div\n class=\"propeller-product-bundles__modal fixed inset-0 z-50 flex items-center justify-center px-4\"\n >\n <div\n class=\"propeller-product-bundles__modal-backdrop fixed inset-0 bg-foreground/20\"\n @click=\"async (event) => closeModal()\"\n ></div>\n <div\n class=\"propeller-product-bundles__modal-content relative w-full max-w-lg bg-card rounded-[var(--radius-container)] shadow-2xl overflow-hidden\"\n >\n <div\n class=\"propeller-product-bundles__modal-header flex items-center gap-3 px-6 py-4 border-b border-border-subtle\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"propeller-product-bundles__modal-success-icon h-5 w-5 flex-shrink-0 text-success\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n <h3\n class=\"propeller-product-bundles__modal-title flex-1 text-base font-semibold text-foreground\"\n >\n {{ getLabel(\"modalTitle\", \"Added to cart\") }}\n </h3>\n <button\n type=\"button\"\n class=\"propeller-product-bundles__modal-close flex-shrink-0 text-foreground-subtle hover:text-muted-foreground focus:outline-none\"\n @click=\"async (event) => closeModal()\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-5 w-5\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n <div class=\"propeller-product-bundles__modal-body px-6 py-5\">\n <div\n class=\"propeller-product-bundles__modal-product flex items-start gap-4\"\n >\n <template\n v-if=\"\n lastAddedBundle &&\n lastAddedBundle.items &&\n lastAddedBundle.items.length > 0 &&\n getProductImage(lastAddedBundle.items[0].product)\n \"\n >\n <img\n class=\"propeller-product-bundles__modal-image w-16 h-16 object-contain rounded border border-border-subtle flex-shrink-0\"\n :src=\"\n lastAddedBundle?.items?.[0]\n ? getProductImage(lastAddedBundle.items[0].product)\n : ''\n \"\n :alt=\"lastAddedBundle?.name || 'Bundle'\"\n />\n </template>\n\n <template\n v-if=\"\n !lastAddedBundle ||\n !lastAddedBundle.items ||\n lastAddedBundle.items.length === 0 ||\n !getProductImage(lastAddedBundle.items[0].product)\n \"\n >\n <div\n class=\"propeller-product-bundles__modal-image-placeholder w-16 h-16 flex items-center justify-center rounded border border-border-subtle flex-shrink-0 bg-surface-hover\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"w-8 h-8 text-foreground-subtle\"\n :strokeWidth=\"1.5\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909M3.75 21h16.5A2.25 2.25 0 0022.5 18.75V5.25A2.25 2.25 0 0020.25 3H3.75A2.25 2.25 0 001.5 5.25v13.5A2.25 2.25 0 003.75 21z\"\n ></path>\n </svg>\n </div>\n </template>\n\n <div class=\"flex-1 min-w-0\">\n <p\n class=\"propeller-product-bundles__modal-name text-sm font-medium text-foreground\"\n >\n {{ lastAddedBundle?.name || getLabel(\"title\", \"Bundle\") }}\n </p>\n </div>\n <div class=\"flex-shrink-0 text-right\">\n <p\n class=\"propeller-product-bundles__modal-quantity text-xs text-muted-foreground\"\n >\n {{ getLabel(\"quantity\", \"Quantity\") }}: 1\n </p>\n <template v-if=\"!getHidePrices() && lastAddedBundle\">\n <p\n class=\"propeller-product-bundles__modal-price text-sm font-semibold text-foreground mt-0.5\"\n >\n {{ formatPrice(getBundlePrice(lastAddedBundle)) }}\n </p>\n </template>\n </div>\n </div>\n <template\n v-if=\"\n lastAddedBundle &&\n lastAddedBundle.items &&\n lastAddedBundle.items.length > 0\n \"\n >\n <div\n class=\"propeller-product-bundles__modal-children mt-3 ml-20 space-y-1 border-l-2 border-secondary/10 pl-2\"\n >\n <template\n :key=\"item.productId + '-' + idx\"\n v-for=\"(item, idx) in lastAddedBundle?.items\"\n >\n <div\n class=\"propeller-product-bundles__modal-child flex justify-between items-center text-xs text-muted-foreground\"\n >\n <span class=\"line-clamp-1\">{{\n getProductName(item.product) || \"Product\"\n }}</span>\n <template v-if=\"!getHidePrices() && item.price\">\n <span\n class=\"text-foreground-subtle whitespace-nowrap ml-2\"\n >{{ formatPrice(getItemPrice(item)) }}</span\n >\n </template>\n </div>\n </template>\n </div>\n </template>\n </div>\n <div\n class=\"propeller-product-bundles__modal-actions flex gap-3 px-6 py-4 border-t border-border-subtle\"\n >\n <button\n type=\"button\"\n class=\"propeller-product-bundles__modal-continue flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-input bg-card px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n @click=\"async (event) => closeModal()\"\n >\n {{ getLabel(\"continueShopping\", \"Continue shopping\") }}</button\n ><button\n type=\"button\"\n class=\"propeller-product-bundles__modal-checkout flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-transparent bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n @click=\"\n async (event) => {\n closeModal();\n if (onProceedToCheckout) onProceedToCheckout();\n }\n \"\n >\n {{ getLabel(\"proceedToCheckout\", \"Proceed to checkout\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from \"vue\";\n\nimport { Bundle, BundleCondition, BundleItem, Cart, Contact, Customer, GraphQLClient, Product } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useProductBundles } from \"../composables/vue/useProductBundles\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getProductImageUrl as _getProductImageUrl } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface ProductBundlesProps {\n // === Core ===\n\n /** GraphQL client instance used to fetch bundle data. */\n graphqlClient: GraphQLClient;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** ID of the product whose bundles should be fetched. */\n productId: number;\n\n /** Language code used for content (e.g. 'NL', 'EN'). */\n language: string;\n\n /** Tax zone code used for pricing (e.g. 'NL'). */\n taxZone: string;\n\n // === Pricing ===\n\n /**\n * When true, net price (incl. tax) is the leading price.\n * Note: in the Propeller SDK `price.gross` = excl. VAT, `price.net` = incl. VAT.\n */\n includeTax?: boolean;\n\n // === Portal / visibility ===\n\n /**\n * Controls portal visibility mode.\n * 'semi-closed' — prices and add-to-cart are hidden for anonymous users.\n * Defaults to 'open'.\n */\n portalMode?: string;\n\n /** Authenticated user — used for semi-closed visibility check. */\n user?: Contact | Customer | null;\n\n /** Active company ID from the company switcher.\n * Overrides user's default company for cart creation and lookup.\n * If not provided, the user's default company is used.\n */\n companyId?: number;\n\n /** Cart ID — required when onAddToCart is not provided */\n cartId?: string;\n\n /**\n * Callback to handle a new cart being created.\n * WARNING: If not provided the component create new carts on every add-to-cart.\n */\n onCartCreated?: (cart: Cart) => void;\n\n /**\n * If true a new cart is created if no cart ID is provided.\n * Defaults to false.\n */\n createCart?: boolean;\n\n // === Display options ===\n\n /** When true, stock availability is validated before adding to cart. */\n stockValidation?: boolean;\n\n /**\n * When true, the individual bundle items are listed inside each bundle card.\n * Defaults to true.\n */\n showIndividualItems?: boolean;\n\n /** Additional configuration object passed through to the component. */\n configuration?: any;\n\n /**\n * Layout variant for the bundle display.\n * - 'vertical' — stacked layout\n * - 'horizontal' — side-by-side (default)\n * - 'compact' — condensed, hides individual items\n */\n layout?: \"vertical\" | \"horizontal\" | \"compact\";\n\n /**\n * Override any UI string.\n * Available keys: title, condition_ALL, condition_EP, leaderItem,\n * youSave, adding, addToCart, loginToSeePrices, addedToCart,\n * modalTitle, continueShopping, proceedToCheckout, noCartId\n */\n labels?: Record<string, string>;\n\n // === Modal / feedback ===\n\n /**\n * When true a modal popup is shown after a successful add-to-cart\n * with buttons to continue shopping or proceed to checkout.\n * Defaults to false (only a brief inline toast is shown).\n */\n showModal?: boolean;\n\n /** Callback fired when the \"Proceed to checkout\" modal button is clicked */\n onProceedToCheckout?: () => void;\n\n // === Callbacks ===\n\n /**\n * Callback triggered before adding the bundle to cart.\n */\n beforeBundleAddToCart?: (bundleId: string, quantity: number) => boolean;\n\n /** Called when the user clicks \"Add bundle to cart\". Receives bundleId and quantity (always 1). */\n onAddBundleToCart?: (bundleId: string, quantity: number) => void;\n\n /**\n * Callback triggered after adding the bundle to cart.\n */\n afterBundleAddToCart?: (cart: Cart, bundle?: Bundle) => void;\n\n /** Extra CSS class applied to the root wrapper element. */\n className?: string;\n}\ninterface ProductBundlesState {\n bundles: Bundle[];\n isLoading: boolean;\n includeTax: boolean;\n isMounted: boolean;\n addingBundleId: string | null;\n lastAddedBundle: Bundle | null;\n activeCartId: string;\n toastMessage: string;\n toastType: string;\n toastVisible: boolean;\n modalVisible: boolean;\n getIncludeTax: () => boolean;\n getShowItems: () => boolean;\n getLayout: () => string;\n getIsAnonymous: () => boolean;\n getHidePrices: () => boolean;\n getLabel: (key: string, fallback: string) => string;\n formatPrice: (value: number) => string;\n getBundlePrice: (bundle: Bundle) => number;\n getOriginalPrice: (bundle: Bundle) => number;\n getItemPrice: (item: BundleItem) => number;\n hasDiscount: (bundle: Bundle) => boolean;\n getDiscountPercentage: (bundle: Bundle) => number;\n getProductImage: (product: Product) => string;\n getProductName: (product: Product) => string;\n showToast: (message: string, type: string) => void;\n dismissToast: () => void;\n closeModal: () => void;\n fetchBundles: () => Promise<void>;\n handleAddToCart: (bundle: Bundle) => Promise<void>;\n initCart: () => Promise<string>;\n}\n\nconst props = defineProps<ProductBundlesProps>();\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\nconst langRef = computed(() => infra.language || \"NL\");\n\nconst {\n bundles,\n loading: bundlesLoading,\n adding,\n cartId: composableCartId,\n fetchBundles,\n addBundleToCart,\n} = useProductBundles({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n companyId: companyRef,\n language: langRef,\n configuration: infra.configuration,\n onCartCreated: props.onCartCreated,\n});\n\n// Alias for template compatibility\nconst isLoading = bundlesLoading;\n\nconst includeTax = ref<ProductBundlesState[\"includeTax\"]>(false);\nconst isMounted = ref<ProductBundlesState[\"isMounted\"]>(false);\nconst addingBundleId = ref<ProductBundlesState[\"addingBundleId\"]>(null);\nconst lastAddedBundle = ref<ProductBundlesState[\"lastAddedBundle\"]>(null);\nconst toastMessage = ref<ProductBundlesState[\"toastMessage\"]>(\"\");\nconst toastType = ref<ProductBundlesState[\"toastType\"]>(\"\");\nconst toastVisible = ref<ProductBundlesState[\"toastVisible\"]>(false);\nconst modalVisible = ref<ProductBundlesState[\"modalVisible\"]>(false);\n\nonMounted(() => {\n isMounted.value = true;\n fetchBundles(props.productId);\n});\nfunction getIncludeTax(): ReturnType<ProductBundlesState[\"getIncludeTax\"]> {\n return infra.includeTax !== undefined ? !!infra.includeTax : includeTax.value;\n}\nfunction getShowItems(): ReturnType<ProductBundlesState[\"getShowItems\"]> {\n return props.showIndividualItems !== undefined\n ? !!props.showIndividualItems\n : true;\n}\nfunction getLayout(): ReturnType<ProductBundlesState[\"getLayout\"]> {\n return (props.layout as string) || \"horizontal\";\n}\nfunction getIsAnonymous(): ReturnType<ProductBundlesState[\"getIsAnonymous\"]> {\n return !infra.user;\n}\nfunction getHidePrices(): ReturnType<ProductBundlesState[\"getHidePrices\"]> {\n return (infra.portalMode as string) === \"semi-closed\" && getIsAnonymous();\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<ProductBundlesState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatPrice(\n value: number,\n): ReturnType<ProductBundlesState[\"formatPrice\"]> {\n return _formatPrice(Number(value), { symbol: infra.currency ?? \"€\" });\n}\nfunction getBundlePrice(\n bundle: Bundle,\n): ReturnType<ProductBundlesState[\"getBundlePrice\"]> {\n return getIncludeTax() ? bundle.price?.net || 0 : bundle.price?.gross || 0;\n}\nfunction getOriginalPrice(\n bundle: Bundle,\n): ReturnType<ProductBundlesState[\"getOriginalPrice\"]> {\n return getIncludeTax()\n ? bundle.price?.originalNet || 0\n : bundle.price?.originalGross || 0;\n}\nfunction getItemPrice(\n item: BundleItem,\n): ReturnType<ProductBundlesState[\"getItemPrice\"]> {\n return getIncludeTax() ? item.price?.net || 0 : item.price?.gross || 0;\n}\nfunction hasDiscount(\n bundle: Bundle,\n): ReturnType<ProductBundlesState[\"hasDiscount\"]> {\n const current: number = getBundlePrice(bundle);\n const original: number = getOriginalPrice(bundle);\n return original > 0 && current < original;\n}\nfunction getDiscountPercentage(\n bundle: Bundle,\n): ReturnType<ProductBundlesState[\"getDiscountPercentage\"]> {\n const original: number = getOriginalPrice(bundle);\n if (original <= 0) return 0;\n return Math.round(((original - getBundlePrice(bundle)) / original) * 100);\n}\nfunction getProductImage(\n product: Product,\n): ReturnType<ProductBundlesState[\"getProductImage\"]> {\n return _getProductImageUrl(product);\n}\nfunction getProductName(\n product: Product,\n): ReturnType<ProductBundlesState[\"getProductName\"]> {\n return product?.names?.[0]?.value || \"\";\n}\nfunction showToast(\n message: string,\n type: string,\n): ReturnType<ProductBundlesState[\"showToast\"]> {\n toastMessage.value = message;\n toastType.value = type;\n toastVisible.value = true;\n setTimeout(() => {\n toastVisible.value = false;\n }, 3000);\n}\nfunction dismissToast(): ReturnType<ProductBundlesState[\"dismissToast\"]> {\n toastVisible.value = false;\n}\nfunction closeModal(): ReturnType<ProductBundlesState[\"closeModal\"]> {\n modalVisible.value = false;\n lastAddedBundle.value = null;\n}\nasync function handleAddToCart(\n bundle: Bundle,\n): ReturnType<ProductBundlesState[\"handleAddToCart\"]> {\n if (addingBundleId.value || adding.value) return;\n addingBundleId.value = bundle.id;\n try {\n if (props.onAddBundleToCart) {\n props.onAddBundleToCart(bundle.id, 1);\n } else {\n if (props.beforeBundleAddToCart) {\n props.beforeBundleAddToCart(bundle.id, 1);\n }\n const existingCartId = props.cartId || composableCartId.value;\n const result = await addBundleToCart(\n bundle.id,\n existingCartId || undefined,\n );\n if (!result.success) {\n showToast(\n result.error ||\n getLabel(\"errorAdding\", \"Failed to add bundle to cart\"),\n \"error\",\n );\n return;\n }\n if (result.cart && props.afterBundleAddToCart) {\n props.afterBundleAddToCart(result.cart, bundle);\n }\n }\n if (props.showModal) {\n lastAddedBundle.value = bundle;\n modalVisible.value = true;\n } else {\n const bundleName = bundle.name || getLabel(\"title\", \"Bundle\");\n showToast(\n `${bundleName} ${getLabel(\"addedToCart\", \"added to cart\")}`,\n \"success\",\n );\n }\n } catch (error) {\n console.error(\"Error adding bundle to cart:\", error);\n showToast(getLabel(\"errorAdding\", \"Failed to add bundle to cart\"), \"error\");\n } finally {\n addingBundleId.value = null;\n }\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-product-card group relative flex h-full overflow-hidden rounded-[var(--radius-container)] border border-border bg-card shadow-sm transition-all duration-200 hover:shadow-md hover:border-secondary/20 ${\n isRow() ? 'flex-row flex-wrap md:flex-nowrap items-center' : 'flex-col'\n } ${className || ''}`\"\n :data-layout=\"isRow() ? 'row' : 'grid'\"\n >\n <template v-if=\"showImage !== false\">\n <!-- Injected imageComponent takes over the full image area\n (no auto-rendered badges/favorite around it). -->\n <component\n v-if=\"props.imageComponent\"\n :is=\"ImageImpl\"\n :product=\"product\"\n :language=\"language\"\n :image-search-filters=\"configuration?.imageSearchFiltersGrid\"\n :image-variant-filters=\"configuration?.imageVariantFiltersMedium\"\n :class=\"`propeller-product-card__media relative overflow-hidden bg-surface-hover ${\n isRow()\n ? 'w-20 h-20 flex-shrink-0 p-2'\n : 'aspect-[4/3] sm:aspect-square p-2 sm:p-4'\n }`\"\n />\n <!-- Default image area; consumer can override via #image slot.\n Slot default still renders the badges/favorite injection/slot blocks. -->\n <slot\n v-else\n name=\"image\"\n :product=\"product\"\n :language=\"language\"\n :imageUrl=\"getProductImageUrl()\"\n :imageSearchFilters=\"configuration?.imageSearchFiltersGrid\"\n :imageVariantFilters=\"configuration?.imageVariantFiltersMedium\"\n :onNavigate=\"handleNavigate\"\n >\n <div\n :class=\"`propeller-product-card__media relative overflow-hidden bg-surface-hover ${\n isRow()\n ? 'w-20 h-20 flex-shrink-0 p-2'\n : 'aspect-[4/3] sm:aspect-square p-2 sm:p-4'\n }`\"\n >\n <span\n class=\"block h-full w-full cursor-pointer\"\n @click=\"handleNavigate()\"\n >\n <template v-if=\"!!getProductImageUrl()\">\n <img\n class=\"propeller-product-card__image h-full w-full object-contain transition-transform duration-300 group-hover:scale-105\"\n :src=\"getProductImageUrl()\"\n :alt=\"getProductName()\"\n />\n </template>\n\n <template v-if=\"!getProductImageUrl()\">\n <div\n class=\"propeller-product-card__image-placeholder flex h-full w-full items-center justify-center text-foreground-subtle\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-16 w-16\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n :strokeWidth=\"1\"\n ></path>\n </svg>\n </div>\n </template>\n </span>\n <!-- Injected badgesComponent takes precedence; otherwise #badges slot\n (default content is the inline badges block). -->\n <component\n v-if=\"props.badgesComponent\"\n :is=\"BadgesImpl\"\n :product=\"product\"\n :labels=\"labels\"\n />\n <slot\n v-else-if=\"\n !!imageLabels &&\n imageLabels.length > 0 &&\n computedImageLabels().length > 0\n \"\n name=\"badges\"\n :product=\"product\"\n :imageLabels=\"computedImageLabels()\"\n :labels=\"labels\"\n >\n <div\n class=\"propeller-product-card__badges pointer-events-none absolute left-2 top-2 flex flex-col gap-1\"\n >\n <template\n :key=\"index\"\n v-for=\"(label, index) in computedImageLabels()\"\n >\n <span\n class=\"propeller-product-card__badge inline-block rounded bg-secondary px-2 py-0.5 text-xs font-medium text-primary-foreground shadow-sm\"\n >{{ label }}</span\n >\n </template>\n </div>\n </slot>\n\n <!-- Injected favoriteComponent takes precedence; otherwise #favorite slot\n (default content is the inline heart button). -->\n <component\n v-if=\"props.favoriteComponent && enableAddFavorite\"\n :is=\"FavoriteImpl\"\n :product=\"product\"\n :user=\"user\"\n :on-toggle-favorite=\"onToggleFavorite\"\n :labels=\"labels\"\n />\n <slot\n v-else-if=\"enableAddFavorite\"\n name=\"favorite\"\n :product=\"product\"\n :isFavorite=\"isFavorite\"\n :toggle=\"handleToggleFavorite\"\n :labels=\"labels\"\n >\n <button\n type=\"button\"\n @click=\"async (e) => handleToggleFavorite(e)\"\n :aria-label=\"\n isFavorite\n ? getLabel('removeFromFavorites', 'Remove from favourites')\n : getLabel('addToFavorites', 'Add to favourites')\n \"\n :data-favorite=\"isFavorite ? 'true' : 'false'\"\n :class=\"`propeller-product-card__favorite-btn absolute right-2 top-2 rounded-full border bg-card p-1.5 shadow-sm transition-colors ${\n isFavorite\n ? 'border-destructive text-destructive'\n : 'border-border-subtle text-foreground-subtle hover:text-destructive'\n }`\"\n >\n <svg\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n :fill=\"isFavorite ? 'currentColor' : 'none'\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z\"\n ></path>\n </svg>\n </button>\n </slot>\n </div>\n </slot>\n </template>\n\n <template v-if=\"isRow()\">\n <div\n class=\"propeller-product-card__body flex flex-1 flex-row items-center gap-4 px-4 py-2 min-w-0\"\n >\n <div class=\"flex flex-col gap-0.5 flex-1 min-w-0\">\n <slot\n v-if=\"showSku !== false && !!getProductSku()\"\n name=\"sku\"\n :product=\"product\"\n :sku=\"getProductSku()\"\n >\n <div\n class=\"propeller-product-card__sku font-mono text-xs text-foreground-subtle\"\n >\n {{ getProductSku() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showName !== false\"\n name=\"name\"\n :product=\"product\"\n :productUrl=\"getProductUrl()\"\n :handleProductClick=\"handleProductClick\"\n :linkable=\"true\"\n :name=\"getProductName()\"\n :onNavigate=\"handleNavigate\"\n >\n <span\n class=\"propeller-product-card__title text-sm font-medium leading-tight text-foreground transition-colors hover:text-primary line-clamp-1 cursor-pointer\"\n @click=\"handleNavigate()\"\n >{{ getProductName() }}</span\n >\n </slot>\n\n <slot\n v-if=\"\n !!textLabels &&\n textLabels.length > 0 &&\n computedTextLabels().length > 0\n \"\n name=\"textLabels\"\n :product=\"product\"\n :values=\"computedTextLabels()\"\n >\n <div class=\"propeller-product-card__labels flex flex-col gap-0.5\">\n <template\n :key=\"index\"\n v-for=\"(item, index) in computedTextLabels()\"\n >\n <div\n class=\"propeller-product-card__label text-xs text-muted-foreground\"\n >\n {{ item.value }}\n </div>\n </template>\n </div>\n </slot>\n\n <slot\n v-if=\"showManufacturer && !!getProductManufacturer()\"\n name=\"manufacturer\"\n :product=\"product\"\n :manufacturer=\"getProductManufacturer()\"\n >\n <div\n class=\"propeller-product-card__manufacturer text-xs text-muted-foreground\"\n >\n {{ getProductManufacturer() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showShortDescription && !!getProductShortDescription()\"\n name=\"shortDescription\"\n :product=\"product\"\n :text=\"getProductShortDescription()\"\n >\n <p\n class=\"propeller-product-card__description line-clamp-2 text-xs text-muted-foreground\"\n >\n {{ getProductShortDescription() }}\n </p>\n </slot>\n </div>\n </div>\n <div\n class=\"propeller-product-card__footer w-full md:w-auto flex items-center gap-3 px-4 py-2 md:py-0 border-t md:border-t-0 border-border-subtle\"\n >\n <slot\n v-if=\"props.showStock && !!props.product.inventory\"\n name=\"stock\"\n :product=\"product\"\n :inventory=\"product.inventory\"\n :showAvailability=\"false\"\n :labels=\"props.stockLabels\"\n >\n <component\n v-if=\"props.stockComponent\"\n :is=\"StockImpl\"\n :inventory=\"props.product.inventory\"\n :show-availability=\"false\"\n :show-stock=\"true\"\n :labels=\"props.stockLabels\"\n />\n <ItemStock\n v-else\n :inventory=\"props.product.inventory\"\n :showAvailability=\"false\"\n :showStock=\"true\"\n :labels=\"props.stockLabels\"\n ></ItemStock>\n </slot>\n\n <slot\n v-if=\"showPrice !== false && !!product?.price\"\n name=\"price\"\n :product=\"product\"\n :price=\"product.price\"\n :includeTax=\"props.includeTax !== undefined ? !!props.includeTax : includeTax\"\n :currency=\"currency\"\n :labels=\"props.priceLabels\"\n >\n <div class=\"propeller-product-card__price\">\n <component\n v-if=\"props.priceComponent\"\n :is=\"PriceImpl\"\n :price=\"product.price\"\n :include-tax=\"\n props.includeTax !== undefined ? !!props.includeTax : includeTax\n \"\n :currency=\"currency\"\n :labels=\"props.priceLabels\"\n />\n <ProductPriceDisplay\n v-else\n :price=\"product.price\"\n :includeTax=\"\n props.includeTax !== undefined ? !!props.includeTax : includeTax\n \"\n priceSize=\"text-sm\"\n :labels=\"props.priceLabels\"\n />\n </div>\n </slot>\n\n <div class=\"propeller-product-card__cta flex-shrink-0 ml-auto\">\n <slot\n name=\"addToCart\"\n :product=\"product\"\n :cartId=\"props.cartId\"\n :labels=\"props.addToCartLabels\"\n >\n <component\n v-if=\"props.addToCartComponent\"\n :is=\"AddToCartImpl\"\n :product=\"props.product\"\n :cart-id=\"props.cartId\"\n :allow-incr-decr=\"props.allowIncrDecr\"\n :show-modal=\"props.showModal\"\n :enable-stock-validation=\"props.enableStockValidation\"\n :on-add-to-cart=\"props.onAddToCart\"\n :after-add-to-cart=\"props.afterAddToCart\"\n :on-proceed-to-checkout=\"props.onProceedToCheckout\"\n :on-request-quote-click=\"props.onRequestQuoteClick\"\n :labels=\"props.addToCartLabels\"\n />\n <AddToCart\n v-else\n :graphqlClient=\"props.graphqlClient\"\n :user=\"props.user\"\n :product=\"props.product\"\n :cartId=\"props.cartId\"\n :configuration=\"props.configuration\"\n :childItems=\"props.childItems\"\n :notes=\"props.notes\"\n :price=\"props.price\"\n :createCart=\"props.createCart\"\n :onCartCreated=\"props.onCartCreated\"\n :onAddToCart=\"props.onAddToCart\"\n :afterAddToCart=\"props.afterAddToCart\"\n :showModal=\"props.showModal\"\n :allowIncrDecr=\"props.allowIncrDecr\"\n :enableStockValidation=\"props.enableStockValidation\"\n :language=\"props.language\"\n :onProceedToCheckout=\"props.onProceedToCheckout\"\n :onRequestQuoteClick=\"props.onRequestQuoteClick\"\n :labels=\"props.addToCartLabels\"\n :companyId=\"props.companyId\"\n ></AddToCart>\n </slot>\n </div>\n </div>\n </template>\n\n <template v-if=\"!isRow()\">\n <div\n class=\"propeller-product-card__body flex flex-1 flex-col gap-1.5 p-3 sm:gap-2 sm:p-4\"\n >\n <slot\n v-if=\"showSku !== false && !!getProductSku()\"\n name=\"sku\"\n :product=\"product\"\n :sku=\"getProductSku()\"\n >\n <div\n class=\"propeller-product-card__sku font-mono text-xs text-foreground-subtle\"\n >\n {{ getProductSku() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showName !== false\"\n name=\"name\"\n :product=\"product\"\n :productUrl=\"getProductUrl()\"\n :handleProductClick=\"handleProductClick\"\n :linkable=\"true\"\n :name=\"getProductName()\"\n :onNavigate=\"handleNavigate\"\n >\n <span\n class=\"propeller-product-card__title text-sm font-medium leading-tight text-foreground transition-colors hover:text-primary line-clamp-2 cursor-pointer\"\n @click=\"handleNavigate()\"\n >{{ getProductName() }}</span\n >\n </slot>\n\n <slot\n v-if=\"\n !!textLabels &&\n textLabels.length > 0 &&\n computedTextLabels().length > 0\n \"\n name=\"textLabels\"\n :product=\"product\"\n :values=\"computedTextLabels()\"\n >\n <div class=\"propeller-product-card__labels flex flex-col gap-0.5\">\n <template\n :key=\"index\"\n v-for=\"(item, index) in computedTextLabels()\"\n >\n <div\n class=\"propeller-product-card__label text-xs text-muted-foreground\"\n >\n {{ item.value }}\n </div>\n </template>\n </div>\n </slot>\n\n <slot\n v-if=\"props.showStock && !!props.product.inventory\"\n name=\"stock\"\n :product=\"product\"\n :inventory=\"product.inventory\"\n :showAvailability=\"props.showAvailability !== false\"\n :labels=\"props.stockLabels\"\n >\n <component\n v-if=\"props.stockComponent\"\n :is=\"StockImpl\"\n :inventory=\"props.product.inventory\"\n :show-availability=\"props.showAvailability !== false\"\n :show-stock=\"true\"\n :labels=\"props.stockLabels\"\n />\n <ItemStock\n v-else\n :inventory=\"props.product.inventory\"\n :showAvailability=\"props.showAvailability !== false\"\n :showStock=\"true\"\n :labels=\"props.stockLabels\"\n ></ItemStock>\n </slot>\n\n <slot\n v-if=\"showManufacturer && !!getProductManufacturer()\"\n name=\"manufacturer\"\n :product=\"product\"\n :manufacturer=\"getProductManufacturer()\"\n >\n <div\n class=\"propeller-product-card__manufacturer text-xs text-muted-foreground\"\n >\n {{ getProductManufacturer() }}\n </div>\n </slot>\n\n <slot\n v-if=\"showShortDescription && !!getProductShortDescription()\"\n name=\"shortDescription\"\n :product=\"product\"\n :text=\"getProductShortDescription()\"\n >\n <p\n class=\"propeller-product-card__description line-clamp-2 text-xs text-muted-foreground\"\n >\n {{ getProductShortDescription() }}\n </p>\n </slot>\n\n <slot\n v-if=\"showPrice !== false && !!product?.price\"\n name=\"price\"\n :product=\"product\"\n :price=\"product.price\"\n :includeTax=\"props.includeTax !== undefined ? !!props.includeTax : includeTax\"\n :currency=\"currency\"\n :labels=\"props.priceLabels\"\n >\n <div class=\"propeller-product-card__price mt-auto pt-1\">\n <component\n v-if=\"props.priceComponent\"\n :is=\"PriceImpl\"\n :price=\"product.price\"\n :include-tax=\"\n props.includeTax !== undefined ? !!props.includeTax : includeTax\n \"\n :currency=\"currency\"\n :labels=\"props.priceLabels\"\n />\n <ProductPriceDisplay\n v-else\n :price=\"product.price\"\n :includeTax=\"\n props.includeTax !== undefined ? !!props.includeTax : includeTax\n \"\n priceSize=\"text-base sm:text-lg\"\n :labels=\"props.priceLabels\"\n />\n </div>\n </slot>\n </div>\n\n <template v-if=\"props.allowAddToCart !== false\">\n <div class=\"propeller-product-card__cta px-3 pb-3 sm:px-4 sm:pb-4\">\n <slot\n name=\"addToCart\"\n :product=\"product\"\n :cartId=\"props.cartId\"\n :labels=\"props.addToCartLabels\"\n >\n <component\n v-if=\"props.addToCartComponent\"\n :is=\"AddToCartImpl\"\n :product=\"props.product\"\n :cart-id=\"props.cartId\"\n :allow-incr-decr=\"props.allowIncrDecr\"\n :show-modal=\"props.showModal\"\n :enable-stock-validation=\"props.enableStockValidation\"\n :on-add-to-cart=\"props.onAddToCart\"\n :after-add-to-cart=\"props.afterAddToCart\"\n :on-proceed-to-checkout=\"props.onProceedToCheckout\"\n :on-request-quote-click=\"props.onRequestQuoteClick\"\n :labels=\"props.addToCartLabels\"\n />\n <AddToCart\n v-else\n :graphqlClient=\"props.graphqlClient\"\n :user=\"props.user\"\n :product=\"props.product\"\n :cartId=\"props.cartId\"\n :configuration=\"props.configuration\"\n :childItems=\"props.childItems\"\n :notes=\"props.notes\"\n :price=\"props.price\"\n :createCart=\"props.createCart\"\n :onCartCreated=\"props.onCartCreated\"\n :onAddToCart=\"props.onAddToCart\"\n :afterAddToCart=\"props.afterAddToCart\"\n :showModal=\"props.showModal\"\n :allowIncrDecr=\"props.allowIncrDecr\"\n :enableStockValidation=\"props.enableStockValidation\"\n :language=\"props.language\"\n :onProceedToCheckout=\"props.onProceedToCheckout\"\n :onRequestQuoteClick=\"props.onRequestQuoteClick\"\n :labels=\"props.addToCartLabels\"\n :companyId=\"props.companyId\"\n ></AddToCart>\n </slot>\n </div>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, type Component } from \"vue\";\n// No router dependency: this is a standalone library component. Consumers\n// pass `onProductClick` for SPA navigation; without it we fall back to a\n// plain location change so the card still works in any host.\n\nimport {\n GraphQLClient,\n Product,\n Contact,\n Customer,\n Cart,\n CartMainItem,\n AttributeResult,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport type { CartChildItemInput } from \"@propeller-commerce/propeller-sdk-v2\";\nimport AddToCart from \"./AddToCart.vue\";\nimport ItemStock from \"./ItemStock.vue\";\nimport ProductPriceDisplay from \"./ProductPrice.vue\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n getProductImageUrl as _getProductImageUrl,\n getProductSku as _getProductSku,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useResolvedProps, type ResolveSpec } from '../composables/vue/useResolvedProps';\nimport DefaultProductPrice from './ProductPrice.vue';\nimport DefaultItemStock from './ItemStock.vue';\nimport DefaultAddToCart from './AddToCart.vue';\nimport DefaultAddToFavorite from './AddToFavorite.vue';\nimport DefaultProductImage from './defaults/DefaultProductImage.vue';\nimport DefaultProductBadges from './defaults/DefaultProductBadges.vue';\n\nexport interface ProductCardProps {\n // === Core ===\n\n /** The product object to display */\n product: Product;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n // === Display toggles ===\n\n /** Show the product name. Defaults to true. */\n showName?: boolean;\n\n /** Show the product image. Defaults to true. */\n showImage?: boolean;\n\n /** Show the product short description. Defaults to false. */\n showShortDescription?: boolean;\n\n /** Show the product SKU. Defaults to true. */\n showSku?: boolean;\n\n /** Show the product manufacturer. Defaults to false. */\n showManufacturer?: boolean;\n\n /**\n * Show the stock / availability widget below the product name.\n * Uses the embedded `ItemStock` component driven by `product.inventory`.\n * Defaults to false.\n */\n showStock?: boolean;\n\n /**\n * Show only the availability indicator (Available / Not available) inside ItemStock.\n * Only relevant when `showStock` is true.\n * Defaults to true.\n */\n showAvailability?: boolean;\n\n /**\n * Show the price below the product name.\n * Defaults to true.\n */\n showPrice?: boolean;\n\n /**\n * Show the AddToCart component.\n * Defaults to true.\n */\n allowAddToCart?: boolean;\n\n /**\n * Label overrides forwarded to the embedded ItemStock component.\n * Keys: inStock, outOfStock, lowStock, available, notAvailable, pieces\n */\n stockLabels?: Record<string, string>;\n\n /** Translated labels forwarded to the embedded `<ProductPrice>` display.\n * See `ProductPriceProps.labels` for slugs (inclTax, exclTax, loginToSeePrices). */\n priceLabels?: Record<string, string>;\n\n // === Attribute labels ===\n\n /**\n * Attribute codes/names to look up and display as badge overlays on the product image.\n * Each code is resolved against `product.attributes.items[].attributeDescription.code`\n * (or `.name`). Attributes with no matching value are silently omitted.\n * Example: ['new', 'sale']\n */\n imageLabels?: string[];\n\n /**\n * Attribute codes/names to look up and display as extra text rows below the product name.\n * Resolved the same way as `imageLabels`.\n * Example: ['brand', 'color']\n */\n textLabels?: string[];\n\n // === UI string overrides ===\n\n /**\n * Override any UI string.\n * Available keys: addToFavorites, removeFromFavorites\n */\n labels?: Record<string, string>;\n\n // === Favourites ===\n\n /** Renders a heart-icon toggle button on the product image. Defaults to false. */\n enableAddFavorite?: boolean;\n\n /**\n * Called whenever the favourite state is toggled.\n * The second argument indicates the new state: `true` = added, `false` = removed.\n */\n onToggleFavorite?: (product: Product, isFavorite: boolean) => void;\n\n // === Navigation ===\n\n /**\n * Called when the product name or image is clicked.\n * When provided, the default `<a>` navigation is prevented so the consumer\n * can use framework-specific routing (e.g. Next.js `router.push`).\n */\n onProductClick?: (product: Product) => void;\n\n // === Pricing ===\n\n /**\n * When true, tax-inclusive price (net) is the leading price.\n * When false, tax-exclusive price (gross) is shown.\n * Defaults to false.\n */\n includeTax?: boolean;\n\n // === Appearance ===\n\n /** Number of grid columns — when 1 the card renders as a compact horizontal row. */\n columns?: number;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /**\n * URL pattern controlling which segments appear in product links.\n * Tokens: page → 'product', id → productId, slug → slug value.\n * Examples: 'page/id/slug' (default) | 'page/slug' | 'page/id'\n * Defaults to 'page/id/slug' when omitted.\n */\n urlPattern?: string;\n\n // === AddToCart pass-through props ===\n\n /** Initialised Propeller SDK GraphQL client (required by embedded AddToCart). */\n graphqlClient: GraphQLClient;\n\n /** Authenticated user — used for cart creation / lookup. */\n user: Contact | Customer | null;\n\n /** ID of an existing cart to add items to. */\n cartId?: string;\n\n /** Config object providing imageSearchFiltersGrid and imageVariantFiltersSmall. */\n configuration?: any;\n\n /** Cluster ID for configurable products. */\n clusterId?: number;\n\n /** Product IDs of selected cluster child options. */\n childItems?: number[];\n\n /** Free-text notes attached to the cart item. */\n notes?: string;\n\n /** Custom unit price override. Omit to use calculated price. */\n price?: number;\n\n /**\n * When true and no cartId is available, the embedded AddToCart automatically\n * looks up or creates a cart. Always pair with onCartCreated.\n */\n createCart?: boolean;\n\n /** Called after a new cart is created internally by AddToCart. */\n onCartCreated?: (cart: Cart) => void;\n\n /**\n * Fully replaces the internal CartService.addItemToCart call inside AddToCart.\n * Must return a Cart object.\n */\n onAddToCart?: (\n product: Product,\n clusterId?: number,\n quantity?: number,\n childItems?: CartChildItemInput[],\n notes?: string,\n price?: number,\n showModal?: boolean,\n ) => Cart;\n\n /** Called after every successful add-to-cart. Receives the updated cart and the added item. */\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n\n /**\n * When true the embedded AddToCart shows a modal after a successful add\n * instead of the default toast notification. Defaults to false.\n */\n showModal?: boolean;\n\n /**\n * Renders − and + buttons beside the quantity input in AddToCart.\n * Defaults to true.\n */\n allowIncrDecr?: boolean;\n\n /** Validate stock before adding to cart. Defaults to false. */\n enableStockValidation?: boolean;\n\n /** Language code forwarded to CartService operations. Defaults to 'NL'. */\n language?: string;\n\n /**\n * Active company ID from the company switcher.\n * When provided, overrides the user's default company for cart creation and lookup.\n */\n companyId?: number;\n\n /** Called when the user clicks \"Proceed to checkout\" inside the AddToCart modal. */\n onProceedToCheckout?: () => void;\n\n /** Called when the user clicks \"Request a Quote\" inside the AddToCart modal. */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /** Label overrides for UI strings\n *\n * available labels:\n * - outOfStock\n * - noCartId\n * - errorAdding\n * - addedToCart\n * - modalTitle\n * - quantity\n * - continueShopping\n * - proceedToCheckout\n * - requestQuoteButton\n * - add\n * - adding\n */\n addToCartLabels?: Record<string, string>;\n\n // ───── Extension API ─────\n // Per-card overrides for sub-components. Precedence:\n // explicit prop > ProductGridConfig context > infra > default.\n priceComponent?: Component;\n stockComponent?: Component;\n addToCartComponent?: Component;\n imageComponent?: Component;\n badgesComponent?: Component;\n favoriteComponent?: Component;\n}\ninterface ProductCardState {\n isFavorite: boolean;\n includeTax: boolean;\n priceListener: any;\n getProductName: () => string;\n getProductSku: () => string;\n getProductImageUrl: () => string;\n getProductPrice: () => string;\n getProductUrl: () => string;\n getProductShortDescription: () => string;\n getProductManufacturer: () => string;\n getLabel: (key: string, fallback: string) => string;\n getAttributeValue: (code: string) => string;\n handleProductClick: (e: any) => void;\n handleToggleFavorite: (e: any) => void;\n isRow: () => boolean;\n computedImageLabels: () => string[];\n computedTextLabels: () => {\n name: string;\n value: string;\n }[];\n}\n\nconst props = withDefaults(defineProps<ProductCardProps>(), {\n showImage: true,\n showName: true,\n showSku: true,\n showPrice: true,\n allowAddToCart: true,\n showAvailability: true,\n showShortDescription: false,\n showManufacturer: false,\n showStock: false,\n enableAddFavorite: false,\n});\n\n// ───── Extension API ─────\n// Resolve sub-component slots from explicit props → ProductGrid context.\nconst RESOLVE_SPEC: ResolveSpec<ProductCardProps> = {\n priceComponent: { grid: 'priceComponent' },\n stockComponent: { grid: 'stockComponent' },\n addToCartComponent: { grid: 'addToCartComponent' },\n imageComponent: { grid: 'imageComponent' },\n badgesComponent: { grid: 'badgesComponent' },\n favoriteComponent: { grid: 'favoriteComponent' },\n};\n\nconst resolved = computed(() => useResolvedProps(props, RESOLVE_SPEC));\n\nconst PriceImpl = computed(() => resolved.value.priceComponent ?? DefaultProductPrice);\nconst StockImpl = computed(() => resolved.value.stockComponent ?? DefaultItemStock);\nconst AddToCartImpl = computed(() => resolved.value.addToCartComponent ?? DefaultAddToCart);\nconst ImageImpl = computed(() => resolved.value.imageComponent ?? DefaultProductImage);\nconst BadgesImpl = computed(() => resolved.value.badgesComponent ?? DefaultProductBadges);\nconst FavoriteImpl = computed(() => resolved.value.favoriteComponent ?? DefaultAddToFavorite);\n\nconst isFavorite = ref<ProductCardState[\"isFavorite\"]>(false);\nconst includeTax = ref<ProductCardState[\"includeTax\"]>(false);\nconst priceListener = ref<ProductCardState[\"priceListener\"]>(null);\n\nfunction isRow(): ReturnType<ProductCardState[\"isRow\"]> {\n return (props.columns as number) === 1;\n}\nfunction getProductName(): ReturnType<ProductCardState[\"getProductName\"]> {\n return getLanguageString(\n (props.product as Product)?.names,\n props.language || \"NL\",\n \"Product\",\n );\n}\nfunction getProductSku(): ReturnType<ProductCardState[\"getProductSku\"]> {\n return _getProductSku(props.product as Product);\n}\nfunction getProductImageUrl(): ReturnType<\n ProductCardState[\"getProductImageUrl\"]\n> {\n return _getProductImageUrl(props.product as Product);\n}\nfunction getProductPrice(): ReturnType<ProductCardState[\"getProductPrice\"]> {\n if (!props.showPrice) return \"\";\n const priceObj = (props.product as Product)?.price;\n const useTax: boolean =\n props.includeTax !== undefined ? !!props.includeTax : includeTax.value;\n const value: number | undefined = useTax ? priceObj?.net : priceObj?.gross;\n if (!value && value !== 0) return \"\";\n return _formatPrice(Number(value), { symbol: props.currency ?? \"€\" });\n}\nfunction getProductUrl(): ReturnType<ProductCardState[\"getProductUrl\"]> {\n return props.configuration?.urls?.getProductUrl(props.product, props.language) ?? \"#\";\n}\nfunction getProductShortDescription(): ReturnType<\n ProductCardState[\"getProductShortDescription\"]\n> {\n return getLanguageString(\n (props.product as Product)?.shortDescriptions,\n props.language || \"NL\",\n \"\",\n );\n}\nfunction getProductManufacturer(): ReturnType<\n ProductCardState[\"getProductManufacturer\"]\n> {\n return (props.product as Product)?.manufacturer || \"\";\n}\nfunction getLabel(\n key: string,\n fallback: string,\n): ReturnType<ProductCardState[\"getLabel\"]> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getAttributeValue(\n code: string,\n): ReturnType<ProductCardState[\"getAttributeValue\"]> {\n const attrs = (props.product as Product)?.attributes?.items || [];\n const found = attrs.find(\n (a: AttributeResult) => a.attributeDescription?.name === code,\n );\n return found?.value?.value || \"\";\n}\nfunction handleNavigate(): void {\n if (props.onProductClick) {\n props.onProductClick(props.product);\n } else if (typeof window !== \"undefined\") {\n // No router in the package — fall back to a native location change.\n window.location.href = getProductUrl();\n }\n}\nfunction handleProductClick(\n e: any,\n): ReturnType<ProductCardState[\"handleProductClick\"]> {\n if (props.onProductClick) {\n e.preventDefault();\n props.onProductClick(props.product);\n }\n}\nfunction handleToggleFavorite(\n e: any,\n): ReturnType<ProductCardState[\"handleToggleFavorite\"]> {\n e.preventDefault();\n e.stopPropagation();\n isFavorite.value = !isFavorite.value;\n if (props.onToggleFavorite) {\n props.onToggleFavorite(props.product, isFavorite.value);\n }\n}\nfunction computedImageLabels(): ReturnType<\n ProductCardState[\"computedImageLabels\"]\n> {\n if (!props.imageLabels || (props.imageLabels as string[]).length === 0)\n return [];\n const attrs = (props.product as Product)?.attributes?.items || [];\n return (props.imageLabels as string[])\n .map((code: string) => {\n const found = attrs.find(\n (a: AttributeResult) => a.attributeDescription?.name === code,\n );\n return found?.value?.value || \"\";\n })\n .filter((v: string) => v.length > 0);\n}\nfunction computedTextLabels(): ReturnType<\n ProductCardState[\"computedTextLabels\"]\n> {\n if (!props.textLabels || (props.textLabels as string[]).length === 0)\n return [];\n const attrs = (props.product as Product)?.attributes?.items || [];\n return (props.textLabels as string[])\n .map((code: string) => {\n const found = attrs.find(\n (a: AttributeResult) => a.attributeDescription?.name === code,\n );\n return {\n name: code,\n value: found?.value?.value || \"\",\n };\n })\n .filter((item: { name: string; value: string }) => item.value.length > 0);\n}\n</script>\n","<template>\n <template v-if=\"!!html\">\n <div\n :class=\"`propeller-product-description ${className || ''}`\"\n :data-expanded=\"expanded ? 'true' : 'false'\"\n :data-truncatable=\"shouldTruncate() ? 'true' : 'false'\"\n >\n <template v-if=\"!shouldTruncate() || expanded\">\n <div\n class=\"propeller-product-description__content prose prose-slate max-w-none text-muted-foreground\"\n v-html=\"html\"\n ></div>\n </template>\n\n <template v-if=\"shouldTruncate() && !expanded\">\n <p class=\"propeller-product-description__truncated text-muted-foreground\">{{ getTruncated() }}</p>\n </template>\n\n <template v-if=\"shouldTruncate()\">\n <button\n type=\"button\"\n class=\"propeller-product-description__toggle mt-2 text-sm font-medium text-primary hover:underline\"\n @click=\"async (event) => toggle()\"\n >\n <template v-if=\"expanded\"> Read less </template>\n\n <template v-if=\"!expanded\"> Read more </template>\n </button>\n </template>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\n\nimport type { Product, Cluster, LocalizedString } from '@propeller-commerce/propeller-sdk-v2';\nimport { getLanguageString, getLanguageUri } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface ProductDescriptionProps {\n /**\n * Product or Cluster object.\n * The component reads `product.descriptions` (an array of LocalizedString)\n * and renders the matching language entry as HTML.\n */\n product: Product | Cluster;\n\n /**\n * Language code used to resolve the correct localised description.\n * Defaults to 'NL'.\n */\n language?: string;\n\n /**\n * When true, the description is initially collapsed to `maxLength` characters.\n * A \"Read more\" / \"Read less\" toggle is shown.\n * Defaults to false.\n */\n collapsed?: boolean;\n\n /**\n * Maximum number of characters shown when collapsed.\n * Set to 0 to display the entire description without truncation.\n * Defaults to 0.\n */\n maxLength?: number;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\ninterface ProductDescriptionState {\n expanded: boolean;\n html: string;\n getDescription: () => string;\n getMaxLen: () => number;\n shouldTruncate: () => boolean;\n getTruncated: () => string;\n toggle: () => void;\n}\n\nconst props = defineProps<ProductDescriptionProps>();\nconst infra = useInfraProps(props);\nconst expanded = ref<ProductDescriptionState['expanded']>(false);\nconst html = ref<ProductDescriptionState['html']>('');\n\nwatch(\n () => [props.product, infra.language],\n () => {\n html.value = getDescription();\n },\n { immediate: true }\n);\nfunction getDescription(): ReturnType<ProductDescriptionState['getDescription']> {\n const product = props.product as Product;\n if (!product?.descriptions) return '';\n return getLanguageString(product.descriptions, infra.language || 'NL', '');\n}\nfunction getMaxLen(): ReturnType<ProductDescriptionState['getMaxLen']> {\n const max = props.maxLength;\n if (!max || (max as number) <= 0) return 0;\n return max as number;\n}\nfunction shouldTruncate(): ReturnType<ProductDescriptionState['shouldTruncate']> {\n if (props.collapsed === false) return false;\n if (!props.collapsed) return false;\n const maxLen = getMaxLen();\n if (maxLen === 0) return false;\n const plain = html.value.replace(/<[^>]*>/g, '');\n return plain.length > maxLen;\n}\nfunction getTruncated(): ReturnType<ProductDescriptionState['getTruncated']> {\n const plain = html.value.replace(/<[^>]*>/g, '');\n const maxLen = getMaxLen();\n if (maxLen === 0 || plain.length <= maxLen) return html.value;\n const truncated = plain.substring(0, maxLen);\n return truncated.substring(0, truncated.lastIndexOf(' ')) + '\\u2026';\n}\nfunction toggle(): ReturnType<ProductDescriptionState['toggle']> {\n expanded.value = !expanded.value;\n}\n</script>\n","<template>\n <div :class=\"`propeller-product-gallery ${className || ''}`\">\n <div\n class=\"propeller-product-gallery__stage relative aspect-square bg-card overflow-hidden\"\n >\n <template v-if=\"getImages().length === 0\">\n <div\n class=\"propeller-product-gallery__empty flex h-full w-full items-center justify-center bg-surface-hover\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-product-gallery__empty-icon h-24 w-24 text-foreground-subtle\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n :strokeWidth=\"1\"\n ></path>\n </svg>\n </div>\n </template>\n\n <template v-if=\"getImages().length > 0\">\n <img\n :alt='getLabel(\"productImageAlt\", \"Product image\")'\n :src=\"getMainImage()\"\n @click=\"async (event) => openLightbox()\"\n :class=\"`h-full w-full object-contain p-8 transition-transform duration-200 ${\n enableZoom !== false ? 'cursor-zoom-in hover:scale-105' : ''\n }`\"\n />\n </template>\n </div>\n <template v-if=\"showThumbnails !== false && hasThumbnails()\">\n <div class=\"flex gap-3 mt-4 overflow-x-auto pb-2\">\n <template :key=\"index\" v-for=\"(img, index) in getImages()\">\n <button\n type=\"button\"\n @click=\"async (event) => selectImage(index)\"\n :class=\"`propeller-product-gallery__thumbnail relative flex-shrink-0 w-20 h-20 rounded-[var(--radius-container)] border-2 overflow-hidden transition-all bg-card ${\n selectedIndex === index\n ? 'border-primary ring-2 ring-primary/20'\n : 'border-transparent hover:border-border'\n }`\"\n >\n <img\n class=\"w-full h-full object-contain p-1\"\n :src=\"img\"\n :alt='`${getLabel(\"productImageAlt\", \"Product image\")} ${index + 1}`'\n />\n </button>\n </template>\n </div>\n </template>\n\n <template v-if=\"lightboxOpen\">\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4\"\n @click=\"async (event) => closeLightbox()\"\n >\n <button\n type=\"button\"\n :aria-label='getLabel(\"closeAriaLabel\", \"Close\")'\n class=\"absolute top-4 right-4 z-10 rounded-full bg-white/20 p-2 text-white hover:bg-white/40 transition-colors\"\n @click=\"\n async (e) => {\n e.stopPropagation();\n closeLightbox();\n }\n \"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-6 w-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </button>\n <template v-if=\"hasThumbnails()\">\n <button\n type=\"button\"\n :aria-label='getLabel(\"previousImageAriaLabel\", \"Previous image\")'\n class=\"absolute left-4 z-10 rounded-full bg-white/20 p-2 text-white hover:bg-white/40 transition-colors\"\n @click=\"\n async (e) => {\n e.stopPropagation();\n prevImage();\n }\n \"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-6 w-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M15 19l-7-7 7-7\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </button>\n </template>\n\n <img\n :alt='getLabel(\"productImageFullscreenAlt\", \"Product image fullscreen\")'\n class=\"max-h-full max-w-full object-contain rounded-[var(--radius-container)]\"\n :src=\"getMainImage()\"\n @click=\"async (e) => e.stopPropagation()\"\n />\n <template v-if=\"hasThumbnails()\">\n <button\n type=\"button\"\n :aria-label='getLabel(\"nextImageAriaLabel\", \"Next image\")'\n class=\"absolute right-4 z-10 rounded-full bg-white/20 p-2 text-white hover:bg-white/40 transition-colors\"\n @click=\"\n async (e) => {\n e.stopPropagation();\n nextImage();\n }\n \"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"h-6 w-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 5l7 7-7 7\"\n :strokeWidth=\"2\"\n ></path>\n </svg>\n </button>\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { getLabel as _getLabel } from \"@propeller-commerce/propeller-v2-core-ui\";\n\nexport interface ProductGalleryProps {\n /**\n * Array of image URLs to display.\n * Obtain from: `product.media?.images?.items?.[0]?.imageVariants?.map(v => v.url)`\n * Component is in skeleton/loading state when this is an empty array.\n */\n images: string[];\n\n /** Show image thumbnails below the main image. Defaults to true. */\n showThumbnails?: boolean;\n\n /** Enable cursor-zoom-in hint on the main image. Defaults to true. */\n enableZoom?: boolean;\n\n /** Enable fullscreen lightbox when clicking the main image. Defaults to true. */\n enableLightbox?: boolean;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /** Translated labels keyed by the slugs used inside the component (see\n * `getLabel` calls). Missing keys fall back to the English defaults. */\n labels?: Record<string, string>;\n}\ninterface ProductGalleryState {\n selectedIndex: number;\n lightboxOpen: boolean;\n getImages: () => string[];\n getMainImage: () => string;\n hasThumbnails: () => boolean;\n selectImage: (index: number) => void;\n openLightbox: () => void;\n closeLightbox: () => void;\n prevImage: () => void;\n nextImage: () => void;\n}\n\nconst props = withDefaults(defineProps<ProductGalleryProps>(), {\n enableZoom: true,\n showThumbnails: true,\n enableLightbox: true,\n});\nconst selectedIndex = ref<ProductGalleryState[\"selectedIndex\"]>(0);\nconst lightboxOpen = ref<ProductGalleryState[\"lightboxOpen\"]>(false);\n\nfunction getImages(): ReturnType<ProductGalleryState[\"getImages\"]> {\n return (props.images as string[]) || [];\n}\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getMainImage(): ReturnType<ProductGalleryState[\"getMainImage\"]> {\n const images = getImages();\n if (!images || images.length === 0) return \"\";\n const idx = selectedIndex.value;\n return images[idx] || images[0] || \"\";\n}\nfunction hasThumbnails(): ReturnType<ProductGalleryState[\"hasThumbnails\"]> {\n const images = getImages();\n return !!images && images.length > 1;\n}\nfunction selectImage(\n index: number,\n): ReturnType<ProductGalleryState[\"selectImage\"]> {\n selectedIndex.value = index;\n}\nfunction openLightbox(): ReturnType<ProductGalleryState[\"openLightbox\"]> {\n if (props.enableLightbox !== false) {\n lightboxOpen.value = true;\n }\n}\nfunction closeLightbox(): ReturnType<ProductGalleryState[\"closeLightbox\"]> {\n lightboxOpen.value = false;\n}\nfunction prevImage(): ReturnType<ProductGalleryState[\"prevImage\"]> {\n const images = getImages();\n const len = images?.length || 0;\n if (len === 0) return;\n selectedIndex.value = (selectedIndex.value - 1 + len) % len;\n}\nfunction nextImage(): ReturnType<ProductGalleryState[\"nextImage\"]> {\n const images = getImages();\n const len = images?.length || 0;\n if (len === 0) return;\n selectedIndex.value = (selectedIndex.value + 1) % len;\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-product-grid w-full ${className || ''}`\"\n :data-loading=\"getIsLoading() ? 'true' : 'false'\"\n >\n <template v-if=\"getIsLoading()\">\n <div\n :class=\"`propeller-product-grid__skeleton-grid ${getGridColsClass()}`\"\n >\n <template :key=\"idx\" v-for=\"(_, idx) in getSkeletonItems()\">\n <div\n class=\"propeller-product-grid__skeleton-card flex flex-col overflow-hidden rounded-[var(--radius-container)] border border-border bg-card shadow-sm\"\n >\n <div\n class=\"propeller-product-grid__skeleton-image aspect-square bg-surface-hover animate-pulse\"\n ></div>\n <div class=\"p-4 flex flex-col gap-2 flex-1\">\n <div\n class=\"propeller-product-grid__skeleton-line h-3 bg-surface-hover animate-pulse rounded w-1/4\"\n ></div>\n <div\n class=\"propeller-product-grid__skeleton-line h-4 bg-surface-hover animate-pulse rounded w-3/4\"\n ></div>\n <div\n class=\"propeller-product-grid__skeleton-line h-4 bg-surface-hover animate-pulse rounded w-1/2\"\n ></div>\n <div class=\"mt-auto pt-2\">\n <div\n class=\"propeller-product-grid__skeleton-line h-5 bg-surface-hover animate-pulse rounded w-1/3\"\n ></div>\n </div>\n </div>\n <template v-if=\"showAddToCart()\">\n <div class=\"p-4 pt-0\">\n <div class=\"flex items-center gap-2\">\n <div\n class=\"propeller-product-grid__skeleton-line h-9 flex-1 bg-surface-hover animate-pulse rounded\"\n ></div>\n <div\n class=\"propeller-product-grid__skeleton-line h-9 flex-1 bg-surface-hover animate-pulse rounded\"\n ></div>\n </div>\n </div>\n </template>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"!getIsLoading()\">\n <template v-if=\"getDisplayProducts().length === 0\">\n <div\n class=\"propeller-product-grid__empty text-center py-24 bg-surface-hover rounded-xl border border-dashed border-border\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-product-grid__empty-icon mx-auto h-12 w-12 text-foreground-subtle\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4\"\n :strokeWidth=\"1\"\n ></path>\n </svg>\n <h3\n class=\"propeller-product-grid__empty-title mt-4 text-lg font-semibold text-foreground\"\n >\n {{ getLabel(\"noProductsFound\", \"No products found\") }}\n </h3>\n <p\n class=\"propeller-product-grid__empty-message mt-1 text-sm text-muted-foreground\"\n >\n {{ getLabel(\"noProductsHelp\", \"Try adjusting your filters or search term.\") }}\n </p>\n </div>\n </template>\n\n <template v-if=\"getDisplayProducts().length > 0\">\n <div :class=\"`propeller-product-grid__grid ${getGridColsClass()}`\">\n <template\n :key=\"(item as Product).productId || (item as Cluster).clusterId || idx\"\n v-for=\"(item, idx) in getDisplayProducts()\"\n >\n <slot name=\"beforeItem\" :item=\"item\" :index=\"idx\" />\n <div>\n <template v-if=\"isClusterItem(item)\">\n <component\n :is=\"ClusterCardImpl\"\n :columns=\"props.columns || 3\"\n :cluster=\"(item as Cluster)\"\n :configuration=\"infra.configuration\"\n :includeTax=\"infra.includeTax\"\n :showPrice=\"props.showPrice\"\n :language=\"infra.language || 'NL'\"\n :showStock=\"props.showStock\"\n :showAvailability=\"props.showAvailability\"\n :labels=\"props.clusterCardLabels\"\n :stockLabels=\"props.stockLabels\"\n :enableAddFavorite=\"props.enableAddFavorite\"\n :onToggleFavorite=\"\n (cluster: Cluster, isFav: boolean) => {\n if (props.onToggleFavorite) {\n props.onToggleFavorite(cluster, isFav);\n }\n }\n \"\n :onClusterClick=\"\n (cluster: Cluster) => {\n if (props.onClusterClick) {\n props.onClusterClick(cluster);\n }\n }\n \"\n />\n </template>\n\n <template v-if=\"!isClusterItem(item)\">\n <component\n :is=\"ProductCardImpl\"\n :columns=\"props.columns || 3\"\n :product=\"(item as Product)\"\n :showPrice=\"props.showPrice\"\n :allowAddToCart=\"\n showAddToCart() ? props.allowAddToCart : false\n \"\n :graphqlClient=\"infra.graphqlClient!\"\n :user=\"infra.user || null\"\n :configuration=\"infra.configuration\"\n :includeTax=\"infra.includeTax\"\n :cartId=\"props.cartId\"\n :createCart=\"props.createCart\"\n :onCartCreated=\"props.onCartCreated\"\n :afterAddToCart=\"props.afterAddToCart\"\n :showModal=\"props.showModal\"\n :allowIncrDecr=\"props.allowIncrDecr\"\n :enableStockValidation=\"props.stockValidation\"\n :language=\"infra.language || 'NL'\"\n :onProceedToCheckout=\"props.onProceedToCheckout\"\n :onRequestQuoteClick=\"props.onRequestQuoteClick\"\n :labels=\"props.productCardLabels\"\n :addToCartLabels=\"props.addToCartLabels\"\n :enableAddFavorite=\"props.enableAddFavorite\"\n :showStock=\"props.showStock\"\n :showAvailability=\"props.showAvailability\"\n :stockLabels=\"props.stockLabels\"\n :priceLabels=\"props.priceLabels\"\n :companyId=\"infra.companyId\"\n :onToggleFavorite=\"\n (product: Product, isFav: boolean) => {\n if (props.onToggleFavorite)\n props.onToggleFavorite(product, isFav);\n }\n \"\n :onProductClick=\"\n (product: Product) => {\n if (props.onProductClick) props.onProductClick(product);\n }\n \"\n />\n </template>\n </div>\n <slot name=\"afterItem\" :item=\"item\" :index=\"idx\" />\n </template>\n </div>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, watch, type Component } from \"vue\";\n\nimport {\n GraphQLClient,\n Product,\n Cluster,\n Cart,\n CartMainItem,\n AttributeFilter,\n ProductTextFilterInput,\n ProductsResponse,\n Category,\n Contact,\n Customer,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport DefaultProductCard from \"./ProductCard.vue\";\nimport DefaultClusterCard from \"./ClusterCard.vue\";\nimport { useProductSearch } from \"../composables/vue/useProductSearch\";\nimport { getLabel as _getLabel } from \"@propeller-commerce/propeller-v2-core-ui\";\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\nimport {\n provideProductGridConfig,\n type ProductGridConfig,\n} from \"../context/ProductGridContext\";\n\nexport interface ProductGridProps {\n // ── Data source ──────────────────────────────────────────────────────────\n\n /**\n * Initialised Propeller SDK GraphQL client.\n * Required when `products` is not provided — used for internal data fetching.\n */\n graphqlClient?: GraphQLClient;\n\n /**\n * Pre-fetched products/clusters to display.\n * When provided the component skips internal API calls entirely.\n * Pass an empty array (not undefined) to show the empty state while the\n * parent controls loading.\n */\n products?: (Product | Cluster)[];\n\n // ── Locale / pricing ─────────────────────────────────────────────────────\n\n /** Language code for product data. Defaults to 'NL'. */\n language?: string;\n\n /** Tax zone used for price calculation. Defaults to 'NL'. */\n taxZone?: string;\n\n // ── Query mode (only used when graphqlClient is provided) ─────────────────\n\n /**\n * Category ID to list products for (category-page mode).\n * When omitted alongside `term` and `brand`, `config.baseCategoryId` is used.\n */\n categoryId?: number;\n\n /**\n * Search term — passes `term` into categoryProductSearchInput and uses\n * `config.baseCategoryId` so the whole catalog is searched.\n */\n term?: string;\n\n /**\n * Manufacturer/brand name — passes `manufacturers: [brand]` into\n * categoryProductSearchInput and uses `config.baseCategoryId`.\n */\n brand?: string;\n\n // ── Layout ────────────────────────────────────────────────────────────────\n\n /** Number of columns in the grid. Accepts 2, 3, 4, 5, or 6. Defaults to 3. */\n columns?: number;\n\n // ── Loading ───────────────────────────────────────────────────────────────\n\n /**\n * Show a skeleton loader.\n * Useful when the parent controls loading state and passes `products` down.\n * The grid automatically shows a skeleton during internal fetches regardless\n * of this prop. Defaults to false.\n */\n isLoading?: boolean;\n\n // ── Portal / visibility ───────────────────────────────────────────────────\n\n /**\n * Controls portal visibility mode.\n * 'open' — full e-commerce; AddToCart is visible in product cards.\n * 'semi-closed' — catalog-only; AddToCart is hidden.\n * Defaults to 'open'.\n */\n portalMode?: string;\n\n /** Authenticated user passed through to ProductCard / AddToCart. */\n user?: Contact | Customer | null;\n\n /** Active company ID from the company switcher. Overrides user's default company for price calculation. Triggers a re-fetch when changed. */\n companyId?: number;\n\n /**\n * When true, tax-inclusive (gross) price is the leading price.\n * Defaults to false.\n */\n includeTax?: boolean;\n\n /**\n * Enables stock validation inside AddToCart.\n * Blocks add when requested quantity exceeds available stock.\n * Defaults to false.\n */\n stockValidation?: boolean;\n\n /**\n * When false, hides the AddToCart control in product cards.\n * ClusterCards always show their \"View cluster\" navigation button.\n * Defaults to true.\n */\n allowAddToCart?: boolean;\n\n /* ── External hooks ───────────────────────────────────────────────────────── */\n\n /**\n * Called after each internal data fetch with the filterable attributes\n * returned by the API (for driving a sibling FiltersSidebar).\n */\n onFiltersChange?: (filters: AttributeFilter[]) => void;\n\n /**\n * Active text filters to apply — built by the parent from FiltersSidebar\n * `onFilterChange` callbacks. Each entry maps to a `textFilters` input\n * row in the CategoryService query.\n * When this prop changes the grid automatically re-fetches (page resets to 1).\n */\n textFilters?: ProductTextFilterInput[];\n\n /**\n * Active price range lower bound from the FiltersSidebar `onPriceChange`.\n * Triggers a re-fetch when changed.\n */\n priceFilterMin?: number;\n\n /**\n * Active price range upper bound from the FiltersSidebar `onPriceChange`.\n * Triggers a re-fetch when changed.\n */\n priceFilterMax?: number;\n\n /**\n * Called when sort state changes internally (for syncing a sibling toolbar).\n */\n onSortChange?: (sort: any) => void;\n\n /**\n * Called after each internal data fetch with the min/max price of the\n * current product set — use to populate a price range slider in the parent.\n */\n onPriceBoundsChange?: (min: number, max: number) => void;\n\n /**\n * Called after each fetch with the total number of products found —\n * use to display a result count in the parent toolbar.\n */\n onItemsFoundChange?: (count: number) => void;\n\n /**\n * Called after each fetch with the number of items visible on the current page\n * (after client-side language filtering).\n */\n onPageItemCountChange?: (count: number) => void;\n\n /**\n * Called when the user clicks Previous / Next in the built-in pagination —\n * use to keep the parent URL / page state in sync.\n */\n onPageChange?: (page: number) => void;\n\n /**\n * Called after each successful internal data fetch with the full\n * ProductsResponse object — use to drive an external GridPagination\n * component by passing the result as its `products` prop.\n */\n onProductsResponse?: (products: ProductsResponse) => void;\n\n /**\n * Called after each successful internal data fetch with the full\n * Category object — use to populate sibling components like GridTitle,\n * CategoryDescription, and CategoryShortDescription.\n */\n onCategoryChange?: (category: Category) => void;\n\n /**\n * Called whenever the internal loading state changes.\n * Use to disable sibling components (e.g. GridFilters) while a fetch is in flight.\n */\n onLoadingChange?: (isLoading: boolean) => void;\n\n /**\n * Externally controlled current page.\n * When provided, the grid uses this value instead of its internal page\n * counter. Wire this to the `onPageChange` callback from a sibling\n * GridPagination so the two components stay in sync.\n * When changed the grid automatically re-fetches.\n */\n page?: number;\n\n /**\n * Number of products per page. Defaults to 12.\n * When changed the grid automatically re-fetches (page resets to 1).\n */\n pageSize?: number;\n\n /**\n * Sort field to use (e.g. 'NAME', 'PRICE').\n * When provided overrides internal sort state.\n * When changed the grid automatically re-fetches (page resets to 1).\n */\n sortField?: string;\n\n /**\n * Sort direction: 'ASC' or 'DESC'.\n * Only used when sortField is also provided.\n * When changed the grid automatically re-fetches (page resets to 1).\n */\n sortOrder?: string;\n\n /* ── Configuration ──────────────────────────────────────────────────────── */\n\n /**\n * Configuration object providing:\n * imageSearchFiltersGrid, imageVariantFiltersMedium — passed to CategoryService\n * baseCategoryId — used when querying by term or brand\n * urls.getProductUrl / urls.getClusterUrl — for card URL generation\n */\n configuration?: any;\n\n /* ── ProductCard / AddToCart pass-through props ─────────────────────────── */\n\n /** ID of an existing cart to add items into. */\n cartId?: string;\n\n /**\n * Auto-create a cart when none is available.\n * Always pair with `onCartCreated` to persist the new cart ID.\n */\n createCart?: boolean;\n\n /** Called after AddToCart creates a new cart internally. */\n onCartCreated?: (cart: Cart) => void;\n\n /** Called after every successful add-to-cart operation. */\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n\n /**\n * When true, AddToCart shows a success modal instead of a toast.\n * Defaults to false.\n */\n showModal?: boolean;\n\n /**\n * Render − / + stepper buttons in AddToCart.\n * Defaults to true.\n */\n allowIncrDecr?: boolean;\n\n /** Called when \"Proceed to checkout\" is clicked in the AddToCart modal. */\n onProceedToCheckout?: () => void;\n\n /** Called when \"Request a Quote\" is clicked in the AddToCart modal. */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /**\n * Label overrides forwarded directly to the embedded AddToCart component.\n * Keys: add, adding, addedToCart, outOfStock, noCartId, errorAdding,\n * modalTitle, quantity, continueShopping, proceedToCheckout\n */\n addToCartLabels?: Record<string, string>;\n\n /** Translated labels forwarded to embedded `<ProductCard>` instances.\n * See `ProductCardProps.labels` for slugs. */\n productCardLabels?: Record<string, string>;\n\n /** Translated labels forwarded to embedded `<ClusterCard>` instances.\n * See `ClusterCardProps.labels` for slugs. */\n clusterCardLabels?: Record<string, string>;\n\n /* ── Stock display ───────────────────────────────────────────────────────── */\n\n /**\n * Show the stock / availability widget on each product card.\n * Forwarded directly to `ProductCard.showStock`.\n * Defaults to false.\n */\n showStock?: boolean;\n\n /**\n * Show only the availability indicator inside the stock widget.\n * Forwarded to `ProductCard.showAvailability`.\n * Defaults to true.\n */\n showAvailability?: boolean;\n\n /**\n * Show the price below the product name.\n * Defaults to true.\n */\n showPrice?: boolean;\n\n /**\n * Label overrides forwarded to the embedded ItemStock component inside each card.\n * Keys: inStock, outOfStock, lowStock, available, notAvailable, pieces\n */\n stockLabels?: Record<string, string>;\n\n /** Translated labels forwarded to the embedded `<ProductPrice>` display\n * inside each `<ProductCard>`. See `ProductPriceProps.labels` for slugs. */\n priceLabels?: Record<string, string>;\n\n /* ── Card interaction ────────────────────────────────────────────────────── */\n\n /** Show a heart-icon favourite toggle on each card. */\n enableAddFavorite?: boolean;\n\n /**\n * Called when a favourite is toggled on any card.\n * Receives the full Product or Cluster object and the new favourite state.\n */\n onToggleFavorite?: (item: Product | Cluster, isFavorite: boolean) => void;\n\n /**\n * Called when a cluster card name, image, or \"View cluster\" button is\n * clicked — use for SPA-style routing instead of full-page navigation.\n */\n onClusterClick?: (cluster: Cluster) => void;\n\n /**\n * Called when a product card name or image is clicked — use for SPA\n * routing instead of full-page navigation.\n */\n onProductClick?: (product: Product) => void;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /** Translated labels keyed by the slugs used inside the component (see\n * `getLabel` calls). Missing keys fall back to the English defaults. */\n labels?: Record<string, string>;\n\n // ───── Extension API ─────\n // Sub-component injection — cascades through ProductGridConfig context\n // to every nested ProductCard / ClusterCard.\n priceComponent?: Component;\n stockComponent?: Component;\n addToCartComponent?: Component;\n imageComponent?: Component;\n badgesComponent?: Component;\n favoriteComponent?: Component;\n\n // Iteration-level: replace the whole ProductCard / ClusterCard.\n productCardComponent?: Component;\n clusterCardComponent?: Component;\n}\ninterface ProductGridState {\n internalProducts: (Product | Cluster)[];\n isInternalLoading: boolean;\n currentPage: number;\n totalPages: number;\n itemsFound: number;\n currentSortField: string;\n currentSortOrder: string;\n fetchId: number;\n fetchProducts: () => Promise<void>;\n isClusterItem: (item: Product | Cluster) => boolean;\n getGridColsClass: () => string;\n handlePageChange: (page: number) => void;\n getDisplayProducts: () => (Product | Cluster)[];\n getIsLoading: () => boolean;\n showAddToCart: () => boolean;\n getSkeletonItems: () => number[];\n}\n\nconst props = withDefaults(defineProps<ProductGridProps>(), {\n allowAddToCart: true,\n allowIncrDecr: true,\n showAvailability: true,\n showPrice: true,\n showStock: false,\n isLoading: false,\n});\n\n// Resolve infrastructure props (graphqlClient, configuration, user, companyId,\n// language, includeTax, portalMode) from the propellerVue plugin scope +\n// <PropellerProvider> when the host doesn't pass them explicitly. Without this\n// a consumer that relies on the provider (e.g. propeller-vue's CategoryView,\n// which omits :graphqlClient) leaves useProductSearch with no client, so its\n// fetch short-circuits and the grid only ever shows SSR-seeded items — empty\n// on every client-side navigation. Explicit props still win via useInfraProps\n// precedence. Mirrors the pattern already used by Menu.vue.\nconst infra = useInfraProps(props);\n\n// ───── Extension API ─────\n// Iteration-level component override: swap the whole card or fall back to\n// the built-in implementation.\nconst ProductCardImpl = computed(\n () => props.productCardComponent ?? DefaultProductCard,\n);\nconst ClusterCardImpl = computed(\n () => props.clusterCardComponent ?? DefaultClusterCard,\n);\n\n// Build the ProductGridConfig that cascades to nested cards. Includes the\n// existing show*/allow* flags + callbacks PLUS the new component-slot keys.\n// NOTE: provideProductGridConfig takes a plain ProductGridConfig, so\n// consumers receive the snapshot at mount time. Extension-API props are\n// expected to be stable for the lifetime of a mounted ProductGrid; if\n// reactivity is later required, change `provideProductGridConfig` to accept\n// a ref/computed and have consumers read `.value`.\nconst gridConfig = computed<ProductGridConfig>(() => ({\n columns: (props.columns as number) || 3,\n showStock: props.showStock,\n showAvailability: props.showAvailability,\n showPrice: props.showPrice,\n allowAddToCart: props.allowAddToCart,\n enableAddFavorite: props.enableAddFavorite,\n createCart: props.createCart,\n showModal: props.showModal,\n allowIncrDecr: props.allowIncrDecr,\n enableStockValidation: props.stockValidation,\n cartId: props.cartId,\n stockLabels: props.stockLabels,\n priceLabels: props.priceLabels,\n addToCartLabels: props.addToCartLabels,\n onCartCreated: props.onCartCreated,\n afterAddToCart: props.afterAddToCart,\n onProceedToCheckout: props.onProceedToCheckout,\n onRequestQuoteClick: props.onRequestQuoteClick,\n onToggleFavorite: props.onToggleFavorite,\n onProductClick: props.onProductClick,\n onClusterClick: props.onClusterClick,\n // Extension API slot cascade\n productCardComponent: props.productCardComponent,\n clusterCardComponent: props.clusterCardComponent,\n priceComponent: props.priceComponent,\n stockComponent: props.stockComponent,\n addToCartComponent: props.addToCartComponent,\n imageComponent: props.imageComponent,\n badgesComponent: props.badgesComponent,\n favoriteComponent: props.favoriteComponent,\n}));\n\n// CRITICAL: provide() must be called from setup synchronously.\nprovideProductGridConfig(gridConfig.value);\n\nconst categoryIdRef = computed(() => props.categoryId);\nconst termRef = computed(() => props.term);\nconst brandRef = computed(() => props.brand);\nconst langRef = computed(() => infra.language || \"NL\");\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId);\nconst textFiltersRef = computed(() => props.textFilters);\nconst priceMinRef = computed(() => props.priceFilterMin);\nconst priceMaxRef = computed(() => props.priceFilterMax);\nconst sortFieldRef = computed(() => props.sortField);\nconst sortOrderRef = computed(() => props.sortOrder);\nconst pageRef = computed(() => props.page);\nconst pageSizeRef = computed(() => props.pageSize ?? 12);\nconst productsRef = computed(() => props.products);\n\nconst {\n displayProducts,\n isLoading,\n itemsFound,\n currentSortField,\n currentSortOrder,\n currentPage,\n totalPages,\n fetchProducts,\n goToPage,\n} = useProductSearch({\n graphqlClient: infra.graphqlClient,\n products: productsRef,\n categoryId: categoryIdRef,\n term: termRef,\n brand: brandRef,\n language: langRef,\n taxZone: props.taxZone,\n user: userRef,\n companyId: companyRef,\n textFilters: textFiltersRef,\n priceFilterMin: priceMinRef,\n priceFilterMax: priceMaxRef,\n sortField: sortFieldRef,\n sortOrder: sortOrderRef,\n page: pageRef,\n pageSize: pageSizeRef,\n configuration: infra.configuration,\n onFiltersChange: props.onFiltersChange,\n onPriceBoundsChange: props.onPriceBoundsChange,\n onItemsFoundChange: props.onItemsFoundChange,\n onPageChange: props.onPageChange,\n onProductsResponse: props.onProductsResponse,\n onCategoryChange: props.onCategoryChange,\n});\n\n// onLoadingChange is not a composable option — wire via watch:\nwatch(\n () => isLoading.value,\n (v) => props.onLoadingChange?.(v),\n);\n\nfunction isClusterItem(\n item: Product | Cluster,\n): ReturnType<ProductGridState[\"isClusterItem\"]> {\n return !!(item as any)?.clusterId;\n}\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction getGridColsClass(): ReturnType<ProductGridState[\"getGridColsClass\"]> {\n const cols = (props.columns as number) || 3;\n if (cols === 1) return \"flex flex-col gap-4\";\n if (cols === 2) return \"grid grid-cols-2 gap-3 sm:gap-6 auto-rows-fr\";\n if (cols === 4)\n return \"grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-6 auto-rows-fr\";\n if (cols === 5)\n return \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3 sm:gap-6 auto-rows-fr\";\n if (cols === 6)\n return \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3 sm:gap-6 auto-rows-fr\";\n return \"grid grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-6 auto-rows-fr\";\n}\nfunction handlePageChange(\n page: number,\n): ReturnType<ProductGridState[\"handlePageChange\"]> {\n goToPage(page);\n}\nfunction getDisplayProducts(): ReturnType<\n ProductGridState[\"getDisplayProducts\"]\n> {\n return displayProducts.value;\n}\nfunction getIsLoading(): ReturnType<ProductGridState[\"getIsLoading\"]> {\n return isLoading.value || (props.isLoading ?? false);\n}\nfunction showAddToCart(): ReturnType<ProductGridState[\"showAddToCart\"]> {\n const mode = (infra.portalMode as string) || \"open\";\n const allow = (props.allowAddToCart as boolean) !== false;\n return mode === \"open\" && allow;\n}\nfunction getSkeletonItems(): ReturnType<ProductGridState[\"getSkeletonItems\"]> {\n const cols = (props.columns as number) || 3;\n const count =\n cols === 2 ? 4 : cols === 4 ? 8 : cols === 5 ? 10 : cols === 6 ? 12 : 6;\n const items: number[] = [];\n for (let i = 0; i < count; i++) items.push(i);\n return items;\n}\n</script>\n","<template>\n <div\n v-if=\"!useNewShell\"\n :class=\"`propeller-product-info ${className || ''}`\"\n :data-loading=\"loading ? 'true' : 'false'\"\n >\n <template v-if=\"loading && !product\">\n <div class=\"propeller-product-info__skeleton animate-pulse space-y-3\">\n <div\n class=\"propeller-product-info__skeleton-line h-4 bg-surface-hover rounded w-1/4\"\n ></div>\n <div\n class=\"propeller-product-info__skeleton-line h-8 bg-surface-hover rounded w-3/4\"\n ></div>\n </div>\n </template>\n\n <template v-if=\"!loading || !!product\">\n <template v-if=\"showSku !== false && !!getProductSku()\">\n <div class=\"text-sm font-mono text-muted-foreground mb-2\">\n SKU: {{ getProductSku() }}\n </div>\n </template>\n\n <template v-if=\"showTitle !== false && !!getProductName()\">\n <h1 class=\"text-4xl font-bold tracking-tight text-foreground mb-4\">\n {{ getProductName() }}\n </h1>\n </template>\n </template>\n </div>\n\n <div\n v-else\n :class=\"`propeller-product-info ${className || ''}`\"\n >\n <slot name=\"beforeContent\" :product=\"resolvedProduct\" />\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div class=\"propeller-product-info__media relative\">\n <slot\n v-if=\"showImage !== false && resolvedProduct\"\n name=\"image\"\n :product=\"resolvedProduct\"\n :language=\"language\"\n :imageSearchFilters=\"imageSearchFilters\"\n :imageVariantFilters=\"imageVariantFilters\"\n >\n <component\n :is=\"ImageImpl\"\n :product=\"resolvedProduct\"\n :language=\"language\"\n :image-search-filters=\"imageSearchFilters\"\n :image-variant-filters=\"imageVariantFilters\"\n />\n </slot>\n <slot\n v-if=\"showBadges !== false && resolvedProduct\"\n name=\"badges\"\n :product=\"resolvedProduct\"\n :labels=\"labels\"\n >\n <component\n :is=\"BadgesImpl\"\n :product=\"resolvedProduct\"\n :labels=\"labels\"\n />\n </slot>\n </div>\n <div class=\"propeller-product-info__content space-y-4\">\n <slot\n v-if=\"showTitle !== false && !!getProductName(resolvedProduct)\"\n name=\"title\"\n :product=\"resolvedProduct\"\n :name=\"getProductName(resolvedProduct)\"\n >\n <h1 class=\"text-2xl font-bold tracking-tight text-foreground\">\n {{ getProductName(resolvedProduct) }}\n </h1>\n </slot>\n <slot\n v-if=\"showSku !== false && !!getProductSku(resolvedProduct)\"\n name=\"sku\"\n :product=\"resolvedProduct\"\n :sku=\"getProductSku(resolvedProduct)\"\n >\n <div class=\"text-sm font-mono text-muted-foreground\">\n SKU: {{ getProductSku(resolvedProduct) }}\n </div>\n </slot>\n <slot\n v-if=\"showFavorite !== false && resolvedProduct\"\n name=\"favorite\"\n :product=\"resolvedProduct\"\n :user=\"user\"\n >\n <component\n :is=\"FavoriteImpl\"\n :product=\"resolvedProduct\"\n :product-id=\"resolvedProduct.productId\"\n :graphql-client=\"graphqlClient\"\n :user=\"user\"\n :labels=\"labels\"\n />\n </slot>\n <slot\n v-if=\"showPrice !== false && resolvedProduct?.price\"\n name=\"price\"\n :product=\"resolvedProduct\"\n :price=\"resolvedProduct.price\"\n :includeTax=\"includeTax\"\n :currency=\"currency\"\n :labels=\"labels\"\n >\n <component\n :is=\"PriceImpl\"\n :price=\"resolvedProduct.price\"\n :include-tax=\"includeTax\"\n :currency=\"currency\"\n :tax-zone=\"taxZone\"\n :user=\"user\"\n :labels=\"labels\"\n />\n </slot>\n <slot\n v-if=\"showStock !== false && resolvedProduct?.inventory\"\n name=\"stock\"\n :product=\"resolvedProduct\"\n :inventory=\"resolvedProduct.inventory\"\n :showStock=\"true\"\n :showAvailability=\"true\"\n :labels=\"labels\"\n >\n <component\n :is=\"StockImpl\"\n :inventory=\"resolvedProduct.inventory\"\n :show-stock=\"true\"\n :show-availability=\"true\"\n :labels=\"labels\"\n />\n </slot>\n <slot\n v-if=\"showAddToCart !== false && resolvedProduct\"\n name=\"addToCart\"\n :product=\"resolvedProduct\"\n :cartId=\"undefined\"\n :labels=\"labels\"\n >\n <component\n :is=\"AddToCartImpl\"\n :product=\"resolvedProduct\"\n :graphql-client=\"graphqlClient\"\n :user=\"user\"\n :company-id=\"companyId\"\n :configuration=\"configuration\"\n :include-tax=\"includeTax\"\n :currency=\"currency\"\n :language=\"language\"\n :labels=\"labels\"\n />\n </slot>\n <slot\n v-if=\"showBundles !== false && resolvedProduct\"\n name=\"bundles\"\n :product=\"resolvedProduct\"\n :labels=\"labels\"\n >\n <component\n :is=\"BundlesImpl\"\n :product=\"resolvedProduct\"\n :product-id=\"resolvedProduct.productId\"\n :graphql-client=\"graphqlClient\"\n :user=\"user\"\n :company-id=\"companyId\"\n :configuration=\"configuration\"\n :include-tax=\"includeTax\"\n :tax-zone=\"taxZone\"\n :language=\"language\"\n :labels=\"labels\"\n />\n </slot>\n <slot\n v-if=\"showBulkPrices !== false && resolvedProduct?.bulkPrices\"\n name=\"bulkPrices\"\n :product=\"resolvedProduct\"\n :bulkPrices=\"resolvedProduct.bulkPrices\"\n :includeTax=\"includeTax\"\n :labels=\"labels\"\n >\n <component\n :is=\"BulkPricesImpl\"\n :product=\"resolvedProduct\"\n :bulk-prices=\"resolvedProduct.bulkPrices\"\n :include-tax=\"includeTax\"\n :tax-zone=\"taxZone\"\n :currency=\"currency\"\n :user=\"user\"\n :labels=\"labels\"\n />\n </slot>\n <slot\n v-if=\"showSurcharges !== false && resolvedProduct\"\n name=\"surcharges\"\n :product=\"resolvedProduct\"\n :includeTax=\"includeTax\"\n :labels=\"labels\"\n >\n <component\n :is=\"SurchargesImpl\"\n :product=\"resolvedProduct\"\n :include-tax=\"includeTax\"\n :labels=\"labels\"\n />\n </slot>\n </div>\n </div>\n <slot name=\"afterContent\" :product=\"resolvedProduct\" />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, watch, type Component } from \"vue\";\n\nimport {\n GraphQLClient,\n Product,\n LocalizedString,\n Contact,\n Customer,\n} from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useProductInfo } from \"../composables/vue/useProductInfo\";\nimport {\n getLanguageString,\n getLanguageUri,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n provideProductGridConfig,\n type ProductGridConfig,\n} from '../context/ProductGridContext';\nimport DefaultProductPrice from './ProductPrice.vue';\nimport DefaultItemStock from './ItemStock.vue';\nimport DefaultAddToCart from './AddToCart.vue';\nimport DefaultAddToFavorite from './AddToFavorite.vue';\nimport DefaultProductBundles from './ProductBundles.vue';\nimport DefaultProductBulkPrices from './ProductBulkPrices.vue';\nimport DefaultProductImage from './defaults/DefaultProductImage.vue';\nimport DefaultProductBadges from './defaults/DefaultProductBadges.vue';\nimport DefaultProductSurcharges from './defaults/DefaultProductSurcharges.vue';\n\nexport interface ProductInfoProps {\n // ── Data source ──────────────────────────────────────────────────────────\n /** The authenticated user (Contact or Customer) */\n user: Contact | Customer | null;\n\n /** Active company ID from the company switcher.\n * Overrides default company for price calculation.\n * Triggers a re-fetch when changed. */\n companyId?: number;\n\n /**\n * Pre-fetched product object to display.\n * When provided the component skips internal fetching.\n */\n product?: Product;\n\n /**\n * Product ID to fetch data for when no `product` prop is provided.\n * Requires `graphqlClient` to be set.\n */\n productId?: number;\n\n /**\n * Initialised Propeller SDK GraphQL client.\n * Required when `productId` is provided for internal data fetching.\n */\n graphqlClient?: GraphQLClient;\n\n /**\n * Image search filter passed to ProductService.getProduct().\n * Controls how many image items are returned.\n * Example: { page: 1, offset: 20 }\n */\n imageSearchFilters?: any;\n\n /**\n * Image variant transformation filter passed to ProductService.getProduct().\n * Controls image size/format variants returned with the product.\n * Example: imageVariantFiltersLarge from @/data/defaults\n * Defaults to { transformations: [] } when omitted.\n */\n imageVariantFilters?: any;\n\n /**\n * Tax zone to use for price calculation.\n */\n taxZone?: string;\n\n /**\n * Called once the product data is loaded — either immediately (when\n * `product` prop is supplied) or after the internal fetch completes.\n * Use this to hydrate sibling components (gallery, price, descriptions, etc.).\n */\n onProductLoaded?: (product: Product) => void;\n\n // ── Display toggles ───────────────────────────────────────────────────────\n\n /** Show the product name. Defaults to true. */\n showTitle?: boolean;\n\n /** Show the product SKU. Defaults to true. */\n showSku?: boolean;\n\n // ── Locale ────────────────────────────────────────────────────────────────\n\n /** Language code used to resolve localised names. Defaults to 'NL'. */\n language?: string;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n /**\n * Config object providing imageSearchFiltersGrid and imageVariantFiltersSmall.\n */\n configuration?: any;\n\n /**\n * Attribute codes/names to look up and display as badge overlays on the product image.\n * Each code is resolved against `product.attributes.items[].attributeDescription.code`\n * (or `.name`). Attributes with no matching value are silently omitted.\n * Example: ['new', 'sale']\n */\n imageLabels?: string[];\n\n /**\n * Attribute codes/names to look up and display as extra text rows below the product name.\n * Resolved the same way as `imageLabels`.\n * Example: ['brand', 'color']\n */\n textLabels?: string[];\n\n // ───── Extension API ─────\n // New PDP shell. Passing ANY new `show*` prop or any *Component prop\n // opts INTO the new shell layout. When none is passed, ProductInfo\n // preserves the legacy minimal title+SKU block (backward compat).\n showImage?: boolean;\n showBadges?: boolean;\n showFavorite?: boolean;\n showPrice?: boolean;\n showStock?: boolean;\n showAddToCart?: boolean;\n showBundles?: boolean;\n showBulkPrices?: boolean;\n showSurcharges?: boolean;\n\n imageComponent?: Component;\n badgesComponent?: Component;\n favoriteComponent?: Component;\n priceComponent?: Component;\n stockComponent?: Component;\n addToCartComponent?: Component;\n bundlesComponent?: Component;\n bulkPricesComponent?: Component;\n surchargesComponent?: Component;\n\n // Forwarded display props for the shell:\n includeTax?: boolean;\n currency?: string;\n\n /**\n * Override any UI string.\n * Forwarded down to nested default components in the new shell.\n */\n labels?: Record<string, string>;\n}\n\nconst props = withDefaults(defineProps<ProductInfoProps>(), {\n showSku: true,\n showTitle: true,\n});\n\nconst userRef = computed(() => props.user ?? null);\nconst companyRef = computed(() => props.companyId);\nconst langRef = computed(() => props.language || \"NL\");\n\nconst { product, cluster, loading, error, fetchProduct, fetchCluster } =\n useProductInfo({\n graphqlClient: props.graphqlClient as GraphQLClient,\n language: langRef,\n taxZone: props.taxZone,\n user: userRef,\n companyId: companyRef,\n configuration: props.configuration,\n });\n\nonMounted(() => {\n if (props.product) {\n if (props.onProductLoaded) {\n props.onProductLoaded(props.product);\n }\n return;\n }\n if (props.productId) {\n fetchProduct(props.productId).then(() => {\n if (product.value && props.onProductLoaded) {\n props.onProductLoaded(product.value);\n }\n });\n }\n});\n\nwatch(\n () => [\n props.productId,\n props.product,\n props.language,\n props.user,\n props.companyId,\n ],\n () => {\n if (props.product) {\n if (props.onProductLoaded) {\n props.onProductLoaded(props.product);\n }\n return;\n }\n if (!props.productId) return;\n fetchProduct(props.productId).then(() => {\n if (product.value && props.onProductLoaded) {\n props.onProductLoaded(product.value);\n }\n });\n },\n);\n\nfunction getDisplayProduct(): Product | null {\n return (props.product as Product) || product.value;\n}\nfunction getProductName(p?: Product | null): string {\n const target = p ?? getDisplayProduct();\n if (!target) return \"\";\n return getLanguageString(target.names, props.language || \"NL\", \"\");\n}\nfunction getProductSku(p?: Product | null): string {\n const target = p ?? getDisplayProduct();\n return target?.sku || \"\";\n}\n\n// ───── Extension API ─────\nconst resolvedProduct = computed<Product | null>(() => getDisplayProduct());\n\n// Keys whose presence on `<ProductInfo>` opts the consumer into the new\n// (composable) shell. Only `*Component` injection props count — Boolean\n// `show*` props are deliberately excluded because Vue 3 normalizes any\n// declared Boolean prop the parent doesn't pass to `false` (not `undefined`),\n// which made `useNewShell` falsely fire on every legacy call site that did\n// `<ProductInfo :product=\"...\" />` with no slots and no injection. The\n// new shell's per-section visibility is still honoured via the\n// `v-if=\"show* !== false && …\"` checks inside the template; consumers who\n// only want to hide a section don't need the new shell anyway, because the\n// legacy shell only renders SKU + title.\nconst NEW_SHELL_KEYS = [\n 'imageComponent', 'badgesComponent', 'favoriteComponent', 'priceComponent',\n 'stockComponent', 'addToCartComponent', 'bundlesComponent',\n 'bulkPricesComponent', 'surchargesComponent',\n] as const;\n\nconst useNewShell = computed(() =>\n NEW_SHELL_KEYS.some((k) => (props as Record<string, unknown>)[k] !== undefined)\n);\n\nconst ImageImpl = computed(() => props.imageComponent ?? DefaultProductImage);\nconst BadgesImpl = computed(() => props.badgesComponent ?? DefaultProductBadges);\nconst FavoriteImpl = computed(() => props.favoriteComponent ?? DefaultAddToFavorite);\nconst PriceImpl = computed(() => props.priceComponent ?? DefaultProductPrice);\nconst StockImpl = computed(() => props.stockComponent ?? DefaultItemStock);\nconst AddToCartImpl = computed(() => props.addToCartComponent ?? DefaultAddToCart);\nconst BundlesImpl = computed(() => props.bundlesComponent ?? DefaultProductBundles);\nconst BulkPricesImpl = computed(() => props.bulkPricesComponent ?? DefaultProductBulkPrices);\nconst SurchargesImpl = computed(() => props.surchargesComponent ?? DefaultProductSurcharges);\n\n// Task 35: cascade injection slots to nested components via grid-config context.\n// PDP isn't a grid; `columns: 1` is the conventional placeholder. The cascade\n// carries only `undefined` values when no slot props are passed, so it is safe\n// to call unconditionally even when the legacy path renders.\nconst pdpConfig = computed<ProductGridConfig>(() => ({\n columns: 1,\n priceComponent: props.priceComponent,\n stockComponent: props.stockComponent,\n addToCartComponent: props.addToCartComponent,\n imageComponent: props.imageComponent,\n badgesComponent: props.badgesComponent,\n favoriteComponent: props.favoriteComponent,\n}));\nprovideProductGridConfig(pdpConfig.value);\n</script>\n","<template>\n <component\n :is=\"'script'\"\n v-if=\"payload\"\n type=\"application/ld+json\"\n v-html=\"payload\"\n />\n</template>\n\n<script setup lang=\"ts\">\n/**\n * Pure SSR-safe component. Emits a single `<script type=\"application/ld+json\">`\n * with the schema.org Product payload built from the SDK `Product`.\n *\n * Renders nothing when the input has no usable name AND no URL. Offers are\n * gated by portal mode (semi-closed + anonymous → no `offers` block).\n *\n * The component uses `<component :is=\"'script'\">` rather than a literal\n * `<script>` element in the template because Vue's template compiler treats\n * a literal `<script>` as the SFC's own script block. The dynamic-component\n * wrapper sidesteps that parsing rule and emits a real `<script>` element in\n * the rendered DOM (and in the SSR output).\n *\n * No `@unhead/vue` dep — keeps the package framework-head-agnostic.\n * Crawlers accept JSON-LD anywhere in the HTML, not just `<head>`.\n */\nimport { computed } from 'vue';\nimport type { Product } from '@propeller-commerce/propeller-sdk-v2';\nimport {\n buildProductJsonLd,\n safeJsonStringify,\n type JsonLdContext,\n} from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface ProductJsonLdProps {\n /** The product to describe. */\n product: Product;\n /** Per-request context: siteUrl, language, currency, portalMode, user, URL builders. */\n context: JsonLdContext;\n}\n\nconst props = defineProps<ProductJsonLdProps>();\n\nconst payload = computed<string | null>(() => {\n const data = buildProductJsonLd(props.product, props.context);\n return data ? safeJsonStringify(data) : null;\n});\n</script>\n","<template>\n <template v-if=\"!(isCrossUpsellMode() && !isLoading && items().length === 0)\">\n <div\n :class=\"`propeller-product-slider ${containerClassName || 'mb-12'}`\"\n :data-loading=\"isLoading ? 'true' : 'false'\"\n >\n <template v-if=\"sliderTitle() || items().length > 0\">\n <div\n class=\"propeller-product-slider__header flex items-center justify-between mb-6\"\n >\n <template v-if=\"sliderTitle()\">\n <h2 class=\"propeller-product-slider__title text-2xl font-bold\">\n {{ sliderTitle() }}\n </h2>\n </template>\n\n <template v-if=\"items().length > desktopCount()\">\n <div class=\"propeller-product-slider__nav flex gap-2\">\n <button\n class=\"propeller-product-slider__nav-btn propeller-product-slider__nav-btn--prev p-2 rounded-full bg-card shadow hover:bg-surface-hover transition disabled:opacity-30 disabled:cursor-not-allowed\"\n @click=\"\n () => {\n if (sliderRef) sliderScrollLeft(sliderRef as HTMLElement);\n }\n \"\n :disabled=\"!canScrollLeft\"\n :aria-label=\"getLabel('scrollLeft', 'Scroll left')\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"w-5 h-5\"\n >\n <path d=\"M15 19l-7-7 7-7\"></path>\n </svg></button\n ><button\n class=\"propeller-product-slider__nav-btn propeller-product-slider__nav-btn--next p-2 rounded-full bg-card shadow hover:bg-surface-hover transition disabled:opacity-30 disabled:cursor-not-allowed\"\n @click=\"\n () => {\n if (sliderRef) sliderScrollRight(sliderRef as HTMLElement);\n }\n \"\n :disabled=\"!canScrollRight\"\n :aria-label=\"getLabel('scrollRight', 'Scroll right')\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n class=\"w-5 h-5\"\n >\n <path d=\"M9 5l7 7-7 7\"></path>\n </svg>\n </button>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"isLoading\">\n <div\n class=\"propeller-product-slider__skeleton flex gap-6 overflow-hidden\"\n >\n <div\n class=\"propeller-product-slider__skeleton-card flex-shrink-0 w-72 h-80 bg-surface-hover rounded-[var(--radius-container)] animate-pulse\"\n ></div>\n <div\n class=\"propeller-product-slider__skeleton-card flex-shrink-0 w-72 h-80 bg-surface-hover rounded-[var(--radius-container)] animate-pulse\"\n ></div>\n <div\n class=\"propeller-product-slider__skeleton-card flex-shrink-0 w-72 h-80 bg-surface-hover rounded-[var(--radius-container)] animate-pulse\"\n ></div>\n <div\n class=\"propeller-product-slider__skeleton-card flex-shrink-0 w-72 h-80 bg-surface-hover rounded-[var(--radius-container)] animate-pulse\"\n ></div>\n </div>\n </template>\n\n <template v-if=\"!isLoading && items().length > 0\">\n <div\n ref=\"sliderRef\"\n class=\"propeller-product-slider__track flex gap-6 overflow-x-auto scroll-smooth pb-4\"\n @scroll=\"(e) => sliderOnScroll(e.target as HTMLElement)\"\n :style=\"{\n scrollbarWidth: 'none',\n msOverflowStyle: 'none',\n }\"\n >\n <template\n :key=\"getItemId(item) + '-' + index\"\n v-for=\"(item, index) in items()\"\n >\n <div\n class=\"propeller-product-slider__slide flex-shrink-0 w-[calc((100%_-_1.5rem)_/_1.5)] md:w-[calc((100%_-_3rem)_/_2.5)] lg:w-[calc((100%_-_4.5rem)_/_4)]\"\n >\n <slot name=\"beforeItem\" :item=\"item\" :index=\"index\" />\n <template v-if=\"isCluster(item)\">\n <component\n :is=\"ClusterCardImpl\"\n :cluster=\"item as Cluster\"\n :configuration=\"configuration\"\n :includeTax=\"includeTax\"\n :language=\"language\"\n :columns=\"3\"\n :enableAddFavorite=\"enableAddFavorite\"\n :showStock=\"showStock\"\n :showAvailability=\"showAvailability\"\n :labels=\"props.clusterCardLabels\"\n :stockLabels=\"stockLabels\"\n :onToggleFavorite=\"\n (cluster: Cluster, isFav: boolean) => {\n if (onToggleFavorite) {\n onToggleFavorite(cluster, isFav);\n }\n }\n \"\n :onClusterClick=\"(cluster: Cluster) => handleClusterClick(cluster)\"\n />\n </template>\n\n <template v-if=\"!isCluster(item)\">\n <component\n :is=\"ProductCardImpl\"\n :product=\"item as Product\"\n :graphqlClient=\"graphqlClient\"\n :user=\"user || null\"\n :companyId=\"companyId\"\n :cartId=\"cartId\"\n :configuration=\"configuration\"\n :includeTax=\"includeTax\"\n :columns=\"3\"\n :allowAddToCart=\"portalMode() === 'open'\"\n :createCart=\"createCart\"\n :onCartCreated=\"onCartCreated\"\n :afterAddToCart=\"afterAddToCart\"\n :showModal=\"showModal\"\n :allowIncrDecr=\"showIncrDecr !== false\"\n :enableStockValidation=\"stockValidation\"\n :language=\"language\"\n :onProceedToCheckout=\"onProceedToCheckout\"\n :onRequestQuoteClick=\"onRequestQuoteClick\"\n :labels=\"props.productCardLabels\"\n :addToCartLabels=\"addToCartLabels\"\n :enableAddFavorite=\"enableAddFavorite\"\n :showStock=\"showStock\"\n :showAvailability=\"showAvailability\"\n :stockLabels=\"stockLabels\"\n :priceLabels=\"props.priceLabels\"\n :onToggleFavorite=\"\n (product: Product, isFav: boolean) => {\n if (onToggleFavorite) onToggleFavorite(product, isFav);\n }\n \"\n :onProductClick=\"(product: Product) => handleProductClick(product)\"\n />\n </template>\n <slot name=\"afterItem\" :item=\"item\" :index=\"index\" />\n </div>\n </template>\n </div>\n </template>\n\n <template\n v-if=\"\n !isLoading &&\n items().length === 0 &&\n !products &&\n !isCrossUpsellMode()\n \"\n >\n <div\n class=\"propeller-product-slider__empty text-center text-muted-foreground py-8\"\n >\n {{ getLabel(\"noProducts\", \"No products found\") }}\n </div>\n </template>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, watch, type Component } from \"vue\";\n\nimport { Cart, CartMainItem, Cluster, Contact, CrossupsellType, Customer, GraphQLClient, Product } from \"@propeller-commerce/propeller-sdk-v2\";\nimport DefaultProductCard from \"./ProductCard.vue\";\nimport DefaultClusterCard from \"./ClusterCard.vue\";\nimport { useProductSlider } from \"../composables/vue/useProductSlider\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\nimport {\n provideProductGridConfig,\n type ProductGridConfig,\n} from \"../context/ProductGridContext\";\n\nexport interface ProductSliderProps {\n // === Data source ===\n\n /**\n * Propeller SDK GraphQL client.\n * Optional — resolved from the `propellerVue` plugin scope via `useInfraProps`\n * when omitted. An explicit prop still wins.\n */\n graphqlClient?: GraphQLClient;\n\n /** Pre-loaded products or clusters to display. When provided, skips internal fetching. */\n products?: (Product | Cluster)[];\n\n /** Product IDs to fetch internally when `products` is not provided */\n productIds?: number[];\n\n /** Cluster IDs to fetch internally when `products` is not provided */\n clusterIds?: number[];\n\n /**\n * Cross-upsell types to fetch. When provided, fetches cross-upsells for the given\n * productId/clusterId instead of fetching products by IDs.\n * Values: 'ACCESSORIES' | 'ALTERNATIVES' | 'RELATED' | 'OPTIONS' | 'PARTS'\n */\n crossUpsellTypes?: CrossupsellType[];\n\n /** Source product ID for cross-upsell lookup. Required when crossUpsellTypes is set. */\n productId?: number;\n\n /** Source cluster ID for cross-upsell lookup. Required when crossUpsellTypes is set. */\n clusterId?: number;\n\n // === Locale / pricing ===\n\n /**\n * Language code for API requests and localized content.\n * Optional — resolved from `<PropellerProvider>` scope via `useInfraProps`\n * when omitted. An explicit prop still wins.\n */\n language?: string;\n\n /** Tax zone for price calculations */\n taxZone?: string;\n\n /**\n * When true, net price (incl. tax) is the leading price.\n * Forwarded to each ProductCard / ClusterCard.\n */\n includeTax?: boolean;\n\n // === Portal / visibility ===\n\n /**\n * Controls portal visibility mode.\n * 'open' — AddToCart is shown on product cards.\n * 'semi-closed' — AddToCart is hidden (catalog-only view).\n * Defaults to 'open'.\n */\n portalMode?: string;\n\n /** Authenticated user for cart operations */\n user?: Contact | Customer | null;\n\n /**\n * Active company ID from the company switcher.\n * Overrides the user's default company for price calculation in cross-upsell fetches\n * and is forwarded to each embedded ProductCard / AddToCart.\n * Triggers a re-fetch when changed.\n */\n companyId?: number;\n\n /* === Layout === */\n\n /** Items visible per breakpoint */\n itemsPerView?: {\n mobile?: number;\n tablet?: number;\n desktop?: number;\n };\n\n /** Slider title displayed above the track */\n title?: string;\n\n /** Additional CSS class for the outer container */\n containerClassName?: string;\n\n /* === Card stock display === */\n\n /**\n * Show the stock / availability widget on each product card.\n * Forwarded to `ProductCard.showStock`.\n * Defaults to false.\n */\n showStock?: boolean;\n\n /**\n * Show only the availability indicator (Available / Not available) inside the stock widget.\n * Forwarded to `ProductCard.showAvailability`.\n * Defaults to true.\n */\n showAvailability?: boolean;\n\n /**\n * Label overrides forwarded to the embedded ItemStock component inside each card.\n * Keys: inStock, outOfStock, lowStock, available, notAvailable, pieces\n */\n stockLabels?: Record<string, string>;\n\n /** Translated labels forwarded to the embedded `<ProductPrice>` display\n * inside each `<ProductCard>`. See `ProductPriceProps.labels` for slugs. */\n priceLabels?: Record<string, string>;\n\n /* === Card favourites === */\n\n /** Show a heart-icon favourite toggle on each card. Defaults to false. */\n enableAddFavorite?: boolean;\n\n /**\n * Called when a favourite is toggled on any card.\n * Receives the full Product or Cluster object and the new favourite state.\n */\n onToggleFavorite?: (item: Product | Cluster, isFavorite: boolean) => void;\n\n /* === Card navigation === */\n\n /** Called when a product card is clicked — use for SPA-style routing. */\n onProductClick?: (product: Product) => void;\n\n /** Called when a cluster card is clicked — use for SPA-style routing. */\n onClusterClick?: (cluster: Cluster) => void;\n\n /* === AddToCart pass-through === */\n\n /** Validate stock before adding to cart. Defaults to false. */\n stockValidation?: boolean;\n\n /** Show increment/decrement stepper buttons in AddToCart. Defaults to true. */\n showIncrDecr?: boolean;\n\n /** ID of an existing cart to add items to. */\n cartId?: string;\n\n /** Auto-create a cart when none is available. Pair with onCartCreated. */\n createCart?: boolean;\n\n /** Called after AddToCart creates a new cart internally. */\n onCartCreated?: (cart: Cart) => void;\n\n /** Called after every successful add-to-cart. Receives the updated cart and the added item. */\n afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n\n /**\n * When true, AddToCart shows a success modal instead of a toast.\n * Defaults to false.\n */\n showModal?: boolean;\n\n /** Called when \"Proceed to checkout\" is clicked in the AddToCart modal. */\n onProceedToCheckout?: () => void;\n\n /** Called when \"Request a Quote\" is clicked in the AddToCart modal. */\n onRequestQuoteClick?: (cart: Cart) => void;\n\n /**\n * Label overrides forwarded to the embedded AddToCart component.\n * Keys: add, adding, addedToCart, outOfStock, noCartId, errorAdding,\n * modalTitle, quantity, continueShopping, proceedToCheckout\n */\n addToCartLabels?: Record<string, string>;\n\n /* === Misc === */\n\n /** Configuration object providing imageSearchFiltersGrid, imageVariantFiltersMedium, urls */\n configuration?: any;\n\n /**\n * Label overrides for the slider UI.\n * Available keys: scrollLeft, scrollRight, noProducts, viewCluster,\n * ACCESSORIES, ALTERNATIVES, RELATED, OPTIONS, PARTS\n */\n labels?: Record<string, string>;\n\n /** Translated labels forwarded to embedded `<ProductCard>` instances. */\n productCardLabels?: Record<string, string>;\n\n /** Translated labels forwarded to embedded `<ClusterCard>` instances. */\n clusterCardLabels?: Record<string, string>;\n\n // ───── Extension API ─────\n // Sub-component injection — cascades through ProductGridConfig context.\n priceComponent?: Component;\n stockComponent?: Component;\n addToCartComponent?: Component;\n imageComponent?: Component;\n badgesComponent?: Component;\n favoriteComponent?: Component;\n\n // Iteration-level: replace the whole ProductCard / ClusterCard.\n productCardComponent?: Component;\n clusterCardComponent?: Component;\n}\n\nconst props = withDefaults(defineProps<ProductSliderProps>(), {\n showAvailability: true,\n showIncrDecr: true,\n showStock: false,\n enableAddFavorite: false,\n});\n\n// Resolve infrastructure props (graphqlClient, configuration, user, companyId,\n// language, includeTax, portalMode) from the propellerVue plugin scope +\n// <PropellerProvider> when the host doesn't pass them explicitly. Without this\n// a consumer relying on the provider (e.g. propeller-vue's PDP / cluster\n// pages, which omit :graphqlClient) leaves useProductSlider with no client, so\n// the crossupsell fetch throws, is swallowed, and the slider renders nothing —\n// no cross/upsells appear. Explicit props still win via useInfraProps\n// precedence. Mirrors the pattern already used by Menu.vue / ProductGrid.vue.\nconst infra = useInfraProps(props);\n\n// ───── Extension API ─────\n// Iteration-level component override: swap the whole card or fall back to\n// the built-in implementation.\nconst ProductCardImpl = computed(\n () => props.productCardComponent ?? DefaultProductCard,\n);\nconst ClusterCardImpl = computed(\n () => props.clusterCardComponent ?? DefaultClusterCard,\n);\n\n// Build the ProductGridConfig that cascades to nested cards inside the slider.\n// Mirrors ProductGrid.vue (Task 31). Slider doesn't have a real grid; use the\n// existing default of 3 columns so cards size sensibly.\nconst gridConfig = computed<ProductGridConfig>(() => ({\n columns: 3,\n showStock: props.showStock,\n showAvailability: props.showAvailability,\n enableAddFavorite: props.enableAddFavorite,\n createCart: props.createCart,\n showModal: props.showModal,\n allowIncrDecr: props.showIncrDecr !== false,\n enableStockValidation: props.stockValidation,\n cartId: props.cartId,\n stockLabels: props.stockLabels,\n priceLabels: props.priceLabels,\n addToCartLabels: props.addToCartLabels,\n onCartCreated: props.onCartCreated,\n afterAddToCart: props.afterAddToCart,\n onProceedToCheckout: props.onProceedToCheckout,\n onRequestQuoteClick: props.onRequestQuoteClick,\n onToggleFavorite: props.onToggleFavorite,\n onProductClick: props.onProductClick,\n onClusterClick: props.onClusterClick,\n // Extension API slot cascade\n productCardComponent: props.productCardComponent,\n clusterCardComponent: props.clusterCardComponent,\n priceComponent: props.priceComponent,\n stockComponent: props.stockComponent,\n addToCartComponent: props.addToCartComponent,\n imageComponent: props.imageComponent,\n badgesComponent: props.badgesComponent,\n favoriteComponent: props.favoriteComponent,\n}));\n\n// Snapshot pattern (same as ProductGrid.vue Task 31): cascade is push-based.\n// Documented caveat: nested cards see the config at mount time; future\n// reactivity needs would require provideProductGridConfig to accept MaybeRef.\nprovideProductGridConfig(gridConfig.value);\n\n// Template-facing resolved bindings. The template reads bare identifiers\n// (graphqlClient, user, companyId, configuration, includeTax, language) which\n// in <script setup> bind to these — so nested cards and the fetch composable\n// all see the context-resolved values, not raw (possibly undefined) props.\nconst graphqlClient = computed(() => infra.graphqlClient);\nconst user = computed(() => infra.user ?? null);\nconst companyId = computed(() => infra.companyId);\nconst configuration = computed(() => infra.configuration);\nconst includeTax = computed(() => infra.includeTax);\nconst language = computed(() => infra.language || \"NL\");\n\nconst langRef = language;\nconst userRef = user;\nconst companyRef = companyId;\nconst sliderRef = ref<HTMLElement | null>(null);\n\nconst {\n products: fetchedItems,\n loading: isLoading,\n canScrollLeft,\n canScrollRight,\n fetchCrossupsells,\n fetchProducts,\n scrollLeft: sliderScrollLeft,\n scrollRight: sliderScrollRight,\n onScroll: sliderOnScroll,\n} = useProductSlider({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n language: langRef,\n user: userRef,\n companyId: companyRef,\n configuration: infra.configuration as any,\n});\n\nonMounted(() => {\n if (props.products && props.products.length > 0) return;\n if (isCrossUpsellMode()) {\n fetchCrossupsells({\n productId: props.productId,\n clusterId: props.clusterId,\n types: props.crossUpsellTypes,\n });\n } else {\n fetchProducts(props.productIds || [], props.clusterIds || []);\n }\n});\n\nwatch(\n () =>\n JSON.stringify([\n props.productIds,\n props.clusterIds,\n props.crossUpsellTypes,\n props.productId,\n props.clusterId,\n language.value,\n companyId.value,\n ]),\n () => {\n if (props.products && props.products.length > 0) return;\n if (isCrossUpsellMode()) {\n fetchCrossupsells({\n productId: props.productId,\n clusterId: props.clusterId,\n types: props.crossUpsellTypes,\n });\n } else {\n fetchProducts(props.productIds || [], props.clusterIds || []);\n }\n },\n);\n\nwatch(isLoading, async (loading) => {\n if (!loading) {\n await nextTick();\n if (sliderRef.value) sliderOnScroll(sliderRef.value);\n }\n});\n\nfunction items(): (Product | Cluster)[] {\n if (props.products && props.products.length > 0) {\n return props.products;\n }\n return fetchedItems.value;\n}\nfunction isCrossUpsellMode(): boolean {\n return !!(props.crossUpsellTypes && props.crossUpsellTypes.length > 0);\n}\nfunction crossUpsellTitle(): string {\n if (!props.crossUpsellTypes || props.crossUpsellTypes.length === 0) return \"\";\n const typeLabels: Record<string, string> = {\n ACCESSORIES: \"Accessories\",\n ALTERNATIVES: \"Alternatives\",\n RELATED: \"Related products\",\n OPTIONS: \"Options\",\n PARTS: \"Parts\",\n };\n return props.crossUpsellTypes\n .map((t: string) => props.labels?.[t.toLowerCase()] || typeLabels[t] || t)\n .join(\" & \");\n}\nfunction sliderTitle(): string | undefined {\n if (props.title !== undefined) return props.title;\n if (isCrossUpsellMode()) return crossUpsellTitle();\n return undefined;\n}\nfunction desktopCount(): number {\n return props.itemsPerView?.desktop || 4;\n}\nfunction portalMode(): string {\n return (infra.portalMode as string) || \"open\";\n}\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction isCluster(item: any): boolean {\n return \"clusterId\" in item && !(\"productId\" in item);\n}\nfunction getItemId(item: any): number {\n return isCluster(item) ? item.clusterId : item.productId;\n}\nfunction handleProductClick(product: Product): void {\n if (props.onProductClick) {\n props.onProductClick(product);\n }\n}\nfunction handleClusterClick(cluster: Cluster): void {\n if (props.onClusterClick) {\n props.onClusterClick(cluster);\n }\n}\n</script>\n","<template>\n <template v-if=\"!loading && hasPublicAttributes()\">\n <div\n :class=\"`propeller-product-specifications ${className || ''}`\"\n :data-layout=\"layout === 'list' ? 'list' : 'table'\"\n :data-grouped=\"grouping ? 'true' : 'false'\"\n >\n <template v-if=\"!grouping\">\n <template v-if=\"layout !== 'list'\">\n <div\n class=\"overflow-hidden rounded-[var(--radius-container)] border border-border\"\n >\n <table class=\"w-full text-sm\">\n <tbody class=\"divide-y divide-border\">\n <template :key=\"i\" v-for=\"(attr, i) in getAttributes()\">\n <tr\n class=\"propeller-product-specifications__row odd:bg-card even:bg-surface-hover/20\"\n >\n <td class=\"px-4 py-2 font-medium text-foreground w-1/2\">\n {{ getAttributeLabel(attr) }}\n </td>\n <td class=\"px-4 py-2 text-muted-foreground\">\n {{ getAttributeValue(attr) }}\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </template>\n\n <template v-if=\"layout === 'list'\">\n <div class=\"space-y-3\">\n <template :key=\"i\" v-for=\"(attr, i) in getAttributes()\">\n <div class=\"flex flex-col gap-0.5\">\n <span\n class=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\"\n >{{ getAttributeLabel(attr) }}</span\n ><span class=\"text-sm text-foreground\">{{\n getAttributeValue(attr)\n }}</span>\n </div>\n </template>\n </div>\n </template>\n </template>\n\n <template v-if=\"!!grouping\">\n <template :key=\"group\" v-for=\"(group, index) in getGroups()\">\n <div class=\"mb-6\">\n <template v-if=\"!!group\">\n <h4\n class=\"text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2\"\n >\n {{ group }}\n </h4>\n </template>\n\n <template v-if=\"layout !== 'list'\">\n <div\n class=\"overflow-hidden rounded-[var(--radius-container)] border border-border\"\n >\n <table class=\"w-full text-sm\">\n <tbody class=\"divide-y divide-border\">\n <template\n :key=\"i\"\n v-for=\"(attr, i) in getAttributesByGroup(group)\"\n >\n <tr\n class=\"propeller-product-specifications__row odd:bg-card even:bg-surface-hover/20\"\n >\n <td class=\"px-4 py-2 font-medium text-foreground w-1/2\">\n {{ getAttributeLabel(attr) }}\n </td>\n <td class=\"px-4 py-2 text-muted-foreground\">\n {{ getAttributeValue(attr) }}\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </template>\n\n <template v-if=\"layout === 'list'\">\n <div class=\"space-y-3\">\n <template\n :key=\"i\"\n v-for=\"(attr, i) in getAttributesByGroup(group)\"\n >\n <div class=\"flex flex-col gap-0.5\">\n <span\n class=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\"\n >{{ getAttributeLabel(attr) }}</span\n ><span class=\"text-sm text-foreground\">{{\n getAttributeValue(attr)\n }}</span>\n </div>\n </template>\n </div>\n </template>\n </div>\n </template>\n </template>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, watch } from \"vue\";\n\nimport { AttributeResult, AttributeType, GraphQLClient, LocalizedString } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useProductSpecs } from \"../composables/vue/useProductSpecs\";\nimport {\n getLanguageString,\n getLanguageUri,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface ProductSpecificationsProps {\n /**\n * Initialised Propeller SDK GraphQL client.\n * Required when `productId` is set — used to fetch public attributes.\n */\n graphqlClient?: GraphQLClient;\n\n /**\n * Product ID to fetch attributes for.\n */\n productId?: number;\n\n /**\n * Pre-fetched attribute result items used as fallback when `productId` is not provided.\n * When `productId` is provided the component fetches its own data and this prop is ignored.\n */\n attributes?: AttributeResult[];\n\n /**\n * Language code used to resolve localised attribute labels.\n * Defaults to 'NL'.\n */\n language?: string;\n\n /**\n * Display layout for the specifications.\n * 'table' — two-column table (name | value). Default.\n * 'list' — vertical label + value stacked rows.\n */\n layout?: string;\n\n /**\n * When true, groups attributes by their group field with a heading per section.\n * When false or omitted, displays a flat ungrouped table/list. Default: false.\n */\n grouping?: boolean;\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n}\n\nconst props = defineProps<ProductSpecificationsProps>();\nconst infra = useInfraProps(props);\n\nconst langRef = computed(() => infra.language || \"NL\");\n\nconst { attributes, loading, fetchSpecs } = useProductSpecs({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n language: langRef,\n});\n\nonMounted(() => {\n if (props.productId) fetchSpecs(props.productId);\n});\n\nwatch(\n () => props.productId,\n (id) => {\n if (id) fetchSpecs(id);\n },\n);\n\nfunction getAttributes(): AttributeResult[] {\n // Prefer fetched attributes; fall back to props.attributes\n const attrs = attributes.value.length\n ? attributes.value\n : (props.attributes as AttributeResult[]) || [];\n return attrs.filter(\n (a: AttributeResult) =>\n a.attributeDescription?.isPublic === true &&\n getAttributeValue(a) !== \"\" &&\n getAttributeValue(a) !== null &&\n getAttributeValue(a) !== \"0\",\n );\n}\nfunction getGroups(): string[] {\n const attrs = getAttributes();\n const seen: string[] = [];\n attrs.forEach((a: AttributeResult) => {\n const group = a.attributeDescription?.group || \"\";\n if (!seen.includes(group)) seen.push(group);\n });\n return seen;\n}\nfunction getAttributesByGroup(group: string): AttributeResult[] {\n return getAttributes().filter(\n (a: AttributeResult) => (a.attributeDescription?.group || \"\") === group,\n );\n}\nfunction getAttributeLabel(attr: AttributeResult): string {\n const descs = attr.attributeDescription?.descriptions || [];\n return getLanguageString(\n descs,\n infra.language || \"NL\",\n attr.attributeDescription?.name || \"\",\n );\n}\nfunction getAttributeValue(attr: AttributeResult): string {\n const v = attr.value;\n if (!v) return \"\";\n const lang = (infra.language as string) || \"NL\";\n if (v.type === AttributeType.TEXT) {\n const entry = (v as any).textValues?.find(\n (tv: any) => tv.language === lang,\n );\n const vals = (entry?.values || []).filter(Boolean);\n return vals.join(\", \");\n }\n if (v.type === AttributeType.ENUM) {\n const vals = ((v as any).enumValues || []).filter(Boolean);\n return vals.join(\", \");\n }\n if (v.type === AttributeType.INT) {\n const val = (v as any).intValue;\n return val !== null && val !== undefined ? String(val) : \"\";\n }\n if (v.type === AttributeType.DECIMAL) {\n const val = (v as any).decimalValue;\n return val !== null && val !== undefined ? String(val) : \"\";\n }\n if (v.type === AttributeType.DATETIME) {\n return (v as any).dateTimeValue || \"\";\n }\n if (v.type === AttributeType.COLOR) {\n return (v as any).colorValue || \"\";\n }\n const fallback = v.value;\n if (fallback === null || fallback === undefined) return \"\";\n if (typeof fallback === \"boolean\") return fallback ? \"Yes\" : \"No\";\n return String(fallback);\n}\nfunction hasPublicAttributes(): boolean {\n return getAttributes().length > 0;\n}\n</script>\n","<template>\n <template v-if=\"product\">\n <div\n :class=\"`propeller-product-tabs ${className || ''}`\"\n :data-active-tab=\"activeTab\"\n >\n <div class=\"propeller-product-tabs__desktop hidden md:block\">\n <div class=\"propeller-product-tabs__tablist flex border-b border-border\">\n <template v-if=\"isTabVisible('description')\">\n <button\n type=\"button\"\n @click=\"async (event) => selectTab('description')\"\n data-tab=\"description\"\n :data-active=\"isActive('description') ? 'true' : 'false'\"\n :class=\"`propeller-product-tabs__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 -mb-px ${\n isActive('description')\n ? 'border-foreground text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'\n }`\"\n >\n {{ getLabel('description', 'Description') }}\n </button>\n </template>\n\n <template v-if=\"isTabVisible('specifications')\">\n <button\n type=\"button\"\n @click=\"async (event) => selectTab('specifications')\"\n data-tab=\"specifications\"\n :data-active=\"isActive('specifications') ? 'true' : 'false'\"\n :class=\"`propeller-product-tabs__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 -mb-px ${\n isActive('specifications')\n ? 'border-foreground text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'\n }`\"\n >\n {{ getLabel('specifications', 'Specifications') }}\n </button>\n </template>\n\n <template v-if=\"isTabVisible('downloads')\">\n <button\n type=\"button\"\n @click=\"async (event) => selectTab('downloads')\"\n data-tab=\"downloads\"\n :data-active=\"isActive('downloads') ? 'true' : 'false'\"\n :class=\"`propeller-product-tabs__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 -mb-px ${\n isActive('downloads')\n ? 'border-foreground text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'\n }`\"\n >\n {{ getLabel('downloads', 'Downloads') }}\n </button>\n </template>\n\n <template v-if=\"isTabVisible('videos')\">\n <button\n type=\"button\"\n @click=\"async (event) => selectTab('videos')\"\n data-tab=\"videos\"\n :data-active=\"isActive('videos') ? 'true' : 'false'\"\n :class=\"`propeller-product-tabs__tab px-5 py-3 text-sm font-medium transition-colors border-b-2 -mb-px ${\n isActive('videos')\n ? 'border-foreground text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'\n }`\"\n >\n {{ getLabel('videos', 'Videos') }}\n </button>\n </template>\n </div>\n <div class=\"propeller-product-tabs__panel pt-6\">\n <template v-if=\"isActive('description') && isTabVisible('description')\">\n <component\n :is=\"ProductDescriptionImpl\"\n :product=\"product\"\n :language=\"language\"\n :collapsed=\"descriptionCollapsed\"\n :maxLength=\"descriptionMaxLength\"\n ></component>\n </template>\n\n <template v-if=\"specsVisited && isTabVisible('specifications')\">\n <div :class=\"isActive('specifications') ? '' : 'hidden'\">\n <component\n :is=\"ProductSpecificationsImpl\"\n :attributes=\"getSpecsAttributes()\"\n :language=\"language\"\n :layout=\"specificationsLayout\"\n :grouping=\"specificationsGrouping\"\n ></component>\n </div>\n </template>\n\n <template v-if=\"isActive('downloads') && isTabVisible('downloads')\">\n <component\n :is=\"ProductDownloadsImpl\"\n :downloads=\"product.media?.documents\"\n :language=\"language || 'NL'\"\n :labels=\"downloadsLabels\"\n ></component>\n </template>\n\n <template v-if=\"isActive('videos') && isTabVisible('videos')\">\n <component\n :is=\"ProductVideosImpl\"\n :videos=\"product.media?.videos\"\n :language=\"language || 'NL'\"\n :labels=\"videosLabels\"\n ></component>\n </template>\n </div>\n </div>\n <div class=\"propeller-product-tabs__mobile md:hidden divide-y divide-border border border-border rounded-[var(--radius-container)]\">\n <template v-if=\"isTabVisible('description')\">\n <div>\n <button\n type=\"button\"\n class=\"propeller-product-tabs__accordion-trigger flex items-center justify-between w-full px-4 py-3 text-sm font-medium text-left\"\n @click=\"\n async (event) => {\n activeTab = activeTab === 'description' ? '' : 'description';\n }\n \"\n >\n {{ getLabel('description', 'Description')\n }}<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n :class=\"`transition-transform ${isActive('description') ? 'rotate-180' : ''}`\"\n >\n <path d=\"m6 9 6 6 6-6\"></path>\n </svg>\n </button>\n <template v-if=\"isActive('description')\">\n <div class=\"propeller-product-tabs__accordion-panel px-4 pb-4\">\n <component\n :is=\"ProductDescriptionImpl\"\n :product=\"product\"\n :language=\"language\"\n :collapsed=\"descriptionCollapsed\"\n :maxLength=\"descriptionMaxLength\"\n ></component>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"isTabVisible('specifications')\">\n <div>\n <button\n type=\"button\"\n class=\"propeller-product-tabs__accordion-trigger flex items-center justify-between w-full px-4 py-3 text-sm font-medium text-left\"\n @click=\"\n () => {\n if (activeTab !== 'specifications') {\n onSpecificationsTabSelected();\n activeTab = 'specifications';\n } else {\n activeTab = '';\n }\n }\n \"\n >\n {{ getLabel('specifications', 'Specifications')\n }}<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n :class=\"`transition-transform ${isActive('specifications') ? 'rotate-180' : ''}`\"\n >\n <path d=\"m6 9 6 6 6-6\"></path>\n </svg>\n </button>\n <template v-if=\"specsVisited && isActive('specifications')\">\n <div class=\"propeller-product-tabs__accordion-panel px-4 pb-4\">\n <component\n :is=\"ProductSpecificationsImpl\"\n :attributes=\"getSpecsAttributes()\"\n :language=\"language\"\n :layout=\"specificationsLayout\"\n :grouping=\"specificationsGrouping\"\n ></component>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"isTabVisible('downloads')\">\n <div>\n <button\n type=\"button\"\n class=\"propeller-product-tabs__accordion-trigger flex items-center justify-between w-full px-4 py-3 text-sm font-medium text-left\"\n @click=\"\n async (event) => {\n activeTab = activeTab === 'downloads' ? '' : 'downloads';\n }\n \"\n >\n {{ getLabel('downloads', 'Downloads')\n }}<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n :class=\"`transition-transform ${isActive('downloads') ? 'rotate-180' : ''}`\"\n >\n <path d=\"m6 9 6 6 6-6\"></path>\n </svg>\n </button>\n <template v-if=\"isActive('downloads')\">\n <div class=\"propeller-product-tabs__accordion-panel px-4 pb-4\">\n <component\n :is=\"ProductDownloadsImpl\"\n :downloads=\"product.media?.documents\"\n :language=\"language || 'NL'\"\n :labels=\"downloadsLabels\"\n ></component>\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"isTabVisible('videos')\">\n <div>\n <button\n type=\"button\"\n class=\"propeller-product-tabs__accordion-trigger flex items-center justify-between w-full px-4 py-3 text-sm font-medium text-left\"\n @click=\"\n async (event) => {\n activeTab = activeTab === 'videos' ? '' : 'videos';\n }\n \"\n >\n {{ getLabel('videos', 'Videos')\n }}<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n :class=\"`transition-transform ${isActive('videos') ? 'rotate-180' : ''}`\"\n >\n <path d=\"m6 9 6 6 6-6\"></path>\n </svg>\n </button>\n <template v-if=\"isActive('videos')\">\n <div class=\"propeller-product-tabs__accordion-panel px-4 pb-4\">\n <component\n :is=\"ProductVideosImpl\"\n :videos=\"product.media?.videos\"\n :language=\"language || 'NL'\"\n :labels=\"videosLabels\"\n ></component>\n </div>\n </template>\n </div>\n </template>\n </div>\n </div>\n </template>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch, type Component } from 'vue';\n\nimport {\n Product,\n GraphQLClient,\n PaginatedMediaDocumentResponse,\n PaginatedMediaVideoResponse,\n AttributeResult,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport DefaultProductDescription from './ProductDescription.vue';\nimport DefaultProductSpecifications from './ProductSpecifications.vue';\nimport DefaultProductDownloads from './ProductDownloads.vue';\nimport DefaultProductVideos from './ProductVideos.vue';\nimport { useProductSpecs } from '../composables/vue/useProductSpecs';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface ProductTabsProps {\n /** Product for which to display the information. */\n product: Product;\n\n // ── Tab visibility ────────────────────────────────────────────────────────\n\n /** If true, displays the Description tab. Defaults to true. */\n showDescription?: boolean;\n\n /** If true, displays the Specifications tab. Defaults to true. */\n showSpecifications?: boolean;\n\n /** If true, displays the Downloads tab. Defaults to true. */\n showDownloads?: boolean;\n\n /** If true, displays the Videos tab. Defaults to true. */\n showVideos?: boolean;\n\n // ── Shared ────────────────────────────────────────────────────────────────\n\n /**\n * Language code passed to all sub-components.\n * Defaults to 'NL'.\n */\n language?: string;\n\n /**\n * Override the tab button labels.\n * Available keys: description, specifications, downloads, videos\n */\n labels?: Record<string, string>;\n\n // ── Description tab ───────────────────────────────────────────────────────\n\n /**\n * When true, the description is initially collapsed to `descriptionMaxLength` characters.\n * A \"Read more\" / \"Read less\" toggle is shown.\n * Passed as `collapsed` to ProductDescription. Defaults to false.\n */\n descriptionCollapsed?: boolean;\n\n /**\n * Maximum number of characters shown when the description is collapsed.\n * Passed as `maxLength` to ProductDescription. Defaults to 0 (no truncation).\n */\n descriptionMaxLength?: number;\n\n // ── Specifications tab ────────────────────────────────────────────────────\n\n /**\n * Initialised Propeller SDK GraphQL client.\n * Passed to ProductSpecifications for internal attribute fetching.\n */\n graphqlClient?: GraphQLClient;\n\n /**\n * Product ID to fetch attributes for.\n * Passed to ProductSpecifications for internal attribute fetching.\n */\n productId?: number;\n\n /**\n * Display layout for the specifications.\n * 'table' — two-column table (name | value). Default.\n * 'list' — vertical label + value stacked rows.\n * Passed as `layout` to ProductSpecifications.\n */\n specificationsLayout?: string;\n\n /**\n * When true, groups specifications by their group field with a heading per section.\n * When false or omitted, displays a flat ungrouped table. Default: false.\n * Passed as `grouping` to ProductSpecifications.\n */\n specificationsGrouping?: boolean;\n\n // ── Downloads tab ─────────────────────────────────────────────────────────\n\n /**\n * Override UI strings for the Downloads section.\n * Available keys: title, download\n * Passed as `labels` to ProductDownloads.\n */\n downloadsLabels?: Record<string, string>;\n\n // ── Videos tab ───────────────────────────────────────────────────────────\n\n /**\n * Override UI strings for the Videos section.\n * Available key: title\n * Passed as `labels` to ProductVideos.\n */\n videosLabels?: Record<string, string>;\n\n // ── Root ─────────────────────────────────────────────────────────────────\n\n /** Extra CSS class applied to the root element. */\n className?: string;\n\n // ───── Extension API ─────\n productDescriptionComponent?: Component;\n productSpecificationsComponent?: Component;\n productDownloadsComponent?: Component;\n productVideosComponent?: Component;\n}\ninterface ProductTabsState {\n activeTab: string;\n specsVisited: boolean;\n fetchedAttributes: AttributeResult[];\n hasDescription: boolean;\n isTabVisible: (tab: string) => boolean;\n isActive: (tab: string) => boolean;\n selectTab: (tab: string) => void;\n getLabel: (key: string, fallback: string) => string;\n getSpecsAttributes: () => AttributeResult[];\n}\n\nconst props = withDefaults(defineProps<ProductTabsProps>(), {\n showDescription: true,\n showSpecifications: true,\n showDownloads: true,\n showVideos: true,\n});\nconst ProductDescriptionImpl = computed(() => props.productDescriptionComponent ?? DefaultProductDescription);\nconst ProductSpecificationsImpl = computed(() => props.productSpecificationsComponent ?? DefaultProductSpecifications);\nconst ProductDownloadsImpl = computed(() => props.productDownloadsComponent ?? DefaultProductDownloads);\nconst ProductVideosImpl = computed(() => props.productVideosComponent ?? DefaultProductVideos);\nconst activeTab = ref<ProductTabsState['activeTab']>('description');\nconst specsVisited = ref<ProductTabsState['specsVisited']>(false);\n\nconst { attributes: fetchedAttributes, fetchSpecs } = useProductSpecs({\n graphqlClient: props.graphqlClient as GraphQLClient,\n language: computed(() => props.language || 'NL'),\n});\n\nconst hasDescription = computed(() => {\n return !!getLanguageString(props.product?.descriptions, props.language || 'NL', '');\n});\n\nonMounted(() => {\n // Set the first visible tab as active\n if (props.showDescription !== false && hasDescription.value) {\n activeTab.value = 'description';\n } else if (props.showSpecifications !== false) {\n activeTab.value = 'specifications';\n specsVisited.value = true;\n } else if (props.showDownloads !== false) {\n activeTab.value = 'downloads';\n } else {\n activeTab.value = 'videos';\n }\n});\n\nwatch(\n () => [props.product, props.language],\n () => {\n // Re-evaluate first visible tab when product data or language changes.\n // If the description is missing in the new language, fall back to specs.\n if (props.showDescription !== false && hasDescription.value) {\n activeTab.value = 'description';\n } else if (props.showSpecifications !== false) {\n activeTab.value = 'specifications';\n specsVisited.value = true;\n // Auto-selecting the specs tab on mount must also kick off the fetch —\n // without this, the user sees only the small attribute subset bundled\n // with the product (no full public-attribute table).\n if (props.productId && !fetchedAttributes.value.length) {\n fetchSpecs(props.productId);\n }\n }\n },\n { immediate: true }\n);\nfunction getSpecsAttributes(): ReturnType<ProductTabsState['getSpecsAttributes']> {\n return fetchedAttributes.value.length\n ? fetchedAttributes.value\n : (props.product?.attributes?.items as AttributeResult[]) || [];\n}\nfunction onSpecificationsTabSelected(): void {\n specsVisited.value = true;\n if (props.productId && !fetchedAttributes.value.length) {\n fetchSpecs(props.productId);\n }\n}\nfunction isTabVisible(tab: string): ReturnType<ProductTabsState['isTabVisible']> {\n if (tab === 'description') return props.showDescription !== false && hasDescription.value;\n if (tab === 'specifications') return props.showSpecifications !== false;\n if (tab === 'downloads') return props.showDownloads !== false;\n if (tab === 'videos') return props.showVideos !== false;\n return false;\n}\nfunction isActive(tab: string): ReturnType<ProductTabsState['isActive']> {\n return activeTab.value === tab;\n}\nfunction selectTab(tab: string): ReturnType<ProductTabsState['selectTab']> {\n if (tab === 'specifications') {\n onSpecificationsTabSelected();\n }\n activeTab.value = tab;\n}\nfunction getLabel(key: string, fallback: string): ReturnType<ProductTabsState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\n</script>\n","<template>\n <div\n :class=\"`propeller-purchase-authorization-configurator ${className || ''}`\"\n >\n <template v-if=\"isAuthManager\">\n <div class=\"space-y-4\">\n <div class=\"flex items-center justify-between\">\n <h2 class=\"text-xl font-semibold\">\n {{ getLabel(\"title\", \"Purchase Authorization Settings\") }}\n </h2>\n <template v-if=\"allowContactCreate !== false\">\n <button\n type=\"button\"\n class=\"propeller-purchase-authorization-configurator__add-btn flex items-center gap-2 bg-primary text-primary-foreground px-4 py-2 rounded-[var(--radius-container)] hover:bg-primary/80 transition text-sm font-medium\"\n @click=\"async (event) => openAddContactModal()\"\n >\n {{ getLabel(\"addContact\", \"Add contact\") }}\n </button>\n </template>\n </div>\n <template v-if=\"loading\">\n <div class=\"flex items-center justify-center py-12\">\n <div\n class=\"w-8 h-8 border-4 border-primary border-t-transparent rounded-full animate-spin\"\n ></div>\n </div>\n </template>\n\n <template v-if=\"!loading\">\n <div\n class=\"overflow-x-auto rounded-[var(--radius-container)] border border-border bg-card shadow-sm\"\n >\n <table class=\"w-full text-sm\">\n <thead class=\"bg-surface-hover/50 border-b border-border\">\n <tr>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colId\", \"ID\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colName\", \"Name\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colRole\", \"Role\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colLimit\", \"Limit\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colActions\", \"Actions\") }}\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-border\">\n <template\n :key=\"contact.contactId\"\n v-for=\"(contact, index) in getContacts()\"\n >\n <tr class=\"hover:bg-surface-hover/30 transition-colors\">\n <td class=\"px-4 py-3 text-muted-foreground\">\n {{ contact.contactId }}\n </td>\n <td class=\"px-4 py-3\">\n <div class=\"font-medium\">\n {{\n [\n contact.firstName,\n contact.middleName,\n contact.lastName,\n ]\n .filter(Boolean)\n .join(\" \")\n }}\n </div>\n <div class=\"text-xs text-muted-foreground mt-0.5\">\n {{ contact.email }}\n </div>\n </td>\n <td class=\"px-4 py-3\">\n <select\n class=\"border border-input rounded-[var(--radius-control)] px-2 py-1.5 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed\"\n :value=\"getRowRole(contact.contactId)\"\n :disabled=\"isCurrentUser(contact.contactId)\"\n @change=\"\n async (e) =>\n handleRoleChange(contact.contactId, (e.target as HTMLInputElement).value)\n \"\n >\n <option value=\"\">\n {{ getLabel(\"selectRole\", \"— Select role —\") }}\n </option>\n <option :value=\"PurchaseRole.PURCHASER\">\n {{ getLabel(\"rolePurchaser\", \"Purchaser\") }}\n </option>\n <option\n :value=\"PurchaseRole.AUTHORIZATION_MANAGER\"\n >\n {{ getLabel(\"roleManager\", \"Authorization Manager\") }}\n </option>\n </select>\n </td>\n <td class=\"px-4 py-3\">\n <template\n v-if=\"\n getRowRole(contact.contactId) ===\n PurchaseRole.PURCHASER\n \"\n >\n <input\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n class=\"w-28 border border-input rounded-[var(--radius-control)] px-2 py-1.5 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary disabled:opacity-50\"\n :value=\"getRowLimit(contact.contactId) ?? ''\"\n :disabled=\"isCurrentUser(contact.contactId)\"\n @change=\"\n async (e) =>\n handleLimitChange(\n contact.contactId,\n (e.target as HTMLInputElement).value,\n )\n \"\n :placeholder=\"getLabel('limitPlaceholder', '0.00')\"\n />\n </template>\n </td>\n <td class=\"px-4 py-3\">\n <div class=\"flex items-center gap-2\">\n <template\n v-if=\"\n hasPac(contact.contactId) &&\n isRowDirty(contact.contactId)\n \"\n >\n <button\n type=\"button\"\n class=\"text-xs bg-primary text-primary-foreground px-3 py-1.5 rounded-[var(--radius-control)] hover:bg-primary/80 transition disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"isRowLoading(contact.contactId)\"\n @click=\"\n async (event) => handleSave(contact.contactId)\n \"\n >\n <template v-if=\"isRowLoading(contact.contactId)\">\n <span\n class=\"inline-block w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin mr-1\"\n ></span>\n </template>\n\n {{ getLabel(\"save\", \"Save\") }}\n </button>\n </template>\n\n <template v-if=\"!hasPac(contact.contactId)\">\n <button\n type=\"button\"\n class=\"text-xs bg-primary text-primary-foreground px-3 py-1.5 rounded-[var(--radius-control)] hover:bg-primary/80 transition disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"\n isRowLoading(contact.contactId) ||\n !getRowRole(contact.contactId)\n \"\n @click=\"\n async (event) => handleCreate(contact.contactId)\n \"\n >\n <template v-if=\"isRowLoading(contact.contactId)\">\n <span\n class=\"inline-block w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin mr-1\"\n ></span>\n </template>\n\n {{ getLabel(\"create\", \"Create\") }}\n </button>\n </template>\n\n <template v-if=\"hasPac(contact.contactId)\">\n <button\n type=\"button\"\n class=\"text-xs border border-border px-3 py-1.5 rounded-[var(--radius-control)] hover:bg-surface-hover transition disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"\n isRowLoading(contact.contactId) ||\n isCurrentUser(contact.contactId)\n \"\n @click=\"\n async (event) => handleDelete(contact.contactId)\n \"\n >\n <template v-if=\"isRowLoading(contact.contactId)\">\n <span\n class=\"inline-block w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin mr-1\"\n ></span>\n </template>\n\n {{ getLabel(\"delete\", \"Delete\") }}\n </button>\n </template>\n </div>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n\n <template v-if=\"getTotalPages() > 1\">\n <div class=\"flex items-center justify-center gap-3 pt-2\">\n <button\n type=\"button\"\n class=\"text-sm px-3 py-1.5 border border-border rounded-[var(--radius-control)] hover:bg-surface-hover transition disabled:opacity-40 disabled:cursor-not-allowed\"\n :disabled=\"currentPage <= 1\"\n @click=\"async (event) => handlePageChange(currentPage - 1)\"\n >\n {{ getLabel(\"previous\", \"Previous\") }}</button\n ><span class=\"text-sm text-muted-foreground\"\n >{{ getLabel(\"page\", \"Page\") }}{{ currentPage\n }}{{ getLabel(\"of\", \"of\") }}{{ getTotalPages() }}</span\n ><button\n type=\"button\"\n class=\"text-sm px-3 py-1.5 border border-border rounded-[var(--radius-control)] hover:bg-surface-hover transition disabled:opacity-40 disabled:cursor-not-allowed\"\n :disabled=\"currentPage >= getTotalPages()\"\n @click=\"async (event) => handlePageChange(currentPage + 1)\"\n >\n {{ getLabel(\"next\", \"Next\") }}\n </button>\n </div>\n </template>\n </template>\n </div>\n\n <template v-if=\"showAddContactModal\">\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\"\n @click=\"async (event) => closeAddContactModal()\"\n >\n <div\n class=\"bg-background rounded-xl shadow-2xl w-full max-w-lg mx-4 p-6 space-y-4\"\n @click=\"async (e) => e.stopPropagation()\"\n >\n <div class=\"flex items-center justify-between\">\n <h3 class=\"text-lg font-semibold\">\n {{ getLabel(\"addContactTitle\", \"Add Contact\") }}\n </h3>\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:text-foreground transition\"\n @click=\"async (event) => closeAddContactModal()\"\n >\n ✕\n </button>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"companyName\", \"Company\")\n }}</label\n ><input\n type=\"text\"\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-surface-hover cursor-not-allowed\"\n :readOnly=\"true\"\n :value=\"company?.name ?? ''\"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"gender\", \"Gender\")\n }}</label\n ><select\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n :value=\"addContactForm.gender\"\n @change=\"\n async (e) => {\n addContactForm = {\n ...addContactForm,\n gender: (e.target as HTMLInputElement).value,\n };\n }\n \"\n >\n <option value=\"\">\n {{ getLabel(\"selectGender\", \"— Select —\") }}\n </option>\n <option :value=\"Gender.M\">\n {{ getLabel(\"genderM\", \"Male\") }}\n </option>\n <option :value=\"Gender.F\">\n {{ getLabel(\"genderF\", \"Female\") }}\n </option>\n <option :value=\"Gender.U\">\n {{ getLabel(\"genderU\", \"Unspecified\") }}\n </option>\n </select>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\"\n >{{ getLabel(\"email\", \"Email\") }} * </label\n ><input\n type=\"email\"\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n :value=\"addContactForm.email\"\n @change=\"\n async (e) => {\n addContactForm = {\n ...addContactForm,\n email: (e.target as HTMLInputElement).value,\n };\n }\n \"\n />\n </div>\n <div class=\"grid grid-cols-3 gap-3\">\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"firstName\", \"First name\")\n }}</label\n ><input\n type=\"text\"\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n :value=\"addContactForm.firstName\"\n @change=\"\n async (e) => {\n addContactForm = {\n ...addContactForm,\n firstName: (e.target as HTMLInputElement).value,\n };\n }\n \"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"middleName\", \"Middle\")\n }}</label\n ><input\n type=\"text\"\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n :value=\"addContactForm.middleName\"\n @change=\"\n async (e) => {\n addContactForm = {\n ...addContactForm,\n middleName: (e.target as HTMLInputElement).value,\n };\n }\n \"\n />\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"lastName\", \"Last name\")\n }}</label\n ><input\n type=\"text\"\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n :value=\"addContactForm.lastName\"\n @change=\"\n async (e) => {\n addContactForm = {\n ...addContactForm,\n lastName: (e.target as HTMLInputElement).value,\n };\n }\n \"\n />\n </div>\n </div>\n <div>\n <label class=\"block text-sm font-medium mb-1\">{{\n getLabel(\"phone\", \"Phone\")\n }}</label\n ><input\n type=\"tel\"\n class=\"w-full border border-input rounded-[var(--radius-control)] px-3 py-2 text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary\"\n :value=\"addContactForm.phone\"\n @change=\"\n async (e) => {\n addContactForm = {\n ...addContactForm,\n phone: (e.target as HTMLInputElement).value,\n };\n }\n \"\n />\n </div>\n <template v-if=\"!!addContactError\">\n <p class=\"text-sm text-destructive\">{{ addContactError }}</p>\n </template>\n\n <div class=\"flex justify-end gap-3 pt-2\">\n <button\n type=\"button\"\n class=\"px-4 py-2 text-sm border border-border rounded-[var(--radius-control)] hover:bg-surface-hover transition\"\n @click=\"async (event) => closeAddContactModal()\"\n >\n {{ getLabel(\"cancel\", \"Cancel\") }}</button\n ><button\n type=\"button\"\n class=\"px-4 py-2 text-sm bg-primary text-primary-foreground rounded-[var(--radius-control)] hover:bg-primary/80 transition disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2\"\n :disabled=\"addContactLoading || !addContactForm.email\"\n @click=\"async (event) => handleAddContactSubmit()\"\n >\n <template v-if=\"addContactLoading\">\n <span\n class=\"inline-block w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin\"\n ></span>\n </template>\n\n {{ getLabel(\"addContactSubmit\", \"Add Contact\") }}\n </button>\n </div>\n </div>\n </div>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { usePurchaseAuthorizationConfigurator } from \"../composables/vue/usePurchaseAuthorization\";\n\nimport { Contact, Customer, Gender, GraphQLClient, PurchaseAuthorizationConfig, PurchaseAuthorizationConfigCreateInput, PurchaseRole, RegisterContactInput } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface PurchaseAuthorizationConfiguratorProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** The logged-in user */\n user: Contact | Customer;\n\n /** The companyId of the current selected company */\n companyId: number;\n\n /**\n * Adds a button \"Add contact\" above the contacts list and enables registering contacts\n * @default true\n */\n allowContactCreate?: boolean;\n\n /** Fires before a contact is added to the company */\n beforeContactCreate?: (input: RegisterContactInput) => void;\n\n /** Override: fires instead of the default UserService.registerContact() call */\n onContactCreate?: (input: RegisterContactInput) => void;\n\n /** Fires after a contact is registered. If not provided, refreshes contacts list. */\n afterContactCreate?: (contact: Contact) => void;\n\n /** Override: fires instead of the default PurchaseAuthorizationConfigCreateInput() call */\n onPurchaseAuthorizationCreate?: (\n pac: PurchaseAuthorizationConfigCreateInput,\n ) => void;\n\n /** Fires after a PAC is created. If not provided, refreshes contacts list. */\n afterPurchaseAuthorizationCreate?: (pac: PurchaseAuthorizationConfig) => void;\n\n /** Override: fires instead of the default updatePurchaseAuthorizationConfig() call */\n onPurchaseAuthorizationUpdate?: (pac: PurchaseAuthorizationConfig) => void;\n\n /** Fires after a PAC is updated. If not provided, refreshes contacts list. */\n afterPurchaseAuthorizationUpdate?: (pac: PurchaseAuthorizationConfig) => void;\n\n /** Override: fires instead of the default deletePurchaseAuthorizationConfig() call */\n onPurchaseAuthorizationDelete?: (pac: PurchaseAuthorizationConfig) => void;\n\n /** Fires after a PAC is deleted. If not provided, refreshes contacts list. */\n afterPurchaseAuthorizationDelete?: (deleted: boolean) => void;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** Custom CSS class for the component */\n className?: string;\n\n /** Configuration object from the application */\n configuration?: Record<string, any>;\n\n /** Rows per page for contacts pagination */\n pageOffset?: number;\n}\n\nconst props = withDefaults(\n defineProps<PurchaseAuthorizationConfiguratorProps>(),\n {\n allowContactCreate: true,\n },\n);\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => infra.user ?? null);\nconst companyRef = computed(() => infra.companyId as number);\n\nconst {\n company,\n loading,\n contacts,\n totalPages,\n currentPage,\n isAuthManager,\n rowEdits,\n pacMap,\n actionLoading,\n showAddContactModal,\n addContactForm,\n addContactLoading,\n addContactError,\n hasPac,\n isCurrentUser,\n isRowDirty,\n getRowRole,\n getRowLimit,\n isRowLoading,\n loadCompany,\n handleRoleChange,\n handleLimitChange,\n handleCreate,\n handleSave,\n handleDelete,\n handlePageChange,\n openAddContactModal,\n closeAddContactModal,\n handleAddContactSubmit,\n} = usePurchaseAuthorizationConfigurator({\n graphqlClient: infra.graphqlClient,\n user: userRef,\n companyId: companyRef,\n pageOffset: props.pageOffset,\n beforeContactCreate: props.beforeContactCreate,\n onContactCreate: props.onContactCreate,\n afterContactCreate: props.afterContactCreate,\n onPurchaseAuthorizationCreate: props.onPurchaseAuthorizationCreate,\n afterPurchaseAuthorizationCreate: props.afterPurchaseAuthorizationCreate,\n onPurchaseAuthorizationUpdate: props.onPurchaseAuthorizationUpdate,\n afterPurchaseAuthorizationUpdate: props.afterPurchaseAuthorizationUpdate,\n onPurchaseAuthorizationDelete: props.onPurchaseAuthorizationDelete,\n afterPurchaseAuthorizationDelete: props.afterPurchaseAuthorizationDelete,\n});\n\n// Wrapper functions to preserve template's function-call style\nfunction getContacts(): Contact[] {\n return contacts.value;\n}\n\nfunction getTotalPages(): number {\n return totalPages.value;\n}\n\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\n</script>\n","<template>\n <div :class=\"`propeller-purchase-authorization-requests ${className || ''}`\">\n <template v-if=\"isAuthManager\">\n <div class=\"propeller-purchase-authorization-requests__content space-y-4\">\n <h2\n class=\"propeller-purchase-authorization-requests__title text-xl font-semibold\"\n >\n {{ getLabel(\"title\", \"Authorization Requests\") }}\n </h2>\n <template v-if=\"loading\">\n <div class=\"flex items-center justify-center py-12\">\n <div\n class=\"w-8 h-8 border-4 border-primary border-t-transparent rounded-full animate-spin\"\n ></div>\n </div>\n </template>\n\n <template v-if=\"!loading\">\n <template v-if=\"carts.length === 0\">\n <div class=\"text-center py-12 text-muted-foreground\">\n {{ getLabel(\"empty\", \"No pending authorization requests\") }}\n </div>\n </template>\n\n <template v-if=\"carts.length > 0\">\n <div\n class=\"overflow-x-auto rounded-[var(--radius-container)] border border-border bg-card shadow-sm\"\n >\n <table class=\"w-full text-sm\">\n <thead class=\"bg-surface-hover/50 border-b border-border\">\n <tr>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colDate\", \"Date\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colQuantity\", \"Quantity\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colTotal\", \"Total\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colRequestedBy\", \"Requested by\") }}\n </th>\n <th\n class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"colActions\", \"Actions\") }}\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-border\">\n <template :key=\"index\" v-for=\"(cart, index) in carts\">\n <tr class=\"hover:bg-surface-hover/30 transition-colors\">\n <td class=\"px-4 py-3 text-muted-foreground\">\n {{ formatDate(cart.lastModifiedAt ?? \"\") }}\n </td>\n <td class=\"px-4 py-3\">{{ getTotalQuantity(cart) }}</td>\n <td class=\"px-4 py-3 font-medium\">\n {{ formatPrice(cart.total?.totalNet ?? 0) }}\n </td>\n <td class=\"px-4 py-3\">\n <div class=\"font-medium\">\n {{ getContactName(cart.contact) }}\n </div>\n <div class=\"text-xs text-muted-foreground mt-0.5\">\n {{ cart.contact?.email }}\n </div>\n </td>\n <td class=\"px-4 py-3\">\n <button\n type=\"button\"\n class=\"px-3 py-1.5 text-sm border border-input rounded-[var(--radius-control)] bg-background hover:bg-surface-hover/50 transition-colors\"\n @click=\"async (event) => handleViewCart(cart)\"\n >\n {{ getLabel(\"view\", \"View\") }}\n </button>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </template>\n </template>\n\n <template v-if=\"!!selectedCart\">\n <div\n class=\"propeller-purchase-authorization-requests__modal fixed inset-0 z-50 flex items-center justify-center px-4\"\n >\n <div\n class=\"propeller-purchase-authorization-requests__modal-backdrop fixed inset-0 bg-foreground/20\"\n @click=\"async (event) => closeModal()\"\n ></div>\n <div\n class=\"propeller-purchase-authorization-requests__modal-content relative w-full max-w-2xl bg-card rounded-[var(--radius-container)] shadow-2xl overflow-hidden max-h-[90vh] flex flex-col\"\n >\n <div\n class=\"propeller-purchase-authorization-requests__modal-header flex items-center justify-between px-6 py-4 border-b border-border-subtle flex-shrink-0\"\n >\n <h3\n class=\"propeller-purchase-authorization-requests__modal-title text-base font-semibold text-foreground\"\n >\n {{ getLabel(\"modalTitle\", \"Authorization Request\") }}\n </h3>\n <button\n type=\"button\"\n class=\"propeller-purchase-authorization-requests__modal-close text-foreground-subtle hover:text-muted-foreground focus:outline-none\"\n @click=\"async (event) => closeModal()\"\n >\n <svg\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n class=\"h-5 w-5\"\n :strokeWidth=\"2\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n ></path>\n </svg>\n </button>\n </div>\n <template v-if=\"modalLoading\">\n <div class=\"flex items-center justify-center py-16\">\n <div\n class=\"w-8 h-8 border-4 border-primary border-t-transparent rounded-full animate-spin\"\n ></div>\n </div>\n </template>\n\n <template v-if=\"!modalLoading\">\n <div class=\"overflow-y-auto flex-1 px-6 py-5 space-y-6\">\n <div>\n <h4\n class=\"propeller-purchase-authorization-requests__modal-section-title text-sm font-semibold text-muted-foreground mb-2\"\n >\n {{ getLabel(\"requesterInfo\", \"Requester\") }}\n </h4>\n <p class=\"text-sm font-medium\">\n {{ getContactName(selectedCart?.contact) }}\n </p>\n <p class=\"text-sm text-muted-foreground\">\n {{ selectedCart?.contact?.email }}\n </p>\n </div>\n <div>\n <h4\n class=\"propeller-purchase-authorization-requests__modal-section-title text-sm font-semibold text-muted-foreground mb-2\"\n >\n {{ getLabel(\"itemsTitle\", \"Items\") }}\n </h4>\n <div class=\"overflow-x-auto rounded border border-border\">\n <table class=\"w-full text-sm\">\n <thead\n class=\"bg-surface-hover/50 border-b border-border\"\n >\n <tr>\n <th\n class=\"text-left px-3 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"itemProduct\", \"Product\") }}\n </th>\n <th\n class=\"text-right px-3 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"itemQty\", \"Qty\") }}\n </th>\n <th\n class=\"text-right px-3 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"itemUnitPrice\", \"Unit price\") }}\n </th>\n <th\n class=\"text-right px-3 py-2 font-medium text-muted-foreground\"\n >\n {{ getLabel(\"itemTotal\", \"Total\") }}\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-border\">\n <template\n :key=\"idx\"\n v-for=\"(item, idx) in getModalItems()\"\n >\n <tr>\n <td class=\"px-3 py-2\">\n {{ getProductName(item) }}\n </td>\n <td class=\"px-3 py-2 text-right\">\n {{ item.quantity ?? 0 }}\n </td>\n <td class=\"px-3 py-2 text-right\">\n {{\n formatPrice(\n (item.quantity ?? 0) > 0\n ? (item.totalSum ?? 0) /\n (item.quantity ?? 1)\n : 0,\n )\n }}\n </td>\n <td class=\"px-3 py-2 text-right font-medium\">\n {{ formatPrice(item.totalSumNet ?? 0) }}\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n </div>\n </div>\n <div class=\"border-t border-border pt-4 space-y-2 text-sm\">\n <div class=\"flex justify-between text-muted-foreground\">\n <span>{{\n getLabel(\"totalExclVat\", \"Total excl. VAT:\")\n }}</span\n ><span>{{\n formatPrice(selectedCart?.total?.totalGross ?? 0)\n }}</span>\n </div>\n <div class=\"flex justify-between text-muted-foreground\">\n <span>{{ getLabel(\"totalVat\", \"VAT:\") }}</span\n ><span>{{\n formatPrice(\n (selectedCart?.total?.totalNet ?? 0) -\n (selectedCart?.total?.totalGross ?? 0),\n )\n }}</span>\n </div>\n <div\n class=\"flex justify-between font-bold text-base border-t border-border pt-2\"\n >\n <span>{{ getLabel(\"total\", \"Total:\") }}</span\n ><span>{{\n formatPrice(selectedCart?.total?.totalNet ?? 0)\n }}</span>\n </div>\n </div>\n </div>\n <div\n class=\"propeller-purchase-authorization-requests__modal-actions flex gap-3 px-6 py-4 border-t border-border-subtle flex-shrink-0\"\n >\n <button\n type=\"button\"\n class=\"propeller-purchase-authorization-requests__modal-delete flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-input bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-surface-hover/50 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n @click=\"async (event) => openDeleteConfirm()\"\n :disabled=\"deleteLoading || acceptLoading\"\n >\n {{ getLabel(\"delete\", \"Delete\") }}</button\n ><button\n type=\"button\"\n class=\"propeller-purchase-authorization-requests__modal-accept flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-transparent bg-secondary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-secondary/90 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n @click=\"async (event) => handleAcceptRequest()\"\n :disabled=\"acceptLoading || deleteLoading\"\n >\n <template v-if=\"acceptLoading\">\n {{ getLabel(\"accepting\", \"Accepting...\") }}\n </template>\n\n <template v-if=\"!acceptLoading\">\n {{ getLabel(\"acceptRequest\", \"Accept request\") }}\n </template>\n </button>\n </div>\n\n <!--\n Delete confirmation overlay. Shown on top of the preview\n modal when the user clicks Delete; a two-step flow so the\n destructive action requires explicit consent before the\n cart is removed.\n -->\n <template v-if=\"showDeleteConfirm\">\n <div\n class=\"propeller-purchase-authorization-requests__delete-confirm fixed inset-0 z-[60] flex items-center justify-center px-4\"\n >\n <div\n class=\"propeller-purchase-authorization-requests__delete-confirm-backdrop fixed inset-0 bg-foreground/40\"\n @click=\"async (event) => closeDeleteConfirm()\"\n ></div>\n <div\n class=\"propeller-purchase-authorization-requests__delete-confirm-content relative w-full max-w-md bg-card rounded-[var(--radius-container)] shadow-2xl overflow-hidden\"\n >\n <div class=\"px-6 py-4 border-b border-border-subtle\">\n <h4\n class=\"propeller-purchase-authorization-requests__delete-confirm-title text-base font-semibold text-foreground\"\n >\n {{\n getLabel(\n \"deleteConfirmTitle\",\n \"Delete authorization request?\",\n )\n }}\n </h4>\n </div>\n <div class=\"px-6 py-4\">\n <p class=\"text-sm text-muted-foreground\">\n {{\n getLabel(\n \"deleteConfirmBody\",\n \"Are you sure you want to delete this authorization request? The cart will be permanently removed.\",\n )\n }}\n </p>\n </div>\n <div\n class=\"flex gap-3 px-6 py-4 border-t border-border-subtle\"\n >\n <button\n type=\"button\"\n class=\"flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-input bg-card px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n @click=\"async (event) => closeDeleteConfirm()\"\n :disabled=\"deleteLoading\"\n >\n {{ getLabel(\"deleteConfirmNo\", \"No\") }}\n </button>\n <button\n type=\"button\"\n class=\"flex-1 inline-flex justify-center rounded-[var(--radius-control)] border border-transparent bg-destructive px-4 py-2 text-sm font-medium text-destructive-foreground hover:bg-destructive/90 focus:outline-none focus:ring-2 focus:ring-destructive focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n @click=\"async (event) => confirmDelete()\"\n :disabled=\"deleteLoading\"\n >\n <template v-if=\"deleteLoading\">\n {{ getLabel(\"deleting\", \"Deleting...\") }}\n </template>\n\n <template v-if=\"!deleteLoading\">\n {{ getLabel(\"deleteConfirmYes\", \"Yes, delete\") }}\n </template>\n </button>\n </div>\n </div>\n </div>\n </template>\n </template>\n </div>\n </div>\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\nimport { usePurchaseAuthorizationRequests } from \"../composables/vue/usePurchaseAuthorization\";\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\n\nimport {\n Contact,\n Customer,\n GraphQLClient,\n Cart,\n CartMainItem,\n} from \"@propeller-commerce/propeller-sdk-v2\";\n\nexport interface PurchaseAuthorizationRequestsProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** The logged-in user */\n user: Contact | Customer;\n\n /** The companyId of the current selected company */\n companyId: number;\n\n /**\n * Override: fires instead of the default CartService.acceptPurchaseAuthorizationRequest() call.\n * Receives the cartId string.\n */\n onAcceptRequest?: (cartId: string) => void;\n\n /**\n * Fires after a purchase authorization request has been accepted.\n * Receives the full accepted Cart object (or the selectedCart if onAcceptRequest override was used).\n */\n afterAcceptRequest?: (cart: Cart) => void;\n\n /**\n * Override: fires instead of the default CartService.deleteCart() call.\n * Receives the cartId string.\n */\n onDeleteRequest?: (cartId: string) => void;\n\n /**\n * Fires after a purchase authorization request has been deleted (cart removed).\n * Receives the deleted cart's id.\n */\n afterDeleteRequest?: (cartId: string) => void;\n\n /** Format date */\n formatDate?: (dateString: string) => string;\n\n /** Format price */\n formatPrice?: (price: number) => string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** Language used to resolve localized product names in the items table. Defaults to 'NL'. */\n language?: string;\n\n /** Additional CSS class for the root element */\n className?: string;\n\n /**\n * App configuration passthrough.\n * Used for imageSearchFiltersGrid, imageVariantFiltersSmall when fetching cart detail.\n */\n configuration?: Record<string, any>;\n\n /** Called when an SDK operation fails; receives the normalized error */\n onError?: (err: Error) => void;\n}\n\nconst props = defineProps<PurchaseAuthorizationRequestsProps>();\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => (infra.user as Contact | Customer | null | undefined) ?? null);\nconst companyRef = computed(() => infra.companyId as number);\n\nconst {\n carts,\n loading,\n selectedCart,\n modalLoading,\n acceptLoading,\n deleteLoading,\n isAuthManager,\n getTotalQuantity,\n getContactName,\n getModalItems,\n loadCarts,\n handleViewCart,\n handleAcceptRequest,\n handleDeleteRequest,\n closeModal,\n} = usePurchaseAuthorizationRequests({\n graphqlClient: infra.graphqlClient as GraphQLClient,\n user: userRef,\n companyId: companyRef,\n configuration: (infra.configuration ?? props.configuration) as any,\n onAcceptRequest: props.onAcceptRequest,\n afterAcceptRequest: props.afterAcceptRequest,\n onDeleteRequest: props.onDeleteRequest,\n afterDeleteRequest: props.afterDeleteRequest,\n onError: props.onError,\n});\n\n// Two-step delete UX: clicking Delete in the preview modal opens a small\n// confirmation overlay so the destructive action requires explicit user\n// confirmation.\nconst showDeleteConfirm = ref(false);\nfunction openDeleteConfirm() {\n showDeleteConfirm.value = true;\n}\nfunction closeDeleteConfirm() {\n showDeleteConfirm.value = false;\n}\nasync function confirmDelete() {\n await handleDeleteRequest();\n showDeleteConfirm.value = false;\n}\n\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\n\nfunction getProductName(item: CartMainItem | any): string {\n // First-class lookup: localized names array on the line item's product.\n // Falls back to bundle name (bundle items) and finally to the SKU so the\n // cell never renders empty for an item that does have data.\n const lang = (infra.language as string | undefined) || props.language || 'NL';\n const fromNames = getLanguageString((item as any)?.product?.names, lang, '');\n if (fromNames) return fromNames;\n const fromBundle = getLanguageString((item as any)?.bundle?.names, lang, '');\n if (fromBundle) return fromBundle;\n return (item as any)?.product?.sku || '';\n}\n\nfunction formatDate(dateStr: string): string {\n if (props.formatDate) return props.formatDate(dateStr);\n if (!dateStr) return \"-\";\n const d = new Date(dateStr);\n return `${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()}`;\n}\n\nfunction formatPrice(price: number): string {\n if (props.formatPrice) return props.formatPrice(price);\n if (!price) return \"-\";\n return _formatPrice(price, { symbol: props.currency ?? \"€\" });\n}\n</script>\n","<template>\n <div class=\"quote-actions space-y-4\">\n <template v-if=\"isExpired\">\n <div\n class=\"propeller-quote-actions__expired text-sm text-muted-foreground bg-surface-hover/50 border border-border rounded-[var(--radius-container)] p-3\"\n >\n {{ getLabel('expiredMessage', 'This quote has expired.') }}\n </div>\n </template>\n\n <template v-else>\n <template v-if=\"showTermsAndConditions\">\n <div class=\"flex items-center space-x-2 pt-2\">\n <input\n type=\"checkbox\"\n id=\"quote-actions-terms\"\n class=\"propeller-quote-actions__checkbox h-4 w-4 rounded border-input text-primary focus:ring-primary\"\n :checked=\"termsAccepted\"\n @change=\"async (event) => handleTermsChange((event.target as HTMLInputElement).checked)\"\n /><label for=\"quote-actions-terms\" class=\"text-sm leading-none\"\n >{{ getLabel('termsPrefix', 'I agree to the')\n }}<a\n href=\"#\"\n class=\"text-primary hover:underline font-medium\"\n @click=\"async (event) => handleTermsLinkClick(event)\"\n >{{ getLabel('termsLink', 'Terms and Conditions') }}</a\n ></label\n >\n </div>\n </template>\n\n <button\n type=\"button\"\n class=\"propeller-quote-actions__submit flex items-center justify-center gap-2 w-full bg-primary text-primary-foreground text-center py-3 rounded-[var(--radius-container)] hover:bg-primary/80 transition font-semibold text-lg disabled:opacity-50 disabled:cursor-not-allowed mt-2\"\n @click=\"async (event) => handleAcceptClick()\"\n :disabled=\"isAcceptDisabled\"\n >\n <template v-if=\"loading\">\n <div\n class=\"propeller-quote-actions__spinner w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin\"\n ></div>\n </template>\n\n <template v-if=\"loading\">\n {{ getLabel('processing', 'Processing...') }}\n </template>\n\n <template v-if=\"!loading\">\n {{ getLabel('acceptButton', 'Accept Quotation') }}\n </template>\n </button>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\";\n\nimport { Order, GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';\nimport { useOrders } from '../composables/vue/useOrders';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface QuoteActionsProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient?: GraphQLClient;\n\n /** The quotation for which the actions will take place */\n quote: Order;\n\n /** Labels used in the quote actions component */\n labels?: Record<string, string>;\n\n /** Action function triggered when the \"Accept quotation\" button is clicked.\n * If not provided, the base implementation calls setOrderStatus on the SDK. */\n onAccept?: (quote: Order) => void;\n\n /** Action function triggered after the quote is accepted. Usually for navigating towards the thank you page. */\n afterAccept?: (quote: Order) => void;\n\n /** Show the terms and conditions acceptance */\n showTermsAndConditions?: boolean;\n\n /** Action when the \"Terms and conditions\" link is clicked */\n onTermsAndConditionsClick?: () => void;\n}\ninterface QuoteActionsState {\n termsAccepted: boolean;\n loading: boolean;\n showTermsAndConditions: boolean;\n isAcceptDisabled: boolean;\n getLabel: (key: string, fallback: string) => string;\n handleTermsChange: (checked: boolean) => void;\n handleTermsLinkClick: (event: Event) => void;\n handleAcceptClick: () => Promise<void>;\n}\n\nconst props = withDefaults(defineProps<QuoteActionsProps>(), {\n showTermsAndConditions: true,\n});\nconst infra = useInfraProps(props);\nconst termsAccepted = ref<QuoteActionsState['termsAccepted']>(false);\nconst loading = ref<QuoteActionsState['loading']>(false);\n\nconst userRef = computed(() => null as any);\nconst companyRef = computed(() => undefined);\nconst { setQuoteStatus } = useOrders({\n graphqlClient: infra.graphqlClient!,\n user: userRef,\n companyId: companyRef,\n});\n\nconst showTermsAndConditions = computed(() => {\n return props.showTermsAndConditions !== undefined ? props.showTermsAndConditions : true;\n});\nconst isExpired = computed(() => {\n const validUntil = (props.quote as any)?.validUntil;\n if (!validUntil) return false;\n const validUntilDate = new Date(validUntil);\n if (Number.isNaN(validUntilDate.getTime())) return false;\n return validUntilDate.getTime() < Date.now();\n});\nconst isAcceptDisabled = computed(() => {\n if (showTermsAndConditions && !termsAccepted.value) return true;\n if (loading.value) return true;\n return false;\n});\n\nfunction getLabel(key: string, fallback: string): ReturnType<QuoteActionsState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction handleTermsChange(checked: boolean): ReturnType<QuoteActionsState['handleTermsChange']> {\n termsAccepted.value = checked;\n}\nfunction handleTermsLinkClick(event: Event): ReturnType<QuoteActionsState['handleTermsLinkClick']> {\n event.preventDefault();\n if (props.onTermsAndConditionsClick) {\n props.onTermsAndConditionsClick();\n }\n}\nasync function handleAcceptClick(): ReturnType<QuoteActionsState['handleAcceptClick']> {\n if (isAcceptDisabled.value) return;\n loading.value = true;\n try {\n if (props.onAccept) {\n props.onAccept(props.quote);\n } else if (props.quote?.id) {\n await setQuoteStatus(props.quote.id, { status: 'NEW' });\n }\n if (props.afterAccept) {\n props.afterAccept(props.quote);\n }\n } finally {\n loading.value = false;\n }\n}\n</script>\n","<template>\n <div\n class=\"propeller-register-form\"\n :data-loading=\"loading ? 'true' : 'false'\"\n :data-user-type=\"selectedUserType\"\n >\n <template v-if=\"resolvedTitle\">\n <div class=\"propeller-register-form__header space-y-1 text-center mb-6\">\n <h2 class=\"propeller-register-form__title text-2xl font-bold\">{{ resolvedTitle }}</h2>\n <template v-if=\"subtitle\">\n <p class=\"propeller-register-form__subtitle text-sm text-muted-foreground\">{{ subtitle }}</p>\n </template>\n </div>\n </template>\n\n <template v-if=\"!submitted\">\n <form class=\"space-y-6\" @submit=\"async (e) => handleSubmit(e)\">\n <div class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold border-b pb-2\">\n {{ personalDetailsTitle }}\n </h3>\n <template v-if=\"showUserTypeSelector\">\n <div class=\"space-y-2\">\n <label class=\"text-sm font-medium leading-none\">{{ userTypeLabel }}</label>\n <div class=\"flex gap-3\">\n <button\n type=\"button\"\n @click=\"\n async (event) => {\n selectedUserType = 'Contact';\n }\n \"\n :class=\"\n 'flex-1 h-10 px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] border transition-colors ' +\n (selectedUserType === 'Contact'\n ? 'border-primary bg-primary/5 text-primary'\n : 'border-input hover:bg-surface-hover')\n \"\n >\n {{ contactLabel }}</button\n ><button\n type=\"button\"\n @click=\"\n async (event) => {\n selectedUserType = 'Customer';\n }\n \"\n :class=\"\n 'flex-1 h-10 px-4 py-2 text-sm font-medium rounded-[var(--radius-control)] border transition-colors ' +\n (selectedUserType === 'Customer'\n ? 'border-primary bg-primary/5 text-primary'\n : 'border-input hover:bg-surface-hover')\n \"\n >\n {{ customerLabel }}\n </button>\n </div>\n </div>\n </template>\n\n <div class=\"space-y-2\">\n <label class=\"text-sm font-medium leading-none\">{{ genderLabel }}</label>\n <div class=\"flex gap-4\">\n <label class=\"flex items-center gap-2 text-sm\"\n ><input\n type=\"radio\"\n name=\"gender\"\n value=\"M\"\n class=\"propeller-register-form__radio h-4 w-4 border-input text-primary focus:ring-primary\"\n :checked=\"gender === Gender.M\"\n @change=\"\n async (event) => {\n gender = Gender.M;\n }\n \"\n :disabled=\"loading\"\n />\n {{ genderMrLabel }} </label\n ><label class=\"flex items-center gap-2 text-sm\"\n ><input\n type=\"radio\"\n name=\"gender\"\n value=\"F\"\n class=\"propeller-register-form__radio h-4 w-4 border-input text-primary focus:ring-primary\"\n :checked=\"gender === Gender.F\"\n @change=\"\n async (event) => {\n gender = Gender.F;\n }\n \"\n :disabled=\"loading\"\n />\n {{ genderMrsLabel }} </label\n ><label class=\"flex items-center gap-2 text-sm\"\n ><input\n type=\"radio\"\n name=\"gender\"\n value=\"U\"\n class=\"propeller-register-form__radio h-4 w-4 border-input text-primary focus:ring-primary\"\n :checked=\"gender === Gender.U\"\n @change=\"\n async (event) => {\n gender = Gender.U;\n }\n \"\n :disabled=\"loading\"\n />\n {{ genderOtherLabel }}\n </label>\n </div>\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-email\" class=\"text-sm font-medium leading-none\"\n >{{ emailLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"email\"\n id=\"register-email\"\n name=\"email\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"email\"\n @change=\"\n async (e) => {\n email = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"emailPlaceholder\"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <template v-if=\"isContact\">\n <div class=\"space-y-4\">\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-vatNumber\" class=\"text-sm font-medium leading-none\"\n >{{ vatNumberLabel }}\n <template v-if=\"isFieldRequired('vatNumber')\">\n <span class=\"propeller-register-form__required text-destructive ml-1\">*</span>\n </template> </label\n ><input\n type=\"text\"\n id=\"register-vatNumber\"\n name=\"vatNumber\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"vatNumber\"\n @change=\"\n async (e) => {\n vatNumber = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"isFieldRequired('vatNumber')\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-cocNumber\" class=\"text-sm font-medium leading-none\"\n >{{ cocNumberLabel }}\n <template v-if=\"isFieldRequired('cocNumber')\">\n <span class=\"propeller-register-form__required text-destructive ml-1\">*</span>\n </template> </label\n ><input\n type=\"text\"\n id=\"register-cocNumber\"\n name=\"cocNumber\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"cocNumber\"\n @change=\"\n async (e) => {\n cocNumber = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"isFieldRequired('cocNumber')\"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-companyName\" class=\"text-sm font-medium leading-none\"\n >{{ companyNameLabel }}\n <template v-if=\"isFieldRequired('companyName')\">\n <span class=\"propeller-register-form__required text-destructive ml-1\">*</span>\n </template> </label\n ><input\n type=\"text\"\n id=\"register-companyName\"\n name=\"companyName\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"companyName\"\n @change=\"\n async (e) => {\n companyName = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"isFieldRequired('companyName')\"\n :disabled=\"loading\"\n />\n </div>\n </div>\n </template>\n\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-firstName\" class=\"text-sm font-medium leading-none\"\n >{{ firstNameLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-firstName\"\n name=\"firstName\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"firstName\"\n @change=\"\n async (e) => {\n firstName = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-middleName\" class=\"text-sm font-medium leading-none\">{{\n middleNameLabel\n }}</label\n ><input\n type=\"text\"\n id=\"register-middleName\"\n name=\"middleName\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"middleName\"\n @change=\"\n async (e) => {\n middleName = (e.target as HTMLInputElement).value;\n }\n \"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-lastName\" class=\"text-sm font-medium leading-none\"\n >{{ lastNameLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-lastName\"\n name=\"lastName\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"lastName\"\n @change=\"\n async (e) => {\n lastName = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-phone\" class=\"text-sm font-medium leading-none\"\n >{{ phoneLabel }}\n <template v-if=\"isFieldRequired('phone')\">\n <span class=\"propeller-register-form__required text-destructive ml-1\">*</span>\n </template> </label\n ><input\n type=\"tel\"\n id=\"register-phone\"\n name=\"phone\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"phone\"\n @change=\"\n async (e) => {\n phone = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"isFieldRequired('phone')\"\n :disabled=\"loading\"\n />\n </div>\n </div>\n </div>\n <div class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold border-b pb-2\">\n {{ billingAddressTitle }}\n </h3>\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-billingPostalCode\" class=\"text-sm font-medium leading-none\"\n >{{ postalCodeLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-billingPostalCode\"\n name=\"billingPostalCode\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"billingPostalCode\"\n @change=\"\n async (e) => {\n billingPostalCode = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-billingStreet\" class=\"text-sm font-medium leading-none\"\n >{{ streetLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-billingStreet\"\n name=\"billingStreet\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"billingStreet\"\n @change=\"\n async (e) => {\n billingStreet = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-billingNumber\" class=\"text-sm font-medium leading-none\"\n >{{ numberLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-billingNumber\"\n name=\"billingNumber\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"billingNumber\"\n @change=\"\n async (e) => {\n billingNumber = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label\n for=\"register-billingNumberExtension\"\n class=\"text-sm font-medium leading-none\"\n >{{ numberExtensionLabel }}</label\n ><input\n type=\"text\"\n id=\"register-billingNumberExtension\"\n name=\"billingNumberExtension\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"billingNumberExtension\"\n @change=\"\n async (e) => {\n billingNumberExtension = (e.target as HTMLInputElement).value;\n }\n \"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-billingCity\" class=\"text-sm font-medium leading-none\"\n >{{ cityLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-billingCity\"\n name=\"billingCity\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"billingCity\"\n @change=\"\n async (e) => {\n billingCity = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-billingCountry\" class=\"text-sm font-medium leading-none\"\n >{{ countryLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><select\n id=\"register-billingCountry\"\n name=\"billingCountry\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"billingCountry\"\n @change=\"\n async (e) => {\n billingCountry = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n >\n <option value=\"\">{{ selectCountryPlaceholder }}</option>\n <template :key=\"entry[0]\" v-for=\"(entry, index) in Object.entries(countries || {})\">\n <option :value=\"entry[0]\">{{ entry[1] }}</option>\n </template>\n </select>\n </div>\n </div>\n </div>\n <div class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold border-b pb-2\">\n {{ deliveryAddressTitle }}\n </h3>\n <div class=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n id=\"register-sameAsDelivery\"\n name=\"sameAsDelivery\"\n class=\"propeller-register-form__checkbox h-4 w-4 rounded border-input text-primary focus:ring-primary\"\n :checked=\"sameAsDelivery\"\n @change=\"\n async (e) => {\n sameAsDelivery = (e.target as HTMLInputElement).checked;\n }\n \"\n :disabled=\"loading\"\n /><label for=\"register-sameAsDelivery\" class=\"text-sm font-medium leading-none\">{{\n sameAsDeliveryLabel\n }}</label>\n </div>\n <template v-if=\"!sameAsDelivery\">\n <div class=\"space-y-4\">\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-deliveryPostalCode\" class=\"text-sm font-medium leading-none\"\n >{{ postalCodeLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-deliveryPostalCode\"\n name=\"deliveryPostalCode\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"deliveryPostalCode\"\n @change=\"\n async (e) => {\n deliveryPostalCode = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-deliveryStreet\" class=\"text-sm font-medium leading-none\"\n >{{ streetLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-deliveryStreet\"\n name=\"deliveryStreet\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"deliveryStreet\"\n @change=\"\n async (e) => {\n deliveryStreet = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-deliveryNumber\" class=\"text-sm font-medium leading-none\"\n >{{ numberLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-deliveryNumber\"\n name=\"deliveryNumber\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"deliveryNumber\"\n @change=\"\n async (e) => {\n deliveryNumber = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label\n for=\"register-deliveryNumberExtension\"\n class=\"text-sm font-medium leading-none\"\n >{{ numberExtensionLabel }}</label\n ><input\n type=\"text\"\n id=\"register-deliveryNumberExtension\"\n name=\"deliveryNumberExtension\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"deliveryNumberExtension\"\n @change=\"\n async (e) => {\n deliveryNumberExtension = (e.target as HTMLInputElement).value;\n }\n \"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-3\">\n <div class=\"space-y-2\">\n <label for=\"register-deliveryCity\" class=\"text-sm font-medium leading-none\"\n >{{ cityLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"text\"\n id=\"register-deliveryCity\"\n name=\"deliveryCity\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"deliveryCity\"\n @change=\"\n async (e) => {\n deliveryCity = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-deliveryCountry\" class=\"text-sm font-medium leading-none\"\n >{{ countryLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><select\n id=\"register-deliveryCountry\"\n name=\"deliveryCountry\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"deliveryCountry\"\n @change=\"\n async (e) => {\n deliveryCountry = (e.target as HTMLInputElement).value;\n }\n \"\n :required=\"true\"\n :disabled=\"loading\"\n >\n <option value=\"\">{{ selectCountryPlaceholder }}</option>\n <template\n :key=\"entry[0]\"\n v-for=\"(entry, index) in Object.entries(countries || {})\"\n >\n <option :value=\"entry[0]\">{{ entry[1] }}</option>\n </template>\n </select>\n </div>\n </div>\n </div>\n </template>\n </div>\n <div class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold border-b pb-2\">\n {{ passwordTitle }}\n </h3>\n <div class=\"space-y-2\">\n <label for=\"register-password\" class=\"text-sm font-medium leading-none\"\n >{{ passwordLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"password\"\n id=\"register-password\"\n name=\"password\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"password\"\n @change=\"\n async (e) => {\n password = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"passwordPlaceholder\"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n <div class=\"space-y-2\">\n <label for=\"register-confirmPassword\" class=\"text-sm font-medium leading-none\"\n >{{ confirmPasswordLabel }}<span class=\"propeller-register-form__required text-destructive ml-1\">*</span></label\n ><input\n type=\"password\"\n id=\"register-confirmPassword\"\n name=\"confirmPassword\"\n class=\"propeller-register-form__input flex h-10 w-full rounded-[var(--radius-control)] border border-input bg-card px-3 py-2 text-sm placeholder:text-foreground-subtle focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent disabled:cursor-not-allowed disabled:opacity-50\"\n :value=\"confirmPassword\"\n @change=\"\n async (e) => {\n confirmPassword = (e.target as HTMLInputElement).value;\n }\n \"\n :placeholder=\"passwordPlaceholder\"\n :required=\"true\"\n :disabled=\"loading\"\n />\n </div>\n </div>\n <template v-if=\"error\">\n <div class=\"propeller-register-form__error text-sm text-destructive bg-destructive/10 p-3 rounded-[var(--radius-control)]\">\n {{ error }}\n </div>\n </template>\n\n <button\n type=\"submit\"\n class=\"propeller-register-form__submit inline-flex items-center justify-center w-full h-10 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-[var(--radius-control)] hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"loading\"\n >\n <template v-if=\"loading\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-register-form__spinner animate-spin -ml-1 mr-2 h-4 w-4 text-primary-foreground\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n class=\"opacity-25\"\n ></circle>\n <path\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n class=\"opacity-75\"\n ></path>\n </svg>\n </template>\n\n <template v-if=\"loading\"> {{ registeringText }} </template>\n\n <template v-else>\n {{ resolvedButtonText }}\n </template>\n </button>\n </form>\n </template>\n\n <template v-if=\"submitted\">\n <div class=\"text-center space-y-4\">\n <div class=\"flex justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n class=\"propeller-register-form__success-icon h-12 w-12 text-success\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n ></path>\n </svg>\n </div>\n <p class=\"propeller-register-form__success-message text-sm text-muted-foreground\">{{ props.labels?.successMessage || 'Your account has been created successfully.' }}</p>\n </div>\n </template>\n\n <template v-if=\"showLoginLink && !submitted\">\n <div class=\"mt-6 border-t pt-6\">\n <div class=\"text-center\">\n <p class=\"propeller-register-form__login-prompt text-sm text-muted-foreground mb-2\">{{ loginText }}</p>\n <button\n type=\"button\"\n class=\"text-sm text-primary hover:underline\"\n @click=\"\n async (event) => {\n if (onLoginClick) onLoginClick();\n }\n \"\n >\n {{ loginLinkText }}\n </button>\n </div>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport type { Cart, Contact, Customer, GraphQLClient } from '@propeller-commerce/propeller-sdk-v2';\nimport { Gender } from '@propeller-commerce/propeller-sdk-v2';\nimport { useAuth } from '../composables/vue/useAuth';\nimport type { RegisterContactInput, RegisterCustomerInput } from '../composables/vue/useAuth';\n\n\n\n\n export interface RegisterFormProps {\n /** GraphQL client for the Propeller SDK */\n graphqlClient: GraphQLClient;\n\n /** Title of the register form\n * @default \"Create account\"\n */\n title?: string;\n\n /** Subtitle of the register form\n * @default \"\"\n */\n subtitle?: string;\n\n /** Label for the submit button\n * @default \"Register\"\n */\n buttonText?: string;\n\n /**\n * Enable choosing between Contact or Customer if null,\n * otherwise proceed with one user type registration only.\n * 'Contact' = Company account (has company name, VAT, CoC fields)\n * 'Customer' = Consumer/personal account\n * @default null\n */\n showUserType?: 'Contact' | 'Customer' | null;\n\n /**\n * Required fields for the registration form.\n * Available field names: firstName, middleName, lastName, email, password,\n * phone, mobile, gender, companyName, vatNumber, cocNumber,\n * street, number, numberExtension, postalCode, city, country\n * @default []\n */\n requiredFields?: string[];\n\n /**\n * When true (default) the new contact/customer is automatically logged in\n * after registration: the SDK access token is set on the GraphQL client and\n * forwarded to `afterRegistration` so the parent can populate auth state.\n * When false, registration completes server-side but no session is kept;\n * `afterRegistration` is called without tokens so the parent can redirect\n * the user to the login page.\n * @default true\n */\n automaticLogin?: boolean;\n\n /**\n * Labels for the registration form fields.\n *\n * Available keys:\n * - firstName, middleName, lastName, email, password, confirmPassword\n * - phone, gender, companyName, vatNumber, cocNumber\n * - street, number, numberExtension, postalCode, city, country\n * - userTypeLabel, contactLabel, customerLabel\n * - emailPlaceholder, passwordPlaceholder, passwordMismatch\n * - billingAddressTitle, deliveryAddressTitle, sameAsDelivery\n * - loginText, loginLink\n * - personalDetailsTitle, passwordTitle\n */\n labels?: Record<string, string>;\n\n /** Callback before the registration process starts */\n beforeRegistration?: () => void;\n\n /** Callback after the user is registered.\n * `anonymousCart` is the cart held in the parent's store/state at the moment of submission,\n * forwarded so the parent can merge it into the new user's cart.\n */\n afterRegistration?: (user: Contact | Customer, accessToken?: string, refreshToken?: string, expiresAt?: string, anonymousCart?: Cart | null) => void;\n\n /** Anonymous cart snapshot from the parent's store/state — forwarded to `afterRegistration`. */\n cart?: Cart | null;\n\n /** Action for the login link click */\n onLoginClick?: () => void;\n\n /** Show/hide the login link\n * @default true\n */\n displayLoginLink?: boolean;\n\n /**\n * Prefered language\n * @default 'NL'\n */\n preferredLanguage?: string;\n\n /**\n * List of countries to display in the country dropdown\n * @default {}\n */\n countries?: Record<string, string>;\n}\nconst props = withDefaults(defineProps<RegisterFormProps>(), {\n automaticLogin: true,\n displayLoginLink: true,\n});\nconst firstName = ref('');\nconst middleName = ref('');\nconst lastName = ref('');\nconst email = ref('');\nconst password = ref('');\nconst confirmPassword = ref('');\nconst phone = ref('');\nconst gender = ref<Gender>(Gender.U);\nconst companyName = ref('');\nconst vatNumber = ref('');\nconst cocNumber = ref('');\nconst billingStreet = ref('');\nconst billingNumber = ref('');\nconst billingNumberExtension = ref('');\nconst billingPostalCode = ref('');\nconst billingCity = ref('');\nconst billingCountry = ref('');\nconst sameAsDelivery = ref(true);\nconst deliveryStreet = ref('');\nconst deliveryNumber = ref('');\nconst deliveryNumberExtension = ref('');\nconst deliveryPostalCode = ref('');\nconst deliveryCity = ref('');\nconst deliveryCountry = ref('');\nconst selectedUserType = ref<'' | 'Contact' | 'Customer'>('');\nconst submitted = ref(false);\n\nconst { loading, error, registerContact, registerCustomer } = useAuth({\n graphqlClient: props.graphqlClient,\n language: props.preferredLanguage || 'NL',\n});\n\n\n\n\n\n\n\n\n\n\n const resolvedTitle = computed(() => {\nreturn props.title !== undefined ? props.title : 'Create account';\n})\nconst resolvedButtonText = computed(() => {\nreturn props.buttonText || 'Register';\n})\nconst showUserTypeSelector = computed(() => {\nreturn props.showUserType === undefined || props.showUserType === null;\n})\nconst effectiveUserType = computed(() => {\nif (props.showUserType) return props.showUserType;\nreturn selectedUserType.value;\n})\nconst isContact = computed(() => {\n return effectiveUserType.value === 'Contact';\n});\nconst isCustomer = computed(() => {\n return effectiveUserType.value === 'Customer';\n});\nconst showLoginLink = computed(() => {\nreturn props.displayLoginLink !== false;\n})\nconst personalDetailsTitle = computed(() => {\nreturn props.labels?.personalDetailsTitle || 'Your details';\n})\nconst billingAddressTitle = computed(() => {\nreturn props.labels?.billingAddressTitle || 'Billing address';\n})\nconst deliveryAddressTitle = computed(() => {\nreturn props.labels?.deliveryAddressTitle || 'Delivery address';\n})\nconst passwordTitle = computed(() => {\nreturn props.labels?.passwordTitle || 'Password';\n})\nconst sameAsDeliveryLabel = computed(() => {\n return props.labels?.sameAsDelivery || 'Delivery address is the same as billing address';\n});\nconst firstNameLabel = computed(() => {\n return props.labels?.firstName || 'First name';\n});\nconst middleNameLabel = computed(() => {\n return props.labels?.middleName || 'Insertion';\n});\nconst lastNameLabel = computed(() => {\n return props.labels?.lastName || 'Last name';\n});\nconst emailLabel = computed(() => {\n return props.labels?.email || 'Email address';\n});\nconst passwordLabel = computed(() => {\n return props.labels?.password || 'Password';\n});\nconst confirmPasswordLabel = computed(() => {\n return props.labels?.confirmPassword || 'Repeat password';\n});\nconst phoneLabel = computed(() => {\n return props.labels?.phone || 'Phone number';\n});\nconst genderLabel = computed(() => {\n return props.labels?.gender || 'Title';\n});\nconst companyNameLabel = computed(() => {\n return props.labels?.companyName || 'Company name';\n});\nconst vatNumberLabel = computed(() => {\n return props.labels?.vatNumber || 'VAT number';\n});\nconst cocNumberLabel = computed(() => {\n return props.labels?.cocNumber || 'CoC number';\n});\nconst streetLabel = computed(() => {\nreturn props.labels?.street || 'Street';\n})\nconst numberLabel = computed(() => {\nreturn props.labels?.number || 'Number';\n})\nconst numberExtensionLabel = computed(() => {\nreturn props.labels?.numberExtension || 'Apt/Suite/Unit';\n})\nconst postalCodeLabel = computed(() => {\nreturn props.labels?.postalCode || 'Postal code';\n})\nconst cityLabel = computed(() => {\nreturn props.labels?.city || 'City';\n})\nconst countryLabel = computed(() => {\nreturn props.labels?.country || 'Country';\n})\nconst selectCountryPlaceholder = computed(() => {\nreturn props.labels?.selectCountry || 'Select country';\n})\nconst registeringText = computed(() => {\nreturn props.labels?.registering || 'Registering...';\n})\nconst genderMrLabel = computed(() => {\nreturn props.labels?.genderMr || 'Mr.';\n})\nconst genderMrsLabel = computed(() => {\nreturn props.labels?.genderMrs || 'Mrs.';\n})\nconst genderOtherLabel = computed(() => {\nreturn props.labels?.genderOther || 'Other';\n})\nconst userTypeLabel = computed(() => {\nreturn props.labels?.userTypeLabel || 'Account type';\n})\nconst contactLabel = computed(() => {\nreturn props.labels?.contactLabel || 'Company';\n})\nconst customerLabel = computed(() => {\nreturn props.labels?.customerLabel || 'Consumer';\n})\nconst emailPlaceholder = computed(() => {\nreturn props.labels?.emailPlaceholder || 'name@example.com';\n})\nconst passwordPlaceholder = computed(() => {\nreturn props.labels?.passwordPlaceholder || '••••••••';\n})\nconst passwordMismatchText = computed(() => {\nreturn props.labels?.passwordMismatch || 'Passwords do not match';\n})\nconst loginText = computed(() => {\nreturn props.labels?.loginText || 'Already have an account?';\n})\nconst loginLinkText = computed(() => {\nreturn props.labels?.loginLink || 'Log in';\n})\n\n\n\n\nfunction isFieldRequired(fieldName: string): boolean {\n if (fieldName === 'companyName' && isContact.value) return true;\n if (!props.requiredFields) return false;\n return props.requiredFields.indexOf(fieldName) !== -1;\n}\nasync function handleSubmit(e: Event | any) {\n e.preventDefault();\n if (!effectiveUserType.value) {\n error.value = 'Please select an account type.';\n return;\n }\n if (password.value !== confirmPassword.value) {\n error.value = passwordMismatchText.value;\n return;\n }\n if (loading.value) return;\n if (props.beforeRegistration) {\n props.beforeRegistration();\n }\n\n const input = {\n email: email.value,\n password: password.value,\n firstName: firstName.value,\n middleName: middleName.value,\n lastName: lastName.value,\n phone: phone.value,\n gender: gender.value,\n companyName: companyName.value,\n vatNumber: vatNumber.value,\n cocNumber: cocNumber.value,\n street: billingStreet.value,\n number: billingNumber.value,\n numberExtension: billingNumberExtension.value,\n postalCode: billingPostalCode.value,\n city: billingCity.value,\n country: billingCountry.value,\n deliveryStreet: deliveryStreet.value,\n deliveryNumber: deliveryNumber.value,\n deliveryNumberExtension: deliveryNumberExtension.value,\n deliveryPostalCode: deliveryPostalCode.value,\n deliveryCity: deliveryCity.value,\n deliveryCountry: deliveryCountry.value,\n sameDeliveryAsBilling: sameAsDelivery.value,\n };\n\n const autoLogin = props.automaticLogin !== false;\n const result = isContact.value\n ? await registerContact(input as RegisterContactInput, props.preferredLanguage, autoLogin)\n : await registerCustomer(input as RegisterCustomerInput, props.preferredLanguage, autoLogin);\n\n if (result.ok) {\n submitted.value = true;\n if (props.afterRegistration) {\n props.afterRegistration(\n (result.data.user ?? null) as Contact | Customer,\n autoLogin ? result.data.accessToken : undefined,\n autoLogin ? result.data.refreshToken : undefined,\n autoLogin ? result.data.expiresAt : undefined,\n props.cart ?? null,\n );\n }\n }\n}\n</script>\n","<template>\n <div\n :data-search-bar=\"true\"\n :class=\"`propeller-search-bar ${containerClassName || 'relative flex-1 max-w-2xl mx-8'}`\"\n :data-open=\"showDropdown ? 'true' : 'false'\"\n >\n <form class=\"propeller-search-bar__form\" @submit=\"async (e) => handleSubmit(e)\">\n <div class=\"propeller-search-bar__input-wrapper relative\">\n <button\n type=\"submit\"\n class=\"propeller-search-bar__submit absolute left-3 top-1/2 transform -translate-y-1/2 p-0 bg-transparent border-none cursor-pointer\"\n >\n <svg\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n class=\"propeller-search-bar__submit-icon w-5 h-5 text-foreground-subtle hover:text-muted-foreground\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <path d=\"m21 21-4.35-4.35\"></path>\n </svg></button\n ><input\n type=\"search\"\n autoComplete=\"off\"\n class=\"propeller-search-bar__input w-full pl-10 pr-10 py-2 bg-white/95 border border-white/20 rounded-[var(--radius-container)] focus:outline-none focus:ring-2 focus:ring-secondary placeholder:text-muted-foreground\"\n :placeholder=\"placeholder\"\n :value=\"searchTerm\"\n @input=\"async (e) => handleInputChange((e.target as HTMLInputElement).value)\"\n />\n <template v-if=\"isLoading\">\n <div class=\"propeller-search-bar__spinner-wrapper absolute right-3 top-1/2 transform -translate-y-1/2\">\n <div class=\"propeller-search-bar__spinner animate-spin rounded-full h-5 w-5 border-b-2 border-primary\"></div>\n </div>\n </template>\n </div>\n </form>\n <template v-if=\"showDropdown\">\n <div\n class=\"propeller-search-bar__dropdown absolute top-full left-0 right-0 mt-2 bg-card rounded-[var(--radius-container)] shadow-xl border z-50 flex flex-col max-h-96\"\n >\n <template v-if=\"results.length > 0\">\n <div class=\"propeller-search-bar__results flex-1 overflow-y-auto\">\n <template :key=\"result.id + '-' + index\" v-for=\"(result, index) in results\">\n <div\n class=\"propeller-search-bar__result flex items-center gap-4 p-3 hover:bg-surface-hover cursor-pointer border-b border-border last:border-b-0\"\n @click=\"async (event) => handleResultClick(result)\"\n >\n <template v-if=\"result.imageUrl || noImageUrl\">\n <div class=\"propeller-search-bar__result-media relative w-16 h-16 flex-shrink-0\">\n <img\n class=\"propeller-search-bar__result-image w-full h-full object-contain\"\n :src=\"result.imageUrl || noImageUrl\"\n :alt=\"result.name\"\n />\n </div>\n </template>\n\n <div class=\"flex-1 min-w-0\">\n <div class=\"propeller-search-bar__result-name font-semibold truncate\">{{ result.name }}</div>\n <template v-if=\"result.sku\">\n <div class=\"propeller-search-bar__result-sku text-sm text-muted-foreground\">SKU: {{ result.sku }}</div>\n </template>\n </div>\n <template v-if=\"result.price !== undefined && result.price !== null\">\n <div class=\"propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0\">\n {{ formatItemPrice(result.price) }}\n </div>\n </template>\n </div>\n </template>\n </div>\n\n <template v-if=\"itemsFound > results.length\">\n <div\n class=\"propeller-search-bar__view-all flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-[var(--radius-container)]\"\n @click=\"async (event) => handleViewAllClick()\"\n >\n {{ getLabel('viewAll', 'View all results') }} ({{ itemsFound }})\n </div>\n </template>\n </template>\n\n <template v-if=\"results.length === 0 && searchTerm.length >= minLength && !isLoading\">\n <div class=\"propeller-search-bar__empty p-4 text-center text-muted-foreground\">\n {{ getLabel('noResults', 'No products found for') }} &quot;{{ searchTerm }}&quot;\n </div>\n </template>\n </div>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, onUnmounted, ref, watch } from \"vue\";\n\nimport {\n GraphQLClient,\n Product,\n Cluster,\n Contact,\n Customer,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { useProductSearch } from '../composables/vue/useProductSearch';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n// No host-config import: result URLs are built from the `configuration`\n// prop's url builders when supplied, else a plain /product|/cluster path.\n\nexport interface SearchBarResult {\n /** Unique identifier */\n id: number | string;\n /** Display name */\n name: string;\n /** SKU code */\n sku?: string;\n /** Price value */\n price?: number;\n /** Image URL */\n imageUrl?: string;\n /** URL path to navigate to */\n url?: string;\n /** Whether this is a cluster (vs product) */\n isCluster?: boolean;\n}\nexport interface SearchBarProps {\n /** Propeller SDK GraphQL client */\n graphqlClient: GraphQLClient;\n\n /** Currency symbol to display. Defaults to '€'. */\n currency?: string;\n\n /** The currently logged in user (Contact or Customer) */\n user?: Contact | Customer | null;\n\n /** Language code for search requests */\n language?: string;\n\n /** Placeholder text for the search input */\n placeholder?: string;\n\n /** Minimum characters before search triggers */\n minSearchLength?: number;\n\n /** Debounce delay in milliseconds */\n debounceMs?: number;\n\n /** Maximum number of results to show in dropdown */\n maxResults?: number;\n\n /** Fallback image URL when product has no image */\n noImageUrl?: string;\n\n /** Fires when the search form is submitted (Enter key). Receives the search term. */\n onSubmit?: (term: string) => void;\n\n /** Fires when a result item is clicked. Receives the result object. */\n onResultClick?: (result: SearchBarResult) => void;\n\n /** Fires when \"View all results\" is clicked. Receives the search term. */\n onViewAllClick?: (term: string) => void;\n\n /** Custom price formatting function */\n formatPrice?: (price: number) => string;\n\n /** Labels for the component */\n labels?: Record<string, string>;\n\n /** Additional class name for the container */\n containerClassName?: string;\n\n /** Tax zone used for price calculation. Defaults to 'NL'. */\n taxZone?: string;\n\n /**\n * Active company ID from the company switcher.\n * When provided, can be forwarded to price calculation in search results\n * if the underlying SDK call supports priceCalculateProductInput.\n */\n companyId?: number;\n\n /**\n * Configuration object providing:\n * imageSearchFiltersGrid, imageVariantFiltersMedium — passed to CategoryService\n * baseCategoryId — used when querying by term or brand\n * urls.getProductUrl / urls.getClusterUrl — for card URL generation\n */\n configuration?: any;\n\n /**\n * Bump this counter to clear the search input from outside (e.g. on route\n * change). Each unique value triggers a one-time reset of the local term.\n */\n clearSignal?: number;\n}\ninterface SearchBarState {\n searchTerm: string;\n results: SearchBarResult[];\n isLoading: boolean;\n showDropdown: boolean;\n itemsFound: number;\n debounceTimer: any;\n clickOutsideListener: {\n fn: ((e: MouseEvent) => void) | null;\n };\n placeholder: string;\n minLength: number;\n debounceMs: number;\n maxResults: number;\n noImageUrl: string;\n getLabel: (key: string, fallback: string) => string;\n formatItemPrice: (price: number) => string;\n mapProductToResult: (item: Product | Cluster) => SearchBarResult;\n handleInputChange: (value: string) => void;\n fetchResults: (term: string) => Promise<void>;\n handleSubmit: (e: any) => void;\n handleResultClick: (result: SearchBarResult) => void;\n handleViewAllClick: () => void;\n}\n\nconst props = defineProps<SearchBarProps>();\nconst infra = useInfraProps(props);\n\nconst companyRef = computed(() => infra.companyId);\n\nconst { search, searchResults, searchItemsFound, searchLoading } = useProductSearch({\n graphqlClient: infra.graphqlClient,\n language: computed(() => infra.language || 'NL'),\n configuration: infra.configuration || {},\n companyId: companyRef,\n});\n\nconst searchTerm = ref<SearchBarState['searchTerm']>('');\nconst results = ref<SearchBarState['results']>([]);\nconst isLoading = searchLoading;\nconst showDropdown = ref<SearchBarState['showDropdown']>(false);\nconst itemsFound = ref<SearchBarState['itemsFound']>(0);\nconst clickOutsideListener = ref<SearchBarState['clickOutsideListener']>({\n fn: null as any,\n});\n\nonMounted(() => {\n const listener = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target && !target.closest('[data-search-bar]')) {\n showDropdown.value = false;\n }\n };\n clickOutsideListener.value = {\n fn: listener,\n };\n document.addEventListener('mousedown', listener);\n});\nonUnmounted(() => {\n if (clickOutsideListener.value.fn) {\n document.removeEventListener('mousedown', clickOutsideListener.value.fn);\n }\n});\nconst placeholder = computed(() => {\n return props.placeholder || 'Search products...';\n});\nconst minLength = computed(() => {\n return props.minSearchLength !== undefined ? props.minSearchLength : 3;\n});\nconst maxResults = computed(() => {\n return props.maxResults !== undefined ? props.maxResults : 8;\n});\nconst noImageUrl = computed(() => {\n return props.noImageUrl || '';\n});\n\n// Sync composable search results into local mapped results + dropdown state\nwatch(searchResults, (rawItems) => {\n const mapped: SearchBarResult[] = [];\n const limit = maxResults.value;\n for (let i = 0; i < rawItems.length && i < limit; i++) {\n mapped.push(mapProductToResult(rawItems[i] as Product | Cluster));\n }\n results.value = mapped;\n showDropdown.value = mapped.length > 0 || searchTerm.value.length >= minLength.value;\n});\n\nwatch(searchItemsFound, (total) => {\n itemsFound.value = total;\n});\n\n// Parents bump `clearSignal` (e.g. on route change) to reset the input. We\n// also stop any in-flight search and close the dropdown.\nwatch(\n () => props.clearSignal,\n () => {\n searchTerm.value = '';\n results.value = [];\n showDropdown.value = false;\n search('');\n },\n);\n\nfunction getLabel(key: string, fallback: string): ReturnType<SearchBarState['getLabel']> {\n return _getLabel(props.labels, key, fallback);\n}\nfunction formatItemPrice(price: number): ReturnType<SearchBarState['formatItemPrice']> {\n if (props.formatPrice) {\n return props.formatPrice(price);\n }\n return _formatPrice(price || 0, { symbol: infra.currency ?? '€' });\n}\nfunction mapProductToResult(\n item: Product | Cluster\n): ReturnType<SearchBarState['mapProductToResult']> {\n const isCluster = 'clusterId' in item;\n const displayItem = isCluster ? (item as Cluster).defaultProduct : item;\n const id = isCluster ? (item as Cluster).clusterId : (item as Product).productId;\n const slug = item.slugs?.[0]?.value || '';\n // Prefer the consumer-supplied url builders from `configuration.urls`\n // (which can language-prefix, etc.); fall back to a plain path.\n const urls = (infra.configuration as { urls?: Record<string, unknown> } | undefined)?.urls;\n const builder = isCluster ? urls?.getClusterUrl : urls?.getProductUrl;\n const url =\n typeof builder === 'function'\n ? (builder as (it: unknown, lang?: string) => string)(item, infra.language)\n : isCluster\n ? '/cluster/' + id + '/' + slug\n : '/product/' + id + '/' + slug;\n return {\n id: id,\n name: item.names?.[0]?.value || 'Product',\n sku: item.sku || displayItem?.sku || '',\n price: displayItem?.price?.gross || 0,\n imageUrl: displayItem?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || '',\n url: url,\n isCluster: isCluster,\n } as SearchBarResult;\n}\nfunction handleInputChange(value: string): ReturnType<SearchBarState['handleInputChange']> {\n searchTerm.value = value;\n if (value.length < minLength.value) {\n results.value = [];\n showDropdown.value = false;\n return;\n }\n // Delegate debouncing + fetching to composable\n search(value);\n}\nfunction handleSubmit(e: any): ReturnType<SearchBarState['handleSubmit']> {\n e.preventDefault();\n const term = searchTerm.value.trim();\n if (props.onSubmit) {\n props.onSubmit(term);\n showDropdown.value = false;\n }\n}\nfunction handleResultClick(\n result: SearchBarResult\n): ReturnType<SearchBarState['handleResultClick']> {\n if (props.onResultClick) {\n props.onResultClick(result);\n }\n showDropdown.value = false;\n searchTerm.value = '';\n}\nfunction handleViewAllClick(): ReturnType<SearchBarState['handleViewAllClick']> {\n if (props.onViewAllClick) {\n props.onViewAllClick(searchTerm.value);\n }\n showDropdown.value = false;\n}\n</script>\n","<template>\n <div class=\"propeller-user-details space-y-6\">\n <template v-if=\"isMounted\">\n <div class=\"propeller-user-details__section propeller-user-details__section--personal rounded-[var(--radius-container)] bg-card text-card-foreground shadow-sm\">\n <div class=\"propeller-user-details__section-header p-6 pb-2\">\n <h3 class=\"propeller-user-details__section-title text-lg font-semibold\">{{ getLabel('personalInformation', 'Personal Information') }}</h3>\n </div>\n <div class=\"propeller-user-details__section-body p-6 pt-2 space-y-4\">\n <div class=\"propeller-user-details__field grid grid-cols-1 gap-1\">\n <label class=\"propeller-user-details__field-label text-xs font-semibold text-muted-foreground uppercase tracking-wide\"\n >{{ getLabel('nameLabel', 'Name') }}</label\n >\n <div class=\"propeller-user-details__field-value font-medium\">{{ getName() }}</div>\n </div>\n <div class=\"propeller-user-details__field grid grid-cols-1 gap-1\">\n <label class=\"propeller-user-details__field-label text-xs font-semibold text-muted-foreground uppercase tracking-wide\"\n >{{ getLabel('emailLabel', 'Email') }}</label\n >\n <div class=\"propeller-user-details__field-value font-medium\">{{ user?.email }}</div>\n </div>\n </div>\n </div>\n\n <template v-if=\"shouldShowCompanyInfo() && getActiveCompany()\">\n <div class=\"propeller-user-details__section propeller-user-details__section--company rounded-[var(--radius-container)] bg-card text-card-foreground shadow-sm\">\n <div class=\"propeller-user-details__section-header p-6 pb-2\">\n <h3 class=\"propeller-user-details__section-title text-lg font-semibold\">{{ getLabel('companyInformation', 'Company Information') }}</h3>\n </div>\n <div class=\"propeller-user-details__section-body p-6 pt-2 space-y-4\">\n <div class=\"propeller-user-details__field grid grid-cols-1 gap-1\">\n <label class=\"propeller-user-details__field-label text-xs font-semibold text-muted-foreground uppercase tracking-wide\"\n >{{ getLabel('companyNameLabel', 'Company Name') }}</label\n >\n <div class=\"propeller-user-details__field-value font-medium\">{{ getActiveCompany()?.name }}</div>\n </div>\n <template v-if=\"getActiveCompany()?.taxNumber\">\n <div class=\"propeller-user-details__field grid grid-cols-1 gap-1\">\n <label class=\"propeller-user-details__field-label text-xs font-semibold text-muted-foreground uppercase tracking-wide\"\n >{{ getLabel('taxNumberLabel', 'Tax Number') }}</label\n >\n <div class=\"propeller-user-details__field-value font-medium\">\n {{ getActiveCompany()?.taxNumber }}\n </div>\n </div>\n </template>\n\n <template v-if=\"getActiveCompany()?.cocNumber\">\n <div class=\"propeller-user-details__field grid grid-cols-1 gap-1\">\n <label class=\"propeller-user-details__field-label text-xs font-semibold text-muted-foreground uppercase tracking-wide\"\n >{{ getLabel('cocNumberLabel', 'CoC Number') }}</label\n >\n <div class=\"propeller-user-details__field-value font-medium\">\n {{ getActiveCompany()?.cocNumber }}\n </div>\n </div>\n </template>\n </div>\n </div>\n </template>\n\n <template v-if=\"shouldListCompanies() && getCompanies().length > 0\">\n <div class=\"propeller-user-details__section propeller-user-details__section--companies rounded-[var(--radius-container)] bg-card text-card-foreground shadow-sm\">\n <div class=\"propeller-user-details__section-header p-6 pb-2\">\n <h3 class=\"propeller-user-details__section-title text-lg font-semibold\">{{ getLabel('companies', 'Companies') }}</h3>\n </div>\n <div class=\"propeller-user-details__section-body p-6 pt-2\">\n <ul class=\"propeller-user-details__companies space-y-2\">\n <template :key=\"String(company.companyId)\" v-for=\"(company, index) in getCompanies()\">\n <li\n :data-active=\"getActiveCompany()?.companyId === company.companyId ? 'true' : 'false'\"\n :class=\"`propeller-user-details__company flex items-center gap-2 py-2 px-3 rounded-[var(--radius-control)] ${\n getActiveCompany()?.companyId === company.companyId\n ? 'bg-primary/10 font-semibold text-primary'\n : 'text-foreground'\n }`\"\n >\n <span class=\"propeller-user-details__company-name truncate\">{{ company.name }}</span>\n <template v-if=\"getActiveCompany()?.companyId === company.companyId\">\n <span class=\"propeller-user-details__company-badge text-xs bg-primary/20 text-primary px-2 py-0.5 rounded-full\"\n >{{ getLabel('activeBadge', 'Active') }}</span\n >\n </template>\n </li>\n </template>\n </ul>\n </div>\n </div>\n </template>\n\n <template v-if=\"shouldShowInvoiceAddress() || shouldShowDeliveryAddress()\">\n <div class=\"propeller-user-details__section propeller-user-details__section--addresses rounded-[var(--radius-container)] bg-card text-card-foreground shadow-sm\">\n <div class=\"propeller-user-details__section-header p-6 pb-2\">\n <h3 class=\"propeller-user-details__section-title text-lg font-semibold\">{{ getLabel('defaultAddresses', 'Default Addresses') }}</h3>\n </div>\n <div class=\"propeller-user-details__section-body p-6 pt-2\">\n <div class=\"propeller-user-details__addresses grid grid-cols-1 md:grid-cols-2 gap-6\">\n <template v-if=\"shouldShowInvoiceAddress()\">\n <div class=\"propeller-user-details__address-group space-y-3\" data-address=\"invoice\">\n <h4 class=\"propeller-user-details__address-title text-base font-bold\">{{ getLabel('invoiceAddress', 'Invoice Address') }}</h4>\n <template v-if=\"getDefaultInvoiceAddress()\">\n <div class=\"propeller-user-details__address-card bg-card p-4 rounded-[var(--radius-container)] shadow-sm border border-border\">\n <template v-if=\"getDefaultInvoiceAddress()?.company\">\n <div class=\"propeller-user-details__address-company font-bold text-lg mb-1\">\n {{ getDefaultInvoiceAddress()?.company }}\n </div>\n </template>\n\n <template v-if=\"getAddressName(getDefaultInvoiceAddress() as Address)\">\n <div class=\"propeller-user-details__address-name font-medium mb-1\">\n {{ getAddressName(getDefaultInvoiceAddress() as Address) }}\n </div>\n </template>\n\n <div class=\"propeller-user-details__address-line text-muted-foreground\">\n {{ getAddressLine1(getDefaultInvoiceAddress() as Address) }}\n </div>\n <div class=\"propeller-user-details__address-line text-muted-foreground\">\n {{ getAddressLine2(getDefaultInvoiceAddress() as Address) }}\n </div>\n <template v-if=\"getDefaultInvoiceAddress()?.country\">\n <div class=\"propeller-user-details__address-country text-muted-foreground\">\n {{ getCountryName(getDefaultInvoiceAddress()?.country || '') }}\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"!getDefaultInvoiceAddress()\">\n <p class=\"propeller-user-details__address-empty text-muted-foreground italic\">{{ getLabel('noInvoiceAddress', 'No invoice address found') }}</p>\n </template>\n </div>\n </template>\n\n <template v-if=\"shouldShowDeliveryAddress()\">\n <div class=\"propeller-user-details__address-group space-y-3\" data-address=\"delivery\">\n <h4 class=\"propeller-user-details__address-title text-base font-bold\">{{ getLabel('deliveryAddress', 'Delivery Address') }}</h4>\n <template v-if=\"getDefaultDeliveryAddress()\">\n <div class=\"propeller-user-details__address-card bg-card p-4 rounded-[var(--radius-container)] shadow-sm border border-border\">\n <template v-if=\"getDefaultDeliveryAddress()?.company\">\n <div class=\"propeller-user-details__address-company font-bold text-lg mb-1\">\n {{ getDefaultDeliveryAddress()?.company }}\n </div>\n </template>\n\n <template v-if=\"getAddressName(getDefaultDeliveryAddress() as Address)\">\n <div class=\"propeller-user-details__address-name font-medium mb-1\">\n {{ getAddressName(getDefaultDeliveryAddress() as Address) }}\n </div>\n </template>\n\n <div class=\"propeller-user-details__address-line text-muted-foreground\">\n {{ getAddressLine1(getDefaultDeliveryAddress() as Address) }}\n </div>\n <div class=\"propeller-user-details__address-line text-muted-foreground\">\n {{ getAddressLine2(getDefaultDeliveryAddress() as Address) }}\n </div>\n <template v-if=\"getDefaultDeliveryAddress()?.country\">\n <div class=\"propeller-user-details__address-country text-muted-foreground\">\n {{ getCountryName(getDefaultDeliveryAddress()?.country || '') }}\n </div>\n </template>\n </div>\n </template>\n\n <template v-if=\"!getDefaultDeliveryAddress()\">\n <p class=\"propeller-user-details__address-empty text-muted-foreground italic\">{{ getLabel('noDeliveryAddress', 'No delivery address found') }}</p>\n </template>\n </div>\n </template>\n </div>\n </div>\n </div>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref } from 'vue';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nimport { Contact, Customer, Company, Address } from '@propeller-commerce/propeller-sdk-v2';\nimport { getCountryName as _getCountryName, getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface UserDetailsProps {\n /** The currently logged in user (Contact or Customer). Resolved from `<PropellerProvider>` when omitted. */\n user?: Contact | Customer;\n\n /**\n * The currently active company\n */\n activeCompany: Company | null;\n\n /**\n * Display basic company information for the default company if the user is Contact\n * @default true\n */\n showCompanyInfo?: boolean;\n\n /**\n * Display a list of all companies if the user is Contact\n * @default false\n */\n listAllContactCompanies?: boolean;\n\n /**\n * Display details of the user's default invoice address\n * @default true\n */\n showDefaultInvoiceAddress?: boolean;\n\n /**\n * Display details of the user's default delivery address\n * @default false\n */\n showDefaultDeliveryAddress?: boolean;\n\n /** Country code-to-name mapping for address display */\n countries?: {\n code: string;\n name: string;\n }[];\n\n /** Translated labels keyed by the slugs used inside the component (see\n * `getLabel` calls). Missing keys fall back to the English defaults. */\n labels?: Record<string, string>;\n}\ninterface UserDetailsState {\n isMounted: boolean;\n isContact: () => boolean;\n getName: () => string;\n getActiveCompany: () => Company | null;\n getCompanies: () => Company[];\n getAllAddresses: () => Address[];\n getDefaultInvoiceAddress: () => Address | null;\n getDefaultDeliveryAddress: () => Address | null;\n getAddressName: (addr: Address) => string;\n getAddressLine1: (addr: Address) => string;\n getAddressLine2: (addr: Address) => string;\n getCountryName: (code: string) => string;\n shouldShowCompanyInfo: () => boolean;\n shouldListCompanies: () => boolean;\n shouldShowInvoiceAddress: () => boolean;\n shouldShowDeliveryAddress: () => boolean;\n}\n\nconst props = withDefaults(defineProps<UserDetailsProps>(), {\n showCompanyInfo: true,\n listAllContactCompanies: false,\n showDefaultInvoiceAddress: true,\n showDefaultDeliveryAddress: false,\n});\n// Resolve user from the propellerVue plugin scope when the consumer doesn't\n// pass :user explicitly (the documented contract — AccountView wires only\n// labels/activeCompany).\nconst infra = useInfraProps(props);\n// Local `user` ref overrides Vue's prop auto-exposure so the template binds\n// to the provider-fallback value rather than the raw (possibly undefined)\n// prop.\nconst user = computed(() => (infra.user ?? props.user) as Contact | Customer | undefined);\nconst isMounted = ref<UserDetailsState['isMounted']>(false);\n\nonMounted(() => {\n isMounted.value = true;\n});\n\nfunction isContact(): ReturnType<UserDetailsState['isContact']> {\n return !!user.value && 'company' in user.value;\n}\nfunction getName(): ReturnType<UserDetailsState['getName']> {\n if (user.value && user.value.firstName) {\n return [user.value.firstName, user.value.lastName].filter(Boolean).join(' ');\n }\n return getLabel('userFallback', 'User');\n}\nfunction getActiveCompany(): ReturnType<UserDetailsState['getActiveCompany']> {\n return isContact() ? props.activeCompany : null;\n}\nfunction getCompanies(): ReturnType<UserDetailsState['getCompanies']> {\n if (!isContact()) return [];\n const contact = user.value as Contact;\n const companiesResponse = contact.companies;\n if (companiesResponse?.items && companiesResponse.items.length > 0) {\n return companiesResponse.items;\n }\n const defaultCompany = contact.company;\n if (defaultCompany) {\n return [defaultCompany];\n }\n return [];\n}\nfunction getAllAddresses(): ReturnType<UserDetailsState['getAllAddresses']> {\n if (isContact()) {\n const company = getActiveCompany();\n return company?.addresses || [];\n }\n const customer = user.value as Customer;\n return customer?.addresses || [];\n}\nfunction getDefaultInvoiceAddress(): ReturnType<UserDetailsState['getDefaultInvoiceAddress']> {\n const addresses = getAllAddresses();\n return (\n addresses.find((addr: Address) => addr.type === 'invoice' && addr.isDefault === 'Y') ?? null\n );\n}\nfunction getDefaultDeliveryAddress(): ReturnType<UserDetailsState['getDefaultDeliveryAddress']> {\n const addresses = getAllAddresses();\n return (\n addresses.find((addr: Address) => addr.type === 'delivery' && addr.isDefault === 'Y') ?? null\n );\n}\nfunction getAddressName(addr: Address): ReturnType<UserDetailsState['getAddressName']> {\n const parts = [addr.firstName, addr.middleName, addr.lastName].filter(Boolean);\n return parts.join(' ');\n}\nfunction getAddressLine1(addr: Address): ReturnType<UserDetailsState['getAddressLine1']> {\n const parts = [addr.street, addr.number, addr.numberExtension].filter(Boolean);\n return parts.join(' ');\n}\nfunction getAddressLine2(addr: Address): ReturnType<UserDetailsState['getAddressLine2']> {\n const parts = [addr.postalCode, addr.city].filter(Boolean);\n return parts.join(' ');\n}\nfunction getCountryName(code: string): ReturnType<UserDetailsState['getCountryName']> {\n return _getCountryName(code, props.countries);\n}\nfunction getLabel(key: string, fallback: string): string {\n return _getLabel(props.labels, key, fallback);\n}\nfunction shouldShowCompanyInfo(): ReturnType<UserDetailsState['shouldShowCompanyInfo']> {\n return props.showCompanyInfo !== false && isContact();\n}\nfunction shouldListCompanies(): ReturnType<UserDetailsState['shouldListCompanies']> {\n return props.listAllContactCompanies === true && isContact();\n}\nfunction shouldShowInvoiceAddress(): ReturnType<UserDetailsState['shouldShowInvoiceAddress']> {\n return props.showDefaultInvoiceAddress !== false;\n}\nfunction shouldShowDeliveryAddress(): ReturnType<UserDetailsState['shouldShowDeliveryAddress']> {\n return props.showDefaultDeliveryAddress === true;\n}\n</script>\n"],"names":["provide","inject","ref","isContact","isCustomer","createServices","AddressType","YesNo","user","ok","err","CartService","CartStatus","cart","getAddresses","Gender","CartAddressType","unref","computed","PurchaseRole","resultCart","addedItem","fetchActiveCart","CrossupsellType","getDefaultInvoiceAddress","getDefaultDeliveryAddress","PaymentStatuses","collectAttributeValues","filterProductsBySelections","index","attributeNameMatches","getAttributeDisplayName","extractAttributeValues","watch","OrderSearchFields","markRaw","OrderItemClass","ProductSortField","ProductSearchableField","ProductStatus","SortOrder","attributes","useInfraProps","usePropellerDeps","reactive","PropellerScopeKey","_renderSlot","_getLabel","_createElementBlock","_openBlock","_hoisted_2","_createElementVNode","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_14","_Fragment","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","DefaultLoginForm","onMounted","onUnmounted","_hoisted_7","_renderList","_normalizeClass","_hoisted_11","_hoisted_13","_createBlock","_resolveDynamicComponent","_unref","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_1","DefaultProductPrice","_getProductImageUrl","_getProductSku","_formatPrice","_formatSurcharge","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","_hoisted_35","_hoisted_36","_getCountryName","_hoisted_37","_hoisted_38","_hoisted_40","_hoisted_41","_hoisted_43","_hoisted_44","_hoisted_46","_hoisted_48","_hoisted_50","_hoisted_51","_hoisted_52","_hoisted_53","_hoisted_55","_hoisted_57","_hoisted_59","_hoisted_60","_hoisted_61","_hoisted_62","_hoisted_64","_hoisted_65","_hoisted_66","_hoisted_67","_hoisted_68","_hoisted_69","_hoisted_70","_hoisted_72","_hoisted_73","_hoisted_74","_hoisted_75","_hoisted_77","_hoisted_78","_hoisted_80","_hoisted_82","_hoisted_84","_hoisted_85","_hoisted_86","_hoisted_88","_hoisted_89","_hoisted_91","_hoisted_92","_hoisted_94","_hoisted_95","_hoisted_97","_hoisted_99","_hoisted_101","_hoisted_102","_hoisted_103","_hoisted_104","_hoisted_106","_hoisted_108","_hoisted_110","_hoisted_111","_hoisted_112","_hoisted_114","_hoisted_115","_hoisted_116","_hoisted_117","_hoisted_118","DefaultAddressCard","_getLocalizedValue","getLabel","formatSurcharge","DefaultItemStock","DefaultProductSurcharges","_hoisted_39","_hoisted_42","DefaultCartItem","DefaultCartBonusItemsImpl","_withCtx","getLanguageString","mediaItems","DefaultProductImage","DefaultProductBadges","DefaultAddToFavorite","_getClusterSku","_getClusterImageUrl","ItemStock","AttributeType","_normalizeStyle","buildClusterJsonLd","safeJsonStringify","_createVNode","AddToCart","items","DefaultFavoriteListItem","DefaultGridPagination","getProductImageUrl","getClusterImageUrl","_createTextVNode","_hoisted_45","_hoisted_47","_hoisted_49","buildItemListJsonLd","DefaultOrderItemCard","OrderSortField","OrderType","BundleCondition","DefaultAddToCart","ProductPriceDisplay","DefaultProductCard","DefaultClusterCard","DefaultProductBundles","DefaultProductBulkPrices","buildProductJsonLd","nextTick","DefaultProductDescription","DefaultProductSpecifications","DefaultProductDownloads","DefaultProductVideos","_hoisted_54","_hoisted_56","_hoisted_58"],"mappings":"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"}