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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -736,12 +736,33 @@ async function initCart(config) {
736
736
  }
737
737
 
738
738
  // src/composables/react/useCart.ts
739
+ var DEFAULT_IMAGE_SEARCH_FILTERS = { page: 1, offset: 1 };
740
+ var DEFAULT_IMAGE_VARIANT_FILTERS = {
741
+ transformations: [
742
+ { name: "thumb", transformation: { format: "WEBP", height: 100, width: 100, fit: "BOUNDS" } }
743
+ ]
744
+ };
739
745
  function useCart(options) {
740
746
  const { graphqlClient, user, companyId, configuration, onCartCreated } = options;
741
747
  const language = options.language || configuration?.language || "NL";
742
748
  const [cart, setCart] = React6.useState(null);
743
749
  const [createdCartId, setCreatedCartId] = React6.useState("");
744
750
  const cartId = options.cartId || createdCartId;
751
+ const cartIdRef = React6.useRef(cartId);
752
+ if (cartId && cartIdRef.current !== cartId) cartIdRef.current = cartId;
753
+ const rememberCart = React6.useCallback((c) => {
754
+ setCart(c);
755
+ setCreatedCartId(c.cartId);
756
+ cartIdRef.current = c.cartId;
757
+ }, []);
758
+ const imageSearchFilters = React6.useCallback(
759
+ () => configuration?.imageSearchFiltersGrid ?? DEFAULT_IMAGE_SEARCH_FILTERS,
760
+ [configuration]
761
+ );
762
+ const imageVariantFilters = React6.useCallback(
763
+ () => configuration?.imageVariantFiltersSmall ?? DEFAULT_IMAGE_VARIANT_FILTERS,
764
+ [configuration]
765
+ );
745
766
  const [loading, setLoading] = React6.useState(false);
746
767
  const [error, setError] = React6.useState(null);
747
768
  const notesTimers = React6.useRef({});
@@ -773,17 +794,15 @@ function useCart(options) {
773
794
  user,
774
795
  companyId,
775
796
  language,
776
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
777
- imageVariantFilters: configuration?.imageVariantFiltersSmall,
797
+ imageSearchFilters: imageSearchFilters(),
798
+ imageVariantFilters: imageVariantFilters(),
778
799
  onCartCreated: (c) => {
779
- setCart(c);
780
- setCreatedCartId(c.cartId);
800
+ rememberCart(c);
781
801
  onCartCreated?.(c);
782
802
  }
783
803
  };
784
804
  const resolved = await initCart(config);
785
- setCart(resolved);
786
- setCreatedCartId(resolved.cartId);
805
+ rememberCart(resolved);
787
806
  return resolved;
788
807
  }, [graphqlClient, user, companyId, language, configuration, onCartCreated]);
