@propeller-commerce/propeller-v2-react-ui 0.4.24 → 0.4.26

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.d.cts CHANGED
@@ -1103,6 +1103,12 @@ interface UseOrdersOptions {
1103
1103
  orderStatuses?: string[];
1104
1104
  /** Fields the free-text `term` is matched against. */
1105
1105
  termFields?: OrderSearchFields[];
1106
+ /**
1107
+ * Seed the search/filter form on mount — e.g. rehydrated from the URL query
1108
+ * so a bookmarked/shared filtered view restores. The consumer is responsible
1109
+ * for the fetch: pass this and the first fetch uses the seeded criteria.
1110
+ */
1111
+ initialSearchForm?: OrderSearchForm;
1106
1112
  /** Portal configuration: image search/variant filters. */
1107
1113
  configuration?: {
1108
1114
  imageSearchFiltersGrid?: MediaImageProductSearchInput;
@@ -2574,6 +2580,12 @@ interface AddressCardProps {
2574
2580
  enableSetDefault?: boolean;
2575
2581
  /** Display the "Default ... Address" badge @default false */
2576
2582
  showDefaultBadge?: boolean;
2583
+ /**
2584
+ * Display the address-type badge (invoice/delivery chip) @default true.
2585
+ * Set to `false` where the surrounding heading already names the address
2586
+ * type, to avoid a redundant raw-looking chip.
2587
+ */
2588
+ showTypeBadge?: boolean;
2577
2589
  /** Called when address is edited; receives the updated address object */
2578
2590
  onEdit?: (address: Address) => void | Promise<void>;
2579
2591
  /** Called after address edit completes */
@@ -4721,6 +4733,19 @@ interface OrderListProps {
4721
4733
  enableSearch?: boolean;
4722
4734
  /** Fields enabled for searching (UI inputs) */
4723
4735
  searchFields?: string[];
4736
+ /**
4737
+ * Seed the filter form on mount — typically rehydrated from the URL query so
4738
+ * a bookmarked/shared filtered view restores on reload. Pair with
4739
+ * `onSearchApply` so the page can keep the URL in sync when filters change.
4740
+ */
4741
+ initialSearchForm?: OrderSearchForm;
4742
+ /**
4743
+ * Fires when the user applies or clears filters (the "Search"/"Clear"
4744
+ * buttons). Receives the active filter form. Use it to persist the filters
4745
+ * to the URL — the component owns no router, so the page decides how (and
4746
+ * whether) to reflect them in `location`.
4747
+ */
4748
+ onSearchApply?: (form: OrderSearchForm) => void;
4724
4749
  /** Term fields configuration (backend) */
4725
4750
  termFields?: any[];
4726
4751
  /** Override company ID for order filtering (respects company switcher) */
@@ -4745,6 +4770,13 @@ interface OrderListProps {
4745
4770
  formatDate?: (dateString: string) => string;
4746
4771
  /** Get status color */
4747
4772
  getStatusColor?: (status: string) => string;
4773
+ /**
4774
+ * Localized display labels for order/quote statuses, keyed by the raw backend
4775
+ * status value (e.g. `{ NEW: 'Nieuw', CONFIRMED: 'Bevestigd', REQUEST:
4776
+ * 'Aangevraagd' }`). Unknown statuses fall back to the raw value. Without
4777
+ * this the list printed the raw enum (NEW/CONFIRMED/REQUEST) to the customer.
4778
+ */
4779
+ statusLabels?: Record<string, string>;
4748
4780
  /** Localization label overrides for UI strings. */
4749
4781
  labels?: {
4750
4782
  /** Text for the per-row "View" action button. */
@@ -4838,6 +4870,19 @@ interface OrderSummaryProps {
4838
4870
  formatDate?: (dateString: string) => string;
4839
4871
  /** Labels for the component */
4840
4872
  labels?: Record<string, string>;
4873
+ /**
4874
+ * Localized order/quote status labels, keyed by the raw backend status
4875
+ * (e.g. `{ NEW: 'Nieuw', REQUEST: 'Aangevraagd' }`). Unknown → raw value.
4876
+ */
4877
+ statusLabels?: Record<string, string>;
4878
+ /**
4879
+ * Localized payment-method names, keyed by the raw method value LOWER-CASED
4880
+ * (e.g. `{ rekening: 'Op rekening', account: 'Op rekening' }`). The backend
4881
+ * sends different raw values on the order vs quote path (REKENING / ACCOUNT),
4882
+ * so mapping both here makes the same method render identically. Unknown →
4883
+ * raw value.
4884
+ */
4885
+ paymethodLabels?: Record<string, string>;
4841
4886
  /** List of countries for resolving codes to names [{code: 'NL', name: 'Netherlands'}, ...] */
4842
4887
  countries?: {
4843
4888
  code: string;
@@ -6565,6 +6610,20 @@ interface SearchBarProps {
6565
6610
  onResultClick?: (result: SearchBarResult) => void;
6566
6611
  /** Fires when "View all results" is clicked. Receives the search term. */
6567
6612
  onViewAllClick?: (term: string) => void;
6613
+ /**
6614
+ * Build the destination URL for a result item. When provided, each result
6615
+ * renders as a real `<a href>` (middle-clickable, new-tab, crawlable) while
6616
+ * `onResultClick` still fires for SPA navigation. Omit to keep the
6617
+ * div-based fallback.
6618
+ */
6619
+ getResultHref?: (result: SearchBarResult) => string;
6620
+ /**
6621
+ * Build the destination URL for the "View all results" CTA. When provided,
6622
+ * the CTA renders as a real `<a href>` (middle-clickable, new-tab, crawlable,
6623
+ * keyboard-focusable) while `onViewAllClick` still fires for SPA navigation.
6624
+ * Omit to keep the div-based fallback.
6625
+ */
6626
+ getViewAllHref?: (term: string) => string;
6568
6627
  /** Custom price formatting function */
6569
6628
  formatPrice?: (price: number) => string;
6570
6629
  /** Currency symbol for prices. Resolved from PropellerProvider when omitted; defaults to '€'. */
package/dist/index.d.ts CHANGED
@@ -1103,6 +1103,12 @@ interface UseOrdersOptions {
1103
1103
  orderStatuses?: string[];
1104
1104
  /** Fields the free-text `term` is matched against. */
1105
1105
  termFields?: OrderSearchFields[];
1106
+ /**
1107
+ * Seed the search/filter form on mount — e.g. rehydrated from the URL query
1108
+ * so a bookmarked/shared filtered view restores. The consumer is responsible
1109
+ * for the fetch: pass this and the first fetch uses the seeded criteria.
1110
+ */
1111
+ initialSearchForm?: OrderSearchForm;
1106
1112
  /** Portal configuration: image search/variant filters. */
1107
1113
  configuration?: {
1108
1114
  imageSearchFiltersGrid?: MediaImageProductSearchInput;
@@ -2574,6 +2580,12 @@ interface AddressCardProps {
2574
2580
  enableSetDefault?: boolean;
2575
2581
  /** Display the "Default ... Address" badge @default false */
2576
2582
  showDefaultBadge?: boolean;
2583
+ /**
2584
+ * Display the address-type badge (invoice/delivery chip) @default true.
2585
+ * Set to `false` where the surrounding heading already names the address
2586
+ * type, to avoid a redundant raw-looking chip.
2587
+ */
2588
+ showTypeBadge?: boolean;
2577
2589
  /** Called when address is edited; receives the updated address object */
2578
2590
  onEdit?: (address: Address) => void | Promise<void>;
2579
2591
  /** Called after address edit completes */
@@ -4721,6 +4733,19 @@ interface OrderListProps {
4721
4733
  enableSearch?: boolean;
4722
4734
  /** Fields enabled for searching (UI inputs) */
4723
4735
  searchFields?: string[];
4736
+ /**
4737
+ * Seed the filter form on mount — typically rehydrated from the URL query so
4738
+ * a bookmarked/shared filtered view restores on reload. Pair with
4739
+ * `onSearchApply` so the page can keep the URL in sync when filters change.
4740
+ */
4741
+ initialSearchForm?: OrderSearchForm;
4742
+ /**
4743
+ * Fires when the user applies or clears filters (the "Search"/"Clear"
4744
+ * buttons). Receives the active filter form. Use it to persist the filters
4745
+ * to the URL — the component owns no router, so the page decides how (and
4746
+ * whether) to reflect them in `location`.
4747
+ */
4748
+ onSearchApply?: (form: OrderSearchForm) => void;
4724
4749
  /** Term fields configuration (backend) */
4725
4750
  termFields?: any[];
4726
4751
  /** Override company ID for order filtering (respects company switcher) */
@@ -4745,6 +4770,13 @@ interface OrderListProps {
4745
4770
  formatDate?: (dateString: string) => string;
4746
4771
  /** Get status color */
4747
4772
  getStatusColor?: (status: string) => string;
4773
+ /**
4774
+ * Localized display labels for order/quote statuses, keyed by the raw backend
4775
+ * status value (e.g. `{ NEW: 'Nieuw', CONFIRMED: 'Bevestigd', REQUEST:
4776
+ * 'Aangevraagd' }`). Unknown statuses fall back to the raw value. Without
4777
+ * this the list printed the raw enum (NEW/CONFIRMED/REQUEST) to the customer.
4778
+ */
4779
+ statusLabels?: Record<string, string>;
4748
4780
  /** Localization label overrides for UI strings. */
4749
4781
  labels?: {
4750
4782
  /** Text for the per-row "View" action button. */
@@ -4838,6 +4870,19 @@ interface OrderSummaryProps {
4838
4870
  formatDate?: (dateString: string) => string;
4839
4871
  /** Labels for the component */
4840
4872
  labels?: Record<string, string>;
4873
+ /**
4874
+ * Localized order/quote status labels, keyed by the raw backend status
4875
+ * (e.g. `{ NEW: 'Nieuw', REQUEST: 'Aangevraagd' }`). Unknown → raw value.
4876
+ */
4877
+ statusLabels?: Record<string, string>;
4878
+ /**
4879
+ * Localized payment-method names, keyed by the raw method value LOWER-CASED
4880
+ * (e.g. `{ rekening: 'Op rekening', account: 'Op rekening' }`). The backend
4881
+ * sends different raw values on the order vs quote path (REKENING / ACCOUNT),
4882
+ * so mapping both here makes the same method render identically. Unknown →
4883
+ * raw value.
4884
+ */
4885
+ paymethodLabels?: Record<string, string>;
4841
4886
  /** List of countries for resolving codes to names [{code: 'NL', name: 'Netherlands'}, ...] */
4842
4887
  countries?: {
4843
4888
  code: string;
@@ -6565,6 +6610,20 @@ interface SearchBarProps {
6565
6610
  onResultClick?: (result: SearchBarResult) => void;
6566
6611
  /** Fires when "View all results" is clicked. Receives the search term. */
6567
6612
  onViewAllClick?: (term: string) => void;
6613
+ /**
6614
+ * Build the destination URL for a result item. When provided, each result
6615
+ * renders as a real `<a href>` (middle-clickable, new-tab, crawlable) while
6616
+ * `onResultClick` still fires for SPA navigation. Omit to keep the
6617
+ * div-based fallback.
6618
+ */
6619
+ getResultHref?: (result: SearchBarResult) => string;
6620
+ /**
6621
+ * Build the destination URL for the "View all results" CTA. When provided,
6622
+ * the CTA renders as a real `<a href>` (middle-clickable, new-tab, crawlable,
6623
+ * keyboard-focusable) while `onViewAllClick` still fires for SPA navigation.
6624
+ * Omit to keep the div-based fallback.
6625
+ */
6626
+ getViewAllHref?: (term: string) => string;
6568
6627
  /** Custom price formatting function */
6569
6628
  formatPrice?: (price: number) => string;
6570
6629
  /** Currency symbol for prices. Resolved from PropellerProvider when omitted; defaults to '€'. */
package/dist/index.js CHANGED
@@ -1698,7 +1698,9 @@ function useOrders(options) {
1698
1698
  const [orders, setOrders] = useState([]);
1699
1699
  const [loading, setLoading] = useState(false);
1700
1700
  const [error, setError] = useState(null);
1701
- const [searchForm, setSearchForm] = useState({});
1701
+ const [searchForm, setSearchForm] = useState(
1702
+ options.initialSearchForm ?? {}
1703
+ );
1702
1704
  const pagination = usePagination(options.itemsPerPage ?? 10);
1703
1705
  const fetchOrders = useCallback(
1704
1706
  async (page = 1) => {
@@ -3258,10 +3260,15 @@ function LoginForm(rawProps) {
3258
3260
  ] }) : null,
3259
3261
  props.accountHeaderLoginForm ? /* @__PURE__ */ jsxs("div", { className: "propeller-login-form__footer flex flex-col gap-2 text-sm pt-3 text-center", children: [
3260
3262
  /* @__PURE__ */ jsx(LoginFormForgotPasswordLink, {}),
3261
- /* @__PURE__ */ jsxs("div", { className: "propeller-login-form__register text-xs text-muted-foreground", children: [
3262
- getLabel(props.labels, "noAccount", "Don't have an account?"),
3263
- /* @__PURE__ */ jsx(LoginFormRegisterLink, {})
3264
- ] })
3263
+ /* @__PURE__ */ jsx("div", { className: "propeller-login-form__register text-xs text-muted-foreground", children: (() => {
3264
+ const tpl = getLabel(props.labels, "noAccount", "Don't have an account? {link}");
3265
+ const [before, after = ""] = tpl.split("{link}");
3266
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3267
+ before,
3268
+ /* @__PURE__ */ jsx(LoginFormRegisterLink, {}),
3269
+ after
3270
+ ] });
3271
+ })() })
3265
3272
  ] }) : null
3266
3273
  ]
3267
3274
  }
@@ -3550,6 +3557,13 @@ function AccountIconAndMenu(rawProps) {
3550
3557
  setMenuOpen(false);
3551
3558
  if (props.onMenuItemClick) props.onMenuItemClick(href);
3552
3559
  }
3560
+ function handleMenuLinkClick(event, href) {
3561
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
3562
+ return;
3563
+ }
3564
+ event.preventDefault();
3565
+ handleMenuItemClick(href);
3566
+ }
3553
3567
  function handleLogoutClick() {
3554
3568
  setMenuOpen(false);
3555
3569
  if (props.onLogoutClick) props.onLogoutClick();
@@ -3598,10 +3612,10 @@ function AccountIconAndMenu(rawProps) {
3598
3612
  /* @__PURE__ */ jsx("p", { className: "propeller-account-menu__user-name font-medium text-foreground truncate", children: getUserName() })
3599
3613
  ] }),
3600
3614
  /* @__PURE__ */ jsx("nav", { className: "propeller-account-menu__nav py-2", children: /* @__PURE__ */ jsx("ul", { className: "propeller-account-menu__list space-y-0.5", children: getMenuLinks()?.map((link) => /* @__PURE__ */ jsx("li", { className: "propeller-account-menu__item", children: /* @__PURE__ */ jsx(
3601
- "button",
3615
+ "a",
3602
3616
  {
3603
- type: "button",
3604
- onClick: (event) => handleMenuItemClick(link.href),
3617
+ href: link.href,
3618
+ onClick: (event) => handleMenuLinkClick(event, link.href),
3605
3619
  "data-active": isActiveLink(link.href) ? "true" : "false",
3606
3620
  className: `propeller-account-menu__link flex w-full items-center gap-3 px-4 py-2.5 text-sm font-medium transition-colors ${isActiveLink(link.href) ? "bg-secondary/5 text-secondary border-l-2 border-secondary" : "text-muted-foreground hover:bg-surface-hover hover:text-foreground"}`,
3607
3621
  children: link.label
@@ -3664,11 +3678,11 @@ function AccountIconAndMenu(rawProps) {
3664
3678
  /* @__PURE__ */ jsx("p", { className: "propeller-account-menu__user-name font-medium text-foreground truncate", children: getUserName() })
3665
3679
  ] }),
3666
3680
  /* @__PURE__ */ jsx("nav", { className: "propeller-account-menu__nav", children: /* @__PURE__ */ jsx("ul", { className: "propeller-account-menu__list space-y-0.5", children: getMenuLinks()?.map((link) => /* @__PURE__ */ jsx("li", { className: "propeller-account-menu__item", children: /* @__PURE__ */ jsx(
3667
- "button",
3681
+ "a",
3668
3682
  {
3669
- type: "button",
3683
+ href: link.href,
3670
3684
  className: "propeller-account-menu__link flex w-full items-center gap-3 px-3 py-2 text-sm font-medium rounded-control text-muted-foreground hover:bg-surface-hover hover:text-foreground transition-colors",
3671
- onClick: (event) => handleMenuItemClick(link.href),
3685
+ onClick: (event) => handleMenuLinkClick(event, link.href),
3672
3686
  children: link.label
3673
3687
  }
3674
3688
  ) }, link.href)) }) }),
@@ -5430,7 +5444,8 @@ function AddressCard(rawProps) {
5430
5444
  ] });
5431
5445
  }
5432
5446
  function AddressCardTypeBadge(props) {
5433
- const { derived } = useAddressCardContext();
5447
+ const { derived, resolved } = useAddressCardContext();
5448
+ if (resolved.showTypeBadge === false) return null;
5434
5449
  if (!derived.addressType) return null;
5435
5450
  return /* @__PURE__ */ jsx(
5436
5451
  "span",
@@ -7129,18 +7144,23 @@ function CartOverview(props) {
7129
7144
  onChange: (event) => setTermsAccepted(event.target.checked)
7130
7145
  }
7131
7146
  ),
7132
- /* @__PURE__ */ jsxs("label", { htmlFor: "cart-overview-terms", className: "text-sm leading-none", children: [
7133
- getLabel(props.labels, "termsPrefix", "I agree to the"),
7134
- /* @__PURE__ */ jsx(
7135
- "a",
7136
- {
7137
- href: "#",
7138
- className: "text-primary hover:underline font-medium",
7139
- onClick: handleTermsLinkClick,
7140
- children: getLabel(props.labels, "termsLink", "Terms and Conditions")
7141
- }
7142
- )
7143
- ] })
7147
+ /* @__PURE__ */ jsx("label", { htmlFor: "cart-overview-terms", className: "text-sm leading-none", children: (() => {
7148
+ const tpl = getLabel(props.labels, "termsConsent", "I agree to the {link}");
7149
+ const [before, after = ""] = tpl.split("{link}");
7150
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
7151
+ before,
7152
+ /* @__PURE__ */ jsx(
7153
+ "a",
7154
+ {
7155
+ href: "#",
7156
+ className: "text-primary hover:underline font-medium",
7157
+ onClick: handleTermsLinkClick,
7158
+ children: getLabel(props.labels, "termsLink", "Terms and Conditions")
7159
+ }
7160
+ ),
7161
+ after
7162
+ ] });
7163
+ })() })
7144
7164
  ] }) : null,
7145
7165
  showPurchaseButton ? /* @__PURE__ */ jsxs(
7146
7166
  "button",
@@ -9905,7 +9925,7 @@ function FavoriteLists(rawProps) {
9905
9925
  ),
9906
9926
  getTotalCount(list),
9907
9927
  "\xA0",
9908
- getLabel(props.labels, "items", "items")
9928
+ getTotalCount(list) === 1 ? getLabel(props.labels, "itemSingular", "item") : getLabel(props.labels, "itemPlural", "items")
9909
9929
  ] }) : null
9910
9930
  ] })
9911
9931
  ] }) : null
@@ -10089,15 +10109,15 @@ function FavoriteLists(rawProps) {
10089
10109
  )
10090
10110
  ] }),
