@propeller-commerce/propeller-v2-react-ui 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { getLabel, getLocalizedValue, formatPrice, getClusterSku, getClusterImageUrl, isContentHidden, getProductSku, getProductImageUrl, createServices, err, ok, formatSurcharge, deriveUserMode, isContact, isCustomer, getAddresses, attributeNameMatches, getAttributeDisplayName, filterProductsBySelections, extractAttributeValues, buildInventoryFilter, MIN_STOCK_THRESHOLD, getNettedBonusItems, getLanguageString, collectAttributeValues, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
2
+ import { getLabel, getLocalizedValue, formatPrice, localeForLanguage, getClusterSku, getClusterImageUrl, isContentHidden, getProductSku, getProductImageUrl, createServices, err, ok, formatSurcharge, deriveUserMode, isContact, isCustomer, getAddresses, attributeNameMatches, getAttributeDisplayName, filterProductsBySelections, extractAttributeValues, buildInventoryFilter, MIN_STOCK_THRESHOLD, getNettedBonusItems, getLanguageString, collectAttributeValues, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
3
3
  export * from '@propeller-commerce/propeller-v2-core-ui';
4
4
  import * as React6 from 'react';
5
- import { createContext, useState, useRef, useMemo, useCallback, useContext, useEffect } from 'react';
5
+ import { createContext, useState, useRef, useCallback, useMemo, useContext, useEffect } from 'react';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
  import { ProductStatus, ProductSortField, SortOrder, PurchaseRole, CrossupsellType, CartStatus, CartAddressType, Gender, YesNo, AddressType, MagicTokenService, PaymentStatuses, OrderSearchFields, OrderItemClass, ProductSearchableField, machineService, AttributeType, OrderSortField, OrderType, OrderDiscountType, BundleCondition } from '@propeller-commerce/propeller-sdk-v2';
8
8
  import { clsx } from 'clsx';
@@ -716,12 +716,33 @@ async function initCart(config) {
716
716
  }
717
717
 
718
718
  // src/composables/react/useCart.ts
719
+ var DEFAULT_IMAGE_SEARCH_FILTERS = { page: 1, offset: 1 };
720
+ var DEFAULT_IMAGE_VARIANT_FILTERS = {
721
+ transformations: [
722
+ { name: "thumb", transformation: { format: "WEBP", height: 100, width: 100, fit: "BOUNDS" } }
723
+ ]
724
+ };
719
725
  function useCart(options) {
720
726
  const { graphqlClient, user, companyId, configuration, onCartCreated } = options;
721
727
  const language = options.language || configuration?.language || "NL";
722
728
  const [cart, setCart] = useState(null);
723
729
  const [createdCartId, setCreatedCartId] = useState("");
724
730
  const cartId = options.cartId || createdCartId;
731
+ const cartIdRef = useRef(cartId);
732
+ if (cartId && cartIdRef.current !== cartId) cartIdRef.current = cartId;
733
+ const rememberCart = useCallback((c) => {
734
+ setCart(c);
735
+ setCreatedCartId(c.cartId);
736
+ cartIdRef.current = c.cartId;
737
+ }, []);
738
+ const imageSearchFilters = useCallback(
739
+ () => configuration?.imageSearchFiltersGrid ?? DEFAULT_IMAGE_SEARCH_FILTERS,
740
+ [configuration]
741
+ );
742
+ const imageVariantFilters = useCallback(
743
+ () => configuration?.imageVariantFiltersSmall ?? DEFAULT_IMAGE_VARIANT_FILTERS,
744
+ [configuration]
745
+ );
725
746
  const [loading, setLoading] = useState(false);
726
747
  const [error, setError] = useState(null);
727
748
  const notesTimers = useRef({});
@@ -753,17 +774,15 @@ function useCart(options) {
753
774
  user,
754
775
  companyId,
755
776
  language,
756
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
757
- imageVariantFilters: configuration?.imageVariantFiltersSmall,
777
+ imageSearchFilters: imageSearchFilters(),
778
+ imageVariantFilters: imageVariantFilters(),
758
779
  onCartCreated: (c) => {
759
- setCart(c);
760
- setCreatedCartId(c.cartId);
780
+ rememberCart(c);
761
781
  onCartCreated?.(c);
762
782
  }
763
783
  };
764
784
  const resolved = await initCart(config);
765
- setCart(resolved);
766
- setCreatedCartId(resolved.cartId);
785
+ rememberCart(resolved);
767
786
  return resolved;
768
787
  }, [graphqlClient, user, companyId, language, configuration, onCartCreated]);
769
788
  const addItem = useCallback(async (opts) => {
@@ -776,14 +795,13 @@ function useCart(options) {
776
795
  }
777
796
  const childItemInputs = opts.childItems?.map((id) => ({ productId: id, quantity: opts.quantity }));
778
797
  if (opts.onAddToCart) {
779
- const resultCart2 = opts.onAddToCart(opts.product, opts.cluster?.clusterId, opts.quantity, childItemInputs, opts.notes, opts.price);
780
- setCart(resultCart2);
781
- setCreatedCartId(resultCart2.cartId);
798
+ const resultCart2 = await opts.onAddToCart(opts.product, opts.cluster?.clusterId, opts.quantity, childItemInputs, opts.notes, opts.price);
799
+ rememberCart(resultCart2);
782
800
  const addedItem2 = resultCart2.items?.find((i) => i.productId === opts.product.productId) ?? null;
783
801
  opts.afterAddToCart?.(resultCart2, addedItem2);
784
802
  return ok({ cart: resultCart2, item: addedItem2 });
785
803
  }
786
- let resolvedCartId = opts.cartId || cartId;
804
+ let resolvedCartId = opts.cartId || cartIdRef.current || cartId;
787
805
  if (!resolvedCartId) {
788
806
  if (opts.createCart) {
789
807
  const c = await resolveCart();
@@ -795,11 +813,10 @@ function useCart(options) {
795
813
  id: resolvedCartId,
796
814
  input: { productId: opts.product.productId, quantity: opts.quantity, ...opts.cluster?.clusterId !== void 0 && { clusterId: opts.cluster.clusterId }, ...childItemInputs && { childItems: childItemInputs }, ...opts.notes && { notes: opts.notes }, ...opts.price !== void 0 && { price: opts.price } },
797
815
  language,
798
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
799
- imageVariantFilters: configuration?.imageVariantFiltersSmall
816
+ imageSearchFilters: imageSearchFilters(),
817
+ imageVariantFilters: imageVariantFilters()
800
818
  });
801
- setCart(resultCart);
802
- setCreatedCartId(resultCart.cartId);
819
+ rememberCart(resultCart);
803
820
  const addedItem = resultCart.items?.find((i) => i.productId === opts.product.productId) ?? null;
804
821
  opts.afterAddToCart?.(resultCart, addedItem);
805
822
  return ok({ cart: resultCart, item: addedItem });
@@ -810,13 +827,25 @@ function useCart(options) {
810
827
  } finally {
811
828
  setLoading(false);
812
829
  }
813
- }, [graphqlClient, cartId, language, configuration, resolveCart]);
830
+ }, [graphqlClient, cartId, language, configuration, resolveCart, rememberCart, imageSearchFilters, imageVariantFilters]);
831
+ const addItems = useCallback(async (items) => {
832
+ const added = [];
833
+ let lastCart = null;
834
+ for (const item of items) {
835
+ const result = await addItem({ createCart: true, ...item });
836
+ if (!result.ok) return err(result.error);
837
+ lastCart = result.data.cart;
838
+ added.push(result.data.item);
839
+ }
840
+ if (!lastCart) return err("No items to add");
841
+ return ok({ cart: lastCart, items: added });
842
+ }, [addItem]);
814
843
  const updateItemQuantity = useCallback(async (cartItemId, quantity) => {
815
844
  if (!cartId) return void 0;
816
845
  setLoading(true);
817
846
  try {
818
847
  const service = createServices(graphqlClient).cart;
819
- const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { quantity }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
848
+ const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { quantity }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
820
849
  setCart(updated);
821
850
  return updated;
822
851
  } catch (e) {
@@ -832,7 +861,7 @@ function useCart(options) {
832
861
  if (!cartId) return;
833
862
  try {
834
863
  const service = createServices(graphqlClient).cart;
835
- const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { notes }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
864
+ const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { notes }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
836
865
  setCart(updated);
837
866
  } catch (e) {
838
867
  setError(e instanceof Error ? e.message : "Failed to update notes");
@@ -848,8 +877,8 @@ function useCart(options) {
848
877
  id: cartId,
849
878
  input: { itemId: cartItemId },
850
879
  language,
851
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
852
- imageVariantFilters: configuration?.imageVariantFiltersSmall
880
+ imageSearchFilters: imageSearchFilters(),
881
+ imageVariantFilters: imageVariantFilters()
853
882
  });
854
883
  setCart(updated);
855
884
  return updated;
@@ -863,7 +892,7 @@ function useCart(options) {
863
892
  if (!cartId) return void 0;
864
893
  try {
865
894
  const service = createServices(graphqlClient).cart;
866
- const updated = await service.addActionCodeToCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
895
+ const updated = await service.addActionCodeToCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
867
896
  setCart(updated);
868
897
  return updated;
869
898
  } catch (e) {
@@ -874,7 +903,7 @@ function useCart(options) {
874
903
  if (!cartId) return void 0;
875
904
  try {
876
905
  const service = createServices(graphqlClient).cart;
877
- const updated = await service.removeActionCodeFromCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
906
+ const updated = await service.removeActionCodeFromCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
878
907
  setCart(updated);
879
908
  return updated;
880
909
  } catch (e) {
@@ -902,7 +931,7 @@ function useCart(options) {
902
931
  }
903
932
  }, [graphqlClient, cartId, language]);
904
933
  const getCrossupsells = useCallback(async (opts) => {
905
- const { productId, clusterId, types, taxZone, imageVariantFilters } = opts;
934
+ const { productId, clusterId, types, taxZone } = opts;
906
935
  if (!productId && !clusterId) return [];
907
936
  try {
908
937
  const service = createServices(graphqlClient).crossupsell;
@@ -915,8 +944,8 @@ function useCart(options) {
915
944
  ...clusterId && { clusterIdsFrom: [clusterId] }
916
945
  },
917
946
  language,
918
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
919
- imageVariantFilters: imageVariantFilters ?? configuration?.imageVariantFiltersSmall,
947
+ imageSearchFilters: imageSearchFilters(),
948
+ imageVariantFilters: opts.imageVariantFilters ?? imageVariantFilters(),
920
949
  priceCalculateProductInput: {
921
950
  taxZone: taxZone || "NL",
922
951
  ...user && "company" in user && { companyId: user?.company?.companyId },
@@ -929,8 +958,8 @@ function useCart(options) {
929
958
  } catch {
930
959
  return [];
931
960
  }
932
- }, [graphqlClient, language, configuration, user]);
933
- return { cart, cartId, loading, error, checkoutAllowed, resolveCart, addItem, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };
961
+ }, [graphqlClient, language, user, imageSearchFilters, imageVariantFilters]);
962
+ return { cart, cartId, loading, error, checkoutAllowed, resolveCart, addItem, addItems, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };
934
963
  }
935
964
  function buildAddressInput(type, addr) {
936
965
  return {
@@ -4423,6 +4452,64 @@ function ActionCode(rawProps) {
4423
4452
  ] });
4424
4453
  }
4425
4454
  var ActionCode_default = ActionCode;
4455
+ function CartBonusItems(rawProps) {
4456
+ const props = useInfraProps(rawProps);
4457
+ const items = props.bonusItems ?? props.cart?.bonusItems ?? [];
4458
+ if (items.length === 0) return null;
4459
+ const currency = props.currency ?? "\u20AC";
4460
+ const money = (value) => formatPrice(value, { symbol: currency, locale: localeForLanguage(props.language) });
4461
+ const productName = (item) => getLocalizedValue(item.product?.names, props.language, "Product");
4462
+ const productImage = (item) => item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
4463
+ return /* @__PURE__ */ jsxs("div", { className: cn(`propeller-cart-bonus-items ${props.className || "mt-2"}`), children: [
4464
+ /* @__PURE__ */ jsx("h2", { className: "propeller-cart-bonus-items__title text-lg font-semibold mb-3", children: getLabel(props.labels, "title", "Bonus items") }),
4465
+ /* @__PURE__ */ jsx("div", { className: "propeller-cart-bonus-items__list space-y-4", children: items.map((item) => {
4466
+ const img = productImage(item);
4467
+ const name = productName(item);
4468
+ const total = props.includeTax ? item.totalPriceNet : item.totalPrice;
4469
+ return /* @__PURE__ */ jsxs(
4470
+ "div",
4471
+ {
4472
+ className: "propeller-cart-bonus-item flex items-center gap-4 bg-card p-4 rounded-container shadow-sm border border-border",
4473
+ children: [
4474
+ /* @__PURE__ */ jsx("div", { className: "propeller-cart-bonus-item__media w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden flex items-center justify-center", children: img ? /* @__PURE__ */ jsx("img", { className: "propeller-cart-bonus-item__image w-full h-full object-contain p-1", src: img, alt: name }) : /* @__PURE__ */ jsx(
4475
+ "svg",
4476
+ {
4477
+ fill: "none",
4478
+ viewBox: "0 0 24 24",
4479
+ stroke: "currentColor",
4480
+ className: "propeller-cart-bonus-item__image-placeholder w-8 h-8 text-foreground-subtle",
4481
+ strokeWidth: 1.5,
4482
+ children: /* @__PURE__ */ jsx(
4483
+ "path",
4484
+ {
4485
+ strokeLinecap: "round",
4486
+ strokeLinejoin: "round",
4487
+ 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"
4488
+ }
4489
+ )
4490
+ }
4491
+ ) }),
4492
+ /* @__PURE__ */ jsxs("div", { className: "propeller-cart-bonus-item__body flex-1 min-w-0", children: [
4493
+ item.product?.sku ? /* @__PURE__ */ jsxs("p", { className: "propeller-cart-bonus-item__sku font-mono text-xs text-foreground-subtle", children: [
4494
+ getLabel(props.labels, "sku", "SKU"),
4495
+ ": ",
4496
+ item.product.sku
4497
+ ] }) : null,
4498
+ /* @__PURE__ */ jsx("p", { className: "propeller-cart-bonus-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2", children: name })
4499
+ ] }),
4500
+ /* @__PURE__ */ jsxs("div", { className: "propeller-cart-bonus-item__qty text-sm text-muted-foreground whitespace-nowrap", children: [
4501
+ item.quantity,
4502
+ " \xD7"
4503
+ ] }),
4504
+ /* @__PURE__ */ jsx("div", { className: "propeller-cart-bonus-item__price font-semibold text-foreground whitespace-nowrap", children: money(total) })
4505
+ ]
4506
+ },
4507
+ item.itemId
4508
+ );
4509
+ }) })
4510
+ ] });
4511
+ }
4512
+ var CartBonusItems_default = CartBonusItems;
4426
4513
  function mergeGrouped(p) {
4427
4514
  const d = p.display;
4428
4515
  const e = p.events;
@@ -4456,6 +4543,7 @@ function AddToCart(rawProps) {
4456
4543
  const [modalVisible, setModalVisible] = useState(() => false);
4457
4544
  const [addedCartItem, setAddedCartItem] = useState(() => null);
4458
4545
  const [activeFullCart, setActiveFullCart] = useState(() => null);
4546
+ const [grantedBonusItems, setGrantedBonusItems] = useState(() => []);
4459
4547
  const [includeTax] = useState(() => false);
4460
4548
  function getProductUrl2() {
4461
4549
  return props.configuration?.urls?.getProductUrl(props.product, props.language) ?? "#";
@@ -4498,9 +4586,9 @@ function AddToCart(rawProps) {
4498
4586
  if (addedCartItem) {
4499
4587
  const useTax = props.includeTax !== void 0 ? !!props.includeTax : includeTax;
4500
4588
  const price = useTax ? addedCartItem.totalSumNet : addedCartItem.totalSum;
4501
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
4589
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
4502
4590
  }
4503
- return formatPrice(props.price !== void 0 ? props.price : props.product?.price?.gross, { symbol: props.currency ?? "\u20AC" });
4591
+ return formatPrice(props.price !== void 0 ? props.price : props.product?.price?.gross, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
4504
4592
  }
4505
4593
  function getModalSku() {
4506
4594
  if (addedCartItem) return addedCartItem.product?.sku || "";
@@ -4534,10 +4622,20 @@ function AddToCart(rawProps) {
4534
4622
  function closeModal() {
4535
4623
  setModalVisible(false);
4536
4624
  setAddedCartItem(null);
4625
+ setGrantedBonusItems([]);
4626
+ }
4627
+ function newBonusItems(before, after) {
4628
+ const granted = after?.bonusItems ?? [];
4629
+ if (granted.length === 0) return [];
4630
+ const previous = before?.bonusItems;
4631
+ if (!previous) return granted;
4632
+ const seen = new Map(previous.map((item) => [item.itemId, item.quantity ?? 0]));
4633
+ return granted.filter((item) => (item.quantity ?? 0) > (seen.get(item.itemId) ?? 0));
4537
4634
  }
4538
4635
  async function handleAddToCart() {
4539
4636
  if (!props.graphqlClient) return;
4540
4637
  if (props.beforeAddToCart && !props.beforeAddToCart()) return;
4638
+ const cartBeforeAdd = activeFullCart ?? cart ?? null;
4541
4639
  const result = await addItem({
4542
4640
  product: props.product,
4543
4641
  cluster: props.cluster,
@@ -4549,6 +4647,7 @@ function AddToCart(rawProps) {
4549
4647
  afterAddToCart: (resultCart, addedItem) => {
4550
4648
  setActiveFullCart(resultCart);
4551
4649
  setAddedCartItem(resolveAddedItem(resultCart, addedItem || null));
4650
+ setGrantedBonusItems(newBonusItems(cartBeforeAdd, resultCart));
4552
4651
  props.afterAddToCart?.(resultCart, addedItem || void 0);
4553
4652
  },
4554
4653
  enableStockValidation: props.enableStockValidation,
@@ -4845,12 +4944,22 @@ function AddToCart(rawProps) {
4845
4944
  /* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: getLocalizedValue(child.product?.names, props.language, "Option") }),
4846
4945
  /* @__PURE__ */ jsx("span", { className: "text-foreground-subtle whitespace-nowrap ml-2", children: formatPrice(
4847
4946
  ((props.includeTax !== void 0 ? !!props.includeTax : includeTax) ? child.totalSumNet : child.totalSum) ?? 0,
4848
- { symbol: props.currency ?? "\u20AC" }
4947
+ { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) }
4849
4948
  ) })
4850
4949
  ]
4851
4950
  },
4852
4951
  idx
4853
- )) }) : null
4952
+ )) }) : null,
4953
+ grantedBonusItems.length > 0 ? /* @__PURE__ */ jsx("div", { className: "propeller-add-to-cart__modal-bonus-items mt-4 pt-4 border-t border-border-subtle", children: /* @__PURE__ */ jsx(
4954
+ CartBonusItems_default,
4955
+ {
4956
+ bonusItems: grantedBonusItems,
4957
+ includeTax: props.includeTax,
4958
+ currency: props.currency,
4959
+ language: props.language,
4960
+ labels: props.bonusItemsLabels
4961
+ }
4962
+ ) }) : null
4854
4963
  ] }),
4855
4964
  /* @__PURE__ */ jsxs("div", { className: "propeller-add-to-cart__modal-actions flex gap-3 px-6 py-4 border-t border-border-subtle", children: [
4856
4965
  /* @__PURE__ */ jsx(
@@ -6376,64 +6485,6 @@ function BreadcrumbsWithProvider(rawProps) {
6376
6485
  return /* @__PURE__ */ jsx(Breadcrumbs_default, { ...props });
6377
6486
  }
6378
6487
  var BreadcrumbsWithProvider_default = BreadcrumbsWithProvider;
6379
- function CartBonusItems(rawProps) {
6380
- const props = useInfraProps(rawProps);
6381
- const items = props.bonusItems ?? props.cart?.bonusItems ?? [];
6382
- if (items.length === 0) return null;
6383
- const currency = props.currency ?? "\u20AC";
6384
- const money = (value) => formatPrice(value, { symbol: currency });
6385
- const productName = (item) => getLocalizedValue(item.product?.names, props.language, "Product");
6386
- const productImage = (item) => item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
6387
- return /* @__PURE__ */ jsxs("div", { className: cn(`propeller-cart-bonus-items ${props.className || "mt-2"}`), children: [
6388
- /* @__PURE__ */ jsx("h2", { className: "propeller-cart-bonus-items__title text-lg font-semibold mb-3", children: getLabel(props.labels, "title", "Bonus items") }),
6389
- /* @__PURE__ */ jsx("div", { className: "propeller-cart-bonus-items__list space-y-4", children: items.map((item) => {
6390
- const img = productImage(item);
6391
- const name = productName(item);
6392
- const total = props.includeTax ? item.totalPriceNet : item.totalPrice;
6393
- return /* @__PURE__ */ jsxs(
6394
- "div",
6395
- {
6396
- className: "propeller-cart-bonus-item flex items-center gap-4 bg-card p-4 rounded-container shadow-sm border border-border",
6397
- children: [
6398
- /* @__PURE__ */ jsx("div", { className: "propeller-cart-bonus-item__media w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden flex items-center justify-center", children: img ? /* @__PURE__ */ jsx("img", { className: "propeller-cart-bonus-item__image w-full h-full object-contain p-1", src: img, alt: name }) : /* @__PURE__ */ jsx(
6399
- "svg",
6400
- {
6401
- fill: "none",
6402
- viewBox: "0 0 24 24",
6403
- stroke: "currentColor",
6404
- className: "propeller-cart-bonus-item__image-placeholder w-8 h-8 text-foreground-subtle",
6405
- strokeWidth: 1.5,
6406
- children: /* @__PURE__ */ jsx(
6407
- "path",
6408
- {
6409
- strokeLinecap: "round",
6410
- strokeLinejoin: "round",
6411
- 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"
6412
- }
6413
- )
6414
- }
6415
- ) }),
6416
- /* @__PURE__ */ jsxs("div", { className: "propeller-cart-bonus-item__body flex-1 min-w-0", children: [
6417
- item.product?.sku ? /* @__PURE__ */ jsxs("p", { className: "propeller-cart-bonus-item__sku font-mono text-xs text-foreground-subtle", children: [
6418
- getLabel(props.labels, "sku", "SKU"),
6419
- ": ",
6420
- item.product.sku
6421
- ] }) : null,
6422
- /* @__PURE__ */ jsx("p", { className: "propeller-cart-bonus-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2", children: name })
6423
- ] }),
6424
- /* @__PURE__ */ jsxs("div", { className: "propeller-cart-bonus-item__qty text-sm text-muted-foreground whitespace-nowrap", children: [
6425
- item.quantity,
6426
- " \xD7"
6427
- ] }),
6428
- /* @__PURE__ */ jsx("div", { className: "propeller-cart-bonus-item__price font-semibold text-foreground whitespace-nowrap", children: money(total) })
6429
- ]
6430
- },
6431
- item.itemId
6432
- );
6433
- }) })
6434
- ] });
6435
- }
6436
- var CartBonusItems_default = CartBonusItems;
6437
6488
 
6438
6489
  // src/composables/shared/utils/preselect.ts
6439
6490
  function pickPreselected(items, stored, keyOf) {
@@ -6447,7 +6498,7 @@ function CartCarriers(props) {
6447
6498
  const carriers = props.cart?.carriers || [];
6448
6499
  function formatCarrierPrice(price) {
6449
6500
  if (props.formatPrice) return props.formatPrice(price);
6450
- return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
6501
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
6451
6502
  }
6452
6503
  function handleSelect(carrier) {
6453
6504
  setSelectedName(carrier.name);
@@ -6644,7 +6695,7 @@ function CartItem(rawProps) {
6644
6695
  function getFormattedPrice() {
6645
6696
  const item = props.cartItem;
6646
6697
  const price = props.includeTax ? item?.totalSumNet || 0 : item?.totalSum || 0;
6647
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6698
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
6648
6699
  }
6649
6700
  function isBundleItem() {
6650
6701
  return !!props.cartItem.bundle;
@@ -6655,7 +6706,7 @@ function CartItem(rawProps) {
6655
6706
  function getBundlePrice2() {
6656
6707
  const price = props.cartItem.bundle?.price?.net;
6657
6708
  if (price === void 0 || price === null) return "";
6658
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6709
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
6659
6710
  }
6660
6711
  function getBundleLeaderName() {
6661
6712
  const items = props.cartItem.bundle?.items;
@@ -6671,7 +6722,7 @@ function CartItem(rawProps) {
6671
6722
  if (!leader) return "";
6672
6723
  const price = leader.price?.net;
6673
6724
  if (price === void 0 || price === null) return "";
6674
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6725
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
6675
6726
  }
6676
6727
  function getBundleNonLeaders2() {
6677
6728
  const items = props.cartItem.bundle?.items;
@@ -6684,7 +6735,7 @@ function CartItem(rawProps) {
6684
6735
  function getBundleItemPrice(bundleItem) {
6685
6736
  const price = bundleItem.price?.net;
6686
6737
  if (price === void 0 || price === null) return "";
6687
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6738
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
6688
6739
  }
6689
6740
  function getCrossupsellName(item) {
6690
6741
  const product = item?.productTo || item?.clusterTo;
@@ -6777,7 +6828,7 @@ function CartItem(rawProps) {
6777
6828
  if (!price) return "";
6778
6829
  const value = props.includeTax ? price.net : price.gross;
6779
6830
  if (value === void 0 || value === null) return "";
6780
- return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
6831
+ return formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
6781
6832
  }
6782
6833
  async function handleAddCrossupsellToCart(item) {
6783
6834
  if (!props.cartId || addingCrossupsellId) return;
@@ -7017,7 +7068,7 @@ function CartItemChildItems(props = {}) {
7017
7068
  /* @__PURE__ */ jsx("span", { className: "text-foreground-subtle hidden sm:inline", children: "-" }),
7018
7069
  /* @__PURE__ */ jsx("span", { className: "text-foreground-subtle text-xs self-center", children: child.product.sku }),
7019
7070
  /* @__PURE__ */ jsx("div", { className: "flex-1 border-b border-dotted border-border mx-1 mb-1" }),
7020
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: formatPrice(child.totalSum, { symbol: resolved.currency ?? "\u20AC" }) })
7071
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: formatPrice(child.totalSum, { symbol: resolved.currency ?? "\u20AC", locale: localeForLanguage(resolved.language) }) })
7021
7072
  ] }, idx))
7022
7073
  ] });
7023
7074
  }
@@ -7258,7 +7309,7 @@ function CartIconAndSidebar(rawProps) {
7258
7309
  const CartBonusItemsImpl = props.cartBonusItemsComponent ?? CartBonusItems_default;
7259
7310
  const CartItemImpl = props.cartItemComponent ?? CartItem_default;
7260
7311
  const currencySymbol = props.currency ?? "\u20AC";
7261
- const money = (value) => value === void 0 || value === null ? "" : formatPrice(value, { symbol: currencySymbol });
7312
+ const money = (value) => value === void 0 || value === null ? "" : formatPrice(value, { symbol: currencySymbol, locale: localeForLanguage(props.language) });
7262
7313
  const { requestAuthorization } = useCart({
7263
7314
  graphqlClient: props.graphqlClient,
7264
7315
  user: props.user ?? null,
@@ -7279,6 +7330,9 @@ function CartIconAndSidebar(rawProps) {
7279
7330
  const useTax = !!props.includeTax;
7280
7331
  const totalRaw = useTax ? props.cart?.total?.totalNet : props.cart?.total?.totalGross;
7281
7332
  const totalPrice = totalRaw === void 0 || totalRaw === null ? money(0) : money(totalRaw);
7333
+ function totalLabel(key) {
7334
+ return useTax ? getLabel(props.labels, key, "Total") : getLabel(props.labels, "totalExclVat", "Total excl. VAT");
7335
+ }
7282
7336
  const sidebarTitle = props.cartSidebarTitle || props.labels?.["cartSidebarTitle"] || "Shopping cart";
7283
7337
  const purchaserPAC = findPurchaserPAC(props.user, props.companyId);
7284
7338
  const totalGross = props.cart?.total?.totalGross ?? 0;
@@ -7368,7 +7422,7 @@ function CartIconAndSidebar(rawProps) {
7368
7422
  ),
7369
7423
  props.showTotals && isHovered && totalItems > 0 ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-icon__popover absolute top-full right-0 mt-1 z-40 bg-popover border border-border rounded-container shadow-lg px-3 py-2 min-w-[140px] text-sm whitespace-nowrap", children: [
7370
7424
  /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-4", children: [
7371
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-icon__popover-label text-muted-foreground", children: getLabel(props.labels, "totalLabel", "Total") }),
7425
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-icon__popover-label text-muted-foreground", children: totalLabel("totalLabel") }),
7372
7426
  /* @__PURE__ */ jsx("span", { className: "propeller-cart-icon__popover-total font-semibold text-foreground", children: totalPrice })
7373
7427
  ] }),
7374
7428
  /* @__PURE__ */ jsxs("div", { className: "propeller-cart-icon__popover-count text-xs text-foreground-subtle mt-0.5", children: [
@@ -7523,7 +7577,7 @@ function CartIconAndSidebar(rawProps) {
7523
7577
  " ",
7524
7578
  items.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-icon__sidebar-footer px-5 py-4 border-t border-border space-y-3 bg-surface-hover", children: [
7525
7579
  /* @__PURE__ */ jsxs("div", { className: "propeller-cart-icon__total-row flex justify-between items-center", children: [
7526
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-icon__total-label text-sm font-medium text-muted-foreground", children: getLabel(props.labels, "total", "Total") }),
7580
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-icon__total-label text-sm font-medium text-muted-foreground", children: totalLabel("total") }),
7527
7581
  /* @__PURE__ */ jsx("span", { className: "propeller-cart-icon__total-value text-base font-bold text-foreground", children: totalPrice })
7528
7582
  ] }),
7529
7583
  showCheckoutButton && !showRequestAuthorizationButton ? /* @__PURE__ */ jsx(
@@ -7765,7 +7819,7 @@ function CartPaymethods(rawProps) {
7765
7819
  });
7766
7820
  function formatMethodPrice(price) {
7767
7821
  if (props.formatPrice) return props.formatPrice(price);
7768
- return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
7822
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
7769
7823
  }
7770
7824
  function methodName(method) {
7771
7825
  const code = (method.code || "").toLowerCase();
@@ -7851,7 +7905,7 @@ function CartSummary(rawProps) {
7851
7905
  if (props.formatPrice) {
7852
7906
  return props.formatPrice(price);
7853
7907
  }
7854
- return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
7908
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
7855
7909
  }
7856
7910
  function subtotal() {
7857
7911
  return props.cart?.total?.subTotal || 0;
@@ -7930,83 +7984,96 @@ function CartSummary(rawProps) {
7930
7984
  setRequestLoading(false);
7931
7985
  }
7932
7986
  }
7933
- return /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary w-full bg-card space-y-3", children: [
7934
- /* @__PURE__ */ jsx("h2", { className: "propeller-cart-summary__title text-xl font-bold mb-4", children: title() }),
7935
- showSubtotal() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "subtotal", children: [
7936
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "subtotal", "Subtotal:") }),
7937
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(subtotal()) })
7938
- ] }) : null,
7939
- showDiscount() && hasDiscount() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-success", "data-row": "discount", children: [
7940
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "discount", "Discount:") }),
7941
- /* @__PURE__ */ jsxs("span", { className: "propeller-cart-summary__value", children: [
7942
- "-",
7943
- formatItemPrice(discountAmount())
7944
- ] })
7945
- ] }) : null,
7946
- hasTransactionCosts() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "transaction-costs", children: [
7947
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "transactionCosts", "Transaction costs:") }),
7948
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(transactionCosts()) })
7949
- ] }) : null,
7950
- showShippingCosts() && hasShippingCosts() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "shipping-costs", children: [
7951
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "shippingCosts", "Shipping costs:") }),
7952
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(shippingCosts()) })
7953
- ] }) : null,
7954
- showTotalExclVat() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground pt-2 border-t", "data-row": "total-excl-vat", children: [
7955
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "totalExclVat", "Total excl. VAT:") }),
7956
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalExclVat()) })
7957
- ] }) : null,
7958
- showVATs() && taxLevels().length > 0 ? /* @__PURE__ */ jsx(Fragment, { children: taxLevels()?.map((tax, index) => /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "vat-line", children: [
7959
- /* @__PURE__ */ jsxs("span", { className: "propeller-cart-summary__label", children: [
7960
- tax.taxPercentage,
7961
- "% ",
7962
- getLabel(props.labels, "vat", "VAT"),
7963
- ":"
7964
- ] }),
7965
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(Number(tax.price)) })
7966
- ] }, index)) }) : null,
7967
- showTotalVat() && totalVat() > 0 ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "total-vat", children: [
7968
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "totalVat", "Total VAT:") }),
7969
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalVat()) })
7970
- ] }) : null,
7971
- /* @__PURE__ */ jsxs("div", { className: "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", children: [
7972
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "total", "Total:") }),
7973
- /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalInclVat()) })
7974
- ] }),
7975
- showCheckoutButton() && !showRequestAuthorizationButton() ? /* @__PURE__ */ jsxs(Fragment, { children: [
7976
- /* @__PURE__ */ jsx(
7977
- "button",
7978
- {
7979
- type: "button",
7980
- className: "propeller-cart-summary__checkout-btn block w-full bg-secondary text-secondary-foreground text-center py-3 rounded-container hover:bg-secondary/90 transition font-semibold mt-4",
7981
- onClick: (event) => handleCheckoutClick(),
7982
- children: getLabel(props.labels, "checkoutButton", "Continue to Checkout")
7983
- }
7987
+ return /* @__PURE__ */ jsxs(
7988
+ "div",
7989
+ {
7990
+ className: cn(
7991
+ // Padding, radius and shadow to match ActionCode, which sits directly
7992
+ // under this panel on the cart page. Without them the summary painted
7993
+ // a card background with its text against the edges and a full-bleed
7994
+ // checkout button — the same column, two different card treatments.
7995
+ "propeller-cart-summary w-full bg-card p-6 rounded-container shadow space-y-3",
7996
+ props.className
7984
7997
  ),
7985
- " ",
7986
- !!props.onRequestQuoteClick && showRequestQuoteButton() ? /* @__PURE__ */ jsx(
7987
- "button",
7988
- {
7989
- type: "button",
7990
- className: "propeller-cart-summary__quote-btn block w-full bg-card border border-secondary text-secondary text-center py-3 rounded-container hover:bg-secondary/5 transition font-semibold mt-2",
7991
- onClick: (event) => props.onRequestQuoteClick && props.onRequestQuoteClick(props.cart),
7992
- children: getLabel(props.labels, "requestQuoteButton", "Request a Quote")
7993
- }
7994
- ) : null
7995
- ] }) : null,
7996
- showRequestAuthorizationButton() ? /* @__PURE__ */ jsxs(
7997
- "button",
7998
- {
7999
- type: "button",
8000
- className: "propeller-cart-summary__authorization-btn block w-full bg-secondary text-secondary-foreground text-center py-3 rounded-container hover:bg-secondary/90 transition font-semibold mt-4 disabled:opacity-50 disabled:cursor-not-allowed",
8001
- onClick: (event) => handleRequestAuthorizationClick(),
8002
- disabled: requestLoading,
8003
- children: [
8004
- requestLoading ? /* @__PURE__ */ jsx(Fragment, { children: getLabel(props.labels, "requestingAuthorization", "Requesting...") }) : null,
8005
- !requestLoading ? /* @__PURE__ */ jsx(Fragment, { children: getLabel(props.labels, "requestAuthorizationButton", "Request Authorization") }) : null
8006
- ]
8007
- }
8008
- ) : null
8009
- ] });
7998
+ children: [
7999
+ /* @__PURE__ */ jsx("h2", { className: "propeller-cart-summary__title text-xl font-bold mb-4", children: title() }),
8000
+ showSubtotal() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "subtotal", children: [
8001
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "subtotal", "Subtotal:") }),
8002
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(subtotal()) })
8003
+ ] }) : null,
8004
+ showDiscount() && hasDiscount() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-success", "data-row": "discount", children: [
8005
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "discount", "Discount:") }),
8006
+ /* @__PURE__ */ jsxs("span", { className: "propeller-cart-summary__value", children: [
8007
+ "-",
8008
+ formatItemPrice(discountAmount())
8009
+ ] })
8010
+ ] }) : null,
8011
+ hasTransactionCosts() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "transaction-costs", children: [
8012
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "transactionCosts", "Transaction costs:") }),
8013
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(transactionCosts()) })
8014
+ ] }) : null,
8015
+ showShippingCosts() && hasShippingCosts() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "shipping-costs", children: [
8016
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "shippingCosts", "Shipping costs:") }),
8017
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(shippingCosts()) })
8018
+ ] }) : null,
8019
+ showTotalExclVat() ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground pt-2 border-t", "data-row": "total-excl-vat", children: [
8020
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "totalExclVat", "Total excl. VAT:") }),
8021
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalExclVat()) })
8022
+ ] }) : null,
8023
+ showVATs() && taxLevels().length > 0 ? /* @__PURE__ */ jsx(Fragment, { children: taxLevels()?.map((tax, index) => /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "vat-line", children: [
8024
+ /* @__PURE__ */ jsxs("span", { className: "propeller-cart-summary__label", children: [
8025
+ tax.taxPercentage,
8026
+ "% ",
8027
+ getLabel(props.labels, "vat", "VAT"),
8028
+ ":"
8029
+ ] }),
8030
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(Number(tax.price)) })
8031
+ ] }, index)) }) : null,
8032
+ showTotalVat() && totalVat() > 0 ? /* @__PURE__ */ jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "total-vat", children: [
8033
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "totalVat", "Total VAT:") }),
8034
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalVat()) })
8035
+ ] }) : null,
8036
+ /* @__PURE__ */ jsxs("div", { className: "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", children: [
8037
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__label", children: getLabel(props.labels, "total", "Total:") }),
8038
+ /* @__PURE__ */ jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalInclVat()) })
8039
+ ] }),
8040
+ showCheckoutButton() && !showRequestAuthorizationButton() ? /* @__PURE__ */ jsxs(Fragment, { children: [
8041
+ /* @__PURE__ */ jsx(
8042
+ "button",
8043
+ {
8044
+ type: "button",
8045
+ className: "propeller-cart-summary__checkout-btn block w-full bg-secondary text-secondary-foreground text-center py-3 rounded-container hover:bg-secondary/90 transition font-semibold mt-4",
8046
+ onClick: (event) => handleCheckoutClick(),
8047
+ children: getLabel(props.labels, "checkoutButton", "Continue to Checkout")
8048
+ }
8049
+ ),
8050
+ " ",
8051
+ !!props.onRequestQuoteClick && showRequestQuoteButton() ? /* @__PURE__ */ jsx(
8052
+ "button",
8053
+ {
8054
+ type: "button",
8055
+ className: "propeller-cart-summary__quote-btn block w-full bg-card border border-secondary text-secondary text-center py-3 rounded-container hover:bg-secondary/5 transition font-semibold mt-2",
8056
+ onClick: (event) => props.onRequestQuoteClick && props.onRequestQuoteClick(props.cart),
8057
+ children: getLabel(props.labels, "requestQuoteButton", "Request a Quote")
8058
+ }
8059
+ ) : null
8060
+ ] }) : null,
8061
+ showRequestAuthorizationButton() ? /* @__PURE__ */ jsxs(
8062
+ "button",
8063
+ {
8064
+ type: "button",
8065
+ className: "propeller-cart-summary__authorization-btn block w-full bg-secondary text-secondary-foreground text-center py-3 rounded-container hover:bg-secondary/90 transition font-semibold mt-4 disabled:opacity-50 disabled:cursor-not-allowed",
8066
+ onClick: (event) => handleRequestAuthorizationClick(),
8067
+ disabled: requestLoading,
8068
+ children: [
8069
+ requestLoading ? /* @__PURE__ */ jsx(Fragment, { children: getLabel(props.labels, "requestingAuthorization", "Requesting...") }) : null,
8070
+ !requestLoading ? /* @__PURE__ */ jsx(Fragment, { children: getLabel(props.labels, "requestAuthorizationButton", "Request Authorization") }) : null
8071
+ ]
8072
+ }
8073
+ ) : null
8074
+ ]
8075
+ }
8076
+ );
8010
8077
  }