789
808
  const addItem = React6.useCallback(async (opts) => {
@@ -796,14 +815,13 @@ function useCart(options) {
796
815
  }
797
816
  const childItemInputs = opts.childItems?.map((id) => ({ productId: id, quantity: opts.quantity }));
798
817
  if (opts.onAddToCart) {
799
- const resultCart2 = opts.onAddToCart(opts.product, opts.cluster?.clusterId, opts.quantity, childItemInputs, opts.notes, opts.price);
800
- setCart(resultCart2);
801
- setCreatedCartId(resultCart2.cartId);
818
+ const resultCart2 = await opts.onAddToCart(opts.product, opts.cluster?.clusterId, opts.quantity, childItemInputs, opts.notes, opts.price);
819
+ rememberCart(resultCart2);
802
820
  const addedItem2 = resultCart2.items?.find((i) => i.productId === opts.product.productId) ?? null;
803
821
  opts.afterAddToCart?.(resultCart2, addedItem2);
804
822
  return propellerV2CoreUi.ok({ cart: resultCart2, item: addedItem2 });
805
823
  }
806
- let resolvedCartId = opts.cartId || cartId;
824
+ let resolvedCartId = opts.cartId || cartIdRef.current || cartId;
807
825
  if (!resolvedCartId) {
808
826
  if (opts.createCart) {
809
827
  const c = await resolveCart();
@@ -815,11 +833,10 @@ function useCart(options) {
815
833
  id: resolvedCartId,
816
834
  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 } },
817
835
  language,
818
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
819
- imageVariantFilters: configuration?.imageVariantFiltersSmall
836
+ imageSearchFilters: imageSearchFilters(),
837
+ imageVariantFilters: imageVariantFilters()
820
838
  });
821
- setCart(resultCart);
822
- setCreatedCartId(resultCart.cartId);
839
+ rememberCart(resultCart);
823
840
  const addedItem = resultCart.items?.find((i) => i.productId === opts.product.productId) ?? null;
824
841
  opts.afterAddToCart?.(resultCart, addedItem);
825
842
  return propellerV2CoreUi.ok({ cart: resultCart, item: addedItem });
@@ -830,13 +847,25 @@ function useCart(options) {
830
847
  } finally {
831
848
  setLoading(false);
832
849
  }
833
- }, [graphqlClient, cartId, language, configuration, resolveCart]);
850
+ }, [graphqlClient, cartId, language, configuration, resolveCart, rememberCart, imageSearchFilters, imageVariantFilters]);
851
+ const addItems = React6.useCallback(async (items) => {
852
+ const added = [];
853
+ let lastCart = null;
854
+ for (const item of items) {
855
+ const result = await addItem({ createCart: true, ...item });
856
+ if (!result.ok) return propellerV2CoreUi.err(result.error);
857
+ lastCart = result.data.cart;
858
+ added.push(result.data.item);
859
+ }
860
+ if (!lastCart) return propellerV2CoreUi.err("No items to add");
861
+ return propellerV2CoreUi.ok({ cart: lastCart, items: added });
862
+ }, [addItem]);
834
863
  const updateItemQuantity = React6.useCallback(async (cartItemId, quantity) => {
835
864
  if (!cartId) return void 0;
836
865
  setLoading(true);
837
866
  try {
838
867
  const service = propellerV2CoreUi.createServices(graphqlClient).cart;
839
- const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { quantity }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
868
+ const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { quantity }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
840
869
  setCart(updated);
841
870
  return updated;
842
871
  } catch (e) {
@@ -852,7 +881,7 @@ function useCart(options) {
852
881
  if (!cartId) return;
853
882
  try {
854
883
  const service = propellerV2CoreUi.createServices(graphqlClient).cart;
855
- const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { notes }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
884
+ const updated = await service.updateCartItem({ id: cartId, itemId: cartItemId, input: { notes }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
856
885
  setCart(updated);
857
886
  } catch (e) {
858
887
  setError(e instanceof Error ? e.message : "Failed to update notes");
@@ -868,8 +897,8 @@ function useCart(options) {
868
897
  id: cartId,
869
898
  input: { itemId: cartItemId },
870
899
  language,
871
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
872
- imageVariantFilters: configuration?.imageVariantFiltersSmall
900
+ imageSearchFilters: imageSearchFilters(),
901
+ imageVariantFilters: imageVariantFilters()
873
902
  });
874
903
  setCart(updated);
875
904
  return updated;
@@ -883,7 +912,7 @@ function useCart(options) {
883
912
  if (!cartId) return void 0;
884
913
  try {
885
914
  const service = propellerV2CoreUi.createServices(graphqlClient).cart;
886
- const updated = await service.addActionCodeToCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
915
+ const updated = await service.addActionCodeToCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
887
916
  setCart(updated);
888
917
  return updated;
889
918
  } catch (e) {
@@ -894,7 +923,7 @@ function useCart(options) {
894
923
  if (!cartId) return void 0;
895
924
  try {
896
925
  const service = propellerV2CoreUi.createServices(graphqlClient).cart;
897
- const updated = await service.removeActionCodeFromCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: configuration?.imageSearchFiltersGrid, imageVariantFilters: configuration?.imageVariantFiltersSmall });
926
+ const updated = await service.removeActionCodeFromCart({ id: cartId, input: { actionCode: code }, language, imageSearchFilters: imageSearchFilters(), imageVariantFilters: imageVariantFilters() });
898
927
  setCart(updated);
899
928
  return updated;
900
929
  } catch (e) {
@@ -922,7 +951,7 @@ function useCart(options) {
922
951
  }
923
952
  }, [graphqlClient, cartId, language]);
924
953
  const getCrossupsells = React6.useCallback(async (opts) => {
925
- const { productId, clusterId, types, taxZone, imageVariantFilters } = opts;
954
+ const { productId, clusterId, types, taxZone } = opts;
926
955
  if (!productId && !clusterId) return [];
927
956
  try {
928
957
  const service = propellerV2CoreUi.createServices(graphqlClient).crossupsell;
@@ -935,8 +964,8 @@ function useCart(options) {
935
964
  ...clusterId && { clusterIdsFrom: [clusterId] }
936
965
  },
937
966
  language,
938
- imageSearchFilters: configuration?.imageSearchFiltersGrid,
939
- imageVariantFilters: imageVariantFilters ?? configuration?.imageVariantFiltersSmall,
967
+ imageSearchFilters: imageSearchFilters(),
968
+ imageVariantFilters: opts.imageVariantFilters ?? imageVariantFilters(),
940
969
  priceCalculateProductInput: {
941
970
  taxZone: taxZone || "NL",
942
971
  ...user && "company" in user && { companyId: user?.company?.companyId },
@@ -949,8 +978,8 @@ function useCart(options) {
949
978
  } catch {
950
979
  return [];
951
980
  }
952
- }, [graphqlClient, language, configuration, user]);
953
- return { cart, cartId, loading, error, checkoutAllowed, resolveCart, addItem, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };
981
+ }, [graphqlClient, language, user, imageSearchFilters, imageVariantFilters]);
982
+ return { cart, cartId, loading, error, checkoutAllowed, resolveCart, addItem, addItems, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };
954
983
  }
955
984
  function buildAddressInput(type, addr) {
956
985
  return {
@@ -4443,6 +4472,64 @@ function ActionCode(rawProps) {
4443
4472
  ] });
4444
4473
  }
4445
4474
  var ActionCode_default = ActionCode;
4475
+ function CartBonusItems(rawProps) {
4476
+ const props = useInfraProps(rawProps);
4477
+ const items = props.bonusItems ?? props.cart?.bonusItems ?? [];
4478
+ if (items.length === 0) return null;
4479
+ const currency = props.currency ?? "\u20AC";
4480
+ const money = (value) => propellerV2CoreUi.formatPrice(value, { symbol: currency, locale: propellerV2CoreUi.localeForLanguage(props.language) });
4481
+ const productName = (item) => propellerV2CoreUi.getLocalizedValue(item.product?.names, props.language, "Product");
4482
+ const productImage = (item) => item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
4483
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(`propeller-cart-bonus-items ${props.className || "mt-2"}`), children: [
4484
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "propeller-cart-bonus-items__title text-lg font-semibold mb-3", children: propellerV2CoreUi.getLabel(props.labels, "title", "Bonus items") }),
4485
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-bonus-items__list space-y-4", children: items.map((item) => {
4486
+ const img = productImage(item);
4487
+ const name = productName(item);
4488
+ const total = props.includeTax ? item.totalPriceNet : item.totalPrice;
4489
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4490
+ "div",
4491
+ {
4492
+ className: "propeller-cart-bonus-item flex items-center gap-4 bg-card p-4 rounded-container shadow-sm border border-border",
4493
+ children: [
4494
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("img", { className: "propeller-cart-bonus-item__image w-full h-full object-contain p-1", src: img, alt: name }) : /* @__PURE__ */ jsxRuntime.jsx(
4495
+ "svg",
4496
+ {
4497
+ fill: "none",
4498
+ viewBox: "0 0 24 24",
4499
+ stroke: "currentColor",
4500
+ className: "propeller-cart-bonus-item__image-placeholder w-8 h-8 text-foreground-subtle",
4501
+ strokeWidth: 1.5,
4502
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4503
+ "path",
4504
+ {
4505
+ strokeLinecap: "round",
4506
+ strokeLinejoin: "round",
4507
+ 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"
4508
+ }
4509
+ )
4510
+ }
4511
+ ) }),
4512
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-bonus-item__body flex-1 min-w-0", children: [
4513
+ item.product?.sku ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "propeller-cart-bonus-item__sku font-mono text-xs text-foreground-subtle", children: [
4514
+ propellerV2CoreUi.getLabel(props.labels, "sku", "SKU"),
4515
+ ": ",
4516
+ item.product.sku
4517
+ ] }) : null,
4518
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-cart-bonus-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2", children: name })
4519
+ ] }),
4520
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-bonus-item__qty text-sm text-muted-foreground whitespace-nowrap", children: [
4521
+ item.quantity,
4522
+ " \xD7"
4523
+ ] }),
4524
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-bonus-item__price font-semibold text-foreground whitespace-nowrap", children: money(total) })
4525
+ ]
4526
+ },
4527
+ item.itemId
4528
+ );
4529
+ }) })
4530
+ ] });
4531
+ }
4532
+ var CartBonusItems_default = CartBonusItems;
4446
4533
  function mergeGrouped(p) {
4447
4534
  const d = p.display;
4448
4535
  const e = p.events;
@@ -4476,6 +4563,7 @@ function AddToCart(rawProps) {
4476
4563
  const [modalVisible, setModalVisible] = React6.useState(() => false);
4477
4564
  const [addedCartItem, setAddedCartItem] = React6.useState(() => null);
4478
4565
  const [activeFullCart, setActiveFullCart] = React6.useState(() => null);
4566
+ const [grantedBonusItems, setGrantedBonusItems] = React6.useState(() => []);
4479
4567
  const [includeTax] = React6.useState(() => false);
4480
4568
  function getProductUrl2() {
4481
4569
  return props.configuration?.urls?.getProductUrl(props.product, props.language) ?? "#";
@@ -4518,9 +4606,9 @@ function AddToCart(rawProps) {
4518
4606
  if (addedCartItem) {
4519
4607
  const useTax = props.includeTax !== void 0 ? !!props.includeTax : includeTax;
4520
4608
  const price = useTax ? addedCartItem.totalSumNet : addedCartItem.totalSum;
4521
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
4609
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
4522
4610
  }
4523
- return propellerV2CoreUi.formatPrice(props.price !== void 0 ? props.price : props.product?.price?.gross, { symbol: props.currency ?? "\u20AC" });
4611
+ return propellerV2CoreUi.formatPrice(props.price !== void 0 ? props.price : props.product?.price?.gross, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
4524
4612
  }
4525
4613
  function getModalSku() {
4526
4614
  if (addedCartItem) return addedCartItem.product?.sku || "";
@@ -4554,10 +4642,20 @@ function AddToCart(rawProps) {
4554
4642
  function closeModal() {
4555
4643
  setModalVisible(false);
4556
4644
  setAddedCartItem(null);
4645
+ setGrantedBonusItems([]);
4646
+ }
4647
+ function newBonusItems(before, after) {
4648
+ const granted = after?.bonusItems ?? [];
4649
+ if (granted.length === 0) return [];
4650
+ const previous = before?.bonusItems;
4651
+ if (!previous) return granted;
4652
+ const seen = new Map(previous.map((item) => [item.itemId, item.quantity ?? 0]));
4653
+ return granted.filter((item) => (item.quantity ?? 0) > (seen.get(item.itemId) ?? 0));
4557
4654
  }
4558
4655
  async function handleAddToCart() {
4559
4656
  if (!props.graphqlClient) return;
4560
4657
  if (props.beforeAddToCart && !props.beforeAddToCart()) return;
4658
+ const cartBeforeAdd = activeFullCart ?? cart ?? null;
4561
4659
  const result = await addItem({
4562
4660
  product: props.product,
4563
4661
  cluster: props.cluster,
@@ -4569,6 +4667,7 @@ function AddToCart(rawProps) {
4569
4667
  afterAddToCart: (resultCart, addedItem) => {
4570
4668
  setActiveFullCart(resultCart);
4571
4669
  setAddedCartItem(resolveAddedItem(resultCart, addedItem || null));
4670
+ setGrantedBonusItems(newBonusItems(cartBeforeAdd, resultCart));
4572
4671
  props.afterAddToCart?.(resultCart, addedItem || void 0);
4573
4672
  },
4574
4673
  enableStockValidation: props.enableStockValidation,
@@ -4865,12 +4964,22 @@ function AddToCart(rawProps) {
4865
4964
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: propellerV2CoreUi.getLocalizedValue(child.product?.names, props.language, "Option") }),
4866
4965
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-subtle whitespace-nowrap ml-2", children: propellerV2CoreUi.formatPrice(
4867
4966
  ((props.includeTax !== void 0 ? !!props.includeTax : includeTax) ? child.totalSumNet : child.totalSum) ?? 0,
4868
- { symbol: props.currency ?? "\u20AC" }
4967
+ { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) }
4869
4968
  ) })
4870
4969
  ]
4871
4970
  },
4872
4971
  idx
4873
- )) }) : null
4972
+ )) }) : null,
4973
+ grantedBonusItems.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-add-to-cart__modal-bonus-items mt-4 pt-4 border-t border-border-subtle", children: /* @__PURE__ */ jsxRuntime.jsx(
4974
+ CartBonusItems_default,
4975
+ {
4976
+ bonusItems: grantedBonusItems,
4977
+ includeTax: props.includeTax,
4978
+ currency: props.currency,
4979
+ language: props.language,
4980
+ labels: props.bonusItemsLabels
4981
+ }
4982
+ ) }) : null
4874
4983
  ] }),
