@sonic-equipment/ui 188.0.0 → 190.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/cards/data-card/data-card.js +1 -1
  2. package/dist/country-selector/connected-country-selector.js +0 -11
  3. package/dist/country-selector/use-countries-languages.js +0 -11
  4. package/dist/delivery-time/delivery-time.js +3 -4
  5. package/dist/exports.d.ts +12 -3
  6. package/dist/forms/fields/select-field/select-field.js +1 -1
  7. package/dist/forms/layout/form/form.js +1 -1
  8. package/dist/header/link-list/navigation-link-list.js +14 -4
  9. package/dist/index.js +13 -4
  10. package/dist/intl/formatted-date.d.ts +4 -0
  11. package/dist/intl/formatted-date.js +8 -0
  12. package/dist/intl/translation-id.d.ts +1 -1
  13. package/dist/intl/use-formatted-date.d.ts +6 -0
  14. package/dist/intl/use-formatted-date.js +19 -0
  15. package/dist/lists/menu-list/menu-list-item.js +3 -1
  16. package/dist/lists/menu-list/menu-list-provider.d.ts +11 -0
  17. package/dist/lists/menu-list/menu-list-provider.js +30 -0
  18. package/dist/lists/menu-list/menu-list.d.ts +2 -1
  19. package/dist/lists/menu-list/menu-list.js +4 -3
  20. package/dist/lists/menu-list/menu-list.module.css.js +1 -1
  21. package/dist/lists/menu-list/use-menu-list-item.d.ts +5 -0
  22. package/dist/lists/menu-list/use-menu-list-item.js +12 -0
  23. package/dist/lists/menu-list/use-menu-list.d.ts +1 -0
  24. package/dist/lists/menu-list/use-menu-list.js +11 -0
  25. package/dist/loading/dynamic-loading-overlay.d.ts +5 -0
  26. package/dist/loading/dynamic-loading-overlay.js +26 -0
  27. package/dist/loading/dynamic-loading-overlay.module.css.js +3 -0
  28. package/dist/pages/checkout/cart-page/cart-page.js +1 -1
  29. package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +2 -4
  30. package/dist/pages/error-page/error-page.js +2 -7
  31. package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.js +0 -2
  32. package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.js +1 -1
  33. package/dist/pages/my-sonic/pages/order-history/order-history.d.ts +1 -0
  34. package/dist/pages/my-sonic/pages/order-history/order-history.js +166 -0
  35. package/dist/pages/my-sonic/pages/order-history/order-history.module.css.js +3 -0
  36. package/dist/pages/product/product-listing-page/product-listing.js +1 -1
  37. package/dist/pages/product/search-result-page/search-results-page.js +1 -1
  38. package/dist/shared/api/storefront/hooks/orders/use-fetch-orders.d.ts +10 -0
  39. package/dist/shared/api/storefront/hooks/orders/use-fetch-orders.js +13 -0
  40. package/dist/shared/api/storefront/model/storefront.model.d.ts +13 -1
  41. package/dist/shared/api/storefront/model/storefront.model.js +28 -1
  42. package/dist/shared/api/storefront/services/order-service.d.ts +12 -0
  43. package/dist/shared/api/storefront/services/order-service.js +29 -0
  44. package/dist/shared/hooks/use-intersection-observer.d.ts +3 -1
  45. package/dist/shared/hooks/use-intersection-observer.js +3 -2
  46. package/dist/shared/utils/date.d.ts +4 -1
  47. package/dist/shared/utils/date.js +6 -5
  48. package/dist/shared/utils/price.d.ts +1 -1
  49. package/dist/shared/{hooks/use-scroll-to.d.ts → utils/scrolling.d.ts} +1 -1
  50. package/dist/shared/utils/scrolling.js +16 -0
  51. package/dist/shared/utils/uuid.d.ts +2 -1
  52. package/dist/styles.css +895 -640
  53. package/dist/table/data-table.d.ts +37 -10
  54. package/dist/table/data-table.js +72 -17
  55. package/dist/table/data-table.module.css.js +1 -1
  56. package/dist/table/elements/switch-sort-direction.d.ts +2 -0
  57. package/dist/table/elements/switch-sort-direction.js +11 -0
  58. package/dist/table/elements/table-context.d.ts +6 -5
  59. package/dist/table/elements/table-context.js +1 -16
  60. package/dist/table/elements/table-provider.d.ts +6 -5
  61. package/dist/table/elements/table-provider.js +23 -17
  62. package/dist/table/elements/table-row-context.d.ts +2 -2
  63. package/dist/table/elements/table-row-provider.js +4 -4
  64. package/dist/table/elements/table-sort-button.d.ts +8 -7
  65. package/dist/table/elements/table-sort-button.js +5 -4
  66. package/dist/table/elements/table.d.ts +1 -1
  67. package/dist/table/elements/table.js +2 -2
  68. package/dist/table/elements/table.module.css.js +1 -1
  69. package/dist/table/elements/td.d.ts +1 -1
  70. package/dist/table/elements/th.d.ts +1 -7
  71. package/dist/table/elements/th.js +2 -3
  72. package/dist/table/elements/tr.d.ts +2 -8
  73. package/dist/table/elements/tr.js +1 -3
  74. package/dist/table/elements/types.d.ts +36 -0
  75. package/dist/table/elements/use-table.js +1 -3
  76. package/dist/table/elements/use-td.d.ts +1 -1
  77. package/dist/table/elements/use-th.d.ts +2 -2
  78. package/package.json +1 -1
  79. package/dist/shared/hooks/use-scroll-to.js +0 -19
  80. package/dist/table/elements/table-column-properties.d.ts +0 -10
  81. package/dist/table/elements/use-tr.d.ts +0 -2
  82. package/dist/table/elements/use-tr.js +0 -16
