order-management 0.0.51 → 0.0.53
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/.medusa/server/src/admin/index.js +136 -411
- package/.medusa/server/src/admin/index.mjs +140 -415
- package/.medusa/server/src/api/admin/returns/[id]/reject/route.js +25 -12
- package/.medusa/server/src/api/admin/returns/[id]/route.js +5 -27
- package/.medusa/server/src/api/admin/returns/route.js +29 -60
- package/.medusa/server/src/api/admin/returns/validators.js +3 -15
- package/.medusa/server/src/api/admin/swaps/[id]/cancel/route.js +70 -0
- package/.medusa/server/src/api/admin/swaps/[id]/reject/route.js +27 -12
- package/.medusa/server/src/api/admin/swaps/[id]/route.js +30 -47
- package/.medusa/server/src/api/admin/swaps/route.js +65 -32
- package/.medusa/server/src/api/admin/swaps/validators.js +13 -3
- package/.medusa/server/src/api/store/guest-orders/[id]/returns/route.js +40 -44
- package/.medusa/server/src/api/store/guest-orders/[id]/swaps/[swap_id]/cancel/route.js +64 -112
- package/.medusa/server/src/api/store/guest-orders/[id]/swaps/[swap_id]/route.js +89 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/swaps/route.js +181 -153
- package/.medusa/server/src/api/store/returns/[id]/cancel/route.js +47 -40
- package/.medusa/server/src/api/store/returns/[id]/route.js +41 -57
- package/.medusa/server/src/api/store/returns/route.js +79 -171
- package/.medusa/server/src/api/store/returns/validators.js +24 -21
- package/.medusa/server/src/api/store/swaps/[id]/cancel/route.js +44 -54
- package/.medusa/server/src/api/store/swaps/[id]/route.js +33 -134
- package/.medusa/server/src/api/store/swaps/route.js +233 -145
- package/.medusa/server/src/helpers/returns.js +1 -69
- package/.medusa/server/src/helpers/swaps.js +13 -4
- package/.medusa/server/src/workflows/index.js +2 -14
- package/.medusa/server/src/workflows/steps/index.js +1 -17
- package/README.md +58 -102
- package/package.json +1 -1
- package/.medusa/server/src/api/admin/returns/[id]/approve/route.js +0 -115
- package/.medusa/server/src/api/admin/returns/[id]/mark-received/route.js +0 -44
- package/.medusa/server/src/api/admin/returns/[id]/process-refund/route.js +0 -44
- package/.medusa/server/src/api/admin/returns/[id]/status/route.js +0 -118
- package/.medusa/server/src/api/admin/swaps/[id]/create-exchange/route.js +0 -330
- package/.medusa/server/src/api/admin/swaps/health/route.js +0 -150
- package/.medusa/server/src/modules/return/index.js +0 -13
- package/.medusa/server/src/modules/return/migrations/Migration20260205000001.js +0 -57
- package/.medusa/server/src/modules/return/models/return.js +0 -21
- package/.medusa/server/src/modules/return/service.js +0 -447
- package/.medusa/server/src/modules/swap/index.js +0 -13
- package/.medusa/server/src/modules/swap/migrations/Migration20260121164326.js +0 -49
- package/.medusa/server/src/modules/swap/migrations/Migration20260123144734.js +0 -29
- package/.medusa/server/src/modules/swap/migrations/Migration20260123162423.js +0 -48
- package/.medusa/server/src/modules/swap/migrations/Migration20260126114640.js +0 -48
- package/.medusa/server/src/modules/swap/models/swap.js +0 -26
- package/.medusa/server/src/modules/swap/service.js +0 -490
- package/.medusa/server/src/subscribers/exchange-created.js +0 -192
- package/.medusa/server/src/subscribers/return-created.js +0 -162
- package/.medusa/server/src/subscribers/return-received.js +0 -75
- package/.medusa/server/src/subscribers/return-refunded.js +0 -258
- package/.medusa/server/src/subscribers/swap-fulfillment-created.js +0 -139
- package/.medusa/server/src/subscribers/swap-return-paid.js +0 -236
- package/.medusa/server/src/subscribers/swap-return-received.js +0 -155
- package/.medusa/server/src/subscribers/swap-shipment-delivered.js +0 -304
- package/.medusa/server/src/workflows/returns/create-return-workflow.js +0 -45
- package/.medusa/server/src/workflows/returns/types.js +0 -3
- package/.medusa/server/src/workflows/returns/update-return-status-workflow.js +0 -23
- package/.medusa/server/src/workflows/returns/update-return-workflow.js +0 -18
- package/.medusa/server/src/workflows/steps/return/calculate-refund-step.js +0 -21
- package/.medusa/server/src/workflows/steps/return/create-medusa-refund-step.js +0 -41
- package/.medusa/server/src/workflows/steps/return/create-return-step.js +0 -24
- package/.medusa/server/src/workflows/steps/return/index.js +0 -28
- package/.medusa/server/src/workflows/steps/return/retrieve-return-step.js +0 -18
- package/.medusa/server/src/workflows/steps/return/rollback-refund-step.js +0 -46
- package/.medusa/server/src/workflows/steps/return/sync-medusa-return-status-step.js +0 -51
- package/.medusa/server/src/workflows/steps/return/update-return-status-step.js +0 -18
- package/.medusa/server/src/workflows/steps/return/update-return-step.js +0 -23
- package/.medusa/server/src/workflows/steps/return/validate-eligibility-step.js +0 -22
- package/.medusa/server/src/workflows/steps/return/validate-order-step.js +0 -115
- package/.medusa/server/src/workflows/steps/return/validate-return-items-step.js +0 -95
- package/.medusa/server/src/workflows/steps/swap/calculate-difference-step.js +0 -56
- package/.medusa/server/src/workflows/steps/swap/create-medusa-exchange-step.js +0 -704
- package/.medusa/server/src/workflows/steps/swap/create-medusa-return-step.js +0 -758
- package/.medusa/server/src/workflows/steps/swap/create-swap-step.js +0 -24
- package/.medusa/server/src/workflows/steps/swap/index.js +0 -30
- package/.medusa/server/src/workflows/steps/swap/retrieve-swap-step.js +0 -26
- package/.medusa/server/src/workflows/steps/swap/rollback-return-step.js +0 -70
- package/.medusa/server/src/workflows/steps/swap/sync-medusa-status-step.js +0 -178
- package/.medusa/server/src/workflows/steps/swap/update-swap-exchange-details-step.js +0 -37
- package/.medusa/server/src/workflows/steps/swap/update-swap-status-step.js +0 -25
- package/.medusa/server/src/workflows/steps/swap/update-swap-step.js +0 -52
- package/.medusa/server/src/workflows/steps/swap/validate-eligibility-step.js +0 -31
- package/.medusa/server/src/workflows/steps/swap/validate-order-step.js +0 -91
- package/.medusa/server/src/workflows/steps/swap/validate-swap-items-step.js +0 -198
- package/.medusa/server/src/workflows/swaps/create-swap-workflow.js +0 -54
- package/.medusa/server/src/workflows/swaps/types.js +0 -3
- package/.medusa/server/src/workflows/swaps/update-swap-status-workflow.js +0 -23
- package/.medusa/server/src/workflows/swaps/update-swap-workflow.js +0 -67
|
@@ -5,114 +5,6 @@ const adminSdk = require("@medusajs/admin-sdk");
|
|
|
5
5
|
const ui = require("@medusajs/ui");
|
|
6
6
|
const icons = require("@medusajs/icons");
|
|
7
7
|
const reactRouterDom = require("react-router-dom");
|
|
8
|
-
const OrderReturnApprovalNoticeWidget = ({ data }) => {
|
|
9
|
-
const orderId = data == null ? void 0 : data.id;
|
|
10
|
-
const [returns, setReturns] = react.useState([]);
|
|
11
|
-
const [loading, setLoading] = react.useState(true);
|
|
12
|
-
react.useEffect(() => {
|
|
13
|
-
if (!orderId) {
|
|
14
|
-
setLoading(false);
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
let cancelled = false;
|
|
18
|
-
const load = async () => {
|
|
19
|
-
try {
|
|
20
|
-
const res = await fetch(
|
|
21
|
-
`/admin/returns?order_id=${encodeURIComponent(orderId)}&limit=50`,
|
|
22
|
-
{ credentials: "include" }
|
|
23
|
-
);
|
|
24
|
-
if (!res.ok || cancelled) return;
|
|
25
|
-
const payload = await res.json();
|
|
26
|
-
const list = Array.isArray(payload.returns) ? payload.returns : [];
|
|
27
|
-
if (!cancelled) setReturns(list);
|
|
28
|
-
} catch {
|
|
29
|
-
if (!cancelled) setReturns([]);
|
|
30
|
-
} finally {
|
|
31
|
-
if (!cancelled) setLoading(false);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
void load();
|
|
35
|
-
return () => {
|
|
36
|
-
cancelled = true;
|
|
37
|
-
};
|
|
38
|
-
}, [orderId]);
|
|
39
|
-
const requestedReturns = returns.filter(
|
|
40
|
-
(r) => {
|
|
41
|
-
var _a;
|
|
42
|
-
return ((_a = r.status) == null ? void 0 : _a.toLowerCase()) === "requested";
|
|
43
|
-
}
|
|
44
|
-
);
|
|
45
|
-
react.useEffect(() => {
|
|
46
|
-
if (requestedReturns.length === 0) return;
|
|
47
|
-
const RECEIVE_BUTTON_MARKER = "data-om-receive-items-hidden";
|
|
48
|
-
const hideReceiveButton = () => {
|
|
49
|
-
const buttons = document.querySelectorAll(
|
|
50
|
-
`button:not([${RECEIVE_BUTTON_MARKER}])`
|
|
51
|
-
);
|
|
52
|
-
for (const btn of buttons) {
|
|
53
|
-
const text = (btn.textContent ?? "").trim();
|
|
54
|
-
if (text === "Receive items" || text.toLowerCase().includes("receive item")) {
|
|
55
|
-
btn.style.setProperty("display", "none", "important");
|
|
56
|
-
btn.setAttribute(RECEIVE_BUTTON_MARKER, "true");
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return false;
|
|
61
|
-
};
|
|
62
|
-
if (hideReceiveButton()) return;
|
|
63
|
-
const observer = new MutationObserver(() => {
|
|
64
|
-
hideReceiveButton();
|
|
65
|
-
});
|
|
66
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
67
|
-
const interval = setInterval(() => {
|
|
68
|
-
if (hideReceiveButton()) {
|
|
69
|
-
clearInterval(interval);
|
|
70
|
-
}
|
|
71
|
-
}, 300);
|
|
72
|
-
return () => {
|
|
73
|
-
clearInterval(interval);
|
|
74
|
-
observer.disconnect();
|
|
75
|
-
document.querySelectorAll(`button[${RECEIVE_BUTTON_MARKER}]`).forEach((el) => {
|
|
76
|
-
el.style.removeProperty("display");
|
|
77
|
-
el.removeAttribute(RECEIVE_BUTTON_MARKER);
|
|
78
|
-
});
|
|
79
|
-
};
|
|
80
|
-
}, [requestedReturns.length]);
|
|
81
|
-
if (loading || requestedReturns.length === 0) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mb-6 overflow-hidden rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
85
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
86
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
87
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.InformationCircle, { className: "text-ui-fg-warning" }),
|
|
88
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-base", children: "Return request(s) pending approval" })
|
|
89
|
-
] }),
|
|
90
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
91
|
-
"This order has ",
|
|
92
|
-
requestedReturns.length,
|
|
93
|
-
" return request",
|
|
94
|
-
requestedReturns.length > 1 ? "s" : "",
|
|
95
|
-
' that must be approved in Return Orders before you can receive items. Do not use the "Receive items" button until the return has been approved.'
|
|
96
|
-
] })
|
|
97
|
-
] }),
|
|
98
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", children: requestedReturns.slice(0, 3).map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
99
|
-
ui.Button,
|
|
100
|
-
{
|
|
101
|
-
size: "small",
|
|
102
|
-
variant: "secondary",
|
|
103
|
-
onClick: () => window.open(`/app/returns/${r.id}`, "_self"),
|
|
104
|
-
children: [
|
|
105
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { className: "mr-1.5 uppercase", color: "orange", children: "Requested" }),
|
|
106
|
-
"Approve return"
|
|
107
|
-
]
|
|
108
|
-
},
|
|
109
|
-
r.id
|
|
110
|
-
)) })
|
|
111
|
-
] }) });
|
|
112
|
-
};
|
|
113
|
-
adminSdk.defineWidgetConfig({
|
|
114
|
-
zone: "order.details.before"
|
|
115
|
-
});
|
|
116
8
|
const useDebounce$1 = (value, delay) => {
|
|
117
9
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
118
10
|
react.useEffect(() => {
|
|
@@ -144,6 +36,7 @@ const ReturnsPage = () => {
|
|
|
144
36
|
const navigate = reactRouterDom.useNavigate();
|
|
145
37
|
const [items, setItems] = react.useState([]);
|
|
146
38
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
39
|
+
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
147
40
|
const [searchQuery, setSearchQuery] = react.useState("");
|
|
148
41
|
const debouncedSearchQuery = useDebounce$1(searchQuery, 300);
|
|
149
42
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
@@ -171,6 +64,9 @@ const ReturnsPage = () => {
|
|
|
171
64
|
if (debouncedSearchQuery.trim()) {
|
|
172
65
|
params.set("q", debouncedSearchQuery.trim());
|
|
173
66
|
}
|
|
67
|
+
if (createdByFilter !== "all") {
|
|
68
|
+
params.set("created_by", createdByFilter);
|
|
69
|
+
}
|
|
174
70
|
params.set("order", "created_at");
|
|
175
71
|
const response = await fetch(
|
|
176
72
|
`/admin/returns?${params.toString()}`,
|
|
@@ -194,11 +90,11 @@ const ReturnsPage = () => {
|
|
|
194
90
|
setIsFetchingMore(false);
|
|
195
91
|
}
|
|
196
92
|
},
|
|
197
|
-
[statusFilter, debouncedSearchQuery]
|
|
93
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
198
94
|
);
|
|
199
95
|
react.useEffect(() => {
|
|
200
96
|
void loadReturns(0, true);
|
|
201
|
-
}, [statusFilter, debouncedSearchQuery, loadReturns]);
|
|
97
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadReturns]);
|
|
202
98
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
203
99
|
const availableStatuses = react.useMemo(() => {
|
|
204
100
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -223,18 +119,33 @@ const ReturnsPage = () => {
|
|
|
223
119
|
className: "md:max-w-sm"
|
|
224
120
|
}
|
|
225
121
|
),
|
|
226
|
-
/* @__PURE__ */ jsxRuntime.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
122
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
123
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
124
|
+
"select",
|
|
125
|
+
{
|
|
126
|
+
value: createdByFilter,
|
|
127
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
128
|
+
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
131
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
137
|
+
"select",
|
|
138
|
+
{
|
|
139
|
+
value: statusFilter,
|
|
140
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
141
|
+
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
142
|
+
children: [
|
|
143
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
144
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
] })
|
|
238
149
|
] }),
|
|
239
150
|
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
240
151
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
@@ -301,9 +212,9 @@ const ReturnsPage = () => {
|
|
|
301
212
|
size: "small",
|
|
302
213
|
onClick: (e) => {
|
|
303
214
|
e.stopPropagation();
|
|
304
|
-
navigate(`/
|
|
215
|
+
navigate(`/app/orders/${returnOrder.order_id}`);
|
|
305
216
|
},
|
|
306
|
-
children: "
|
|
217
|
+
children: "Go to order"
|
|
307
218
|
}
|
|
308
219
|
) })
|
|
309
220
|
]
|
|
@@ -357,6 +268,7 @@ const SwapsPage = () => {
|
|
|
357
268
|
const navigate = reactRouterDom.useNavigate();
|
|
358
269
|
const [items, setItems] = react.useState([]);
|
|
359
270
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
271
|
+
const [createdByFilter, setCreatedByFilter] = react.useState("all");
|
|
360
272
|
const [searchQuery, setSearchQuery] = react.useState("");
|
|
361
273
|
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
362
274
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
@@ -384,6 +296,9 @@ const SwapsPage = () => {
|
|
|
384
296
|
if (debouncedSearchQuery.trim()) {
|
|
385
297
|
params.set("order_id", debouncedSearchQuery.trim());
|
|
386
298
|
}
|
|
299
|
+
if (createdByFilter !== "all") {
|
|
300
|
+
params.set("created_by", createdByFilter);
|
|
301
|
+
}
|
|
387
302
|
const response = await fetch(
|
|
388
303
|
`/admin/swaps?${params.toString()}`,
|
|
389
304
|
{ credentials: "include" }
|
|
@@ -406,11 +321,11 @@ const SwapsPage = () => {
|
|
|
406
321
|
setIsFetchingMore(false);
|
|
407
322
|
}
|
|
408
323
|
},
|
|
409
|
-
[statusFilter, debouncedSearchQuery]
|
|
324
|
+
[statusFilter, createdByFilter, debouncedSearchQuery]
|
|
410
325
|
);
|
|
411
326
|
react.useEffect(() => {
|
|
412
327
|
void loadSwaps(0, true);
|
|
413
|
-
}, [statusFilter, debouncedSearchQuery, loadSwaps]);
|
|
328
|
+
}, [statusFilter, createdByFilter, debouncedSearchQuery, loadSwaps]);
|
|
414
329
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
415
330
|
const availableStatuses = react.useMemo(() => {
|
|
416
331
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -420,8 +335,8 @@ const SwapsPage = () => {
|
|
|
420
335
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-7xl flex-col gap-6 p-6", children: [
|
|
421
336
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
422
337
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
423
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
424
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
338
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchanges" }),
|
|
339
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer exchange requests" })
|
|
425
340
|
] }),
|
|
426
341
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
427
342
|
] }),
|
|
@@ -435,18 +350,33 @@ const SwapsPage = () => {
|
|
|
435
350
|
className: "md:max-w-sm"
|
|
436
351
|
}
|
|
437
352
|
),
|
|
438
|
-
/* @__PURE__ */ jsxRuntime.
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
353
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
354
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
355
|
+
"select",
|
|
356
|
+
{
|
|
357
|
+
value: createdByFilter,
|
|
358
|
+
onChange: (event) => setCreatedByFilter(event.target.value),
|
|
359
|
+
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
360
|
+
children: [
|
|
361
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All (Created by)" }),
|
|
362
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "customer", children: "Customer" }),
|
|
363
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Admin" })
|
|
364
|
+
]
|
|
365
|
+
}
|
|
366
|
+
),
|
|
367
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
368
|
+
"select",
|
|
369
|
+
{
|
|
370
|
+
value: statusFilter,
|
|
371
|
+
onChange: (event) => setStatusFilter(event.target.value),
|
|
372
|
+
className: "h-9 rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive md:max-w-xs",
|
|
373
|
+
children: [
|
|
374
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "all", children: "All Statuses" }),
|
|
375
|
+
availableStatuses.map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
376
|
+
]
|
|
377
|
+
}
|
|
378
|
+
)
|
|
379
|
+
] })
|
|
450
380
|
] }),
|
|
451
381
|
error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
452
382
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
@@ -460,11 +390,11 @@ const SwapsPage = () => {
|
|
|
460
390
|
) })
|
|
461
391
|
] }) : null,
|
|
462
392
|
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swaps..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
463
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
464
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
393
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No exchanges yet" }),
|
|
394
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Exchange requests created by customers will appear here." })
|
|
465
395
|
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
466
396
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
467
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
397
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Exchange ID" }),
|
|
468
398
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
469
399
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
470
400
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Difference Due" }),
|
|
@@ -512,9 +442,9 @@ const SwapsPage = () => {
|
|
|
512
442
|
size: "small",
|
|
513
443
|
onClick: (e) => {
|
|
514
444
|
e.stopPropagation();
|
|
515
|
-
navigate(`/
|
|
445
|
+
navigate(`/app/orders/${swap.order_id}`);
|
|
516
446
|
},
|
|
517
|
-
children: "
|
|
447
|
+
children: "Go to order"
|
|
518
448
|
}
|
|
519
449
|
) })
|
|
520
450
|
]
|
|
@@ -534,7 +464,7 @@ const SwapsPage = () => {
|
|
|
534
464
|
] }) });
|
|
535
465
|
};
|
|
536
466
|
const config$2 = adminSdk.defineRouteConfig({
|
|
537
|
-
label: "
|
|
467
|
+
label: "Exchanges",
|
|
538
468
|
icon: icons.ArrowPath
|
|
539
469
|
});
|
|
540
470
|
const getStatusBadgeClass$1 = (status) => {
|
|
@@ -568,7 +498,6 @@ const ReturnDetailPage = () => {
|
|
|
568
498
|
const { id } = reactRouterDom.useParams();
|
|
569
499
|
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
570
500
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
571
|
-
const [isApproving, setIsApproving] = react.useState(false);
|
|
572
501
|
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
573
502
|
const [error, setError] = react.useState(null);
|
|
574
503
|
const [updateError, setUpdateError] = react.useState(null);
|
|
@@ -600,48 +529,6 @@ const ReturnDetailPage = () => {
|
|
|
600
529
|
};
|
|
601
530
|
void loadReturn();
|
|
602
531
|
}, [id, navigate]);
|
|
603
|
-
const handleApprove = async () => {
|
|
604
|
-
if (!id) {
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
607
|
-
try {
|
|
608
|
-
setIsApproving(true);
|
|
609
|
-
setUpdateError(null);
|
|
610
|
-
setUpdateSuccess(false);
|
|
611
|
-
const response = await fetch(`/admin/returns/${id}/approve`, {
|
|
612
|
-
method: "POST",
|
|
613
|
-
headers: {
|
|
614
|
-
"Content-Type": "application/json"
|
|
615
|
-
},
|
|
616
|
-
credentials: "include"
|
|
617
|
-
});
|
|
618
|
-
if (!response.ok) {
|
|
619
|
-
const message = await response.text();
|
|
620
|
-
throw new Error(message || "Unable to approve return");
|
|
621
|
-
}
|
|
622
|
-
const payload = await response.json();
|
|
623
|
-
setReturnOrder(payload.return);
|
|
624
|
-
setUpdateSuccess(true);
|
|
625
|
-
const orderId = payload.return.order_id;
|
|
626
|
-
if (orderId) {
|
|
627
|
-
window.location.href = `/app/orders/${orderId}`;
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
631
|
-
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
632
|
-
credentials: "include"
|
|
633
|
-
});
|
|
634
|
-
if (detailResponse.ok) {
|
|
635
|
-
const detailPayload = await detailResponse.json();
|
|
636
|
-
setReturnOrder(detailPayload.return);
|
|
637
|
-
}
|
|
638
|
-
} catch (approveErr) {
|
|
639
|
-
const message = approveErr instanceof Error ? approveErr.message : "Unable to approve return";
|
|
640
|
-
setUpdateError(message);
|
|
641
|
-
} finally {
|
|
642
|
-
setIsApproving(false);
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
532
|
const handleReject = async () => {
|
|
646
533
|
if (!id) {
|
|
647
534
|
return;
|
|
@@ -721,37 +608,24 @@ const ReturnDetailPage = () => {
|
|
|
721
608
|
] })
|
|
722
609
|
] }),
|
|
723
610
|
returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
724
|
-
/* @__PURE__ */ jsxRuntime.
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
736
|
-
ui.Button,
|
|
737
|
-
{
|
|
738
|
-
variant: "danger",
|
|
739
|
-
onClick: handleReject,
|
|
740
|
-
disabled: isApproving || isRejecting,
|
|
741
|
-
isLoading: isRejecting,
|
|
742
|
-
children: "Reject Return"
|
|
743
|
-
}
|
|
744
|
-
)
|
|
745
|
-
] }),
|
|
746
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Approving will create a Medusa return entity and process the return request" })
|
|
611
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
612
|
+
ui.Button,
|
|
613
|
+
{
|
|
614
|
+
variant: "danger",
|
|
615
|
+
onClick: handleReject,
|
|
616
|
+
disabled: isRejecting,
|
|
617
|
+
isLoading: isRejecting,
|
|
618
|
+
children: "Reject (Cancel) Return"
|
|
619
|
+
}
|
|
620
|
+
) }),
|
|
621
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: 'Cancel this return request. Use "Mark as received" when items are received.' })
|
|
747
622
|
] }),
|
|
748
|
-
|
|
749
|
-
returnOrder.status === "approved" && returnOrder.medusa_return_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
623
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
750
624
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
751
625
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
752
626
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
753
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
754
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.
|
|
627
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
628
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
755
629
|
] }),
|
|
756
630
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
757
631
|
ui.Button,
|
|
@@ -763,7 +637,7 @@ const ReturnDetailPage = () => {
|
|
|
763
637
|
"_blank"
|
|
764
638
|
);
|
|
765
639
|
},
|
|
766
|
-
children: "View
|
|
640
|
+
children: "View order"
|
|
767
641
|
}
|
|
768
642
|
) })
|
|
769
643
|
] })
|
|
@@ -885,26 +759,26 @@ const getStatusBadgeClass = (status) => {
|
|
|
885
759
|
if (statusLower === "completed") {
|
|
886
760
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
887
761
|
}
|
|
888
|
-
if (statusLower === "cancelled") {
|
|
762
|
+
if (statusLower === "cancelled" || statusLower === "canceled") {
|
|
889
763
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
890
764
|
}
|
|
765
|
+
if (statusLower === "pending") {
|
|
766
|
+
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
767
|
+
}
|
|
891
768
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
892
769
|
};
|
|
893
770
|
const SwapDetailPage = () => {
|
|
894
|
-
var _a, _b;
|
|
771
|
+
var _a, _b, _c;
|
|
895
772
|
const navigate = reactRouterDom.useNavigate();
|
|
896
773
|
const { id } = reactRouterDom.useParams();
|
|
897
774
|
const [swap, setSwap] = react.useState(null);
|
|
898
775
|
const [order, setOrder] = react.useState(null);
|
|
899
|
-
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
900
776
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
901
|
-
|
|
902
|
-
const [
|
|
903
|
-
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
777
|
+
react.useState(false);
|
|
778
|
+
const [isCancelling, setIsCancelling] = react.useState(false);
|
|
904
779
|
const [error, setError] = react.useState(null);
|
|
905
780
|
const [updateError, setUpdateError] = react.useState(null);
|
|
906
781
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
907
|
-
const availableStatuses = ["requested", "approved", "rejected"];
|
|
908
782
|
react.useEffect(() => {
|
|
909
783
|
if (!id) {
|
|
910
784
|
navigate("/swaps");
|
|
@@ -924,7 +798,6 @@ const SwapDetailPage = () => {
|
|
|
924
798
|
const payload = await response.json();
|
|
925
799
|
setSwap(payload.swap);
|
|
926
800
|
setOrder(payload.order || null);
|
|
927
|
-
setSelectedStatus("");
|
|
928
801
|
} catch (loadError) {
|
|
929
802
|
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
930
803
|
setError(message);
|
|
@@ -934,55 +807,15 @@ const SwapDetailPage = () => {
|
|
|
934
807
|
};
|
|
935
808
|
void loadSwap();
|
|
936
809
|
}, [id, navigate]);
|
|
937
|
-
const
|
|
938
|
-
if (!id || !selectedStatus) {
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
try {
|
|
942
|
-
setIsUpdating(true);
|
|
943
|
-
setUpdateError(null);
|
|
944
|
-
setUpdateSuccess(false);
|
|
945
|
-
const response = await fetch(`/admin/swaps/${id}/status`, {
|
|
946
|
-
method: "POST",
|
|
947
|
-
headers: {
|
|
948
|
-
"Content-Type": "application/json"
|
|
949
|
-
},
|
|
950
|
-
credentials: "include",
|
|
951
|
-
body: JSON.stringify({ status: selectedStatus })
|
|
952
|
-
});
|
|
953
|
-
if (!response.ok) {
|
|
954
|
-
const message = await response.text();
|
|
955
|
-
throw new Error(message || "Unable to update status");
|
|
956
|
-
}
|
|
957
|
-
const payload = await response.json();
|
|
958
|
-
setSwap(payload.swap);
|
|
959
|
-
setSelectedStatus("");
|
|
960
|
-
setUpdateSuccess(true);
|
|
961
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
962
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
963
|
-
credentials: "include"
|
|
964
|
-
});
|
|
965
|
-
if (detailResponse.ok) {
|
|
966
|
-
const detailPayload = await detailResponse.json();
|
|
967
|
-
setSwap(detailPayload.swap);
|
|
968
|
-
setOrder(detailPayload.order || null);
|
|
969
|
-
}
|
|
970
|
-
} catch (updateErr) {
|
|
971
|
-
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
972
|
-
setUpdateError(message);
|
|
973
|
-
} finally {
|
|
974
|
-
setIsUpdating(false);
|
|
975
|
-
}
|
|
976
|
-
};
|
|
977
|
-
const handleAutoCreateExchange = async () => {
|
|
810
|
+
const handleCancelExchange = async () => {
|
|
978
811
|
if (!id) {
|
|
979
812
|
return;
|
|
980
813
|
}
|
|
981
814
|
try {
|
|
982
|
-
|
|
815
|
+
setIsCancelling(true);
|
|
983
816
|
setUpdateError(null);
|
|
984
817
|
setUpdateSuccess(false);
|
|
985
|
-
const response = await fetch(`/admin/swaps/${id}/
|
|
818
|
+
const response = await fetch(`/admin/swaps/${id}/cancel`, {
|
|
986
819
|
method: "POST",
|
|
987
820
|
headers: {
|
|
988
821
|
"Content-Type": "application/json"
|
|
@@ -991,51 +824,7 @@ const SwapDetailPage = () => {
|
|
|
991
824
|
});
|
|
992
825
|
if (!response.ok) {
|
|
993
826
|
const message = await response.text();
|
|
994
|
-
throw new Error(message || "Unable to
|
|
995
|
-
}
|
|
996
|
-
const payload = await response.json();
|
|
997
|
-
setSwap(payload.swap);
|
|
998
|
-
setUpdateSuccess(true);
|
|
999
|
-
const orderId = payload.swap.order_id;
|
|
1000
|
-
if (orderId) {
|
|
1001
|
-
window.location.href = `/app/orders/${orderId}`;
|
|
1002
|
-
return;
|
|
1003
|
-
}
|
|
1004
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1005
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
1006
|
-
credentials: "include"
|
|
1007
|
-
});
|
|
1008
|
-
if (detailResponse.ok) {
|
|
1009
|
-
const detailPayload = await detailResponse.json();
|
|
1010
|
-
setSwap(detailPayload.swap);
|
|
1011
|
-
setOrder(detailPayload.order || null);
|
|
1012
|
-
}
|
|
1013
|
-
} catch (approveErr) {
|
|
1014
|
-
const message = approveErr instanceof Error ? approveErr.message : "Unable to create exchange from swap";
|
|
1015
|
-
setUpdateError(message);
|
|
1016
|
-
} finally {
|
|
1017
|
-
setIsApproving(false);
|
|
1018
|
-
}
|
|
1019
|
-
};
|
|
1020
|
-
const handleReject = async () => {
|
|
1021
|
-
if (!id) {
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
try {
|
|
1025
|
-
setIsRejecting(true);
|
|
1026
|
-
setUpdateError(null);
|
|
1027
|
-
setUpdateSuccess(false);
|
|
1028
|
-
const response = await fetch(`/admin/swaps/${id}/reject`, {
|
|
1029
|
-
method: "POST",
|
|
1030
|
-
headers: {
|
|
1031
|
-
"Content-Type": "application/json"
|
|
1032
|
-
},
|
|
1033
|
-
credentials: "include",
|
|
1034
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
1035
|
-
});
|
|
1036
|
-
if (!response.ok) {
|
|
1037
|
-
const message = await response.text();
|
|
1038
|
-
throw new Error(message || "Unable to reject swap");
|
|
827
|
+
throw new Error(message || "Unable to cancel exchange");
|
|
1039
828
|
}
|
|
1040
829
|
const payload = await response.json();
|
|
1041
830
|
setSwap(payload.swap);
|
|
@@ -1049,13 +838,17 @@ const SwapDetailPage = () => {
|
|
|
1049
838
|
setSwap(detailPayload.swap);
|
|
1050
839
|
setOrder(detailPayload.order || null);
|
|
1051
840
|
}
|
|
1052
|
-
} catch (
|
|
1053
|
-
const message =
|
|
841
|
+
} catch (cancelErr) {
|
|
842
|
+
const message = cancelErr instanceof Error ? cancelErr.message : "Unable to cancel exchange";
|
|
1054
843
|
setUpdateError(message);
|
|
1055
844
|
} finally {
|
|
1056
|
-
|
|
845
|
+
setIsCancelling(false);
|
|
1057
846
|
}
|
|
1058
847
|
};
|
|
848
|
+
const isOrderExchange = Boolean(swap == null ? void 0 : swap.exchange_id);
|
|
849
|
+
const canCancelExchange = isOrderExchange && swap && !["cancelled", "canceled", "completed", "declined"].includes(
|
|
850
|
+
((_a = swap.status) == null ? void 0 : _a.toLowerCase()) ?? ""
|
|
851
|
+
);
|
|
1059
852
|
if (isLoading) {
|
|
1060
853
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
|
|
1061
854
|
}
|
|
@@ -1065,7 +858,7 @@ const SwapDetailPage = () => {
|
|
|
1065
858
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/swaps"), children: "Back to list" }) })
|
|
1066
859
|
] }) }) });
|
|
1067
860
|
}
|
|
1068
|
-
const statusHistory = ((
|
|
861
|
+
const statusHistory = ((_b = swap.metadata) == null ? void 0 : _b.status_history) || [];
|
|
1069
862
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
1070
863
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
1071
864
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1083,7 +876,7 @@ const SwapDetailPage = () => {
|
|
|
1083
876
|
),
|
|
1084
877
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
1085
878
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1086
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
879
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Exchange Details" }),
|
|
1087
880
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
1088
881
|
] }),
|
|
1089
882
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1096,88 +889,25 @@ const SwapDetailPage = () => {
|
|
|
1096
889
|
)
|
|
1097
890
|
] })
|
|
1098
891
|
] }),
|
|
1099
|
-
|
|
1100
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1112
|
-
ui.Button,
|
|
1113
|
-
{
|
|
1114
|
-
variant: "danger",
|
|
1115
|
-
onClick: handleReject,
|
|
1116
|
-
disabled: isApproving || isRejecting,
|
|
1117
|
-
isLoading: isRejecting,
|
|
1118
|
-
children: "Reject Swap"
|
|
1119
|
-
}
|
|
1120
|
-
)
|
|
1121
|
-
] }),
|
|
1122
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Approving will automatically create an exchange with return items and new items from the swap request" })
|
|
1123
|
-
] }),
|
|
1124
|
-
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1125
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Update Status" }),
|
|
1126
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end", children: [
|
|
1127
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
1128
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-2 block text-sm font-medium text-ui-fg-base", children: "New Status" }),
|
|
1129
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1130
|
-
"select",
|
|
1131
|
-
{
|
|
1132
|
-
value: selectedStatus,
|
|
1133
|
-
onChange: (event) => setSelectedStatus(event.target.value),
|
|
1134
|
-
className: "h-9 w-full rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive",
|
|
1135
|
-
children: [
|
|
1136
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
1137
|
-
availableStatuses.filter((status) => status !== swap.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1138
|
-
]
|
|
1139
|
-
}
|
|
1140
|
-
)
|
|
1141
|
-
] }),
|
|
1142
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1143
|
-
ui.Button,
|
|
1144
|
-
{
|
|
1145
|
-
variant: "primary",
|
|
1146
|
-
onClick: handleStatusUpdate,
|
|
1147
|
-
disabled: !selectedStatus || isUpdating,
|
|
1148
|
-
isLoading: isUpdating,
|
|
1149
|
-
children: "Update Status"
|
|
1150
|
-
}
|
|
1151
|
-
)
|
|
1152
|
-
] }),
|
|
1153
|
-
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
1154
|
-
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
1155
|
-
] }),
|
|
1156
|
-
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1157
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
1158
|
-
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1159
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1160
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1161
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1162
|
-
] }),
|
|
1163
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1164
|
-
ui.Button,
|
|
1165
|
-
{
|
|
1166
|
-
variant: "secondary",
|
|
1167
|
-
onClick: () => {
|
|
1168
|
-
window.open(`/app/orders/${swap.order_id}/exchanges/${swap.exchange_id}`, "_blank");
|
|
1169
|
-
},
|
|
1170
|
-
children: "View Exchange"
|
|
1171
|
-
}
|
|
1172
|
-
) })
|
|
1173
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange is being created. Please refresh the page to see the exchange details." }) })
|
|
892
|
+
canCancelExchange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
893
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
894
|
+
ui.Button,
|
|
895
|
+
{
|
|
896
|
+
variant: "danger",
|
|
897
|
+
onClick: handleCancelExchange,
|
|
898
|
+
disabled: isCancelling,
|
|
899
|
+
isLoading: isCancelling,
|
|
900
|
+
children: "Cancel Exchange"
|
|
901
|
+
}
|
|
902
|
+
) }),
|
|
903
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This will cancel the exchange request. The order will remain unchanged." })
|
|
1174
904
|
] }),
|
|
1175
905
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1176
906
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1177
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
907
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
1178
908
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1179
909
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1180
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
910
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1181
911
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
1182
912
|
] }),
|
|
1183
913
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
@@ -1249,7 +979,7 @@ const SwapDetailPage = () => {
|
|
|
1249
979
|
] }),
|
|
1250
980
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1251
981
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
1252
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = order.customer) == null ? void 0 : _c.email) || order.email || "—" })
|
|
1253
983
|
] }),
|
|
1254
984
|
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1255
985
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
@@ -1295,12 +1025,7 @@ const config = adminSdk.defineRouteConfig({
|
|
|
1295
1025
|
icon: icons.ArrowPath
|
|
1296
1026
|
});
|
|
1297
1027
|
const i18nTranslations0 = {};
|
|
1298
|
-
const widgetModule = { widgets: [
|
|
1299
|
-
{
|
|
1300
|
-
Component: OrderReturnApprovalNoticeWidget,
|
|
1301
|
-
zone: ["order.details.before"]
|
|
1302
|
-
}
|
|
1303
|
-
] };
|
|
1028
|
+
const widgetModule = { widgets: [] };
|
|
1304
1029
|
const routeModule = {
|
|
1305
1030
|
routes: [
|
|
1306
1031
|
{
|
|
@@ -1323,12 +1048,6 @@ const routeModule = {
|
|
|
1323
1048
|
};
|
|
1324
1049
|
const menuItemModule = {
|
|
1325
1050
|
menuItems: [
|
|
1326
|
-
{
|
|
1327
|
-
label: config$3.label,
|
|
1328
|
-
icon: config$3.icon,
|
|
1329
|
-
path: "/returns",
|
|
1330
|
-
nested: void 0
|
|
1331
|
-
},
|
|
1332
1051
|
{
|
|
1333
1052
|
label: config$2.label,
|
|
1334
1053
|
icon: config$2.icon,
|
|
@@ -1336,9 +1055,9 @@ const menuItemModule = {
|
|
|
1336
1055
|
nested: void 0
|
|
1337
1056
|
},
|
|
1338
1057
|
{
|
|
1339
|
-
label: config$
|
|
1340
|
-
icon: config$
|
|
1341
|
-
path: "/returns
|
|
1058
|
+
label: config$3.label,
|
|
1059
|
+
icon: config$3.icon,
|
|
1060
|
+
path: "/returns",
|
|
1342
1061
|
nested: void 0
|
|
1343
1062
|
},
|
|
1344
1063
|
{
|
|
@@ -1346,6 +1065,12 @@ const menuItemModule = {
|
|
|
1346
1065
|
icon: config.icon,
|
|
1347
1066
|
path: "/swaps/:id",
|
|
1348
1067
|
nested: void 0
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
label: config$1.label,
|
|
1071
|
+
icon: config$1.icon,
|
|
1072
|
+
path: "/returns/:id",
|
|
1073
|
+
nested: void 0
|
|
1349
1074
|
}
|
|
1350
1075
|
]
|
|
1351
1076
|
};
|