8011
8078
  var CartSummary_default = CartSummary;
8012
8079
  function CategoryDescription(props) {
@@ -8146,7 +8213,7 @@ function ClusterCard(rawProps) {
8146
8213
  const useTax = props.includeTax !== void 0 ? !!props.includeTax : false;
8147
8214
  const priceObj = contentHidden ? void 0 : cluster?.defaultProduct?.price;
8148
8215
  const priceValue = useTax ? priceObj?.net : priceObj?.gross;
8149
- const clusterPrice = props.showPrice === false ? "" : formatPrice(priceValue, { symbol: props.currency ?? "\u20AC" });
8216
+ const clusterPrice = props.showPrice === false ? "" : formatPrice(priceValue, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
8150
8217
  function handleClusterClick(e) {
8151
8218
  if (props.onClusterClick) {
8152
8219
  e.preventDefault();
@@ -8572,7 +8639,7 @@ function ProductPriceDisplay(props) {
8572
8639
  }
8573
8640
  function formatPrice17(value) {
8574
8641
  if (value === null || value === void 0) return "";
8575
- return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
8642
+ return formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
8576
8643
  }
8577
8644
  function getOptionsTotal(useNet) {
8578
8645
  const options = props.options || [];
@@ -8661,6 +8728,11 @@ var RESOLVE_SPEC2 = {
8661
8728
  includeTax: { infra: "includeTax" },
8662
8729
  portalMode: { infra: "portalMode" },
8663
8730
  configuration: { infra: "configuration" },
8731
+ // Same entry ClusterCard has always had. Without it a shop priced in
8732
+ // anything but euros had no route to the cards at all: the grid resolved the
8733
+ // currency and then dropped it, and the card fell through to the package
8734
+ // default on every price it rendered.
8735
+ currency: { infra: "currency", default: "\u20AC" },
8664
8736
  columns: { grid: "columns", default: 3 },
8665
8737
  showPrice: { grid: "showPrice" },
8666
8738
  showStock: { grid: "showStock" },
@@ -8995,7 +9067,8 @@ function ProductCardPrice(props) {
8995
9067
  {
8996
9068
  price: product.price,
8997
9069
  includeTax: derived.useTax,
8998
- labels: resolved.priceLabels
9070
+ labels: resolved.priceLabels,
9071
+ currency: resolved.currency
8999
9072
  }
9000
9073
  ) });
9001
9074
  }
@@ -9006,6 +9079,8 @@ function ProductCardPrice(props) {
9006
9079
  includeTax: derived.useTax,
9007
9080
  priceSize: props.priceSize ?? "text-base sm:text-lg",
9008
9081
  labels: resolved.priceLabels,
9082
+ currency: resolved.currency,
9083
+ language: resolved.language,
9009
9084
  portalMode: resolved.portalMode,
9010
9085
  user: resolved.user,
9011
9086
  showLoginPrompt: false
@@ -9411,6 +9486,7 @@ ProductGridCompound.Pagination = ProductGridPagination;
9411
9486
  var ProductGrid_default = ProductGridCompound;
9412
9487
  function GridFilters(rawProps) {
9413
9488
  const props = useInfraProps(rawProps);
9489
+ const currencySymbol = props.currency ?? "\u20AC";
9414
9490
  const [selectedFilters, setSelectedFilters] = useState(
9415
9491
  () => ({ ...props.activeTextFilters || {} })
9416
9492
  );
@@ -9627,7 +9703,7 @@ function GridFilters(rawProps) {
9627
9703
  ] }),
9628
9704
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9629
9705
  /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
9630
- /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__price-currency absolute left-2.5 top-1/2 -translate-y-1/2 text-xs text-foreground-subtle pointer-events-none", children: "\u20AC" }),
9706
+ /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__price-currency absolute left-2.5 top-1/2 -translate-y-1/2 text-xs text-foreground-subtle pointer-events-none", children: currencySymbol }),
9631
9707
  /* @__PURE__ */ jsx(
9632
9708
  "input",
9633
9709
  {
@@ -9646,7 +9722,7 @@ function GridFilters(rawProps) {
9646
9722
  ] }),
9647
9723
  /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__price-separator text-foreground-subtle text-sm select-none", children: "\u2013" }),
9648
9724
  /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
9649
- /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__price-currency absolute left-2.5 top-1/2 -translate-y-1/2 text-xs text-foreground-subtle pointer-events-none", children: "\u20AC" }),
9725
+ /* @__PURE__ */ jsx("span", { className: "propeller-grid-filters__price-currency absolute left-2.5 top-1/2 -translate-y-1/2 text-xs text-foreground-subtle pointer-events-none", children: currencySymbol }),
9650
9726
  /* @__PURE__ */ jsx(
9651
9727
  "input",
9652
9728
  {
@@ -9954,6 +10030,7 @@ var DEFAULT_LABELS = {
9954
10030
  };
9955
10031
  function GridToolbar(rawProps) {
9956
10032
  const props = useInfraProps(rawProps);
10033
+ const currencySymbol = props.currency ?? "\u20AC";
9957
10034
  const [currentSortField, setCurrentSortField] = useState(
9958
10035
  ProductSortField.CATEGORY_ORDER
9959
10036
  );
@@ -10166,9 +10243,11 @@ function GridToolbar(rawProps) {
10166
10243
  },
10167
10244
  children: [
10168
10245
  getLabel59("price"),
10169
- ": \u20AC",
10246
+ ": ",
10247
+ currencySymbol,
10170
10248
  props.priceFilterMin ?? 0,
10171
- " \u2013 \u20AC",
10249
+ " \u2013 ",
10250
+ currencySymbol,
10172
10251
  props.priceFilterMax ?? "\u221E",
10173
10252
  /* @__PURE__ */ jsx("span", { className: "propeller-grid-toolbar__filter-badge-remove", children: "\xD7" })
10174
10253
  ]
@@ -10819,8 +10898,8 @@ function ClusterInfo(rawProps) {
10819
10898
  ] });
10820
10899
  }
10821
10900
  var ClusterInfo_default = ClusterInfo;
10822
- function formatPrice9(price, currency) {
10823
- return formatPrice(price, { symbol: currency });
10901
+ function formatPrice9(price, currency, language) {
10902
+ return formatPrice(price, { symbol: currency, locale: localeForLanguage(language) });
10824
10903
  }
10825
10904
  function getProductName2(product, language) {
10826
10905
  return getLocalizedValue(product.names, language, `Product ${product.productId}`);
@@ -10847,7 +10926,7 @@ function ClusterOptions(rawProps) {
10847
10926
  const products = (option.products || []).map((p) => ({
10848
10927
  productId: p.productId,
10849
10928
  productIdStr: p.productId.toString(),
10850
- label: hidePrices ? getProductName2(p, language) : `${getProductName2(p, language)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC")}`
10929
+ label: hidePrices ? getProductName2(p, language) : `${getProductName2(p, language)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC", language)}`
10851
10930
  }));
10852
10931
  let previewImageUrl = "";
10853
10932
  let previewName = "";
@@ -10859,7 +10938,7 @@ function ClusterOptions(rawProps) {
10859
10938
  if (selectedProduct) {
10860
10939
  previewImageUrl = getProductImageUrl4(selectedProduct);
10861
10940
  previewName = getProductName2(selectedProduct, language);
10862
- previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
10941
+ previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC", props.language);
10863
10942
  }
10864
10943
  }
10865
10944
  const isRequired = option.isRequired === YesNo.Y;
@@ -11348,7 +11427,7 @@ function FavoriteListItem(rawProps) {
11348
11427
  if (!priceObj) return "";
11349
11428
  const value = useTax ? priceObj.net : priceObj.gross;
11350
11429
  if (!value && value !== 0) return "";
11351
- return formatPrice(value, { symbol: currency });
11430
+ return formatPrice(value, { symbol: currency, locale: localeForLanguage(props.language) });
11352
11431
  })();
11353
11432
  function handleItemClick(e) {
11354
11433
  if (props.onItemClick) {
@@ -12923,12 +13002,12 @@ function ItemsOverview(rawProps) {
12923
13002
  const showPrice = props.showPrice !== void 0 ? props.showPrice : true;
12924
13003
  const items = props.cart?.items ?? [];
12925
13004
  const currencySymbol = props.currency ?? "\u20AC";
12926
- const money = (value) => value === void 0 || value === null ? "" : formatPrice(value, { symbol: currencySymbol });
13005
+ const money = (value) => value === void 0 || value === null ? "" : formatPrice(value, { symbol: currencySymbol, locale: localeForLanguage(props.language) });
12927
13006
  function formatItemPrice(price) {
12928
13007
  if (props.formatPrice) {
12929
13008
  return props.formatPrice(price);
12930
13009
  }
12931
- return formatPrice(price || 0, { symbol: currencySymbol });
13010
+ return formatPrice(price || 0, { symbol: currencySymbol, locale: localeForLanguage(props.language) });
12932
13011
  }
12933
13012
  function lineTotal(item) {
12934
13013
  return (useTax ? item.totalSumNet : item.totalSum) || 0;
@@ -13531,20 +13610,21 @@ var OrderActions_default = OrderActions;
13531
13610
  function getProductName3(orderItem, language) {
13532
13611
  return getLocalizedValue(orderItem?.product?.names, language, "") || orderItem?.name || "Unknown Product";
13533
13612
  }
13534
- function getClusterUrl(orderItem, language) {
13613
+ function getClusterUrl(orderItem, language, urls) {
13535
13614
  const cluster = orderItem?.product?.cluster;
13536
13615
  if (!cluster) return "";
13537
13616
  const id = cluster.clusterId;
13538
13617
  const slug = getLocalizedValue(cluster.slugs, language, "");
13539
13618
  if (!id || !slug) return "";
13540
- return `/cluster/${id}/${slug}`;
13619
+ return urls?.getClusterUrl?.(cluster, language) || `/cluster/${id}/${slug}`;
13541
13620
  }
13542
- function getProductUrl(orderItem, language) {
13543
- const cu = getClusterUrl(orderItem, language);
13621
+ function getProductUrl(orderItem, language, urls) {
13622
+ const cu = getClusterUrl(orderItem, language, urls);
13544
13623
  if (cu) return cu;
13545
- const id = orderItem?.product?.productId;
13546
- const slug = getLocalizedValue(orderItem?.product?.slugs, language, "");
13547
- if (id && slug) return `/product/${id}/${slug}`;
13624
+ const product = orderItem?.product;
13625
+ const id = product?.productId;
13626
+ const slug = getLocalizedValue(product?.slugs, language, "");
13627
+ if (id && slug) return urls?.getProductUrl?.(product, language) || `/product/${id}/${slug}`;
13548
13628
  return "";
13549
13629
  }
13550
13630
  function OrderItemCard(props) {
@@ -13561,7 +13641,7 @@ function OrderItemCard(props) {
13561
13641
  const productName = getProductName3(item, props.language);
13562
13642
  const productSku = item?.product?.sku || item?.sku || "";
13563
13643
  const productImage = item?.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
13564
- const productUrl = getProductUrl(item, props.language);
13644
+ const productUrl = getProductUrl(item, props.language, props.configuration?.urls);
13565
13645
  const quantity = item?.quantity || 0;
13566
13646
  const priceTotal = item?.priceTotal || 0;
13567
13647
  const discount = item?.discount || 0;
@@ -13574,7 +13654,7 @@ function OrderItemCard(props) {
13574
13654
  return props.formatPrice(price);
13575
13655
  }
13576
13656
  if (!price && price !== 0) return "-";
13577
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
13657
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
13578
13658
  }
13579
13659
  const discountDisplay = discountPercentage > 0 ? `${formatItemPrice(discount)} (${discountPercentage.toFixed(2).replace(".", ",")}%)` : formatItemPrice(discount);
13580
13660
  return /* @__PURE__ */ jsxs("tbody", { className: "propeller-order-item-card", children: [
@@ -13739,7 +13819,7 @@ function OrderList(rawProps) {
13739
13819
  function formatPrice17(price) {
13740
13820
  if (props.formatPrice) return props.formatPrice(price);
13741
13821
  if (!price) return "-";
13742
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
13822
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
13743
13823
  }
13744
13824
  function getStatusColor(status) {
13745
13825
  if (props.getStatusColor) return props.getStatusColor(status);
@@ -14168,7 +14248,31 @@ function OrderList(rawProps) {
14168
14248
  ) })
14169
14249
  ] })
14170
14250
  ] }) : null
14171
- ] }) : /* @__PURE__ */ jsx("div", { className: `propeller-order-list__empty${props.flat ? "" : " bg-card rounded-container shadow"} p-8 text-center`, children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mb-4", children: getLabel(props.labels, "noOrders", "No orders found.") }) }) }) : /* @__PURE__ */ jsx("div", { className: "propeller-order-list__loading p-8 text-center text-muted-foreground", children: getLabel(props.labels, "loading", "Loading orders...") })
14251
+ ] }) : /* @__PURE__ */ jsx("div", { className: `propeller-order-list__empty${props.flat ? "" : " bg-card rounded-container shadow"} p-8 text-center`, children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mb-4", children: getLabel(props.labels, "noOrders", "No orders found.") }) }) }) : (
14252
+ // A centred line of text collapsed the list to one row and then
14253
+ // snapped back, which is what made a language switch on the account
14254
+ // pages look broken. Skeleton rows hold the layout instead.
14255
+ /* @__PURE__ */ jsx(
14256
+ "div",
14257
+ {
14258
+ className: `propeller-order-list__loading${props.flat ? "" : " bg-card rounded-container shadow"} p-4`,
14259
+ "aria-busy": "true",
14260
+ "aria-label": getLabel(props.labels, "loading", "Loading orders..."),
14261
+ children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxs(
14262
+ "div",
14263
+ {
14264
+ className: "propeller-order-list__skeleton-row flex items-center gap-4 py-4 border-b border-border last:border-b-0 animate-pulse",
14265
+ children: [
14266
+ /* @__PURE__ */ jsx("div", { className: "propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-24" }),
14267
+ /* @__PURE__ */ jsx("div", { className: "propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-32" }),
14268
+ /* @__PURE__ */ jsx("div", { className: "propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-20 ml-auto" })
14269
+ ]
14270
+ },
14271
+ index
14272
+ ))
14273
+ }
14274
+ )
14275
+ )
14172
14276
  ] });
14173
14277
  }
14174
14278
  var OrderList_default = OrderList;
@@ -14209,7 +14313,7 @@ function QuickOrderInner(props) {
14209
14313
  } = props;
14210
14314
  const user = props.user ?? null;
14211
14315
  const graphqlClient = props.graphqlClient;
14212
- const displayPrice = (n) => props.formatPrice ? props.formatPrice(n) : formatPrice(n, { symbol: currency });
14316
+ const displayPrice = (n) => props.formatPrice ? props.formatPrice(n) : formatPrice(n, { symbol: currency, locale: localeForLanguage(props.language) });
14213
14317
  const L = (key, fallback) => getLabel(labels, key, fallback);
14214
14318
  const { submitting, searchProducts, submit } = useQuickOrder({
14215
14319
  graphqlClient,
@@ -14743,7 +14847,7 @@ function OrderSummary(props) {
14743
14847
  if (props.formatPrice) {
14744
14848
  return props.formatPrice(price);
14745
14849
  }
14746
- return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
14850
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
14747
14851
  }
14748
14852
  function numericDate(dateString) {
14749
14853
  const d = new Date(dateString);
@@ -14851,7 +14955,7 @@ function OrderTotals(props) {
14851
14955
  const postageData = props.order?.postageData;
14852
14956
  function formatItemPrice(price) {
14853
14957
  if (props.formatPrice) return props.formatPrice(price);
14854
- return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
14958
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
14855
14959
  }
14856
14960
  const subtotal = total?.gross || 0;
14857
14961
  const hasDiscount = !!total && total.discountType !== OrderDiscountType.N && total.discountValue > 0;
@@ -15016,7 +15120,7 @@ function ProductBulkPrices(props) {
15016
15120
  function getPrice(tier) {
15017
15121
  const value = includeTax ? tier.net : tier.gross;
15018
15122
  if (value === null || value === void 0) return "";
15019
- return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
15123
+ return formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
15020
15124
  }
15021
15125
  function getQuantityLabel(tier, index) {
15022
15126
  const discount = tier.discount;
@@ -15027,13 +15131,14 @@ function ProductBulkPrices(props) {
15027
15131
  if (nextQty) return `${qty}\u2013${nextQty - 1}`;
15028
15132
  return `${qty}+`;
15029
15133
  }
15134
+ const title = props.labels?.title ?? "Volume pricing";
15030
15135
  return /* @__PURE__ */ jsx(Fragment, { children: !isHidden2 && hasItems ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
15031
15136
  "div",
15032
15137
  {
15033
15138
  className: cn(`propeller-product-bulk-prices ${props.className || ""}`),
15034
15139
  "data-include-tax": includeTax ? "true" : "false",
15035
15140
  children: [
15036
- getLabel(props.labels, "title", "Volume pricing") ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-bulk-prices__title text-base font-semibold text-foreground mb-3", children: getLabel(props.labels, "title", "Volume pricing") }) : null,
15141
+ title ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-bulk-prices__title text-base font-semibold text-foreground mb-3", children: title }) : null,
15037
15142
  /* @__PURE__ */ jsx("div", { className: "propeller-product-bulk-prices__table-wrapper overflow-hidden rounded-container border border-border", children: /* @__PURE__ */ jsxs("table", { className: "propeller-product-bulk-prices__table w-full text-sm", children: [
15038
15143
  /* @__PURE__ */ jsx("thead", { className: "propeller-product-bulk-prices__thead bg-muted/50", children: /* @__PURE__ */ jsxs("tr", { children: [
15039
15144
  /* @__PURE__ */ jsx("th", { className: "propeller-product-bulk-prices__th propeller-product-bulk-prices__th--quantity px-4 py-2 text-left font-medium text-muted-foreground", children: getLabel(props.labels, "quantityFrom", "Qty from") }),
@@ -15080,7 +15185,7 @@ function ProductBundles(rawProps) {
15080
15185
  const props = useInfraProps(rawProps);
15081
15186
  const language = props.language;
15082
15187
  const currencySymbol = props.currency ?? "\u20AC";
15083
- const money = (value) => formatPrice(value, { symbol: currencySymbol });
15188
+ const money = (value) => formatPrice(value, { symbol: currencySymbol, locale: localeForLanguage(props.language) });
15084
15189
  const [isMounted, setIsMounted] = useState(false);
15085
15190
  const [addingBundleId, setAddingBundleId] = useState(null);
15086
15191
  const [lastAddedBundle, setLastAddedBundle] = useState(null);
@@ -15271,7 +15376,7 @@ function ProductBundles(rawProps) {
15271
15376
  onClick: () => handleAddToCart(bundle),
15272
15377
  disabled: addingBundleId === bundle.id,
15273
15378
  "data-loading": addingBundleId === bundle.id ? "true" : "false",
15274
- children: addingBundleId === bundle.id ? getLabel(props.labels, "adding", "Adding...") : getLabel(props.labels, "addToCart", "In cart")
15379
+ children: addingBundleId === bundle.id ? getLabel(props.labels, "adding", "Adding...") : getLabel(props.labels, "addToCart", "Add to cart")
15275
15380
  }
15276
15381
  )
15277
15382
  ] }) : props.showLoginPrompt !== false ? /* @__PURE__ */ jsx("div", { className: "propeller-product-bundles__login-prompt text-center text-sm text-muted-foreground py-2", children: getLabel(
@@ -17410,7 +17515,7 @@ function PurchaseAuthorizationRequests(rawProps) {
17410
17515
  }
17411
17516
  function formatPrice17(price) {
17412
17517
  if (props.formatPrice) return props.formatPrice(price);
17413
- return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
17518
+ return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
17414
17519
  }
17415
17520
  const columnLabelKeys = {
17416
17521
  date: ["colDate", "Date"],
@@ -18631,12 +18736,12 @@ function RegisterForm(rawProps) {
18631
18736
  ] });
18632
18737
  }
18633
18738
  var RegisterForm_default = RegisterForm;
18634
- function mapToSearchBarResult(item, language) {
18739
+ function mapToSearchBarResult(item, language, urls) {
18635
18740
  const isCluster = "clusterId" in item;
18636
18741
  const displayItem = isCluster ? item.defaultProduct : item;
18637
18742
  const id = isCluster ? item.clusterId : item.productId;
18638
18743
  const slug = getLocalizedValue(item.slugs, language, "");
18639
- const url = isCluster ? "/cluster/" + id + "/" + slug : "/product/" + id + "/" + slug;
18744
+ const url = isCluster ? urls?.getClusterUrl?.(item, language) || "/cluster/" + id + "/" + slug : urls?.getProductUrl?.(item, language) || "/product/" + id + "/" + slug;
18640
18745
  const priceNet = displayItem?.price?.net || 0;
18641
18746
  const priceGross = displayItem?.price?.gross || 0;
18642
18747
  const localizedName = language && item.names?.find((n) => n.language === language)?.value || item.names?.[0]?.value || "Product";
@@ -18676,13 +18781,19 @@ function SearchBar(rawProps) {
18676
18781
  applyOrderlists: props.applyOrderlists,
18677
18782
  productTrackAttributes: props.productTrackAttributes
18678
18783
  });
18679
- const results = searchResults.slice(0, maxResults).map((item) => mapToSearchBarResult(item, props.language));
18784
+ const results = searchResults.slice(0, maxResults).map(
18785
+ (item) => mapToSearchBarResult(
18786
+ item,
18787
+ props.language,
18788
+ props.configuration?.urls
18789
+ )
18790
+ );
18680
18791
  const itemsFound = searchItemsFound;
18681
18792
  function formatItemPrice(price) {
18682
18793
  if (props.formatPrice) {
18683
18794
  return props.formatPrice(price);
18684
18795
  }
18685
- return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
18796
+ return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
18686
18797
  }
18687
18798
  const useTax = !!props.includeTax;
18688
18799
  function leadingPrice(result) {
@@ -18781,7 +18892,14 @@ function SearchBar(rawProps) {
18781
18892
  {
18782
18893
  type: "search",
18783
18894
  autoComplete: "off",
18784
- className: "propeller-search-bar__input w-full pl-10 pr-10 py-2 bg-white/95 border border-white/20 rounded-container focus:outline-none focus:ring-2 focus:ring-secondary placeholder:text-muted-foreground",
18895
+ className: cn(
18896
+ // Themed surface + border rather than the white-on-white the
18897
+ // boilerplate's dark header band happened to make work: on a
18898
+ // light header `bg-white/95 border-white/20` rendered as an
18899
+ // invisible input.
18900
+ "propeller-search-bar__input w-full pl-10 pr-10 py-2 bg-card border border-input rounded-container focus:outline-none focus:ring-2 focus:ring-secondary placeholder:text-muted-foreground",
18901
+ props.inputClassName
18902
+ ),
18785
18903
  placeholder: props.placeholder || "Search products...",
18786
18904
  value: localTerm,
18787
18905
  onChange: (e) => handleInputChange(e.target.value)