4875
4984
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-add-to-cart__modal-actions flex gap-3 px-6 py-4 border-t border-border-subtle", children: [
4876
4985
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6396,64 +6505,6 @@ function BreadcrumbsWithProvider(rawProps) {
6396
6505
  return /* @__PURE__ */ jsxRuntime.jsx(Breadcrumbs_default, { ...props });
6397
6506
  }
6398
6507
  var BreadcrumbsWithProvider_default = BreadcrumbsWithProvider;
6399
- function CartBonusItems(rawProps) {
6400
- const props = useInfraProps(rawProps);
6401
- const items = props.bonusItems ?? props.cart?.bonusItems ?? [];
6402
- if (items.length === 0) return null;
6403
- const currency = props.currency ?? "\u20AC";
6404
- const money = (value) => propellerV2CoreUi.formatPrice(value, { symbol: currency });
6405
- const productName = (item) => propellerV2CoreUi.getLocalizedValue(item.product?.names, props.language, "Product");
6406
- const productImage = (item) => item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
6407
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(`propeller-cart-bonus-items ${props.className || "mt-2"}`), children: [
6408
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "propeller-cart-bonus-items__title text-lg font-semibold mb-3", children: propellerV2CoreUi.getLabel(props.labels, "title", "Bonus items") }),
6409
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-bonus-items__list space-y-4", children: items.map((item) => {
6410
- const img = productImage(item);
6411
- const name = productName(item);
6412
- const total = props.includeTax ? item.totalPriceNet : item.totalPrice;
6413
- return /* @__PURE__ */ jsxRuntime.jsxs(
6414
- "div",
6415
- {
6416
- className: "propeller-cart-bonus-item flex items-center gap-4 bg-card p-4 rounded-container shadow-sm border border-border",
6417
- children: [
6418
- /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("img", { className: "propeller-cart-bonus-item__image w-full h-full object-contain p-1", src: img, alt: name }) : /* @__PURE__ */ jsxRuntime.jsx(
6419
- "svg",
6420
- {
6421
- fill: "none",
6422
- viewBox: "0 0 24 24",
6423
- stroke: "currentColor",
6424
- className: "propeller-cart-bonus-item__image-placeholder w-8 h-8 text-foreground-subtle",
6425
- strokeWidth: 1.5,
6426
- children: /* @__PURE__ */ jsxRuntime.jsx(
6427
- "path",
6428
- {
6429
- strokeLinecap: "round",
6430
- strokeLinejoin: "round",
6431
- 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"
6432
- }
6433
- )
6434
- }
6435
- ) }),
6436
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-bonus-item__body flex-1 min-w-0", children: [
6437
- item.product?.sku ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "propeller-cart-bonus-item__sku font-mono text-xs text-foreground-subtle", children: [
6438
- propellerV2CoreUi.getLabel(props.labels, "sku", "SKU"),
6439
- ": ",
6440
- item.product.sku
6441
- ] }) : null,
6442
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-cart-bonus-item__title font-semibold text-sm md:text-base text-foreground line-clamp-2", children: name })
6443
- ] }),
6444
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-bonus-item__qty text-sm text-muted-foreground whitespace-nowrap", children: [
6445
- item.quantity,
6446
- " \xD7"
6447
- ] }),
6448
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-bonus-item__price font-semibold text-foreground whitespace-nowrap", children: money(total) })
6449
- ]
6450
- },
6451
- item.itemId
6452
- );
6453
- }) })
6454
- ] });
6455
- }
6456
- var CartBonusItems_default = CartBonusItems;
6457
6508
 
6458
6509
  // src/composables/shared/utils/preselect.ts
6459
6510
  function pickPreselected(items, stored, keyOf) {
@@ -6467,7 +6518,7 @@ function CartCarriers(props) {
6467
6518
  const carriers = props.cart?.carriers || [];
6468
6519
  function formatCarrierPrice(price) {
6469
6520
  if (props.formatPrice) return props.formatPrice(price);
6470
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
6521
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
6471
6522
  }
6472
6523
  function handleSelect(carrier) {
6473
6524
  setSelectedName(carrier.name);
@@ -6664,7 +6715,7 @@ function CartItem(rawProps) {
6664
6715
  function getFormattedPrice() {
6665
6716
  const item = props.cartItem;
6666
6717
  const price = props.includeTax ? item?.totalSumNet || 0 : item?.totalSum || 0;
6667
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6718
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
6668
6719
  }
6669
6720
  function isBundleItem() {
6670
6721
  return !!props.cartItem.bundle;
@@ -6675,7 +6726,7 @@ function CartItem(rawProps) {
6675
6726
  function getBundlePrice2() {
6676
6727
  const price = props.cartItem.bundle?.price?.net;
6677
6728
  if (price === void 0 || price === null) return "";
6678
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6729
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
6679
6730
  }
6680
6731
  function getBundleLeaderName() {
6681
6732
  const items = props.cartItem.bundle?.items;
@@ -6691,7 +6742,7 @@ function CartItem(rawProps) {
6691
6742
  if (!leader) return "";
6692
6743
  const price = leader.price?.net;
6693
6744
  if (price === void 0 || price === null) return "";
6694
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6745
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
6695
6746
  }
6696
6747
  function getBundleNonLeaders2() {
6697
6748
  const items = props.cartItem.bundle?.items;
@@ -6704,7 +6755,7 @@ function CartItem(rawProps) {
6704
6755
  function getBundleItemPrice(bundleItem) {
6705
6756
  const price = bundleItem.price?.net;
6706
6757
  if (price === void 0 || price === null) return "";
6707
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
6758
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
6708
6759
  }
6709
6760
  function getCrossupsellName(item) {
6710
6761
  const product = item?.productTo || item?.clusterTo;
@@ -6797,7 +6848,7 @@ function CartItem(rawProps) {
6797
6848
  if (!price) return "";
6798
6849
  const value = props.includeTax ? price.net : price.gross;
6799
6850
  if (value === void 0 || value === null) return "";
6800
- return propellerV2CoreUi.formatPrice(value, { symbol: props.currency ?? "\u20AC" });
6851
+ return propellerV2CoreUi.formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
6801
6852
  }
6802
6853
  async function handleAddCrossupsellToCart(item) {
6803
6854
  if (!props.cartId || addingCrossupsellId) return;
@@ -7037,7 +7088,7 @@ function CartItemChildItems(props = {}) {
7037
7088
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-subtle hidden sm:inline", children: "-" }),
7038
7089
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-subtle text-xs self-center", children: child.product.sku }),
7039
7090
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 border-b border-dotted border-border mx-1 mb-1" }),
7040
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: propellerV2CoreUi.formatPrice(child.totalSum, { symbol: resolved.currency ?? "\u20AC" }) })
7091
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: propellerV2CoreUi.formatPrice(child.totalSum, { symbol: resolved.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(resolved.language) }) })
7041
7092
  ] }, idx))
7042
7093
  ] });
7043
7094
  }
