order-management 0.0.37 → 0.0.38
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 +394 -378
- package/.medusa/server/src/admin/index.mjs +395 -379
- package/.medusa/server/src/api/admin/returns/[id]/approve/route.js +115 -0
- package/.medusa/server/src/api/admin/returns/[id]/mark-received/route.js +44 -0
- package/.medusa/server/src/api/admin/returns/[id]/process-refund/route.js +44 -0
- package/.medusa/server/src/api/admin/returns/[id]/reject/route.js +56 -0
- package/.medusa/server/src/api/admin/returns/[id]/route.js +69 -86
- package/.medusa/server/src/api/admin/returns/route.js +62 -168
- package/.medusa/server/src/api/admin/returns/validators.js +15 -2
- package/.medusa/server/src/api/store/orders/[order_id]/returns/route.js +91 -0
- package/.medusa/server/src/api/store/orders/[order_id]/swaps/route.js +5 -5
- package/.medusa/server/src/api/store/orders/cancel/[order_id]/route.js +3 -3
- package/.medusa/server/src/api/store/orders/reorder/[order_id]/route.js +3 -3
- package/.medusa/server/src/api/store/returns/[id]/cancel/route.js +53 -0
- package/.medusa/server/src/api/store/returns/[id]/route.js +73 -0
- package/.medusa/server/src/api/store/returns/route.js +240 -0
- package/.medusa/server/src/api/store/swaps/[id]/cancel/route.js +3 -3
- package/.medusa/server/src/api/store/swaps/[id]/route.js +5 -5
- package/.medusa/server/src/api/store/swaps/route.js +5 -5
- package/.medusa/server/src/helpers/returns.js +216 -0
- package/.medusa/server/src/modules/return/index.js +13 -0
- package/.medusa/server/src/modules/return/migrations/Migration20260205000001.js +57 -0
- package/.medusa/server/src/modules/return/models/return.js +21 -0
- package/.medusa/server/src/modules/return/service.js +417 -0
- package/.medusa/server/src/services/otp-service.js +3 -2
- package/.medusa/server/src/subscribers/return-created.js +162 -0
- package/.medusa/server/src/subscribers/return-received.js +75 -0
- package/.medusa/server/src/subscribers/return-refunded.js +258 -0
- package/.medusa/server/src/workflows/index.js +8 -2
- package/.medusa/server/src/workflows/returns/create-return-workflow.js +43 -0
- package/.medusa/server/src/workflows/returns/types.js +3 -0
- package/.medusa/server/src/workflows/returns/update-return-status-workflow.js +23 -0
- package/.medusa/server/src/workflows/returns/update-return-workflow.js +18 -0
- package/.medusa/server/src/workflows/steps/index.js +17 -1
- package/.medusa/server/src/workflows/steps/return/calculate-refund-step.js +21 -0
- package/.medusa/server/src/workflows/steps/return/create-medusa-refund-step.js +41 -0
- package/.medusa/server/src/workflows/steps/return/create-return-step.js +22 -0
- package/.medusa/server/src/workflows/steps/return/index.js +28 -0
- package/.medusa/server/src/workflows/steps/return/retrieve-return-step.js +18 -0
- package/.medusa/server/src/workflows/steps/return/rollback-refund-step.js +46 -0
- package/.medusa/server/src/workflows/steps/return/sync-medusa-return-status-step.js +51 -0
- package/.medusa/server/src/workflows/steps/return/update-return-status-step.js +18 -0
- package/.medusa/server/src/workflows/steps/return/update-return-step.js +23 -0
- package/.medusa/server/src/workflows/steps/return/validate-eligibility-step.js +22 -0
- package/.medusa/server/src/workflows/steps/return/validate-order-step.js +108 -0
- package/.medusa/server/src/workflows/steps/return/validate-return-items-step.js +100 -0
- package/README.md +327 -0
- package/package.json +1 -1
|
@@ -18,21 +18,21 @@ const getStatusBadgeClass$3 = (status) => {
|
|
|
18
18
|
if (statusLower === "requested") {
|
|
19
19
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
20
20
|
}
|
|
21
|
-
if (statusLower === "
|
|
21
|
+
if (statusLower === "received") {
|
|
22
22
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
23
23
|
}
|
|
24
|
-
if (statusLower === "
|
|
24
|
+
if (statusLower === "requires_action") {
|
|
25
25
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
26
26
|
}
|
|
27
27
|
if (statusLower === "completed") {
|
|
28
28
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
29
29
|
}
|
|
30
|
-
if (statusLower === "
|
|
30
|
+
if (statusLower === "canceled") {
|
|
31
31
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
32
32
|
}
|
|
33
33
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
34
34
|
};
|
|
35
|
-
const
|
|
35
|
+
const ReturnsPage = () => {
|
|
36
36
|
const navigate = reactRouterDom.useNavigate();
|
|
37
37
|
const [items, setItems] = react.useState([]);
|
|
38
38
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
@@ -44,7 +44,7 @@ const SwapsPage = () => {
|
|
|
44
44
|
const [offset, setOffset] = react.useState(0);
|
|
45
45
|
const [count, setCount] = react.useState(0);
|
|
46
46
|
const limit = 50;
|
|
47
|
-
const
|
|
47
|
+
const loadReturns = react.useCallback(
|
|
48
48
|
async (nextOffset, replace = false) => {
|
|
49
49
|
var _a;
|
|
50
50
|
try {
|
|
@@ -61,24 +61,25 @@ const SwapsPage = () => {
|
|
|
61
61
|
params.set("status", statusFilter);
|
|
62
62
|
}
|
|
63
63
|
if (debouncedSearchQuery.trim()) {
|
|
64
|
-
params.set("
|
|
64
|
+
params.set("q", debouncedSearchQuery.trim());
|
|
65
65
|
}
|
|
66
|
+
params.set("order", "created_at");
|
|
66
67
|
const response = await fetch(
|
|
67
|
-
`/admin/
|
|
68
|
+
`/admin/returns?${params.toString()}`,
|
|
68
69
|
{ credentials: "include" }
|
|
69
70
|
);
|
|
70
71
|
if (!response.ok) {
|
|
71
72
|
const message = await response.text();
|
|
72
|
-
throw new Error(message || "Unable to load
|
|
73
|
+
throw new Error(message || "Unable to load return orders");
|
|
73
74
|
}
|
|
74
75
|
const payload = await response.json();
|
|
75
76
|
setCount(payload.count ?? 0);
|
|
76
|
-
setOffset(nextOffset + (((_a = payload.
|
|
77
|
+
setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
|
|
77
78
|
setItems(
|
|
78
|
-
(prev) => replace ? payload.
|
|
79
|
+
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
79
80
|
);
|
|
80
81
|
} catch (loadError) {
|
|
81
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
82
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
82
83
|
setError(message);
|
|
83
84
|
} finally {
|
|
84
85
|
setIsLoading(false);
|
|
@@ -88,8 +89,8 @@ const SwapsPage = () => {
|
|
|
88
89
|
[statusFilter, debouncedSearchQuery]
|
|
89
90
|
);
|
|
90
91
|
react.useEffect(() => {
|
|
91
|
-
void
|
|
92
|
-
}, [statusFilter, debouncedSearchQuery,
|
|
92
|
+
void loadReturns(0, true);
|
|
93
|
+
}, [statusFilter, debouncedSearchQuery, loadReturns]);
|
|
93
94
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
94
95
|
const availableStatuses = react.useMemo(() => {
|
|
95
96
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -99,16 +100,16 @@ const SwapsPage = () => {
|
|
|
99
100
|
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: [
|
|
100
101
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
101
102
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
102
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
103
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
103
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
|
|
104
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
104
105
|
] }),
|
|
105
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
106
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
106
107
|
] }),
|
|
107
108
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
108
109
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
109
110
|
ui.Input,
|
|
110
111
|
{
|
|
111
|
-
placeholder: "Search by
|
|
112
|
+
placeholder: "Search by return ID, order ID, or customer email",
|
|
112
113
|
value: searchQuery,
|
|
113
114
|
onChange: (event) => setSearchQuery(event.target.value),
|
|
114
115
|
className: "md:max-w-sm"
|
|
@@ -133,50 +134,51 @@ const SwapsPage = () => {
|
|
|
133
134
|
ui.Button,
|
|
134
135
|
{
|
|
135
136
|
variant: "secondary",
|
|
136
|
-
onClick: () =>
|
|
137
|
+
onClick: () => loadReturns(0, true),
|
|
137
138
|
children: "Try again"
|
|
138
139
|
}
|
|
139
140
|
) })
|
|
140
141
|
] }) : null,
|
|
141
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
142
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
143
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
142
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return orders..." }) }) : items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
143
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
144
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
144
145
|
] }) : /* @__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: [
|
|
145
146
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
146
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
147
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Return ID" }),
|
|
147
148
|
/* @__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" }),
|
|
149
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
148
150
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
149
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
151
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund Amount" }),
|
|
150
152
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
151
153
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
152
154
|
] }) }),
|
|
153
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
155
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
154
156
|
"tr",
|
|
155
157
|
{
|
|
156
158
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
157
|
-
onClick: () => navigate(`/
|
|
159
|
+
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
158
160
|
children: [
|
|
159
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children:
|
|
160
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
161
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: returnOrder.id }) }) }),
|
|
162
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
163
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
161
164
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
162
165
|
ui.Badge,
|
|
163
166
|
{
|
|
164
167
|
size: "2xsmall",
|
|
165
|
-
className: `uppercase ${getStatusBadgeClass$3(
|
|
166
|
-
children:
|
|
168
|
+
className: `uppercase ${getStatusBadgeClass$3(returnOrder.status)}`,
|
|
169
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
167
170
|
}
|
|
168
171
|
) }),
|
|
169
172
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
170
|
-
const amount =
|
|
173
|
+
const amount = returnOrder.refund_amount;
|
|
171
174
|
if (amount == null || amount === void 0) {
|
|
172
175
|
return "—";
|
|
173
176
|
}
|
|
174
177
|
const displayAmount = Number(amount) / 100;
|
|
175
|
-
const currency =
|
|
176
|
-
|
|
177
|
-
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
178
|
+
const currency = returnOrder.currency_code || "$";
|
|
179
|
+
return `${currency}${displayAmount.toFixed(2)}`;
|
|
178
180
|
})() }),
|
|
179
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(
|
|
181
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
180
182
|
year: "numeric",
|
|
181
183
|
month: "short",
|
|
182
184
|
day: "numeric",
|
|
@@ -191,14 +193,14 @@ const SwapsPage = () => {
|
|
|
191
193
|
size: "small",
|
|
192
194
|
onClick: (e) => {
|
|
193
195
|
e.stopPropagation();
|
|
194
|
-
navigate(`/
|
|
196
|
+
navigate(`/returns/${returnOrder.id}`);
|
|
195
197
|
},
|
|
196
198
|
children: "View"
|
|
197
199
|
}
|
|
198
200
|
) })
|
|
199
201
|
]
|
|
200
202
|
},
|
|
201
|
-
|
|
203
|
+
returnOrder.id
|
|
202
204
|
)) })
|
|
203
205
|
] }) }),
|
|
204
206
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -206,14 +208,14 @@ const SwapsPage = () => {
|
|
|
206
208
|
{
|
|
207
209
|
variant: "secondary",
|
|
208
210
|
isLoading: isFetchingMore,
|
|
209
|
-
onClick: () =>
|
|
211
|
+
onClick: () => loadReturns(offset, false),
|
|
210
212
|
children: "Load more"
|
|
211
213
|
}
|
|
212
214
|
) }) : null
|
|
213
215
|
] }) });
|
|
214
216
|
};
|
|
215
217
|
const config$3 = adminSdk.defineRouteConfig({
|
|
216
|
-
label: "
|
|
218
|
+
label: "Return Orders",
|
|
217
219
|
icon: icons.ArrowPath
|
|
218
220
|
});
|
|
219
221
|
const useDebounce = (value, delay) => {
|
|
@@ -229,21 +231,21 @@ const getStatusBadgeClass$2 = (status) => {
|
|
|
229
231
|
if (statusLower === "requested") {
|
|
230
232
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
231
233
|
}
|
|
232
|
-
if (statusLower === "
|
|
234
|
+
if (statusLower === "approved") {
|
|
233
235
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
234
236
|
}
|
|
235
|
-
if (statusLower === "
|
|
237
|
+
if (statusLower === "rejected") {
|
|
236
238
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
237
239
|
}
|
|
238
240
|
if (statusLower === "completed") {
|
|
239
241
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
240
242
|
}
|
|
241
|
-
if (statusLower === "
|
|
243
|
+
if (statusLower === "cancelled") {
|
|
242
244
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
243
245
|
}
|
|
244
246
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
245
247
|
};
|
|
246
|
-
const
|
|
248
|
+
const SwapsPage = () => {
|
|
247
249
|
const navigate = reactRouterDom.useNavigate();
|
|
248
250
|
const [items, setItems] = react.useState([]);
|
|
249
251
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
@@ -255,7 +257,7 @@ const ReturnsPage = () => {
|
|
|
255
257
|
const [offset, setOffset] = react.useState(0);
|
|
256
258
|
const [count, setCount] = react.useState(0);
|
|
257
259
|
const limit = 50;
|
|
258
|
-
const
|
|
260
|
+
const loadSwaps = react.useCallback(
|
|
259
261
|
async (nextOffset, replace = false) => {
|
|
260
262
|
var _a;
|
|
261
263
|
try {
|
|
@@ -272,25 +274,24 @@ const ReturnsPage = () => {
|
|
|
272
274
|
params.set("status", statusFilter);
|
|
273
275
|
}
|
|
274
276
|
if (debouncedSearchQuery.trim()) {
|
|
275
|
-
params.set("
|
|
277
|
+
params.set("order_id", debouncedSearchQuery.trim());
|
|
276
278
|
}
|
|
277
|
-
params.set("order", "created_at");
|
|
278
279
|
const response = await fetch(
|
|
279
|
-
`/admin/
|
|
280
|
+
`/admin/swaps?${params.toString()}`,
|
|
280
281
|
{ credentials: "include" }
|
|
281
282
|
);
|
|
282
283
|
if (!response.ok) {
|
|
283
284
|
const message = await response.text();
|
|
284
|
-
throw new Error(message || "Unable to load
|
|
285
|
+
throw new Error(message || "Unable to load swaps");
|
|
285
286
|
}
|
|
286
287
|
const payload = await response.json();
|
|
287
288
|
setCount(payload.count ?? 0);
|
|
288
|
-
setOffset(nextOffset + (((_a = payload.
|
|
289
|
+
setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
|
|
289
290
|
setItems(
|
|
290
|
-
(prev) => replace ? payload.
|
|
291
|
+
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
291
292
|
);
|
|
292
293
|
} catch (loadError) {
|
|
293
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
294
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
294
295
|
setError(message);
|
|
295
296
|
} finally {
|
|
296
297
|
setIsLoading(false);
|
|
@@ -300,8 +301,8 @@ const ReturnsPage = () => {
|
|
|
300
301
|
[statusFilter, debouncedSearchQuery]
|
|
301
302
|
);
|
|
302
303
|
react.useEffect(() => {
|
|
303
|
-
void
|
|
304
|
-
}, [statusFilter, debouncedSearchQuery,
|
|
304
|
+
void loadSwaps(0, true);
|
|
305
|
+
}, [statusFilter, debouncedSearchQuery, loadSwaps]);
|
|
305
306
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
306
307
|
const availableStatuses = react.useMemo(() => {
|
|
307
308
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -311,16 +312,16 @@ const ReturnsPage = () => {
|
|
|
311
312
|
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: [
|
|
312
313
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
313
314
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
314
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
315
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
315
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Swaps" }),
|
|
316
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer swap requests" })
|
|
316
317
|
] }),
|
|
317
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
318
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
318
319
|
] }),
|
|
319
320
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
320
321
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
321
322
|
ui.Input,
|
|
322
323
|
{
|
|
323
|
-
placeholder: "Search by
|
|
324
|
+
placeholder: "Search by swap ID or order ID",
|
|
324
325
|
value: searchQuery,
|
|
325
326
|
onChange: (event) => setSearchQuery(event.target.value),
|
|
326
327
|
className: "md:max-w-sm"
|
|
@@ -345,51 +346,50 @@ const ReturnsPage = () => {
|
|
|
345
346
|
ui.Button,
|
|
346
347
|
{
|
|
347
348
|
variant: "secondary",
|
|
348
|
-
onClick: () =>
|
|
349
|
+
onClick: () => loadSwaps(0, true),
|
|
349
350
|
children: "Try again"
|
|
350
351
|
}
|
|
351
352
|
) })
|
|
352
353
|
] }) : null,
|
|
353
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
354
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
355
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
354
|
+
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: [
|
|
355
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No swaps yet" }),
|
|
356
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Swap requests created by customers will appear here." })
|
|
356
357
|
] }) : /* @__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: [
|
|
357
358
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
358
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
359
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Swap ID" }),
|
|
359
360
|
/* @__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" }),
|
|
360
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
361
361
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
362
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
362
|
+
/* @__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" }),
|
|
363
363
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
364
364
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
365
365
|
] }) }),
|
|
366
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
366
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
367
367
|
"tr",
|
|
368
368
|
{
|
|
369
369
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
370
|
-
onClick: () => navigate(`/
|
|
370
|
+
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
371
371
|
children: [
|
|
372
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children:
|
|
373
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
374
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
372
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: swap.id }) }) }),
|
|
373
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
375
374
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
376
375
|
ui.Badge,
|
|
377
376
|
{
|
|
378
377
|
size: "2xsmall",
|
|
379
|
-
className: `uppercase ${getStatusBadgeClass$2(
|
|
380
|
-
children:
|
|
378
|
+
className: `uppercase ${getStatusBadgeClass$2(swap.status)}`,
|
|
379
|
+
children: swap.status.replace(/_/g, " ")
|
|
381
380
|
}
|
|
382
381
|
) }),
|
|
383
382
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
384
|
-
const amount =
|
|
383
|
+
const amount = swap.difference_due;
|
|
385
384
|
if (amount == null || amount === void 0) {
|
|
386
385
|
return "—";
|
|
387
386
|
}
|
|
388
387
|
const displayAmount = Number(amount) / 100;
|
|
389
|
-
const currency =
|
|
390
|
-
|
|
388
|
+
const currency = swap.currency_code || "$";
|
|
389
|
+
const sign = displayAmount >= 0 ? "+" : "";
|
|
390
|
+
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
391
391
|
})() }),
|
|
392
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(
|
|
392
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
393
393
|
year: "numeric",
|
|
394
394
|
month: "short",
|
|
395
395
|
day: "numeric",
|
|
@@ -404,14 +404,14 @@ const ReturnsPage = () => {
|
|
|
404
404
|
size: "small",
|
|
405
405
|
onClick: (e) => {
|
|
406
406
|
e.stopPropagation();
|
|
407
|
-
navigate(`/
|
|
407
|
+
navigate(`/swaps/${swap.id}`);
|
|
408
408
|
},
|
|
409
409
|
children: "View"
|
|
410
410
|
}
|
|
411
411
|
) })
|
|
412
412
|
]
|
|
413
413
|
},
|
|
414
|
-
|
|
414
|
+
swap.id
|
|
415
415
|
)) })
|
|
416
416
|
] }) }),
|
|
417
417
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -419,14 +419,14 @@ const ReturnsPage = () => {
|
|
|
419
419
|
{
|
|
420
420
|
variant: "secondary",
|
|
421
421
|
isLoading: isFetchingMore,
|
|
422
|
-
onClick: () =>
|
|
422
|
+
onClick: () => loadSwaps(offset, false),
|
|
423
423
|
children: "Load more"
|
|
424
424
|
}
|
|
425
425
|
) }) : null
|
|
426
426
|
] }) });
|
|
427
427
|
};
|
|
428
428
|
const config$2 = adminSdk.defineRouteConfig({
|
|
429
|
-
label: "
|
|
429
|
+
label: "Swaps",
|
|
430
430
|
icon: icons.ArrowPath
|
|
431
431
|
});
|
|
432
432
|
const getStatusBadgeClass$1 = (status) => {
|
|
@@ -440,6 +440,12 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
440
440
|
if (statusLower === "rejected") {
|
|
441
441
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
442
442
|
}
|
|
443
|
+
if (statusLower === "received") {
|
|
444
|
+
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
445
|
+
}
|
|
446
|
+
if (statusLower === "refunded") {
|
|
447
|
+
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
448
|
+
}
|
|
443
449
|
if (statusLower === "completed") {
|
|
444
450
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
445
451
|
}
|
|
@@ -448,91 +454,45 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
448
454
|
}
|
|
449
455
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
450
456
|
};
|
|
451
|
-
const
|
|
457
|
+
const ReturnDetailPage = () => {
|
|
452
458
|
var _a, _b;
|
|
453
459
|
const navigate = reactRouterDom.useNavigate();
|
|
454
460
|
const { id } = reactRouterDom.useParams();
|
|
455
|
-
const [
|
|
456
|
-
const [order, setOrder] = react.useState(null);
|
|
457
|
-
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
461
|
+
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
458
462
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
459
|
-
const [isUpdating, setIsUpdating] = react.useState(false);
|
|
460
463
|
const [isApproving, setIsApproving] = react.useState(false);
|
|
461
464
|
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
462
465
|
const [error, setError] = react.useState(null);
|
|
463
466
|
const [updateError, setUpdateError] = react.useState(null);
|
|
464
467
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
465
|
-
const availableStatuses = ["requested", "approved", "rejected"];
|
|
466
468
|
react.useEffect(() => {
|
|
467
469
|
if (!id) {
|
|
468
|
-
navigate("/
|
|
470
|
+
navigate("/returns");
|
|
469
471
|
return;
|
|
470
472
|
}
|
|
471
|
-
const
|
|
473
|
+
const loadReturn = async () => {
|
|
472
474
|
try {
|
|
473
475
|
setIsLoading(true);
|
|
474
476
|
setError(null);
|
|
475
|
-
const response = await fetch(`/admin/
|
|
477
|
+
const response = await fetch(`/admin/returns/${id}`, {
|
|
476
478
|
credentials: "include"
|
|
477
479
|
});
|
|
478
480
|
if (!response.ok) {
|
|
479
481
|
const message = await response.text();
|
|
480
|
-
throw new Error(message || "Unable to load
|
|
482
|
+
throw new Error(message || "Unable to load return order");
|
|
481
483
|
}
|
|
482
484
|
const payload = await response.json();
|
|
483
|
-
|
|
484
|
-
setOrder(payload.order || null);
|
|
485
|
-
setSelectedStatus("");
|
|
485
|
+
setReturnOrder(payload.return);
|
|
486
486
|
} catch (loadError) {
|
|
487
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
487
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
488
488
|
setError(message);
|
|
489
489
|
} finally {
|
|
490
490
|
setIsLoading(false);
|
|
491
491
|
}
|
|
492
492
|
};
|
|
493
|
-
void
|
|
493
|
+
void loadReturn();
|
|
494
494
|
}, [id, navigate]);
|
|
495
|
-
const
|
|
496
|
-
if (!id || !selectedStatus) {
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
try {
|
|
500
|
-
setIsUpdating(true);
|
|
501
|
-
setUpdateError(null);
|
|
502
|
-
setUpdateSuccess(false);
|
|
503
|
-
const response = await fetch(`/admin/swaps/${id}/status`, {
|
|
504
|
-
method: "POST",
|
|
505
|
-
headers: {
|
|
506
|
-
"Content-Type": "application/json"
|
|
507
|
-
},
|
|
508
|
-
credentials: "include",
|
|
509
|
-
body: JSON.stringify({ status: selectedStatus })
|
|
510
|
-
});
|
|
511
|
-
if (!response.ok) {
|
|
512
|
-
const message = await response.text();
|
|
513
|
-
throw new Error(message || "Unable to update status");
|
|
514
|
-
}
|
|
515
|
-
const payload = await response.json();
|
|
516
|
-
setSwap(payload.swap);
|
|
517
|
-
setSelectedStatus("");
|
|
518
|
-
setUpdateSuccess(true);
|
|
519
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
520
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
521
|
-
credentials: "include"
|
|
522
|
-
});
|
|
523
|
-
if (detailResponse.ok) {
|
|
524
|
-
const detailPayload = await detailResponse.json();
|
|
525
|
-
setSwap(detailPayload.swap);
|
|
526
|
-
setOrder(detailPayload.order || null);
|
|
527
|
-
}
|
|
528
|
-
} catch (updateErr) {
|
|
529
|
-
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
530
|
-
setUpdateError(message);
|
|
531
|
-
} finally {
|
|
532
|
-
setIsUpdating(false);
|
|
533
|
-
}
|
|
534
|
-
};
|
|
535
|
-
const handleAutoCreateExchange = async () => {
|
|
495
|
+
const handleApprove = async () => {
|
|
536
496
|
if (!id) {
|
|
537
497
|
return;
|
|
538
498
|
}
|
|
@@ -540,7 +500,7 @@ const SwapDetailPage = () => {
|
|
|
540
500
|
setIsApproving(true);
|
|
541
501
|
setUpdateError(null);
|
|
542
502
|
setUpdateSuccess(false);
|
|
543
|
-
const response = await fetch(`/admin/
|
|
503
|
+
const response = await fetch(`/admin/returns/${id}/approve`, {
|
|
544
504
|
method: "POST",
|
|
545
505
|
headers: {
|
|
546
506
|
"Content-Type": "application/json"
|
|
@@ -549,22 +509,21 @@ const SwapDetailPage = () => {
|
|
|
549
509
|
});
|
|
550
510
|
if (!response.ok) {
|
|
551
511
|
const message = await response.text();
|
|
552
|
-
throw new Error(message || "Unable to
|
|
512
|
+
throw new Error(message || "Unable to approve return");
|
|
553
513
|
}
|
|
554
514
|
const payload = await response.json();
|
|
555
|
-
|
|
515
|
+
setReturnOrder(payload.return);
|
|
556
516
|
setUpdateSuccess(true);
|
|
557
517
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
558
|
-
const detailResponse = await fetch(`/admin/
|
|
518
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
559
519
|
credentials: "include"
|
|
560
520
|
});
|
|
561
521
|
if (detailResponse.ok) {
|
|
562
522
|
const detailPayload = await detailResponse.json();
|
|
563
|
-
|
|
564
|
-
setOrder(detailPayload.order || null);
|
|
523
|
+
setReturnOrder(detailPayload.return);
|
|
565
524
|
}
|
|
566
525
|
} catch (approveErr) {
|
|
567
|
-
const message = approveErr instanceof Error ? approveErr.message : "Unable to
|
|
526
|
+
const message = approveErr instanceof Error ? approveErr.message : "Unable to approve return";
|
|
568
527
|
setUpdateError(message);
|
|
569
528
|
} finally {
|
|
570
529
|
setIsApproving(false);
|
|
@@ -578,7 +537,7 @@ const SwapDetailPage = () => {
|
|
|
578
537
|
setIsRejecting(true);
|
|
579
538
|
setUpdateError(null);
|
|
580
539
|
setUpdateSuccess(false);
|
|
581
|
-
const response = await fetch(`/admin/
|
|
540
|
+
const response = await fetch(`/admin/returns/${id}/reject`, {
|
|
582
541
|
method: "POST",
|
|
583
542
|
headers: {
|
|
584
543
|
"Content-Type": "application/json"
|
|
@@ -588,37 +547,36 @@ const SwapDetailPage = () => {
|
|
|
588
547
|
});
|
|
589
548
|
if (!response.ok) {
|
|
590
549
|
const message = await response.text();
|
|
591
|
-
throw new Error(message || "Unable to reject
|
|
550
|
+
throw new Error(message || "Unable to reject return");
|
|
592
551
|
}
|
|
593
552
|
const payload = await response.json();
|
|
594
|
-
|
|
553
|
+
setReturnOrder(payload.return);
|
|
595
554
|
setUpdateSuccess(true);
|
|
596
555
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
597
|
-
const detailResponse = await fetch(`/admin/
|
|
556
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
598
557
|
credentials: "include"
|
|
599
558
|
});
|
|
600
559
|
if (detailResponse.ok) {
|
|
601
|
-
const detailPayload = await
|
|
602
|
-
|
|
603
|
-
setOrder(detailPayload.order || null);
|
|
560
|
+
const detailPayload = await detailResponse.json();
|
|
561
|
+
setReturnOrder(detailPayload.return);
|
|
604
562
|
}
|
|
605
563
|
} catch (updateErr) {
|
|
606
|
-
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject
|
|
564
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject return";
|
|
607
565
|
setUpdateError(message);
|
|
608
566
|
} finally {
|
|
609
567
|
setIsRejecting(false);
|
|
610
568
|
}
|
|
611
569
|
};
|
|
612
570
|
if (isLoading) {
|
|
613
|
-
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
|
|
571
|
+
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 return order..." }) }) }) });
|
|
614
572
|
}
|
|
615
|
-
if (error || !
|
|
573
|
+
if (error || !returnOrder) {
|
|
616
574
|
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.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
617
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
618
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
575
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
576
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/returns"), children: "Back to list" }) })
|
|
619
577
|
] }) }) });
|
|
620
578
|
}
|
|
621
|
-
const statusHistory = ((_a =
|
|
579
|
+
const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
|
|
622
580
|
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: [
|
|
623
581
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
624
582
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -626,7 +584,7 @@ const SwapDetailPage = () => {
|
|
|
626
584
|
{
|
|
627
585
|
variant: "transparent",
|
|
628
586
|
size: "small",
|
|
629
|
-
onClick: () => navigate("/
|
|
587
|
+
onClick: () => navigate("/returns"),
|
|
630
588
|
className: "w-fit",
|
|
631
589
|
children: [
|
|
632
590
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -636,29 +594,29 @@ const SwapDetailPage = () => {
|
|
|
636
594
|
),
|
|
637
595
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
638
596
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
639
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
640
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
597
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
|
|
598
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
641
599
|
] }),
|
|
642
600
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
643
601
|
ui.Badge,
|
|
644
602
|
{
|
|
645
603
|
size: "small",
|
|
646
|
-
className: `uppercase ${getStatusBadgeClass$1(
|
|
647
|
-
children:
|
|
604
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
605
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
648
606
|
}
|
|
649
607
|
)
|
|
650
608
|
] })
|
|
651
609
|
] }),
|
|
652
|
-
|
|
610
|
+
returnOrder.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
653
611
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
654
612
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
655
613
|
ui.Button,
|
|
656
614
|
{
|
|
657
615
|
variant: "primary",
|
|
658
|
-
onClick:
|
|
616
|
+
onClick: handleApprove,
|
|
659
617
|
disabled: isApproving || isRejecting,
|
|
660
618
|
isLoading: isApproving,
|
|
661
|
-
children: "Approve &
|
|
619
|
+
children: "Approve & Process Return"
|
|
662
620
|
}
|
|
663
621
|
),
|
|
664
622
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -668,98 +626,62 @@ const SwapDetailPage = () => {
|
|
|
668
626
|
onClick: handleReject,
|
|
669
627
|
disabled: isApproving || isRejecting,
|
|
670
628
|
isLoading: isRejecting,
|
|
671
|
-
children: "Reject
|
|
629
|
+
children: "Reject Return"
|
|
672
630
|
}
|
|
673
631
|
)
|
|
674
632
|
] }),
|
|
675
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Approving will
|
|
633
|
+
/* @__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" })
|
|
676
634
|
] }),
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
/* @__PURE__ */ jsxRuntime.
|
|
680
|
-
|
|
681
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-2 block text-sm font-medium text-ui-fg-base", children: "New Status" }),
|
|
682
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
683
|
-
"select",
|
|
684
|
-
{
|
|
685
|
-
value: selectedStatus,
|
|
686
|
-
onChange: (event) => setSelectedStatus(event.target.value),
|
|
687
|
-
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",
|
|
688
|
-
children: [
|
|
689
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
690
|
-
availableStatuses.filter((status) => status !== swap.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
691
|
-
]
|
|
692
|
-
}
|
|
693
|
-
)
|
|
694
|
-
] }),
|
|
695
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
696
|
-
ui.Button,
|
|
697
|
-
{
|
|
698
|
-
variant: "primary",
|
|
699
|
-
onClick: handleStatusUpdate,
|
|
700
|
-
disabled: !selectedStatus || isUpdating,
|
|
701
|
-
isLoading: isUpdating,
|
|
702
|
-
children: "Update Status"
|
|
703
|
-
}
|
|
704
|
-
)
|
|
705
|
-
] }),
|
|
706
|
-
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
707
|
-
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
708
|
-
] }),
|
|
709
|
-
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
710
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
711
|
-
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
635
|
+
(returnOrder.status === "approved" || returnOrder.status === "received" || returnOrder.status === "refunded") && returnOrder.medusa_return_id && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Receive item and process refund from the order detail page (same flow as admin-created returns)." }) }),
|
|
636
|
+
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: [
|
|
637
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
638
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
712
639
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
713
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
714
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
640
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Medusa Return ID" }),
|
|
641
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.medusa_return_id })
|
|
715
642
|
] }),
|
|
716
643
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
717
644
|
ui.Button,
|
|
718
645
|
{
|
|
719
646
|
variant: "secondary",
|
|
720
647
|
onClick: () => {
|
|
721
|
-
window.open(
|
|
648
|
+
window.open(
|
|
649
|
+
`/app/orders/${returnOrder.order_id}`,
|
|
650
|
+
"_blank"
|
|
651
|
+
);
|
|
722
652
|
},
|
|
723
|
-
children: "View
|
|
653
|
+
children: "View in Medusa"
|
|
724
654
|
}
|
|
725
655
|
) })
|
|
726
|
-
] })
|
|
656
|
+
] })
|
|
727
657
|
] }),
|
|
728
658
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
729
659
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
730
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
660
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Details" }),
|
|
731
661
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
732
662
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
733
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
734
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
663
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
664
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
735
665
|
] }),
|
|
736
666
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
737
667
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
738
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
739
|
-
] }),
|
|
740
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
741
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
742
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
668
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
|
|
743
669
|
] }),
|
|
744
|
-
|
|
670
|
+
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
745
671
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
746
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
672
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
747
673
|
] }),
|
|
748
|
-
|
|
674
|
+
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
749
675
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
750
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
676
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
751
677
|
] }),
|
|
752
678
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
753
679
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
754
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
680
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
755
681
|
] }),
|
|
756
682
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
757
683
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
758
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
759
|
-
] }),
|
|
760
|
-
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
761
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
762
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
684
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
763
685
|
] })
|
|
764
686
|
] })
|
|
765
687
|
] }),
|
|
@@ -789,31 +711,31 @@ const SwapDetailPage = () => {
|
|
|
789
711
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
790
712
|
] })
|
|
791
713
|
] }),
|
|
792
|
-
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
714
|
+
returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
793
715
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
794
716
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
795
717
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
796
718
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
797
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
719
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
798
720
|
] }),
|
|
799
721
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
800
722
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
801
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
723
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
802
724
|
] }),
|
|
803
725
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
804
726
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
805
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = order.customer) == null ? void 0 : _b.email) || order.email || "—" })
|
|
727
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = returnOrder.order.customer) == null ? void 0 : _b.email) || returnOrder.order.email || "—" })
|
|
806
728
|
] }),
|
|
807
|
-
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
729
|
+
returnOrder.order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
808
730
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
809
731
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
810
|
-
order.currency_code || "$",
|
|
811
|
-
(Number(order.total) / 100).toFixed(2)
|
|
732
|
+
returnOrder.order.currency_code || "$",
|
|
733
|
+
(Number(returnOrder.order.total) / 100).toFixed(2)
|
|
812
734
|
] })
|
|
813
735
|
] })
|
|
814
736
|
] })
|
|
815
737
|
] }),
|
|
816
|
-
|
|
738
|
+
returnOrder.return_items && returnOrder.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
817
739
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
818
740
|
/* @__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: [
|
|
819
741
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
@@ -821,96 +743,83 @@ const SwapDetailPage = () => {
|
|
|
821
743
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
822
744
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
823
745
|
] }) }),
|
|
824
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
746
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
825
747
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
826
748
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
827
749
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
828
750
|
] }, item.id || index)) })
|
|
829
751
|
] }) })
|
|
830
752
|
] }),
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
/* @__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: [
|
|
834
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
835
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
836
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
837
|
-
] }) }),
|
|
838
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
839
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
840
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
841
|
-
] }, item.variant_id || index)) })
|
|
842
|
-
] }) })
|
|
843
|
-
] })
|
|
753
|
+
updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: updateError }) }),
|
|
754
|
+
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-success", children: "Action completed successfully" }) })
|
|
844
755
|
] }) });
|
|
845
756
|
};
|
|
846
757
|
const config$1 = adminSdk.defineRouteConfig({
|
|
847
|
-
label: "
|
|
848
|
-
icon: icons.
|
|
758
|
+
label: "Return Order Details",
|
|
759
|
+
icon: icons.CheckCircle
|
|
849
760
|
});
|
|
850
761
|
const getStatusBadgeClass = (status) => {
|
|
851
762
|
const statusLower = status.toLowerCase();
|
|
852
763
|
if (statusLower === "requested") {
|
|
853
764
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
854
765
|
}
|
|
855
|
-
if (statusLower === "
|
|
766
|
+
if (statusLower === "approved") {
|
|
856
767
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
857
768
|
}
|
|
858
|
-
if (statusLower === "
|
|
769
|
+
if (statusLower === "rejected") {
|
|
859
770
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
860
771
|
}
|
|
861
772
|
if (statusLower === "completed") {
|
|
862
773
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
863
774
|
}
|
|
864
|
-
if (statusLower === "
|
|
775
|
+
if (statusLower === "cancelled") {
|
|
865
776
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
866
777
|
}
|
|
867
778
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
868
779
|
};
|
|
869
|
-
const
|
|
870
|
-
var _a, _b
|
|
780
|
+
const SwapDetailPage = () => {
|
|
781
|
+
var _a, _b;
|
|
871
782
|
const navigate = reactRouterDom.useNavigate();
|
|
872
783
|
const { id } = reactRouterDom.useParams();
|
|
873
|
-
const [
|
|
784
|
+
const [swap, setSwap] = react.useState(null);
|
|
785
|
+
const [order, setOrder] = react.useState(null);
|
|
874
786
|
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
875
787
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
876
788
|
const [isUpdating, setIsUpdating] = react.useState(false);
|
|
789
|
+
const [isApproving, setIsApproving] = react.useState(false);
|
|
790
|
+
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
877
791
|
const [error, setError] = react.useState(null);
|
|
878
792
|
const [updateError, setUpdateError] = react.useState(null);
|
|
879
793
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
880
|
-
const availableStatuses = [
|
|
881
|
-
"requested",
|
|
882
|
-
"received",
|
|
883
|
-
"requires_action",
|
|
884
|
-
"completed",
|
|
885
|
-
"canceled"
|
|
886
|
-
];
|
|
794
|
+
const availableStatuses = ["requested", "approved", "rejected"];
|
|
887
795
|
react.useEffect(() => {
|
|
888
796
|
if (!id) {
|
|
889
|
-
navigate("/
|
|
797
|
+
navigate("/swaps");
|
|
890
798
|
return;
|
|
891
799
|
}
|
|
892
|
-
const
|
|
800
|
+
const loadSwap = async () => {
|
|
893
801
|
try {
|
|
894
802
|
setIsLoading(true);
|
|
895
803
|
setError(null);
|
|
896
|
-
const response = await fetch(`/admin/
|
|
804
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
897
805
|
credentials: "include"
|
|
898
806
|
});
|
|
899
807
|
if (!response.ok) {
|
|
900
808
|
const message = await response.text();
|
|
901
|
-
throw new Error(message || "Unable to load
|
|
809
|
+
throw new Error(message || "Unable to load swap");
|
|
902
810
|
}
|
|
903
811
|
const payload = await response.json();
|
|
904
|
-
|
|
812
|
+
setSwap(payload.swap);
|
|
813
|
+
setOrder(payload.order || null);
|
|
905
814
|
setSelectedStatus("");
|
|
906
815
|
} catch (loadError) {
|
|
907
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
816
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
908
817
|
setError(message);
|
|
909
818
|
} finally {
|
|
910
819
|
setIsLoading(false);
|
|
911
820
|
}
|
|
912
821
|
};
|
|
913
|
-
void
|
|
822
|
+
void loadSwap();
|
|
914
823
|
}, [id, navigate]);
|
|
915
824
|
const handleStatusUpdate = async () => {
|
|
916
825
|
if (!id || !selectedStatus) {
|
|
@@ -920,7 +829,7 @@ const ReturnDetailPage = () => {
|
|
|
920
829
|
setIsUpdating(true);
|
|
921
830
|
setUpdateError(null);
|
|
922
831
|
setUpdateSuccess(false);
|
|
923
|
-
const response = await fetch(`/admin/
|
|
832
|
+
const response = await fetch(`/admin/swaps/${id}/status`, {
|
|
924
833
|
method: "POST",
|
|
925
834
|
headers: {
|
|
926
835
|
"Content-Type": "application/json"
|
|
@@ -933,16 +842,17 @@ const ReturnDetailPage = () => {
|
|
|
933
842
|
throw new Error(message || "Unable to update status");
|
|
934
843
|
}
|
|
935
844
|
const payload = await response.json();
|
|
936
|
-
|
|
845
|
+
setSwap(payload.swap);
|
|
937
846
|
setSelectedStatus("");
|
|
938
847
|
setUpdateSuccess(true);
|
|
939
848
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
940
|
-
const detailResponse = await fetch(`/admin/
|
|
849
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
941
850
|
credentials: "include"
|
|
942
851
|
});
|
|
943
852
|
if (detailResponse.ok) {
|
|
944
853
|
const detailPayload = await detailResponse.json();
|
|
945
|
-
|
|
854
|
+
setSwap(detailPayload.swap);
|
|
855
|
+
setOrder(detailPayload.order || null);
|
|
946
856
|
}
|
|
947
857
|
} catch (updateErr) {
|
|
948
858
|
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
@@ -951,16 +861,93 @@ const ReturnDetailPage = () => {
|
|
|
951
861
|
setIsUpdating(false);
|
|
952
862
|
}
|
|
953
863
|
};
|
|
864
|
+
const handleAutoCreateExchange = async () => {
|
|
865
|
+
if (!id) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
try {
|
|
869
|
+
setIsApproving(true);
|
|
870
|
+
setUpdateError(null);
|
|
871
|
+
setUpdateSuccess(false);
|
|
872
|
+
const response = await fetch(`/admin/swaps/${id}/create-exchange`, {
|
|
873
|
+
method: "POST",
|
|
874
|
+
headers: {
|
|
875
|
+
"Content-Type": "application/json"
|
|
876
|
+
},
|
|
877
|
+
credentials: "include"
|
|
878
|
+
});
|
|
879
|
+
if (!response.ok) {
|
|
880
|
+
const message = await response.text();
|
|
881
|
+
throw new Error(message || "Unable to create exchange from swap");
|
|
882
|
+
}
|
|
883
|
+
const payload = await response.json();
|
|
884
|
+
setSwap(payload.swap);
|
|
885
|
+
setUpdateSuccess(true);
|
|
886
|
+
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
887
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
888
|
+
credentials: "include"
|
|
889
|
+
});
|
|
890
|
+
if (detailResponse.ok) {
|
|
891
|
+
const detailPayload = await detailResponse.json();
|
|
892
|
+
setSwap(detailPayload.swap);
|
|
893
|
+
setOrder(detailPayload.order || null);
|
|
894
|
+
}
|
|
895
|
+
} catch (approveErr) {
|
|
896
|
+
const message = approveErr instanceof Error ? approveErr.message : "Unable to create exchange from swap";
|
|
897
|
+
setUpdateError(message);
|
|
898
|
+
} finally {
|
|
899
|
+
setIsApproving(false);
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
const handleReject = async () => {
|
|
903
|
+
if (!id) {
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
try {
|
|
907
|
+
setIsRejecting(true);
|
|
908
|
+
setUpdateError(null);
|
|
909
|
+
setUpdateSuccess(false);
|
|
910
|
+
const response = await fetch(`/admin/swaps/${id}/reject`, {
|
|
911
|
+
method: "POST",
|
|
912
|
+
headers: {
|
|
913
|
+
"Content-Type": "application/json"
|
|
914
|
+
},
|
|
915
|
+
credentials: "include",
|
|
916
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
917
|
+
});
|
|
918
|
+
if (!response.ok) {
|
|
919
|
+
const message = await response.text();
|
|
920
|
+
throw new Error(message || "Unable to reject swap");
|
|
921
|
+
}
|
|
922
|
+
const payload = await response.json();
|
|
923
|
+
setSwap(payload.swap);
|
|
924
|
+
setUpdateSuccess(true);
|
|
925
|
+
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
926
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
927
|
+
credentials: "include"
|
|
928
|
+
});
|
|
929
|
+
if (detailResponse.ok) {
|
|
930
|
+
const detailPayload = await response.json();
|
|
931
|
+
setSwap(detailPayload.swap);
|
|
932
|
+
setOrder(detailPayload.order || null);
|
|
933
|
+
}
|
|
934
|
+
} catch (updateErr) {
|
|
935
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject swap";
|
|
936
|
+
setUpdateError(message);
|
|
937
|
+
} finally {
|
|
938
|
+
setIsRejecting(false);
|
|
939
|
+
}
|
|
940
|
+
};
|
|
954
941
|
if (isLoading) {
|
|
955
|
-
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
|
|
942
|
+
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..." }) }) }) });
|
|
956
943
|
}
|
|
957
|
-
if (error || !
|
|
944
|
+
if (error || !swap) {
|
|
958
945
|
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.jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
959
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
960
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
946
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
947
|
+
/* @__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" }) })
|
|
961
948
|
] }) }) });
|
|
962
949
|
}
|
|
963
|
-
const statusHistory = ((_a =
|
|
950
|
+
const statusHistory = ((_a = swap.metadata) == null ? void 0 : _a.status_history) || [];
|
|
964
951
|
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: [
|
|
965
952
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
966
953
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -968,7 +955,7 @@ const ReturnDetailPage = () => {
|
|
|
968
955
|
{
|
|
969
956
|
variant: "transparent",
|
|
970
957
|
size: "small",
|
|
971
|
-
onClick: () => navigate("/
|
|
958
|
+
onClick: () => navigate("/swaps"),
|
|
972
959
|
className: "w-fit",
|
|
973
960
|
children: [
|
|
974
961
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -978,20 +965,45 @@ const ReturnDetailPage = () => {
|
|
|
978
965
|
),
|
|
979
966
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
980
967
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
981
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
982
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
968
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Swap Details" }),
|
|
969
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
983
970
|
] }),
|
|
984
971
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
985
972
|
ui.Badge,
|
|
986
973
|
{
|
|
987
974
|
size: "small",
|
|
988
|
-
className: `uppercase ${getStatusBadgeClass(
|
|
989
|
-
children:
|
|
975
|
+
className: `uppercase ${getStatusBadgeClass(swap.status)}`,
|
|
976
|
+
children: swap.status.replace(/_/g, " ")
|
|
990
977
|
}
|
|
991
978
|
)
|
|
992
979
|
] })
|
|
993
980
|
] }),
|
|
994
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
981
|
+
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
983
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
984
|
+
ui.Button,
|
|
985
|
+
{
|
|
986
|
+
variant: "primary",
|
|
987
|
+
onClick: handleAutoCreateExchange,
|
|
988
|
+
disabled: isApproving || isRejecting,
|
|
989
|
+
isLoading: isApproving,
|
|
990
|
+
children: "Approve & Create Exchange"
|
|
991
|
+
}
|
|
992
|
+
),
|
|
993
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
994
|
+
ui.Button,
|
|
995
|
+
{
|
|
996
|
+
variant: "danger",
|
|
997
|
+
onClick: handleReject,
|
|
998
|
+
disabled: isApproving || isRejecting,
|
|
999
|
+
isLoading: isRejecting,
|
|
1000
|
+
children: "Reject Swap"
|
|
1001
|
+
}
|
|
1002
|
+
)
|
|
1003
|
+
] }),
|
|
1004
|
+
/* @__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" })
|
|
1005
|
+
] }),
|
|
1006
|
+
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
995
1007
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Update Status" }),
|
|
996
1008
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end", children: [
|
|
997
1009
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
@@ -1004,7 +1016,7 @@ const ReturnDetailPage = () => {
|
|
|
1004
1016
|
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",
|
|
1005
1017
|
children: [
|
|
1006
1018
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
1007
|
-
availableStatuses.filter((status) => status !==
|
|
1019
|
+
availableStatuses.filter((status) => status !== swap.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1008
1020
|
]
|
|
1009
1021
|
}
|
|
1010
1022
|
)
|
|
@@ -1023,37 +1035,60 @@ const ReturnDetailPage = () => {
|
|
|
1023
1035
|
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
1024
1036
|
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
1025
1037
|
] }),
|
|
1038
|
+
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1039
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
1040
|
+
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1041
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1042
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1043
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1044
|
+
] }),
|
|
1045
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1046
|
+
ui.Button,
|
|
1047
|
+
{
|
|
1048
|
+
variant: "secondary",
|
|
1049
|
+
onClick: () => {
|
|
1050
|
+
window.open(`/app/orders/${swap.order_id}/exchanges/${swap.exchange_id}`, "_blank");
|
|
1051
|
+
},
|
|
1052
|
+
children: "View Exchange"
|
|
1053
|
+
}
|
|
1054
|
+
) })
|
|
1055
|
+
] }) : /* @__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." }) })
|
|
1056
|
+
] }),
|
|
1026
1057
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1027
1058
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1028
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
1059
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Swap Information" }),
|
|
1029
1060
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1030
1061
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1031
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1032
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1062
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Swap ID" }),
|
|
1063
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
1033
1064
|
] }),
|
|
1034
1065
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1035
1066
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
1036
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1067
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
|
|
1037
1068
|
] }),
|
|
1038
1069
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1039
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1040
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1070
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
1071
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
1041
1072
|
] }),
|
|
1042
|
-
|
|
1073
|
+
swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1043
1074
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
1044
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1075
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
|
|
1045
1076
|
] }),
|
|
1046
|
-
|
|
1077
|
+
swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1047
1078
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
1048
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1079
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
|
|
1049
1080
|
] }),
|
|
1050
1081
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1051
1082
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
1052
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
1083
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
1053
1084
|
] }),
|
|
1054
1085
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1055
1086
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
1056
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
1087
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
1088
|
+
] }),
|
|
1089
|
+
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1090
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1091
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1057
1092
|
] })
|
|
1058
1093
|
] })
|
|
1059
1094
|
] }),
|
|
@@ -1064,23 +1099,18 @@ const ReturnDetailPage = () => {
|
|
|
1064
1099
|
{
|
|
1065
1100
|
className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
|
|
1066
1101
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1067
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
),
|
|
1076
|
-
entry.from && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1077
|
-
"from ",
|
|
1078
|
-
entry.from.replace("_", " ")
|
|
1079
|
-
] })
|
|
1080
|
-
] }),
|
|
1102
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1103
|
+
ui.Badge,
|
|
1104
|
+
{
|
|
1105
|
+
size: "2xsmall",
|
|
1106
|
+
className: `uppercase ${getStatusBadgeClass(entry.status)}`,
|
|
1107
|
+
children: entry.status.replace(/_/g, " ")
|
|
1108
|
+
}
|
|
1109
|
+
) }),
|
|
1081
1110
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1082
|
-
new Date(entry.
|
|
1083
|
-
entry.
|
|
1111
|
+
new Date(entry.timestamp).toLocaleString(),
|
|
1112
|
+
entry.admin_id && ` by ${entry.admin_id}`,
|
|
1113
|
+
entry.reason && ` - ${entry.reason}`
|
|
1084
1114
|
] })
|
|
1085
1115
|
] })
|
|
1086
1116
|
},
|
|
@@ -1088,123 +1118,109 @@ const ReturnDetailPage = () => {
|
|
|
1088
1118
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
1089
1119
|
] })
|
|
1090
1120
|
] }),
|
|
1091
|
-
|
|
1121
|
+
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1092
1122
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
1093
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1094
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
1095
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1096
|
-
|
|
1097
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
1098
|
-
] }),
|
|
1099
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1100
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
1101
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
1102
|
-
] }),
|
|
1103
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1104
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
1105
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.customer) == null ? void 0 : _c.email) || returnOrder.order.email || "—" })
|
|
1106
|
-
] }),
|
|
1107
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1108
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
1109
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.total).toFixed(2)}` : "—" })
|
|
1110
|
-
] })
|
|
1123
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1124
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1125
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
1126
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
1111
1127
|
] }),
|
|
1112
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
1113
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1126
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Created" }),
|
|
1127
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.created_at ? new Date(returnOrder.order.created_at).toLocaleString() : "—" })
|
|
1128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1129
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
1130
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
1131
|
+
] }),
|
|
1132
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1133
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
1134
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = order.customer) == null ? void 0 : _b.email) || order.email || "—" })
|
|
1135
|
+
] }),
|
|
1136
|
+
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1137
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
1138
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
1139
|
+
order.currency_code || "$",
|
|
1140
|
+
(Number(order.total) / 100).toFixed(2)
|
|
1128
1141
|
] })
|
|
1129
1142
|
] })
|
|
1130
1143
|
] })
|
|
1131
1144
|
] }),
|
|
1132
|
-
|
|
1145
|
+
swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1133
1146
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
1134
1147
|
/* @__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: [
|
|
1135
1148
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1136
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item" }),
|
|
1137
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
1149
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item ID" }),
|
|
1150
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
1151
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
1138
1152
|
] }) }),
|
|
1139
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
] }, item.id);
|
|
1145
|
-
}) })
|
|
1153
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1154
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
1155
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
1156
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
1157
|
+
] }, item.id || index)) })
|
|
1146
1158
|
] }) })
|
|
1147
1159
|
] }),
|
|
1148
|
-
|
|
1149
|
-
(
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1160
|
+
swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1161
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
1162
|
+
/* @__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: [
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1164
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
1165
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
1166
|
+
] }) }),
|
|
1167
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
1169
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
1170
|
+
] }, item.variant_id || index)) })
|
|
1171
|
+
] }) })
|
|
1156
1172
|
] })
|
|
1157
1173
|
] }) });
|
|
1158
1174
|
};
|
|
1159
1175
|
const config = adminSdk.defineRouteConfig({
|
|
1160
|
-
label: "
|
|
1176
|
+
label: "Swap Details",
|
|
1161
1177
|
icon: icons.ArrowPath
|
|
1162
1178
|
});
|
|
1163
1179
|
const i18nTranslations0 = {};
|
|
1164
1180
|
const widgetModule = { widgets: [] };
|
|
1165
1181
|
const routeModule = {
|
|
1166
1182
|
routes: [
|
|
1167
|
-
{
|
|
1168
|
-
Component: SwapsPage,
|
|
1169
|
-
path: "/swaps"
|
|
1170
|
-
},
|
|
1171
1183
|
{
|
|
1172
1184
|
Component: ReturnsPage,
|
|
1173
1185
|
path: "/returns"
|
|
1174
1186
|
},
|
|
1175
1187
|
{
|
|
1176
|
-
Component:
|
|
1177
|
-
path: "/swaps
|
|
1188
|
+
Component: SwapsPage,
|
|
1189
|
+
path: "/swaps"
|
|
1178
1190
|
},
|
|
1179
1191
|
{
|
|
1180
1192
|
Component: ReturnDetailPage,
|
|
1181
1193
|
path: "/returns/:id"
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
Component: SwapDetailPage,
|
|
1197
|
+
path: "/swaps/:id"
|
|
1182
1198
|
}
|
|
1183
1199
|
]
|
|
1184
1200
|
};
|
|
1185
1201
|
const menuItemModule = {
|
|
1186
1202
|
menuItems: [
|
|
1187
1203
|
{
|
|
1188
|
-
label: config$
|
|
1189
|
-
icon: config$
|
|
1204
|
+
label: config$2.label,
|
|
1205
|
+
icon: config$2.icon,
|
|
1190
1206
|
path: "/swaps",
|
|
1191
1207
|
nested: void 0
|
|
1192
1208
|
},
|
|
1193
1209
|
{
|
|
1194
|
-
label: config$
|
|
1195
|
-
icon: config$
|
|
1210
|
+
label: config$3.label,
|
|
1211
|
+
icon: config$3.icon,
|
|
1196
1212
|
path: "/returns",
|
|
1197
1213
|
nested: void 0
|
|
1198
1214
|
},
|
|
1199
1215
|
{
|
|
1200
|
-
label: config
|
|
1201
|
-
icon: config
|
|
1216
|
+
label: config.label,
|
|
1217
|
+
icon: config.icon,
|
|
1202
1218
|
path: "/swaps/:id",
|
|
1203
1219
|
nested: void 0
|
|
1204
1220
|
},
|
|
1205
1221
|
{
|
|
1206
|
-
label: config.label,
|
|
1207
|
-
icon: config.icon,
|
|
1222
|
+
label: config$1.label,
|
|
1223
|
+
icon: config$1.icon,
|
|
1208
1224
|
path: "/returns/:id",
|
|
1209
1225
|
nested: void 0
|
|
1210
1226
|
}
|