@evenicanpm/storefront-core 2.4.2 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +90 -90
- package/src/api-manager/datasources/d365/d365-cart.datasource.ts +4 -3
- package/src/api-manager/datasources/d365/d365-user.datasource.ts +3 -3
- package/src/api-manager/datasources/d365/utils/get-context-cookie.ts +1 -0
- package/src/api-manager/datasources/e4/address/e4-address.datasource.ts +5 -14
- package/src/api-manager/datasources/e4/address/e4-address.translator.ts +4 -3
- package/src/api-manager/datasources/e4/categories/e4-categories.translator.ts +1 -1
- package/src/api-manager/datasources/e4/graphqlRequestSdk.ts +29 -3
- package/src/api-manager/datasources/e4/product/e4-product.translator.ts +1 -1
- package/src/api-manager/index.ts +1 -1
- package/src/api-manager/lib/get-graphql-client.ts +1 -1
- package/src/api-manager/services/cart/mutations/add-discount-code.ts +0 -11
- package/src/api-manager/services/create-query.ts +13 -7
- package/src/api-manager/services/user/mutations/add-to-wishlist.ts +1 -1
- package/src/api-manager/services/user/mutations/remove-from-wishlist.ts +1 -1
- package/src/auth/AUTH GUIDE.md +880 -0
- package/src/cms/blocks/components/featured-categories.tsx +18 -15
- package/src/cms/blocks/components/featured-products.tsx +3 -2
- package/src/cms/blocks/components/footer/data/index.ts +0 -0
- package/src/cms/blocks/components/footer/index.tsx +0 -0
- package/src/cms/blocks/components/footer/sections/footer-app-store.tsx +0 -0
- package/src/cms/blocks/components/footer/sections/footer-contact.tsx +0 -2
- package/src/cms/blocks/components/footer/sections/footer-links.tsx +0 -0
- package/src/cms/blocks/components/footer/sections/footer-logo.tsx +2 -1
- package/src/cms/blocks/components/footer/sections/footer-social-links.tsx +0 -0
- package/src/cms/blocks/components/footer/styles/index.ts +0 -0
- package/src/cms/blocks/components/hero-carousel/index.tsx +0 -0
- package/src/cms/blocks/components/product-carousel/index.tsx +0 -0
- package/src/cms/blocks/components/shared/featured-product-card.tsx +0 -0
- package/src/cms/blocks/components/shared/product-category-item.tsx +0 -0
- package/src/cms/blocks/components/shared/product-grid.tsx +0 -0
- package/src/cms/blocks/components/shared/top-categories-card.tsx +0 -0
- package/src/cms/blocks/components/shared/top-rating-product-card.tsx +0 -0
- package/src/cms/blocks/icons/components/category.tsx +0 -0
- package/src/cms/blocks/icons/components/dotted-star.tsx +0 -0
- package/src/cms/blocks/icons/components/gift-box.tsx +0 -0
- package/src/cms/blocks/icons/components/light.tsx +0 -0
- package/src/cms/blocks/icons/components/new-arrival.tsx +0 -0
- package/src/cms/blocks/icons/components/rank-badge.tsx +0 -0
- package/src/components/SearchInput.stories.tsx +12 -10
- package/src/components/base-layout.tsx +42 -0
- package/src/components/categories/category-list/category-list.tsx +32 -12
- package/src/components/header/__tests__/header.test.tsx +0 -24
- package/src/components/header/components/mobile-header.tsx +16 -8
- package/src/components/header/header.tsx +6 -3
- package/src/components/mini-cart/components/bottom-actions.tsx +7 -2
- package/src/components/mini-cart/components/cart-item.tsx +16 -13
- package/src/components/mini-cart/components/empty-view.tsx +12 -6
- package/src/components/mini-cart/components/top-header.tsx +9 -8
- package/src/components/mini-cart/mini-cart-trigger.tsx +11 -5
- package/src/components/mini-cart/mini-cart.tsx +30 -15
- package/src/components/mobile-navigation/mobile-navigation-bar.tsx +6 -2
- package/src/components/navbar/categories.tsx +8 -2
- package/src/components/navbar/category-based-menu/category-based-menu.tsx +6 -2
- package/src/components/navbar/mega-menu/mega-menu.tsx +22 -14
- package/src/components/navbar/mobile-menu/mobile-menu.test.tsx +8 -11
- package/src/components/navbar/mobile-menu/mobile-menu.tsx +13 -11
- package/src/components/navbar/nav-list/nav-list.tsx +3 -2
- package/src/components/navbar/navbar.tsx +4 -2
- package/src/components/product-cards/product-card/product-card.tsx +50 -26
- package/src/components/product-cards/product-card-plp/product-card.tsx +37 -16
- package/src/components/product-cards/product-card-plp-list/product-card.tsx +38 -16
- package/src/components/product-cards/product-card-search/product-card.tsx +34 -13
- package/src/components/product-dialog/ProductDialog.stories.tsx +20 -18
- package/src/components/product-dialog/compound/product-dialog.tsx +7 -4
- package/src/components/product-dimensions/compound/dimensions-group.tsx +4 -2
- package/src/components/product-dimensions/compound/dimensions.tsx +15 -6
- package/src/components/product-quantity-buttons/compound/quantity-buttons-root.tsx +21 -13
- package/src/components/products-view/compound/products-grid-view.tsx +11 -4
- package/src/components/products-view/compound/products-list-view.tsx +11 -4
- package/src/components/search-bar/compound/search-bar-root.tsx +6 -4
- package/src/components/search-bar/compound/textfield-adornment-category.tsx +25 -8
- package/src/components/search-bar/hooks/use-click-outside.ts +7 -1
- package/src/components/search-bar/hooks/use-search.ts +3 -3
- package/src/components/user/index.ts +3 -0
- package/src/components/user/use-user-auth.ts +163 -0
- package/src/components/user/user.tsx +215 -0
- package/src/components/wishlist-dialogs/add-to-wishlist/AddToWishlist.stories.tsx +20 -15
- package/src/components/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-dialog.tsx +11 -8
- package/src/components/wishlist-dialogs/add-to-wishlist/compound/add-to-wishlist-list.tsx +18 -3
- package/src/components/wishlist-dialogs/add-to-wishlist/index.tsx +0 -1
- package/src/components/wishlist-dialogs/create-wishlist/compound/create-wishlist-dialog.tsx +6 -2
- package/src/hooks/use-overflow-detect.ts +4 -4
- package/src/lib/graphqlRequestSdk.ts +0 -0
- package/src/lib/page-slugs.ts +16 -0
- package/src/pages/account/account-navigation.tsx +7 -14
- package/src/pages/account/account-routes.ts +4 -9
- package/src/pages/account/addresses/address-form.tsx +38 -16
- package/src/pages/account/addresses/address-item.tsx +18 -8
- package/src/pages/account/dashboard-header.tsx +20 -13
- package/src/pages/account/orders/order-history-filters-panel.tsx +21 -20
- package/src/pages/account/orders/order-history-header.tsx +14 -4
- package/src/pages/account/orders/order-history-root.tsx +3 -1
- package/src/pages/account/orders/order-history-row.tsx +12 -4
- package/src/pages/account/orders/order-history-search-and-filter.tsx +88 -59
- package/src/pages/account/orders/order-history-search-dropdown.tsx +26 -9
- package/src/pages/account/orders/order-history-sort.tsx +3 -1
- package/src/pages/account/orders/order-history-table.tsx +27 -5
- package/src/pages/account/orders/order-progress.tsx +12 -6
- package/src/pages/account/orders/order-row.tsx +18 -6
- package/src/pages/account/orders/order-summary.tsx +24 -8
- package/src/pages/account/orders/ordered-products.tsx +15 -5
- package/src/pages/account/profile/user-info.tsx +11 -3
- package/src/pages/account/table-row-skeleton.tsx +1 -1
- package/src/pages/account/wishlist/create-new-list.tsx +33 -9
- package/src/pages/account/wishlist/wishlist-item.tsx +18 -6
- package/src/pages/cart/cart-item.tsx +21 -7
- package/src/pages/cart/checkout-form.tsx +55 -22
- package/src/pages/cart/coupon-entry.tsx +143 -36
- package/src/pages/cart/estimate-shipping.tsx +45 -21
- package/src/pages/checkout/checkout-alt-form/checkout-form.tsx +22 -14
- package/src/pages/checkout/checkout-alt-form/checkout-step.tsx +37 -16
- package/src/pages/checkout/checkout-alt-form/steps/address/address-card.tsx +9 -3
- package/src/pages/checkout/checkout-alt-form/steps/address/delivery-address.tsx +84 -51
- package/src/pages/checkout/checkout-alt-form/steps/address/new-address-form.tsx +41 -19
- package/src/pages/checkout/checkout-alt-form/steps/customer-info/customer-information.tsx +17 -10
- package/src/pages/checkout/checkout-alt-form/steps/payment/payment-details.tsx +15 -6
- package/src/pages/checkout/checkout-alt-form/steps/shipping/delivery-options.tsx +6 -2
- package/src/pages/checkout/checkout-alt-summary/cart-item.tsx +12 -4
- package/src/pages/checkout/checkout-alt-summary/checkout-alt-summary.tsx +12 -5
- package/src/pages/checkout/checkout-alt-summary/list-item.tsx +17 -10
- package/src/pages/confirmation/address.tsx +6 -2
- package/src/pages/confirmation/confirmation-summary.tsx +12 -4
- package/src/pages/confirmation/ordered-products.tsx +12 -4
- package/src/pages/product-details/bopis/store-card/shop-card.tsx +2 -2
- package/src/pages/product-details/bopis/store-card/utils/getDaysResources.ts +1 -1
- package/src/pages/product-details/product-intro/compound/product-info.tsx +41 -18
- package/src/pages/product-details/product-intro/compound/product-intro-images.tsx +18 -12
- package/src/pages/product-details/product-intro/compound/product-intro.tsx +20 -10
- package/src/pages/product-details/product-intro/compound/thumbnail-with-skeleton.tsx +1 -1
- package/src/pages/product-details/product-tabs.tsx +20 -12
- package/src/pages/product-list/product-list-view.tsx +4 -2
- package/src/pages/product-list/search-bar.tsx +7 -7
- package/src/pages/product-list/side-nav.tsx +5 -3
- package/src/pages/quickorder/order-upload.tsx +1 -1
- package/src/pages/quickorder/provider.tsx +26 -14
- package/src/pages/quickorder/quick-order.tsx +49 -22
- package/src/providers/nav-provider/index.tsx +16 -11
- package/tsconfig.json +0 -5
- package/src/components/header/components/user.tsx +0 -322
- /package/src/components/{header → user}/__tests__/user.test.tsx +0 -0
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
SalesStatus,
|
|
5
5
|
} from "@msdyn365-commerce/retail-proxy";
|
|
6
6
|
import { Box } from "@mui/material";
|
|
7
|
-
import { createContext, useContext, useState } from "react";
|
|
7
|
+
import { createContext, useContext, useMemo, useState } from "react";
|
|
8
8
|
import {
|
|
9
9
|
type CreatedDateFilter,
|
|
10
10
|
FilterSourceType,
|
|
@@ -226,10 +226,8 @@ type OrdersSearchAndFilterContextType = {
|
|
|
226
226
|
selectedOrigins: OriginFilter[];
|
|
227
227
|
handleSelectOrigin: (origin: OriginFilter) => void;
|
|
228
228
|
createdDate?: CreatedDateFilter;
|
|
229
|
-
handleSelectCreatedDate: (
|
|
230
|
-
|
|
231
|
-
toggle?: boolean,
|
|
232
|
-
) => void;
|
|
229
|
+
handleSelectCreatedDate: (date: CreatedDateFilter | undefined) => void;
|
|
230
|
+
handleSetCreatedDate: (date: CreatedDateFilter | undefined) => void;
|
|
233
231
|
orderStatus?: OrderStatusFilter;
|
|
234
232
|
handleSelectOrderStatus: (status: OrderStatusFilter | undefined) => void;
|
|
235
233
|
|
|
@@ -291,15 +289,12 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
291
289
|
});
|
|
292
290
|
};
|
|
293
291
|
|
|
294
|
-
const handleSelectCreatedDate = (
|
|
295
|
-
date
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
prev?.label === date?.label ? undefined : date,
|
|
301
|
-
)
|
|
302
|
-
: setCreatedDate(date);
|
|
292
|
+
const handleSelectCreatedDate = (date: CreatedDateFilter | undefined) => {
|
|
293
|
+
setCreatedDate((prev) => (prev?.label === date?.label ? undefined : date));
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const handleSetCreatedDate = (date: CreatedDateFilter | undefined) => {
|
|
297
|
+
setCreatedDate(date);
|
|
303
298
|
};
|
|
304
299
|
|
|
305
300
|
const handleSelectOrderStatus = (status: OrderStatusFilter | undefined) => {
|
|
@@ -313,6 +308,47 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
313
308
|
setOrderSearchCriteria(searchCriteria);
|
|
314
309
|
};
|
|
315
310
|
|
|
311
|
+
const applySearchTextCriteria = (
|
|
312
|
+
orderSearchCriteria: OrderSearchCriteria,
|
|
313
|
+
): void => {
|
|
314
|
+
if (!searchText) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (selectedSearchOption === 0) {
|
|
319
|
+
orderSearchCriteria.ChannelReferenceId = searchText;
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (selectedSearchOption === 1) {
|
|
324
|
+
orderSearchCriteria.SalesId = searchText;
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (selectedSearchOption === 2) {
|
|
329
|
+
const channelIds = stores
|
|
330
|
+
?.filter((store) =>
|
|
331
|
+
store.location.OrgUnitName?.toLocaleLowerCase().includes(
|
|
332
|
+
searchText.toLowerCase(),
|
|
333
|
+
),
|
|
334
|
+
)
|
|
335
|
+
.map((store) => store.location.ChannelId)
|
|
336
|
+
.filter((id): id is number => id !== undefined);
|
|
337
|
+
|
|
338
|
+
if (channelIds?.length) {
|
|
339
|
+
if (orderSearchCriteria.ChannelIds?.length) {
|
|
340
|
+
const intersectingChannelIds = channelIds.filter((id) =>
|
|
341
|
+
orderSearchCriteria.ChannelIds?.includes(id),
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
orderSearchCriteria.ChannelIds = intersectingChannelIds;
|
|
345
|
+
} else {
|
|
346
|
+
orderSearchCriteria.ChannelIds = channelIds;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
316
352
|
const createSearchCriteria = (): OrderSearchCriteria => {
|
|
317
353
|
const orderSearchCriteria: OrderSearchCriteria = {};
|
|
318
354
|
|
|
@@ -322,7 +358,7 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
322
358
|
}
|
|
323
359
|
const salesStatus = orderStatus?.value ?? undefined;
|
|
324
360
|
const salesStatuses: SalesStatus[] =
|
|
325
|
-
salesStatus
|
|
361
|
+
salesStatus === undefined ? [] : [salesStatus];
|
|
326
362
|
if (salesStatuses.length > 0) {
|
|
327
363
|
orderSearchCriteria.OrderStatusValues = salesStatuses;
|
|
328
364
|
}
|
|
@@ -333,34 +369,7 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
333
369
|
orderSearchCriteria.EndDateTime = endDate;
|
|
334
370
|
}
|
|
335
371
|
|
|
336
|
-
|
|
337
|
-
if (selectedSearchOption === 0) {
|
|
338
|
-
orderSearchCriteria.ChannelReferenceId = searchText;
|
|
339
|
-
} else if (selectedSearchOption === 1) {
|
|
340
|
-
orderSearchCriteria.SalesId = searchText;
|
|
341
|
-
} else if (selectedSearchOption === 2) {
|
|
342
|
-
const channelIds = stores
|
|
343
|
-
?.filter((store) =>
|
|
344
|
-
store.location.OrgUnitName?.toLocaleLowerCase().includes(
|
|
345
|
-
searchText.toLowerCase(),
|
|
346
|
-
),
|
|
347
|
-
)
|
|
348
|
-
.map((store) => store.location.ChannelId)
|
|
349
|
-
.filter((id): id is number => id !== undefined);
|
|
350
|
-
|
|
351
|
-
if (channelIds?.length) {
|
|
352
|
-
if (orderSearchCriteria.ChannelIds?.length) {
|
|
353
|
-
const intersectingChannelIds = channelIds.filter((id) =>
|
|
354
|
-
orderSearchCriteria.ChannelIds?.includes(id),
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
orderSearchCriteria.ChannelIds = intersectingChannelIds;
|
|
358
|
-
} else {
|
|
359
|
-
orderSearchCriteria.ChannelIds = channelIds;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
372
|
+
applySearchTextCriteria(orderSearchCriteria);
|
|
364
373
|
|
|
365
374
|
return orderSearchCriteria;
|
|
366
375
|
};
|
|
@@ -395,7 +404,9 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
395
404
|
Number.isNaN(customStart.getTime()) ||
|
|
396
405
|
Number.isNaN(customEnd.getTime())
|
|
397
406
|
) {
|
|
398
|
-
throw new
|
|
407
|
+
throw new TypeError(
|
|
408
|
+
"Invalid date format in customized date range.",
|
|
409
|
+
);
|
|
399
410
|
}
|
|
400
411
|
|
|
401
412
|
startDate.setTime(customStart.getTime());
|
|
@@ -407,7 +418,9 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
407
418
|
}
|
|
408
419
|
break;
|
|
409
420
|
default:
|
|
410
|
-
throw new Error(
|
|
421
|
+
throw new Error(
|
|
422
|
+
`Unsupported date filter option: ${option?.label ?? "unknown"}`,
|
|
423
|
+
);
|
|
411
424
|
}
|
|
412
425
|
|
|
413
426
|
return { startDate, endDate };
|
|
@@ -421,20 +434,36 @@ const OrdersSearchAndFilter = ({ children }: { children: React.ReactNode }) => {
|
|
|
421
434
|
: new Date(year, month - 1, day, 0, 0, 0, 0);
|
|
422
435
|
};
|
|
423
436
|
|
|
424
|
-
const value =
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
437
|
+
const value = useMemo(
|
|
438
|
+
() => ({
|
|
439
|
+
searchText,
|
|
440
|
+
setSearchText,
|
|
441
|
+
selectedSearchOption,
|
|
442
|
+
setSelectedSearchOption,
|
|
443
|
+
originOptions,
|
|
444
|
+
selectedOrigins,
|
|
445
|
+
handleSelectOrigin,
|
|
446
|
+
createdDate,
|
|
447
|
+
handleSelectCreatedDate,
|
|
448
|
+
handleSetCreatedDate,
|
|
449
|
+
orderStatus,
|
|
450
|
+
handleSelectOrderStatus,
|
|
451
|
+
executeSearch,
|
|
452
|
+
}),
|
|
453
|
+
[
|
|
454
|
+
searchText,
|
|
455
|
+
selectedSearchOption,
|
|
456
|
+
originOptions,
|
|
457
|
+
selectedOrigins,
|
|
458
|
+
handleSelectOrigin,
|
|
459
|
+
createdDate,
|
|
460
|
+
handleSelectCreatedDate,
|
|
461
|
+
handleSetCreatedDate,
|
|
462
|
+
orderStatus,
|
|
463
|
+
handleSelectOrderStatus,
|
|
464
|
+
executeSearch,
|
|
465
|
+
],
|
|
466
|
+
);
|
|
438
467
|
|
|
439
468
|
return (
|
|
440
469
|
<OrdersSearchAndFilterContext.Provider value={value}>
|
|
@@ -14,11 +14,31 @@ interface Props {
|
|
|
14
14
|
searchOptions: DisplaySearchOption[];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
const SearchOptionItem = ({
|
|
18
|
+
item,
|
|
19
|
+
onClose,
|
|
20
|
+
handleChange,
|
|
21
|
+
}: {
|
|
22
|
+
item: DisplaySearchOption;
|
|
23
|
+
onClose: () => void;
|
|
24
|
+
handleChange: (optionId: number) => void;
|
|
25
|
+
}) => (
|
|
26
|
+
<MenuItem
|
|
27
|
+
key={item.id}
|
|
28
|
+
onClick={() => {
|
|
29
|
+
handleChange(item.id);
|
|
30
|
+
onClose();
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
33
|
+
{item.name}
|
|
34
|
+
</MenuItem>
|
|
35
|
+
);
|
|
36
|
+
|
|
17
37
|
export default function OrdersSearchDropdown({
|
|
18
38
|
title,
|
|
19
39
|
handleChange,
|
|
20
40
|
searchOptions,
|
|
21
|
-
}: Props) {
|
|
41
|
+
}: Readonly<Props>) {
|
|
22
42
|
const { breakpoints } = useTheme();
|
|
23
43
|
const _searchOptions = Array.isArray(searchOptions) ? searchOptions : [];
|
|
24
44
|
const options: DisplaySearchOption[] = [
|
|
@@ -37,15 +57,12 @@ export default function OrdersSearchDropdown({
|
|
|
37
57
|
)}
|
|
38
58
|
options={(onClose) => {
|
|
39
59
|
return options.map((item: DisplaySearchOption) => (
|
|
40
|
-
<
|
|
60
|
+
<SearchOptionItem
|
|
41
61
|
key={item.id}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
>
|
|
47
|
-
{item.name}
|
|
48
|
-
</MenuItem>
|
|
62
|
+
item={item}
|
|
63
|
+
onClose={onClose}
|
|
64
|
+
handleChange={handleChange}
|
|
65
|
+
/>
|
|
49
66
|
));
|
|
50
67
|
}}
|
|
51
68
|
/>
|
|
@@ -41,7 +41,9 @@ interface OrderSortProps {
|
|
|
41
41
|
setSortColumn: (selectedSortColumn: SortColumn) => void;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export default function OrdersSort({
|
|
44
|
+
export default function OrdersSort({
|
|
45
|
+
setSortColumn,
|
|
46
|
+
}: Readonly<OrderSortProps>) {
|
|
45
47
|
const [selectedSort, setSelectedSort] = useState<number>(0);
|
|
46
48
|
const t = useTranslations("Account.Orders");
|
|
47
49
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { SalesOrder } from "@evenicanpm/storefront-core/src/api-manager/schemas/order.schema";
|
|
1
2
|
import NoRecords from "@evenicanpm/storefront-core/src/components/no-records";
|
|
2
3
|
import { Box, CircularProgress } from "@mui/material";
|
|
3
|
-
import { cloneElement, Fragment } from "react";
|
|
4
|
+
import { cloneElement, Fragment, useMemo } from "react";
|
|
4
5
|
import OrderHistoryHeader from "./order-history-header";
|
|
5
6
|
import OrdersPagination from "./order-history-pagination";
|
|
6
7
|
import { useOrderHistory } from "./order-history-root";
|
|
@@ -8,11 +9,30 @@ import OrderHistoryRow, {
|
|
|
8
9
|
OrderHistoryTableRowContext,
|
|
9
10
|
} from "./order-history-row";
|
|
10
11
|
|
|
12
|
+
const OrderHistoryTableRowProvider = ({
|
|
13
|
+
order,
|
|
14
|
+
children,
|
|
15
|
+
}: {
|
|
16
|
+
order: SalesOrder;
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
}) => {
|
|
19
|
+
const contextValue = useMemo(() => ({ order }), [order]);
|
|
20
|
+
return (
|
|
21
|
+
<OrderHistoryTableRowContext.Provider value={contextValue}>
|
|
22
|
+
{children}
|
|
23
|
+
</OrderHistoryTableRowContext.Provider>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
11
27
|
const OrderHistoryTable = ({ children }: { children: React.ReactNode }) => {
|
|
12
28
|
return <>{children}</>;
|
|
13
29
|
};
|
|
14
30
|
|
|
15
|
-
|
|
31
|
+
const OrderHistoryTableList = ({
|
|
32
|
+
children,
|
|
33
|
+
}: {
|
|
34
|
+
children: React.ReactElement;
|
|
35
|
+
}) => {
|
|
16
36
|
const { orders, isLoading } = useOrderHistory();
|
|
17
37
|
|
|
18
38
|
if (isLoading) {
|
|
@@ -30,12 +50,12 @@ OrderHistoryTable.List = ({ children }: { children: React.ReactElement }) => {
|
|
|
30
50
|
return (
|
|
31
51
|
<Fragment>
|
|
32
52
|
{orders.map((order, index) => (
|
|
33
|
-
<
|
|
53
|
+
<OrderHistoryTableRowProvider
|
|
34
54
|
key={order.RecordId ?? index}
|
|
35
|
-
|
|
55
|
+
order={order}
|
|
36
56
|
>
|
|
37
57
|
{cloneElement(children)}
|
|
38
|
-
</
|
|
58
|
+
</OrderHistoryTableRowProvider>
|
|
39
59
|
))}
|
|
40
60
|
<Box mt={4}>
|
|
41
61
|
<OrderHistoryTable.Pagination>
|
|
@@ -47,6 +67,8 @@ OrderHistoryTable.List = ({ children }: { children: React.ReactElement }) => {
|
|
|
47
67
|
);
|
|
48
68
|
};
|
|
49
69
|
|
|
70
|
+
OrderHistoryTable.List = OrderHistoryTableList;
|
|
71
|
+
|
|
50
72
|
OrderHistoryTable.Header = OrderHistoryHeader;
|
|
51
73
|
OrderHistoryTable.Row = OrderHistoryRow;
|
|
52
74
|
OrderHistoryTable.Pagination = OrdersPagination;
|
|
@@ -13,7 +13,7 @@ import Box from "@mui/material/Box";
|
|
|
13
13
|
import Card from "@mui/material/Card";
|
|
14
14
|
import styled from "@mui/material/styles/styled";
|
|
15
15
|
import { useTranslations } from "next-intl";
|
|
16
|
-
import { createContext, Fragment, useContext } from "react";
|
|
16
|
+
import { createContext, Fragment, useContext, useMemo } from "react";
|
|
17
17
|
import { MdDone as Done } from "react-icons/md";
|
|
18
18
|
|
|
19
19
|
// STYLED COMPONENTS
|
|
@@ -59,18 +59,20 @@ const OrderProgress = ({
|
|
|
59
59
|
}: React.PropsWithChildren<Props>) => {
|
|
60
60
|
const STEP_ICONS = [PackageBox, TruckFilled, Delivery];
|
|
61
61
|
const STATUS_LIST = ["Packaging", "Shipping", "Delivering", "Complete"];
|
|
62
|
+
const contextValue = useMemo(
|
|
63
|
+
() => ({ status, stepIcons: STEP_ICONS, statusList: STATUS_LIST }),
|
|
64
|
+
[status],
|
|
65
|
+
);
|
|
62
66
|
|
|
63
67
|
return (
|
|
64
|
-
<OrderProgressContext.Provider
|
|
65
|
-
value={{ status, stepIcons: STEP_ICONS, statusList: STATUS_LIST }}
|
|
66
|
-
>
|
|
68
|
+
<OrderProgressContext.Provider value={contextValue}>
|
|
67
69
|
<Card sx={{ p: "2rem 1.5rem", mb: 4 }}>{children}</Card>
|
|
68
70
|
</OrderProgressContext.Provider>
|
|
69
71
|
);
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
// SUBCOMPONENTS
|
|
73
|
-
|
|
75
|
+
const OrderProgressSteps = () => {
|
|
74
76
|
const context = useContext(OrderProgressContext);
|
|
75
77
|
if (!context) return null;
|
|
76
78
|
|
|
@@ -118,7 +120,9 @@ OrderProgress.Steps = () => {
|
|
|
118
120
|
);
|
|
119
121
|
};
|
|
120
122
|
|
|
121
|
-
OrderProgress.
|
|
123
|
+
OrderProgress.Steps = OrderProgressSteps;
|
|
124
|
+
|
|
125
|
+
const OrderProgressDeliveryDate = () => {
|
|
122
126
|
const t = useTranslations("Account.OrderDetails");
|
|
123
127
|
const context = useContext(OrderProgressContext);
|
|
124
128
|
if (!context) return null;
|
|
@@ -150,4 +154,6 @@ OrderProgress.DeliveryDate = () => {
|
|
|
150
154
|
);
|
|
151
155
|
};
|
|
152
156
|
|
|
157
|
+
OrderProgress.DeliveryDate = OrderProgressDeliveryDate;
|
|
158
|
+
|
|
153
159
|
export default OrderProgress;
|
|
@@ -12,7 +12,7 @@ import IconButton from "@mui/material/IconButton";
|
|
|
12
12
|
import { format } from "date-fns";
|
|
13
13
|
import Link from "next/link";
|
|
14
14
|
import type React from "react";
|
|
15
|
-
import { createContext, useContext } from "react";
|
|
15
|
+
import { createContext, useContext, useMemo } from "react";
|
|
16
16
|
import { MdEast as East } from "react-icons/md";
|
|
17
17
|
|
|
18
18
|
type Props = { order: SalesOrder };
|
|
@@ -36,9 +36,13 @@ const OrderRowContext = createContext<{
|
|
|
36
36
|
|
|
37
37
|
const OrderRow = ({ order, children }: React.PropsWithChildren<Props>) => {
|
|
38
38
|
const { formatCurrency } = useCurrencyFormatter();
|
|
39
|
+
const contextValue = useMemo(
|
|
40
|
+
() => ({ order, formatCurrency }),
|
|
41
|
+
[order, formatCurrency],
|
|
42
|
+
);
|
|
39
43
|
|
|
40
44
|
return (
|
|
41
|
-
<OrderRowContext.Provider value={
|
|
45
|
+
<OrderRowContext.Provider value={contextValue}>
|
|
42
46
|
<Link href={`/account/orders/${order.SalesId}`}>
|
|
43
47
|
<TableRow sx={{ gridTemplateColumns: "2fr 1fr 1fr 1fr 1fr" }}>
|
|
44
48
|
{children}
|
|
@@ -48,14 +52,16 @@ const OrderRow = ({ order, children }: React.PropsWithChildren<Props>) => {
|
|
|
48
52
|
);
|
|
49
53
|
};
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
const OrderRowOrderNumber = () => {
|
|
52
56
|
const context = useContext(OrderRowContext);
|
|
53
57
|
if (!context) return null;
|
|
54
58
|
const { order } = context;
|
|
55
59
|
return <H6 ellipsis>{order?.ChannelReferenceId}</H6>;
|
|
56
60
|
};
|
|
57
61
|
|
|
58
|
-
OrderRow.
|
|
62
|
+
OrderRow.OrderNumber = OrderRowOrderNumber;
|
|
63
|
+
|
|
64
|
+
const OrderRowStatus = () => {
|
|
59
65
|
const context = useContext(OrderRowContext);
|
|
60
66
|
if (!context) return null;
|
|
61
67
|
const { order } = context;
|
|
@@ -67,7 +73,9 @@ OrderRow.Status = () => {
|
|
|
67
73
|
);
|
|
68
74
|
};
|
|
69
75
|
|
|
70
|
-
OrderRow.
|
|
76
|
+
OrderRow.Status = OrderRowStatus;
|
|
77
|
+
|
|
78
|
+
const OrderRowDate = () => {
|
|
71
79
|
const context = useContext(OrderRowContext);
|
|
72
80
|
if (!context) return null;
|
|
73
81
|
const { order } = context;
|
|
@@ -78,7 +86,9 @@ OrderRow.Date = () => {
|
|
|
78
86
|
);
|
|
79
87
|
};
|
|
80
88
|
|
|
81
|
-
OrderRow.
|
|
89
|
+
OrderRow.Date = OrderRowDate;
|
|
90
|
+
|
|
91
|
+
const OrderRowTotal = () => {
|
|
82
92
|
const context = useContext(OrderRowContext);
|
|
83
93
|
if (!context) return null;
|
|
84
94
|
const { order, formatCurrency } = context;
|
|
@@ -89,6 +99,8 @@ OrderRow.Total = () => {
|
|
|
89
99
|
);
|
|
90
100
|
};
|
|
91
101
|
|
|
102
|
+
OrderRow.Total = OrderRowTotal;
|
|
103
|
+
|
|
92
104
|
OrderRow.Action = () => {
|
|
93
105
|
return (
|
|
94
106
|
<Box display={{ sm: "inline-flex", xs: "none" }} justifyContent="end">
|
|
@@ -11,7 +11,7 @@ import Divider from "@mui/material/Divider";
|
|
|
11
11
|
import Grid from "@mui/material/Grid2";
|
|
12
12
|
import { useTranslations } from "next-intl";
|
|
13
13
|
import type React from "react";
|
|
14
|
-
import { createContext, useContext } from "react";
|
|
14
|
+
import { createContext, useContext, useMemo } from "react";
|
|
15
15
|
|
|
16
16
|
type Props = { order: SalesOrder };
|
|
17
17
|
|
|
@@ -23,9 +23,13 @@ const OrderSummaryContext = createContext<{
|
|
|
23
23
|
// Compound Component
|
|
24
24
|
const OrderSummary = ({ order, children }: React.PropsWithChildren<Props>) => {
|
|
25
25
|
const { formatCurrency } = useCurrencyFormatter();
|
|
26
|
+
const contextValue = useMemo(
|
|
27
|
+
() => ({ order, formatCurrency }),
|
|
28
|
+
[order, formatCurrency],
|
|
29
|
+
);
|
|
26
30
|
|
|
27
31
|
return (
|
|
28
|
-
<OrderSummaryContext.Provider value={
|
|
32
|
+
<OrderSummaryContext.Provider value={contextValue}>
|
|
29
33
|
<Grid container spacing={3}>
|
|
30
34
|
{children}
|
|
31
35
|
</Grid>
|
|
@@ -47,7 +51,7 @@ OrderSummary.SummaryWrapper = ({ children }: { children: React.ReactNode }) => (
|
|
|
47
51
|
);
|
|
48
52
|
|
|
49
53
|
// Subcomponents
|
|
50
|
-
|
|
54
|
+
const OrderSummaryAddressHeading = () => {
|
|
51
55
|
const t = useTranslations("Account.OrderDetails");
|
|
52
56
|
return (
|
|
53
57
|
<H5 mt={0} mb={2}>
|
|
@@ -56,7 +60,9 @@ OrderSummary.AddressHeading = () => {
|
|
|
56
60
|
);
|
|
57
61
|
};
|
|
58
62
|
|
|
59
|
-
OrderSummary.
|
|
63
|
+
OrderSummary.AddressHeading = OrderSummaryAddressHeading;
|
|
64
|
+
|
|
65
|
+
const OrderSummaryAddressContent = () => {
|
|
60
66
|
const context = useContext(OrderSummaryContext);
|
|
61
67
|
if (!context) return null;
|
|
62
68
|
const { order } = context;
|
|
@@ -70,7 +76,9 @@ OrderSummary.AddressContent = () => {
|
|
|
70
76
|
);
|
|
71
77
|
};
|
|
72
78
|
|
|
73
|
-
OrderSummary.
|
|
79
|
+
OrderSummary.AddressContent = OrderSummaryAddressContent;
|
|
80
|
+
|
|
81
|
+
const OrderSummarySummaryHeading = () => {
|
|
74
82
|
const t = useTranslations("Account.OrderDetails");
|
|
75
83
|
return (
|
|
76
84
|
<H5 mt={0} mb={2}>
|
|
@@ -79,7 +87,9 @@ OrderSummary.SummaryHeading = () => {
|
|
|
79
87
|
);
|
|
80
88
|
};
|
|
81
89
|
|
|
82
|
-
OrderSummary.
|
|
90
|
+
OrderSummary.SummaryHeading = OrderSummarySummaryHeading;
|
|
91
|
+
|
|
92
|
+
const OrderSummaryListItem = ({
|
|
83
93
|
title,
|
|
84
94
|
property,
|
|
85
95
|
}: {
|
|
@@ -101,9 +111,11 @@ OrderSummary.ListItem = ({
|
|
|
101
111
|
);
|
|
102
112
|
};
|
|
103
113
|
|
|
114
|
+
OrderSummary.ListItem = OrderSummaryListItem;
|
|
115
|
+
|
|
104
116
|
OrderSummary.Divider = Divider;
|
|
105
117
|
|
|
106
|
-
|
|
118
|
+
const OrderSummaryTotal = () => {
|
|
107
119
|
const t = useTranslations("Account.OrderDetails");
|
|
108
120
|
const context = useContext(OrderSummaryContext);
|
|
109
121
|
if (!context) return null;
|
|
@@ -117,9 +129,13 @@ OrderSummary.Total = () => {
|
|
|
117
129
|
);
|
|
118
130
|
};
|
|
119
131
|
|
|
120
|
-
OrderSummary.
|
|
132
|
+
OrderSummary.Total = OrderSummaryTotal;
|
|
133
|
+
|
|
134
|
+
const OrderSummaryPaidBy = ({ children }: { children?: React.ReactNode }) => {
|
|
121
135
|
const t = useTranslations("Account.OrderDetails");
|
|
122
136
|
return <Paragraph>{children ?? t("paidBy")}</Paragraph>;
|
|
123
137
|
};
|
|
124
138
|
|
|
139
|
+
OrderSummary.PaidBy = OrderSummaryPaidBy;
|
|
140
|
+
|
|
125
141
|
export default OrderSummary;
|
|
@@ -22,7 +22,7 @@ import Grid from "@mui/material/Grid2";
|
|
|
22
22
|
import Link from "next/link";
|
|
23
23
|
import { useTranslations } from "next-intl";
|
|
24
24
|
import type React from "react";
|
|
25
|
-
import { createContext } from "react";
|
|
25
|
+
import { createContext, useMemo } from "react";
|
|
26
26
|
|
|
27
27
|
type Props = { order: SalesOrder };
|
|
28
28
|
|
|
@@ -36,8 +36,12 @@ const OrderedProducts = ({
|
|
|
36
36
|
children,
|
|
37
37
|
}: React.PropsWithChildren<Props>) => {
|
|
38
38
|
const { formatCurrency } = useCurrencyFormatter();
|
|
39
|
+
const contextValue = useMemo(
|
|
40
|
+
() => ({ order, formatCurrency }),
|
|
41
|
+
[order, formatCurrency],
|
|
42
|
+
);
|
|
39
43
|
return (
|
|
40
|
-
<OrderedProductsContext.Provider value={
|
|
44
|
+
<OrderedProductsContext.Provider value={contextValue}>
|
|
41
45
|
<Card sx={{ p: 0, mb: "30px" }}>{children}</Card>
|
|
42
46
|
</OrderedProductsContext.Provider>
|
|
43
47
|
);
|
|
@@ -50,7 +54,7 @@ OrderedProducts.Header = ({ children }: React.PropsWithChildren) => (
|
|
|
50
54
|
</FlexBetween>
|
|
51
55
|
);
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
const OrderedProductsHeaderItem = ({
|
|
54
58
|
title,
|
|
55
59
|
value,
|
|
56
60
|
}: {
|
|
@@ -66,6 +70,8 @@ OrderedProducts.HeaderItem = ({
|
|
|
66
70
|
);
|
|
67
71
|
};
|
|
68
72
|
|
|
73
|
+
OrderedProducts.HeaderItem = OrderedProductsHeaderItem;
|
|
74
|
+
|
|
69
75
|
OrderedProducts.List = ({ children }: React.PropsWithChildren) => (
|
|
70
76
|
<Grid container spacing={2} padding={"20px 15px 10px"} alignItems={"center"}>
|
|
71
77
|
{children}
|
|
@@ -120,7 +126,7 @@ OrderedProducts.Title = ({ item }: { item: SalesLine }) => {
|
|
|
120
126
|
return <H6>{item?.Product?.Name}</H6>;
|
|
121
127
|
};
|
|
122
128
|
|
|
123
|
-
|
|
129
|
+
const OrderedProductsPrice = ({ item }: { item: SalesLine }) => {
|
|
124
130
|
const { formatCurrency } = useCurrencyFormatter();
|
|
125
131
|
return (
|
|
126
132
|
<Paragraph color="grey.600">
|
|
@@ -129,6 +135,8 @@ OrderedProducts.Price = ({ item }: { item: SalesLine }) => {
|
|
|
129
135
|
);
|
|
130
136
|
};
|
|
131
137
|
|
|
138
|
+
OrderedProducts.Price = OrderedProductsPrice;
|
|
139
|
+
|
|
132
140
|
OrderedProducts.Dimensions = ({ item }: { item: SalesLine }) => {
|
|
133
141
|
if (!item.Product?.Dimensions?.length) {
|
|
134
142
|
return (
|
|
@@ -150,7 +158,7 @@ OrderedProducts.Dimensions = ({ item }: { item: SalesLine }) => {
|
|
|
150
158
|
);
|
|
151
159
|
};
|
|
152
160
|
|
|
153
|
-
|
|
161
|
+
const OrderedProductsReviewButton = () => {
|
|
154
162
|
const t = useTranslations("Account.OrderDetails");
|
|
155
163
|
return (
|
|
156
164
|
<Grid size={{ xs: 4, sm: 3 }}>
|
|
@@ -163,4 +171,6 @@ OrderedProducts.ReviewButton = () => {
|
|
|
163
171
|
);
|
|
164
172
|
};
|
|
165
173
|
|
|
174
|
+
OrderedProducts.ReviewButton = OrderedProductsReviewButton;
|
|
175
|
+
|
|
166
176
|
export default OrderedProducts;
|
|
@@ -12,7 +12,12 @@ import Card from "@mui/material/Card";
|
|
|
12
12
|
import type { Theme } from "@mui/material/styles";
|
|
13
13
|
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
14
14
|
import { useTranslations } from "next-intl";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
createContext,
|
|
17
|
+
type PropsWithChildren,
|
|
18
|
+
useContext,
|
|
19
|
+
useMemo,
|
|
20
|
+
} from "react";
|
|
16
21
|
|
|
17
22
|
interface UserInfoContextValue {
|
|
18
23
|
user: User;
|
|
@@ -26,9 +31,10 @@ interface UserInfoProps extends PropsWithChildren {
|
|
|
26
31
|
|
|
27
32
|
const UserInfo = ({ user, children }: UserInfoProps) => {
|
|
28
33
|
const downMd = useMediaQuery((theme: Theme) => theme.breakpoints.down("sm"));
|
|
34
|
+
const contextValue = useMemo(() => ({ user }), [user]);
|
|
29
35
|
|
|
30
36
|
return (
|
|
31
|
-
<UserInfoContext.Provider value={
|
|
37
|
+
<UserInfoContext.Provider value={contextValue}>
|
|
32
38
|
<Card
|
|
33
39
|
sx={{
|
|
34
40
|
mt: 3,
|
|
@@ -59,7 +65,7 @@ interface ItemProps {
|
|
|
59
65
|
transform?: (val: string) => string;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
const UserInfoItem = ({ title, field, value, transform }: ItemProps) => {
|
|
63
69
|
const ctx = useContext(UserInfoContext);
|
|
64
70
|
const t = useTranslations("Account.Profile");
|
|
65
71
|
if (!ctx) return null;
|
|
@@ -85,4 +91,6 @@ UserInfo.Item = ({ title, field, value, transform }: ItemProps) => {
|
|
|
85
91
|
);
|
|
86
92
|
};
|
|
87
93
|
|
|
94
|
+
UserInfo.Item = UserInfoItem;
|
|
95
|
+
|
|
88
96
|
export default UserInfo;
|
|
@@ -9,7 +9,7 @@ interface TableRowSkeletonProps {
|
|
|
9
9
|
|
|
10
10
|
export default function TableRowSkeleton({
|
|
11
11
|
sx = { gridTemplateColumns: "2fr 1fr 1fr 1fr 1fr" },
|
|
12
|
-
}: TableRowSkeletonProps) {
|
|
12
|
+
}: Readonly<TableRowSkeletonProps>) {
|
|
13
13
|
return (
|
|
14
14
|
<TableRow sx={sx}>
|
|
15
15
|
<Skeleton variant="text" width="60%" />
|