@@ -7278,7 +7329,7 @@ function CartIconAndSidebar(rawProps) {
7278
7329
  const CartBonusItemsImpl = props.cartBonusItemsComponent ?? CartBonusItems_default;
7279
7330
  const CartItemImpl = props.cartItemComponent ?? CartItem_default;
7280
7331
  const currencySymbol = props.currency ?? "\u20AC";
7281
- const money = (value) => value === void 0 || value === null ? "" : propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol });
7332
+ const money = (value) => value === void 0 || value === null ? "" : propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol, locale: propellerV2CoreUi.localeForLanguage(props.language) });
7282
7333
  const { requestAuthorization } = useCart({
7283
7334
  graphqlClient: props.graphqlClient,
7284
7335
  user: props.user ?? null,
@@ -7299,6 +7350,9 @@ function CartIconAndSidebar(rawProps) {
7299
7350
  const useTax = !!props.includeTax;
7300
7351
  const totalRaw = useTax ? props.cart?.total?.totalNet : props.cart?.total?.totalGross;
7301
7352
  const totalPrice = totalRaw === void 0 || totalRaw === null ? money(0) : money(totalRaw);
7353
+ function totalLabel(key) {
7354
+ return useTax ? propellerV2CoreUi.getLabel(props.labels, key, "Total") : propellerV2CoreUi.getLabel(props.labels, "totalExclVat", "Total excl. VAT");
7355
+ }
7302
7356
  const sidebarTitle = props.cartSidebarTitle || props.labels?.["cartSidebarTitle"] || "Shopping cart";
7303
7357
  const purchaserPAC = findPurchaserPAC(props.user, props.companyId);
7304
7358
  const totalGross = props.cart?.total?.totalGross ?? 0;
@@ -7388,7 +7442,7 @@ function CartIconAndSidebar(rawProps) {
7388
7442
  ),
7389
7443
  props.showTotals && isHovered && totalItems > 0 ? /* @__PURE__ */ jsxRuntime.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: [
7390
7444
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between gap-4", children: [
7391
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__popover-label text-muted-foreground", children: propellerV2CoreUi.getLabel(props.labels, "totalLabel", "Total") }),
7445
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__popover-label text-muted-foreground", children: totalLabel("totalLabel") }),
7392
7446
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__popover-total font-semibold text-foreground", children: totalPrice })
7393
7447
  ] }),
7394
7448
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__popover-count text-xs text-foreground-subtle mt-0.5", children: [
@@ -7543,7 +7597,7 @@ function CartIconAndSidebar(rawProps) {
7543
7597
  " ",
7544
7598
  items.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__sidebar-footer px-5 py-4 border-t border-border space-y-3 bg-surface-hover", children: [
7545
7599
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__total-row flex justify-between items-center", children: [
7546
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__total-label text-sm font-medium text-muted-foreground", children: propellerV2CoreUi.getLabel(props.labels, "total", "Total") }),
7600
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__total-label text-sm font-medium text-muted-foreground", children: totalLabel("total") }),
7547
7601
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-icon__total-value text-base font-bold text-foreground", children: totalPrice })
7548
7602
  ] }),
7549
7603
  showCheckoutButton && !showRequestAuthorizationButton ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -7785,7 +7839,7 @@ function CartPaymethods(rawProps) {
7785
7839
  });
7786
7840
  function formatMethodPrice(price) {
7787
7841
  if (props.formatPrice) return props.formatPrice(price);
7788
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
7842
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
7789
7843
  }