10091
10111
  /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
10092
- /* @__PURE__ */ jsxs("p", { className: "propeller-favorite-lists__delete-prompt", children: [
10093
- getLabel(props.labels, "deleteConfirm", "Are you sure you want to delete"),
10094
- /* @__PURE__ */ jsxs("strong", { children: [
10095
- '"',
10096
- listToDelete?.name,
10097
- '"'
10098
- ] }),
10099
- "?"
10100
- ] }),
10112
+ /* @__PURE__ */ jsx("p", { className: "propeller-favorite-lists__delete-prompt", children: (() => {
10113
+ const tpl = getLabel(props.labels, "deleteConfirm", 'Are you sure you want to delete "{name}"?');
10114
+ const [before, after = ""] = tpl.split("{name}");
10115
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
10116
+ before,
10117
+ /* @__PURE__ */ jsx("strong", { children: listToDelete?.name }),
10118
+ after
10119
+ ] });
10120
+ })() }),
10101
10121
  /* @__PURE__ */ jsx("p", { className: "propeller-favorite-lists__delete-warning text-sm text-destructive", children: getLabel(props.labels, "deleteWarning", "This action cannot be undone.") })
10102
10122
  ] }),
10103
10123
  /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 pt-6", children: [
@@ -10681,6 +10701,8 @@ var DEFAULT_LABELS2 = {
10681
10701
  [SortOrder.DESC]: "High to Low",
10682
10702
  clearAll: "Clear All",
10683
10703
  products: " Products",
10704
+ productSingular: "Product",
10705
+ productPlural: "Products",
10684
10706
  from: "from",
10685
10707
  results: "results",
10686
10708
  perPage: " per page",
@@ -10774,7 +10796,8 @@ function GridToolbar(rawProps) {
10774
10796
  /* @__PURE__ */ jsxs("div", { className: "propeller-grid-toolbar__bar flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-4", children: [
10775
10797
  /* @__PURE__ */ jsx("div", { className: "propeller-grid-toolbar__count text-sm text-muted-foreground font-medium", children: props.itemsFound > 0 ? /* @__PURE__ */ jsxs("span", { children: [
10776
10798
  props.itemsFound,
10777
- getLabel53("products")
10799
+ "\xA0",
10800
+ props.itemsFound === 1 ? getLabel53("productSingular") : getLabel53("productPlural")
10778
10801
  ] }) : null }),
10779
10802
  /* @__PURE__ */ jsxs("div", { className: "propeller-grid-toolbar__controls flex flex-wrap items-center gap-3", children: [
10780
10803
  /* @__PURE__ */ jsx(
@@ -11816,7 +11839,8 @@ function OrderList(rawProps) {
11816
11839
  orderStatuses: props.orderStatus,
11817
11840
  termFields: props.termFields,
11818
11841
  itemsPerPage: props.initialItemsPerPage || 10,
11819
- channelIds: props.channelIds
11842
+ channelIds: props.channelIds,
11843
+ initialSearchForm: props.initialSearchForm
11820
11844
  });
11821
11845
  function handlePageChange(newPage) {
11822
11846
  if (newPage >= 1 && newPage <= totalPages) {
@@ -11850,6 +11874,9 @@ function OrderList(rawProps) {
11850
11874
  return "bg-warning/10 text-warning";
11851
11875
  }
11852
11876
  }
11877
+ function statusLabel(status) {
11878
+ return props.statusLabels?.[status] || status;
11879
+ }
11853
11880
  function getColumnLabel(col) {
11854
11881
  if (props.columnConfig && props.columnConfig[col]) {
11855
11882
  return props.columnConfig[col];
@@ -12126,6 +12153,7 @@ function OrderList(rawProps) {
12126
12153
  onClick: (event) => {
12127
12154
  setSearchForm({});
12128
12155
  fetchOrders(1);
12156
+ props.onSearchApply?.({});
12129
12157
  },
12130
12158
  children: getLabel(props.labels, "clearButton", "Clear")
12131
12159
  }
@@ -12134,7 +12162,10 @@ function OrderList(rawProps) {
12134
12162
  "button",
12135
12163
  {
12136
12164
  className: "propeller-order-list__search-btn inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-control shadow-sm text-primary-foreground bg-primary hover:bg-primary/80 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary",
12137
- onClick: (event) => fetchOrders(1),
12165
+ onClick: (event) => {
12166
+ fetchOrders(1);
12167
+ props.onSearchApply?.(searchForm);
12168
+ },
12138
12169
  children: getLabel(props.labels, "searchButton", "Search")
12139
12170
  }
12140
12171
  )
@@ -12154,7 +12185,7 @@ function OrderList(rawProps) {
12154
12185
  /* @__PURE__ */ jsx("tbody", { className: "propeller-order-list__tbody bg-card divide-y divide-border", children: orders?.map((order) => /* @__PURE__ */ jsx(
12155
12186
  "tr",
12156
12187
  {
12157
- className: "propeller-order-list__row hover:bg-surface-hover",
12188
+ className: `propeller-order-list__row hover:bg-surface-hover ${rowsClickable ? "cursor-pointer" : ""}`,
12158
12189
  "data-clickable": rowsClickable ? "true" : "false",
12159
12190
  onClick: (event) => rowsClickable && props.onOrderClick(order.id),
12160
12191
  children: columns?.map((col) => /* @__PURE__ */ jsxs(
@@ -12170,7 +12201,7 @@ function OrderList(rawProps) {
12170
12201
  {
12171
12202
  className: `propeller-order-list__status px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${getStatusColor(order.status)}`,
12172
12203
  "data-status": order.status,
12173
- children: order.status
12204
+ children: statusLabel(order.status)
12174
12205
  }
12175
12206
  ) : null,
12176
12207
  col === "total" ? /* @__PURE__ */ jsx(Fragment, { children: formatPrice17(order.total?.net) }) : null,
@@ -12472,11 +12503,13 @@ function OrderSummary(props) {
12472
12503
  const showRemarks = props.showRemarks !== void 0 ? props.showRemarks : true;
12473
12504
  const orderNumber = order?.id || "";
12474
12505
  const orderDate = order?.createdAt || "";
12475
- const orderStatus = order?.status || "";
12506
+ const rawStatus = order?.status || "";
12507
+ const orderStatus = rawStatus ? props.statusLabels?.[rawStatus] || rawStatus : "";
12476
12508
  const orderTotal = Number(order?.total?.net || 0);
12477
12509
  const orderReference = order?.reference || "";
12478
12510
  const orderRemarks = order?.remarks || "";
12479
- const paymentMethod = order?.paymentData?.method || "";
12511
+ const rawPaymentMethod = order?.paymentData?.method || "";
12512
+ const paymentMethod = rawPaymentMethod ? props.paymethodLabels?.[rawPaymentMethod.toLowerCase()] || rawPaymentMethod : "";
12480
12513
  const carrierName = order?.postageData?.carrier || "";
12481
12514
  const addresses = order?.addresses || [];
12482
12515
  const invoiceAddress = addresses.find((a) => a.type === "invoice") || null;
@@ -16164,18 +16197,23 @@ function QuoteActions(rawProps) {
16164
16197
  onChange: (event) => handleTermsChange(event.target.checked)
16165
16198
  }
16166
16199
  ),
16167
- /* @__PURE__ */ jsxs("label", { htmlFor: "quote-actions-terms", className: "text-sm leading-none", children: [
16168
- getLabel(props.labels, "termsPrefix", "I agree to the"),
16169
- /* @__PURE__ */ jsx(
16170
- "a",
16171
- {
16172
- href: "#",
16173
- className: "text-primary hover:underline font-medium",
16174
- onClick: (event) => handleTermsLinkClick(event),
16175
- children: getLabel(props.labels, "termsLink", "Terms and Conditions")
16176
- }
16177
- )
16178
- ] })
16200
+ /* @__PURE__ */ jsx("label", { htmlFor: "quote-actions-terms", className: "text-sm leading-none", children: (() => {
16201
+ const tpl = getLabel(props.labels, "termsConsent", "I agree to the {link}");
16202
+ const [before, after = ""] = tpl.split("{link}");
16203
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
16204
+ before,
16205
+ /* @__PURE__ */ jsx(
16206
+ "a",
16207
+ {
16208
+ href: "#",
16209
+ className: "text-primary hover:underline font-medium",
16210
+ onClick: (event) => handleTermsLinkClick(event),
16211
+ children: getLabel(props.labels, "termsLink", "Terms and Conditions")
16212
+ }
16213
+ ),
16214
+ after
16215
+ ] });
16216
+ })() })
16179
16217
  ] }) : null,
16180
16218
  /* @__PURE__ */ jsxs(
16181
16219
  "button",
@@ -17237,6 +17275,9 @@ function SearchBar(rawProps) {
17237
17275
  }
17238
17276
  setShowDropdown(false);
17239
17277
  }
17278
+ function isModifiedClick(event) {
17279
+ return event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
17280
+ }
17240
17281
  useEffect(() => {
17241
17282
  const listener = (e) => {
17242
17283
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -17290,39 +17331,68 @@ function SearchBar(rawProps) {
17290
17331
  ] }) }),
17291
17332
  showDropdown ? /* @__PURE__ */ jsxs("div", { className: "propeller-search-bar__dropdown absolute top-full left-0 right-0 mt-2 bg-card rounded-container shadow-xl border border-border z-50 flex flex-col max-h-96", children: [
17292
17333
  results.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
17293
- /* @__PURE__ */ jsx("div", { className: "propeller-search-bar__results flex-1 overflow-y-auto", children: results?.map((result, index) => /* @__PURE__ */ jsxs(
17294
- "div",
17334
+ /* @__PURE__ */ jsx("div", { className: "propeller-search-bar__results flex-1 overflow-y-auto", children: results?.map((result, index) => {
17335
+ const ResultTag = props.getResultHref ? "a" : "div";
17336
+ const resultProps = props.getResultHref ? {
17337
+ href: props.getResultHref(result),
17338
+ onClick: (event) => {
17339
+ if (isModifiedClick(event)) return;
17340
+ event.preventDefault();
17341
+ handleResultClick(result);
17342
+ }
17343
+ } : { onClick: (_event) => handleResultClick(result) };
17344
+ return /* @__PURE__ */ jsxs(
17345
+ ResultTag,
17346
+ {
17347
+ className: "propeller-search-bar__result flex items-center gap-4 p-3 hover:bg-surface-hover cursor-pointer border-b border-border-subtle last:border-b-0",
17348
+ ...resultProps,
17349
+ children: [
17350
+ result.imageUrl || noImageUrl() ? /* @__PURE__ */ jsx("div", { className: "propeller-search-bar__result-media relative w-16 h-16 flex-shrink-0", children: /* @__PURE__ */ jsx(
17351
+ "img",
17352
+ {
17353
+ className: "propeller-search-bar__result-image w-full h-full object-contain",
17354
+ src: result.imageUrl || noImageUrl(),
17355
+ alt: result.name
17356
+ }
17357
+ ) }) : null,
17358
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
17359
+ /* @__PURE__ */ jsx("div", { className: "propeller-search-bar__result-name font-semibold truncate", children: result.name }),
17360
+ result.sku ? /* @__PURE__ */ jsxs("div", { className: "propeller-search-bar__result-sku text-sm text-muted-foreground", children: [
17361
+ "SKU: ",
17362
+ result.sku
17363
+ ] }) : null
17364
+ ] }),
17365
+ result.price !== void 0 && result.price !== null ? /* @__PURE__ */ jsxs("div", { className: "propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0 text-right", children: [
17366
+ /* @__PURE__ */ jsx("span", { className: "propeller-search-bar__result-price-value", children: formatItemPrice(leadingPrice(result)) }),
17367
+ /* @__PURE__ */ jsx("span", { className: "propeller-search-bar__result-price-label block text-xs font-normal text-muted-foreground", children: priceTaxLabel() })
17368
+ ] }) : null
17369
+ ]
17370
+ },
17371
+ result.id + "-" + index
17372
+ );
17373
+ }) }),
17374
+ itemsFound > results.length ? props.getViewAllHref ? /* @__PURE__ */ jsxs(
17375
+ "a",
17295
17376
  {
17296
- className: "propeller-search-bar__result flex items-center gap-4 p-3 hover:bg-surface-hover cursor-pointer border-b border-border-subtle last:border-b-0",
17297
- onClick: (event) => handleResultClick(result),
17377
+ href: props.getViewAllHref(localTerm),
17378
+ className: "propeller-search-bar__view-all block flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-container",
17379
+ onClick: (event) => {
17380
+ if (isModifiedClick(event)) return;
17381
+ event.preventDefault();
17382
+ handleViewAllClick();
17383
+ },
17298
17384
  children: [
17299
- result.imageUrl || noImageUrl() ? /* @__PURE__ */ jsx("div", { className: "propeller-search-bar__result-media relative w-16 h-16 flex-shrink-0", children: /* @__PURE__ */ jsx(
17300
- "img",
17301
- {
17302
- className: "propeller-search-bar__result-image w-full h-full object-contain",
17303
- src: result.imageUrl || noImageUrl(),
17304
- alt: result.name
17305
- }
17306
- ) }) : null,
17307
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
17308
- /* @__PURE__ */ jsx("div", { className: "propeller-search-bar__result-name font-semibold truncate", children: result.name }),
17309
- result.sku ? /* @__PURE__ */ jsxs("div", { className: "propeller-search-bar__result-sku text-sm text-muted-foreground", children: [
17310
- "SKU: ",
17311
- result.sku
17312
- ] }) : null
17313
- ] }),
17314
- result.price !== void 0 && result.price !== null ? /* @__PURE__ */ jsxs("div", { className: "propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0 text-right", children: [
17315
- /* @__PURE__ */ jsx("span", { className: "propeller-search-bar__result-price-value", children: formatItemPrice(leadingPrice(result)) }),
17316
- /* @__PURE__ */ jsx("span", { className: "propeller-search-bar__result-price-label block text-xs font-normal text-muted-foreground", children: priceTaxLabel() })
17317
- ] }) : null
17385
+ getLabel(props.labels, "viewAll", "View all results"),
17386
+ " (",
17387
+ itemsFound,
17388
+ ")"
17318
17389
  ]
17319
- },
17320
- result.id + "-" + index
17321
- )) }),
17322
- itemsFound > results.length ? /* @__PURE__ */ jsxs(
17323
- "div",
17390
+ }
17391
+ ) : /* @__PURE__ */ jsxs(
17392
+ "button",
17324
17393
  {
17325
- className: "propeller-search-bar__view-all flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-container",
17394
+ type: "button",
17395
+ className: "propeller-search-bar__view-all block w-full flex-shrink-0 p-3 text-center text-primary hover:bg-primary/5 cursor-pointer font-semibold border-t border-border bg-card rounded-b-container",
17326
17396
  onClick: (event) => handleViewAllClick(),
17327
17397
  children: [
17328
17398
  getLabel(props.labels, "viewAll", "View all results"),