@@ -0,0 +1,3 @@
1
+ var styles = {"dynamic-loading-overlay":"dynamic-loading-overlay-module-CAecM","content":"dynamic-loading-overlay-module-XeFAb","loading-indicator":"dynamic-loading-overlay-module-lhL5i","spinner":"dynamic-loading-overlay-module-cpo4H","is-loading":"dynamic-loading-overlay-module-3bed-"};
2
+
3
+ export { styles as default };
@@ -99,7 +99,7 @@ function CartContent({ cartLines }) {
99
99
  originalTotalPrice: ensureNumber(cartLine.properties.totalListPrice),
100
100
  pricePerUnit: cartLine.pricing?.unitNetPrice || 0,
101
101
  totalPrice: cartLine.pricing?.extendedUnitNetPrice || 0,
102
- }, productId: cartLine.productId || '', sku: cartLine.erpNumber || '', tags: [], title: cartLine.shortDescription }, cartLine.id))) }) }));
102
+ }, productId: cartLine.productId || '', sku: cartLine.erpNumber || '', tags: [cartLine.properties.label].filter(Boolean), title: cartLine.shortDescription }, cartLine.id))) }) }));
103
103
  }
104
104
  function CartPage() {
105
105
  const t = useFormattedMessage();
@@ -5,13 +5,12 @@ import { PrintButton } from '../../../buttons/print-button/print-button.js';
5
5
  import { OrderLineCard } from '../../../cards/orderline-card/orderline-card.js';
6
6
  import { CartTotals } from '../../../cart-totals/cart-totals.js';
7
7
  import { InfoDisplay } from '../../../display/info-display/info-display.js';
8
+ import { FormattedDate } from '../../../intl/formatted-date.js';
8
9
  import { FormattedMessage } from '../../../intl/formatted-message.js';
9
- import { useCultureCode } from '../../../intl/use-culture-code.js';
10
10
  import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
11
11
  import { OrderLineList } from '../../../lists/orderline-list/orderline-list.js';
12
12
  import { useSaveCartForLater } from '../../../shared/api/storefront/hooks/cart/use-save-cart-for-later.js';
13
13
  import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
14
- import { formatDateToLocaleString } from '../../../shared/utils/date.js';
15
14
  import { ensureNumber } from '../../../shared/utils/number.js';
16
15
  import { useToast } from '../../../toast/use-toast.js';
17
16
  import { Page } from '../../components/page/page.js';
@@ -25,7 +24,6 @@ import styles from './order-confirmation-page.module.css.js';
25
24
  function OrderConfirmationPageContent({ cart, }) {
26
25
  const t = useFormattedMessage();
27
26
  const { addToast } = useToast();
28
- const cultureCode = useCultureCode();
29
27
  const saveCartForLater = useSaveCartForLater({
30
28
  onError: () => {
31
29
  addToast({
@@ -56,7 +54,7 @@ function OrderConfirmationPageContent({ cart, }) {
56
54
  secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(Button, { color: "secondary", onClick: () => {
57
55
  saveCartForLater.mutate({ cart });
58
56
  }, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })), jsx(PrintButton, {})] })),
59
- }, overview: jsx(CartTotals, { currencyCode: currencyCode, fulfillmentMethod: cart.fulfillmentMethod, orderNumber: cart.orderNumber, shippingCost: cart.shippingAndHandling, subtotal: cart.orderSubTotal, tax: cart.totalTax, total: cart.orderGrandTotal, vatPercentage: cart.cartLines?.[0]?.pricing?.vatRate }), children: jsxs("div", { children: [jsx(CheckoutPageSection, { hasBorder: false, title: t('General'), children: jsx(CheckoutPageSectionContent, { children: jsxs("div", { className: styles['general-order-info'], children: [cart.orderDate && (jsx(InfoDisplay, { id: "order-date", label: t('Order date'), value: formatDateToLocaleString(new Date(cart.orderDate), cultureCode) })), cart.requestedDeliveryDateDisplay && (jsx(InfoDisplay, { id: "requested-delivery-date", label: t('Requested delivery date'), value: formatDateToLocaleString(new Date(cart.requestedDeliveryDateDisplay.toString()), cultureCode) })), cart.poNumber && (jsx(InfoDisplay, { id: "po-number", label: t('PO Number'), value: cart.poNumber }))] }) }) }), jsx(CheckoutPageSection, { hasBorder: false, title: t('Billing and shipping information'), children: jsx(CheckoutPageSectionContent, { children: jsx(BillingAndInvoiceInformation, { billToAddress: cart.billTo && {
57
+ }, overview: jsx(CartTotals, { currencyCode: currencyCode, fulfillmentMethod: cart.fulfillmentMethod, orderNumber: cart.orderNumber, shippingCost: cart.shippingAndHandling, subtotal: cart.orderSubTotal, tax: cart.totalTax, total: cart.orderGrandTotal, vatPercentage: cart.cartLines?.[0]?.pricing?.vatRate }), children: jsxs("div", { children: [jsx(CheckoutPageSection, { hasBorder: false, title: t('General'), children: jsx(CheckoutPageSectionContent, { children: jsxs("div", { className: styles['general-order-info'], children: [cart.orderDate && (jsx(InfoDisplay, { id: "order-date", label: t('Order date'), value: jsx(FormattedDate, { date: cart.orderDate }) })), cart.requestedDeliveryDateDisplay && (jsx(InfoDisplay, { id: "requested-delivery-date", label: t('Requested delivery date'), value: jsx(FormattedDate, { date: cart.requestedDeliveryDate }) })), cart.poNumber && (jsx(InfoDisplay, { id: "po-number", label: t('PO Number'), value: cart.poNumber }))] }) }) }), jsx(CheckoutPageSection, { hasBorder: false, title: t('Billing and shipping information'), children: jsx(CheckoutPageSectionContent, { children: jsx(BillingAndInvoiceInformation, { billToAddress: cart.billTo && {
60
58
  address1: cart.billTo.address1,
61
59
  address2: cart.billTo.address2,
62
60
  address3: cart.billTo.address3,
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { useEffect } from 'react';
4
+ import { logger } from '../../logging/logger.js';
4
5
  import { isRequestError } from '../../shared/fetch/request.js';
5
6
  import { environment } from '../../shared/utils/environment.js';
6
7
  import { Heading } from '../../typography/heading/heading.js';
@@ -9,13 +10,7 @@ import { PATHS } from '../paths.js';
9
10
 
10
11
  function ErrorPage({ error }) {
11
12
  useEffect(() => {
12
- const timeoutId = setTimeout(() => {
13
- if (!isRequestError(error))
14
- throw error;
15
- }, 0);
16
- return () => {
17
- clearTimeout(timeoutId);
18
- };
13
+ logger.error('ErrorPage error:', error);
19
14
  }, [error]);
20
15
  return (jsx(Page, { breadcrumb: [
21
16
  { href: PATHS.HOME, label: 'Home' },
@@ -1,6 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { FormattedMessage } from '../../../../intl/formatted-message.js';
3
- import { logger } from '../../../../logging/logger.js';
4
3
  import { useFetchCurrentAccount } from '../../../../shared/api/storefront/hooks/account/use-fetch-current-account.js';
5
4
  import { usePatchSession } from '../../../../shared/api/storefront/hooks/authentication/use-patch-session.js';
6
5
  import { useNavigate } from '../../../../shared/routing/use-navigate.js';
@@ -18,7 +17,6 @@ function ConnectedChangePasswordDialog({ isOpen, onClose, }) {
18
17
  if (!isOpen)
19
18
  return null;
20
19
  return (jsx(ChangePasswordDialog, { error: errorFetchCurrentAccount || errorPatchSession, isLoading: isLoading, isOpen: isOpen, isUpdating: isUpdating, onClose: onClose, onPasswordChanged: async (currentPassword, newPassword) => {
21
- logger.info(currentPassword, newPassword);
22
20
  await patchSession({
23
21
  session: {
24
22
  email: account?.email,
@@ -6,7 +6,7 @@ import { mySonicNavigationItems } from './my-sonic-navigation-items.js';
6
6
  import styles from './my-sonic-desktop-navigation.module.css.js';
7
7
 
8
8
  function MySonicDesktopNavigation({ className, currentPath, onLogout, }) {
9
- return (jsx(MenuList, { className: className, children: mySonicNavigationItems.map(item => (jsx(MenuListItem, { hasChildren: true, badge: jsx(item.Icon, {}), ...(item.type === 'action'
9
+ return (jsx(MenuList, { collapsible: true, className: className, children: mySonicNavigationItems.map(item => (jsx(MenuListItem, { badge: jsx(item.Icon, {}), ...(item.type === 'action'
10
10
  ? item.action === 'logout'
11
11
  ? { onClick: onLogout }
12
12
  : {}
@@ -0,0 +1 @@
1
+ export declare function OrderHistory(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,166 @@
1
+ "use client";
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
+ import { useRef, useState, useEffect } from 'react';
4
+ import { Link } from '../../../../buttons/link/link.js';
5
+ import { Price } from '../../../../display/price/price.js';
6
+ import { Pagination } from '../../../../filters/pagination/pagination.js';
7
+ import { SearchField } from '../../../../forms/fields/search-field/search-field.js';
8
+ import { SelectField } from '../../../../forms/fields/select-field/select-field.js';
9
+ import { SolidCartIcon } from '../../../../icons/solid/solid-cart-icon.js';
10
+ import { FormattedDate } from '../../../../intl/formatted-date.js';
11
+ import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
12
+ import { useIntl } from '../../../../intl/use-intl.js';
13
+ import { DynamicLoadingOverlay } from '../../../../loading/dynamic-loading-overlay.js';
14
+ import { useFetchOrders } from '../../../../shared/api/storefront/hooks/orders/use-fetch-orders.js';
15
+ import { orderStatuses } from '../../../../shared/api/storefront/model/storefront.model.js';
16
+ import { scrollIntoViewRef } from '../../../../shared/utils/scrolling.js';
17
+ import { DataTable } from '../../../../table/data-table.js';
18
+ import { ErrorPage } from '../../../error-page/error-page.js';
19
+ import styles from './order-history.module.css.js';
20
+
21
+ const dateOptions = {
22
+ day: 'numeric',
23
+ month: 'numeric',
24
+ year: 'numeric',
25
+ };
26
+ function OrderHistory() {
27
+ const t = useFormattedMessage();
28
+ const { cultureCode } = useIntl();
29
+ const orderHistoryRef = useRef(null);
30
+ const [status, setStatus] = useState();
31
+ const [search, setSearch] = useState('');
32
+ const [sort, setSort] = useState();
33
+ const [page, setPage] = useState(1);
34
+ const { data, error, isFetching } = useFetchOrders({
35
+ page,
36
+ pageSize: 20,
37
+ search,
38
+ sort,
39
+ status,
40
+ });
41
+ useEffect(() => {
42
+ scrollIntoViewRef(orderHistoryRef);
43
+ }, [page]);
44
+ if (error)
45
+ return jsx(ErrorPage, { error: error });
46
+ const { orders, pagination } = data ?? {
47
+ orders: [],
48
+ pagination: {},
49
+ };
50
+ const searchOrders = (value) => {
51
+ if (value.length >= 3 || value.length === 0) {
52
+ setPage(1);
53
+ setSearch(value);
54
+ }
55
+ };
56
+ const filterOrders = (value) => {
57
+ if (value === status)
58
+ return;
59
+ setPage(1);
60
+ setStatus(value === 'any' ? undefined : value);
61
+ };
62
+ const filterOptions = orderStatuses.reduce((options, status) => ({
63
+ ...options,
64
+ [status]: t(`orderStatus.${status}`),
65
+ }), { any: t('orderStatus.Any') });
66
+ return (jsx(Fragment, { children: jsxs("section", { ref: orderHistoryRef, className: styles['order-history'], children: [jsx("div", { className: styles['search'], children: jsx(SearchField, { isDebounced: true, label: "Search orders", onChange: searchOrders, placeholder: "Search orders", showLabel: false, variant: "outline" }) }), jsx("div", { className: styles['filter'], children: jsx(SelectField, { label: "Filter order status", onChange: filterOrders, options: filterOptions, selectedOption: status, showLabel: false }) }), jsx("div", { "aria-label": "Results", "aria-live": "polite", className: styles['results'], children: jsx(DynamicLoadingOverlay, { isLoading: isFetching, children: orders && orders.length > 0 ? (jsx(DataTable, { actions: [
67
+ {
68
+ isPrimary: true,
69
+ key: 'reorder',
70
+ label: 'Reorder',
71
+ onAction: order => window?.alert(`Reorder ${order.id}`),
72
+ },
73
+ ], columns: [
74
+ {
75
+ header: {
76
+ label: 'Order#',
77
+ },
78
+ key: 'webOrderNumber',
79
+ props: {
80
+ cssColumn: 'minmax(10ch, min-content)',
81
+ nowrap: true,
82
+ sticky: true,
83
+ },
84
+ sort: { direction: 'DESC', isEnabled: true },
85
+ value: {
86
+ render: order => (jsx(Link, { hasUnderline: true, color: "secondary", href: `/my-sonic/order-history/${order.id}`, onClick: () => window?.alert(`open ${order.id}`), children: order.webOrderNumber })),
87
+ },
88
+ },
89
+ {
90
+ header: { label: 'Date' },
91
+ key: 'orderDate',
92
+ props: {
93
+ cssColumn: 'minmax(13ch, min-content)',
94
+ nowrap: true,
95
+ },
96
+ sort: { isEnabled: true },
97
+ value: {
98
+ render: order => (jsx(FormattedDate, { date: order.orderDate, options: dateOptions })),
99
+ },
100
+ },
101
+ {
102
+ header: { label: 'Total' },
103
+ key: 'orderTotal',
104
+ props: {
105
+ align: 'end',
106
+ cssColumn: 'minmax(12ch, min-content)',
107
+ nowrap: true,
108
+ },
109
+ sort: {
110
+ columnName: 'orderTotal',
111
+ isEnabled: true,
112
+ },
113
+ value: {
114
+ render: order => (jsx(Price, { currencyCode: order.currencyCode, locale: cultureCode, price: order.orderTotal })),
115
+ },
116
+ },
117
+ {
118
+ header: { label: 'Status' },
119
+ key: 'status',
120
+ props: {
121
+ cssColumn: 'minmax(25ch, min-content)',
122
+ nowrap: true,
123
+ },
124
+ value: {
125
+ render: order => t(`orderStatus.${order.status}`),
126
+ },
127
+ },
128
+ {
129
+ header: { label: 'Shipping address' },
130
+ key: 'address',
131
+ props: { cssColumn: 'minmax(25ch, 1fr)', truncated: 2 },
132
+ sort: { columnName: 'stAddress1', isEnabled: true },
133
+ value: {
134
+ render: row => `${row.stAddress1} ${row.shipToPostalCode} ${row.shipToCity} ${row.stCountry.toUpperCase()}`,
135
+ },
136
+ },
137
+ {
138
+ header: { label: 'PO#' },
139
+ key: 'customerPO',
140
+ props: {
141
+ cssColumn: 'minmax(17ch, min-content)',
142
+ truncated: 1,
143
+ },
144
+ sort: { isEnabled: true },
145
+ value: { propertyName: 'customerPO' },
146
+ },
147
+ {
148
+ header: {
149
+ Icon: SolidCartIcon,
150
+ label: 'Reorder',
151
+ },
152
+ key: 'reorder',
153
+ props: { align: 'center', nowrap: true },
154
+ value: { action: 'reorder' },
155
+ },
156
+ ], data: orders, onSort: (key, direction) => {
157
+ if (direction === 'NONE')
158
+ return;
159
+ setSort({
160
+ name: key,
161
+ order: direction,
162
+ });
163
+ } })) : (!isFetching && (jsx("p", { className: styles['no-results'], children: "No orders found." }))) }) }), orders && orders.length > 0 && (jsx("nav", { className: styles['paging'], children: jsx(Pagination, { currentPage: pagination?.currentPage || 1, onChange: page => setPage(page), totalPages: pagination?.numberOfPages || 1 }) })), jsx("div", { className: styles['sticky-bar'], role: "presentation" })] }) }));
164
+ }
165
+
166
+ export { OrderHistory };
@@ -0,0 +1,3 @@
1
+ var styles = {"order-history":"order-history-module-LrkiZ","search":"order-history-module-Y18m7","filter":"order-history-module-tBrZG","results":"order-history-module-5mST2","no-results":"order-history-module-g-FzV","paging":"order-history-module-POsiS","sticky-bar":"order-history-module-98Tvf"};
2
+
3
+ export { styles as default };
@@ -11,7 +11,7 @@ import { FormattedMessage } from '../../../intl/formatted-message.js';
11
11
  import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
12
12
  import { useLanguageCode } from '../../../intl/use-language-code.js';
13
13
  import { PromoBanners } from '../../../promos/promo-banners/promo-banners.js';
14
- import { scrollToTop } from '../../../shared/hooks/use-scroll-to.js';
14
+ import { scrollToTop } from '../../../shared/utils/scrolling.js';
15
15
  import { Sidebar } from '../../../sidebar/sidebar.js';
16
16
  import { ToggleSidebarButton } from '../../../sidebar/toggle-sidebar-button.js';
17
17
  import { Page } from '../../components/page/page.js';
@@ -10,7 +10,7 @@ import { useAlgoliaHits } from '../../../algolia/use-algolia-hits.js';
10
10
  import { FormattedMessage } from '../../../intl/formatted-message.js';
11
11
  import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
12
12
  import { useLanguageCode } from '../../../intl/use-language-code.js';
13
- import { scrollToTop } from '../../../shared/hooks/use-scroll-to.js';
13
+ import { scrollToTop } from '../../../shared/utils/scrolling.js';
14
14
  import { Sidebar } from '../../../sidebar/sidebar.js';
15
15
  import { ToggleSidebarButton } from '../../../sidebar/toggle-sidebar-button.js';
16
16
  import { Page } from '../../components/page/page.js';
@@ -0,0 +1,10 @@
1
+ import { OrderStatus } from '../../model/storefront.model';
2
+ import { SortOption } from '../../services/order-service';
3
+ export declare function useFetchOrders({ enabled, page, pageSize, search, sort, status, }?: {
4
+ enabled?: boolean;
5
+ page: number;
6
+ pageSize: number;
7
+ search?: string;
8
+ sort?: SortOption;
9
+ status?: OrderStatus;
10
+ }): import("@tanstack/react-query").UseQueryResult<import("../../model/storefront.model").OrderCollectionModel, Error>;
@@ -0,0 +1,13 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { fetchOrders } from '../../services/order-service.js';
3
+
4
+ function useFetchOrders({ enabled = true, page = 1, pageSize = 20, search, sort, status, } = { enabled: true, page: 1, pageSize: 20, search: '' }) {
5
+ return useQuery({
6
+ enabled,
7
+ placeholderData: prev => prev,
8
+ queryFn: () => fetchOrders({ page, pageSize, search, sort, status }),
9
+ queryKey: ['orders', page, pageSize, search, sort, status],
10
+ });
11
+ }
12
+
13
+ export { useFetchOrders };
@@ -2255,7 +2255,7 @@ export interface OrderModel extends BaseModel {
2255
2255
  stAddress4: string;
2256
2256
  stCompanyName: string;
2257
2257
  stCountry: string;
2258
- status: string;
2258
+ status: OrderStatus;
2259
2259
  statusDisplay: string;
2260
2260
  taxAmount: number;
2261
2261
  taxAmountDisplay: string;
@@ -3068,3 +3068,15 @@ export interface Country {
3068
3068
  languages: Language[];
3069
3069
  name: string;
3070
3070
  }
3071
+ export declare const orderStatusMappings: {
3072
+ readonly Cancelled: ["Cancelled"];
3073
+ readonly Fulfilled: ["FullyDelivered"];
3074
+ readonly 'Partially fulfilled': ["PartiallyDelivered"];
3075
+ readonly Processing: ["Edited", "ProcessingInWarehouse", "ResubmittedInWarehouse", "SendToWarehouse", "Submitted"];
3076
+ readonly Saved: ["Saved"];
3077
+ readonly 'Waiting for customer service': ["ErrorSendingToWarehouse", "PendingPaymentValidation", "OnHold", "PendingManualVatValidation"];
3078
+ };
3079
+ export type OrderStatus = keyof typeof orderStatusMappings;
3080
+ export declare const orderStatuses: OrderStatus[];
3081
+ export declare function fromApiStatusToOrderStatus(status: string): OrderStatus;
3082
+ export declare const isValidStatus: (status: string | undefined | null) => status is OrderStatus;
@@ -38,5 +38,32 @@ var BadgeStyleValues;
38
38
  BadgeStyleValues["Rectangle"] = "Rectangle";
39
39
  BadgeStyleValues["Round"] = "Round";
40
40
  })(BadgeStyleValues || (BadgeStyleValues = {}));
41
+ const orderStatusMappings = {
42
+ Cancelled: ['Cancelled'],
43
+ Fulfilled: ['FullyDelivered'],
44
+ 'Partially fulfilled': ['PartiallyDelivered'],
45
+ Processing: [
46
+ 'Edited',
47
+ 'ProcessingInWarehouse',
48
+ 'ResubmittedInWarehouse',
49
+ 'SendToWarehouse',
50
+ 'Submitted',
51
+ ],
52
+ Saved: ['Saved'],
53
+ 'Waiting for customer service': [
54
+ 'ErrorSendingToWarehouse',
55
+ 'PendingPaymentValidation',
56
+ 'OnHold',
57
+ 'PendingManualVatValidation',
58
+ ],
59
+ };
60
+ const orderStatuses = Object.keys(orderStatusMappings);
61
+ function fromApiStatusToOrderStatus(status) {
62
+ const orderStatus = Object.entries(orderStatusMappings).find(([, mappedStatuses]) => mappedStatuses.includes(status))?.[0];
63
+ if (!orderStatus)
64
+ throw new Error(`Unknown order status: ${status}`);
65
+ return orderStatus;
66
+ }
67
+ const isValidStatus = (status) => Object.keys(orderStatusMappings).includes(status || '');
41
68
 
42
- export { AvailabilityMessageType, BadgeImagePlacementValues, BadgeStyleValues, BadgeTypeValues, CurrencyPositioningType, VariantDisplayTypeValues };
69
+ export { AvailabilityMessageType, BadgeImagePlacementValues, BadgeStyleValues, BadgeTypeValues, CurrencyPositioningType, VariantDisplayTypeValues, fromApiStatusToOrderStatus, isValidStatus, orderStatusMappings, orderStatuses };
@@ -0,0 +1,12 @@
1
+ import { OrderCollectionModel, OrderStatus } from '../model/storefront.model';
2
+ export interface SortOption {
3
+ name: string;
4
+ order: 'ASC' | 'DESC';
5
+ }
6
+ export declare function fetchOrders({ page, pageSize, search, sort, status, }?: {
7
+ page?: number;
8
+ pageSize?: number;
9
+ search?: string;
10
+ sort?: SortOption;
11
+ status?: OrderStatus;
12
+ }): Promise<OrderCollectionModel>;
@@ -0,0 +1,29 @@
1
+ import { config } from '../../../../config.js';
2
+ import { request } from '../../../fetch/request.js';
3
+ import { orderStatusMappings, fromApiStatusToOrderStatus } from '../model/storefront.model.js';
4
+
5
+ async function fetchOrders({ page = 1, pageSize = 20, search, sort, status, } = {}) {
6
+ const searchParams = new URLSearchParams();
7
+ if (page)
8
+ searchParams.set('page', page.toString());
9
+ if (pageSize)
10
+ searchParams.set('pageSize', pageSize.toString());
11
+ if (search)
12
+ searchParams.set('search', search);
13
+ if (sort)
14
+ searchParams.set('sort', `${sort.name} ${sort.order.toLocaleUpperCase()}`);
15
+ if (status) {
16
+ const mappedStatuses = orderStatusMappings[status];
17
+ mappedStatuses.forEach(mappedStatus => {
18
+ searchParams.append('status', mappedStatus);
19
+ });
20
+ }
21
+ const { body } = await request({
22
+ credentials: 'include',
23
+ url: `${config.SHOP_API_URL}/api/v1/orders/${searchParams.size > 0 ? `?${searchParams.toString()}` : ''}`,
24
+ });
25
+ body.orders?.forEach(order => (order.status = fromApiStatusToOrderStatus(order.status)));
26
+ return body;
27
+ }
28
+
29
+ export { fetchOrders };
@@ -6,9 +6,11 @@ export interface UseIntersectionObserverProps {
6
6
  intersectionObserverInit?: IntersectionObserverInit;
7
7
  isDisabled?: boolean;
8
8
  observables: Observable[];
9
+ onCallback?: (entries: IntersectionObserverEntry[]) => void;
9
10
  onIntersectingChange?: (isIntersecting: boolean) => void;
11
+ threshold?: number[] | number;
10
12
  }
11
- export declare function useIntersectionObserver({ intersectionObserverInit, isDisabled, observables, onIntersectingChange, }: UseIntersectionObserverProps): {
13
+ export declare function useIntersectionObserver({ intersectionObserverInit, isDisabled, observables, onCallback, onIntersectingChange, threshold, }: UseIntersectionObserverProps): {
12
14
  isIntersecting: boolean;
13
15
  };
14
16
  export {};
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useState, useRef, useEffect } from 'react';
3
3
 
4
- function useIntersectionObserver({ intersectionObserverInit, isDisabled, observables, onIntersectingChange, }) {
4
+ function useIntersectionObserver({ intersectionObserverInit, isDisabled, observables, onCallback, onIntersectingChange, threshold = 0, }) {
5
5
  const [isIntersecting, setIntersecting] = useState(false);
6
6
  const state = useRef([]);
7
7
  function disconnectObservers() {
@@ -21,9 +21,10 @@ function useIntersectionObserver({ intersectionObserverInit, isDisabled, observa
21
21
  if (isCurrentlyAnyIntersecting !== isIntersecting) {
22
22
  onIntersectingChange?.(isCurrentlyAnyIntersecting);
23
23
  }
24
+ onCallback?.(entries);
24
25
  }, {
25
26
  rootMargin: '0px',
26
- threshold: 0,
27
+ threshold,
27
28
  ...observable.options,
28
29
  ...intersectionObserverInit,
29
30
  }),
@@ -1,2 +1,5 @@
1
1
  import { CultureCode } from '../../intl/types';
2
- export declare function formatDateToLocaleString(date?: Date, cultureCode?: CultureCode, options?: Intl.DateTimeFormatOptions): string;
2
+ export declare function formatDate(date: Date, cultureCode?: CultureCode, options?: Intl.DateTimeFormatOptions): string;
3
+ export declare function formatDate(date: string, cultureCode?: CultureCode, options?: Intl.DateTimeFormatOptions): string | undefined;
4
+ export declare function formatDate(date: null | undefined, cultureCode?: CultureCode, options?: Intl.DateTimeFormatOptions): undefined;
5
+ export declare function formatDate(date: Date | string | null | undefined, cultureCode?: CultureCode, options?: Intl.DateTimeFormatOptions): string | undefined;
@@ -1,12 +1,13 @@
1
- function formatDateToLocaleString(date, cultureCode, options = {
1
+ function formatDate(date, cultureCode, options = {
2
2
  day: 'numeric',
3
3
  month: 'long',
4
4
  weekday: 'long',
5
5
  year: 'numeric',
6
6
  }) {
7
- if (!date || !cultureCode)
8
- return '';
9
- return date.toLocaleDateString(cultureCode, options);
7
+ if (!date)
8
+ return;
9
+ const formattedDate = new Intl.DateTimeFormat(cultureCode, options).format(date instanceof Date ? date : new Date(date));
10
+ return formattedDate;
10
11
  }
11
12
 
12
- export { formatDateToLocaleString };
13
+ export { formatDate };