7790
7844
  function methodName(method) {
7791
7845
  const code = (method.code || "").toLowerCase();
@@ -7871,7 +7925,7 @@ function CartSummary(rawProps) {
7871
7925
  if (props.formatPrice) {
7872
7926
  return props.formatPrice(price);
7873
7927
  }
7874
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
7928
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
7875
7929
  }
7876
7930
  function subtotal() {
7877
7931
  return props.cart?.total?.subTotal || 0;
@@ -7950,83 +8004,96 @@ function CartSummary(rawProps) {
7950
8004
  setRequestLoading(false);
7951
8005
  }
7952
8006
  }
7953
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary w-full bg-card space-y-3", children: [
7954
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "propeller-cart-summary__title text-xl font-bold mb-4", children: title() }),
7955
- showSubtotal() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "subtotal", children: [
7956
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "subtotal", "Subtotal:") }),
7957
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(subtotal()) })
7958
- ] }) : null,
7959
- showDiscount() && hasDiscount() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-success", "data-row": "discount", children: [
7960
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "discount", "Discount:") }),
7961
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "propeller-cart-summary__value", children: [
7962
- "-",
7963
- formatItemPrice(discountAmount())
7964
- ] })
7965
- ] }) : null,
7966
- hasTransactionCosts() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "transaction-costs", children: [
7967
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "transactionCosts", "Transaction costs:") }),
7968
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(transactionCosts()) })
7969
- ] }) : null,
7970
- showShippingCosts() && hasShippingCosts() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "shipping-costs", children: [
7971
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "shippingCosts", "Shipping costs:") }),
7972
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(shippingCosts()) })
7973
- ] }) : null,
7974
- showTotalExclVat() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground pt-2 border-t", "data-row": "total-excl-vat", children: [
7975
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "totalExclVat", "Total excl. VAT:") }),
7976
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalExclVat()) })
7977
- ] }) : null,
7978
- showVATs() && taxLevels().length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: taxLevels()?.map((tax, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "vat-line", children: [
7979
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "propeller-cart-summary__label", children: [
7980
- tax.taxPercentage,
7981
- "% ",
7982
- propellerV2CoreUi.getLabel(props.labels, "vat", "VAT"),
7983
- ":"
7984
- ] }),
7985
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(Number(tax.price)) })
7986
- ] }, index)) }) : null,
7987
- showTotalVat() && totalVat() > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "total-vat", children: [
7988
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "totalVat", "Total VAT:") }),
7989
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalVat()) })
7990
- ] }) : null,
7991
- /* @__PURE__ */ jsxRuntime.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: [
7992
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "total", "Total:") }),
7993
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalInclVat()) })
7994
- ] }),
7995
- showCheckoutButton() && !showRequestAuthorizationButton() ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7996
- /* @__PURE__ */ jsxRuntime.jsx(
7997
- "button",
7998
- {
7999
- type: "button",
8000
- 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",
8001
- onClick: (event) => handleCheckoutClick(),
8002
- children: propellerV2CoreUi.getLabel(props.labels, "checkoutButton", "Continue to Checkout")
8003
- }
8007
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8008
+ "div",
8009
+ {
8010
+ className: cn(
8011
+ // Padding, radius and shadow to match ActionCode, which sits directly
8012
+ // under this panel on the cart page. Without them the summary painted
8013
+ // a card background with its text against the edges and a full-bleed
8014
+ // checkout button — the same column, two different card treatments.
8015
+ "propeller-cart-summary w-full bg-card p-6 rounded-container shadow space-y-3",
8016
+ props.className
8004
8017
  ),
8005
- " ",
8006
- !!props.onRequestQuoteClick && showRequestQuoteButton() ? /* @__PURE__ */ jsxRuntime.jsx(
8007
- "button",
8008
- {
8009
- type: "button",
8010
- 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",
8011
- onClick: (event) => props.onRequestQuoteClick && props.onRequestQuoteClick(props.cart),
8012
- children: propellerV2CoreUi.getLabel(props.labels, "requestQuoteButton", "Request a Quote")
8013
- }
8014
- ) : null
8015
- ] }) : null,
8016
- showRequestAuthorizationButton() ? /* @__PURE__ */ jsxRuntime.jsxs(
8017
- "button",
8018
- {
8019
- type: "button",
8020
- 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",
8021
- onClick: (event) => handleRequestAuthorizationClick(),
8022
- disabled: requestLoading,
8023
- children: [
8024
- requestLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: propellerV2CoreUi.getLabel(props.labels, "requestingAuthorization", "Requesting...") }) : null,
8025
- !requestLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: propellerV2CoreUi.getLabel(props.labels, "requestAuthorizationButton", "Request Authorization") }) : null
8026
- ]
8027
- }
8028
- ) : null
8029
- ] });
8018
+ children: [
8019
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "propeller-cart-summary__title text-xl font-bold mb-4", children: title() }),
8020
+ showSubtotal() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "subtotal", children: [
8021
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "subtotal", "Subtotal:") }),
8022
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(subtotal()) })
8023
+ ] }) : null,
8024
+ showDiscount() && hasDiscount() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-success", "data-row": "discount", children: [
8025
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "discount", "Discount:") }),
8026
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "propeller-cart-summary__value", children: [
8027
+ "-",
8028
+ formatItemPrice(discountAmount())
8029
+ ] })
8030
+ ] }) : null,
8031
+ hasTransactionCosts() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "transaction-costs", children: [
8032
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "transactionCosts", "Transaction costs:") }),
8033
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(transactionCosts()) })
8034
+ ] }) : null,
8035
+ showShippingCosts() && hasShippingCosts() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground", "data-row": "shipping-costs", children: [
8036
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "shippingCosts", "Shipping costs:") }),
8037
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(shippingCosts()) })
8038
+ ] }) : null,
8039
+ showTotalExclVat() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground pt-2 border-t", "data-row": "total-excl-vat", children: [
8040
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "totalExclVat", "Total excl. VAT:") }),
8041
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalExclVat()) })
8042
+ ] }) : null,
8043
+ showVATs() && taxLevels().length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: taxLevels()?.map((tax, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "vat-line", children: [
8044
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "propeller-cart-summary__label", children: [
8045
+ tax.taxPercentage,
8046
+ "% ",
8047
+ propellerV2CoreUi.getLabel(props.labels, "vat", "VAT"),
8048
+ ":"
8049
+ ] }),
8050
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(Number(tax.price)) })
8051
+ ] }, index)) }) : null,
8052
+ showTotalVat() && totalVat() > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-summary__row flex justify-between text-muted-foreground text-sm", "data-row": "total-vat", children: [
8053
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "totalVat", "Total VAT:") }),
8054
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalVat()) })
8055
+ ] }) : null,
8056
+ /* @__PURE__ */ jsxRuntime.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: [
8057
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__label", children: propellerV2CoreUi.getLabel(props.labels, "total", "Total:") }),
8058
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-summary__value", children: formatItemPrice(totalInclVat()) })
8059
+ ] }),
8060
+ showCheckoutButton() && !showRequestAuthorizationButton() ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8061
+ /* @__PURE__ */ jsxRuntime.jsx(
8062
+ "button",
8063
+ {
8064
+ type: "button",
8065
+ 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",
8066
+ onClick: (event) => handleCheckoutClick(),
8067
+ children: propellerV2CoreUi.getLabel(props.labels, "checkoutButton", "Continue to Checkout")
8068
+ }
8069
+ ),
8070
+ " ",
8071
+ !!props.onRequestQuoteClick && showRequestQuoteButton() ? /* @__PURE__ */ jsxRuntime.jsx(
8072
+ "button",
8073
+ {
8074
+ type: "button",
8075
+ 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",
8076
+ onClick: (event) => props.onRequestQuoteClick && props.onRequestQuoteClick(props.cart),
8077
+ children: propellerV2CoreUi.getLabel(props.labels, "requestQuoteButton", "Request a Quote")
8078
+ }
8079
+ ) : null
8080
+ ] }) : null,
8081
+ showRequestAuthorizationButton() ? /* @__PURE__ */ jsxRuntime.jsxs(
8082
+ "button",
8083
+ {
8084
+ type: "button",
8085
+ 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",
8086
+ onClick: (event) => handleRequestAuthorizationClick(),
8087
+ disabled: requestLoading,
8088
+ children: [
8089
+ requestLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: propellerV2CoreUi.getLabel(props.labels, "requestingAuthorization", "Requesting...") }) : null,
8090
+ !requestLoading ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: propellerV2CoreUi.getLabel(props.labels, "requestAuthorizationButton", "Request Authorization") }) : null
8091
+ ]
8092
+ }
8093
+ ) : null
8094
+ ]
8095
+ }
8096
+ );
8030
8097
  }
8031
8098
  var CartSummary_default = CartSummary;
