@evenicanpm/storefront-core 2.2.0 → 2.3.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/package.json +7 -3
- package/src/api-manager/README.md +52 -27
- package/src/api-manager/datasources/d365/d365-cart.datasource.ts +166 -17
- package/src/api-manager/datasources/d365/d365-invoice.datasource.ts +100 -0
- package/src/api-manager/datasources/d365/d365-order.datasource.ts +75 -18
- package/src/api-manager/datasources/d365/d365-product.datasource.ts +19 -1
- package/src/api-manager/datasources/d365/d365-user.datasource.ts +96 -22
- package/src/api-manager/datasources/d365/d365.datasource.ts +3 -0
- package/src/api-manager/datasources/d365/utils/get-context-cookie.ts +10 -3
- package/src/api-manager/datasources/e4/e4.datasource.ts +9 -0
- package/src/api-manager/datasources/e4/order/e4-order.datasource.ts +7 -4
- package/src/api-manager/datasources/e4/user/e4-user.datasource.ts +4 -0
- package/src/api-manager/index.ts +54 -3
- package/src/api-manager/lib/get-graphql-client.ts +11 -5
- package/src/api-manager/schemas/cart.schema.ts +10 -1
- package/src/api-manager/schemas/invoice.schema.ts +55 -0
- package/src/api-manager/schemas/order.schema.ts +13 -1
- package/src/api-manager/schemas/user.schema.ts +8 -0
- package/src/api-manager/services/create-query.ts +4 -10
- package/src/api-manager/services/invoice/queries/get-invoice-details.ts +18 -0
- package/src/api-manager/services/invoice/queries/get-invoices.ts +18 -0
- package/src/api-manager/services/order/queries/get-order-details.ts +1 -1
- package/src/api-manager/services/order/queries/get-orders.ts +6 -3
- package/src/api-manager/services/user/queries/get-customer-balance.ts +20 -0
- package/src/api-manager/types/Datasource.ts +21 -2
- package/src/auth/better-auth.ts +1 -1
- package/src/cms/blocks/block-manager.tsx +18 -3
- package/src/cms/blocks/components/cta-banner.tsx +65 -0
- package/src/cms/blocks/components/hero-image.tsx +83 -0
- package/src/cms/blocks/index.tsx +2 -0
- package/src/cms/blocks/interfaces.ts +20 -0
- package/src/cms/draft-mode-badge.tsx +26 -0
- package/src/cms/queries.ts +81 -0
- package/src/components/flex-box/flex-box.tsx +2 -0
- package/src/components/header/components/user.tsx +37 -12
- package/src/components/mini-cart/mini-cart.tsx +3 -3
- package/src/components/wishlist-dialogs/add-to-wishlist/compound/wishlist-dialog-header.tsx +1 -0
- package/src/pages/account/account-navigation.tsx +88 -60
- package/src/pages/account/account-routes.ts +52 -0
- package/src/pages/account/orders/order-history-filter-types.tsx +26 -0
- package/src/pages/account/orders/order-history-filters-panel.tsx +375 -0
- package/src/pages/account/orders/order-history-header.tsx +54 -0
- package/src/pages/account/orders/order-history-pagination.tsx +55 -0
- package/src/pages/account/orders/order-history-root.tsx +125 -0
- package/src/pages/account/orders/order-history-row.tsx +110 -0
- package/src/pages/account/orders/order-history-search-and-filter.tsx +449 -0
- package/src/pages/account/orders/order-history-search-bar.tsx +84 -0
- package/src/pages/account/orders/order-history-search-dropdown.tsx +53 -0
- package/src/pages/account/orders/order-history-sort.tsx +90 -0
- package/src/pages/account/orders/order-history-table.tsx +54 -0
- package/src/pages/account/orders/order-row.tsx +2 -2
- package/src/pages/account/orders/orders-drop-down-handler.tsx +19 -0
- package/src/pages/account/table-header.tsx +20 -0
- package/src/pages/account/wishlist/wishlist-item.tsx +1 -1
- package/src/pages/blog/blog-card.tsx +9 -3
- package/src/pages/blog/blog-detail-view.tsx +150 -0
- package/src/pages/blog/blog-list-view.tsx +59 -0
- package/src/pages/cart/estimate-shipping.tsx +6 -5
- package/src/pages/checkout/checkout-alt-form/checkout-form.tsx +43 -21
- package/src/pages/checkout/checkout-alt-form/steps/payment/payment-details.tsx +144 -19
- package/src/pages/cms-page-view.tsx +53 -0
- package/src/pages/quickorder/order-upload.tsx +12 -6
- package/src/pages/quickorder/quick-order.tsx +25 -20
|
@@ -9,6 +9,11 @@ import {
|
|
|
9
9
|
Paragraph,
|
|
10
10
|
Span,
|
|
11
11
|
} from "@evenicanpm/storefront-core/src/components/Typography";
|
|
12
|
+
import {
|
|
13
|
+
type AccountRoute,
|
|
14
|
+
type AccountRouteOverrides,
|
|
15
|
+
createAccountRoutes,
|
|
16
|
+
} from "@evenicanpm/storefront-core/src/pages/account/account-routes";
|
|
12
17
|
// STYLED COMPONENTS
|
|
13
18
|
import {
|
|
14
19
|
MainContainer,
|
|
@@ -17,88 +22,114 @@ import {
|
|
|
17
22
|
import { usePathname } from "next/navigation";
|
|
18
23
|
import { useTranslations } from "next-intl";
|
|
19
24
|
import { createContext, Fragment, type ReactNode } from "react";
|
|
20
|
-
|
|
21
|
-
import {
|
|
22
|
-
MdFavoriteBorder as FavoriteBorder,
|
|
23
|
-
MdPerson as Person,
|
|
24
|
-
MdPlace as Place,
|
|
25
|
-
MdOutlineShoppingBag as ShoppingBagOutlined,
|
|
26
|
-
} from "react-icons/md";
|
|
25
|
+
import type { IconType } from "react-icons";
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
28
|
*
|
|
30
29
|
*** Extend menu:
|
|
31
30
|
<AccountNavigation
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
items={[
|
|
32
|
+
...DEFAULT_MENU_ITEMS,
|
|
33
|
+
{
|
|
34
|
+
title: "EXTRAS",
|
|
35
|
+
list: [
|
|
36
|
+
{
|
|
37
|
+
href: "/account/rewards",
|
|
38
|
+
title: "rewards",
|
|
39
|
+
Icon: RewardsIcon,
|
|
40
|
+
count: 5,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
]}
|
|
46
45
|
/>;
|
|
47
46
|
|
|
48
47
|
*** Override completely:
|
|
49
48
|
<AccountNavigation>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
<AccountNavigation.Section title="Custom Section">
|
|
50
|
+
<AccountNavigation.Item
|
|
51
|
+
href="/custom"
|
|
52
|
+
Icon={CustomIcon}
|
|
53
|
+
label="Custom Page"
|
|
54
|
+
/>
|
|
55
|
+
</AccountNavigation.Section>
|
|
57
56
|
</AccountNavigation>;
|
|
58
57
|
*/
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
59
|
+
interface NavItem {
|
|
60
|
+
href: string;
|
|
61
|
+
title: string;
|
|
62
|
+
Icon: IconType;
|
|
63
|
+
count?: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface NavSection {
|
|
67
|
+
title: string;
|
|
68
|
+
list: NavItem[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param route
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
const routeToNavItem = (route: AccountRoute): NavItem => {
|
|
77
|
+
return {
|
|
78
|
+
href: route.href,
|
|
79
|
+
title: route.titleKey,
|
|
80
|
+
Icon: route.Icon,
|
|
81
|
+
count: route.count,
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const DEFAULT_MENU_ITEMS = (
|
|
86
|
+
overrides?: AccountRouteOverrides,
|
|
87
|
+
): NavSection[] => {
|
|
88
|
+
const routes = createAccountRoutes(overrides);
|
|
89
|
+
return [
|
|
90
|
+
{
|
|
91
|
+
title: "DASHBOARD",
|
|
92
|
+
list: [
|
|
93
|
+
routeToNavItem(routes.orders),
|
|
94
|
+
routeToNavItem(routes.wishlists),
|
|
95
|
+
routeToNavItem(routes.invoices),
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
title: "ACCOUNT SETTINGS",
|
|
100
|
+
list: [routeToNavItem(routes.profile), routeToNavItem(routes.addresses)],
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
};
|
|
81
104
|
|
|
82
105
|
interface AccountNavigationContextValue {
|
|
83
|
-
items:
|
|
106
|
+
items: NavSection[];
|
|
84
107
|
}
|
|
85
108
|
|
|
86
109
|
const AccountNavigationContext =
|
|
87
110
|
createContext<AccountNavigationContextValue | null>(null);
|
|
111
|
+
|
|
88
112
|
interface AccountNavigationProps {
|
|
89
|
-
items?:
|
|
113
|
+
items?: NavSection[];
|
|
90
114
|
children?: ReactNode;
|
|
115
|
+
routeOverrides?: AccountRouteOverrides;
|
|
91
116
|
}
|
|
92
117
|
|
|
93
|
-
const AccountNavigation = ({
|
|
118
|
+
const AccountNavigation = ({
|
|
119
|
+
items,
|
|
120
|
+
children,
|
|
121
|
+
routeOverrides,
|
|
122
|
+
}: AccountNavigationProps) => {
|
|
94
123
|
const pathname = usePathname();
|
|
95
124
|
const t = useTranslations("Account.Menu");
|
|
96
125
|
|
|
97
126
|
const { data: user } = getUser.useData();
|
|
98
127
|
const { data: counts } = getUserCounts.useData(String(user?.RecordId) || "");
|
|
99
128
|
|
|
100
|
-
|
|
101
|
-
|
|
129
|
+
const defaultItems = DEFAULT_MENU_ITEMS(routeOverrides);
|
|
130
|
+
|
|
131
|
+
// Render either the props items or the default items
|
|
132
|
+
const itemsWCounts = (items || defaultItems).map((section) => ({
|
|
102
133
|
...section,
|
|
103
134
|
list: section.list.map((item) => {
|
|
104
135
|
if (item.href === "/account/orders") {
|
|
@@ -112,10 +143,10 @@ const AccountNavigation = ({ items, children }: AccountNavigationProps) => {
|
|
|
112
143
|
}));
|
|
113
144
|
|
|
114
145
|
return (
|
|
115
|
-
<AccountNavigationContext.Provider value={{ items:
|
|
146
|
+
<AccountNavigationContext.Provider value={{ items: itemsWCounts }}>
|
|
116
147
|
<MainContainer>
|
|
117
148
|
{children ||
|
|
118
|
-
|
|
149
|
+
itemsWCounts.map((section) => (
|
|
119
150
|
<AccountNavigation.Section
|
|
120
151
|
key={section.title}
|
|
121
152
|
title={section.title}
|
|
@@ -151,10 +182,7 @@ AccountNavigation.Section = ({ title, children }: SectionProps) => {
|
|
|
151
182
|
);
|
|
152
183
|
};
|
|
153
184
|
|
|
154
|
-
interface ItemProps {
|
|
155
|
-
href: string;
|
|
156
|
-
Icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
|
|
157
|
-
count?: number;
|
|
185
|
+
interface ItemProps extends Pick<NavItem, "href" | "Icon" | "count"> {
|
|
158
186
|
label: string;
|
|
159
187
|
isActive?: boolean;
|
|
160
188
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { IconType } from "react-icons";
|
|
2
|
+
import {
|
|
3
|
+
MdFavoriteBorder as FavoriteBorder,
|
|
4
|
+
MdDocumentScanner as InvoicesIcon,
|
|
5
|
+
MdPerson as Person,
|
|
6
|
+
MdPlace as Place,
|
|
7
|
+
MdOutlineShoppingBag as ShoppingBagOutlined,
|
|
8
|
+
} from "react-icons/md";
|
|
9
|
+
|
|
10
|
+
export interface AccountRoute {
|
|
11
|
+
href: string;
|
|
12
|
+
titleKey: string;
|
|
13
|
+
Icon: IconType;
|
|
14
|
+
count?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AccountRouteOverrides {
|
|
18
|
+
wishlists?: { href?: string; titleKey?: string };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const defaults = {
|
|
22
|
+
orders: {
|
|
23
|
+
href: "/account/orders",
|
|
24
|
+
titleKey: "orders",
|
|
25
|
+
Icon: ShoppingBagOutlined,
|
|
26
|
+
count: 0,
|
|
27
|
+
},
|
|
28
|
+
wishlists: {
|
|
29
|
+
href: "/account/wish-lists",
|
|
30
|
+
titleKey: "wishlists",
|
|
31
|
+
Icon: FavoriteBorder,
|
|
32
|
+
},
|
|
33
|
+
invoices: {
|
|
34
|
+
href: "/account/invoices",
|
|
35
|
+
titleKey: "invoices",
|
|
36
|
+
Icon: InvoicesIcon,
|
|
37
|
+
},
|
|
38
|
+
profile: { href: "/account/profile", titleKey: "profile", Icon: Person },
|
|
39
|
+
addresses: {
|
|
40
|
+
href: "/account/addresses",
|
|
41
|
+
titleKey: "addresses",
|
|
42
|
+
Icon: Place,
|
|
43
|
+
count: 0,
|
|
44
|
+
},
|
|
45
|
+
} as const satisfies Record<string, AccountRoute>;
|
|
46
|
+
|
|
47
|
+
export type AccountRouteKey = keyof typeof defaults;
|
|
48
|
+
|
|
49
|
+
export const createAccountRoutes = (overrides?: AccountRouteOverrides) => ({
|
|
50
|
+
...defaults,
|
|
51
|
+
wishlists: { ...defaults.wishlists, ...overrides?.wishlists },
|
|
52
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export enum FilterSourceType {
|
|
2
|
+
Origin = "Origin",
|
|
3
|
+
CreatedDate = "CreatedDate",
|
|
4
|
+
OrderStatus = "OrderStatus",
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface OriginFilter {
|
|
8
|
+
sourceType: FilterSourceType.Origin;
|
|
9
|
+
label: string;
|
|
10
|
+
value: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface CreatedDateFilter {
|
|
14
|
+
sourceType: FilterSourceType.CreatedDate;
|
|
15
|
+
label: string;
|
|
16
|
+
startValue?: string;
|
|
17
|
+
endValue?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface OrderStatusFilter {
|
|
21
|
+
sourceType: FilterSourceType.OrderStatus;
|
|
22
|
+
label: string;
|
|
23
|
+
value: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type FilterOption = OriginFilter | CreatedDateFilter | OrderStatusFilter;
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { SalesStatus } from "@msdyn365-commerce/retail-proxy";
|
|
2
|
+
import { KeyboardArrowRight } from "@mui/icons-material";
|
|
3
|
+
import {
|
|
4
|
+
Box,
|
|
5
|
+
Button,
|
|
6
|
+
Checkbox,
|
|
7
|
+
Divider,
|
|
8
|
+
FormControlLabel,
|
|
9
|
+
FormGroup,
|
|
10
|
+
Radio,
|
|
11
|
+
RadioGroup,
|
|
12
|
+
TextField,
|
|
13
|
+
Typography,
|
|
14
|
+
} from "@mui/material";
|
|
15
|
+
import { useTranslations } from "next-intl";
|
|
16
|
+
import { useState } from "react";
|
|
17
|
+
import { HiX } from "react-icons/hi";
|
|
18
|
+
import {
|
|
19
|
+
type CreatedDateFilter,
|
|
20
|
+
type FilterOption,
|
|
21
|
+
FilterSourceType,
|
|
22
|
+
type OrderStatusFilter,
|
|
23
|
+
} from "./order-history-filter-types";
|
|
24
|
+
import { useOrdersSearchAndFilter } from "./order-history-search-and-filter";
|
|
25
|
+
|
|
26
|
+
const createdDateOptions: CreatedDateFilter[] = [
|
|
27
|
+
{
|
|
28
|
+
sourceType: FilterSourceType.CreatedDate,
|
|
29
|
+
label: "Last 7 days",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
sourceType: FilterSourceType.CreatedDate,
|
|
33
|
+
label: "Last 30 days",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
sourceType: FilterSourceType.CreatedDate,
|
|
37
|
+
label: "Last 3 months",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
sourceType: FilterSourceType.CreatedDate,
|
|
41
|
+
label: "Last 6 months",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
sourceType: FilterSourceType.CreatedDate,
|
|
45
|
+
label: "Custom Dates",
|
|
46
|
+
startValue: "",
|
|
47
|
+
endValue: "",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const orderStatusOptions: OrderStatusFilter[] = [
|
|
52
|
+
{
|
|
53
|
+
sourceType: FilterSourceType.OrderStatus,
|
|
54
|
+
label: "Created",
|
|
55
|
+
value: SalesStatus.Created,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
sourceType: FilterSourceType.OrderStatus,
|
|
59
|
+
label: "Processing",
|
|
60
|
+
value: SalesStatus.Processing,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
sourceType: FilterSourceType.OrderStatus,
|
|
64
|
+
label: "Delivered",
|
|
65
|
+
value: SalesStatus.Delivered,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
sourceType: FilterSourceType.OrderStatus,
|
|
69
|
+
label: "Invoiced",
|
|
70
|
+
value: SalesStatus.Invoiced,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
sourceType: FilterSourceType.OrderStatus,
|
|
74
|
+
label: "Cancelled",
|
|
75
|
+
value: SalesStatus.Canceled,
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
const OrdersFilterPanel = ({ children }: { children: React.ReactNode }) => {
|
|
80
|
+
const {
|
|
81
|
+
selectedOrigins,
|
|
82
|
+
handleSelectOrigin,
|
|
83
|
+
createdDate,
|
|
84
|
+
handleSelectCreatedDate,
|
|
85
|
+
orderStatus,
|
|
86
|
+
handleSelectOrderStatus,
|
|
87
|
+
} = useOrdersSearchAndFilter();
|
|
88
|
+
const [open, setOpen] = useState(false);
|
|
89
|
+
const t = useTranslations("Account.Orders");
|
|
90
|
+
|
|
91
|
+
const handleToggle = () => setOpen((prev) => !prev);
|
|
92
|
+
|
|
93
|
+
const activeFilters: FilterOption[] = [];
|
|
94
|
+
selectedOrigins.forEach((origin) => {
|
|
95
|
+
activeFilters.push(origin);
|
|
96
|
+
});
|
|
97
|
+
if (createdDate) {
|
|
98
|
+
activeFilters.push(createdDate);
|
|
99
|
+
}
|
|
100
|
+
if (orderStatus) {
|
|
101
|
+
activeFilters.push(orderStatus);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const handleRemoveActiveFilter = (filter: FilterOption) => {
|
|
105
|
+
switch (filter.sourceType) {
|
|
106
|
+
case FilterSourceType.Origin:
|
|
107
|
+
handleSelectOrigin(filter);
|
|
108
|
+
break;
|
|
109
|
+
case FilterSourceType.CreatedDate:
|
|
110
|
+
handleSelectCreatedDate(undefined);
|
|
111
|
+
break;
|
|
112
|
+
case FilterSourceType.OrderStatus:
|
|
113
|
+
handleSelectOrderStatus(undefined);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const handleClearAllFilters = () => {
|
|
119
|
+
selectedOrigins.forEach((origin) => {
|
|
120
|
+
handleSelectOrigin(origin);
|
|
121
|
+
});
|
|
122
|
+
handleSelectCreatedDate(undefined);
|
|
123
|
+
handleSelectOrderStatus(undefined);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<Box
|
|
128
|
+
sx={{
|
|
129
|
+
border: "1px solid #eee",
|
|
130
|
+
borderRadius: 2,
|
|
131
|
+
bgcolor: "#fff",
|
|
132
|
+
mb: 3,
|
|
133
|
+
mt: 2,
|
|
134
|
+
flex: "1 1 0",
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
<Box display="flex" sx={{ pt: 1, pl: 1 }}>
|
|
138
|
+
<Button
|
|
139
|
+
onClick={handleToggle}
|
|
140
|
+
sx={{ textTransform: "none", mb: 1, mr: 1, ml: 1 }}
|
|
141
|
+
>
|
|
142
|
+
<Typography sx={{ marginRight: 1, fontWeight: 600 }}>
|
|
143
|
+
{t("filterBtn")}
|
|
144
|
+
</Typography>
|
|
145
|
+
|
|
146
|
+
<KeyboardArrowRight
|
|
147
|
+
fontSize="small"
|
|
148
|
+
color="inherit"
|
|
149
|
+
sx={{
|
|
150
|
+
transform: open ? "rotate(90deg)" : "rotate(0deg)", // 0deg = right, 90deg = down
|
|
151
|
+
transition: "transform 0.3s ease",
|
|
152
|
+
transformOrigin: "center",
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
</Button>
|
|
156
|
+
<Box>
|
|
157
|
+
{activeFilters.length > 0 &&
|
|
158
|
+
activeFilters.map((filter, index) => (
|
|
159
|
+
<Box
|
|
160
|
+
key={index}
|
|
161
|
+
sx={{
|
|
162
|
+
display: "inline-flex",
|
|
163
|
+
alignItems: "center",
|
|
164
|
+
backgroundColor: "#f0f0f0",
|
|
165
|
+
borderRadius: 4,
|
|
166
|
+
px: 1.5,
|
|
167
|
+
py: 0.75,
|
|
168
|
+
mr: 1,
|
|
169
|
+
mb: 1,
|
|
170
|
+
cursor: "pointer",
|
|
171
|
+
|
|
172
|
+
"&:hover": {
|
|
173
|
+
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
|
|
174
|
+
},
|
|
175
|
+
}}
|
|
176
|
+
onClick={() => handleRemoveActiveFilter(filter)}
|
|
177
|
+
>
|
|
178
|
+
<Typography mr={1}>{filter.label}</Typography>
|
|
179
|
+
<HiX />
|
|
180
|
+
</Box>
|
|
181
|
+
))}
|
|
182
|
+
</Box>
|
|
183
|
+
{activeFilters.length > 0 && (
|
|
184
|
+
<Typography
|
|
185
|
+
sx={{
|
|
186
|
+
cursor: "pointer",
|
|
187
|
+
mx: 1,
|
|
188
|
+
my: 1,
|
|
189
|
+
minWidth: "60px",
|
|
190
|
+
textDecoration: "underline",
|
|
191
|
+
}}
|
|
192
|
+
onClick={handleClearAllFilters}
|
|
193
|
+
>
|
|
194
|
+
{t("clearAllBtn")}
|
|
195
|
+
</Typography>
|
|
196
|
+
)}
|
|
197
|
+
</Box>
|
|
198
|
+
|
|
199
|
+
{open && (
|
|
200
|
+
<>
|
|
201
|
+
<Box
|
|
202
|
+
display="flex"
|
|
203
|
+
gap={4}
|
|
204
|
+
p={3}
|
|
205
|
+
sx={{
|
|
206
|
+
border: "1px solid #e0e0e0",
|
|
207
|
+
borderRadius: 2,
|
|
208
|
+
bgcolor: "#fff",
|
|
209
|
+
mb: 2,
|
|
210
|
+
}}
|
|
211
|
+
>
|
|
212
|
+
{children}
|
|
213
|
+
</Box>
|
|
214
|
+
|
|
215
|
+
{/* Done Button */}
|
|
216
|
+
<Box textAlign="right" pr={2} pb={2}>
|
|
217
|
+
<Button
|
|
218
|
+
variant="contained"
|
|
219
|
+
color="primary"
|
|
220
|
+
onClick={handleToggle}
|
|
221
|
+
sx={{ borderRadius: "24px", textTransform: "none" }}
|
|
222
|
+
>
|
|
223
|
+
{t("doneBtn")}
|
|
224
|
+
</Button>
|
|
225
|
+
</Box>
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
228
|
+
</Box>
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const OriginsFilterList = () => {
|
|
233
|
+
const { originOptions, selectedOrigins, handleSelectOrigin } =
|
|
234
|
+
useOrdersSearchAndFilter();
|
|
235
|
+
const t = useTranslations("Account.Orders");
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<Box>
|
|
239
|
+
<Typography fontWeight={600} mb={1}>
|
|
240
|
+
{t("originHeader")}
|
|
241
|
+
</Typography>
|
|
242
|
+
<Divider />
|
|
243
|
+
<FormGroup
|
|
244
|
+
sx={{
|
|
245
|
+
maxHeight: "400px",
|
|
246
|
+
overflowY: "auto",
|
|
247
|
+
flexWrap: "nowrap",
|
|
248
|
+
}}
|
|
249
|
+
>
|
|
250
|
+
{originOptions.map((originOption, index) => (
|
|
251
|
+
<FormControlLabel
|
|
252
|
+
key={index}
|
|
253
|
+
control={
|
|
254
|
+
<Checkbox
|
|
255
|
+
checked={selectedOrigins.some(
|
|
256
|
+
(o) => o.value === originOption.value,
|
|
257
|
+
)}
|
|
258
|
+
onChange={() => handleSelectOrigin(originOption)}
|
|
259
|
+
/>
|
|
260
|
+
}
|
|
261
|
+
label={originOption.label}
|
|
262
|
+
/>
|
|
263
|
+
))}
|
|
264
|
+
</FormGroup>
|
|
265
|
+
</Box>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const CreatedDateFilterList = () => {
|
|
270
|
+
const { createdDate, handleSelectCreatedDate } = useOrdersSearchAndFilter();
|
|
271
|
+
const t = useTranslations("Account.Orders");
|
|
272
|
+
|
|
273
|
+
return (
|
|
274
|
+
<Box sx={{ minWidth: "155px" }}>
|
|
275
|
+
<Typography fontWeight={600} mb={1}>
|
|
276
|
+
{t("createdDateHeader")}
|
|
277
|
+
</Typography>
|
|
278
|
+
<Divider />
|
|
279
|
+
<RadioGroup value={createdDate?.label ?? ""}>
|
|
280
|
+
{createdDateOptions.map((createdDateOption, index) => (
|
|
281
|
+
<div key={index}>
|
|
282
|
+
<FormControlLabel
|
|
283
|
+
key={createdDateOption.label}
|
|
284
|
+
value={createdDateOption.label}
|
|
285
|
+
control={
|
|
286
|
+
<Radio
|
|
287
|
+
onClick={() => {
|
|
288
|
+
handleSelectCreatedDate(createdDateOption);
|
|
289
|
+
}}
|
|
290
|
+
/>
|
|
291
|
+
}
|
|
292
|
+
label={createdDateOption.label}
|
|
293
|
+
/>
|
|
294
|
+
{createdDateOption.label === "Custom Dates" &&
|
|
295
|
+
createdDate &&
|
|
296
|
+
createdDate.label === "Custom Dates" && (
|
|
297
|
+
<Box mt={1} display="flex" flexDirection="column" gap={2}>
|
|
298
|
+
<TextField
|
|
299
|
+
label="From"
|
|
300
|
+
type="date"
|
|
301
|
+
value={createdDate?.startValue || ""}
|
|
302
|
+
onChange={(e) =>
|
|
303
|
+
handleSelectCreatedDate(
|
|
304
|
+
{ ...createdDate, startValue: e.target.value },
|
|
305
|
+
false,
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
slotProps={{
|
|
309
|
+
inputLabel: {
|
|
310
|
+
shrink: true,
|
|
311
|
+
},
|
|
312
|
+
}}
|
|
313
|
+
variant="outlined"
|
|
314
|
+
/>
|
|
315
|
+
<TextField
|
|
316
|
+
label="To"
|
|
317
|
+
type="date"
|
|
318
|
+
value={createdDate?.endValue || ""}
|
|
319
|
+
onChange={(e) =>
|
|
320
|
+
handleSelectCreatedDate(
|
|
321
|
+
{ ...createdDate, endValue: e.target.value },
|
|
322
|
+
false,
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
slotProps={{
|
|
326
|
+
inputLabel: {
|
|
327
|
+
shrink: true,
|
|
328
|
+
},
|
|
329
|
+
}}
|
|
330
|
+
variant="outlined"
|
|
331
|
+
/>
|
|
332
|
+
</Box>
|
|
333
|
+
)}
|
|
334
|
+
</div>
|
|
335
|
+
))}
|
|
336
|
+
</RadioGroup>
|
|
337
|
+
</Box>
|
|
338
|
+
);
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const OrderStatusFilterList = () => {
|
|
342
|
+
const { orderStatus, handleSelectOrderStatus } = useOrdersSearchAndFilter();
|
|
343
|
+
const t = useTranslations("Account.Orders");
|
|
344
|
+
|
|
345
|
+
return (
|
|
346
|
+
<Box>
|
|
347
|
+
<Typography fontWeight={600} mb={1}>
|
|
348
|
+
{t("orderStatusHeader")}
|
|
349
|
+
</Typography>
|
|
350
|
+
<Divider />
|
|
351
|
+
<RadioGroup value={orderStatus?.value ?? -1}>
|
|
352
|
+
{orderStatusOptions.map((orderStatusOption) => (
|
|
353
|
+
<FormControlLabel
|
|
354
|
+
key={orderStatusOption.label}
|
|
355
|
+
value={orderStatusOption.value}
|
|
356
|
+
control={
|
|
357
|
+
<Radio
|
|
358
|
+
onClick={() => {
|
|
359
|
+
handleSelectOrderStatus(orderStatusOption);
|
|
360
|
+
}}
|
|
361
|
+
/>
|
|
362
|
+
}
|
|
363
|
+
label={orderStatusOption.label}
|
|
364
|
+
/>
|
|
365
|
+
))}
|
|
366
|
+
</RadioGroup>
|
|
367
|
+
</Box>
|
|
368
|
+
);
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
OrdersFilterPanel.Origins = OriginsFilterList;
|
|
372
|
+
OrdersFilterPanel.CreatedDate = CreatedDateFilterList;
|
|
373
|
+
OrdersFilterPanel.OrderStatus = OrderStatusFilterList;
|
|
374
|
+
|
|
375
|
+
export default OrdersFilterPanel;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// GLOBAL CUSTOM COMPONENT
|
|
2
|
+
import { Paragraph } from "@evenicanpm/storefront-core/src/components/Typography";
|
|
3
|
+
// CUSTOM UTILS LIBRARY FUNCTION;
|
|
4
|
+
import TableHeader from "@evenicanpm/storefront-core/src/pages/account/table-header";
|
|
5
|
+
import Box from "@mui/material/Box";
|
|
6
|
+
import { useTranslations } from "next-intl";
|
|
7
|
+
import { createContext } from "react";
|
|
8
|
+
|
|
9
|
+
export const OrderHistoryTableHeaderContext =
|
|
10
|
+
createContext<undefined>(undefined);
|
|
11
|
+
|
|
12
|
+
const OrderHistoryTableHeader = ({
|
|
13
|
+
children,
|
|
14
|
+
}: {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}) => {
|
|
17
|
+
return (
|
|
18
|
+
<OrderHistoryTableHeaderContext.Provider value={undefined}>
|
|
19
|
+
<Box>
|
|
20
|
+
<TableHeader sx={{ gridTemplateColumns: "2fr 1fr 1fr 1fr 1fr" }}>
|
|
21
|
+
{children}
|
|
22
|
+
</TableHeader>
|
|
23
|
+
</Box>
|
|
24
|
+
</OrderHistoryTableHeaderContext.Provider>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
OrderHistoryTableHeader.OrderNumber = () => {
|
|
29
|
+
const t = useTranslations("Account.Orders");
|
|
30
|
+
return <Paragraph ellipsis>{t("orderNumberHeader")}</Paragraph>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
OrderHistoryTableHeader.OrderStatus = () => {
|
|
34
|
+
const t = useTranslations("Account.Orders");
|
|
35
|
+
return <Box textAlign="center">{t("orderStatusHeader")}</Box>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
OrderHistoryTableHeader.TransactionDate = () => {
|
|
39
|
+
const t = useTranslations("Account.Orders");
|
|
40
|
+
return (
|
|
41
|
+
<Paragraph textAlign={{ sm: "center", xs: "left" }}>
|
|
42
|
+
{t("transactionDateHeader")}
|
|
43
|
+
</Paragraph>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
OrderHistoryTableHeader.TransactionAmount = () => {
|
|
48
|
+
const t = useTranslations("Account.Orders");
|
|
49
|
+
return (
|
|
50
|
+
<Paragraph textAlign="center">{t("transactionAmountHeader")}</Paragraph>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default OrderHistoryTableHeader;
|