{"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/shared/utils/listingUserId.ts","../src/composables/vue/useProductSearch.ts","../src/composables/vue/useQuickOrder.ts","../src/composables/vue/useMachines.ts","../src/composables/shared/utils/machineLanguage.ts","../src/composables/vue/useSpareParts.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/composables/shared/utils/cn.ts","../src/components/LoginForm.vue","../src/components/AccountIconAndMenu.vue","../src/components/ActionCode.vue","../src/components/CartBonusItems.vue","../src/components/AddToCart.vue","../src/components/AddToFavorite.vue","../src/components/AddressCard.vue","../src/components/AddressSelector.vue","../src/composables/shared/utils/radioGroup.ts","../src/composables/shared/utils/preselect.ts","../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/GridFiltersPanel.vue","../src/components/GridToolbar.vue","../src/components/ItemListJsonLd.vue","../src/components/LoginToOrderButton.vue","../src/components/ItemsOverview.vue","../src/components/ProductCard.vue","../src/components/ProductGrid.vue","../src/components/MachineGrid.vue","../src/components/MenuLevel.vue","../src/components/Menu.vue","../src/components/OrderActions.vue","../src/components/OrderBonusItems.vue","../src/components/OrderList.vue","../src/components/QuickOrder.vue","../src/components/OrderShipments.vue","../src/components/PriceToggle.vue","../src/components/ProductBundles.vue","../src/components/ProductDescription.vue","../src/components/ProductGallery.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   * Render arbitrary content directly below each card's product name. Receives\n   * the product as a prop; cascades to every ProductCard. Lets hosts surface\n   * extra per-product info (e.g. package descriptions) across the whole grid\n   * without swapping the entire card.\n   */\n  belowNameComponent?: 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, MagicTokenService } 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  MagicToken,\n  MagicTokenCreateInput,\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  magicLogin: (token: string) => Promise<Result<AuthSuccess, string>>;\n  createMagicToken: (input: MagicTokenCreateInput) => Promise<Result<MagicToken, 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\n/**\n * A viewer search/pagination input (contactPAConfigInput /\n * contactCompaniesSearchInput) must be a GraphQL *input object*. A truthiness\n * guard is not enough: an empty array `[]` is truthy yet the backend rejects it\n * (\"Expected type ContactPurchaseAuthorizationConfigSearchInput to be an\n * object\"). Only spread values that are genuine non-array objects so a host that\n * configures `[]` (or anything non-object) is safely omitted instead of erroring\n * the whole viewer query.\n */\nconst isViewerSearchInput = (v: unknown): v is Record<string, unknown> =>\n  typeof v === 'object' && v !== null && !Array.isArray(v);\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        // Contact-scoped pagination inputs. Kept out unless the host supplies a\n        // real input object — see isViewerSearchInput (an empty array `[]` is\n        // truthy but invalid and 400s the whole viewer query).\n        ...(isViewerSearchInput(configuration?.contactPAConfigInput) && {\n          contactPAConfigInput: configuration.contactPAConfigInput,\n        }),\n        ...(isViewerSearchInput(configuration?.contactCompaniesSearchInput) && {\n          contactCompaniesSearchInput: configuration.contactCompaniesSearchInput,\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  // ── Magic-token login ───────────────────────────────────────────────────────\n  // Passwordless: exchange a backend-issued magic token for a session, then run\n  // the IDENTICAL tail as login() (Bearer + getViewer). The token is\n  // single-use/expiring and typically arrives in a deep link (ERP / punchout\n  // handoff). See MagicTokenService.magicTokenLogin.\n\n  async function magicLogin(token: string): Promise<Result<AuthSuccess, string>> {\n    loading.value = true;\n    error.value = null;\n    try {\n      const loginResult = await new MagicTokenService(graphqlClient).magicTokenLogin(token);\n      const session = loginResult?.session;\n      const accessToken = session?.accessToken;\n      const refreshToken = session?.refreshToken;\n      const expiresAt = session?.expirationTime;\n      if (accessToken) {\n        // Mirrors login(): setAccessToken here (the host persists the token). NB\n        // this is the un-hardened Vue path — the React package uses an in-memory\n        // header only. Fold into the pending Vue localStorage-hardening pass.\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        // See isViewerSearchInput — an empty array `[]` is truthy but 400s the viewer.\n        ...(isViewerSearchInput(configuration?.contactPAConfigInput) && {\n          contactPAConfigInput: configuration.contactPAConfigInput,\n        }),\n        ...(isViewerSearchInput(configuration?.contactCompaniesSearchInput) && {\n          contactCompaniesSearchInput: configuration.contactCompaniesSearchInput,\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 : 'Magic-token login failed';\n      error.value = msg;\n      return err(msg);\n    } finally {\n      loading.value = false;\n    }\n  }\n\n  // ── Create magic token ──────────────────────────────────────────────────────\n  // Issue a magic token for a contact/customer (authenticated call). Returns the\n  // MagicToken whose `id` is embedded in a magic-login link. The real caller is\n  // punchout link-generation; exposed here as the auth-adjacent capability.\n\n  async function createMagicToken(input: MagicTokenCreateInput): Promise<Result<MagicToken, string>> {\n    loading.value = true;\n    error.value = null;\n    try {\n      const token = await new MagicTokenService(graphqlClient).createMagicToken(input);\n      return ok(token);\n    } catch (e: unknown) {\n      const msg = e instanceof Error ? e.message : 'Failed to create magic token';\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, magicLogin, createMagicToken, 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, watch, type Ref, type ComputedRef } from 'vue';\nimport { CartStatus, CrossupsellType } 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  isCheckoutAllowed,\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  /**\n   * Adds several products in one call, sequentially, threading the resolved\n   * cart id from each add into the next. Stops at the first failure.\n   */\n  addItems: (\n    items: AddItemOptions[],\n  ) => Promise<Result<{ cart: Cart; items: (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  // The caller's cart id has to keep winning AFTER setup. This used to unwrap\n  // it once into a plain ref, so a component created before the cart resolved —\n  // the header's cart sidebar renders on the first paint of every page — held\n  // '' forever, and every id-guarded action failed silently: \"Request\n  // authorization\" rendered enabled, fired, and returned `err('No cart')`\n  //. Computed, so a ref passed by the host stays reactive and a\n  // plain string still works.\n  const createdCartId = ref('');\n  const cartId = computed<string>(() => unref(options.cartId) || createdCartId.value);\n  const loading = ref(false);\n  const error = ref<string | null>(null);\n  let notesTimers: Record<string, ReturnType<typeof setTimeout>> = {};\n\n  // Active company for the PAC lookup: the switcher selection, else the\n  // contact's own company. Matching on the raw option found no config for a\n  // contact acting for their own company, so every cart read as within limit.\n  const resolvedCompanyIdRef = computed<number | undefined>(() => {\n    const u = user.value;\n    return (\n      companyIdRef.value ??\n      (u && 'contactId' in u ? (u as Contact).company?.companyId : undefined)\n    );\n  });\n\n  // Hydrate a cart the composable was only given the id of. `checkoutAllowed`\n  // has to weigh a total against the purchaser's limit, and with no cart it\n  // answered \"allowed\" — so an app gating its own checkout button on this let\n  // an over-limit purchaser through while the library's own UI showed\n  // \"Request authorization\".\n  watch(\n    [() => cartId.value, () => cart.value],\n    async ([id, current]: [string, Cart | null]) => {\n      if (!graphqlClient || !id || current) return;\n      try {\n        const fetched = await createServices(graphqlClient).cart.getCart({\n          cartId: id,\n          imageSearchFilters: configuration.imageSearchFiltersGrid,\n          imageVariantFilters: configuration.imageVariantFiltersSmall,\n          language: languageRef.value || configuration.language || 'NL',\n        });\n        if (fetched) cart.value = fetched as Cart;\n      } catch {\n        // Leave `cart` null — `checkoutAllowed` then reports `false`, which\n        // holds checkout rather than opening it on a failed read.\n      }\n    },\n    { immediate: true }\n  );\n\n  // Fails CLOSED while a seeded cart is still loading: with nothing to weigh,\n  // the honest answer is \"not yet\". The predicate reads both plain and\n  // underscore-prefixed SDK shapes.\n  const checkoutAllowed = computed<boolean>(() => {\n    if (cartId.value && !cart.value) return false;\n    return isCheckoutAllowed(user.value, resolvedCompanyIdRef.value, cart.value);\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; createdCartId.value = c.cartId; onCartCreated?.(c); },\n    };\n    const resolved = await initCart(config);\n    cart.value = resolved;\n    createdCartId.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; createdCartId.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; createdCartId.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  /**\n   * Adds several products in one call, sequentially, threading each add's\n   * resolved cart id into the next so the first may create the cart and the\n   * rest land in it. Stops at the first failure and returns that error rather\n   * than continuing into a half-filled basket.\n   *\n   * \"Add this whole set to the basket\" is a normal requirement (kits, re-order,\n   * recipe packs) and there was no bulk call, so every consumer wrote the loop.\n   */\n  async function addItems(\n    items: AddItemOptions[],\n  ): Promise<Result<{ cart: Cart; items: (CartMainItem | null)[] }, string>> {\n    const added: (CartMainItem | null)[] = [];\n    let lastCart: Cart | null = null;\n    for (const item of items) {\n      const result = await addItem({ createCart: true, ...item });\n      if (!result.ok) return err(result.error);\n      lastCart = result.data.cart;\n      added.push(result.data.item);\n    }\n    if (!lastCart) return err('No items to add');\n    return ok({ cart: lastCart, items: added });\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          createdCartId.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 resolvedCompanyId = resolvedCompanyIdRef.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          // Switcher selection wins; the contact's default company is the fallback.\n          ...(resolvedCompanyId !== undefined && { companyId: resolvedCompanyId }),\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, addItems, 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   * Order status to set. When omitted it defaults to `'REQUEST'` in quote mode\n   * and `'NEW'` otherwise. Pass `'UNFINISHED'` for an order awaiting an external\n   * payment (PSP) whose final status the payment webhook sets later. Any backend\n   * status string is accepted.\n   */\n  orderStatus?: 'NEW' | 'REQUEST' | 'UNFINISHED' | (string & {});\n  /**\n   * Whether this placement *finalizes* the order — i.e. sends the order\n   * confirmation email, fires the confirm event, attaches the order PDF, and\n   * clears the cart. Defaults to `true`.\n   *\n   * Set this to `false` for an order awaiting an external payment (e.g.\n   * `'UNFINISHED'` orders handed off to a PSP). The confirmation/cart deletion\n   * should then happen when the payment is confirmed (the PSP webhook), not at\n   * placement — otherwise the shopper is emailed and the cart cleared before\n   * they've paid.\n   */\n  finalizeOrder?: boolean;\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    // Optional fields are omitted when blank: the API validates them whenever\n    // they are present and rejects an empty string (e.g. `email must be an\n    // email`), which a delivery address legitimately leaves empty.\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      ...(addr.company && { company: addr.company }),\n      ...(addr.gender && { gender: addr.gender }),\n      ...(addr.middleName && { middleName: addr.middleName }),\n      ...(addr.number && { number: addr.number }),\n      ...(addr.numberExtension && { numberExtension: addr.numberExtension }),\n      ...(addr.country && { country: addr.country }),\n      ...(addr.email && { email: addr.email }),\n      ...(addr.mobile && { mobile: addr.mobile }),\n      ...(addr.phone && { phone: addr.phone }),\n      ...(addr.notes && { notes: addr.notes }),\n      ...(addr.icp && { 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.orderStatus ?? (opts.isQuoteMode ? 'REQUEST' : 'NEW');\n      // Whether this placement finalizes the order. Default `true`; pass\n      // `finalizeOrder: false` for a PSP order awaiting payment so the\n      // confirmation email/event/PDF and cart deletion fire later (from the\n      // payment webhook) instead of at placement.\n      const finalizeOrder = opts.finalizeOrder ?? true;\n      // Quotes never send the order-confirmation email/PDF; a PSP-pending order\n      // also suppresses them until paid.\n      const sendConfirmation = finalizeOrder && !opts.isQuoteMode;\n\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: sendConfirmation,\n        addPDFAttachment: sendConfirmation,\n        triggerOrderSendConfirmEvent: sendConfirmation,\n        deleteCart: finalizeOrder,\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: string;\n  name: string;\n  displayType: string;\n  priority: string;\n  displayName: string;\n  availableValues: string[];\n  selectedValue: string;\n  disabled: boolean;\n}\n\n/**\n * Sorted setting carrying `name`/`id` aliases mapped from the SDK's\n * `attributeName`/`uuid` (the scalar `name`/`id` were removed in SDK 0.14.0).\n */\ntype SortedSetting = ClusterConfigSetting & { name: string; id: string };\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(): SortedSetting[] {\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      .map((s: ClusterConfigSetting): SortedSetting => ({ ...s, name: s.attributeName, id: s.uuid }));\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\n/** What a favorite-list mutation did — see `onListChanged`. */\nexport interface FavoriteListChange {\n  action: 'created' | 'updated' | 'deleted';\n  listId?: string | number;\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  /**\n   * Called after a list mutation succeeds.\n   *\n   * The `change` argument is optional so existing zero-argument callbacks keep\n   * working, but without it a host cannot tell a create from a delete — which\n   * makes the composable useless for analytics, audit trails or optimistic UI\n   * that needs to know WHAT happened rather than merely THAT something did.\n   */\n  onListChanged?: (change?: FavoriteListChange) => 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?.({ action: 'updated', listId, name: data.name, isDefault: data.isDefault }); 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?.({ action: 'updated', listId, name: data.name, isDefault: data.isDefault });\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?.({ action: 'deleted', listId, name: list.name }); 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?.({ action: 'deleted', listId, name: list.name });\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?.({ action: 'created', name, isDefault }); 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?.({ action: 'created', listId: created?.id, name, isDefault });\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  // Every translation, not just the active language — see `mapCategory`.\n  names: Array<{ value: string; language: string }>;\n  slugs: Array<{ value: string; language: 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      names { value language }\n      slugs { value language }\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 the first translation that\n * exists.\n *\n * That fallback only works because the query asks for `names`/`slugs` with NO\n * language argument, so every translation comes back. It used to filter\n * server-side — `names(language: $language)` — which meant a category with no\n * translation in the active language returned an EMPTY array, `[0]` was\n * `undefined` too, and the row rendered with a blank label and an empty slug:\n * invisible and unclickable. An untranslated category now falls back to the\n * name it does have rather than disappearing from the menu.\n */\nfunction mapCategory(raw: MenuCategoryRaw, language: string): MenuCategory {\n  const nameEntry = raw.names?.find(n => n.language === language) ?? raw.names?.[0];\n  const slugEntry = raw.slugs?.find(s => s.language === language) ?? raw.slugs?.[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) {\n          category(categoryId: $categoryId) {\n            categoryId\n            hidden\n            names { value language }\n            slugs { value language }\n            ${buildCategoriesQuery(depth)}\n          }\n        }\n      `;\n      const variables: Record<string, unknown> = { categoryId: rootCategoryId };\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  /**\n   * Seed the search/filter form on mount — e.g. rehydrated from the URL query\n   * so a bookmarked/shared filtered view restores. The consumer owns the fetch.\n   */\n  initialSearchForm?: OrderSearchForm;\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>(options.initialSearchForm ?? {});\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  /**\n   * Scope the product fetch to specific orderlist IDs (e.g. a chosen B2B\n   * contract). Overrides the default resolution of all the company's orderlists.\n   */\n  orderlistIds?: Ref<number[] | undefined>;\n  /**\n   * Apply the orderlist filter. Defaults to `true`; set `false` to browse\n   * unscoped (full catalogue) for an authenticated user without a contract.\n   */\n  applyOrderlists?: Ref<boolean | 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      // Explicit options.orderlistIds (e.g. a chosen contract) take precedence\n      // and skip the auto-resolution of all company orderlists. When the caller\n      // sets applyOrderlists:false, disable orderlist scoping entirely.\n      const explicitOrderlistIds = options.orderlistIds?.value;\n      let orderlistIds: number[] = [];\n      let applyOrderlists = true;\n      if (explicitOrderlistIds && explicitOrderlistIds.length > 0) {\n        orderlistIds = explicitOrderlistIds;\n        applyOrderlists = options.applyOrderlists?.value !== false;\n      } else if (options.applyOrderlists?.value === false) {\n        applyOrderlists = false;\n      } else 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,\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.attributeName\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 * Resolve the `userId` a catalog listing query should be scoped to.\n *\n * Logged in: the contact's or customer's own id. Logged out: the channel's\n * ANONYMOUS user, supplied by the host as `configuration.anonymousUserId`.\n *\n * Sending nothing for an anonymous visitor is not equivalent to sending the\n * anonymous user. The backend applies assortment rules — negative order lists\n * in particular — per user, so an unscoped query returns products the visitor\n * is not supposed to see. The host's SSR seed already scopes to the channel's\n * anonymous user; without this the client refetch asked a differently-scoped\n * question and quietly replaced the correct server-rendered list.\n *\n * The id is resolved server-side (only the server can reach the channel) and\n * seeded into `configuration`, the same route `baseCategoryId` takes since\n * No module guesses it.\n */\nexport function resolveListingUserId(\n  user: { contactId?: number; customerId?: number } | null | undefined,\n  configuration?: { anonymousUserId?: number } | null\n): number | undefined {\n  if (user && 'contactId' in user) return user.contactId;\n  if (user && 'customerId' in user) return user.customerId;\n  return configuration?.anonymousUserId;\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  AttributeResultSearchInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { usePagination } from '../shared/usePagination';\nimport { createServices, buildInventoryFilter, type Availability } from '@propeller-commerce/propeller-v2-core-ui';\nimport { resolveListingUserId } from '../shared/utils/listingUserId';\n\n/** `productTrackAttributes` → the query's attribute input. Undefined when empty. */\nfunction buildAttributeInput(names?: string[]): AttributeResultSearchInput | undefined {\n  if (!names || names.length === 0) return undefined;\n  return { attributeDescription: { names } } as AttributeResultSearchInput;\n}\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  /** Scope the product fetch to specific orderlist IDs (e.g. a chosen B2B contract). */\n  orderlistIds?: Ref<number[] | undefined>;\n  /**\n   * Apply the orderlist filter. Defaults to `true` when `orderlistIds` is\n   * non-empty, `false` otherwise — so an authenticated user without a contract\n   * still sees the full catalogue.\n   */\n  applyOrderlists?: Ref<boolean | undefined>;\n  /**\n   * Attribute names to request per product, e.g. `['MPN']`. Unset returns the\n   * first page of ALL attributes (12 per product), so products with more than\n   * 12 silently lose the rest — name what you render.\n   */\n  productTrackAttributes?: Ref<string[] | undefined>;\n  textFilters?: Ref<ProductTextFilterInput[] | undefined>;\n  priceFilterMin?: Ref<number | undefined>;\n  priceFilterMax?: Ref<number | undefined>;\n  /**\n   * Stock selection to filter by. `'all'` or unset sends no stock filter.\n   * Filtering happens server-side, so `itemsFound` and the page count\n   * describe the filtered set.\n   */\n  availability?: Ref<Availability | undefined>;\n  /** Minimum stock quantity for the `'in-stock'` selection. */\n  minStock?: 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    /** The channel's anonymous user — logged-out listings are scoped to it. */\n    anonymousUserId?: 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 availabilityRef = options.availability ?? ref<Availability | undefined>(undefined);\n  const minStockRef = options.minStock ?? 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    // Case-insensitive: PIM language casing is not guaranteed to match the\n    // storefront's. An exact compare drops EVERY product from the grid when the\n    // two disagree — a blank listing rather than a blank field.\n    const target = lang.toUpperCase();\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 || '').toUpperCase() === target);\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      const inventoryFilter = buildInventoryFilter(availabilityRef.value, minStockRef.value);\n\n      // Resolve user IDs\n      const user = userRef.value;\n      const userId = resolveListingUserId(user, configuration);\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      // Orderlist (contract) scoping. When orderlistIds are supplied, apply them\n      // (unless explicitly disabled); otherwise send applyOrderlists:false so an\n      // authenticated user without a contract still sees the full catalogue.\n      // `applyOrderlists`/`orderlistIds` are accepted by the backend but not yet\n      // present on the SDK's CategoryProductSearchInput type — cast to include them.\n      const orderlistIdsVal = options.orderlistIds?.value;\n      const orderlistScope =\n        orderlistIdsVal && orderlistIdsVal.length > 0\n          ? {\n              applyOrderlists: options.applyOrderlists?.value !== false,\n              orderlistIds: orderlistIdsVal,\n            }\n          : { applyOrderlists: false };\n\n      const 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        ...(inventoryFilter && { inventory: inventoryFilter }),\n        ...(sortInputs.length && { sortInputs }),\n        ...(companyIdRef.value && { companyId: companyIdRef.value }),\n        ...(userId !== undefined && { userId }),\n        ...orderlistScope,\n      } as CategoryProductSearchInput & {\n        applyOrderlists?: boolean;\n        orderlistIds?: number[];\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 attributeInput = buildAttributeInput(options.productTrackAttributes?.value);\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        ...(attributeInput && { attributeResultSearchInput: attributeInput }),\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 lang = languageRef.value || 'NL';\n        // Route the autosuggest through the SAME category term-search the grid\n        // uses (`getCategory` over the base category), NOT the flat\n        // `getProducts` search. Orderlist (contract) scoping is honoured by the\n        // `category.products` resolver but NOT by the flat `products` resolver —\n        // sending orderlistIds on a ProductSearchInput is silently ignored\n        // server-side, so the preview leaked the full catalogue while the grid\n        // (and the submitted results) stayed contract-scoped. Using the category\n        // path makes the preview and the grid agree.\n        const service = createServices(graphqlClient).category;\n        const catId = configuration?.baseCategoryId ?? 0;\n        if (!catId) {\n          searchResults.value = [];\n          searchItemsFound.value = 0;\n          return;\n        }\n\n        // When orderlistIds are supplied, apply them (unless explicitly\n        // disabled); otherwise send applyOrderlists:false so an authed user\n        // without a contract still previews the full catalogue.\n        const searchOrderlistIds = options.orderlistIds?.value;\n        const orderlistScope =\n          searchOrderlistIds && searchOrderlistIds.length > 0\n            ? {\n                applyOrderlists: options.applyOrderlists?.value !== false,\n                orderlistIds: searchOrderlistIds,\n              }\n            : { applyOrderlists: false };\n\n        const user = userRef.value;\n        const userId = resolveListingUserId(user, configuration);\n        const contactId: number | undefined =\n          user && 'contactId' in user ? (user as Contact).contactId : undefined;\n        const customerId: number | undefined =\n          user && 'customerId' in user ? (user as Customer).customerId : undefined;\n\n        const inventoryFilter = buildInventoryFilter(availabilityRef.value, minStockRef.value);\n\n        const categoryProductSearchInput = {\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          hidden: false,\n          ...(inventoryFilter && { inventory: inventoryFilter }),\n          term,\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          sortInputs: [{ field: ProductSortField.RELEVANCE, order: SortOrder.DESC }],\n          ...(companyIdRef.value && { companyId: companyIdRef.value }),\n          ...(userId !== undefined && { userId }),\n          ...orderlistScope,\n        } as CategoryProductSearchInput & {\n          applyOrderlists?: boolean;\n          orderlistIds?: number[];\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 attributeInput = buildAttributeInput(options.productTrackAttributes?.value);\n\n        const variables: CategoryQueryVariables = {\n          categoryId: catId,\n          language: lang,\n          categoryProductSearchInput,\n          priceCalculateProductInput,\n          imageSearchFilters: configuration?.imageSearchFiltersGrid,\n          imageVariantFilters: configuration?.imageVariantFiltersMedium as TransformationsInput,\n          ...(attributeInput && { attributeResultSearchInput: attributeInput }),\n        };\n\n        const response = await service.getCategory(variables);\n        const productsResponse = response?.products as ProductsResponse | undefined;\n        const rawItems = (productsResponse?.items ?? []) as (Product | Cluster)[];\n        // Drop products with no name in the active language — same as the grid\n        // (`fetchProducts`), so the preview shows EN results under EN instead of\n        // leaking other-language variants. Adjust the total by the dropped count.\n        const items = filterByLanguage(rawItems, lang);\n        const untranslated = rawItems.length - items.length;\n        const apiTotal = productsResponse?.itemsFound ?? rawItems.length;\n        searchResults.value = items;\n        searchItemsFound.value = Math.max(0, apiTotal - untranslated);\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      availabilityRef,\n      minStockRef,\n      sortFieldRef,\n      sortOrderRef,\n      pageSizeRef,\n      companyIdRef,\n      userRef,\n      pagination.currentPage,\n      // Joined: callers pass an array literal, so its identity changes each render.\n      () => (options.productTrackAttributes?.value ?? []).join(','),\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 * useQuickOrder (Vue) — bulk \"quick order\" pad: resolve SKUs/codes to products\n * and add them all to the cart in a single bulk mutation. Vue port of the\n * React composable; same seams (`Category` + `CartItemBulk`).\n *\n *  - `searchProducts(term)` — product typeahead for a row (the component\n *    debounces). Scoped to `configuration.baseCategoryId` via the category\n *    resolver, the same path ProductGrid uses: the flat `products` resolver\n *    ignores orderlist scoping server-side and would return products outside\n *    the user's catalogue. Without a base category it returns nothing rather\n *    than falling back. Returns [] on empty/error (a typeahead must not throw).\n *  - `submit(lines)` — resolve/create the cart (shared `initCart`) then bulk-add\n *    every line via `CartService.bulkUpdateCartItems` (`CartItemBulk`).\n *\n * All product/price data comes from the API — a row's typed code is only ever a\n * *search term*, never trusted for the product identity or price.\n */\n\nimport { ref, type Ref } from 'vue';\nimport {\n  ProductSearchableField,\n  ProductSortField,\n  ProductStatus,\n  SortOrder,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport type {\n  GraphQLClient,\n  Product,\n  Cluster,\n  Cart,\n  CategoryProductSearchInput,\n  CategoryQueryVariables,\n  MediaImageProductSearchInput,\n  TransformationsInput,\n  CartItemBulkInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport type { AnyUser } from '@propeller-commerce/propeller-v2-core-ui';\nimport {\n  createServices,\n  getProductImageUrl,\n  getClusterImageUrl,\n} from '@propeller-commerce/propeller-v2-core-ui';\nimport { initCart } from '../shared/utils/cartInit';\nimport { resolveListingUserId } from '../shared/utils/listingUserId';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\n/** A product resolved from a typed code — the shape a row fills in on select. */\nexport interface QuickOrderMatch {\n  productId: number;\n  clusterId?: number;\n  name: string;\n  sku: string;\n  netPrice: number;\n  grossPrice: number;\n  minQuantity: number;\n  imageUrl: string;\n}\n\n/** One line a caller submits to be added to the cart. */\nexport interface QuickOrderLine {\n  productId: number;\n  quantity: number;\n  clusterId?: number;\n  code?: string;\n}\n\nexport interface UseQuickOrderOptions {\n  graphqlClient: GraphQLClient;\n  /** The signed-in user (quick order is an authenticated feature). */\n  user?: AnyUser;\n  /** Active company id — scopes cart + pricing for B2B users. */\n  companyId?: number;\n  /** Language for search + cart queries. Defaults to `'NL'`. */\n  language?: string;\n  /** Max typeahead results per row. Defaults to 8. */\n  searchLimit?: number;\n  /** Tax zone for price calculation. Defaults to `'NL'`. */\n  taxZone?: string;\n  /** Orderlist (contract) ids to scope the catalogue by. */\n  orderlistIds?: number[];\n  /** Set `false` to ignore `orderlistIds`. Defaults to true when ids are given. */\n  applyOrderlists?: boolean;\n  /** Image filters + the base category the search is scoped to. */\n  configuration?: {\n    /** The channel's anonymous user — logged-out listings are scoped to it. */\n    anonymousUserId?: number;\n    imageSearchFiltersGrid?: MediaImageProductSearchInput;\n    imageVariantFiltersSmall?: TransformationsInput;\n    /** Catalog root. Without it the search returns nothing — see `searchProducts`. */\n    baseCategoryId?: number;\n  };\n  onCartCreated?: (cart: Cart) => void;\n  afterAddToCart?: (cart: Cart) => void;\n}\n\nexport interface QuickOrderSubmitResult {\n  success: boolean;\n  cart?: Cart;\n  added?: number;\n  error?: string;\n}\n\nexport interface UseQuickOrderReturn {\n  submitting: Ref<boolean>;\n  error: Ref<string | null>;\n  searchProducts: (term: string) => Promise<QuickOrderMatch[]>;\n  submit: (lines: QuickOrderLine[]) => Promise<QuickOrderSubmitResult>;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction toMatch(item: Product | Cluster, language?: string): QuickOrderMatch {\n  const isCluster = 'clusterId' in item;\n  const displayItem = isCluster ? (item as Cluster).defaultProduct : (item as Product);\n  const productId = (displayItem as Product)?.productId ?? (item as Product).productId;\n  const clusterId = isCluster ? (item as Cluster).clusterId : undefined;\n  const name =\n    (language && item.names?.find((n) => n.language === language)?.value) ||\n    item.names?.[0]?.value ||\n    'Product';\n  const netPrice = displayItem?.price?.net ?? 0;\n  const grossPrice = displayItem?.price?.gross ?? 0;\n  const minQuantity = Math.max(1, (displayItem as Product)?.minimumQuantity ?? 1);\n  const imageUrl = isCluster\n    ? getClusterImageUrl(item as Cluster)\n    : getProductImageUrl(item as Product);\n  return {\n    productId,\n    clusterId,\n    name,\n    sku: item.sku || displayItem?.sku || '',\n    netPrice,\n    grossPrice,\n    minQuantity,\n    imageUrl,\n  };\n}\n\n// ── Composable ────────────────────────────────────────────────────────────────\n\nexport function useQuickOrder(options: UseQuickOrderOptions): UseQuickOrderReturn {\n  const {\n    graphqlClient,\n    user,\n    companyId,\n    configuration = {},\n    onCartCreated,\n    afterAddToCart,\n  } = options;\n  const language = options.language || 'NL';\n  const searchLimit = options.searchLimit ?? 8;\n  const taxZone = options.taxZone || 'NL';\n  const { orderlistIds, applyOrderlists } = options;\n\n  const submitting = ref(false);\n  const error = ref<string | null>(null);\n\n  async function searchProducts(term: string): Promise<QuickOrderMatch[]> {\n    const trimmed = term.trim();\n    if (!trimmed || !graphqlClient) return [];\n    // No catalog root means no scope to search within. Fail closed rather than\n    // fall back to the flat resolver, which would leak the whole catalogue.\n    const catId = configuration.baseCategoryId ?? 0;\n    if (!catId) return [];\n    try {\n      const service = createServices(graphqlClient).category;\n\n      // Apply the contract when ids are supplied, else explicitly disable so an\n      // authenticated user without one still searches the full catalogue.\n      const orderlistScope =\n        orderlistIds && orderlistIds.length > 0\n          ? { applyOrderlists: applyOrderlists !== false, orderlistIds }\n          : { applyOrderlists: false };\n\n      const userId = resolveListingUserId(user, configuration);\n      const contactId: number | undefined =\n        user && 'contactId' in user ? (user as { contactId?: number }).contactId : undefined;\n      const customerId: number | undefined =\n        user && 'customerId' in user ? (user as { customerId?: number }).customerId : undefined;\n\n      const input = {\n        term: trimmed,\n        language,\n        page: 1,\n        offset: searchLimit,\n        statuses: [ProductStatus.A, ProductStatus.P, ProductStatus.T, ProductStatus.S],\n        hidden: false,\n        sortInputs: [{ field: ProductSortField.RELEVANCE, order: SortOrder.DESC }],\n        ...(companyId && { companyId }),\n        ...(userId !== undefined && { userId }),\n        ...orderlistScope,\n        searchFields: [\n          {\n            fieldNames: [\n              ProductSearchableField.SKU,\n              ProductSearchableField.NAME,\n              ProductSearchableField.KEYWORDS,\n              ProductSearchableField.CUSTOM_KEYWORDS,\n            ],\n            boost: 5,\n          },\n          {\n            fieldNames: [\n              ProductSearchableField.MANUFACTURER_CODE,\n              ProductSearchableField.EAN_CODE,\n              ProductSearchableField.BAR_CODE,\n              ProductSearchableField.SUPPLIER_CODE,\n              ProductSearchableField.PRODUCT_ID,\n            ],\n            boost: 1,\n          },\n        ],\n      } as CategoryProductSearchInput & {\n        applyOrderlists?: boolean;\n        orderlistIds?: number[];\n      };\n\n      const variables = {\n        categoryId: catId,\n        language,\n        categoryProductSearchInput: input,\n        priceCalculateProductInput: {\n          taxZone,\n          ...(companyId && { companyId }),\n          ...(contactId !== undefined && { contactId }),\n          ...(customerId !== undefined && { customerId }),\n        },\n        imageSearchFilters: configuration.imageSearchFiltersGrid,\n        imageVariantFilters: configuration.imageVariantFiltersSmall as TransformationsInput,\n      } as CategoryQueryVariables;\n\n      const response = await service.getCategory(variables);\n      const items = ((response?.products as { items?: unknown[] } | undefined)?.items ??\n        []) as (Product | Cluster)[];\n      return items.map((it) => toMatch(it, language));\n    } catch {\n      return [];\n    }\n  }\n\n  async function submit(lines: QuickOrderLine[]): Promise<QuickOrderSubmitResult> {\n    const valid = lines.filter((l) => l.productId && (l.quantity ?? 0) > 0);\n    if (!valid.length) return { success: false, error: 'No items to add' };\n    if (!graphqlClient) return { success: false, error: 'No GraphQL client' };\n\n    submitting.value = true;\n    error.value = null;\n    try {\n      const services = createServices(graphqlClient);\n      const cart = await initCart({\n        graphqlClient,\n        user: user ?? null,\n        companyId,\n        language,\n        imageSearchFilters: configuration.imageSearchFiltersGrid,\n        imageVariantFilters: configuration.imageVariantFiltersSmall,\n        onCartCreated,\n      });\n\n      const items: CartItemBulkInput[] = valid.map((l) => ({\n        productId: l.productId,\n        quantity: l.quantity,\n        ...(l.clusterId ? { clusterId: l.clusterId } : {}),\n      }));\n\n      const bulk = await services.cart.bulkUpdateCartItems({\n        input: { cartId: cart.cartId, items },\n      });\n\n      // Re-hydrate the cart (the bulk mutation returns counts, not the cart).\n      const updated = await services.cart.getCart({\n        cartId: cart.cartId,\n        language,\n        imageSearchFilters: configuration.imageSearchFiltersGrid as MediaImageProductSearchInput,\n        imageVariantFilters: configuration.imageVariantFiltersSmall as TransformationsInput,\n      });\n      const finalCart = updated ?? cart;\n\n      afterAddToCart?.(finalCart);\n      return {\n        success: true,\n        cart: finalCart,\n        added: (bulk?.created ?? 0) + (bulk?.updated ?? 0),\n      };\n    } catch (e: unknown) {\n      const msg = e instanceof Error ? e.message : 'Failed to add items to cart';\n      error.value = msg;\n      return { success: false, error: msg };\n    } finally {\n      submitting.value = false;\n    }\n  }\n\n  return { submitting, error, searchProducts, submit };\n}\n","/**\n * useMachines (Vue) — the machine-tree ROOT: a company's installations.\n *\n * The sibling of `useSpareParts` for the root level. Where `useSpareParts`\n * fetches one node by slug, this resolves a *list* of installation ids\n * (`MY_INSTALLATIONS`) in ONE request, by concatenating an aliased\n * `machine(source:, sourceId:)` selection per id — mirroring the WordPress\n * reference's `installations()` mega-query. One shared `$source`/`$language`,\n * one `$sourceId_N` per id, all resolved in a single round-trip.\n *\n * It calls `graphqlClient.execute()` with a hand-built document rather than an\n * SDK operation because the alias count is dynamic (N ids → N aliases) — there\n * is no static operation for that. The selection is the minimal set a\n * `MachineCard` needs (`id`/`name`/`description`/`slug`/first image url).\n *\n * Mirrors `propeller-v2-react-ui`'s `useMachines`. The machine pages are CSR,\n * so the fetch is client-only (`typeof window` guard) — no SSR self-fetch.\n */\n\nimport { ref, computed, watch, type Ref, type ComputedRef } from 'vue';\nimport type { GraphQLClient, SparePartsMachine } from '@propeller-commerce/propeller-sdk-v2';\n\n/**\n * The minimal fields a root `MachineCard` needs. Inlined (not the SDK's\n * `SparePartsMachineMinimalFields` fragment) because that fragment drags in\n * image-transform variables we don't want on the lightweight root list, and the\n * concat query hand-writes its own variable block. `imageVariants[0].url` is the\n * exact field `MachineCard`'s image walk reads.\n */\n// name/description/slug deliberately carry NO (language:) field argument.\n// That argument narrows the result to ONE language, which defeats the\n// cross-language fallback getLocalizedValue already implements: an installation\n// with no slug in the tree language came back with an empty slug, MachineGrid\n// could not build an href, and the row was dropped from the list with nothing\n// saying so (PWP-993). The query-level machine(language: $language) below still\n// selects the tree.\nconst ROOT_MACHINE_FIELDS = `\n  id\n  name { language value }\n  description { language value }\n  slug { language value }\n  media {\n    images {\n      items { imageVariants(input: $imageVariantFilters) { url } }\n    }\n  }\n`;\n\n/**\n * Build ONE aliased query resolving every installation in a single request:\n * `machine_0: machine(source: $source, sourceId: $sourceId_0, language: $language) { … }`\n * per id. One shared `$source`/`$language`/`$imageVariantFilters`, one\n * `$sourceId_N` per id. `imageVariants(input:)` is NON_NULL — the same\n * `TransformationsInput!` the SDK `machine`/`category` queries require.\n */\nexport function buildRootMachinesQuery(count: number): string {\n  const vars = [\n    '$source: String',\n    '$language: String',\n    '$imageVariantFilters: TransformationsInput!',\n    ...Array.from({ length: count }, (_, i) => `$sourceId_${i}: String`),\n  ].join('\\n    ');\n\n  const aliases = Array.from({ length: count }, (_, i) => `\n    machine_${i}: machine(source: $source, sourceId: $sourceId_${i}, language: $language) {\n      ${ROOT_MACHINE_FIELDS}\n    }`).join('\\n');\n\n  return `query RootMachines(\\n    ${vars}\\n  ) {${aliases}\\n  }`;\n}\n\nexport interface UseMachinesOptions {\n  /** SDK client. Without it the composable stays idle. */\n  graphqlClient?: GraphQLClient;\n  /** External system the machine ids belong to (pairs with each id). */\n  source?: Ref<string | undefined>;\n  /** Installation ids (from the `MY_INSTALLATIONS` company track attribute). */\n  sourceIds?: Ref<string[] | undefined>;\n  /** Language the machine TREE is authored in (usually EN). */\n  language?: Ref<string | undefined>;\n  /**\n   * Image transformation for the card thumbnail — the `TransformationsInput!`\n   * the schema requires on `imageVariants(input:)`. Without it the query fails\n   * validation. Pass `config.imageVariantFiltersMedium` (same value the node\n   * query uses).\n   */\n  imageVariantFilters?: unknown;\n}\n\nexport interface UseMachinesReturn {\n  /** Resolved installations, in `sourceIds` order, nulls dropped. */\n  machines: ComputedRef<SparePartsMachine[]>;\n  /** `true` while the concat request is in flight. */\n  isLoading: Ref<boolean>;\n  /** Re-run the fetch. */\n  fetchMachines: () => Promise<void>;\n}\n\n/**\n * useMachines — resolve a company's installations in one concatenated request.\n */\nexport function useMachines(options: UseMachinesOptions): UseMachinesReturn {\n  const { graphqlClient, imageVariantFilters } = options;\n  const sourceRef = options.source ?? ref<string | undefined>(undefined);\n  const languageRef = options.language ?? ref<string | undefined>(undefined);\n  const sourceIdsRef = options.sourceIds ?? ref<string[]>([]);\n\n  const internalMachines = ref<SparePartsMachine[]>([]) as Ref<SparePartsMachine[]>;\n  const isLoading = ref(false);\n\n  /** Per-instance guard: only the newest fetch commits. Mirrors `useSpareParts`. */\n  let fetchId = 0;\n\n  async function fetchMachines(): Promise<void> {\n    const source = sourceRef.value;\n    const sourceIds = sourceIdsRef.value ?? [];\n    // Idle: no client / source / ids → don't fetch (the gated return below hides\n    // any stale list until the next successful fetch).\n    if (!graphqlClient || !source || sourceIds.length === 0) return;\n\n    const thisId = ++fetchId;\n    isLoading.value = true;\n\n    try {\n      const variables: Record<string, unknown> = {\n        source,\n        language: languageRef.value ?? '',\n        imageVariantFilters,\n      };\n      sourceIds.forEach((id, i) => {\n        variables[`sourceId_${i}`] = id;\n      });\n\n      const result = await graphqlClient.execute<Record<string, SparePartsMachine | null>>({\n        query: buildRootMachinesQuery(sourceIds.length),\n        variables,\n        operationName: 'RootMachines',\n      });\n\n      if (thisId !== fetchId) return;\n\n      const data = result.data ?? {};\n      internalMachines.value = sourceIds\n        .map((_, i) => data[`machine_${i}`])\n        .filter((m): m is SparePartsMachine => m != null);\n    } catch (e) {\n      console.error('[useMachines] fetchMachines error:', e);\n      if (thisId === fetchId) internalMachines.value = [];\n    } finally {\n      if (thisId === fetchId) isLoading.value = false;\n    }\n  }\n\n  // Gate the output on `sourceIds` so a switch to an empty installation set\n  // shows nothing immediately, even before a stale fetch result clears.\n  const machines = computed<SparePartsMachine[]>(() =>\n    (sourceIdsRef.value?.length ?? 0) > 0 ? internalMachines.value : []\n  );\n\n  // Key the fetch on its INPUTS (content). The ids are content-keyed via their\n  // joined string so a new-but-equal array does not retrigger. Client-only: the\n  // machine pages are CSR, so never self-fetch during SSR.\n  watch(\n    [sourceRef, languageRef, () => (sourceIdsRef.value ?? []).join(',')],\n    () => {\n      if (typeof window !== 'undefined') void fetchMachines();\n    },\n    { immediate: true }\n  );\n\n  return { machines, isLoading, fetchMachines };\n}\n","/**\n * Resolving a machine slug when the tree is only half-translated.\n *\n * `machine(slug:, language:)` resolves a slug ONLY in the language that slug\n * was authored in. `language` is also mandatory (omitting it is a validation\n * error, not a wildcard) and case-sensitive — `'nl'` misses where `'NL'` hits.\n *\n * That matters because the listing no longer narrows to one language: an\n * installation authored only in NL now appears in an EN tree and is linked by\n * its NL slug (PWP-993). Following that link then asked for\n * `machine(slug: \"<NL slug>\", language: \"EN\")`, which the API answers with\n * `SPARE_PARTS_MACHINE_NOT_FOUND_ERROR` — so the row came back but the page\n * behind it was empty, with a title derived from the slug and no error. The bug\n * moved one click deeper instead of going away.\n *\n * The URL carries no language, so the only thing a cold deep link can do is try\n * the languages the shop actually uses. `machine(id:)` is language-agnostic,\n * but an id is not what a shareable URL contains.\n */\n\n/** The API's code for \"this slug does not exist in this language\". */\nconst MACHINE_NOT_FOUND = 'SPARE_PARTS_MACHINE_NOT_FOUND_ERROR';\n\n/** Is this the API saying the slug/language pair does not exist? */\nexport function isMachineNotFound(error: unknown): boolean {\n  const entries = (error as { errors?: Array<{ extensions?: { code?: string }; message?: string }> })\n    ?.errors;\n  if (!Array.isArray(entries)) return false;\n  return entries.some(\n    (e) =>\n      e?.extensions?.code === MACHINE_NOT_FOUND ||\n      /no machine found for slug and language/i.test(e?.message ?? '')\n  );\n}\n\n/**\n * The languages to try, in order: the tree language first (the common case and\n * the only one that costs a request in a fully-translated shop), then the\n * storefront language, then any others the host declares.\n *\n * Upper-cased and de-duplicated — the API matches the case exactly.\n */\nexport function machineLanguageCandidates(\n  machineLanguage: string | undefined,\n  language: string | undefined,\n  extra: string[] | undefined\n): string[] {\n  const ordered = [machineLanguage, language, ...(extra ?? [])];\n  const seen = new Set<string>();\n  const out: string[] = [];\n  for (const raw of ordered) {\n    const value = raw?.trim().toUpperCase();\n    if (!value || seen.has(value)) continue;\n    seen.add(value);\n    out.push(value);\n  }\n  return out;\n}\n\n/**\n * Call `fetchOne` with each candidate language until one resolves.\n *\n * Returns `null` when every candidate reported \"not found\" — that is a real\n * answer (the slug exists in no language we know of), and the caller should say\n * so rather than render an empty listing. Any OTHER failure is rethrown\n * immediately: a network blip or an auth error must not be retried three times\n * and then reported as a missing machine.\n */\nexport async function resolveMachineAcrossLanguages<T>(\n  candidates: string[],\n  fetchOne: (language: string) => Promise<T | null | undefined>\n): Promise<{ machine: T; language: string } | null> {\n  for (const language of candidates) {\n    try {\n      const machine = await fetchOne(language);\n      // A null counts as \"not found in this language\" and must keep the loop\n      // going. The API answers a wrong-language slug with a PARTIAL response —\n      // `machine: null` alongside SPARE_PARTS_MACHINE_NOT_FOUND_ERROR — and the\n      // SDK's `runOperation` returns that data rather than throwing unless the\n      // client sets `throwOnPartialErrors`, which no boilerplate does. Treating\n      // the null as a hit made the first candidate always win, so the fallback\n      // never ran and `notFound` was never set (PWP-993, round three).\n      if (machine !== null && machine !== undefined) return { machine, language };\n    } catch (error) {\n      if (!isMachineNotFound(error)) throw error;\n    }\n  }\n  return null;\n}\n","/**\n * useSpareParts (Vue) — a machine node's spare-parts list.\n *\n * The machine-tree sibling of `useProductSearch`: same contract (options in,\n * state + actions out), same controlled/uncontrolled sentinel, same race\n * guard — but sourced from `machine(slug:).sparePartProducts` instead of\n * `category(categoryId:).products`.\n *\n * Mirrors `propeller-v2-react-ui`'s `useSpareParts`. The machine pages are CSR,\n * so the fetch is client-only (`typeof window` guard) — no SSR self-fetch.\n */\n\nimport { ref, computed, watch, type Ref, type ComputedRef } from 'vue';\nimport {\n  machineService,\n  ProductStatus,\n  type GraphQLClient,\n  type SparePartsMachine,\n  type SparePartsMachineProductSearchInput,\n  type SparePart,\n  type SparePartsResponse,\n  type AttributeFilter,\n  type Contact,\n  type Customer,\n  type ProductSortInput,\n  type ProductSortField,\n  type SortOrder,\n  type ProductTextFilterInput,\n  type ProductPriceFilterInput,\n  type PriceCalculateProductInput,\n  type FilterAvailableAttributeInput,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { resolveListingUserId } from '../shared/utils/listingUserId';\nimport {\n  machineLanguageCandidates,\n  resolveMachineAcrossLanguages,\n} from '../shared/utils/machineLanguage';\n\n/** Statuses the storefront shows. Mirrors `useProductSearch` / `lib/server`. */\nconst STOREFRONT_STATUSES: ProductStatus[] = [\n  ProductStatus.A,\n  ProductStatus.P,\n  ProductStatus.T,\n  ProductStatus.S,\n];\n\nexport interface UseSparePartsOptions {\n  /** SDK client. Without it the composable stays idle (controlled mode needs no client). */\n  graphqlClient?: GraphQLClient;\n  /**\n   * Controlled mode: pre-fetched parts (e.g. SSR-seeded). When the ref's VALUE\n   * is DEFINED the composable performs no fetching and echoes these back. Pass\n   * `[]` (not `undefined`) to show an empty state while the host controls loading.\n   */\n  parts?: Ref<SparePart[] | undefined>;\n  /** Slug of the machine whose parts to list. */\n  slug?: Ref<string | undefined>;\n  /** Free-text search, scoped server-side to this machine's parts. */\n  term?: Ref<string | undefined>;\n  /** Language for the spare parts themselves (the storefront language). */\n  language: Ref<string>;\n  /**\n   * Language the MACHINE TREE is authored in. Defaults to `language`.\n   *\n   * `machine(slug:, language:)` is language-scoped and hard-errors with\n   * \"No machine found for slug and language\" when the machine has no name/slug\n   * in that language. Machine trees are commonly maintained in one language\n   * (typically EN) while their spare parts are localized.\n   */\n  machineLanguage?: Ref<string | undefined>;\n  /**\n   * Extra languages to try when the slug does not resolve in `machineLanguage`.\n   *\n   * A slug resolves only in the language it was authored in, so a tree that is\n   * only half-translated has machines reachable by an NL slug but not an EN\n   * one. `machineLanguage` and `language` are always tried first; list the\n   * shop's other locales here to cover the rest. Order is the try order.\n   */\n  machineLanguages?: Ref<string[] | undefined>;\n  /** Tax zone for price calculation. */\n  taxZone?: string;\n  /** Active user — drives `userId` scoping and contact/customer pricing. */\n  user?: Ref<Contact | Customer | null>;\n  /** Active company — scopes the assortment. */\n  companyId?: Ref<number | undefined>;\n  /** Attribute (facet) filters. */\n  textFilters?: Ref<ProductTextFilterInput[] | undefined>;\n  /** Price-range filter lower bound. */\n  priceFilterMin?: Ref<number | undefined>;\n  /** Price-range filter upper bound. */\n  priceFilterMax?: Ref<number | undefined>;\n  /** Sort field. */\n  sortField?: Ref<string | undefined>;\n  /** Sort direction. */\n  sortOrder?: Ref<string | undefined>;\n  /** Items per page. Defaults to 12. */\n  pageSize?: Ref<number>;\n\n  /**\n   * Controlled page. When provided the composable renders (and fetches) this\n   * page and `goToPage` becomes advisory — the host owns the number, typically\n   * from the URL. Every other listing input was already an option, so its\n   * absence read as \"paging is internal\" and it was not (PWP-995b). Omit it to\n   * keep the previous uncontrolled behaviour.\n   */\n  page?: Ref<number>;\n  /** Image filter config, mirroring `useProductSearch`'s `configuration`. */\n  configuration?: {\n    /** The channel's anonymous user — logged-out listings are scoped to it. */\n    anonymousUserId?: number;\n    imageSearchFiltersGrid?: unknown;\n    imageVariantFiltersMedium?: unknown;\n  };\n  /** Fired with the facet list after each fetch. */\n  onFiltersChange?: (filters: AttributeFilter[]) => void;\n  /** Fired with the price-slider bounds after each fetch. */\n  onPriceBoundsChange?: (min: number, max: number) => void;\n  /** Fired with the total item count after each fetch. */\n  onItemsFoundChange?: (count: number) => void;\n  /** Fired with the raw parts response after each fetch. */\n  onPartsResponse?: (response: SparePartsResponse) => void;\n  /** Fired with the machine itself after each fetch (name, child machines, …). */\n  onMachineChange?: (machine: SparePartsMachine) => void;\n}\n\nexport interface UseSparePartsReturn {\n  /** The parts to render — the controlled prop when set, else the fetched list. */\n  displayParts: ComputedRef<SparePart[]>;\n  /** Child machines of this node, for rendering alongside the parts. */\n  childMachines: Ref<SparePartsMachine[]>;\n  /** Total parts found. */\n  itemsFound: Ref<number>;\n  /** `true` while an internal fetch is in flight. Always `false` when controlled. */\n  isLoading: ComputedRef<boolean>;\n  /** Current page (1-based). */\n  currentPage: Ref<number>;\n  /** Total pages. */\n  totalPages: Ref<number>;\n  /** Re-run the fetch. No-op in controlled mode. */\n  fetchParts: () => Promise<void>;\n  /** Navigate to a page. */\n  goToPage: (page: number) => void;\n  /**\n   * The slug resolved in none of the candidate languages.\n   *\n   * Distinct from \"resolved but has no parts\": this node does not exist, and a\n   * host that renders the usual empty listing for it shows a page built\n   * entirely from the URL. Always `false` in controlled mode.\n   */\n  notFound: ComputedRef<boolean>;\n}\n\n/** Resolve contact/customer ids from the active user, mirroring the React hook. */\nfunction resolveUserIds(\n  user: Contact | Customer | null | undefined,\n  configuration?: { anonymousUserId?: number }\n): {\n  userId?: number;\n  contactId?: number;\n  customerId?: number;\n} {\n  const contactId = user && 'contactId' in user ? (user as Contact).contactId : undefined;\n  const customerId = user && 'customerId' in user ? (user as Customer).customerId : undefined;\n  // contactId/customerId stay strictly the logged-in ids; only the listing\n  // scope falls back to the channel's anonymous user.\n  return { userId: resolveListingUserId(user, configuration), contactId, customerId };\n}\n\n/**\n * useSpareParts — fetch and paginate a machine node's spare-parts list.\n */\nexport function useSpareParts(options: UseSparePartsOptions): UseSparePartsReturn {\n  const graphqlClient = options.graphqlClient;\n  const languageRef = options.language;\n  const slugRef = options.slug ?? ref<string | undefined>(undefined);\n  const termRef = options.term ?? ref<string | undefined>(undefined);\n  const machineLanguageRef = options.machineLanguage ?? ref<string | undefined>(undefined);\n  const machineLanguagesRef = options.machineLanguages ?? ref<string[] | undefined>(undefined);\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<Contact | Customer | null>(null);\n  const companyIdRef = options.companyId ?? ref<number | undefined>(undefined);\n  const taxZone = options.taxZone;\n\n  const internalParts = ref<SparePart[]>([]) as Ref<SparePart[]>;\n  const childMachines = ref<SparePartsMachine[]>([]) as Ref<SparePartsMachine[]>;\n  const itemsFound = ref(0);\n  const internalLoading = ref(false);\n  const internalPage = ref(1);\n  // Controlled when `options.page` is given, mirroring `options.parts`.\n  const currentPage = computed(() => options.page?.value ?? internalPage.value);\n  const totalPages = ref(1);\n  const notFound = ref(false);\n\n  /** Per-instance guard: only the newest fetch commits. Mirrors `useProductSearch`. */\n  let fetchId = 0;\n\n  const isControlled = computed(() => options.parts?.value !== undefined);\n  const displayParts = computed<SparePart[]>(() =>\n    isControlled.value ? options.parts!.value ?? [] : internalParts.value\n  );\n  const isLoading = computed(() => !isControlled.value && internalLoading.value);\n\n  async function fetchParts(): Promise<void> {\n    if (!graphqlClient || isControlled.value || !slugRef.value) return;\n\n    const thisId = ++fetchId;\n    internalLoading.value = true;\n\n    try {\n      // `machineService(client)` rather than `createServices(client).machine` —\n      // the core-ui `Services` bundle has no machine entry.\n      const service = machineService(graphqlClient);\n      const { userId, contactId, customerId } = resolveUserIds(userRef.value, options.configuration);\n\n      const sortInputs: ProductSortInput[] = sortFieldRef.value\n        ? [{ field: sortFieldRef.value as ProductSortField, order: sortOrderRef.value as SortOrder }]\n        : [];\n\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      // `language`/`page`/`offset`/`statuses` are NON_NULL on the schema —\n      // passing this input at all means passing all four.\n      const sparePartsMachineProductSearchInput: SparePartsMachineProductSearchInput = {\n        language: languageRef.value,\n        page: currentPage.value,\n        offset: pageSizeRef.value,\n        statuses: STOREFRONT_STATUSES,\n        hidden: false,\n        ...(termRef.value && { term: termRef.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 && { taxZone }),\n        ...(companyIdRef.value && { companyId: companyIdRef.value }),\n        ...(contactId !== undefined && { contactId }),\n        ...(customerId !== undefined && { customerId }),\n      };\n\n      // Without this the response's `filters` array is empty and the filter\n      // sidebar renders \"No filters available\".\n      const filterAvailableAttributeInput: FilterAvailableAttributeInput = {\n        isSearchable: true,\n      };\n\n      // A slug resolves only in the language it was authored in, so try the\n      // tree language first and fall back through the shop's other languages.\n      // Without this a machine listed by its NL slug in an EN tree opened an\n      // empty page — the PWP-993 row was restored but its contents were not.\n      const resolved = await resolveMachineAcrossLanguages(\n        machineLanguageCandidates(\n          machineLanguageRef.value,\n          languageRef.value,\n          machineLanguagesRef.value\n        ),\n        (language) =>\n          service.getMachine({\n            slug: slugRef.value,\n            // The machine tree's language, NOT the parts' — see `machineLanguage`.\n            language,\n            sparePartsMachineProductSearchInput,\n            filterAvailableAttributeInput,\n            priceCalculateProductInput,\n            imageSearchFilters: options.configuration?.imageSearchFiltersGrid as never,\n            imageVariantFilters: options.configuration?.imageVariantFiltersMedium as never,\n          })\n      );\n\n      if (thisId !== fetchId) return;\n\n      // Exhausted every language: the slug exists in none of them. Say so —\n      // rendering an empty parts list under a title derived from the slug is\n      // what made this invisible in the first place.\n      if (!resolved) {\n        notFound.value = true;\n        internalParts.value = [];\n        childMachines.value = [];\n        itemsFound.value = 0;\n        options.onItemsFoundChange?.(0);\n        totalPages.value = 1;\n        return;\n      }\n      notFound.value = false;\n      const machine = resolved.machine;\n\n      const partsResponse = machine?.sparePartProducts as SparePartsResponse | undefined;\n      const items = (partsResponse?.items ?? []) as SparePart[];\n\n      internalParts.value = items;\n      childMachines.value = (machine?.machines ?? []) as SparePartsMachine[];\n\n      const found = partsResponse?.itemsFound ?? items.length;\n      itemsFound.value = found;\n      options.onItemsFoundChange?.(found);\n      totalPages.value = partsResponse?.pages ?? 1;\n\n      if (partsResponse) options.onPartsResponse?.(partsResponse);\n      if (partsResponse?.filters) options.onFiltersChange?.(partsResponse.filters);\n\n      // Price-slider bounds. Same caveat as `useProductSearch`: the API's\n      // aggregate is populated for anonymous reads but comes back 0 for a\n      // contact-priced request, so fall back to the resolved per-item prices.\n      const aggMin = partsResponse?.minPrice;\n      const aggMax = partsResponse?.maxPrice;\n      if (aggMax !== undefined && aggMax > 0) {\n        options.onPriceBoundsChange?.(aggMin ?? 0, aggMax);\n      } else {\n        const prices = items\n          .map((p) => {\n            const product = p?.product as { price?: { gross?: number; net?: number } } | undefined;\n            return product?.price?.gross ?? product?.price?.net;\n          })\n          .filter((n): n is number => typeof n === 'number' && n > 0);\n        if (prices.length) {\n          options.onPriceBoundsChange?.(Math.floor(Math.min(...prices)), Math.ceil(Math.max(...prices)));\n        }\n      }\n\n      if (machine) options.onMachineChange?.(machine);\n    } catch (e) {\n      console.error('[useSpareParts] fetchParts error:', e);\n      if (thisId === fetchId) internalParts.value = [];\n    } finally {\n      if (thisId === fetchId) internalLoading.value = false;\n    }\n  }\n\n  function goToPage(page: number): void {\n    // `totalPages <= 1` means the count isn't known yet, so don't reject — else\n    // the first pagination click is silently dropped. Mirrors the React hook.\n    if (page >= 1 && (totalPages.value <= 1 || page <= totalPages.value)) {\n      internalPage.value = page;\n    }\n  }\n\n  // Key the fetch on its INPUTS (content), NOT on the textFilters array\n  // identity. MachineGrid rebuilds `textFilters` from the fetched facet list on\n  // every response, so watching the array by reference would re-fetch on its own\n  // output forever. `JSON.stringify` keys on filter *content*; a new-but-equal\n  // array no longer retriggers. Client-only: the machine pages are CSR.\n  watch(\n    [\n      slugRef,\n      termRef,\n      languageRef,\n      machineLanguageRef,\n      () => (machineLanguagesRef.value ?? []).join(','),\n      companyIdRef,\n      () => JSON.stringify(textFiltersRef.value ?? []),\n      priceMinRef,\n      priceMaxRef,\n      sortFieldRef,\n      sortOrderRef,\n      pageSizeRef,\n      currentPage,\n      () => {\n        const { contactId, customerId } = resolveUserIds(userRef.value, options.configuration);\n        return `${contactId ?? ''}:${customerId ?? ''}`;\n      },\n      isControlled,\n    ],\n    () => {\n      if (!isControlled.value && typeof window !== 'undefined') void fetchParts();\n    },\n    { immediate: true }\n  );\n\n  return {\n    displayParts,\n    childMachines,\n    itemsFound,\n    isLoading,\n    currentPage,\n    totalPages,\n    fetchParts,\n    goToPage,\n    notFound: computed(() => !isControlled.value && notFound.value),\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';\nimport { resolveListingUserId } from '../shared/utils/listingUserId';\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    /** The channel's anonymous user — logged-out listings are scoped to it. */\n    anonymousUserId?: number;\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    return resolveListingUserId(options.user?.value ?? null, configuration);\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    /**\n     * Whether a session exists, independent of whether `user` has loaded yet.\n     * Deliberately absent from `withDefaults`: Vue coerces an unpassed boolean\n     * to `false`, and defaulting it would be indistinguishable from a host\n     * saying \"definitely anonymous\". Left undefined so `isContentHidden` keeps\n     * its previous behaviour for hosts that do not supply it.\n     */\n    isAuthenticated?: boolean;\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 isAuthenticated() {\n    return props.isAuthenticated;\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","/**\n * Merge class lists so the LAST conflicting utility wins.\n *\n * Every component here builds its class attribute by appending the host's\n * override to its own defaults. Attribute order does not decide CSS — the\n * cascade does — so `class=\"text-white text-cocoa\"` rendered white, and\n * `iconClassName=\"text-cocoa\"` looked like it did nothing. It appeared to work\n * on components whose baked-in default happened to lose the cascade anyway,\n * which is worse than a consistent failure.\n *\n * `twMerge` resolves the conflict properly: same utility group → later value\n * replaces the earlier one. Unknown classes (our BEM hooks, `propeller-*`) are\n * passed through untouched.\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n  return twMerge(clsx(inputs));\n}\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          <!-- Full prompt with a {link} placeholder so the translation owns the\n               wording AND the spacing around the register link (was\n               \"…account?Create an Account\", no space). -->\n          {{ noAccountParts.before\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>{{ noAccountParts.after }}\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}\n// Split the register prompt around {link} so the register button renders in\n// place and the translation owns the wording + spacing.\nconst noAccountParts = computed(() => {\n  const tpl = getLabel('noAccount', \"Don't have an account? {link}\");\n  const [before, after = ''] = tpl.split('{link}');\n  return { before, after };\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                  <a\n                    :href=\"link.href\"\n                    @click=\"(event: MouseEvent) => handleMenuLinkClick(event, 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-primary/5 text-primary border-l-2 border-primary'\n                        : 'text-muted-foreground hover:bg-surface-hover hover:text-foreground'\n                    }`\"\n                  >\n                    {{ link.label }}\n                  </a>\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=\"cn(\n          '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-inherit',\n          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              {{ getLabel('greeting', 'Hi, {name}').replace('{name}', 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=\"cn(\n            '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,\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                      <a\n                        :href=\"link.href\"\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=\"(event: MouseEvent) => handleMenuLinkClick(event, link.href)\"\n                      >\n                        {{ link.label }}\n                      </a>\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 { cn } from '../composables/shared/utils/cn';\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}\n\n// Anchor click handler for menu links. The links are real <a href> so they can\n// be middle-clicked, opened in a new tab, and crawled. A plain left click is\n// intercepted for SPA navigation; modified clicks (ctrl/cmd/shift/middle) fall\n// through to the browser's native new-tab / new-window behaviour.\nfunction handleMenuLinkClick(event: MouseEvent, href: string): void {\n  if (\n    event.defaultPrevented ||\n    event.button !== 0 ||\n    event.metaKey ||\n    event.ctrlKey ||\n    event.shiftKey ||\n    event.altKey\n  ) {\n    return;\n  }\n  event.preventDefault();\n  handleMenuItemClick(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. Resolved from PropellerProvider when omitted. */\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 || getLabel('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  <!--\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 { localeForLanguage } 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 ?? \"€\", locale: localeForLanguage(props.language) });\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 flex-wrap items-center gap-2 w-full md:flex-nowrap\">\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 w-full md:w-auto\"\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 flex-1 md:flex-none md: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-full md: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 min-w-0 basis-full md:basis-auto inline-flex justify-center items-center gap-2 h-10 px-3 sm:px-6 border border-transparent text-sm font-medium rounded-[var(--radius-control)] text-primary-foreground bg-secondary hover:bg-secondary/80 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        <svg\n          class=\"propeller-add-to-cart__icon w-[1.1em] h-[1.1em] flex-shrink-0\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          :strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <circle cx=\"8\" cy=\"21\" r=\"1\"></circle>\n          <circle cx=\"19\" cy=\"21\" r=\"1\"></circle>\n          <path 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\"></path>\n        </svg>\n        <span class=\"propeller-add-to-cart__submit-label min-w-0 truncate\">\n          {{ loading ? getLabel(\"adding\", \"Adding...\") : getLabel(\"add\", \"Add\") }}\n        </span>\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                      getLanguageString(child.product?.names, language || 'NL', '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            <template v-if=\"grantedBonusItems.length > 0\">\n              <div\n                class=\"propeller-add-to-cart__modal-bonus-items mt-4 pt-4 border-t border-border-subtle\"\n              >\n                <CartBonusItems\n                  :bonusItems=\"grantedBonusItems\"\n                  :labels=\"bonusItemsLabels\"\n                />\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 CartBonusItems from './CartBonusItems.vue';\nimport { getLabel as _getLabel, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n\n  /** The authenticated user (Contact or Customer). Resolved from PropellerProvider when omitted. */\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  /**\n   * Labels for the bonus-items block in the success modal.\n   * Keys: `title` ('Bonus items'), `sku` ('SKU').\n   */\n  bonusItemsLabels?: Record<string, string>;\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);\n// Bonus items this add earned. A promotion that grants a free product said\n// nothing at the moment it fired — the shopper only found it by opening the\n// cart later, which is exactly when it can no longer influence them.\nconst grantedBonusItems = ref<CartBaseItem[]>([]);\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 getLanguageString((props.product as Product)?.names, props.language || 'NL', '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 ?? \"€\", locale: localeForLanguage(props.language) });\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  // Snapshot before the mutation so the modal can tell which bonus items this\n  // particular add earned.\n  const cartBeforeAdd = cart.value ?? null;\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      grantedBonusItems.value = newBonusItems(cartBeforeAdd, resultCart);\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 getLanguageString(addedCartItem.value.product?.names, props.language || 'NL', '') || 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 ?? \"€\", locale: localeForLanguage(props.language) });\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 ?? \"€\", locale: localeForLanguage(props.language) });\n}\nfunction closeModal(): ReturnType<AddToCartState[\"closeModal\"]> {\n  modalVisible.value = false;\n  success.value = false;\n  addedCartItem.value = null;\n  grantedBonusItems.value = [];\n}\n\n/**\n * The bonus items present after the add that were not there before it.\n *\n * With no `before` cart to compare against — the very first add after a page\n * load, where the hook has not resolved a cart yet — every bonus item in the\n * cart is reported. That over-reports on a cart that already held bonus items;\n * showing them is still better than showing nothing.\n */\nfunction newBonusItems(before: Cart | null, after: Cart | undefined): CartBaseItem[] {\n  const granted = (after as any)?.bonusItems ?? [];\n  if (granted.length === 0) return [];\n  const previous = (before as any)?.bonusItems;\n  if (!previous) return granted;\n  const seen = new Map(\n    previous.map((item: CartBaseItem) => [item.itemId, item.quantity ?? 0]),\n  );\n  return granted.filter(\n    (item: CartBaseItem) => (item.quantity ?? 0) > ((seen.get(item.itemId) as number) ?? 0),\n  );\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\n/** Which way the favorite toggle went — see `onFavoriteChanged`. */\nexport interface FavoriteChange {\n  action: \"added\" | \"removed\";\n  listId?: string | number;\n  productId?: number;\n  clusterId?: number;\n}\n\nexport interface AddToFavoriteProps {\n  /** The initialized GraphQL Client instance. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n\n  /** The authenticated user. Resolved from PropellerProvider when omitted. */\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  /**\n   * Called after the favorite toggle succeeds, with which way it went.\n   *\n   * The argument is optional so existing zero-argument callbacks keep working.\n   * Without it an add and a removal are indistinguishable, so a host cannot\n   * report \"added to wishlist\" without inventing the direction — and a\n   * wishlist metric that also counts removals is worse than none.\n   */\n  onFavoriteChanged?: (change?: FavoriteChange) => 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    // Captured before the ref is cleared below. The React twin can read the\n    // pre-update value out of its closure after setState; a ref cannot.\n    const addedListId = selectedListId.value;\n    await addToList(addedListId, pid, cid);\n    const newMemberIds = new Set(memberListIds.value);\n    newMemberIds.add(String(addedListId));\n    memberListIds.value = newMemberIds;\n    selectedListId.value = \"\";\n    showModal.value = false;\n    if (props.onFavoriteChanged) {\n      props.onFavoriteChanged({\n        action: \"added\",\n        listId: addedListId,\n        productId: pid,\n        clusterId: cid,\n      });\n    }\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) {\n      props.onFavoriteChanged({\n        action: \"removed\",\n        listId,\n        productId: pid,\n        clusterId: cid,\n      });\n    }\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 && showTypeBadge !== false\"\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                  :pattern=\"EMAIL_PATTERN\"\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                    :pattern=\"EMAIL_PATTERN\"\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\n/**\n * Email pattern requiring a dotted top-level domain.\n *\n * `type=\"email\"` alone accepts dotless domains such as `aa@gg` — valid per the\n * HTML5 spec (intranet hosts like `user@localhost`), but not a deliverable\n * address here, and rejected by the API. Email is optional on an address; this\n * only constrains the value once something has been typed.\n */\nconst EMAIL_PATTERN = '[^@\\\\s]+@[^@\\\\s.]+(?:\\\\.[^@\\\\s.]+)*\\\\.[A-Za-z]{2,}';\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  /**\n   * Display the address-type badge (invoice/delivery chip) @default true.\n   * Set to `false` where the surrounding heading already names the address\n   * type, to avoid a redundant raw-looking chip.\n   */\n  showTypeBadge?: 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. Resolved from PropellerProvider when omitted. */\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","/**\n * Keyboard + roving-tabindex helpers for card-style radio groups.\n *\n * CartPaymethods / CartCarriers / DeliveryDate render their options as styled\n * cards, not `<input type=\"radio\">`, so they got no keyboard or screen-reader\n * affordances for free: the options were plain divs with a click handler —\n * unreachable by Tab, invisible to the accessibility tree, and (because\n * choosing a carrier is required to advance checkout) a hard block for\n * keyboard-only and screen-reader users.\n *\n * Rather than restyle three components around native inputs, they keep their\n * markup and adopt the ARIA radiogroup pattern. These two helpers are the\n * whole behavioural contract, shared so the three stay consistent.\n */\n\nconst NEXT_KEYS = ['ArrowRight', 'ArrowDown']\n// 'Spacebar' is the legacy IE/Edge name for ' '. Cheap to accept.\nconst SELECT_KEYS = ['Enter', ' ', 'Spacebar']\n\n/**\n * `keydown` handler for an element carrying `role=\"radio\"`.\n *\n * Enter/Space selects; arrow keys move focus to the previous/next radio in the\n * enclosing `role=\"radiogroup\"` and select it, which is how native radios\n * behave. Selection is driven by dispatching a real `click`, so the component's\n * existing `@click` handler stays the single place selection is implemented —\n * no second code path to keep in sync.\n */\nexport function radioGroupKeydown(event: KeyboardEvent): void {\n  const el = event.currentTarget as HTMLElement | null\n  if (!el) return\n\n  if (SELECT_KEYS.includes(event.key)) {\n    // Space would scroll the page, Enter could submit a wrapping form.\n    event.preventDefault()\n    el.click()\n    return\n  }\n\n  const isNext = NEXT_KEYS.includes(event.key)\n  const isPrev = event.key === 'ArrowLeft' || event.key === 'ArrowUp'\n  if (!isNext && !isPrev) return\n  event.preventDefault()\n\n  const group = el.closest('[role=\"radiogroup\"]')\n  if (!group) return\n  const radios = Array.from(\n    group.querySelectorAll<HTMLElement>('[role=\"radio\"]'),\n  ).filter((r) => r.getAttribute('aria-disabled') !== 'true')\n\n  const current = radios.indexOf(el)\n  if (current === -1) return\n  // Wrap around at both ends, as the radiogroup pattern specifies.\n  const target = radios[(current + (isNext ? 1 : -1) + radios.length) % radios.length]\n  if (!target || target === el) return\n  target.focus()\n  target.click()\n}\n\n/**\n * Roving tabindex: exactly ONE radio in a group is tabbable, so Tab enters and\n * leaves the group as a single stop and the arrow keys move within it.\n *\n * The selected option owns the tab stop. With nothing selected yet the first\n * option takes it — otherwise the group would have no tabbable element at all\n * and a keyboard user could never reach it, which is the state checkout starts\n * in.\n */\nexport function radioTabIndex(\n  isSelected: boolean,\n  index: number,\n  hasSelection: boolean,\n): number {\n  return isSelected || (!hasSelection && index === 0) ? 0 : -1\n}\n","/**\n * Pick what a selectable list should start on.\n *\n * Checkout must never render a payment method / carrier grid with nothing\n * selected: the user should be able to hit Continue straight away. Prefer what\n * the cart already stores; when it stores nothing — a fresh cart — or stores a\n * value the backend no longer offers, fall back to the first option.\n *\n * Kept separate from the components because both packages test pure logic in\n * `node` and cannot mount an SFC / run an effect.\n */\nexport function pickPreselected<T>(\n  items: T[] | null | undefined,\n  stored: string | null | undefined,\n  keyOf: (item: T) => string,\n): T | undefined {\n  const list = items || [];\n  return (stored ? list.find((item) => keyOf(item) === stored) : undefined) || list[0];\n}\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-2 sm:grid-cols-3 lg:grid-cols-4 gap-3\"\n        role=\"radiogroup\"\n        :aria-label=\"getLabel('carriersLabel', 'Delivery method')\"\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            @keydown=\"radioGroupKeydown\"\n            role=\"radio\"\n            :aria-checked=\"activeName === carrier.name ? 'true' : 'false'\"\n            :tabindex=\"radioTabIndex(activeName === carrier.name, index, activeName !== '')\"\n            :data-selected=\"activeName === carrier.name ? 'true' : 'false'\"\n            :class=\"`propeller-cart-carriers__carrier relative cursor-pointer border rounded-[var(--radius-container)] p-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-secondary focus-visible:ring-offset-1 flex flex-col items-center justify-center gap-2 text-center aspect-square transition-all ${\n              activeName === carrier.name\n                ? 'border-secondary bg-secondary/5 shadow-sm'\n                : 'border-border hover:border-secondary/30'\n            }`\"\n          >\n            <template v-if=\"showPrice !== false\">\n              <span\n                class=\"propeller-cart-carriers__carrier-price absolute top-2 right-2 text-xs bg-surface-hover text-muted-foreground px-2 py-0.5 rounded-full\"\n                >{{ formatCarrierPrice(carrier.price) }}</span\n              >\n            </template>\n            <template v-if=\"showLogo && getLogoUrl(carrier)\">\n              <span\n                class=\"propeller-cart-carriers__carrier-logo-wrap flex items-center justify-center h-10 w-full\"\n              >\n                <img\n                  class=\"propeller-cart-carriers__carrier-logo max-h-10 max-w-[80%] w-auto object-contain\"\n                  :src=\"getLogoUrl(carrier)\"\n                  :alt=\"carrier.name\"\n                />\n              </span>\n            </template>\n            <span\n              class=\"propeller-cart-carriers__carrier-name font-medium text-sm\"\n              >{{ carrier.name }}</span\n            >\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, onMounted, 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 { localeForLanguage } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { radioGroupKeydown, radioTabIndex } from '../composables/shared/utils/radioGroup';\nimport { pickPreselected } from '../composables/shared/utils/preselect';\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\n// Something is always selected — the cart's stored carrier, else the first one\n// offered, so the user can hit Continue without a click. Computed\n// rather than assigned state so it is right in the first render; the cart\n// arrives after mount.\nconst preselected = computed(() =>\n  pickPreselected(\n    carriers.value,\n    props.cart?.postageData?.carrier as string | undefined,\n    (c: CartCarrier) => c.name,\n  ),\n);\nconst activeName = computed(() => selectedName.value || preselected.value?.name || \"\");\n\n// Report the preselection upwards. Deliberately NOT an `immediate` watch —\n// that also fires during SSR, where the host's callback would mutate the cart\n// while rendering. A user pick sets `selectedName` and takes over from here.\nfunction notifyPreselection() {\n  if (selectedName.value || !preselected.value) return;\n  if (props.onCarrierSelect) props.onCarrierSelect(preselected.value);\n}\nwatch(() => preselected.value?.name, notifyPreselection);\nonMounted(notifyPreselection);\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 ?? \"€\", locale: localeForLanguage(infra.language) });\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                getLanguageString(child.product.names, infra.language || 'NL', '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=\"infra.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=\"infra.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          :aria-label=\"getLabel('deleteLabel', 'Remove item')\"\n          :title=\"getLabel('deleteLabel', 'Remove item')\"\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, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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 { useInfraProps } from '../composables/vue/useInfraProps';\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. Resolved from PropellerProvider when omitted. */\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  cardFrame: true,\n  showDelete: 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\n// Resolve infra ONCE at setup. `inject()` (inside useInfraProps) only works\n// during setup — calling it lazily from inside a `computed` getter yields a\n// null context, so the spec-based `resolved.value.*` above cannot be relied on\n// for keys read after setup. The money below therefore reads `language` and\n// `currency` through this proxy: reading them off `props` meant every host had\n// to pass them, and cart lines silently formatted at the `nl-NL` default on a\n// shop reading in any other language.\nconst infra = useInfraProps(props);\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);\nconst companyIdRef = computed(() => resolved.value.companyId);\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  companyId: companyIdRef,\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);\n\n// Crossupsells are priced for the active company — refetch when it changes.\nwatch(companyIdRef, () => {\n  fetchCrossupsells();\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 getLanguageString(props.cartItem.product?.names, infra.language || 'NL', '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      infra.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: infra.language,\n        currency: infra.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: infra.currency ?? \"€\", locale: localeForLanguage(infra.language) });\n}\nfunction getChildItemPrice(\n  child: CartBaseItem,\n): ReturnType<CartItemState[\"getChildItemPrice\"]> {\n  return _formatPrice(Number(child.totalSum ?? 0), { symbol: infra.currency ?? \"€\", locale: localeForLanguage(infra.language) });\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: infra.currency ?? \"€\", locale: localeForLanguage(infra.language) });\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 getLanguageString(leader.product.names, infra.language || 'NL', '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: infra.currency ?? \"€\", locale: localeForLanguage(infra.language) });\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 getLanguageString(bundleItem.product.names, infra.language || 'NL', '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: infra.currency ?? \"€\", locale: localeForLanguage(infra.language) });\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 getLanguageString(product?.names, infra.language || 'NL', '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      infra.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: infra.currency ?? \"€\", locale: localeForLanguage(infra.language) });\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=\"cn(\n          'propeller-cart-icon__trigger relative inline-flex items-center justify-center p-2 rounded-[var(--radius-control)] transition-colors text-foreground',\n          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              >{{ getTotalLabel(\"totalLabel\") }}</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=\"cn(\n        '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,\n      )\"\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                  :labels=\"cartItemLabels\"\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=\"useTax\"\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=\"getLanguageString((rowCartItem as CartMainItem).product?.names, infra.language || 'NL', '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` follows the toggle (via useTax) so bonus lines\n                 share the same basis as the item lines and the total;\n                 currency/language resolve from the Propeller provider. -->\n            <component\n              :is=\"CartBonusItemsImpl\"\n              :cart=\"cart\"\n              :includeTax=\"useTax\"\n              className=\"mt-4\"\n              :labels=\"cartBonusItemsLabels\"\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                  >{{ getTotalLabel(\"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 { cn } from '../composables/shared/utils/cn';\nimport { computed, onMounted, ref, type Component } from \"vue\";\n\nimport { Cart, CartMainItem, Contact, Customer, GraphQLClient } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { useCart } from \"../composables/vue/useCart\";\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { getLabel as _getLabel, getLanguageString, isOverAuthorizationLimit, findPurchaserPac } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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, totalExclVat, itemsLabel, emptyCart,\n   * continueShopping, qty, total, checkoutButton, cartPageButton, closeLabel\n   */\n  labels?: Record<string, string>;\n\n  /**\n   * Labels forwarded to the inner CartItem rows (e.g. `qtyPrefix`). Without\n   * this the sidebar's line items fell back to English (\"Qty:\") even on a\n   * localized page. Keys match CartItem's label map.\n   */\n  cartItemLabels?: Record<string, string>;\n\n  /** Labels for the bonus-items block. Keys: `title`, `sku`. */\n  cartBonusItemsLabels?: 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}\n// Single source of truth for the tax basis so the line items, the grand total,\n// and the bonus items all agree AND follow the Incl./Excl. BTW toggle. Was: the\n// lines were pinned excl. (includeTax=false) while the total read totalNet\n// (incl.) — they never reconciled, and neither responded to the toggle. SDK\n// mapping: net = incl. VAT, gross = excl. VAT. Resolved from <PropellerProvider>.\nconst useTax = computed(() => !!infra.includeTax);\n// The figure follows the toggle, so the label has to as well. In excl. mode\n// this is the cart page's \"Total excl. VAT\", not its \"Total\" — an unqualified\n// \"Total\" here named a number one VAT amount below what the shopper is charged,\n// and the mini-cart is the figure they see first.\nfunction getTotalLabel(key: string): string {\n  return useTax.value\n    ? _getLabel(props.labels, key, \"Total\")\n    : _getLabel(props.labels, \"totalExclVat\", \"Total excl. VAT\");\n}\nfunction getTotalPrice(): ReturnType<CartIconAndSidebarState[\"getTotalPrice\"]> {\n  const total = useTax.value\n    ? props.cart?.total?.totalNet\n    : props.cart?.total?.totalGross;\n  return _formatPrice(total ?? 0, { symbol: (infra.currency as string | undefined) ?? \"€\", locale: localeForLanguage(props.language) });\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  // No PURCHASER config means no limit applies, so checkout stays open.\n  const pac = findPurchaserPac(infra.user as any, infra.companyId as any);\n  if (!pac) return true;\n  return !isOverAuthorizationLimit(\n    infra.user as any,\n    infra.companyId as any,\n    props.cart as any,\n  );\n}\nfunction showRequestAuthorizationButton(): ReturnType<\n  CartIconAndSidebarState[\"showRequestAuthorizationButton\"]\n> {\n  return isOverAuthorizationLimit(\n    infra.user as any,\n    infra.companyId as any,\n    props.cart as any,\n  );\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            ><!-- Full sentence with a {link} placeholder so the translation owns\n                  the wording AND spacing around the link (was \"de<a>…\", no\n                  space, English word order). -->{{ termsConsentParts.before\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            >{{ termsConsentParts.after }}</label\n          >\n        </div>\n      </template>\n\n      <!-- An over-limit purchaser reaching /checkout directly used to get the\n           full flow and an ungated \"Place order\" — the backend refused it with\n           CART_INVALID_STATUS_ERROR, so it ended in an error rather than the\n           authorization flow the cart page offers. -->\n      <template v-if=\"showPurchaseButton && overLimit\">\n        <p class=\"propeller-cart-overview__authorization-required text-sm text-muted-foreground mt-2\">\n          {{\n            getLabel(\n              'authorizationRequired',\n              'This order exceeds your authorization limit. Request authorization from the cart to continue.',\n            )\n          }}\n        </p>\n      </template>\n\n      <template v-if=\"showPurchaseButton && !overLimit\">\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, Contact, Customer, GraphQLClient } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel, isOverAuthorizationLimit } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { getCountryName as _getCountryName } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface CartOverviewProps {\n  /** GraphQL client for the Propeller SDK. Resolved from PropellerProvider when omitted. */\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\n  /** Maps a lowercased payment-method code to its display name. Falls back to the raw value. */\n  paymethodLabels?: Record<string, string>;\n\n  /** Logged-in user — used for the purchase-authorization check. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer | null;\n\n  /** Active company ID — used for the purchase-authorization check. Resolved from PropellerProvider when omitted. */\n  companyId?: number;\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 infra = useInfraProps(props);\n\n// Same predicate CartSummary and the cart sidebar use, against props.cart —\n// so the checkout page cannot contradict what the cart already said.\nconst overLimit = computed(() =>\n  isOverAuthorizationLimit(\n    (infra.user ?? props.user) as never,\n    (infra.companyId ?? props.companyId) as never,\n    props.cart as never,\n  ),\n);\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  const raw = props.cart?.paymentData?.method || \"\";\n  if (!raw) return \"\";\n  return props.paymethodLabels?.[raw.toLowerCase()] || raw;\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  // Numeric day-first DD-MM-YYYY. `toLocaleDateString()` with no locale used the\n  // runtime default (US M/D/YYYY on many hosts). Fixed, locale-neutral.\n  const d = new Date(date);\n  if (isNaN(d.getTime())) return date;\n  const day = String(d.getDate()).padStart(2, \"0\");\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  return `${day}-${month}-${d.getFullYear()}`;\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}\n// Split the terms-consent template around {link} so the anchor renders in place\n// and the translation owns the wording + spacing.\nconst termsConsentParts = computed(() => {\n  const tpl = getLabel(\"termsConsent\", \"I agree to the {link}\");\n  const [before, after = \"\"] = tpl.split(\"{link}\");\n  return { before, after };\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-2 sm:grid-cols-3 lg:grid-cols-4 gap-3\"\n        role=\"radiogroup\"\n        :aria-label=\"getLabel('methodsLabel', 'Payment method')\"\n      >\n        <template :key=\"method.code\" v-for=\"(method, index) in payMethods\">\n          <div\n            @click=\"async (event) => handleSelect(method)\"\n            @keydown=\"radioGroupKeydown\"\n            role=\"radio\"\n            :aria-checked=\"activeCode === method.code ? 'true' : 'false'\"\n            :tabindex=\"radioTabIndex(activeCode === method.code, index, activeCode !== '')\"\n            :data-selected=\"activeCode === method.code ? 'true' : 'false'\"\n            :class=\"`propeller-cart-paymethods__method relative cursor-pointer border rounded-[var(--radius-container)] p-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-secondary focus-visible:ring-offset-1 flex flex-col items-center justify-center gap-2 text-center aspect-square transition-all ${\n              activeCode === method.code\n                ? 'border-secondary bg-secondary/5 shadow-sm'\n                : 'border-border hover:border-secondary/30'\n            }`\"\n          >\n            <template v-if=\"method.price > 0\">\n              <span\n                class=\"propeller-cart-paymethods__method-price absolute top-2 right-2 text-xs bg-surface-hover text-muted-foreground px-2 py-0.5 rounded-full\"\n                >{{ formatMethodPrice(method.price) }}</span\n              >\n            </template>\n            <template v-if=\"showLogo && getLogoUrl(method)\">\n              <span\n                class=\"propeller-cart-paymethods__method-logo-wrap flex items-center justify-center h-10 w-full\"\n              >\n                <img\n                  class=\"propeller-cart-paymethods__method-logo max-h-10 max-w-[80%] w-auto object-contain\"\n                  :src=\"getLogoUrl(method)\"\n                  :alt=\"methodName(method)\"\n                />\n              </span>\n            </template>\n            <span\n              class=\"propeller-cart-paymethods__method-name font-medium text-sm\"\n              >{{ methodName(method) }}</span\n            >\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, onMounted, 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 { localeForLanguage } from '@propeller-commerce/propeller-v2-core-ui';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { radioGroupKeydown, radioTabIndex } from '../composables/shared/utils/radioGroup';\nimport { pickPreselected } from '../composables/shared/utils/preselect';\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. Resolved from PropellerProvider when omitted. */\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  /** Display the payment method logo (default: true). Falls back to the name when no logo is set. */\n  showPaymethodLogo?: 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\n  /**\n   * Localized display names for payment methods, keyed by the method **code**\n   * (lower-cased, e.g. `{ pickup: 'Bij afhalen', on_account: 'Op rekening' }`).\n   * The backend `method.name` is often an un-localized English string, so this\n   * map lets the host override it per locale. Lookup order:\n   * `paymethodLabels[code]` → `method.name` → `method.code`.\n   */\n  paymethodLabels?: Record<string, string>;\n}\ninterface CartPaymethodsState {\n  selectedCode: string;\n  containerClass: string;\n  showOnAccountForGuests: boolean;\n  showLogo: 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  getLogoUrl: (method: CartPaymethod) => string;\n  handleSelect: (method: CartPaymethod) => void;\n}\n\nconst props = withDefaults(defineProps<CartPaymethodsProps>(), {\n  showOnAccountForGuests: false,\n  showPaymethodLogo: true,\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 showLogo = computed(() => {\n  return props.showPaymethodLogo !== undefined ? props.showPaymethodLogo : true;\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    // `.value` matters: both are computed refs, and a ref object is always\n    // truthy — without it \"on account\" was never hidden from guests, and it\n    // could then win the preselection below.\n    if (!showOnAccountForGuests.value && isGuest.value && isOnAccountMethod(m)) {\n      return false;\n    }\n    return true;\n  });\n});\n\n// Something is always selected — the cart's stored method, else the first one\n// offered, so the user can hit Continue without a click. Computed\n// rather than assigned state so it is right in the first render; the cart\n// arrives after mount.\nconst preselected = computed(() =>\n  pickPreselected(\n    payMethods.value,\n    props.cart?.paymentData?.method as string | undefined,\n    (m: CartPaymethod) => m.code,\n  ),\n);\nconst activeCode = computed(() => selectedCode.value || preselected.value?.code || \"\");\n\n// Report the preselection upwards so the host persists it and the order\n// summary shows THIS method's transaction costs; the host skips the mutation\n// when the cart already stores it. Deliberately NOT an `immediate` watch —\n// that also fires during SSR, where the callback would mutate the cart while\n// rendering. A user pick sets `selectedCode` and takes over from here.\nfunction notifyPreselection() {\n  if (selectedCode.value || !preselected.value) return;\n  if (props.onPaymethodSelect) props.onPaymethodSelect(preselected.value);\n}\nwatch(() => preselected.value?.code, notifyPreselection);\nonMounted(notifyPreselection);\n// Localized display name: host override by code → backend name → code.\nfunction methodName(method: CartPaymethod): string {\n  const code = (method.code || \"\").toLowerCase();\n  return props.paymethodLabels?.[code] || method.name || method.code || \"\";\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 ?? \"€\", locale: localeForLanguage(infra.language) });\n}\nfunction getLogoUrl(\n  method: CartPaymethod,\n): ReturnType<CartPaymethodsState[\"getLogoUrl\"]> {\n  return method.logo || \"\";\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\n    :class=\"`propeller-cart-summary w-full bg-card p-6 rounded-[var(--radius-container)] shadow space-y-3 ${className || ''}`\"\n  >\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=\"hasTransactionCosts\">\n      <div class=\"propeller-cart-summary__row flex justify-between text-muted-foreground\" data-row=\"transaction-costs\">\n        <span class=\"propeller-cart-summary__label\">{{ getLabel('transactionCosts', 'Transaction costs:') }}</span\n        ><span class=\"propeller-cart-summary__value\">{{ formatItemPrice(transactionCosts) }}</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 } from '@propeller-commerce/propeller-sdk-v2';\nimport { useCart } from '../composables/vue/useCart';\nimport { getLabel as _getLabel, isOverAuthorizationLimit } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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  /** Extra classes for the panel root, appended after the defaults. */\n  className?: string;\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  hasTransactionCosts: boolean;\n  transactionCosts: 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 || getLabel('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});\n// Transaction costs are already inside total.totalGross, so without this line\n// the panel's own rows never add up to \"Total excl. VAT\". Mirrors\n// the transaction-costs row OrderTotals has always rendered.\nconst hasTransactionCosts = computed(() => {\n  return (props.cart?.paymentData?.price || 0) > 0;\n});\nconst transactionCosts = computed(() => {\n  return Number(props.cart?.paymentData?.price || 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  // Against props.cart, not the composable's internal one - see the note above.\n  isOverAuthorizationLimit(infra.user as any, infra.companyId as any, props.cart as any),\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 ?? '€', locale: localeForLanguage(infra.language) });\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 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\"> {{ getLabel('readLess', 'Read less') }} </template>\n\n          <template v-if=\"!expanded\"> {{ getLabel('readMore', '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 { getLabel as _getLabel, 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   * Resolved from PropellerProvider when omitted.\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\n  /** Translated labels: `readMore`, `readLess`. */\n  labels?: Record<string, 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);\nfunction getLabel(key: string, fallback: string): string {\n  return _getLabel(props.labels, key, fallback);\n}\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?.descriptions, 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  // Case-insensitive: media language casing is not guaranteed to match the\n  // storefront's. Compared inline rather than via core-ui's resolver because\n  // that one falls back to items[0], which would let a wrong-language variant\n  // on the FIRST media item beat a right-language one on a later item and\n  // collapse the pass ordering below.\n  const targetUpper = (target || '').toUpperCase();\n  const langMatches = (value?: string): boolean => (value || '').toUpperCase() === targetUpper;\n\n  for (const m of mediaItems) {\n    const match = m.imageVariants?.find((v) => langMatches(v.language) && v.url);\n    if (match?.url) return match.url;\n  }\n  for (const m of mediaItems) {\n    const match = m.images?.find((i) => langMatches(i.language) && 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 flex-col gap-2 md:flex-row md:items-center md:gap-3 px-4 py-2 md:py-0 border-t md:border-t-0 border-border-subtle\"\n      >\n        <div\n          class=\"propeller-cluster-card__footer-meta flex items-center justify-between gap-3 md:contents\"\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=\"resolvedIncludeTax\"\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=\"resolvedIncludeTax\"\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        </div>\n\n        <div class=\"propeller-cluster-card__cta w-full md:w-auto md:flex-shrink-0 md: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 min-w-0 items-center justify-center rounded-[var(--radius-control)] bg-primary px-3 sm: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              ><span class=\"propeller-cluster-card__cta-label min-w-0 truncate\">{{ getLabel(\"viewCluster\", \"View cluster\") }}</span></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        <div\n          v-if=\"showStock && !!cluster.defaultProduct?.inventory\"\n          class=\"hidden md:block\"\n        >\n          <slot\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        </div>\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        <div\n          v-if=\"!!getClusterPrice()\"\n          class=\"mt-auto hidden md:block\"\n        >\n          <slot\n            name=\"price\"\n            :cluster=\"cluster\"\n            :price=\"cluster.defaultProduct?.price\"\n            :includeTax=\"resolvedIncludeTax\"\n            :currency=\"currency\"\n            :labels=\"labels\"\n          >\n            <div class=\"propeller-cluster-card__price pt-1\">\n              <component\n                v-if=\"props.priceComponent\"\n                :is=\"PriceImpl\"\n                :price=\"cluster.defaultProduct?.price\"\n                :include-tax=\"resolvedIncludeTax\"\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>\n      <div\n        v-if=\"(showStock && !!cluster.defaultProduct?.inventory) || !!getClusterPrice()\"\n        class=\"propeller-cluster-card__footer-meta flex flex-wrap items-center justify-between gap-x-2 gap-y-1 px-3 pt-1 sm:px-4 md:hidden\"\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=\"!!getClusterPrice()\"\n          name=\"price\"\n          :cluster=\"cluster\"\n          :price=\"cluster.defaultProduct?.price\"\n          :includeTax=\"resolvedIncludeTax\"\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=\"resolvedIncludeTax\"\n            :currency=\"currency\"\n            :labels=\"labels\"\n          />\n          <span v-else class=\"propeller-cluster-card__price font-bold text-foreground text-base min-w-0 text-right\">{{\n            getClusterPrice()\n          }}</span>\n        </slot>\n      </div>\n      <div class=\"propeller-cluster-card__cta px-3 pb-3 pt-2 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 min-w-0 items-center justify-center rounded-[var(--radius-control)] bg-primary px-3 sm: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            ><span class=\"propeller-cluster-card__cta-label min-w-0 truncate\">{{ getLabel(\"viewCluster\", \"View cluster\") }}</span></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 { localeForLanguage } 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 { useInfraProps } from '../composables/vue/useInfraProps';\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  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  // NOTE: includeTax is resolved separately (see `infra`/`resolvedIncludeTax`\n  // below) because the infra fallback must read injected context at setup —\n  // useResolvedProps runs inside a `computed` here, where inject() returns null.\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\n// Resolve infra ONCE at setup (inject() is setup-only; lazy use inside a\n// computed yields null). The returned proxy is reactive, so the VAT toggle\n// still propagates. Effective flag: explicit prop > provider infra > false.\n// Vue coerces an absent boolean prop to `false`; treat only explicit `true` as\n// a host override and otherwise defer to the provider scope (VAT toggle).\nconst infra = useInfraProps(props);\nconst resolvedIncludeTax = computed<boolean>(() =>\n  props.includeTax === true ? true : !!infra.includeTax,\n);\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);\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 = resolvedIncludeTax.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 ?? \"€\", locale: localeForLanguage(props.language) });\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: string;\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.attributeName),\n    );\n    if (matchingAttr) {\n      const values = extractAttributeValues(matchingAttr);\n      if (values.length > 0) {\n        initial[setting.attributeName] = 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.attributeName],\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.attributeName]) {\n      previousSelections[prevSetting.attributeName] = selections[prevSetting.attributeName];\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.attributeName, index);\n    const selectedValue = sel[setting.attributeName] || \"\";\n    const isPreviousSelectionMissing =\n      index > 0 &&\n      sortedSettings\n        .slice(0, index)\n        .some((prev: ClusterConfigSetting) => !sel[prev.attributeName]);\n    const isDisabled =\n      availableValues.length === 0 || isPreviousSelectionMissing;\n    const displayName = getAttributeDisplayName(setting.attributeName);\n    const attributeType = getAttributeType(setting.attributeName);\n    return {\n      id: setting.uuid,\n      name: setting.attributeName,\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.attributeName === 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].attributeName];\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.attributeName,\n      i,\n      newSelections,\n    );\n    if (available.length > 0) {\n      newSelections[nextSetting.attributeName] = 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.attributeName],\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). Resolved from PropellerProvider when omitted. */\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, Contact, Customer, Product, YesNo } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel, isContentHidden, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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  /** Authenticated user. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer | null;\n\n  /**\n   * Portal access mode. In `'semi-closed'` option prices are omitted from the\n   * dropdown labels and preview for anonymous visitors.\n   */\n  portalMode?: 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\", locale: localeForLanguage(infra.language) });\n}\nfunction getProductName(\n  product: Product,\n): ReturnType<ClusterOptionsState[\"getProductName\"]> {\n  return (\n    getLanguageString((product as Product).names, infra.language || \"NL\") ||\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  const hidePrices = isContentHidden(props.portalMode, props.user, infra.isAuthenticated as boolean | undefined);\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: hidePrices\n          ? getProductName(p)\n          : `${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 = hidePrices\n            ? ''\n            : formatPrice(selectedProduct.price?.gross || 0);\n        }\n      }\n      const isRequired = option.isRequired === YesNo.Y;\n      return {\n        id: option.id,\n        idStr,\n        name: getLanguageString(option.names, infra.language || \"NL\", `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=\"cn(\n        'propeller-company-switcher__trigger flex items-center gap-2 rounded-[var(--radius-control)] px-3 py-1.5 text-sm font-medium transition-colors text-inherit',\n        triggerClassName,\n      )\"\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';\nimport { cn } from '../composables/shared/utils/cn';\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\n  /** Additional class name for the switcher's trigger button. */\n  triggerClassName?: 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      role=\"radiogroup\"\n      :aria-label=\"getLabel('deliveryDateLabel', 'Delivery date')\"\n    >\n      <template :key=\"index\" v-for=\"(dateStr, index) in upcomingDates\">\n        <div\n          @click=\"async (event) => handleSelect(dateStr)\"\n          @keydown=\"radioGroupKeydown\"\n          role=\"radio\"\n          :aria-checked=\"selectedDayKey !== '' && upcomingDayKeys[index] === selectedDayKey ? 'true' : 'false'\"\n          :tabindex=\"radioTabIndex(selectedDayKey !== '' && upcomingDayKeys[index] === selectedDayKey, index, selectedDayKey !== '')\"\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 focus:outline-none focus-visible:ring-2 focus-visible:ring-secondary focus-visible:ring-offset-1 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          @keydown=\"radioGroupKeydown\"\n          role=\"radio\"\n          :aria-checked=\"isCustomDateSelected ? 'true' : 'false'\"\n          aria-haspopup=\"dialog\"\n          :tabindex=\"radioTabIndex(isCustomDateSelected, upcomingDates.length, selectedDayKey !== '' || isCustomDateSelected)\"\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 focus:outline-none focus-visible:ring-2 focus-visible:ring-secondary focus-visible:ring-offset-1 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            :lang=\"inputLang\"\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';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { radioGroupKeydown, radioTabIndex } from '../composables/shared/utils/radioGroup';\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\n  /**\n   * Active language/locale (e.g. `'NL'`). Sets the `lang` attribute on the\n   * native `<input type=\"date\">` so the browser renders its calendar chrome\n   * (month name, weekday headers, Today/Clear) in that locale. Resolved from\n   * `<PropellerProvider>` when omitted. Quick-pick tile text is localized\n   * separately via `labels` (day_N / month_N keys).\n   */\n  language?: 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});\n// Explicit props win; otherwise infra (e.g. `language`) resolves from\n// <PropellerProvider>.\nconst infra = useInfraProps(props);\nconst inputLang = computed(() =>\n  infra.language ? String(infra.language).toLowerCase() : undefined,\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      // The cart's requestDate can be a weekend (e.g. the backend defaults to\n      // \"tomorrow\" without a business-day rule). Adopting it verbatim when\n      // skipWeekends is on drops the selected date into the \"Other date\" tile —\n      // it isn't one of the weekday quick-picks — so the soonest/selected date\n      // renders LAST, out of sequence, and the \"Other date...\" entry point is\n      // replaced by that date's label. When that happens, snap to the first\n      // valid weekday tile (the earliest offered delivery day) instead.\n      const parsed = new Date(normalized);\n      const isWeekend =\n        !isNaN(parsed.getTime()) &&\n        (parsed.getDay() === 0 || parsed.getDay() === 6);\n      const tiles = upcomingDates.value;\n      const adopt =\n        skipWeekends.value && isWeekend && tiles.length > 0\n          ? tiles[0]\n          : normalized;\n      selectedDate.value = adopt;\n      if (props.onDateSelect) {\n        props.onDateSelect(adopt);\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 WEEKDAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n  const MONTHS = [\n    \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n    \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\",\n  ];\n  // Weekday / month names go through `labels` so the tile reads in the active\n  // locale (e.g. NL \"ma, jul 20\") instead of hardcoded English. Keys:\n  // day_0..day_6 (Sun–Sat), month_0..month_11 (Jan–Dec); English is fallback.\n  const weekday = getLabel(`day_${date.getDay()}`, WEEKDAYS[date.getDay()]);\n  const month = getLabel(`month_${date.getMonth()}`, MONTHS[date.getMonth()]);\n  return weekday + \", \" + month + \" \" + 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, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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 getLanguageString(getProduct()?.names, infra.language || \"NL\", \"Product\");\n  }\n  return (\n    getLanguageString(getCluster()?.names, infra.language || \"NL\") ||\n    getLanguageString(getCluster()?.defaultProduct?.names, infra.language || \"NL\") ||\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 ?? \"€\", locale: localeForLanguage(props.language) });\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   * Pagination state: `page` (current page) and `pages` (total pages).\n   * Structural, so a `ProductsResponse` fits as-is and callers holding the two\n   * numbers on their own — `useSpareParts`, `FavoriteListDetails` — need no cast.\n   */\n  products: Pick<ProductsResponse, 'page' | 'pages'> | { page?: number; pages?: number };\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?.pages || 1;\n}\nfunction getCurrentPage(): ReturnType<GridPaginationState['getCurrentPage']> {\n  return props.products?.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()\"\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 to favorite list\") }}\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, getLanguageString } 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. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n\n  /** The logged in user for which the favorite list is going to be displayed. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer;\n\n  /**\n   * Active company ID from the company switcher.\n   * Overrides the user's default company for price calculation.\n   * Triggers a re-fetch when changed. */\n  companyId?: number;\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 getLanguageString((item as Product).names, infra.language || \"NL\", \"Product\");\n  const cluster = item as Cluster;\n  return (\n    getLanguageString(cluster.names, infra.language || \"NL\") ||\n    getLanguageString(cluster.defaultProduct?.names, infra.language || \"NL\") ||\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);\n\n// Prices are scoped to the active company — the loaded list is stale once it changes.\nwatch(\n  () => (infra.companyId as number | undefined) ?? props.companyId,\n  () => {\n    fetchList();\n  },\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      // Switcher selection wins; the contact's default company is the fallback.\n      const activeCompanyId =\n        (infra.companyId as number | undefined) ??\n        props.companyId ??\n        contact.company?.companyId;\n      if (activeCompanyId) {\n        priceInput.companyId = activeCompanyId;\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                              getTotalCount(list) === 1\n                                ? getLabel(\"itemSingular\", \"item\")\n                                : getLabel(\"itemPlural\", \"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              <!-- Full-sentence label with a {name} placeholder so the\n                   translation controls word order (Dutch strands the verb at\n                   the end). Split around {name}; the name is bold in place. -->\n              {{ deletePromptParts.before\n              }}<strong>{{ listToDelete?.name }}</strong>{{ deletePromptParts.after }}\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 type { FavoriteListChange } 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). Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer | null;\n\n  /** The initialized GraphQL Client instance. Resolved from PropellerProvider when omitted. */\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  /**\n   * Called after any list mutation succeeds, with what it did.\n   *\n   * The argument is optional so existing zero-argument callbacks keep working.\n   */\n  onListChanged?: (change?: FavoriteListChange) => 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  if (isNaN(d.getTime())) return 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  // Numeric day-first DD-MM-YYYY, consistent with the order components.\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\n// Split the delete-confirm template around {name} so the name renders bold in\n// place and the translation owns the word order + surrounding quotes.\nconst deletePromptParts = computed(() => {\n  const tpl = getLabel(\"deleteConfirm\", 'Are you sure you want to delete \"{name}\"?');\n  const [before, after = \"\"] = tpl.split(\"{name}\");\n  return { before, after };\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. Resolved from PropellerProvider when omitted. */\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              >{{ currencySymbol }}</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              >{{ currencySymbol }}</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=\"showAvailability()\">\n      <div class=\"propeller-grid-filters__availability space-y-3\">\n        <h3\n          class=\"propeller-grid-filters__availability-title text-xs font-semibold uppercase tracking-wide text-muted-foreground\"\n        >\n          {{ getLabel(\"availability\", \"Availability\") }}\n        </h3>\n        <div\n          class=\"propeller-grid-filters__availability-toggle inline-flex h-8 w-full rounded-[var(--radius-control)] border border-input overflow-hidden\"\n        >\n          <button\n            type=\"button\"\n            :class=\"`propeller-grid-filters__availability-option flex-1 text-xs font-medium transition-colors ${\n              availability === 'all' ? 'bg-secondary text-secondary-foreground' : 'bg-transparent text-muted-foreground hover:text-foreground'\n            }`\"\n            :aria-pressed=\"availability === 'all'\"\n            :disabled=\"!!isLoading\"\n            @click=\"() => handleAvailabilityChange('all')\"\n          >\n            {{ getLabel(\"allProducts\", \"All products\") }}\n          </button>\n          <button\n            type=\"button\"\n            :class=\"`propeller-grid-filters__availability-option flex-1 text-xs font-medium transition-colors ${\n              availability === 'in-stock' ? 'bg-secondary text-secondary-foreground' : 'bg-transparent text-muted-foreground hover:text-foreground'\n            }`\"\n            :aria-pressed=\"availability === 'in-stock'\"\n            :disabled=\"!!isLoading\"\n            @click=\"() => handleAvailabilityChange('in-stock')\"\n          >\n            {{ getLabel(\"inStock\", \"In stock\") }}\n          </button>\n        </div>\n        <div\n          v-if=\"availability === 'in-stock'\"\n          class=\"propeller-grid-filters__availability-quantity flex items-center gap-2 text-sm text-muted-foreground\"\n        >\n          <span>{{ getLabel(\"atLeast\", \"at least\") }}</span>\n          <div\n            class=\"propeller-grid-filters__availability-stepper inline-flex items-center h-8 rounded-[var(--radius-control)] border border-input bg-card overflow-hidden focus-within:ring-1 focus-within:ring-secondary\"\n          >\n            <button\n              type=\"button\"\n              class=\"propeller-grid-filters__quantity-decrease h-full w-8 flex items-center justify-center text-muted-foreground disabled:opacity-40 disabled:cursor-not-allowed hover:bg-accent hover:text-foreground transition-colors\"\n              :aria-label=\"getLabel('quantityDecrease', 'Decrease quantity')\"\n              :disabled=\"!!isLoading || minStock <= MIN_STOCK_THRESHOLD\"\n              @click=\"() => handleMinStockChange(minStock - 1)\"\n            >\n              −\n            </button>\n            <input\n              type=\"number\"\n              inputmode=\"numeric\"\n              class=\"propeller-grid-filters__availability-quantity-input w-10 h-full px-0 text-center font-medium text-foreground bg-transparent border-0 focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n              :aria-label=\"getLabel('atLeast', 'at least')\"\n              :min=\"MIN_STOCK_THRESHOLD\"\n              :step=\"1\"\n              :value=\"minStockInput\"\n              :disabled=\"!!isLoading\"\n              @input=\"(e) => (minStockInput = (e.target as HTMLInputElement).value)\"\n              @blur=\"() => commitMinStockInput()\"\n              @keyup.enter=\"(e) => (e.target as HTMLInputElement).blur()\"\n            />\n            <button\n              type=\"button\"\n              class=\"propeller-grid-filters__quantity-increase h-full w-8 flex items-center justify-center text-muted-foreground disabled:opacity-40 disabled:cursor-not-allowed hover:bg-accent hover:text-foreground transition-colors\"\n              :aria-label=\"getLabel('quantityIncrease', 'Increase quantity')\"\n              :disabled=\"!!isLoading\"\n              @click=\"() => handleMinStockChange(minStock + 1)\"\n            >\n              +\n            </button>\n          </div>\n          <span>{{ getLabel(\"pcs\", \"pcs\") }}</span>\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, computed } from 'vue';\n\nimport { Contact, Customer, AttributeFilter } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel, isContentHidden, type Availability, MIN_STOCK_THRESHOLD } from \"@propeller-commerce/propeller-v2-core-ui\";\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\nexport interface GridFiltersProps {\n  /** Currency symbol shown in the price-range inputs. Resolved from <PropellerProvider> when omitted; defaults to '€'. */\n  currency?: string;\n\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   * Show the availability (stock) section. Defaults to false so hosts opt in\n   * rather than gaining a new filter section on upgrade.\n   *\n   * The host should pass its own \"show stock\" setting here — a stock filter\n   * is meaningless when no stock is displayed anywhere in the grid. When\n   * truthy the section is still subject to the same semi-closed-portal\n   * visibility rule as the price filter (hidden for anonymous users).\n   */\n  showAvailabilityFilter?: boolean;\n\n  /**\n   * Currently active availability selection (URL-driven). Seeds the toggle\n   * on the first render so a restored filtered URL renders it correctly.\n   */\n  activeAvailability?: Availability;\n\n  /** Currently active minimum stock quantity (URL-driven). Undefined means the minimum. */\n  activeMinStock?: number;\n\n  /** Called on every toggle or stepper change with both values. */\n  onAvailabilityChange?: (sel: Availability, minStock: number) => void;\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  showAvailability: () => 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  handleAvailabilityChange: (value: Availability) => void;\n  handleMinStockChange: (value: number) => void;\n  commitMinStockInput: () => 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  showAvailabilityFilter: false,\n});\n\n// The glyph was a literal euro, so a non-euro shop had no handle on it.\nconst infra = useInfraProps(props);\nconst currencySymbol = computed(() => (infra.currency as string | undefined) ?? '€');\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// Seeded directly from `activeAvailability`/`activeMinStock` (not defaults +\n// a watcher) so the toggle/stepper are correct on the very first render, including SSR.\nconst availability = ref<Availability>(props.activeAvailability || \"all\");\nconst minStock = ref<number>((props.activeMinStock as number) ?? MIN_STOCK_THRESHOLD);\n// Raw buffer so the field can be cleared while typing; committed on blur/Enter.\nconst minStockInput = ref<string>(String((props.activeMinStock as number) ?? MIN_STOCK_THRESHOLD));\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    availability.value = \"all\";\n    minStock.value = MIN_STOCK_THRESHOLD;\n    minStockInput.value = String(MIN_STOCK_THRESHOLD);\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);\n// Adopt parent-supplied availability (URL state rehydration).\nwatch(\n  () => [props.activeAvailability, props.activeMinStock],\n  () => {\n    if (!props.activeAvailability) return;\n    availability.value = props.activeAvailability;\n    minStock.value = (props.activeMinStock as number) ?? MIN_STOCK_THRESHOLD;\n    minStockInput.value = String((props.activeMinStock as number) ?? MIN_STOCK_THRESHOLD);\n  },\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 showAvailability(): ReturnType<GridFiltersState[\"showAvailability\"]> {\n  if (!props.showAvailabilityFilter) return false;\n  return !isContentHidden(props.portalMode, props.user, infra.isAuthenticated as boolean | undefined);\n}\nfunction getFilterName(\n  filter: AttributeFilter,\n): ReturnType<GridFiltersState[\"getFilterName\"]> {\n  return (filter as AttributeFilter)?.attributeDescription?.name || \"\";\n}\n// Resolve the label in the active language; falls back to the first\n// description, then the raw attribute name.\nfunction getFilterTitle(\n  filter: AttributeFilter,\n): ReturnType<GridFiltersState[\"getFilterTitle\"]> {\n  const descriptions = (filter as AttributeFilter)?.attributeDescription\n    ?.descriptions;\n  const lang = props.language?.toUpperCase();\n  const match = lang\n    ? descriptions?.find((d) => d?.language?.toUpperCase() === lang)\n    : undefined;\n  return (\n    match?.value ||\n    descriptions?.[0]?.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  // Unlike React's GridFilters (where the equivalent counter omits\n  // availability and is never called), this counter IS used — include\n  // availability so it stays accurate.\n  if (availability.value === \"in-stock\") n += 1;\n  return n;\n}\nfunction hasActiveFilters(): ReturnType<GridFiltersState[\"hasActiveFilters\"]> {\n  const sel = selectedFilters.value as Record<string, string[]>;\n  const hasText = Object.keys(sel).some((k: string) => (sel[k] || []).length > 0);\n  return hasText || availability.value === \"in-stock\";\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 handleAvailabilityChange(\n  value: Availability,\n): ReturnType<GridFiltersState[\"handleAvailabilityChange\"]> {\n  const nextMinStock = value === \"all\" ? MIN_STOCK_THRESHOLD : minStock.value;\n  availability.value = value;\n  minStock.value = nextMinStock;\n  minStockInput.value = String(nextMinStock);\n  isPending.value = true;\n  if (props.onAvailabilityChange) props.onAvailabilityChange(value, nextMinStock);\n  if (props.getSelectedFilters) props.getSelectedFilters();\n}\nfunction handleMinStockChange(\n  value: number,\n): ReturnType<GridFiltersState[\"handleMinStockChange\"]> {\n  const n = Math.max(Math.floor(value) || MIN_STOCK_THRESHOLD, MIN_STOCK_THRESHOLD);\n  const prev = minStock.value;\n  minStock.value = n;\n  minStockInput.value = String(n);\n  if (n === prev) return;\n  isPending.value = true;\n  if (props.onAvailabilityChange) props.onAvailabilityChange(availability.value, n);\n  if (props.getSelectedFilters) props.getSelectedFilters();\n}\n// Commit the raw buffer on blur/Enter; empty or non-numeric falls back to the minimum.\nfunction commitMinStockInput(): ReturnType<GridFiltersState[\"commitMinStockInput\"]> {\n  const parsed = parseInt(minStockInput.value, 10);\n  handleMinStockChange(isNaN(parsed) ? MIN_STOCK_THRESHOLD : parsed);\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  availability.value = \"all\";\n  minStock.value = MIN_STOCK_THRESHOLD;\n  minStockInput.value = String(MIN_STOCK_THRESHOLD);\n  if (props.onClearFilters) props.onClearFilters();\n  if (props.getSelectedFilters) props.getSelectedFilters();\n}\n// Prefer `countActive`. Once a group has a selection, `count` is the\n// INTERSECTION with that selection — for an unticked sibling in a multi-select\n// (OR) group that is \"products carrying both values\", which is near-meaningless\n// and reads as a wildly low total: a season facet showing \"(1)\" that adds 2\n// products when ticked. `countActive` is the same option counted with its own\n// group's filters lifted (other groups still applied), which is what the option\n// actually contributes. With no selection in the group the backend returns\n// count === countActive, so this is a no-op there.\nfunction getCount(option: any): ReturnType<GridFiltersState[\"getCount\"]> {\n  const c = option?.count || 0;\n  const ca = option?.countActive || 0;\n  return 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\n    :class=\"`propeller-grid-filters-panel w-full lg:w-64 lg:flex-shrink-0 ${wrapperClassName || ''}`\"\n  >\n    <button\n      type=\"button\"\n      class=\"propeller-grid-filters-panel__trigger lg:hidden inline-flex items-center justify-center gap-2 h-10 px-4 rounded-[var(--radius-control)] border border-border bg-card text-sm font-medium text-foreground shadow-sm hover:bg-surface-hover transition-colors\"\n      @click=\"open = true\"\n      aria-haspopup=\"dialog\"\n      :aria-expanded=\"open\"\n    >\n      <svg\n        class=\"propeller-grid-filters-panel__trigger-icon w-[1.1em] h-[1.1em] flex-shrink-0\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        :strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden=\"true\"\n      >\n        <path d=\"M22 3H2l8 9.46V19l4 2v-8.54L22 3z\"></path>\n      </svg>\n      {{ getLabel(\"filtersButton\", \"Filters\") }}\n      <template v-if=\"activeFilterCount && activeFilterCount > 0\">\n        <span\n          class=\"propeller-grid-filters-panel__count inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full bg-secondary text-secondary-foreground text-xs font-semibold\"\n          >{{ activeFilterCount }}</span\n        >\n      </template>\n    </button>\n\n    <div\n      :class=\"`propeller-grid-filters-panel__backdrop lg:hidden fixed inset-0 z-40 bg-foreground/40 transition-opacity ${open ? 'opacity-100' : 'pointer-events-none opacity-0'}`\"\n      @click=\"open = false\"\n      aria-hidden=\"true\"\n    ></div>\n\n    <div\n      :class=\"`propeller-grid-filters-panel__panel fixed inset-y-0 left-0 z-50 w-80 max-w-[85vw] bg-card shadow-xl flex flex-col transition-transform duration-300 lg:static lg:z-auto lg:w-auto lg:max-w-none lg:translate-x-0 lg:bg-transparent lg:shadow-none lg:block ${open ? 'translate-x-0' : '-translate-x-full'}`\"\n      role=\"dialog\"\n      aria-modal=\"true\"\n    >\n      <div\n        class=\"propeller-grid-filters-panel__header lg:hidden flex items-center justify-between gap-3 px-4 h-14 border-b border-border-subtle flex-shrink-0\"\n      >\n        <span\n          class=\"propeller-grid-filters-panel__title text-base font-semibold text-foreground\"\n          >{{ getLabel(\"filtersButton\", \"Filters\") }}</span\n        >\n        <button\n          type=\"button\"\n          class=\"propeller-grid-filters-panel__close inline-flex items-center justify-center h-8 w-8 rounded-[var(--radius-control)] text-foreground-subtle hover:text-foreground hover:bg-surface-hover transition-colors\"\n          @click=\"open = false\"\n          :aria-label=\"getLabel('closeFilters', 'Close')\"\n        >\n          <svg\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            :strokeWidth=\"2\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            class=\"w-5 h-5\"\n          >\n            <path d=\"M18 6 6 18M6 6l12 12\"></path>\n          </svg>\n        </button>\n      </div>\n\n      <div\n        class=\"propeller-grid-filters-panel__body flex-1 overflow-y-auto px-4 py-4 lg:flex-none lg:overflow-visible lg:p-0\"\n      >\n        <GridFilters v-bind=\"gridFiltersProps\" :labels=\"labels\" />\n      </div>\n\n      <div\n        class=\"propeller-grid-filters-panel__footer lg:hidden px-4 py-3 border-t border-border-subtle flex-shrink-0\"\n      >\n        <button\n          type=\"button\"\n          class=\"propeller-grid-filters-panel__apply w-full inline-flex justify-center items-center h-10 px-6 rounded-[var(--radius-control)] text-sm font-medium text-primary-foreground bg-secondary hover:bg-secondary/90 transition-colors\"\n          @click=\"open = false\"\n        >\n          {{ getLabel(\"applyFilters\", \"Show results\") }}\n        </button>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from \"vue\";\nimport { getLabel as _getLabel } from \"@propeller-commerce/propeller-v2-core-ui\";\nimport GridFilters, { type GridFiltersProps } from \"./GridFilters.vue\";\n\nexport interface GridFiltersPanelProps extends GridFiltersProps {\n  /**\n   * Number of active filters, shown as a badge on the mobile trigger button.\n   * The host computes this from its active filter state. Omit or 0 to hide\n   * the badge.\n   */\n  activeFilterCount?: number;\n\n  /** Extra CSS class on the outer panel root. */\n  wrapperClassName?: string;\n}\n\nconst props = defineProps<GridFiltersPanelProps>();\n\nconst open = ref(false);\n\nconst gridFiltersProps = computed(() => {\n  const { activeFilterCount, wrapperClassName, labels, ...rest } = props;\n  return rest;\n});\n\nfunction getLabel(key: string, fallback: string): string {\n  return _getLabel(props.labels, key, fallback);\n}\n\nfunction onKey(e: KeyboardEvent): void {\n  if (e.key === \"Escape\") open.value = false;\n}\n\nwatch(open, (isOpen) => {\n  if (typeof document === \"undefined\") return;\n  if (isOpen) {\n    document.addEventListener(\"keydown\", onKey);\n    document.body.style.overflow = \"hidden\";\n  } else {\n    document.removeEventListener(\"keydown\", onKey);\n    document.body.style.overflow = \"\";\n  }\n});\n\nonUnmounted(() => {\n  if (typeof document === \"undefined\") return;\n  document.removeEventListener(\"keydown\", onKey);\n  document.body.style.overflow = \"\";\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 }} {{ itemsFound === 1 ? getLabel('productSingular') : getLabel('productPlural') }}</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') }}: {{ currencySymbol }} {{ priceFilterMin ?? 0 }} – {{ currencySymbol }}{{ priceFilterMax ?? '∞'\n            }}<span class=\"propeller-grid-toolbar__filter-badge-remove\">×</span></span\n          >\n        </template>\n\n        <template v-if=\"availability === 'in-stock'\">\n          <span\n            class=\"propeller-grid-toolbar__filter-badge propeller-grid-toolbar__filter-badge--availability 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 (onAvailabilityFilterRemove) onAvailabilityFilterRemove();\n              }\n            \"\n            >{{ getAvailabilityLabel() }}<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, computed } from 'vue';\n\nimport { Contact, Customer, ProductSortField, SortOrder } from '@propeller-commerce/propeller-sdk-v2';\nimport { type Availability, MIN_STOCK_THRESHOLD } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\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  productSingular: 'Product',\n  productPlural: 'Products',\n  from: 'from',\n  results: 'results',\n  perPage: ' per page',\n  price: 'Price',\n  inStock: 'In stock',\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   * Hide the price-ascending/descending sort options entirely. Default: false.\n   * Useful for closed B2B portals where prices are \"by quotation\".\n   */\n  hidePriceSort?: boolean;\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?: 'grid' | 'list';\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: 'grid' | 'list') => 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   * Currently active availability (stock) selection.\n   * Renders a single removable chip when set to `'in-stock'`.\n   */\n  availability?: Availability;\n\n  /** Currently active minimum stock quantity, shown on the chip above the default. */\n  minStock?: number;\n\n  /** Called when the availability filter badge × is clicked. */\n  onAvailabilityFilterRemove?: () => 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: 'grid' | 'list';\n  getLabel: (key: string) => string;\n  getSortOptions: () => string[];\n  getOffsetOptions: () => number[];\n  hasActiveFilters: () => boolean;\n  getActiveFilterBadges: () => FilterBadge[];\n  isPriceSortDisabled: () => boolean;\n  getAvailabilityLabel: () => string;\n  handleSortFieldChange: (field: string) => void;\n  handleSortOrderChange: (order: string) => void;\n  handleOffsetChange: (offset: number) => void;\n  handleViewChange: () => void;\n}\n\nconst props = defineProps<GridToolbarProps>();\n\n// The active price-filter chip rendered its euro inline as text — no prop and\n// no class, so a non-euro shop had no way to reach it at all.\nconst infra = useInfraProps(props);\nconst currencySymbol = computed(() => (infra.currency as string | undefined) ?? '€');\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;\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  const base = opts.length > 0 ? opts : ALL_SORT_FIELDS;\n  return props.hidePriceSort\n    ? base.filter((f) => f !== ProductSortField.PRICE)\n    : base;\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  const hasAvailability = props.availability === 'in-stock';\n  return hasText || hasPrice || hasAvailability;\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 getAvailabilityLabel(): ReturnType<GridToolbarState['getAvailabilityLabel']> {\n  const qty = props.minStock as number | undefined;\n  if (qty !== undefined && qty > MIN_STOCK_THRESHOLD) return `${getLabel('inStock')}: ${qty}+`;\n  return getLabel('inStock');\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  <button\n    type=\"button\"\n    :class=\"`propeller-login-to-order inline-flex items-center justify-center gap-2 h-10 px-4 w-full rounded-[var(--radius-control)] bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 transition-opacity ${className || ''}`\"\n    @click=\"handleClick\"\n  >\n    <User class=\"propeller-login-to-order__icon w-4 h-4\" aria-hidden=\"true\" />\n    {{ getLabel('loginToOrder', 'Log in to order') }}\n  </button>\n</template>\n\n<script setup lang=\"ts\">\nimport { User } from 'lucide-vue-next';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\n\nexport interface LoginToOrderButtonProps {\n  /**\n   * Invoked when the button is clicked. The host owns navigation — the package\n   * cannot know whether the app routes with a router push or a plain redirect.\n   * When omitted the button still renders but does nothing.\n   */\n  onLoginClick?: () => void;\n\n  /** Translated labels. Key: `loginToOrder`. */\n  labels?: Record<string, string>;\n\n  /** Extra classes appended to the button. */\n  className?: string;\n}\n\nconst props = defineProps<LoginToOrderButtonProps>();\n\nfunction getLabel(key: string, fallback: string): string {\n  return _getLabel(props.labels, key, fallback);\n}\n\nfunction handleClick(): void {\n  if (props.onLoginClick) props.onLoginClick();\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                          getLanguageString(child.product?.names, infra.language || \"NL\", \"Option\")\n                        }}</span\n                        ><span\n                          class=\"text-foreground-subtle whitespace-nowrap ml-2\"\n                          >{{ formatItemPrice(getItemTotalPrice(child)) }}</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, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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\n  /** Include tax in the line prices. Resolved from `PropellerProvider` when omitted; defaults to `false`. */\n  includeTax?: boolean;\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// The component read neither `includeTax` nor the toggle, so it printed line\n// prices always excl. VAT while `<CartItem>` on /cart followed the toggle —\n// the same lines on two tax bases in consecutive steps.\n// SDK mapping: net = incl. VAT, gross = excl. VAT.\nconst useTax = computed(() => !!infra.includeTax);\n/** Bundle / bundle-item price on the active tax basis. */\nfunction bundlePriceOf(price: any): number | null | undefined {\n  if (!price) return undefined;\n  return useTax.value ? price.net : price.gross;\n}\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 ?? \"€\", locale: localeForLanguage(props.language) });\n}\nfunction getItemName(item: any): ReturnType<ItemsOverviewState[\"getItemName\"]> {\n  return getLanguageString(item.product?.names, infra.language || \"NL\", \"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 (useTax.value ? item.totalSumNet : item.totalSum) || 0;\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 = bundlePriceOf(item.bundle?.price);\n  if (price === undefined || price === null) return \"\";\n  return _formatPrice(Number(price), { symbol: infra.currency ?? \"€\", locale: localeForLanguage(props.language) });\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 getLanguageString(leader.product.names, infra.language || \"NL\", \"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 = bundlePriceOf(leader.price);\n  if (price === undefined || price === null) return \"\";\n  return _formatPrice(Number(price), { symbol: infra.currency ?? \"€\", locale: localeForLanguage(props.language) });\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 getLanguageString(bundleItem.product?.names, infra.language || \"NL\", \"Product\");\n}\nfunction getBundleItemPrice(\n  bundleItem: any,\n): ReturnType<ItemsOverviewState[\"getBundleItemPrice\"]> {\n  const price = bundlePriceOf(bundleItem.price);\n  if (price === undefined || price === null) return \"\";\n  return _formatPrice(Number(price), { symbol: infra.currency ?? \"€\", locale: localeForLanguage(props.language) });\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 name=\"belowName\" :product=\"product\">\n            <div\n              v-if=\"BelowNameImpl\"\n              class=\"propeller-product-card__below-name\"\n            >\n              <component :is=\"BelowNameImpl\" :product=\"product\" />\n            </div>\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 flex-col gap-2 md:flex-row md:items-center md:gap-3 px-4 py-2 md:py-0 border-t md:border-t-0 border-border-subtle\"\n      >\n        <div\n          class=\"propeller-product-card__footer-meta flex items-center justify-between gap-3 md:contents\"\n        >\n        <slot\n          v-if=\"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=\"resolvedIncludeTax\"\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                resolvedIncludeTax\n              \"\n              :currency=\"currency\"\n              :labels=\"props.priceLabels\"\n            />\n            <ProductPriceDisplay\n              v-else\n              :price=\"product.price\"\n              :includeTax=\"\n                resolvedIncludeTax\n              \"\n              priceSize=\"text-sm\"\n              :labels=\"props.priceLabels\"\n              :portalMode=\"props.portalMode ?? infra.portalMode\"\n              :user=\"props.user ?? infra.user\"\n              :showLoginPrompt=\"false\"\n            />\n          </div>\n        </slot>\n        </div>\n\n        <div class=\"propeller-product-card__cta w-full md:w-auto md:flex-shrink-0 md:ml-auto\">\n          <slot\n            name=\"addToCart\"\n            :product=\"product\"\n            :cartId=\"props.cartId\"\n            :labels=\"props.addToCartLabels\"\n          >\n            <!-- Before the injected component so a host control is gated too. -->\n            <LoginToOrderButton\n              v-if=\"contentHidden\"\n              :labels=\"props.addToCartLabels\"\n              :on-login-click=\"props.onLoginClick\"\n            />\n            <component\n              v-else-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              :create-cart=\"props.createCart\"\n              :on-cart-created=\"props.onCartCreated\"\n              :include-tax=\"props.includeTax\"\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 name=\"belowName\" :product=\"product\">\n          <div\n            v-if=\"BelowNameImpl\"\n            class=\"propeller-product-card__below-name\"\n          >\n            <component :is=\"BelowNameImpl\" :product=\"product\" />\n          </div>\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        <div\n          v-if=\"showStock && !!props.product.inventory\"\n          class=\"hidden md:block\"\n        >\n          <slot\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        </div>\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        <div\n          v-if=\"showPrice !== false && !!product?.price\"\n          class=\"mt-auto hidden md:block\"\n        >\n          <slot\n            name=\"price\"\n            :product=\"product\"\n            :price=\"product.price\"\n            :includeTax=\"resolvedIncludeTax\"\n            :currency=\"currency\"\n            :labels=\"props.priceLabels\"\n          >\n            <div class=\"propeller-product-card__price pt-1\">\n              <component\n                v-if=\"props.priceComponent\"\n                :is=\"PriceImpl\"\n                :price=\"product.price\"\n                :include-tax=\"\n                  resolvedIncludeTax\n                \"\n                :currency=\"currency\"\n                :labels=\"props.priceLabels\"\n              />\n              <ProductPriceDisplay\n                v-else\n                :price=\"product.price\"\n                :includeTax=\"\n                  resolvedIncludeTax\n                \"\n                priceSize=\"text-base sm:text-lg\"\n                :labels=\"props.priceLabels\"\n                :portalMode=\"props.portalMode ?? infra.portalMode\"\n                :user=\"props.user ?? infra.user\"\n                :showLoginPrompt=\"false\"\n              />\n            </div>\n          </slot>\n        </div>\n      </div>\n\n      <div\n        v-if=\"(showStock && !!props.product.inventory) || (showPrice !== false && !!product?.price)\"\n        class=\"propeller-product-card__footer-meta flex flex-wrap items-center justify-between gap-x-2 gap-y-1 px-3 pt-1 sm:px-4 md:hidden\"\n      >\n        <slot\n          v-if=\"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=\"showPrice !== false && !!product?.price\"\n          name=\"price\"\n          :product=\"product\"\n          :price=\"product.price\"\n          :includeTax=\"resolvedIncludeTax\"\n          :currency=\"currency\"\n          :labels=\"props.priceLabels\"\n        >\n          <div class=\"propeller-product-card__price min-w-0 text-right\">\n            <component\n              v-if=\"props.priceComponent\"\n              :is=\"PriceImpl\"\n              :price=\"product.price\"\n              :include-tax=\"resolvedIncludeTax\"\n              :currency=\"currency\"\n              :labels=\"props.priceLabels\"\n            />\n            <ProductPriceDisplay\n              v-else\n              :price=\"product.price\"\n              :includeTax=\"resolvedIncludeTax\"\n              priceSize=\"text-base\"\n              :labels=\"props.priceLabels\"\n              :portalMode=\"props.portalMode ?? infra.portalMode\"\n              :user=\"props.user ?? infra.user\"\n              :showLoginPrompt=\"false\"\n            />\n          </div>\n        </slot>\n      </div>\n\n      <template v-if=\"showCta\">\n        <div class=\"propeller-product-card__cta px-3 pb-3 pt-2 sm:px-4 sm:pb-4\">\n          <slot\n            name=\"addToCart\"\n            :product=\"product\"\n            :cartId=\"props.cartId\"\n            :labels=\"props.addToCartLabels\"\n          >\n            <!-- Before the injected component so a host control is gated too. -->\n            <LoginToOrderButton\n              v-if=\"contentHidden\"\n              :labels=\"props.addToCartLabels\"\n              :on-login-click=\"props.onLoginClick\"\n            />\n            <component\n              v-else-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              :create-cart=\"props.createCart\"\n              :on-cart-created=\"props.onCartCreated\"\n              :include-tax=\"props.includeTax\"\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 { localeForLanguage } 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 { isContentHidden } from '@propeller-commerce/propeller-v2-core-ui';\nimport LoginToOrderButton from './LoginToOrderButton.vue';\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useResolvedProps, type ResolveSpec } from '../composables/vue/useResolvedProps';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\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). Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n\n  /** Authenticated user — used for cart creation / lookup. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer | null;\n\n  /**\n   * Portal access mode — `'open'` / `'semi-closed'` / `'closed'`. Resolved from\n   * PropellerProvider when omitted. In `'semi-closed'` the card hides price and\n   * stock from anonymous visitors and offers a log-in action in place of\n   * add-to-cart; signed-in users are unaffected.\n   */\n  portalMode?: string;\n\n  /**\n   * Invoked when an anonymous visitor clicks the log-in action that replaces\n   * add-to-cart in a semi-closed portal. The host owns navigation.\n   */\n  onLoginClick?: () => void;\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  /**\n   * Render arbitrary content directly below the product name (and above the\n   * short description / price), in both the grid and row layouts. Receives the\n   * product as a prop so hosts can surface extra info — e.g. package\n   * descriptions, custom badges — without forking the card. Consumers can also\n   * use the `#belowName` scoped slot directly; this prop is the cascadable\n   * (grid-wide) equivalent.\n   */\n  belowNameComponent?: Component;\n}\ninterface ProductCardState {\n  isFavorite: boolean;\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  allowIncrDecr: 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  // NOTE: includeTax is resolved separately (see `infra`/`resolvedIncludeTax`\n  // below) because the infra fallback must read injected context at setup —\n  // useResolvedProps runs inside a `computed` here, where inject() returns null.\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  belowNameComponent: { grid: 'belowNameComponent' },\n};\n\nconst resolved = computed(() => useResolvedProps(props, RESOLVE_SPEC));\n\n// Resolve infra ONCE at setup. `inject()` (inside useInfraProps) only works\n// during setup — calling it lazily from inside a `computed` getter yields a\n// null context, which is why the spec-based `resolved.value.includeTax` could\n// not see the provider's VAT flag. `useInfraProps` returns a reactive proxy,\n// so reads below still track provider changes (the VAT toggle).\nconst infra = useInfraProps(props);\n\n// Effective tax-inclusive flag: explicit prop > provider infra (VAT toggle) >\n// false. Used by both the price text and the embedded <ProductPrice> so they\n// can never disagree.\n// Vue coerces an absent `includeTax?: boolean` prop to `false`, so `false` is\n// indistinguishable from \"not set\". Treat only an explicit `true` as a host\n// override; otherwise defer to the provider scope (the VAT toggle). ProductGrid\n// already resolves the effective flag and passes it down explicitly.\nconst resolvedIncludeTax = computed<boolean>(() =>\n  props.includeTax === true ? true : !!infra.includeTax,\n);\n\n// Read through `infra` so call sites need not thread portalMode/user.\nconst contentHidden = computed<boolean>(() =>\n  isContentHidden(\n    (props.portalMode ?? infra.portalMode) as string | undefined,\n    (props.user ?? infra.user) as Contact | Customer | null | undefined,\ninfra.isAuthenticated as boolean | undefined,\n  ),\n);\nconst showStock = computed<boolean>(() => !!props.showStock && !contentHidden.value);\n// Keep the CTA slot when hidden — it carries the log-in action instead.\nconst showCta = computed<boolean>(\n  () => props.allowAddToCart !== false || contentHidden.value,\n);\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// No default — renders only when a host supplies a belowNameComponent (or uses\n// the #belowName slot). `null` so the `v-if=\"BelowNameImpl\"` guard skips it.\nconst BelowNameImpl = computed(() => resolved.value.belowNameComponent ?? null);\n\nconst isFavorite = ref<ProductCardState[\"isFavorite\"]>(false);\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 = resolvedIncludeTax.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 ?? \"€\", locale: localeForLanguage(props.language) });\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  <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=\"resolvedIncludeTax\"\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=\"resolvedIncludeTax\"\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                  :onLoginClick=\"props.onLoginClick\"\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, isContentHidden, type Availability } from \"@propeller-commerce/propeller-v2-core-ui\";\nimport { useInfraProps } from \"../composables/vue/useInfraProps\";\nimport { usePropellerContext } from \"../context/PropellerContext\";\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  /** Scope the product fetch to specific orderlist IDs (e.g. a chosen B2B contract). */\n  orderlistIds?: number[];\n\n  /**\n   * Apply the orderlist filter. Defaults to `true` when `orderlistIds` is\n   * non-empty, `false` otherwise — so an authenticated user without a contract\n   * still sees the full catalogue.\n   */\n  applyOrderlists?: boolean;\n\n  /**\n   * Attribute names to request per product, e.g. `['MPN']` — makes\n   * `product.attributes` usable in card slots. Unset returns the first page of\n   * ALL attributes (12 per product), so products with more than 12 silently\n   * lose the rest.\n   */\n  productTrackAttributes?: 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   * Active stock selection from the filters sidebar. Triggers a re-fetch when\n   * changed. `'all'` or undefined means no stock filter.\n   */\n  availability?: Availability;\n\n  /** Minimum stock quantity for the `'in-stock'` selection. Defaults to the minimum threshold. */\n  minStock?: 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   * Called when an anonymous visitor clicks the log-in action that replaces\n   * add-to-cart in a semi-closed portal. The host owns navigation.\n   */\n  onLoginClick?: () => 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\n  /**\n   * Render arbitrary content directly below each card's product name. Receives\n   * the product as a prop; cascades to every ProductCard via ProductGridConfig.\n   * Lets hosts surface extra per-product info (e.g. package descriptions)\n   * across the whole grid without swapping the entire card.\n   */\n  belowNameComponent?: 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  // Must stay `undefined`: `useProductInfo` reads `=== false` as \"the host\n  // deliberately disabled orderlist scoping\". Vue casts an absent Boolean prop\n  // to `false`, so contract scoping was switched off on every grid that did not\n  // pass this explicitly.\n  applyOrderlists: undefined,\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// Effective tax-inclusive flag for the whole grid, passed down to every card.\n// Vue coerces an absent `includeTax?: boolean` prop to `false`, so `false` is\n// indistinguishable from \"not set\" — `infra.includeTax` would therefore always\n// read the coerced `false` and shadow the provider. Resolve from the provider\n// context directly instead: an explicit `true` is a host opt-in; otherwise the\n// PropellerProvider scope (the VAT toggle) decides.\nconst ctxForTax = usePropellerContext();\nconst resolvedIncludeTax = computed<boolean>(() =>\n  props.includeTax === true\n    ? true\n    : !!(ctxForTax ? ctxForTax.includeTax : false),\n);\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  belowNameComponent: props.belowNameComponent,\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 orderlistIdsRef = computed(() => props.orderlistIds);\nconst applyOrderlistsRef = computed(() => props.applyOrderlists);\nconst productTrackAttributesRef = computed(() => props.productTrackAttributes);\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 availabilityRef = computed(() => props.availability);\nconst minStockRef = computed(() => props.minStock);\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  orderlistIds: orderlistIdsRef,\n  applyOrderlists: applyOrderlistsRef,\n  productTrackAttributes: productTrackAttributesRef,\n  language: langRef,\n  taxZone: props.taxZone,\n  user: userRef,\n  companyId: companyRef,\n  textFilters: textFiltersRef,\n  priceFilterMin: priceMinRef,\n  priceFilterMax: priceMaxRef,\n  availability: availabilityRef,\n  minStock: minStockRef,\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 allow = (props.allowAddToCart as boolean) !== false;\n  // Anonymous visitors only — a signed-in user keeps add-to-cart.\n  return (\n    !isContentHidden(\n      infra.portalMode as string | undefined,\n      (props.user ?? infra.user) as Contact | Customer | null | undefined,\ninfra.isAuthenticated as boolean | undefined,\n    ) && allow\n  );\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 :class=\"className\">\n    <!-- ── Root render ─────────────────────────────────────────────────────── -->\n    <template v-if=\"isRoot\">\n      <h1 class=\"propeller-grid-title mb-6 text-2xl font-semibold\">\n        {{ rootTitle ?? 'Machines' }}\n      </h1>\n      <p v-if=\"rootLoading\" class=\"py-12 text-center text-foreground-subtle\">\n        {{ getMachineLabel('loading', 'Loading…') }}\n      </p>\n      <p v-else-if=\"rootCards.length === 0\" class=\"py-12 text-center text-foreground-subtle\">\n        {{ getMachineLabel('noMachines', 'No machines found.') }}\n      </p>\n      <!-- Bare `grid` (no `grid-cols-1`) is 1 implicit column on mobile. Do NOT\n           add `grid-cols-1`: a consumer app that ships its own Tailwind build\n           after this package's CSS emits an unprefixed `.grid-cols-1` that wins\n           the cascade tie and pins the grid to one column at every breakpoint\n           (ProductGrid dodges this with a `grid-cols-2` base). -->\n      <div v-else class=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        <MachineCard\n          v-for=\"entry in rootCards\"\n          :key=\"entry.machine.id\"\n          :machine=\"entry.machine\"\n          :href=\"entry.href\"\n          :language=\"machineLanguage\"\n          :labels=\"machineCardLabels\"\n        />\n      </div>\n    </template>\n\n    <!-- The slug resolved in no language we know of. Without this the page\n         rendered a title title-cased from the URL above an empty parts list and\n         no error, so a machine that could not be opened looked exactly like one\n         with no parts (PWP-993). -->\n    <template v-else-if=\"notFound && !partsLoading\">\n      <nav aria-label=\"Breadcrumb\" class=\"propeller-breadcrumbs mb-6\">\n        <ol class=\"flex flex-wrap items-center gap-2 text-sm text-foreground-subtle\">\n          <li>\n            <a :href=\"basePath\" class=\"hover:text-primary\">{{ rootTitle ?? 'Machines' }}</a>\n          </li>\n        </ol>\n      </nav>\n      <p class=\"py-12 text-center text-foreground-subtle\">\n        {{ getMachineLabel('machineNotFound', 'This machine could not be found.') }}\n      </p>\n    </template>\n\n    <!-- ── Node render ─────────────────────────────────────────────────────── -->\n    <template v-else>\n      <!-- Breadcrumbs from the URL segments — leaf name from the fetched machine,\n           ancestors title-cased from their slug (backend only knows the leaf). -->\n      <nav aria-label=\"Breadcrumb\" class=\"propeller-breadcrumbs mb-6\">\n        <ol class=\"flex flex-wrap items-center gap-2 text-sm text-foreground-subtle\">\n          <li>\n            <a :href=\"basePath\" class=\"hover:text-primary\">{{ rootTitle ?? 'Machines' }}</a>\n          </li>\n          <li\n            v-for=\"(segment, i) in segments\"\n            :key=\"`${basePath}/${segments.slice(0, i + 1).join('/')}`\"\n            class=\"flex items-center gap-2\"\n          >\n            <span aria-hidden=\"true\">/</span>\n            <span\n              v-if=\"i === segments.length - 1\"\n              aria-current=\"page\"\n              class=\"text-foreground\"\n            >\n              {{ machineName }}\n            </span>\n            <a\n              v-else\n              :href=\"`${basePath}/${segments.slice(0, i + 1).join('/')}`\"\n              class=\"hover:text-primary\"\n            >\n              {{ slugToLabel(segment) }}\n            </a>\n          </li>\n        </ol>\n      </nav>\n\n      <h1 class=\"propeller-grid-title mb-6 text-2xl font-semibold\">{{ machineName }}</h1>\n\n      <!-- Child machines — their own section above the parts. A node with zero\n           parts still shows its children. -->\n      <div\n        v-if=\"childMachines.length > 0\"\n        class=\"propeller-machine-children mb-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-4\"\n      >\n        <template v-for=\"child in childMachines\" :key=\"`machine-${child.id}`\">\n          <MachineCard\n            :machine=\"child\"\n            :href=\"childSlugHref(child)\"\n            :language=\"machineLanguage\"\n            :labels=\"machineCardLabels\"\n          />\n        </template>\n      </div>\n\n      <div v-if=\"hasParts\" class=\"flex flex-col gap-8 lg:flex-row\">\n        <GridFiltersPanel\n          :filters=\"gridFilters\"\n          :priceMin=\"priceBoundsMin\"\n          :priceMax=\"priceBoundsMax\"\n          :onFilterChange=\"handleFilterChange\"\n          :onPriceChange=\"handlePriceRangeChange\"\n          :onClearFilters=\"clearAllFilters\"\n          :collapsed=\"true\"\n          :clearSignal=\"clearSignal\"\n          :activeTextFilters=\"listing.filters\"\n          :activePriceMin=\"listing.minPrice\"\n          :activePriceMax=\"listing.maxPrice\"\n          :isLoading=\"partsLoading\"\n          :labels=\"filtersLabels\"\n        />\n\n        <div class=\"w-full flex-1\">\n          <!-- In-node search box: draft synced to the URL term (reset on\n               back/forward/clear), read on submit. -->\n          <div class=\"mb-4 flex gap-2\">\n            <input\n              v-model=\"searchDraft\"\n              type=\"search\"\n              :placeholder=\"getMachineLabel('searchParts', 'Search parts…')\"\n              :aria-label=\"getMachineLabel('searchParts', 'Search parts')\"\n              class=\"w-full rounded border border-border bg-card px-3 py-2\"\n              @keydown.enter=\"submitSearch\"\n            />\n            <button\n              type=\"button\"\n              class=\"rounded bg-primary px-4 py-2 text-primary-foreground\"\n              @click=\"submitSearch\"\n            >\n              {{ toolbarLabels?.search ?? 'Search' }}\n            </button>\n          </div>\n\n          <div\n            class=\"sticky top-[80px] z-30 mb-2 bg-card/95 py-2 backdrop-blur lg:static lg:bg-transparent lg:py-0\"\n          >\n            <GridToolbar\n              :itemsFound=\"itemsFound\"\n              :page=\"currentPage\"\n              :pageSize=\"listing.offset\"\n              :pageItemCount=\"partProducts.length\"\n              :activeTextFilters=\"listing.filters\"\n              :priceFilterMin=\"listing.minPrice\"\n              :priceFilterMax=\"listing.maxPrice\"\n              :defaultSort=\"defaultSort\"\n              :onSortChange=\"(field: string, order: string) => handleSortChange(field, order as 'ASC' | 'DESC')\"\n              :onOffsetChange=\"handleOffsetChange\"\n              :viewMode=\"viewMode\"\n              :onViewChange=\"(mode: 'grid' | 'list') => (viewMode = mode)\"\n              :onFilterRemove=\"handleFilterRemove\"\n              :onPriceFilterRemove=\"() => handlePriceRangeChange(undefined, undefined)\"\n              :onClearFilters=\"clearAllFilters\"\n              :labels=\"toolbarLabels\"\n            />\n          </div>\n\n          <!-- Always controlled: `useSpareParts` owns fetching, the grid renders. -->\n          <ProductGrid\n            :products=\"partProducts\"\n            :isLoading=\"partsLoading\"\n            :onProductClick=\"onProductClick\"\n            :allowAddToCart=\"allowAddToCart\"\n            :showPrice=\"showPrice\"\n            :showModal=\"true\"\n            :createCart=\"createCart\"\n            :cartId=\"cartId\"\n            :onCartCreated=\"onCartCreated\"\n            :afterAddToCart=\"afterAddToCart\"\n            :columns=\"viewMode === 'list' ? 1 : 3\"\n            :showAvailability=\"showAvailability\"\n            :showStock=\"showStock\"\n            :productCardComponent=\"productCardComponent\"\n            :productCardLabels=\"productCardLabels\"\n            :addToCartLabels=\"addToCartLabels\"\n            :stockLabels=\"stockLabels\"\n            :priceLabels=\"priceLabels\"\n            :labels=\"labels\"\n            :belowNameComponent=\"QtyBelowName\"\n          />\n\n          <div class=\"mt-8\">\n            <GridPagination\n              :products=\"{ page: currentPage, pages: totalPages }\"\n              :onPageChange=\"handlePageChange\"\n              :labels=\"paginationLabels\"\n            />\n          </div>\n        </div>\n      </div>\n    </template>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * MachineGrid (Vue) — the spare-parts machine tree, as one self-contained grid.\n *\n * The machine-tree sibling of `ProductGrid`. Driven by the current URL path\n * (`segments`), it renders one of two modes:\n *  - **Root** (`segments` empty): resolves the company's installations in ONE\n *    concatenated request via `useMachines(source, sourceIds)` → `MachineCard`s.\n *  - **Node** (`segments` non-empty): fetches that machine by its leaf slug via\n *    `useSpareParts`, and renders its child machines (`MachineCard`s) above a\n *    category-style spare-parts listing (facets + toolbar + a permanently\n *    controlled `ProductGrid` + pagination, with the qty-in-machine below-name).\n *\n * Navigation between levels is via `MachineCard`'s `href` (built from `basePath`\n * + segments + child slug) — the package owns no router. The parts listing is\n * **controlled**: the current state comes in via `listing`, and every filter /\n * sort / page / search interaction emits the next state via `onListingChange`.\n * The host route maps that to the URL. Mirrors `propeller-v2-react-ui`'s\n * `MachineGrid`. The machine pages are CSR — the composables fetch client-only.\n */\nimport { computed, ref, watch, defineComponent, h, type Component } from 'vue';\nimport {\n  AttributeType,\n  type AttributeFilter,\n  type Cluster,\n  type Product,\n  type ProductSortField,\n  type SortOrder,\n  type Cart,\n  type CartMainItem,\n  type SparePartsMachine,\n  type ProductTextFilterInput,\n  type Contact,\n  type Customer,\n  type GraphQLClient,\n} from '@propeller-commerce/propeller-sdk-v2';\nimport { getLabel as _getLabel, getLocalizedValue } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { useMachines } from '../composables/vue/useMachines';\nimport { useSpareParts } from '../composables/vue/useSpareParts';\nimport ProductGrid from './ProductGrid.vue';\nimport MachineCard from './MachineCard.vue';\nimport GridFiltersPanel from './GridFiltersPanel.vue';\nimport GridToolbar from './GridToolbar.vue';\nimport GridPagination from './GridPagination.vue';\n\n/**\n * The controlled listing state for the spare-parts view — mirrors what the host\n * derives from the URL (`page`/`offset`/`sort`/attribute-`filters`/`price`/`term`).\n * Primitives + SDK enums only, so no app type leaks into the package.\n */\nexport interface MachineListingState {\n  page: number;\n  offset: number;\n  sortField: ProductSortField | string;\n  sortOrder: SortOrder | string;\n  /** Attribute name → selected facet values. */\n  filters: Record<string, string[]>;\n  minPrice?: number;\n  maxPrice?: number;\n  term: string;\n}\n\nexport interface MachineGridProps {\n  // ── Identity / navigation ────────────────────────────────────────────────\n  /** Current URL path under the machines root, e.g. `['mixer','frame']`. `[]` = root. */\n  segments: string[];\n  /** Localized machines base path (e.g. `/nl/machines`) — used to build hrefs. */\n  basePath: string;\n\n  // ── Root query ───────────────────────────────────────────────────────────\n  /** External system the installation ids belong to (root mode). */\n  source?: string;\n  /** Installation ids from `MY_INSTALLATIONS` (root mode). */\n  sourceIds?: string[];\n  /** Title for the root list. Defaults to `'Machines'`. */\n  rootTitle?: string;\n\n  // ── Tree ─────────────────────────────────────────────────────────────────\n  /** Language the machine tree is authored in (usually EN). Defaults to `'EN'`. */\n  machineLanguage?: string;\n  /**\n   * Other languages the tree may be authored in, tried in order when a slug\n   * does not resolve in `machineLanguage`.\n   *\n   * A slug resolves only in its own language, so a half-translated tree lists a\n   * machine by its NL slug and then cannot open it with `language: 'EN'`. Pass\n   * the shop's locales here; `machineLanguage` and the storefront `language`\n   * are always tried first (PWP-993).\n   */\n  machineLanguages?: string[];\n\n  // ── Controlled listing (parts) ───────────────────────────────────────────\n  listing: MachineListingState;\n  onListingChange: (next: MachineListingState) => void;\n\n  // ── Infra (resolved via useInfraProps; explicit wins) ────────────────────\n  graphqlClient?: GraphQLClient;\n  user?: Contact | Customer | null;\n  companyId?: number;\n  /** Storefront language (parts). */\n  language?: string;\n  taxZone?: string;\n  configuration?: { imageSearchFiltersGrid?: unknown; imageVariantFiltersMedium?: unknown };\n  portalMode?: string;\n\n  // ── Parts card pass-through (to the inner ProductGrid) ────────────────────\n  cartId?: string;\n  createCart?: boolean;\n  onCartCreated?: (cart: Cart) => void;\n  /**\n   * Fired after every successful add-to-cart (adds into an EXISTING cart too,\n   * not just the first create). Forward to the host cart store or the cart\n   * icon/sidebar/page won't reflect parts added from the grid.\n   */\n  afterAddToCart?: (cart: Cart, item?: CartMainItem) => void;\n  allowAddToCart?: boolean;\n  showPrice?: boolean;\n  showStock?: boolean;\n  showAvailability?: boolean;\n  onProductClick?: (product: Product) => void;\n\n  // ── Labels ────────────────────────────────────────────────────────────────\n  /**\n   * Custom card for the PARTS list, forwarded to the inner ProductGrid. Without\n   * it the same product looked different depending on the page it was reached\n   * from (PWP-995c).\n   */\n  productCardComponent?: Component;\n\n  paginationLabels?: Record<string, string>;\n  filtersLabels?: Record<string, string>;\n  toolbarLabels?: Record<string, string>;\n  /**\n   * Labels for the machine side of the grid.\n   *\n   * Keys read here: `loading`, `noMachines`, `machineNotFound`,\n   * `quantityInMachine` and `searchParts`. The same object is passed to each\n   * `MachineCard` as its `labels`, which reads `viewMachine` — so all six keys\n   * belong in it (PWP-995d).\n   *\n   * `quantityInMachine` and `searchParts` used to be read from `toolbarLabels`,\n   * which is forwarded verbatim to `GridToolbar`: a shop that translated its\n   * toolbar dictionary properly still got \"Qty in machine\" and \"Search parts…\"\n   * in English, because those keys belong to no toolbar (PWP-995a). They are\n   * still read from `toolbarLabels` as a fallback so existing hosts keep\n   * working.\n   */\n  machineCardLabels?: Record<string, string>;\n\n  /**\n   * Labels for the PARTS list, forwarded verbatim to the inner ProductGrid and\n   * the components it embeds.\n   *\n   * MachineGrid used to forward none of these and expose no way to reach them,\n   * so a translated storefront rendered \"In stock\", \"Add\" and \"Search parts…\"\n   * in English in the middle of its own copy (PWP-995a).\n   */\n  productCardLabels?: Record<string, string>;\n  addToCartLabels?: Record<string, string>;\n  stockLabels?: Record<string, string>;\n  priceLabels?: Record<string, string>;\n  labels?: Record<string, string>;\n\n  className?: string;\n}\n\n// Spelled out rather than left to `showStock ?? true` in the template: Vue casts\n// an ABSENT Boolean prop to `false`, not `undefined`, so `?? true` never fired\n// and the grid shipped with stock, prices and add-to-cart switched off unless\n// the host passed each one — while the React twin showed them (PWP-995).\nconst props = withDefaults(defineProps<MachineGridProps>(), {\n  createCart: true,\n  allowAddToCart: true,\n  showPrice: true,\n  showStock: true,\n  showAvailability: false,\n});\n/**\n * The grid's own strings. `machineCardLabels` first, then `toolbarLabels` for\n * hosts that already put `quantityInMachine` / `searchParts` there, then\n * English (PWP-995a).\n */\nfunction getMachineLabel(key: string, fallback: string): string {\n  return props.machineCardLabels?.[key] ?? props.toolbarLabels?.[key] ?? fallback;\n}\n\n// Explicit props win; otherwise infra resolves from <PropellerProvider>.\nconst infra = useInfraProps(props);\n\nconst isRoot = computed(() => props.segments.length === 0);\nconst currentSlug = computed(() => props.segments[props.segments.length - 1] ?? '');\nconst currentPath = computed(() => [props.basePath, ...props.segments].join('/'));\nconst machineLanguage = computed(() => props.machineLanguage ?? 'EN');\nconst language = computed(() => (infra.language as string) ?? 'NL');\nconst configuration = computed(\n  () => (props.configuration ?? (infra.configuration as MachineGridProps['configuration']))\n);\n\nconst viewMode = ref<'grid' | 'list'>('list');\nconst clearSignal = ref(0);\n\n// Facets / bounds / the fetched node arrive from the parts hook.\nconst gridFilters = ref<AttributeFilter[]>([]) as import('vue').Ref<AttributeFilter[]>;\nconst priceBoundsMin = ref<number | undefined>();\nconst priceBoundsMax = ref<number | undefined>();\nconst itemsFound = ref(0);\nconst machine = ref<SparePartsMachine | undefined>();\n\n/** Title-case a URL slug for a breadcrumb ancestor (no fetched name available). */\nfunction slugToLabel(slug: string): string {\n  return slug\n    .split('-')\n    .filter(Boolean)\n    .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n    .join(' ');\n}\n\nconst activeTextFilters = computed<ProductTextFilterInput[]>(() =>\n  Object.entries(props.listing.filters)\n    .filter(([, values]) => values.length > 0)\n    .map(([name, values]) => {\n      const def = gridFilters.value.find((f) => f.attributeDescription?.name === name);\n      return { name, values, exclude: false, type: def?.type ?? AttributeType.TEXT };\n    })\n);\n\n// ── Root: the installations, one concatenated request ──────────────────────\nconst { machines: rootMachines, isLoading: rootLoading } = useMachines({\n  graphqlClient: infra.graphqlClient as GraphQLClient | undefined,\n  source: computed(() => props.source),\n  // Only fetch the root list at the root — idle while drilled in.\n  sourceIds: computed(() => (isRoot.value ? props.sourceIds ?? [] : [])),\n  language: machineLanguage,\n  imageVariantFilters: configuration.value?.imageVariantFiltersMedium,\n});\n\n// ── Node: this machine's parts + direct children ───────────────────────────\nconst { displayParts, childMachines, isLoading: partsLoading, currentPage, totalPages, notFound } =\n  useSpareParts({\n    graphqlClient: infra.graphqlClient as GraphQLClient | undefined,\n    // Idle at the root (no slug).\n    slug: computed(() => (isRoot.value ? undefined : currentSlug.value)),\n    term: computed(() => props.listing.term || undefined),\n    language,\n    machineLanguage,\n    machineLanguages: computed(() => props.machineLanguages),\n    taxZone: props.taxZone,\n    user: computed(() => (infra.user as Contact | Customer | null) ?? null),\n    companyId: computed(() => infra.companyId as number | undefined),\n    textFilters: activeTextFilters,\n    priceFilterMin: computed(() => props.listing.minPrice),\n    priceFilterMax: computed(() => props.listing.maxPrice),\n    sortField: computed(() => props.listing.sortField as string),\n    sortOrder: computed(() => props.listing.sortOrder as string),\n    pageSize: computed(() => props.listing.offset),\n    // The composable takes the controlled page directly now. It used to own its\n    // own counter, so the only way to drive it from URL state was the watcher\n    // below - undiscoverable unless you read this file (PWP-995b).\n    page: computed(() => props.listing.page),\n    configuration: configuration.value,\n    onFiltersChange: (f) => (gridFilters.value = f),\n    onPriceBoundsChange: (min, max) => {\n      priceBoundsMin.value = min;\n      priceBoundsMax.value = max;\n    },\n    onItemsFoundChange: (c) => (itemsFound.value = c),\n    onMachineChange: (m) => (machine.value = m),\n  });\n\n// The parts hook owns its own page counter; feed the controlled URL page into\n// it or pagination writes the page to the URL but never refetches. Mirrors\n// ProductGrid's page sync; also resets to 1 when a filter/sort emit sets page=1.\nconst machineName = computed(() =>\n  machine.value ? getLocalizedValue(machine.value.name, machineLanguage.value) : slugToLabel(currentSlug.value)\n);\n\nconst partProducts = computed(\n  () => displayParts.value.map((p) => p.product).filter(Boolean) as unknown as (Product | Cluster)[]\n);\n\nconst quantityBySku = computed(() => {\n  const map = new Map<string, number>();\n  for (const part of displayParts.value) {\n    const sku = (part.product as { sku?: string } | undefined)?.sku ?? part.sku;\n    if (sku && typeof part.quantity === 'number') map.set(sku, part.quantity);\n  }\n  return map;\n});\n\nconst hasParts = computed(() => itemsFound.value > 0 || partProducts.value.length > 0);\n\nconst defaultSort = computed(() => [\n  { field: props.listing.sortField as string, order: props.listing.sortOrder as string },\n]);\n\n// `undefined` when the machine has no slug in ANY language — it genuinely has\n// no URL, so the card renders unlinked rather than vanishing. getLocalizedValue\n// already falls back across languages; the queries feeding it no longer narrow\n// to one (PWP-993).\nfunction childSlugHref(child: SparePartsMachine): string | undefined {\n  const slug = getLocalizedValue(child.slug, machineLanguage.value);\n  return slug ? `${currentPath.value}/${slug}` : undefined;\n}\n\nconst rootCards = computed(() =>\n  rootMachines.value.map((m) => ({ machine: m, href: childSlugHref(m) }))\n);\n\n// Per-card qty below the name. React uses a render-prop; Vue's ProductGrid\n// cascades a `belowNameComponent` (receiving `product`) through ProductGridConfig\n// — a stable component whose render reads the reactive qty map.\nconst QtyBelowName: Component = defineComponent({\n  name: 'MachinePartQuantity',\n  props: { product: { type: Object, required: true } },\n  setup(cprops) {\n    return () => {\n      const sku = (cprops.product as { sku?: string })?.sku;\n      const qty = sku ? quantityBySku.value.get(sku) : undefined;\n      if (!qty) return null;\n      const label = getMachineLabel('quantityInMachine', 'Qty in machine');\n      return h(\n        'span',\n        { class: 'propeller-spare-part__quantity text-sm text-foreground-subtle' },\n        `${label}: ${qty}`\n      );\n    };\n  },\n});\n\n// ── Listing intent → onListingChange (host maps to the URL) ─────────────────\nfunction emitListing(\n  nextFilters: Record<string, string[]>,\n  page = 1,\n  nextMin?: number,\n  nextMax?: number,\n  nextOffset?: number,\n  nextSortField?: ProductSortField | string,\n  nextSortOrder?: SortOrder | string,\n  nextTerm?: string\n): void {\n  props.onListingChange({\n    filters: nextFilters,\n    page,\n    minPrice: nextMin,\n    maxPrice: nextMax,\n    offset: nextOffset ?? props.listing.offset,\n    sortField: nextSortField ?? props.listing.sortField,\n    sortOrder: (nextSortOrder as SortOrder) ?? props.listing.sortOrder,\n    term: nextTerm ?? props.listing.term,\n  });\n}\n\nfunction handleFilterChange(filter: AttributeFilter, value: string | number): void {\n  const name = filter.attributeDescription?.name || '';\n  const current = props.listing.filters[name] || [];\n  const valueStr = String(value);\n  const next = current.includes(valueStr)\n    ? current.filter((v) => v !== valueStr)\n    : [...current, valueStr];\n  const nextFilters = { ...props.listing.filters, [name]: next };\n  if (next.length === 0) delete nextFilters[name];\n  emitListing(nextFilters, 1, props.listing.minPrice, props.listing.maxPrice, props.listing.offset, props.listing.sortField, props.listing.sortOrder);\n}\n\nfunction handlePriceRangeChange(newMin?: number, newMax?: number): void {\n  emitListing(props.listing.filters, 1, newMin, newMax, props.listing.offset, props.listing.sortField, props.listing.sortOrder);\n}\n\nfunction clearAllFilters(): void {\n  clearSignal.value += 1;\n  emitListing({}, 1, undefined, undefined, props.listing.offset, props.listing.sortField, props.listing.sortOrder, '');\n}\n\nfunction handleSortChange(field: string, order: 'ASC' | 'DESC'): void {\n  emitListing(props.listing.filters, 1, props.listing.minPrice, props.listing.maxPrice, props.listing.offset, field, order);\n}\n\nfunction handleOffsetChange(newOffset: number): void {\n  emitListing(props.listing.filters, 1, props.listing.minPrice, props.listing.maxPrice, newOffset, props.listing.sortField, props.listing.sortOrder);\n}\n\nfunction handlePageChange(page: number): void {\n  emitListing(props.listing.filters, page, props.listing.minPrice, props.listing.maxPrice, props.listing.offset, props.listing.sortField, props.listing.sortOrder);\n}\n\nfunction handleFilterRemove(filterName: string, value: string): void {\n  const current = props.listing.filters[filterName] || [];\n  const newVals = current.filter((v) => v !== value);\n  const nextFilters = { ...props.listing.filters, [filterName]: newVals };\n  if (newVals.length === 0) delete nextFilters[filterName];\n  emitListing(nextFilters, 1, props.listing.minPrice, props.listing.maxPrice, props.listing.offset, props.listing.sortField, props.listing.sortOrder);\n}\n\n// In-node search: draft synced to the URL term, read on submit.\nconst searchDraft = ref(props.listing.term);\nwatch(() => props.listing.term, (t) => (searchDraft.value = t));\nfunction submitSearch(): void {\n  emitListing(props.listing.filters, 1, props.listing.minPrice, props.listing.maxPrice, props.listing.offset, props.listing.sortField, props.listing.sortOrder, searchDraft.value);\n}\n</script>\n","<template>\n  <!-- Flyout styles lay each level out as a SIBLING column inside one flex row,\n       so the recursion emits the column then the next one alongside it. The\n       accordion nests its children inside the parent <li> instead. -->\n  <template v-if=\"variant === 'columns'\">\n    <ul\n      class=\"propeller-menu__list w-64 py-1 flex-shrink-0\"\n      :class=\"level + 1 < maxDepth ? 'border-r border-border' : ''\"\n      :data-level=\"level + 1\"\n    >\n      <li\n        v-for=\"(cat, idx) in items\"\n        :key=\"`l${level}-${cat.categoryId}-${idx}`\"\n        class=\"propeller-menu__item\"\n        :data-level=\"level + 1\"\n        :data-active=\"isOpen(cat) ? 'true' : 'false'\"\n        @mouseenter=\"emit('open', level, cat.categoryId)\"\n      >\n        <a\n          :href=\"getUrl(cat)\"\n          class=\"propeller-menu__link flex items-center justify-between px-4 py-2.5 text-sm transition-colors\"\n          :class=\"isOpen(cat) ? 'bg-accent text-accent-foreground' : 'text-foreground hover:bg-accent/50'\"\n          @click=\"(e) => onItemClick(cat, e)\"\n        >\n          <span class=\"propeller-menu__label\">{{ getName(cat) }}</span>\n          <svg\n            v-if=\"hasRenderableChildren(cat)\"\n            class=\"propeller-menu__chevron w-3.5 h-3.5 flex-shrink-0\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            stroke-width=\"2\"\n            stroke-linecap=\"round\"\n            stroke-linejoin=\"round\"\n            aria-hidden=\"true\"\n          >\n            <polyline points=\"9 18 15 12 9 6\" />\n          </svg>\n        </a>\n      </li>\n    </ul>\n    <MenuLevel\n      v-if=\"openChild\"\n      variant=\"columns\"\n      :items=\"getChildren(openChild)\"\n      :level=\"level + 1\"\n      :max-depth=\"maxDepth\"\n      :open-path=\"openPath\"\n      :get-url=\"getUrl\"\n      :get-name=\"getName\"\n      :get-children=\"getChildren\"\n      :on-item-click=\"onItemClick\"\n      @open=\"(l, id) => emit('open', l, id)\"\n      @toggle=\"(l, id) => emit('toggle', l, id)\"\n    />\n  </template>\n\n  <ul\n    v-else\n    class=\"propeller-menu__list\"\n    :class=\"level === 0 ? 'divide-y divide-border' : level === 1 ? 'bg-accent/30' : 'bg-accent/20'\"\n    :data-level=\"level + 1\"\n  >\n    <li\n      v-for=\"(cat, idx) in items\"\n      :key=\"`l${level}-${cat.categoryId}-${idx}`\"\n      class=\"propeller-menu__item\"\n      :data-level=\"level + 1\"\n      :data-expanded=\"isOpen(cat) ? 'true' : 'false'\"\n    >\n      <div class=\"flex items-center justify-between\">\n        <a\n          :href=\"getUrl(cat)\"\n          class=\"propeller-menu__link flex-1 py-3 text-sm text-foreground\"\n          :style=\"{ paddingLeft: `${1 + level}rem` }\"\n          @click=\"(e) => onItemClick(cat, e)\"\n        >\n          {{ getName(cat) }}\n        </a>\n        <button\n          v-if=\"hasRenderableChildren(cat)\"\n          type=\"button\"\n          class=\"propeller-menu__toggle cursor-pointer px-4 py-3 text-muted-foreground transition-colors hover:text-foreground\"\n          :aria-expanded=\"isOpen(cat)\"\n          :aria-label=\"getName(cat)\"\n          @click=\"emit('toggle', level, cat.categoryId)\"\n        >\n          <svg\n            class=\"propeller-menu__chevron w-3.5 h-3.5 transition-transform\"\n            :class=\"isOpen(cat) ? 'rotate-180' : ''\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            stroke-width=\"2\"\n            stroke-linecap=\"round\"\n            stroke-linejoin=\"round\"\n            aria-hidden=\"true\"\n          >\n            <polyline points=\"6 9 12 15 18 9\" />\n          </svg>\n        </button>\n      </div>\n      <MenuLevel\n        v-if=\"isOpen(cat) && hasRenderableChildren(cat)\"\n        variant=\"accordion\"\n        :items=\"getChildren(cat)\"\n        :level=\"level + 1\"\n        :max-depth=\"maxDepth\"\n        :open-path=\"openPath\"\n        :get-url=\"getUrl\"\n        :get-name=\"getName\"\n        :get-children=\"getChildren\"\n        :on-item-click=\"onItemClick\"\n        @open=\"(l, id) => emit('open', l, id)\"\n        @toggle=\"(l, id) => emit('toggle', l, id)\"\n      />\n    </li>\n  </ul>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { MenuCategory } from '../composables/vue/useMenu';\n\n/**\n * One level of the category menu, rendering itself for each deeper level.\n *\n * Recursion lives in its own component because a Vue SFC template cannot call\n * a local render function the way JSX can — a self-referencing component is the\n * idiomatic equivalent. State stays in `Menu.vue`: this receives the open path\n * and emits intent, so there is a single source of truth for what is open.\n */\nexport interface MenuLevelProps {\n  /** Categories to render at this level. */\n  items: MenuCategory[];\n  /** 0-based depth of this level. */\n  level: number;\n  /** Deepest level that may render, already resolved against the style's cap. */\n  maxDepth: number;\n  /** Open branch, root → deepest, as category ids. */\n  openPath: number[];\n  /** `'columns'` for the flyout styles, `'accordion'` for the nested mobile menu. */\n  variant: 'columns' | 'accordion';\n  /** Resolves a category's href — owned by `Menu.vue` (honours `getUrl`/config). */\n  getUrl: (cat: MenuCategory) => string;\n  /** Resolves a category's display name. */\n  getName: (cat: MenuCategory) => string;\n  /** Resolves a category's visible children. */\n  getChildren: (cat: MenuCategory) => MenuCategory[];\n  /** Click handler — owned by `Menu.vue` so SPA routing stays in one place. */\n  onItemClick: (cat: MenuCategory, e: any) => void;\n}\n\nconst props = defineProps<MenuLevelProps>();\nconst emit = defineEmits<{\n  (e: 'open', level: number, categoryId: number | null): void;\n  (e: 'toggle', level: number, categoryId: number): void;\n}>();\n\nfunction isOpen(cat: MenuCategory): boolean {\n  return props.openPath[props.level] === cat.categoryId;\n}\n\n/**\n * Whether to show the expand affordance. Gated on the child actually being\n * renderable at this depth — otherwise the chevron promises a level that never\n * appears.\n */\nfunction hasRenderableChildren(cat: MenuCategory): boolean {\n  return props.getChildren(cat).length > 0 && props.level + 1 < props.maxDepth;\n}\n\n/** The category whose column is open at this level, if any. */\nconst openChild = computed<MenuCategory | null>(() => {\n  if (props.level + 1 >= props.maxDepth) return null;\n  const openId = props.openPath[props.level];\n  const found = props.items.find((c) => c.categoryId === openId);\n  return found && props.getChildren(found).length > 0 ? found : null;\n});\n</script>\n","<template>\n  <div\n    :class=\"`propeller-menu ${className || ''}`\"\n    :data-variant=\"$slots.menu ? (menuStyle || 'custom') : getMenuStyle()\"\n    :data-loading=\"isLoading ? 'true' : 'false'\"\n  >\n    <!--\n      Custom renderer. The built-in styles are three arrangements of the same\n      tree; this is the escape hatch for a fourth, since an unrecognised\n      `menuStyle` string could never match a branch on its own. Exposes the\n      state and helpers the built-ins use, so a custom menu gets working\n      open/close, URL building and click handling rather than reimplementing\n      them and drifting. When present it owns the loading/error states too.\n    -->\n    <template v-if=\"$slots.menu\">\n      <slot\n        name=\"menu\"\n        :categories=\"menuCategories\"\n        :is-loading=\"isLoading\"\n        :has-error=\"hasError\"\n        :max-depth=\"maxDepth\"\n        :get-sub-categories=\"getSubCategories\"\n        :get-category-name=\"getCategoryName\"\n        :get-category-url=\"getCategoryUrl\"\n        :handle-item-click=\"handleItemClick\"\n        :open-path=\"openPath\"\n        :is-open-at=\"isOpenAt\"\n        :open-at=\"openAt\"\n        :toggle-at=\"toggleAt\"\n      />\n    </template>\n\n    <template v-if=\"!$slots.menu && 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=\"!$slots.menu && !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        !$slots.menu &&\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        !$slots.menu &&\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        <!--\n          `max-w-[100vw] overflow-x-auto` so a deep tree degrades to a scroll\n          rather than running off the viewport: at 5 levels the columns total\n          1280px, which clears a 1440px desktop but not a smaller laptop or a\n          trigger positioned mid-page.\n        -->\n        <div class=\"flex max-w-[100vw] overflow-x-auto bg-popover border border-border shadow-lg\">\n          <MenuLevel\n            variant=\"columns\"\n            :items=\"menuCategories\"\n            :level=\"0\"\n            :max-depth=\"maxDepth\"\n            :open-path=\"openPath\"\n            :get-url=\"getCategoryUrl\"\n            :get-name=\"getCategoryName\"\n            :get-children=\"getSubCategories\"\n            :on-item-click=\"handleItemClick\"\n            @open=\"openAt\"\n            @toggle=\"toggleAt\"\n          />\n        </div>\n      </nav>\n    </template>\n\n    <template\n      v-if=\"\n        !$slots.menu &&\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=\"isOpenAt(0, l1.categoryId) ? 'true' : 'false'\"\n              @mouseenter=\"async (event) => openAt(0, l1.categoryId)\"\n              @click=\"async (e) => handleItemClick(l1, e)\"\n              :class=\"`propeller-menu__tab cursor-pointer px-5 py-3 text-sm font-medium transition-colors border-b-2 ${\n                isOpenAt(0, 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=\"isOpenAt(0, 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) => openAt(0, l1.categoryId)\"\n              @mouseleave=\"async (event) => openAt(0, 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        !$slots.menu &&\n        !isLoading &&\n        !hasError &&\n\n        menuCategories.length > 0\n      \"\n    >\n      <!--\n        Accordion. Two roles:\n          • the mobile drawer for EVERY style (the flyout columns can't lay out\n            on a narrow screen), hence it renders regardless of `menuStyle`\n          • the desktop menu when `menuStyle=\"accordion\"` is chosen explicitly —\n            the only style with no layout ceiling, so the one to pick for trees\n            deeper than a flyout can show\n\n        Without the second role `menuStyle=\"accordion\"` matched no desktop\n        branch and rendered an empty panel above `md`, while the depth warning\n        recommended exactly that style for deep trees.\n      -->\n      <nav\n        :class=\"`propeller-menu__nav propeller-menu-mobile ${getMenuStyle() === 'accordion' ? 'block' : 'md:hidden'} ${menuClass || ''}`\"\n      >\n        <MenuLevel\n          variant=\"accordion\"\n          :items=\"menuCategories\"\n          :level=\"0\"\n          :max-depth=\"maxDepth\"\n          :open-path=\"openPath\"\n          :get-url=\"getCategoryUrl\"\n          :get-name=\"getCategoryName\"\n          :get-children=\"getSubCategories\"\n          :on-item-click=\"handleItemClick\"\n          @open=\"openAt\"\n          @toggle=\"toggleAt\"\n        />\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 MenuLevel from './MenuLevel.vue';\nimport { getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\n\n/** Every style with a built-in renderer — the source of truth for the union. */\nconst RENDERED_STYLES = ['dropdown-vertical', 'jumbotron', 'accordion'] as const;\n\nexport type MenuStyle = (typeof RENDERED_STYLES)[number];\n\nexport interface MenuProps {\n  /**\n   * Initialised Propeller SDK GraphQL client.\n   * Used internally to fetch the category hierarchy.\n   * Resolved from PropellerProvider when omitted.\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   * Resolved from PropellerProvider when omitted.\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). Lays each\n   *   level out as another 256px column, so it caps at 5 levels.\n   * - 'jumbotron': full-width mega-menu panel showing all subcategories.\n   * - 'accordion': inline vertical nesting at every breakpoint. The only style\n   *   with no depth ceiling — use it for trees deeper than a flyout can show.\n   *   (Also the mobile presentation of the other styles.)\n   *\n   * Typed as `MenuStyle | (string & {})` so the built-ins autocomplete while\n   * any other value still type-checks — pair a custom value with the `menu`\n   * slot to render it. Without that slot, an unrecognised value falls back to\n   * 'accordion' and warns in development.\n   */\n  menuStyle?: 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   * Custom URL builder for category links. Overrides `menuLinkFormat` /\n   * `configuration.urls.getCategoryUrl`. Lets hosts inject dynamic query strings\n   * (e.g. `?contract=…`) that a static format string cannot express.\n   * Mirrors the `getUrl` prop on Breadcrumbs.\n   */\n  getUrl?: (category: Category) => 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\n// Which branch is open, root → deepest, as category ids. One value instead of\n// a ref per level: \"opening a shallower item closes the deeper ones\" falls out\n// of `slice(0, level)` rather than a hand-written reset per level, which grows\n// quadratically and is easy to get wrong.\nconst openPath = ref<number[]>([]);\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  const category = {\n    categoryId: cat.categoryId,\n    slugs: [{ value: cat.slug, language: lang }],\n  } as Category;\n  // Consumer-provided URL builder takes precedence (mirrors Breadcrumbs.getUrl).\n  if (props.getUrl) return props.getUrl(category);\n  return infra.configuration?.urls?.getCategoryUrl(category, lang) ?? '#';\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      names: [{ value: cat.name, language: lang }],\n      slugs: [{ value: cat.slug, language: lang }],\n    } as Category);\n  }\n}\n/** Open `categoryId` at `level` (0-based), discarding any deeper open branch. */\nfunction openAt(level: number, categoryId: number | null): void {\n  const next = openPath.value.slice(0, level);\n  if (categoryId !== null) next.push(categoryId);\n  openPath.value = next;\n}\n\n/** Accordion variant — re-selecting the open item collapses it. */\nfunction toggleAt(level: number, categoryId: number): void {\n  openPath.value =\n    openPath.value[level] === categoryId\n      ? openPath.value.slice(0, level)\n      : [...openPath.value.slice(0, level), categoryId];\n}\n\n/** True when `categoryId` is the open branch at `level`. */\nfunction isOpenAt(level: number, categoryId: number): boolean {\n  return openPath.value[level] === categoryId;\n}\nfunction getLabel(key: string, fallback: string): string {\n  return _getLabel(props.labels, key, fallback);\n}\n/**\n * Levels the current style can actually display. The flyout style lays every\n * level out as another 256px column, so the ceiling is how many fit on screen:\n * 5 columns = 1280px, which clears a 1440px desktop. Past that they run off the\n * viewport. The accordion nests vertically and has no layout ceiling.\n *\n * Reads `getMenuStyle()`, not the raw prop, so an unrecognised style is capped\n * as the accordion it actually falls back to.\n */\nconst maxDepth = computed<number>(() => {\n  const requested = Math.max(1, props.depth ?? 3);\n  const style = getMenuStyle();\n  const cap = style === 'accordion' ? Number.POSITIVE_INFINITY : 5;\n  if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production' && requested > cap) {\n    console.warn(\n      `[Menu] depth={${requested}} exceeds what menuStyle=\"${style}\" can lay out (${cap}); rendering ${cap} levels. Use menuStyle=\"accordion\" for deeper trees.`\n    );\n  }\n  return Math.min(requested, cap);\n});\n\nfunction getMenuStyle(): MenuStyle {\n  const requested = (props.menuStyle as string | undefined) || 'dropdown-vertical';\n  if (!(RENDERED_STYLES as readonly string[]).includes(requested)) {\n    // A custom value is legitimate when paired with the `menu` slot — but we\n    // only reach here if that slot wasn't used, so the style genuinely has\n    // nothing to draw it. Fall back to the accordion (which can display any\n    // tree) rather than matching no branch and rendering an empty panel with\n    // no clue why.\n    if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n      console.warn(\n        `[Menu] menuStyle=\"${requested}\" has no built-in renderer (available: ${RENDERED_STYLES.join(', ')}); falling back to \"accordion\". Use the \\`menu\\` slot to draw a custom style.`\n      );\n    }\n    return 'accordion';\n  }\n  return requested as MenuStyle;\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. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n  /** The order to act upon */\n  order: Order;\n  /** The authenticated user. Resolved from PropellerProvider when omitted. */\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'. The\n    discount lives on a sibling 'incentive' item linked via parentOrderItemId,\n    so each line is netted against its siblings before display.\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 } from \"@propeller-commerce/propeller-sdk-v2\";\nimport { getLabel as _getLabel, getNettedBonusItems } 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  getNettedBonusItems(props.items ?? props.order?.items ?? []),\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 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\"\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                props.onSearchApply?.({});\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=\"\n              async (event) => {\n                fetchOrders(1);\n                props.onSearchApply?.(searchForm);\n              }\n            \"\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${flat ? '' : ' 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 v-if=\"!hideHeader\" 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 ${rowsClickable ? 'cursor-pointer' : ''}`\"\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                            >{{ statusLabel(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${flat ? '' : ' 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      <!--\n        A centred line of text collapsed the list to one row and then snapped it\n        back, which is what made a language switch on the account pages look\n        broken. Skeleton rows hold the layout instead.\n      -->\n      <div\n        class=\"propeller-order-list__loading p-4\"\n        aria-busy=\"true\"\n        :aria-label=\"getLabel('loading', 'Loading orders...')\"\n      >\n        <div\n          v-for=\"index in 3\"\n          :key=\"index\"\n          class=\"propeller-order-list__skeleton-row flex items-center gap-4 py-4 border-b border-border last:border-b-0 animate-pulse\"\n        >\n          <div class=\"propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-24\" />\n          <div class=\"propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-32\" />\n          <div class=\"propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-20 ml-auto\" />\n        </div>\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, type OrderSearchForm } from \"../composables/vue/useOrders\";\nimport { formatPrice as _formatPrice } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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). Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer | null;\n\n  /** Currency symbol to display. Defaults to '€'. */\n  currency?: string;\n\n  /** The initialized GraphQL Client instance. Resolved from PropellerProvider when omitted. */\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  /**\n   * Seed the filter form on mount — typically rehydrated from the URL query so\n   * a bookmarked/shared filtered view restores on reload. Pair with\n   * `onSearchApply` so the page can keep the URL in sync when filters change.\n   */\n  initialSearchForm?: OrderSearchForm;\n\n  /**\n   * Fires when the user applies or clears filters (the \"Search\"/\"Clear\"\n   * buttons). Receives the active filter form. Use it to persist the filters\n   * to the URL — the component owns no router, so the page decides how (and\n   * whether) to reflect them in `location`.\n   */\n  onSearchApply?: (form: OrderSearchForm) => void;\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  /** Hide the column header row. Defaults to false. */\n  hideHeader?: boolean;\n\n  /** Drop the results container's card chrome (background/border/shadow). Defaults to false. */\n  flat?: 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  /**\n   * Localized display labels for order/quote statuses, keyed by the raw backend\n   * status value (e.g. `{ NEW: 'Nieuw', CONFIRMED: 'Bevestigd', REQUEST:\n   * 'Aangevraagd' }`). Unknown statuses fall back to the raw value.\n   */\n  statusLabels?: Record<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 = withDefaults(defineProps<OrderListProps>(), {\n  hideHeader: false,\n  flat: false,\n});\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  initialSearchForm: props.initialSearchForm,\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  // Numeric day-first DD-MM-YYYY. `toLocaleDateString()` with no locale used\n  // the runtime default (US M/D/YYYY on many hosts), misreading dates by months\n  // on NL. Fixed, locale-neutral order; override via `props.formatDate`.\n  const d = new Date(dateString);\n  if (isNaN(d.getTime())) return dateString;\n  const day = String(d.getDate()).padStart(2, \"0\");\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  return `${day}-${month}-${d.getFullYear()}`;\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 ?? \"€\", locale: localeForLanguage(infra.language) });\n}\n// Map the raw backend status to a localized label; unknown → raw value.\nfunction statusLabel(status: string): string {\n  return props.statusLabels?.[status] || status;\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","<script setup lang=\"ts\">\n/**\n * <QuickOrder> (Vue) — a bulk \"quick order\" pad. Each row has a SKU/code\n * typeahead; selecting a match fills the row's name / net price / min-quantity.\n * \"Add to cart\" resolves the user's cart and bulk-adds every resolved row in a\n * single `CartItemBulk` mutation (via {@link useQuickOrder}). Optionally accepts\n * a spreadsheet parser so users can upload an XLSX of code+quantity pairs.\n *\n * The typed code is only ever a *search term* — a row's product identity, name\n * and price always come from the API, never from the typed/uploaded value.\n *\n * Vue port of the React `<QuickOrder>`; identical behaviour and prop contract.\n */\nimport { ref, computed } from 'vue';\nimport type { Cart, Contact, Customer, GraphQLClient, MediaImageProductSearchInput, TransformationsInput } from '@propeller-commerce/propeller-sdk-v2';\nimport { formatPrice as _formatPrice, getLabel as _getLabel } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } from '@propeller-commerce/propeller-v2-core-ui';\nimport { useInfraProps } from '../composables/vue/useInfraProps';\nimport { useQuickOrder, type QuickOrderMatch } from '../composables/vue/useQuickOrder';\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\n/** A parsed spreadsheet line: a product code and a desired quantity. */\nexport interface QuickOrderUploadLine {\n  code: string;\n  quantity: number;\n}\n\nexport interface QuickOrderProps {\n  /** The authenticated user. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer | null;\n  /** GraphQL client. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n  /** Active company id — scopes cart + pricing for B2B users. */\n  companyId?: number;\n  /** Language for search/cart queries. Defaults to `'NL'`. */\n  language?: string;\n  /** Currency symbol/code shown next to prices. Defaults to `'€'`. */\n  currency?: string;\n  /**\n   * Image filters forwarded to the typeahead + cart queries so results carry\n   * thumbnails (same values the SearchBar uses). Without them the API returns\n   * no image variants and the dropdown shows no product images.\n   */\n  configuration?: {\n    imageSearchFiltersGrid?: MediaImageProductSearchInput;\n    imageVariantFiltersSmall?: TransformationsInput;\n    /**\n     * Catalog root the code search is scoped to. Required: without it the\n     * typeahead and the upload resolve nothing, since searching outside a\n     * category ignores orderlist scoping and would surface products the user\n     * has no access to.\n     */\n    baseCategoryId?: number;\n    /** The channel's anonymous user — logged-out listings are scoped to it. */\n    anonymousUserId?: number;\n  };\n  /** Tax zone for price calculation. Defaults to `'NL'`. */\n  taxZone?: string;\n  /** Show tax-inclusive prices. Resolves from the Propeller provider. */\n  includeTax?: boolean;\n  /** Orderlist (contract) ids to scope the catalogue by. */\n  orderlistIds?: number[];\n  /** Set `false` to ignore `orderlistIds`. Defaults to true when ids are given. */\n  applyOrderlists?: boolean;\n  /** Number of blank rows to start with. Defaults to 5. */\n  initialRows?: number;\n  /** Minimum characters before the typeahead fires. Defaults to 3. */\n  searchThreshold?: number;\n  /** Typeahead debounce in ms. Defaults to 300. */\n  debounceMs?: number;\n  /**\n   * Optional spreadsheet parser. When supplied, the XLSX upload panel is shown;\n   * the app parses the file (e.g. via SheetJS) and returns code+quantity lines.\n   * Kept as a prop so the package stays free of a heavy xlsx dependency.\n   */\n  parseSpreadsheet?: (file: File) => Promise<QuickOrderUploadLine[]>;\n  /** URL to a downloadable XLSX template. */\n  templateUrl?: string;\n\n  /**\n   * Called when the template link is clicked. Navigation is untouched — this\n   * is a notification, not a handler: a buyer fetching the template is a\n   * quick-order intent signal that otherwise leaves no trace at all.\n   */\n  onTemplateDownload?: () => void;\n  /** Max upload file size in bytes. Defaults to 2 MB. */\n  maxUploadBytes?: number;\n  /** Max rows accepted from an upload. Defaults to 500. */\n  maxUploadRows?: number;\n  /** Format a price. Defaults to the shared helper (renders the symbol). */\n  formatPrice?: (price: number) => string;\n  /** Fires when the bulk add creates a fresh cart — persist the cart id. */\n  onCartCreated?: (cart: Cart) => void;\n  /** Fires after a successful add — receives the resulting cart. */\n  afterAddToCart?: (cart: Cart) => void;\n  /** Fires when some uploaded/entered codes could not be resolved. */\n  onMissingCodes?: (codes: string[]) => void;\n  /** Override base container styles. */\n  className?: string;\n  /** Localization label overrides. */\n  labels?: Record<string, string>;\n}\n\n// ── Row model ────────────────────────────────────────────────────────────────\n\ninterface Row {\n  key: string;\n  code: string;\n  productId: number | null;\n  clusterId?: number;\n  name: string;\n  /** Unit price incl. VAT. */\n  netPrice: number;\n  /** Unit price excl. VAT. */\n  grossPrice: number;\n  quantity: number;\n  minQuantity: number;\n  matches: QuickOrderMatch[];\n  searching: boolean;\n  /** `true` once a search completed for the current input (drives \"no results\"). */\n  searched: boolean;\n}\n\nlet ROW_SEQ = 0;\nfunction blankRow(): Row {\n  ROW_SEQ += 1;\n  return {\n    key: `qo-${ROW_SEQ}`,\n    code: '',\n    productId: null,\n    name: '',\n    netPrice: 0,\n    grossPrice: 0,\n    quantity: 1,\n    minQuantity: 1,\n    matches: [],\n    searching: false,\n    searched: false,\n  };\n}\n\n// ── Setup ────────────────────────────────────────────────────────────────────\n\n// `applyOrderlists` must stay `undefined` when unset: downstream reads `=== false`\n// as \"deliberately disabled\", and Vue casts an absent Boolean prop to `false`.\nconst props = withDefaults(defineProps<QuickOrderProps>(), {\n  applyOrderlists: undefined,\n  includeTax: undefined,\n});\nconst infra = useInfraProps(props);\n\nconst currency = computed(() => props.currency ?? '€');\nconst language = computed(() => (infra.language as string) ?? props.language ?? 'NL');\nconst searchThreshold = computed(() => props.searchThreshold ?? 3);\nconst debounceMs = computed(() => props.debounceMs ?? 300);\nconst initialRows = computed(() => Math.max(1, props.initialRows ?? 5));\nconst maxUploadBytes = computed(() => props.maxUploadBytes ?? 2 * 1024 * 1024);\nconst maxUploadRows = computed(() => props.maxUploadRows ?? 500);\n\nfunction getLabel(key: string, fallback: string): string {\n  return _getLabel(props.labels, key, fallback);\n}\n\nconst includeTax = computed(() => (infra.includeTax as boolean | undefined) ?? props.includeTax ?? false);\nfunction rowPrice(r: Row): number {\n  return includeTax.value ? r.netPrice : r.grossPrice;\n}\n\n// Price formatter — a consumer-supplied `formatPrice` wins (it owns its own\n// symbol); otherwise the shared helper renders the symbol via `symbol: currency`.\nfunction displayPrice(n: number): string {\n  return props.formatPrice ? props.formatPrice(n) : _formatPrice(n, { symbol: currency.value, locale: localeForLanguage(props.language) });\n}\n\nconst { submitting, searchProducts, submit } = useQuickOrder({\n  graphqlClient: infra.graphqlClient!,\n  user: infra.user ?? null,\n  companyId: infra.companyId,\n  language: language.value,\n  configuration: props.configuration,\n  taxZone: props.taxZone,\n  orderlistIds: props.orderlistIds,\n  applyOrderlists: props.applyOrderlists,\n  onCartCreated: props.onCartCreated,\n  afterAddToCart: props.afterAddToCart,\n});\n\nconst rows = ref<Row[]>(Array.from({ length: initialRows.value }, blankRow));\nconst missing = ref<string[]>([]);\nconst uploadError = ref<string | null>(null);\nconst uploading = ref(false);\nconst notice = ref<string | null>(null);\nconst fileInput = ref<HTMLInputElement | null>(null);\nconst searchTimers: Record<string, ReturnType<typeof setTimeout>> = {};\n\nconst resolvedCount = computed(() => rows.value.filter((r) => r.productId).length);\n\nfunction patchRow(key: string, patch: Partial<Row>) {\n  const i = rows.value.findIndex((r) => r.key === key);\n  if (i !== -1) rows.value[i] = { ...rows.value[i], ...patch };\n}\n\n// ── Typeahead ────────────────────────────────────────────────────────────────\nfunction onCodeInput(key: string, value: string) {\n  patchRow(key, { code: value, productId: null, name: '', netPrice: 0, grossPrice: 0, searched: false });\n  notice.value = null;\n  if (searchTimers[key]) clearTimeout(searchTimers[key]);\n  if (value.trim().length < searchThreshold.value) {\n    patchRow(key, { matches: [], searching: false, searched: false });\n    return;\n  }\n  patchRow(key, { searching: true });\n  searchTimers[key] = setTimeout(async () => {\n    const results = await searchProducts(value);\n    patchRow(key, { matches: results, searching: false, searched: true });\n  }, debounceMs.value);\n}\n\nfunction selectMatch(key: string, match: QuickOrderMatch) {\n  const dup = rows.value.some((r) => r.key !== key && r.productId && r.code === match.sku);\n  if (dup) {\n    notice.value = getLabel('alreadyInList', 'Product is already in the list');\n    patchRow(key, { code: '', matches: [], productId: null, name: '', netPrice: 0, grossPrice: 0, searched: false });\n    return;\n  }\n  patchRow(key, {\n    code: match.sku,\n    productId: match.productId,\n    clusterId: match.clusterId,\n    name: match.name,\n    netPrice: match.netPrice,\n    grossPrice: match.grossPrice,\n    quantity: match.minQuantity,\n    minQuantity: match.minQuantity,\n    matches: [],\n    searching: false,\n    searched: false,\n  });\n}\n\nfunction setQuantity(key: string, raw: string) {\n  const n = parseInt(raw, 10);\n  const i = rows.value.findIndex((r) => r.key === key);\n  if (i === -1) return;\n  const r = rows.value[i];\n  rows.value[i] = { ...r, quantity: Number.isFinite(n) && n > 0 ? Math.max(r.minQuantity, n) : r.minQuantity };\n}\n\nfunction addRow() {\n  rows.value = [...rows.value, blankRow()];\n}\nfunction removeRow(key: string) {\n  if (rows.value.length > 1) rows.value = rows.value.filter((r) => r.key !== key);\n}\n\n// ── XLSX upload ────────────────────────────────────────────────────────────────\nasync function onFileChosen(e: Event) {\n  const file = (e.target as HTMLInputElement).files?.[0];\n  if (!file || !props.parseSpreadsheet) return;\n  uploadError.value = null;\n  missing.value = [];\n  if (file.size > maxUploadBytes.value) {\n    uploadError.value = `File too large (max ${Math.round(maxUploadBytes.value / 1024 / 1024)} MB)`;\n    return;\n  }\n  uploading.value = true;\n  try {\n    let lines = await props.parseSpreadsheet(file);\n    lines = lines\n      .slice(0, maxUploadRows.value)\n      .map((l) => ({ code: String(l.code ?? '').trim(), quantity: Math.max(1, parseInt(String(l.quantity), 10) || 1) }))\n      .filter((l) => l.code.length > 0);\n    if (!lines.length) {\n      uploadError.value = 'No valid rows found in the file';\n      return;\n    }\n    const resolved: Row[] = [];\n    const notFound: string[] = [];\n    for (const line of lines) {\n      const matches = await searchProducts(line.code);\n      const exact = matches.find((m) => m.sku.toLowerCase() === line.code.toLowerCase()) || matches[0];\n      if (!exact) {\n        notFound.push(line.code);\n        continue;\n      }\n      if (resolved.some((r) => r.productId === exact.productId)) continue;\n      resolved.push({\n        ...blankRow(),\n        code: exact.sku,\n        productId: exact.productId,\n        clusterId: exact.clusterId,\n        name: exact.name,\n        netPrice: exact.netPrice,\n        grossPrice: exact.grossPrice,\n        quantity: Math.max(exact.minQuantity, line.quantity),\n        minQuantity: exact.minQuantity,\n      });\n    }\n    if (resolved.length) rows.value = [...resolved, blankRow()];\n    if (notFound.length) {\n      missing.value = notFound;\n      props.onMissingCodes?.(notFound);\n    }\n  } catch {\n    uploadError.value = 'Could not read the file';\n  } finally {\n    uploading.value = false;\n    if (fileInput.value) fileInput.value.value = '';\n  }\n}\n\n// ── Submit ────────────────────────────────────────────────────────────────────\nasync function handleSubmit() {\n  const lines = rows.value\n    .filter((r) => r.productId)\n    .map((r) => ({ productId: r.productId as number, quantity: r.quantity, clusterId: r.clusterId, code: r.code }));\n  if (!lines.length) {\n    notice.value = getLabel('noItems', 'Add at least one product before submitting');\n    return;\n  }\n  const res = await submit(lines);\n  if (res.success) {\n    rows.value = Array.from({ length: initialRows.value }, blankRow);\n    missing.value = [];\n    notice.value = null;\n  } else {\n    notice.value = res.error ?? 'Failed to add items to cart';\n  }\n}\n</script>\n\n<template>\n  <div :class=\"className ?? 'propeller-quick-order'\">\n    <div class=\"flex flex-col lg:flex-row gap-8\">\n      <!-- Upload panel (only when a parser is supplied) -->\n      <div v-if=\"parseSpreadsheet\" class=\"w-full lg:w-1/3\">\n        <h3 class=\"text-lg font-semibold mb-3 text-foreground\">{{ getLabel('uploadTitle', 'Upload Excel file') }}</h3>\n        <a\n          v-if=\"templateUrl\"\n          :href=\"templateUrl\"\n          target=\"_blank\"\n          rel=\"noopener nofollow\"\n          class=\"text-primary hover:underline text-sm inline-block mb-4\"\n          @click=\"onTemplateDownload?.()\"\n        >{{ getLabel('downloadTemplate', 'Download XLSX template') }}</a>\n        <p class=\"text-xs text-muted-foreground mb-3\">\n          {{ getLabel('uploadHint', 'Column A: article no. / SKU — Column B: quantity. First two rows are ignored.') }}\n        </p>\n        <input\n          ref=\"fileInput\"\n          type=\"file\"\n          accept=\".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel\"\n          class=\"block w-full text-sm text-muted-foreground file:mr-3 file:py-2 file:px-4 file:rounded file:border-0 file:bg-primary file:text-primary-foreground hover:file:bg-primary/90\"\n          :disabled=\"uploading\"\n          @change=\"onFileChosen\"\n        />\n        <p v-if=\"uploading\" class=\"text-sm text-muted-foreground mt-2\">{{ getLabel('upload', 'Uploading…') }}</p>\n        <p v-if=\"uploadError\" class=\"text-sm text-destructive mt-2\">{{ uploadError }}</p>\n      </div>\n\n      <!-- Manual row pad -->\n      <div class=\"flex-1\">\n        <h3 class=\"text-lg font-semibold mb-3 text-foreground\">{{ getLabel('title', 'Add your products manually') }}</h3>\n\n        <!-- Header -->\n        <div class=\"hidden md:grid grid-cols-12 gap-2 px-2 pb-2 text-xs font-medium text-muted-foreground border-b border-border\">\n          <div class=\"col-span-3\">{{ getLabel('colCode', 'Article no. / SKU') }}</div>\n          <div class=\"col-span-3\">{{ getLabel('colName', 'Product name') }}</div>\n          <div class=\"col-span-2\">{{ includeTax ? getLabel('colPriceInclVat', 'incl. VAT') : getLabel('colPrice', 'excl. VAT') }}</div>\n          <div class=\"col-span-1\">{{ getLabel('colQuantity', 'Qty') }}</div>\n          <div class=\"col-span-2 text-right\">{{ getLabel('colTotal', 'Total') }}</div>\n          <div class=\"col-span-1\" />\n        </div>\n\n        <!-- Rows -->\n        <div class=\"divide-y divide-border\">\n          <div v-for=\"r in rows\" :key=\"r.key\" class=\"grid grid-cols-12 gap-2 items-center py-2 relative\">\n            <!-- Code + typeahead -->\n            <div class=\"col-span-12 md:col-span-3 relative\">\n              <input\n                type=\"text\"\n                :value=\"r.code\"\n                :readonly=\"!!r.productId\"\n                :placeholder=\"getLabel('colCode', 'Article no. / SKU')\"\n                class=\"w-full rounded border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring\"\n                @input=\"onCodeInput(r.key, ($event.target as HTMLInputElement).value)\"\n              />\n              <ul\n                v-if=\"(r.searching || r.matches.length > 0 || r.searched) && !r.productId\"\n                class=\"absolute z-20 mt-1 w-[320px] max-w-[90vw] bg-card border border-border rounded shadow-lg max-h-72 overflow-auto\"\n              >\n                <li v-if=\"r.searching\" class=\"px-3 py-2 text-sm text-muted-foreground\">…</li>\n                <template v-else-if=\"r.matches.length\">\n                  <li v-for=\"m in r.matches\" :key=\"`${r.key}-${m.productId}`\">\n                    <button\n                      type=\"button\"\n                      class=\"flex items-center gap-2 w-full text-left px-3 py-2 hover:bg-muted text-sm\"\n                      @click=\"selectMatch(r.key, m)\"\n                    >\n                      <img v-if=\"m.imageUrl\" :src=\"m.imageUrl\" alt=\"\" width=\"32\" height=\"32\" class=\"rounded object-cover\" />\n                      <span class=\"flex-1\">\n                        <span class=\"block text-foreground\">{{ m.name }}</span>\n                        <span v-if=\"m.sku\" class=\"block text-xs text-muted-foreground\">SKU: {{ m.sku }}</span>\n                      </span>\n                    </button>\n                  </li>\n                </template>\n                <li v-else class=\"px-3 py-2 text-sm text-muted-foreground\">{{ getLabel('noResults', 'No results found') }}</li>\n              </ul>\n            </div>\n\n            <!-- Name -->\n            <div class=\"col-span-6 md:col-span-3\">\n              <input type=\"text\" :value=\"r.name\" disabled class=\"w-full rounded border border-input bg-muted/40 px-2 py-1.5 text-sm text-muted-foreground\" />\n            </div>\n\n            <!-- Net price -->\n            <div class=\"col-span-3 md:col-span-2\">\n              <input type=\"text\" :value=\"r.productId ? displayPrice(rowPrice(r)) : ''\" disabled class=\"w-full rounded border border-input bg-muted/40 px-2 py-1.5 text-sm text-muted-foreground\" />\n            </div>\n\n            <!-- Quantity -->\n            <div class=\"col-span-3 md:col-span-1\">\n              <input\n                type=\"number\"\n                :min=\"r.minQuantity\"\n                :step=\"1\"\n                :value=\"r.productId ? r.quantity : ''\"\n                :disabled=\"!r.productId\"\n                class=\"w-full rounded border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:bg-muted/40\"\n                @input=\"setQuantity(r.key, ($event.target as HTMLInputElement).value)\"\n                @keydown=\"(e: KeyboardEvent) => { if (['e','E','+','-','.'].includes(e.key)) e.preventDefault() }\"\n              />\n            </div>\n\n            <!-- Line total -->\n            <div class=\"col-span-9 md:col-span-2 text-right text-sm text-foreground whitespace-nowrap\">\n              {{ r.productId ? displayPrice(rowPrice(r) * r.quantity) : '' }}\n            </div>\n\n            <!-- Remove -->\n            <div class=\"col-span-3 md:col-span-1 flex justify-end\">\n              <button type=\"button\" :aria-label=\"getLabel('remove', 'Remove')\" class=\"text-muted-foreground hover:text-destructive p-1\" @click=\"removeRow(r.key)\">✕</button>\n            </div>\n          </div>\n        </div>\n\n        <!-- Add row -->\n        <button type=\"button\" class=\"mt-3 text-primary hover:underline text-sm font-medium\" @click=\"addRow\">\n          + {{ getLabel('addRow', 'Add more rows') }}\n        </button>\n\n        <!-- Missing codes -->\n        <p v-if=\"missing.length\" class=\"text-sm text-destructive mt-4\">\n          {{ getLabel('missingCodes', 'The following products were not added:') }} {{ missing.join(', ') }}\n        </p>\n        <p v-if=\"notice\" class=\"text-sm text-destructive mt-2\">{{ notice }}</p>\n\n        <!-- Submit -->\n        <div class=\"flex items-center justify-end mt-6 pt-4 border-t border-border\">\n          <button\n            type=\"button\"\n            :disabled=\"submitting || resolvedCount === 0\"\n            class=\"bg-primary text-primary-foreground px-6 py-2.5 rounded font-medium hover:bg-primary/90 transition disabled:opacity-50 disabled:cursor-not-allowed\"\n            @click=\"handleSubmit\"\n          >\n            {{ submitting ? getLabel('adding', 'Adding…') : getLabel('addToCart', 'Add to cart') }}\n          </button>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\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                                  getOrderItemForShipmentItem(\n                                    shipmentItem as ShipmentItem,\n                                  )?.sku ||\n                                  \"-\"\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  // Numeric day-first DD-MM-YYYY, consistent with the order list / summary.\n  const d = new Date(dateStr);\n  if (isNaN(d.getTime())) return dateStr;\n  const day = String(d.getDate()).padStart(2, \"0\");\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  return `${day}-${month}-${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 { computed, 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   * Controlled mode: current on/off state (true = incl. VAT). When supplied,\n   * the toggle reflects THIS value (label + aria-checked) and tracks its\n   * changes, instead of owning local state. Pair with `inclExclVatSwitched`.\n   * Prefer this over `initialState` when the host persists the state (e.g. a\n   * cookie): `initialState` is read once and can't reflect the persisted mode\n   * on load, so the control would lie about the current mode.\n   */\n  value?: boolean;\n\n  /**\n   * Uncontrolled mode: initial state of the toggle. Ignored when `value` is\n   * supplied. 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\n// `value` MUST stay `undefined` when unset — it is the controlled/uncontrolled\n// sentinel, and Vue's cast of an absent Boolean prop to `false` made\n// `isControlled` permanently true, so an uncontrolled toggle was frozen at\n// \"excl. VAT\" and ignored its own clicks. `initialState` is documented as\n// defaulting to true and was reaching `?? true` as `false` for the same reason.\nconst props = withDefaults(defineProps<PriceToggleProps>(), {\n  value: undefined,\n  initialState: true,\n});\nconst isControlled = computed(() => props.value !== undefined);\n// Local state for uncontrolled mode only.\nconst internal = ref<PriceToggleState['isOn']>(props.initialState ?? true);\n// In controlled mode `isOn` follows `props.value` (reactively — a getter, so a\n// later store change is reflected without a watch); otherwise it's the local\n// ref. This is what fixes the \"control lies about the mode on load\" bug: a\n// cookie-backed `value` now drives the label + aria-checked from the first\n// render, and stays in sync afterwards.\nconst isOn = computed(() => (isControlled.value ? !!props.value : internal.value));\n\nonMounted(() => {\n  // Uncontrolled + SSR: re-sync the local ref to `initialState` after hydration.\n  if (!isControlled.value && typeof window !== 'undefined') {\n    internal.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  // Only mutate local state in uncontrolled mode; in controlled mode the parent\n  // owns the value and re-renders us via `props.value`.\n  if (!isControlled.value) {\n    internal.value = newValue;\n  }\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() && props.showLoginPrompt !== false\">\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, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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. Resolved from PropellerProvider when omitted. */\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'). Resolved from PropellerProvider when omitted. */\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  /**\n   * Show the \"log in to see prices\" prompt when prices are hidden.\n   * Defaults to true; pass false to render nothing in its place.\n   */\n  showLoginPrompt?: boolean;\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\n// Both documented as defaulting to true; Vue casts an ABSENT Boolean prop to\n// `false`, so bundle items were never listed and the login prompt never showed\n// unless a host passed them. See `useInfraProps` for the same bug on infra keys.\nconst props = withDefaults(defineProps<ProductBundlesProps>(), {\n  showIndividualItems: true,\n  showLoginPrompt: true,\n});\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 ?? \"€\", locale: localeForLanguage(props.language) });\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 getLanguageString(product?.names, infra.language || \"NL\", \"\");\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  <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 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\"> {{ getLabel('readLess', 'Read less') }} </template>\n\n          <template v-if=\"!expanded\"> {{ getLabel('readMore', '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 { getLabel as _getLabel, 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\n  /** Translated labels: `readMore`, `readLess`. */\n  labels?: Record<string, 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);\nfunction getLabel(key: string, fallback: string): string {\n  return _getLabel(props.labels, key, fallback);\n}\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    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            :portal-mode=\"portalMode\"\n            :show-login-prompt=\"false\"\n          />\n        </slot>\n        <slot\n          v-if=\"showStock !== false && resolvedProduct?.inventory && !contentHidden\"\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        <LoginToOrderButton\n          v-if=\"contentHidden && resolvedProduct\"\n          :labels=\"labels\"\n          :on-login-click=\"onLoginClick\"\n        />\n        <slot\n          v-else-if=\"showAddToCart !== false && resolvedProduct\"\n          name=\"addToCart\"\n          :product=\"resolvedProduct\"\n          :cartId=\"cartId\"\n          :labels=\"labels\"\n        >\n          <component\n            :is=\"AddToCartImpl\"\n            :product=\"resolvedProduct\"\n            :graphql-client=\"graphqlClient\"\n            :user=\"user\"\n            :company-id=\"companyId\"\n            :cart-id=\"cartId\"\n            :create-cart=\"createCart\"\n            :on-cart-created=\"onCartCreated\"\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  Cart,\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 { isContentHidden } from '@propeller-commerce/propeller-v2-core-ui';\nimport LoginToOrderButton from './LoginToOrderButton.vue';\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). Resolved from PropellerProvider when omitted. */\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   * Scope the product fetch to specific orderlist IDs (e.g. a chosen B2B\n   * contract). Overrides the default resolution of all the company's orderlists.\n   */\n  orderlistIds?: number[];\n\n  /**\n   * Apply the orderlist filter. Defaults to `true`; set `false` to browse\n   * unscoped (full catalogue) for an authenticated user without a contract.\n   */\n  applyOrderlists?: boolean;\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\n  /**\n   * Portal access mode. In `'semi-closed'` price, stock and add-to-cart are\n   * withheld from anonymous visitors, who get a log-in action instead.\n   */\n  portalMode?: string;\n  /**\n   * Whether a session exists, independent of whether `user` has loaded yet.\n   * Passed down alongside `portalMode`; closes the hydration window in which\n   * an authenticated visitor still has a null `user`.\n   */\n  isAuthenticated?: boolean;\n\n  /**\n   * Invoked when an anonymous visitor clicks the log-in action that replaces\n   * add-to-cart in a semi-closed portal. The host owns navigation.\n   */\n  onLoginClick?: () => void;\n  showBundles?: boolean;\n  showBulkPrices?: boolean;\n  showSurcharges?: boolean;\n\n  imageComponent?: Component;\n  badgesComponent?: Component;\n  // Without these the PDP's add-to-cart had no cart to add to: with no cartId\n  // and createCart defaulting to false, every add failed outright for a\n  // visitor who did not already have a cart.\n\n  /** Cart to add into. Omit and pass `createCart` to start one on first add. */\n  cartId?: string;\n\n  /** If true a new cart is created when no `cartId` is available. */\n  createCart?: boolean;\n\n  /**\n   * Called when a new cart is created, so the host can persist `cart.cartId`.\n   * WARNING: without it a new cart is created on every add.\n   */\n  onCartCreated?: (cart: Cart) => void;\n\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 orderlistIdsRef = computed(() => props.orderlistIds);\nconst applyOrderlistsRef = computed(() => props.applyOrderlists);\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    orderlistIds: orderlistIdsRef,\n    applyOrderlists: applyOrderlistsRef,\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 contentHidden = computed<boolean>(() =>\n  isContentHidden(props.portalMode, props.user, props.isAuthenticated),\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=\"showAddToCart()\"\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                  :onLoginClick=\"onLoginClick\"\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, isContentHidden } 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   * Show the add-to-cart control on each card. Defaults to true; a semi-closed\n   * portal still withholds it from anonymous visitors regardless.\n   */\n  allowAddToCart?: boolean;\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   * Called when an anonymous visitor clicks the log-in action that replaces\n   * add-to-cart in a semi-closed portal. The host owns navigation.\n   */\n  onLoginClick?: () => 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  allowAddToCart: 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 showAddToCart(): boolean {\n  const allow = (props.allowAddToCart as boolean) !== false;\n  // Anonymous visitors only — a signed-in user keeps add-to-cart.\n  return (\n    !isContentHidden(\n      infra.portalMode as string | undefined,\n      (props.user ?? infra.user) as Contact | Customer | null | undefined,\ninfra.isAuthenticated as boolean | undefined,\n    ) && allow\n  );\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\n    v-if=\"\n      !loading &&\n      (hasPublicAttributes() ||\n        packageDescription ||\n        !!$slots.beforeSpecs ||\n        !!$slots.afterSpecs)\n    \"\n  >\n    <div\n      :class=\"`propeller-product-specifications ${className || ''}`\"\n      :data-layout=\"layout === 'list' ? 'list' : 'table'\"\n      :data-grouped=\"grouping ? 'true' : 'false'\"\n    >\n      <p\n        v-if=\"packageDescription\"\n        class=\"propeller-product-specifications__package-description mb-4 text-sm text-muted-foreground\"\n      >\n        {{ packageDescription }}\n      </p>\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                <slot name=\"beforeSpecs\" :layout=\"layoutMode\" />\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                <slot name=\"afterSpecs\" :layout=\"layoutMode\" />\n              </tbody>\n            </table>\n          </div>\n        </template>\n\n        <template v-if=\"layout === 'list'\">\n          <div class=\"space-y-3\">\n            <slot name=\"beforeSpecs\" :layout=\"layoutMode\" />\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            <slot name=\"afterSpecs\" :layout=\"layoutMode\" />\n          </div>\n        </template>\n      </template>\n\n      <template v-if=\"!!grouping\">\n        <template v-if=\"!!$slots.beforeSpecs\">\n          <div\n            v-if=\"layoutMode === 'table'\"\n            class=\"mb-6 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                <slot name=\"beforeSpecs\" :layout=\"layoutMode\" />\n              </tbody>\n            </table>\n          </div>\n          <div v-else class=\"mb-6 space-y-3\">\n            <slot name=\"beforeSpecs\" :layout=\"layoutMode\" />\n          </div>\n        </template>\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 v-if=\"!!$slots.afterSpecs\">\n          <div\n            v-if=\"layoutMode === 'table'\"\n            class=\"mb-6 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                <slot name=\"afterSpecs\" :layout=\"layoutMode\" />\n              </tbody>\n            </table>\n          </div>\n          <div v-else class=\"space-y-3\">\n            <slot name=\"afterSpecs\" :layout=\"layoutMode\" />\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  /**\n   * Optional package-description string (e.g. contents / packaging notes),\n   * rendered above the attribute table. Omitted when empty.\n   */\n  packageDescription?: string;\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\n// Active layout, passed to the beforeSpecs/afterSpecs scoped slots so a consumer\n// can return a <tr> (table) or a block element (list).\nconst layoutMode = computed<'table' | 'list'>(() =>\n  props.layout === 'list' ? 'list' : 'table',\n);\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              :labels=\"labels\"\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                :package-description=\"specificationsPackageDescription\"\n              >\n                <template v-if=\"$slots.specificationsBefore\" #beforeSpecs=\"slotProps\">\n                  <slot name=\"specificationsBefore\" v-bind=\"slotProps\" />\n                </template>\n                <template v-if=\"$slots.specificationsAfter\" #afterSpecs=\"slotProps\">\n                  <slot name=\"specificationsAfter\" v-bind=\"slotProps\" />\n                </template>\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                  :labels=\"labels\"\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                  :package-description=\"specificationsPackageDescription\"\n                >\n                  <template v-if=\"$slots.specificationsBefore\" #beforeSpecs=\"slotProps\">\n                    <slot name=\"specificationsBefore\" v-bind=\"slotProps\" />\n                  </template>\n                  <template v-if=\"$slots.specificationsAfter\" #afterSpecs=\"slotProps\">\n                    <slot name=\"specificationsAfter\" v-bind=\"slotProps\" />\n                  </template>\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  /**\n   * Extra package-description string rendered in the specifications section\n   * (e.g. contents / packaging notes). Passed as `packageDescription` to\n   * ProductSpecifications.\n   */\n  specificationsPackageDescription?: string;\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                :aria-label=\"getLabel('closeLabel', 'Close')\"\n                @click=\"async (event) => closeAddContactModal()\"\n              >\n                <span aria-hidden=\"true\">✕</span>\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              <!-- Server errors are unlocalised; `addContactFailed` replaces\n                   them outright when supplied. -->\n              <p class=\"text-sm text-destructive\">\n                {{ props.labels?.addContactFailed || addContactError }}\n              </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. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n\n  /** The logged-in user. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer;\n\n  /** The companyId of the current selected company. Resolved from PropellerProvider when omitted. */\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          v-if=\"!hideTitle\"\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=\"`propeller-purchase-authorization-requests__results overflow-x-auto${flat ? '' : ' rounded-[var(--radius-container)] border border-border bg-card shadow-sm'}`\"\n            >\n              <table class=\"w-full text-sm\">\n                <thead v-if=\"!hideHeader\" class=\"bg-surface-hover/50 border-b border-border\">\n                  <tr>\n                    <template :key=\"col\" v-for=\"(col, index) in columns\">\n                      <th\n                        class=\"text-left px-4 py-3 font-medium text-muted-foreground\"\n                      >\n                        {{ getColumnLabel(col) }}\n                      </th>\n                    </template>\n                  </tr>\n                </thead>\n                <tbody class=\"divide-y divide-border\">\n                  <template :key=\"index\" v-for=\"(cart, index) in displayedCarts\">\n                    <tr class=\"hover:bg-surface-hover/30 transition-colors\">\n                      <template :key=\"col\" v-for=\"(col, index) in columns\">\n                        <td\n                          :class=\"`px-4 py-3${col === 'date' ? ' text-muted-foreground' : ''}${col === 'total' ? ' font-medium' : ''}`\"\n                        >\n                          <template v-if=\"col === 'date'\">\n                            {{ formatDate(cart.lastModifiedAt ?? \"\") }}\n                          </template>\n                          <template v-if=\"col === 'quantity'\">\n                            {{ getTotalQuantity(cart) }}\n                          </template>\n                          <template v-if=\"col === 'total'\">\n                            {{ formatPrice(cart.total?.totalNet ?? 0) }}\n                          </template>\n                          <template v-if=\"col === 'requestedBy'\">\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                          </template>\n                          <template v-if=\"col === 'action'\">\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                          </template>\n                        </td>\n                      </template>\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                  :aria-label=\"getLabel('closeLabel', 'Close')\"\n                  @click=\"async (event) => closeModal()\"\n                >\n                  <svg\n                    aria-hidden=\"true\"\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 excl. VAT\") }}\n                            </th>\n                            <th\n                              class=\"text-right px-3 py-2 font-medium text-muted-foreground\"\n                            >\n                              {{ getLabel(\"itemTotal\", \"Total excl. VAT\") }}\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.totalSum ?? 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 { localeForLanguage } 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. Resolved from PropellerProvider when omitted. */\n  graphqlClient?: GraphQLClient;\n\n  /** Currency symbol to display. Defaults to '€'. */\n  currency?: string;\n\n  /** The logged-in user. Resolved from PropellerProvider when omitted. */\n  user?: Contact | Customer;\n\n  /** The companyId of the current selected company. Resolved from PropellerProvider when omitted. */\n  companyId?: number;\n\n  /** Limit the number of requests shown (e.g. 3 = last 3 modified). undefined = show all */\n  limit?: number;\n\n  /** Columns to display, in order. Keys: 'date' | 'quantity' | 'total' | 'requestedBy' | 'action'. Defaults to all five. */\n  columns?: string[];\n\n  /** Label mapping for columns */\n  columnConfig?: Record<string, string>;\n\n  /** Show the actions column and its buttons. Defaults to true. */\n  showActions?: boolean;\n\n  /** Hide the column header row. Defaults to false. */\n  hideHeader?: boolean;\n\n  /** Drop the results container's card chrome (background/border/shadow). Defaults to false. */\n  flat?: boolean;\n\n  /** Hide the component's own title. Defaults to false. */\n  hideTitle?: boolean;\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 = withDefaults(defineProps<PurchaseAuthorizationRequestsProps>(), {\n  showActions: true,\n  hideHeader: false,\n  flat: false,\n  hideTitle: false,\n});\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 columns = computed(() =>\n  (props.columns || ['date', 'quantity', 'total', 'requestedBy', 'action']).filter(\n    (col) => props.showActions || col !== 'action',\n  ),\n);\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\nconst displayedCarts = computed(() => {\n  if (props.limit && props.limit > 0) {\n    const sorted = [...carts.value].sort((a: Cart, b: Cart) => {\n      const dateA = new Date(a.lastModifiedAt || '').getTime();\n      const dateB = new Date(b.lastModifiedAt || '').getTime();\n      return dateB - dateA;\n    });\n    return sorted.slice(0, props.limit);\n  }\n  return carts.value;\n});\n\nconst columnLabelKeys: Record<string, [string, string]> = {\n  date: ['colDate', 'Date'],\n  quantity: ['colQuantity', 'Quantity'],\n  total: ['colTotal', 'Total'],\n  requestedBy: ['colRequestedBy', 'Requested by'],\n  action: ['colActions', 'Actions'],\n};\n\nfunction getColumnLabel(col: string): string {\n  if (props.columnConfig?.[col]) return props.columnConfig[col];\n  const [key, fallback] = columnLabelKeys[col] || [col, col];\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  // Numeric day-first DD-MM-YYYY, consistent with the order list / summary.\n  const d = new Date(dateStr);\n  if (isNaN(d.getTime())) return dateStr;\n  const day = String(d.getDate()).padStart(2, \"0\");\n  const month = String(d.getMonth() + 1).padStart(2, \"0\");\n  return `${day}-${month}-${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 ?? \"€\", locale: localeForLanguage(props.language) });\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            ><!-- Full sentence with a {link} placeholder — see CartOverview. -->{{ termsConsentParts.before\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            >{{ termsConsentParts.after }}</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}\n// Split the terms-consent template around {link} — see CartOverview.\nconst termsConsentParts = computed(() => {\n  const tpl = getLabel('termsConsent', 'I agree to the {link}');\n  const [before, after = ''] = tpl.split('{link}');\n  return { before, after };\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. Resolved from PropellerProvider when omitted. */\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 selectUserTypeText = computed(() => {\nreturn props.labels?.selectUserType || 'Please select an account type.';\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 = selectUserTypeText.value;\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-card border border-input 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              <component\n                :is=\"props.getResultHref ? 'a' : 'div'\"\n                :href=\"props.getResultHref ? props.getResultHref(result) : undefined\"\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=\"(event: MouseEvent) => handleResultAnchorClick(event, 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                <!-- Custom price cell via the scoped #price slot (e.g. a\n                     \"Price by quotation\" label); otherwise the default price,\n                     which `showPrice: false` hides entirely. -->\n                <slot\n                  v-if=\"$slots.price\"\n                  name=\"price\"\n                  :result=\"result\"\n                />\n                <template v-else-if=\"showPrice !== false && result.price !== undefined && result.price !== null\">\n                  <div class=\"propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0 text-right\">\n                    <span class=\"propeller-search-bar__result-price-value\">{{ formatItemPrice(leadingPrice(result)) }}</span>\n                    <span class=\"propeller-search-bar__result-price-label block text-xs font-normal text-muted-foreground\">{{ priceTaxLabel() }}</span>\n                  </div>\n                </template>\n              </component>\n            </template>\n          </div>\n\n          <template v-if=\"itemsFound > results.length\">\n            <a\n              v-if=\"props.getViewAllHref\"\n              :href=\"props.getViewAllHref(searchTerm)\"\n              class=\"propeller-search-bar__view-all block 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=\"handleViewAllAnchorClick\"\n            >\n              {{ getLabel('viewAll', 'View all results') }} ({{ itemsFound }})\n            </a>\n            <button\n              v-else\n              type=\"button\"\n              class=\"propeller-search-bar__view-all block w-full 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=\"handleViewAllClick\"\n            >\n              {{ getLabel('viewAll', 'View all results') }} ({{ itemsFound }})\n            </button>\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, getLanguageString } from '@propeller-commerce/propeller-v2-core-ui';\nimport { localeForLanguage } 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  /**\n   * Leading price value (kept for back-compat). Populated with the net or gross\n   * amount per the active toggle — see `priceNet`/`priceGross` for both values.\n   */\n  price?: number;\n  /** Tax-inclusive price (SDK `price.net`). */\n  priceNet?: number;\n  /** Tax-exclusive price (SDK `price.gross`). */\n  priceGross?: 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. Resolved from PropellerProvider when omitted. */\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  /**\n   * Build the destination URL for a result item. When provided, each result\n   * renders as a real `<a href>` (middle-clickable, new-tab, crawlable) while\n   * `onResultClick` still fires for SPA navigation. Omit to keep the\n   * div-based fallback.\n   */\n  getResultHref?: (result: SearchBarResult) => string;\n\n  /**\n   * Build the destination URL for the \"View all results\" CTA. When provided,\n   * the CTA renders as a real `<a href>` (middle-clickable, new-tab, crawlable,\n   * keyboard-focusable) while `onViewAllClick` still fires for SPA navigation.\n   * Omit to keep the button fallback.\n   */\n  getViewAllHref?: (term: string) => string;\n\n  /**\n   * Show the price column on each autosuggest result. Defaults to `true`.\n   * Set `false` to hide prices entirely in the dropdown — e.g. a B2B\n   * contract-catalogue context where prices are quote-only and shouldn't\n   * appear in the live preview. Ignored when the `price` slot is provided.\n   *\n   * For custom per-result price content (e.g. a \"Price by quotation\" label),\n   * use the scoped `#price` slot instead — it receives `{ result }` and fully\n   * overrides the default price cell.\n   */\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\n  /**\n   * When true, the tax-inclusive (net) price leads; false shows tax-exclusive\n   * (gross). SDK mapping: `price.net` = incl. VAT, `price.gross` = excl. VAT.\n   * Resolved from `<PropellerProvider>` when omitted; defaults to `false`.\n   */\n  includeTax?: boolean;\n\n  /**\n   * Labels for the incl./excl. price suffix. Keys: `inclTax`, `exclTax`.\n   * Falls back to English 'incl. VAT' / 'excl. VAT'.\n   */\n  priceLabels?: 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  /** Scope the autosuggest fetch to specific orderlist IDs (e.g. a chosen B2B contract). */\n  orderlistIds?: number[];\n\n  /**\n   * Apply the orderlist filter. Defaults to `true` when `orderlistIds` is\n   * non-empty, `false` otherwise — so an authenticated user without a contract\n   * still sees the full catalogue.\n   */\n  applyOrderlists?: boolean;\n\n  /** Attribute names to request per product, e.g. `['MPN']`. See ProductGrid. */\n  productTrackAttributes?: string[];\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\n// `applyOrderlists` must stay `undefined` when unset: downstream reads `=== false`\n// as \"deliberately disabled\", and Vue casts an absent Boolean prop to `false`.\nconst props = withDefaults(defineProps<SearchBarProps>(), { applyOrderlists: undefined });\nconst infra = useInfraProps(props);\n\nconst userRef = computed(() => (infra.user ?? null) as Contact | Customer | null);\nconst companyRef = computed(() => infra.companyId);\nconst orderlistIdsRef = computed(() => props.orderlistIds);\nconst applyOrderlistsRef = computed(() => props.applyOrderlists);\nconst productTrackAttributesRef = computed(() => props.productTrackAttributes);\n\nconst { search, searchResults, searchItemsFound, searchLoading } = useProductSearch({\n  graphqlClient: infra.graphqlClient,\n  language: computed(() => infra.language || 'NL'),\n  configuration: infra.configuration || {},\n  // `user` supplies userId/contactId/customerId to the autosuggest query.\n  // Without it the dropdown's results diverge from the grid's: orderlist\n  // scoping is driven by userId, so `orderlistIds` alone is ignored by the\n  // backend and the dropdown shows the whole catalogue while the grid below\n  // shows only the contract's products.\n  user: userRef,\n  companyId: companyRef,\n  orderlistIds: orderlistIdsRef,\n  applyOrderlists: applyOrderlistsRef,\n  productTrackAttributes: productTrackAttributesRef,\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 ?? '€', locale: localeForLanguage(props.language) });\n}\n// Match ProductPrice: the toggle picks which value leads. SDK mapping —\n// net = incl. VAT, gross = excl. VAT. Default (includeTax undefined) is excl.\nconst useTax = computed(() => !!infra.includeTax);\nfunction leadingPrice(result: SearchBarResult): number {\n  return useTax.value\n    ? result.priceNet ?? result.price ?? 0\n    : result.priceGross ?? result.price ?? 0;\n}\nfunction priceTaxLabel(): string {\n  return useTax.value\n    ? _getLabel(props.priceLabels, 'inclTax', 'incl. VAT')\n    : _getLabel(props.priceLabels, 'exclTax', 'excl. VAT');\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  // `slugs[0]` is the catalog default language; the result's name\n  // below is already resolved by language.\n  const slug = getLanguageString(item.slugs, infra.language || 'NL', '');\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  const priceNet = displayItem?.price?.net || 0;\n  const priceGross = displayItem?.price?.gross || 0;\n  // Prefer the name in the active language; fall back to the first available.\n  // The backend search doesn't language-filter, so a product may carry names in\n  // several languages — without this the row could show the wrong-language name\n  // (e.g. FR while EN is selected).\n  const lang = infra.language;\n  const localizedName =\n    (lang && item.names?.find((n: { language?: string }) => n.language === lang)?.value) ||\n    getLanguageString(item.names, infra.language || \"NL\") ||\n    'Product';\n  return {\n    id: id,\n    name: localizedName,\n    sku: item.sku || displayItem?.sku || '',\n    // `price` stays gross for back-compat; the row picks net/gross per toggle.\n    price: priceGross,\n    priceNet: priceNet,\n    priceGross: priceGross,\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\n// True when a click should be left to the browser (open in new tab/window)\n// instead of intercepted for SPA navigation.\nfunction isModifiedClick(event: MouseEvent): boolean {\n  return (\n    event.defaultPrevented ||\n    event.button !== 0 ||\n    event.metaKey ||\n    event.ctrlKey ||\n    event.shiftKey ||\n    event.altKey\n  );\n}\n\n// Result rows render as <a href> when getResultHref is set. Intercept plain\n// clicks for SPA nav; let modified clicks open natively.\nfunction handleResultAnchorClick(event: MouseEvent, result: SearchBarResult): void {\n  if (props.getResultHref) {\n    if (isModifiedClick(event)) return;\n    event.preventDefault();\n  }\n  handleResultClick(result);\n}\n\n// \"View all\" renders as <a href> when getViewAllHref is set — same guard.\nfunction handleViewAllAnchorClick(event: MouseEvent): void {\n  if (isModifiedClick(event)) return;\n  event.preventDefault();\n  handleViewAllClick();\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","MagicTokenService","CartService","CartStatus","cart","getAddresses","Gender","CartAddressType","computed","unref","watch","isCheckoutAllowed","resultCart","addedItem","fetchActiveCart","CrossupsellType","getDefaultInvoiceAddress","getDefaultDeliveryAddress","PaymentStatuses","collectAttributeValues","filterProductsBySelections","index","attributeNameMatches","getAttributeDisplayName","extractAttributeValues","OrderSearchFields","markRaw","OrderItemClass","buildAttributeInput","ProductSortField","ProductSearchableField","buildInventoryFilter","ProductStatus","SortOrder","getClusterImageUrl","getProductImageUrl","machineService","attributes","PurchaseRole","useInfraProps","usePropellerDeps","reactive","PropellerScopeKey","_renderSlot","twMerge","clsx","_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","_createTextVNode","DefaultLoginForm","onMounted","onUnmounted","_hoisted_7","_renderList","_normalizeClass","_unref","_hoisted_11","_hoisted_13","_createBlock","_resolveDynamicComponent","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_1","_getLocalizedValue","_formatPrice","localeForLanguage","DefaultProductPrice","getLanguageString","_getProductImageUrl","_getProductSku","_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","_hoisted_37","_hoisted_38","_createVNode","CartBonusItems","_hoisted_39","_getCountryName","_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","getLabel","formatSurcharge","DefaultItemStock","DefaultProductSurcharges","_hoisted_42","DefaultCartItem","DefaultCartBonusItemsImpl","findPurchaserPac","isOverAuthorizationLimit","_withCtx","mediaItems","DefaultProductImage","DefaultProductBadges","DefaultAddToFavorite","_getClusterSku","_getClusterImageUrl","ItemStock","AttributeType","_normalizeStyle","buildClusterJsonLd","safeJsonStringify","isContentHidden","AddToCart","items","DefaultFavoriteListItem","DefaultGridPagination","_hoisted_45","_hoisted_47","_hoisted_49","MIN_STOCK_THRESHOLD","GridFilters","_mergeProps","buildItemListJsonLd","User","DefaultAddToCart","ProductPriceDisplay","LoginToOrderButton","usePropellerContext","DefaultProductCard","DefaultClusterCard","getLocalizedValue","defineComponent","h","MachineCard","GridFiltersPanel","GridToolbar","ProductGrid","GridPagination","$slots","MenuLevel","DefaultOrderItemCard","getNettedBonusItems","OrderSortField","OrderType","r","BundleCondition","DefaultProductBundles","DefaultProductBulkPrices","buildProductJsonLd","nextTick","DefaultProductDescription","DefaultProductSpecifications","DefaultProductDownloads","DefaultProductVideos","_hoisted_54"],"mappings":"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"}