8032
8099
  function CategoryDescription(props) {
@@ -8166,7 +8233,7 @@ function ClusterCard(rawProps) {
8166
8233
  const useTax = props.includeTax !== void 0 ? !!props.includeTax : false;
8167
8234
  const priceObj = contentHidden ? void 0 : cluster?.defaultProduct?.price;
8168
8235
  const priceValue = useTax ? priceObj?.net : priceObj?.gross;
8169
- const clusterPrice = props.showPrice === false ? "" : propellerV2CoreUi.formatPrice(priceValue, { symbol: props.currency ?? "\u20AC" });
8236
+ const clusterPrice = props.showPrice === false ? "" : propellerV2CoreUi.formatPrice(priceValue, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
8170
8237
  function handleClusterClick(e) {
8171
8238
  if (props.onClusterClick) {
8172
8239
  e.preventDefault();
@@ -8592,7 +8659,7 @@ function ProductPriceDisplay(props) {
8592
8659
  }
8593
8660
  function formatPrice17(value) {
8594
8661
  if (value === null || value === void 0) return "";
8595
- return propellerV2CoreUi.formatPrice(value, { symbol: props.currency ?? "\u20AC" });
8662
+ return propellerV2CoreUi.formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
8596
8663
  }
8597
8664
  function getOptionsTotal(useNet) {
8598
8665
  const options = props.options || [];
@@ -8681,6 +8748,11 @@ var RESOLVE_SPEC2 = {
8681
8748
  includeTax: { infra: "includeTax" },
8682
8749
  portalMode: { infra: "portalMode" },
8683
8750
  configuration: { infra: "configuration" },
8751
+ // Same entry ClusterCard has always had. Without it a shop priced in
8752
+ // anything but euros had no route to the cards at all: the grid resolved the
8753
+ // currency and then dropped it, and the card fell through to the package
8754
+ // default on every price it rendered.
8755
+ currency: { infra: "currency", default: "\u20AC" },
8684
8756
  columns: { grid: "columns", default: 3 },
8685
8757
  showPrice: { grid: "showPrice" },
8686
8758
  showStock: { grid: "showStock" },
@@ -9015,7 +9087,8 @@ function ProductCardPrice(props) {
9015
9087
  {
9016
9088
  price: product.price,
9017
9089
  includeTax: derived.useTax,
9018
- labels: resolved.priceLabels
9090
+ labels: resolved.priceLabels,
9091
+ currency: resolved.currency
9019
9092
  }
9020
9093
  ) });
9021
9094
  }
@@ -9026,6 +9099,8 @@ function ProductCardPrice(props) {
9026
9099
  includeTax: derived.useTax,
9027
9100
  priceSize: props.priceSize ?? "text-base sm:text-lg",
9028
9101
  labels: resolved.priceLabels,
9102
+ currency: resolved.currency,
9103
+ language: resolved.language,
9029
9104
  portalMode: resolved.portalMode,
9030
9105
  user: resolved.user,
9031
9106
  showLoginPrompt: false
@@ -9431,6 +9506,7 @@ ProductGridCompound.Pagination = ProductGridPagination;
9431
9506
  var ProductGrid_default = ProductGridCompound;
9432
9507
  function GridFilters(rawProps) {
9433
9508
  const props = useInfraProps(rawProps);
9509
+ const currencySymbol = props.currency ?? "\u20AC";
9434
9510
  const [selectedFilters, setSelectedFilters] = React6.useState(
9435
9511
  () => ({ ...props.activeTextFilters || {} })
9436
9512
  );
@@ -9647,7 +9723,7 @@ function GridFilters(rawProps) {
9647
9723
  ] }),
9648
9724
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9649
9725
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
9650
- /* @__PURE__ */ jsxRuntime.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" }),
9726
+ /* @__PURE__ */ jsxRuntime.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 }),
9651
9727
  /* @__PURE__ */ jsxRuntime.jsx(
9652
9728
  "input",
9653
9729
  {
@@ -9666,7 +9742,7 @@ function GridFilters(rawProps) {
9666
9742
  ] }),
9667
9743
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-grid-filters__price-separator text-foreground-subtle text-sm select-none", children: "\u2013" }),
9668
9744
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
9669
- /* @__PURE__ */ jsxRuntime.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" }),
9745
+ /* @__PURE__ */ jsxRuntime.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 }),
9670
9746
  /* @__PURE__ */ jsxRuntime.jsx(
9671
9747
  "input",
9672
9748
  {
@@ -9974,6 +10050,7 @@ var DEFAULT_LABELS = {
9974
10050
  };
9975
10051
  function GridToolbar(rawProps) {
9976
10052
  const props = useInfraProps(rawProps);
10053
+ const currencySymbol = props.currency ?? "\u20AC";
9977
10054
  const [currentSortField, setCurrentSortField] = React6.useState(
9978
10055
  propellerSdkV2.ProductSortField.CATEGORY_ORDER
9979
10056
  );
@@ -10186,9 +10263,11 @@ function GridToolbar(rawProps) {
10186
10263
  },
10187
10264
  children: [
10188
10265
  getLabel59("price"),
10189
- ": \u20AC",
10266
+ ": ",
10267
+ currencySymbol,
10190
10268
  props.priceFilterMin ?? 0,
10191
- " \u2013 \u20AC",
10269
+ " \u2013 ",
10270
+ currencySymbol,
10192
10271
  props.priceFilterMax ?? "\u221E",
10193
10272
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-grid-toolbar__filter-badge-remove", children: "\xD7" })
10194
10273
  ]
@@ -10839,8 +10918,8 @@ function ClusterInfo(rawProps) {
10839
10918
  ] });
10840
10919
  }
10841
10920
  var ClusterInfo_default = ClusterInfo;
10842
- function formatPrice9(price, currency) {
10843
- return propellerV2CoreUi.formatPrice(price, { symbol: currency });
10921
+ function formatPrice9(price, currency, language) {
10922
+ return propellerV2CoreUi.formatPrice(price, { symbol: currency, locale: propellerV2CoreUi.localeForLanguage(language) });
10844
10923
  }
10845
10924
  function getProductName2(product, language) {
10846
10925
  return propellerV2CoreUi.getLocalizedValue(product.names, language, `Product ${product.productId}`);
@@ -10867,7 +10946,7 @@ function ClusterOptions(rawProps) {
10867
10946
  const products = (option.products || []).map((p) => ({
10868
10947
  productId: p.productId,
10869
10948
  productIdStr: p.productId.toString(),
10870
- label: hidePrices ? getProductName2(p, language) : `${getProductName2(p, language)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC")}`
10949
+ label: hidePrices ? getProductName2(p, language) : `${getProductName2(p, language)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC", language)}`
10871
10950
  }));
10872
10951
  let previewImageUrl = "";
10873
10952
  let previewName = "";
@@ -10879,7 +10958,7 @@ function ClusterOptions(rawProps) {
10879
10958
  if (selectedProduct) {
10880
10959
  previewImageUrl = getProductImageUrl4(selectedProduct);
10881
10960
  previewName = getProductName2(selectedProduct, language);
10882
- previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
10961
+ previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC", props.language);
10883
10962
  }
10884
10963
  }
10885
10964
  const isRequired = option.isRequired === propellerSdkV2.YesNo.Y;
@@ -11368,7 +11447,7 @@ function FavoriteListItem(rawProps) {
11368
11447
  if (!priceObj) return "";
11369
11448
  const value = useTax ? priceObj.net : priceObj.gross;
11370
11449
  if (!value && value !== 0) return "";
11371
- return propellerV2CoreUi.formatPrice(value, { symbol: currency });
11450
+ return propellerV2CoreUi.formatPrice(value, { symbol: currency, locale: propellerV2CoreUi.localeForLanguage(props.language) });
11372
11451
  })();
11373
11452
  function handleItemClick(e) {
11374
11453
  if (props.onItemClick) {
@@ -12943,12 +13022,12 @@ function ItemsOverview(rawProps) {
12943
13022
  const showPrice = props.showPrice !== void 0 ? props.showPrice : true;
12944
13023
  const items = props.cart?.items ?? [];
12945
13024
  const currencySymbol = props.currency ?? "\u20AC";
12946
- const money = (value) => value === void 0 || value === null ? "" : propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol });
13025
+ const money = (value) => value === void 0 || value === null ? "" : propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol, locale: propellerV2CoreUi.localeForLanguage(props.language) });
12947
13026
  function formatItemPrice(price) {
12948
13027
  if (props.formatPrice) {
12949
13028
  return props.formatPrice(price);
12950
13029
  }
12951
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: currencySymbol });
13030
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: currencySymbol, locale: propellerV2CoreUi.localeForLanguage(props.language) });
12952
13031
  }
12953
13032
  function lineTotal(item) {
12954
13033
  return (useTax ? item.totalSumNet : item.totalSum) || 0;
@@ -13551,20 +13630,21 @@ var OrderActions_default = OrderActions;
13551
13630
  function getProductName3(orderItem, language) {
13552
13631
  return propellerV2CoreUi.getLocalizedValue(orderItem?.product?.names, language, "") || orderItem?.name || "Unknown Product";
13553
13632
  }
13554
- function getClusterUrl(orderItem, language) {
13633
+ function getClusterUrl(orderItem, language, urls) {
13555
13634
  const cluster = orderItem?.product?.cluster;
13556
13635
  if (!cluster) return "";
13557
13636
  const id = cluster.clusterId;
13558
13637
  const slug = propellerV2CoreUi.getLocalizedValue(cluster.slugs, language, "");
13559
13638
  if (!id || !slug) return "";
13560
- return `/cluster/${id}/${slug}`;
13639
+ return urls?.getClusterUrl?.(cluster, language) || `/cluster/${id}/${slug}`;
13561
13640
  }
13562
- function getProductUrl(orderItem, language) {
13563
- const cu = getClusterUrl(orderItem, language);
13641
+ function getProductUrl(orderItem, language, urls) {
13642
+ const cu = getClusterUrl(orderItem, language, urls);
13564
13643
  if (cu) return cu;
13565
- const id = orderItem?.product?.productId;
13566
- const slug = propellerV2CoreUi.getLocalizedValue(orderItem?.product?.slugs, language, "");
13567
- if (id && slug) return `/product/${id}/${slug}`;
13644
+ const product = orderItem?.product;
13645
+ const id = product?.productId;
13646
+ const slug = propellerV2CoreUi.getLocalizedValue(product?.slugs, language, "");
13647
+ if (id && slug) return urls?.getProductUrl?.(product, language) || `/product/${id}/${slug}`;
13568
13648
  return "";
13569
13649
  }
13570
13650
  function OrderItemCard(props) {
@@ -13581,7 +13661,7 @@ function OrderItemCard(props) {
13581
13661
  const productName = getProductName3(item, props.language);
13582
13662
  const productSku = item?.product?.sku || item?.sku || "";
13583
13663
  const productImage = item?.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
13584
- const productUrl = getProductUrl(item, props.language);
13664
+ const productUrl = getProductUrl(item, props.language, props.configuration?.urls);
13585
13665
  const quantity = item?.quantity || 0;
13586
13666
  const priceTotal = item?.priceTotal || 0;
13587
13667
  const discount = item?.discount || 0;
@@ -13594,7 +13674,7 @@ function OrderItemCard(props) {
13594
13674
  return props.formatPrice(price);
13595
13675
  }
13596
13676
  if (!price && price !== 0) return "-";
13597
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
13677
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
13598
13678
  }
13599
13679
  const discountDisplay = discountPercentage > 0 ? `${formatItemPrice(discount)} (${discountPercentage.toFixed(2).replace(".", ",")}%)` : formatItemPrice(discount);
13600
13680
  return /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "propeller-order-item-card", children: [
@@ -13673,11 +13753,11 @@ function OrderItemCard(props) {
13673
13753
  className: isChildItem ? "propeller-order-item-card__cell propeller-order-item-card__cell--price px-6 py-2 text-right whitespace-nowrap text-sm text-muted-foreground" : "propeller-order-item-card__cell propeller-order-item-card__cell--price px-6 py-4 text-right whitespace-nowrap",
13674
13754
  children: (() => {
13675
13755
  const PriceImpl = props.priceComponent;
13676
- if (PriceImpl) {
13756
+ if (PriceImpl && item?.product?.price) {
13677
13757
  return /* @__PURE__ */ jsxRuntime.jsx(
13678
13758
  PriceImpl,
13679
13759
  {
13680
- price: item?.product?.price,
13760
+ price: item.product.price,
13681
13761
  currency: props.currency,
13682
13762
  labels: props.labels
13683
13763
  }
@@ -13759,7 +13839,7 @@ function OrderList(rawProps) {
13759
13839
  function formatPrice17(price) {
13760
13840
  if (props.formatPrice) return props.formatPrice(price);
13761
13841
  if (!price) return "-";
13762
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
13842
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
13763
13843
  }
13764
13844
  function getStatusColor(status) {
13765
13845
  if (props.getStatusColor) return props.getStatusColor(status);
@@ -14188,7 +14268,31 @@ function OrderList(rawProps) {
14188
14268
  ) })
14189
14269
  ] })
14190
14270
  ] }) : null
14191
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `propeller-order-list__empty${props.flat ? "" : " bg-card rounded-container shadow"} p-8 text-center`, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: propellerV2CoreUi.getLabel(props.labels, "noOrders", "No orders found.") }) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-order-list__loading p-8 text-center text-muted-foreground", children: propellerV2CoreUi.getLabel(props.labels, "loading", "Loading orders...") })
14271
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `propeller-order-list__empty${props.flat ? "" : " bg-card rounded-container shadow"} p-8 text-center`, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: propellerV2CoreUi.getLabel(props.labels, "noOrders", "No orders found.") }) }) }) : (
14272
+ // A centred line of text collapsed the list to one row and then
14273
+ // snapped back, which is what made a language switch on the account
14274
+ // pages look broken. Skeleton rows hold the layout instead.
14275
+ /* @__PURE__ */ jsxRuntime.jsx(
14276
+ "div",
14277
+ {
14278
+ className: `propeller-order-list__loading${props.flat ? "" : " bg-card rounded-container shadow"} p-4`,
14279
+ "aria-busy": "true",
14280
+ "aria-label": propellerV2CoreUi.getLabel(props.labels, "loading", "Loading orders..."),
14281
+ children: Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsxs(
14282
+ "div",
14283
+ {
14284
+ className: "propeller-order-list__skeleton-row flex items-center gap-4 py-4 border-b border-border last:border-b-0 animate-pulse",
14285
+ children: [
14286
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-24" }),
14287
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-32" }),
14288
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-order-list__skeleton-line h-4 bg-surface-hover rounded w-20 ml-auto" })
14289
+ ]
14290
+ },
14291
+ index
14292
+ ))
14293
+ }
14294
+ )
14295
+ )
14192
14296
  ] });
14193
14297
  }
14194
14298
  var OrderList_default = OrderList;
@@ -14229,7 +14333,7 @@ function QuickOrderInner(props) {
14229
14333
  } = props;
14230
14334
  const user = props.user ?? null;
14231
14335
  const graphqlClient = props.graphqlClient;
14232
- const displayPrice = (n) => props.formatPrice ? props.formatPrice(n) : propellerV2CoreUi.formatPrice(n, { symbol: currency });
14336
+ const displayPrice = (n) => props.formatPrice ? props.formatPrice(n) : propellerV2CoreUi.formatPrice(n, { symbol: currency, locale: propellerV2CoreUi.localeForLanguage(props.language) });
14233
14337
  const L = (key, fallback) => propellerV2CoreUi.getLabel(labels, key, fallback);
14234
14338
  const { submitting, searchProducts, submit } = useQuickOrder({
14235
14339
  graphqlClient,
@@ -14662,7 +14766,7 @@ function OrderShipments(props) {
14662
14766
  /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-4 py-2 text-muted-foreground", children: [
14663
14767
  !!shipmentItem.sku ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: shipmentItem.sku }) : null,
14664
14768
  !shipmentItem.sku ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14665
- !!getOrderItemForShipmentItem(shipmentItem) ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: getOrderItemForShipmentItem(shipmentItem)?.product?.sku || "-" }) : null,
14769
+ !!getOrderItemForShipmentItem(shipmentItem) ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: getOrderItemForShipmentItem(shipmentItem)?.product?.sku || getOrderItemForShipmentItem(shipmentItem)?.sku || "-" }) : null,
14666
14770
  !getOrderItemForShipmentItem(shipmentItem) ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "-" }) : null
14667
14771
  ] }) : null
14668
14772
  ] }),
@@ -14763,7 +14867,7 @@ function OrderSummary(props) {
14763
14867
  if (props.formatPrice) {
14764
14868
  return props.formatPrice(price);
14765
14869
  }
14766
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
14870
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
14767
14871
  }
14768
14872
  function numericDate(dateString) {
14769
14873
  const d = new Date(dateString);
@@ -14871,7 +14975,7 @@ function OrderTotals(props) {
14871
14975
  const postageData = props.order?.postageData;
14872
14976
  function formatItemPrice(price) {
14873
14977
  if (props.formatPrice) return props.formatPrice(price);
14874
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
14978
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
14875
14979
  }
14876
14980
  const subtotal = total?.gross || 0;
14877
14981
  const hasDiscount = !!total && total.discountType !== propellerSdkV2.OrderDiscountType.N && total.discountValue > 0;
@@ -15036,7 +15140,7 @@ function ProductBulkPrices(props) {
15036
15140
  function getPrice(tier) {
15037
15141
  const value = includeTax ? tier.net : tier.gross;
15038
15142
  if (value === null || value === void 0) return "";
15039
- return propellerV2CoreUi.formatPrice(value, { symbol: props.currency ?? "\u20AC" });
15143
+ return propellerV2CoreUi.formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
15040
15144
  }
15041
15145
  function getQuantityLabel(tier, index) {
15042
15146
  const discount = tier.discount;
@@ -15047,13 +15151,14 @@ function ProductBulkPrices(props) {
15047
15151
  if (nextQty) return `${qty}\u2013${nextQty - 1}`;
15048
15152
  return `${qty}+`;
15049
15153
  }
15154
+ const title = props.labels?.title ?? "Volume pricing";
15050
15155
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: !isHidden2 && hasItems ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
15051
15156
  "div",
15052
15157
  {
15053
15158
  className: cn(`propeller-product-bulk-prices ${props.className || ""}`),
15054
15159
  "data-include-tax": includeTax ? "true" : "false",
15055
15160
  children: [
15056
- propellerV2CoreUi.getLabel(props.labels, "title", "Volume pricing") ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "propeller-product-bulk-prices__title text-base font-semibold text-foreground mb-3", children: propellerV2CoreUi.getLabel(props.labels, "title", "Volume pricing") }) : null,
15161
+ title ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "propeller-product-bulk-prices__title text-base font-semibold text-foreground mb-3", children: title }) : null,
15057
15162
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bulk-prices__table-wrapper overflow-hidden rounded-container border border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "propeller-product-bulk-prices__table w-full text-sm", children: [
15058
15163
  /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "propeller-product-bulk-prices__thead bg-muted/50", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
15059
15164
  /* @__PURE__ */ jsxRuntime.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: propellerV2CoreUi.getLabel(props.labels, "quantityFrom", "Qty from") }),
@@ -15100,7 +15205,7 @@ function ProductBundles(rawProps) {
15100
15205
  const props = useInfraProps(rawProps);
15101
15206
  const language = props.language;
15102
15207
  const currencySymbol = props.currency ?? "\u20AC";
15103
- const money = (value) => propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol });
15208
+ const money = (value) => propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol, locale: propellerV2CoreUi.localeForLanguage(props.language) });
15104
15209
  const [isMounted, setIsMounted] = React6.useState(false);
15105
15210
  const [addingBundleId, setAddingBundleId] = React6.useState(null);
15106
15211
  const [lastAddedBundle, setLastAddedBundle] = React6.useState(null);
@@ -15291,7 +15396,7 @@ function ProductBundles(rawProps) {
15291
15396
  onClick: () => handleAddToCart(bundle),
15292
15397
  disabled: addingBundleId === bundle.id,
15293
15398
  "data-loading": addingBundleId === bundle.id ? "true" : "false",
15294
- children: addingBundleId === bundle.id ? propellerV2CoreUi.getLabel(props.labels, "adding", "Adding...") : propellerV2CoreUi.getLabel(props.labels, "addToCart", "In cart")
15399
+ children: addingBundleId === bundle.id ? propellerV2CoreUi.getLabel(props.labels, "adding", "Adding...") : propellerV2CoreUi.getLabel(props.labels, "addToCart", "Add to cart")
15295
15400
  }
15296
15401
  )
15297
15402
  ] }) : props.showLoginPrompt !== false ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__login-prompt text-center text-sm text-muted-foreground py-2", children: propellerV2CoreUi.getLabel(
@@ -17430,7 +17535,7 @@ function PurchaseAuthorizationRequests(rawProps) {
17430
17535
  }
17431
17536
  function formatPrice17(price) {
17432
17537
  if (props.formatPrice) return props.formatPrice(price);
17433
- return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC" });
17538
+ return propellerV2CoreUi.formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
17434
17539
  }
17435
17540
  const columnLabelKeys = {
17436
17541
  date: ["colDate", "Date"],
@@ -18651,12 +18756,12 @@ function RegisterForm(rawProps) {
18651
18756
  ] });
18652
18757
  }
18653
18758
  var RegisterForm_default = RegisterForm;
18654
- function mapToSearchBarResult(item, language) {
18759
+ function mapToSearchBarResult(item, language, urls) {
18655
18760
  const isCluster = "clusterId" in item;
18656
18761
  const displayItem = isCluster ? item.defaultProduct : item;
18657
18762
  const id = isCluster ? item.clusterId : item.productId;
18658
18763
  const slug = propellerV2CoreUi.getLocalizedValue(item.slugs, language, "");
18659
- const url = isCluster ? "/cluster/" + id + "/" + slug : "/product/" + id + "/" + slug;
18764
+ const url = isCluster ? urls?.getClusterUrl?.(item, language) || "/cluster/" + id + "/" + slug : urls?.getProductUrl?.(item, language) || "/product/" + id + "/" + slug;
18660
18765
  const priceNet = displayItem?.price?.net || 0;
18661
18766
  const priceGross = displayItem?.price?.gross || 0;
18662
18767
  const localizedName = language && item.names?.find((n) => n.language === language)?.value || item.names?.[0]?.value || "Product";
@@ -18696,13 +18801,19 @@ function SearchBar(rawProps) {
18696
18801
  applyOrderlists: props.applyOrderlists,
18697
18802
  productTrackAttributes: props.productTrackAttributes
18698
18803
  });
18699
- const results = searchResults.slice(0, maxResults).map((item) => mapToSearchBarResult(item, props.language));
18804
+ const results = searchResults.slice(0, maxResults).map(
18805
+ (item) => mapToSearchBarResult(
18806
+ item,
18807
+ props.language,
18808
+ props.configuration?.urls
18809
+ )
18810
+ );
18700
18811
  const itemsFound = searchItemsFound;
18701
18812
  function formatItemPrice(price) {
18702
18813
  if (props.formatPrice) {
18703
18814
  return props.formatPrice(price);
18704
18815
  }
18705
- return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
18816
+ return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: propellerV2CoreUi.localeForLanguage(props.language) });
18706
18817
  }
18707
18818
  const useTax = !!props.includeTax;
18708
18819
  function leadingPrice(result) {
@@ -18801,7 +18912,14 @@ function SearchBar(rawProps) {
18801
18912
  {
18802
18913
  type: "search",
18803
18914
  autoComplete: "off",
18804
- 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",
18915
+ className: cn(
18916
+ // Themed surface + border rather than the white-on-white the
18917
+ // boilerplate's dark header band happened to make work: on a
18918
+ // light header `bg-white/95 border-white/20` rendered as an
18919
+ // invisible input.
18920
+ "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",
18921
+ props.inputClassName
18922
+ ),
18805
18923
  placeholder: props.placeholder || "Search products...",
18806
18924
  value: localTerm,
18807
18925
  onChange: (e) => handleInputChange(e.target.value)