order-management 0.0.24 → 0.0.25
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 +589 -627
- package/.medusa/server/src/admin/index.mjs +590 -628
- package/.medusa/server/src/api/admin/swaps/[id]/approve/route.js +8 -3
- package/.medusa/server/src/api/admin/swaps/[id]/shipping-options/route.js +105 -0
- package/.medusa/server/src/api/admin/swaps/validators.js +2 -1
- package/.medusa/server/src/api/store/orders/[order_id]/swaps/route.js +2 -1
- package/.medusa/server/src/api/store/swaps/route.js +2 -1
- package/.medusa/server/src/helpers/order-exchange-data.js +175 -1
- package/.medusa/server/src/modules/swap/service.js +1 -1
- package/.medusa/server/src/workflows/steps/swap/create-medusa-exchange-step.js +265 -24
- package/.medusa/server/src/workflows/steps/swap/create-medusa-return-step.js +630 -23
- package/.medusa/server/src/workflows/steps/swap/update-swap-exchange-details-step.js +12 -2
- package/.medusa/server/src/workflows/steps/swap/validate-swap-items-step.js +102 -4
- package/.medusa/server/src/workflows/swaps/approve-swap-workflow.js +56 -12
- package/package.json +1 -1
- package/.medusa/server/src/api/admin/swaps/[id]/confirm-exchange/route.js +0 -145
- package/.medusa/server/src/workflows/swaps/confirm-exchange-workflow.js +0 -51
|
@@ -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) => {
|
|
@@ -434,67 +434,65 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
434
434
|
if (statusLower === "requested") {
|
|
435
435
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
436
436
|
}
|
|
437
|
-
if (statusLower === "
|
|
437
|
+
if (statusLower === "received") {
|
|
438
438
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
439
439
|
}
|
|
440
|
-
if (statusLower === "
|
|
440
|
+
if (statusLower === "requires_action") {
|
|
441
441
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
442
442
|
}
|
|
443
443
|
if (statusLower === "completed") {
|
|
444
444
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
445
445
|
}
|
|
446
|
-
if (statusLower === "
|
|
446
|
+
if (statusLower === "canceled") {
|
|
447
447
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
448
448
|
}
|
|
449
449
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
450
450
|
};
|
|
451
|
-
const
|
|
452
|
-
var _a, _b;
|
|
451
|
+
const ReturnDetailPage = () => {
|
|
452
|
+
var _a, _b, _c;
|
|
453
453
|
const navigate = reactRouterDom.useNavigate();
|
|
454
454
|
const { id } = reactRouterDom.useParams();
|
|
455
|
-
const [
|
|
456
|
-
const [order, setOrder] = react.useState(null);
|
|
455
|
+
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
457
456
|
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
458
457
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
459
458
|
const [isUpdating, setIsUpdating] = react.useState(false);
|
|
460
|
-
const [isApproving, setIsApproving] = react.useState(false);
|
|
461
|
-
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
462
|
-
const [isCreatingExchange, setIsCreatingExchange] = react.useState(false);
|
|
463
|
-
const [sendNotification, setSendNotification] = react.useState(false);
|
|
464
|
-
const [exchangeError, setExchangeError] = react.useState(null);
|
|
465
|
-
const [exchangeSuccess, setExchangeSuccess] = react.useState(false);
|
|
466
459
|
const [error, setError] = react.useState(null);
|
|
467
460
|
const [updateError, setUpdateError] = react.useState(null);
|
|
468
461
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
469
|
-
const availableStatuses = [
|
|
462
|
+
const availableStatuses = [
|
|
463
|
+
"requested",
|
|
464
|
+
"received",
|
|
465
|
+
"requires_action",
|
|
466
|
+
"completed",
|
|
467
|
+
"canceled"
|
|
468
|
+
];
|
|
470
469
|
react.useEffect(() => {
|
|
471
470
|
if (!id) {
|
|
472
|
-
navigate("/
|
|
471
|
+
navigate("/returns");
|
|
473
472
|
return;
|
|
474
473
|
}
|
|
475
|
-
const
|
|
474
|
+
const loadReturn = async () => {
|
|
476
475
|
try {
|
|
477
476
|
setIsLoading(true);
|
|
478
477
|
setError(null);
|
|
479
|
-
const response = await fetch(`/admin/
|
|
478
|
+
const response = await fetch(`/admin/returns/${id}`, {
|
|
480
479
|
credentials: "include"
|
|
481
480
|
});
|
|
482
481
|
if (!response.ok) {
|
|
483
482
|
const message = await response.text();
|
|
484
|
-
throw new Error(message || "Unable to load
|
|
483
|
+
throw new Error(message || "Unable to load return order");
|
|
485
484
|
}
|
|
486
485
|
const payload = await response.json();
|
|
487
|
-
|
|
488
|
-
setOrder(payload.order || null);
|
|
486
|
+
setReturnOrder(payload.return);
|
|
489
487
|
setSelectedStatus("");
|
|
490
488
|
} catch (loadError) {
|
|
491
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
489
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
492
490
|
setError(message);
|
|
493
491
|
} finally {
|
|
494
492
|
setIsLoading(false);
|
|
495
493
|
}
|
|
496
494
|
};
|
|
497
|
-
void
|
|
495
|
+
void loadReturn();
|
|
498
496
|
}, [id, navigate]);
|
|
499
497
|
const handleStatusUpdate = async () => {
|
|
500
498
|
if (!id || !selectedStatus) {
|
|
@@ -504,7 +502,7 @@ const SwapDetailPage = () => {
|
|
|
504
502
|
setIsUpdating(true);
|
|
505
503
|
setUpdateError(null);
|
|
506
504
|
setUpdateSuccess(false);
|
|
507
|
-
const response = await fetch(`/admin/
|
|
505
|
+
const response = await fetch(`/admin/returns/${id}/status`, {
|
|
508
506
|
method: "POST",
|
|
509
507
|
headers: {
|
|
510
508
|
"Content-Type": "application/json"
|
|
@@ -517,17 +515,16 @@ const SwapDetailPage = () => {
|
|
|
517
515
|
throw new Error(message || "Unable to update status");
|
|
518
516
|
}
|
|
519
517
|
const payload = await response.json();
|
|
520
|
-
|
|
518
|
+
setReturnOrder(payload.return);
|
|
521
519
|
setSelectedStatus("");
|
|
522
520
|
setUpdateSuccess(true);
|
|
523
521
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
524
|
-
const detailResponse = await fetch(`/admin/
|
|
522
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
525
523
|
credentials: "include"
|
|
526
524
|
});
|
|
527
525
|
if (detailResponse.ok) {
|
|
528
526
|
const detailPayload = await detailResponse.json();
|
|
529
|
-
|
|
530
|
-
setOrder(detailPayload.order || null);
|
|
527
|
+
setReturnOrder(detailPayload.return);
|
|
531
528
|
}
|
|
532
529
|
} catch (updateErr) {
|
|
533
530
|
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
@@ -536,134 +533,16 @@ const SwapDetailPage = () => {
|
|
|
536
533
|
setIsUpdating(false);
|
|
537
534
|
}
|
|
538
535
|
};
|
|
539
|
-
const handleApprove = async () => {
|
|
540
|
-
if (!id) {
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
try {
|
|
544
|
-
setIsApproving(true);
|
|
545
|
-
setUpdateError(null);
|
|
546
|
-
setUpdateSuccess(false);
|
|
547
|
-
const response = await fetch(`/admin/swaps/${id}/approve`, {
|
|
548
|
-
method: "POST",
|
|
549
|
-
headers: {
|
|
550
|
-
"Content-Type": "application/json"
|
|
551
|
-
},
|
|
552
|
-
credentials: "include"
|
|
553
|
-
});
|
|
554
|
-
if (!response.ok) {
|
|
555
|
-
const message = await response.text();
|
|
556
|
-
throw new Error(message || "Unable to approve swap");
|
|
557
|
-
}
|
|
558
|
-
const payload = await response.json();
|
|
559
|
-
setSwap(payload.swap);
|
|
560
|
-
setUpdateSuccess(true);
|
|
561
|
-
setTimeout(() => setUpdateSuccess(false), 5e3);
|
|
562
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
563
|
-
credentials: "include"
|
|
564
|
-
});
|
|
565
|
-
if (detailResponse.ok) {
|
|
566
|
-
const detailPayload = await detailResponse.json();
|
|
567
|
-
setSwap(detailPayload.swap);
|
|
568
|
-
setOrder(detailPayload.order || null);
|
|
569
|
-
}
|
|
570
|
-
} catch (updateErr) {
|
|
571
|
-
const message = updateErr instanceof Error ? updateErr.message : "Unable to approve swap";
|
|
572
|
-
setUpdateError(message);
|
|
573
|
-
} finally {
|
|
574
|
-
setIsApproving(false);
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
const handleReject = async () => {
|
|
578
|
-
if (!id) {
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
try {
|
|
582
|
-
setIsRejecting(true);
|
|
583
|
-
setUpdateError(null);
|
|
584
|
-
setUpdateSuccess(false);
|
|
585
|
-
const response = await fetch(`/admin/swaps/${id}/reject`, {
|
|
586
|
-
method: "POST",
|
|
587
|
-
headers: {
|
|
588
|
-
"Content-Type": "application/json"
|
|
589
|
-
},
|
|
590
|
-
credentials: "include",
|
|
591
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
592
|
-
});
|
|
593
|
-
if (!response.ok) {
|
|
594
|
-
const message = await response.text();
|
|
595
|
-
throw new Error(message || "Unable to reject swap");
|
|
596
|
-
}
|
|
597
|
-
const payload = await response.json();
|
|
598
|
-
setSwap(payload.swap);
|
|
599
|
-
setUpdateSuccess(true);
|
|
600
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
601
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
602
|
-
credentials: "include"
|
|
603
|
-
});
|
|
604
|
-
if (detailResponse.ok) {
|
|
605
|
-
const detailPayload = await response.json();
|
|
606
|
-
setSwap(detailPayload.swap);
|
|
607
|
-
setOrder(detailPayload.order || null);
|
|
608
|
-
}
|
|
609
|
-
} catch (updateErr) {
|
|
610
|
-
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject swap";
|
|
611
|
-
setUpdateError(message);
|
|
612
|
-
} finally {
|
|
613
|
-
setIsRejecting(false);
|
|
614
|
-
}
|
|
615
|
-
};
|
|
616
|
-
const handleCreateExchange = async () => {
|
|
617
|
-
if (!id) {
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
try {
|
|
621
|
-
setIsCreatingExchange(true);
|
|
622
|
-
setExchangeError(null);
|
|
623
|
-
setExchangeSuccess(false);
|
|
624
|
-
const response = await fetch(`/admin/swaps/${id}/confirm-exchange`, {
|
|
625
|
-
method: "POST",
|
|
626
|
-
headers: {
|
|
627
|
-
"Content-Type": "application/json"
|
|
628
|
-
},
|
|
629
|
-
credentials: "include",
|
|
630
|
-
body: JSON.stringify({
|
|
631
|
-
send_notification: sendNotification
|
|
632
|
-
})
|
|
633
|
-
});
|
|
634
|
-
if (!response.ok) {
|
|
635
|
-
const errorData = await response.json().catch(() => ({ message: "Failed to create exchange" }));
|
|
636
|
-
throw new Error(errorData.message || errorData.error || "Failed to create exchange");
|
|
637
|
-
}
|
|
638
|
-
const result = await response.json();
|
|
639
|
-
setSwap(result.swap);
|
|
640
|
-
setExchangeSuccess(true);
|
|
641
|
-
setTimeout(() => setExchangeSuccess(false), 5e3);
|
|
642
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
643
|
-
credentials: "include"
|
|
644
|
-
});
|
|
645
|
-
if (detailResponse.ok) {
|
|
646
|
-
const detailPayload = await detailResponse.json();
|
|
647
|
-
setSwap(detailPayload.swap);
|
|
648
|
-
setOrder(detailPayload.order || null);
|
|
649
|
-
}
|
|
650
|
-
} catch (createErr) {
|
|
651
|
-
const message = createErr instanceof Error ? createErr.message : "Unable to create exchange";
|
|
652
|
-
setExchangeError(message);
|
|
653
|
-
} finally {
|
|
654
|
-
setIsCreatingExchange(false);
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
536
|
if (isLoading) {
|
|
658
|
-
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
|
|
537
|
+
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..." }) }) }) });
|
|
659
538
|
}
|
|
660
|
-
if (error || !
|
|
539
|
+
if (error || !returnOrder) {
|
|
661
540
|
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: [
|
|
662
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
663
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
541
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
542
|
+
/* @__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" }) })
|
|
664
543
|
] }) }) });
|
|
665
544
|
}
|
|
666
|
-
const statusHistory = ((_a =
|
|
545
|
+
const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
|
|
667
546
|
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: [
|
|
668
547
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
669
548
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -671,7 +550,7 @@ const SwapDetailPage = () => {
|
|
|
671
550
|
{
|
|
672
551
|
variant: "transparent",
|
|
673
552
|
size: "small",
|
|
674
|
-
onClick: () => navigate("/
|
|
553
|
+
onClick: () => navigate("/returns"),
|
|
675
554
|
className: "w-fit",
|
|
676
555
|
children: [
|
|
677
556
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -681,42 +560,20 @@ const SwapDetailPage = () => {
|
|
|
681
560
|
),
|
|
682
561
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
683
562
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
684
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
685
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
563
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
|
|
564
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
686
565
|
] }),
|
|
687
566
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
688
567
|
ui.Badge,
|
|
689
568
|
{
|
|
690
569
|
size: "small",
|
|
691
|
-
className: `uppercase ${getStatusBadgeClass$1(
|
|
692
|
-
children:
|
|
570
|
+
className: `uppercase ${getStatusBadgeClass$1(returnOrder.status)}`,
|
|
571
|
+
children: returnOrder.status.replace("_", " ")
|
|
693
572
|
}
|
|
694
573
|
)
|
|
695
574
|
] })
|
|
696
575
|
] }),
|
|
697
|
-
|
|
698
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
699
|
-
ui.Button,
|
|
700
|
-
{
|
|
701
|
-
variant: "primary",
|
|
702
|
-
onClick: handleApprove,
|
|
703
|
-
disabled: isApproving || isRejecting,
|
|
704
|
-
isLoading: isApproving,
|
|
705
|
-
children: "Approve Swap"
|
|
706
|
-
}
|
|
707
|
-
),
|
|
708
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
709
|
-
ui.Button,
|
|
710
|
-
{
|
|
711
|
-
variant: "secondary",
|
|
712
|
-
onClick: handleReject,
|
|
713
|
-
disabled: isApproving || isRejecting,
|
|
714
|
-
isLoading: isRejecting,
|
|
715
|
-
children: "Reject Swap"
|
|
716
|
-
}
|
|
717
|
-
)
|
|
718
|
-
] }),
|
|
719
|
-
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
576
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
720
577
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Update Status" }),
|
|
721
578
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end", children: [
|
|
722
579
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
@@ -729,7 +586,7 @@ const SwapDetailPage = () => {
|
|
|
729
586
|
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",
|
|
730
587
|
children: [
|
|
731
588
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
732
|
-
availableStatuses.filter((status) => status !==
|
|
589
|
+
availableStatuses.filter((status) => status !== returnOrder.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace("_", " ").toUpperCase() }, status))
|
|
733
590
|
]
|
|
734
591
|
}
|
|
735
592
|
)
|
|
@@ -748,139 +605,37 @@ const SwapDetailPage = () => {
|
|
|
748
605
|
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
749
606
|
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
750
607
|
] }),
|
|
751
|
-
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
752
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
753
|
-
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
754
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
755
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
756
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
757
|
-
] }),
|
|
758
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
759
|
-
ui.Button,
|
|
760
|
-
{
|
|
761
|
-
variant: "secondary",
|
|
762
|
-
onClick: () => {
|
|
763
|
-
window.open(`/app/orders/${swap.order_id}/exchanges/${swap.exchange_id}`, "_blank");
|
|
764
|
-
},
|
|
765
|
-
children: "View Exchange"
|
|
766
|
-
}
|
|
767
|
-
) })
|
|
768
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
769
|
-
swap.return_items && swap.return_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
770
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mb-3 text-base", children: "Return Items (Inbound)" }),
|
|
771
|
-
/* @__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: [
|
|
772
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
773
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item" }),
|
|
774
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
775
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
776
|
-
] }) }),
|
|
777
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle bg-ui-bg-base", children: swap.return_items.map((item, index) => {
|
|
778
|
-
var _a2;
|
|
779
|
-
const orderItem = (_a2 = order == null ? void 0 : order.items) == null ? void 0 : _a2.find((oi) => oi.id === item.id);
|
|
780
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
781
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: (orderItem == null ? void 0 : orderItem.title) || item.id }),
|
|
782
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
783
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
784
|
-
] }, item.id || index);
|
|
785
|
-
}) })
|
|
786
|
-
] }) })
|
|
787
|
-
] }),
|
|
788
|
-
swap.new_items && swap.new_items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
789
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "mb-3 text-base", children: "New Items (Outbound)" }),
|
|
790
|
-
/* @__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: [
|
|
791
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
792
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Product/Variant" }),
|
|
793
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
794
|
-
] }) }),
|
|
795
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle bg-ui-bg-base", children: swap.new_items.map((item, index) => {
|
|
796
|
-
var _a2;
|
|
797
|
-
const orderItem = (_a2 = order == null ? void 0 : order.items) == null ? void 0 : _a2.find((oi) => oi.variant_id === item.variant_id);
|
|
798
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
799
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: (orderItem == null ? void 0 : orderItem.title) || item.variant_id }),
|
|
800
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
801
|
-
] }, item.variant_id || index);
|
|
802
|
-
}) })
|
|
803
|
-
] }) })
|
|
804
|
-
] }),
|
|
805
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 rounded-lg border border-ui-border-base bg-ui-bg-subtle p-4", children: [
|
|
806
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-base", children: "Exchange Details" }),
|
|
807
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [
|
|
808
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
809
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return Location" }),
|
|
810
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.return_location_id || "—" })
|
|
811
|
-
] }),
|
|
812
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
813
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return Shipping Method" }),
|
|
814
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.return_shipping_method_id || "—" })
|
|
815
|
-
] }),
|
|
816
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
817
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Outbound Shipping Method" }),
|
|
818
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.outbound_shipping_method_id || "—" })
|
|
819
|
-
] })
|
|
820
|
-
] })
|
|
821
|
-
] }),
|
|
822
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
823
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
824
|
-
"input",
|
|
825
|
-
{
|
|
826
|
-
type: "checkbox",
|
|
827
|
-
id: "send-notification",
|
|
828
|
-
checked: sendNotification,
|
|
829
|
-
onChange: (e) => setSendNotification(e.target.checked),
|
|
830
|
-
className: "h-4 w-4 rounded border-ui-border-base text-ui-fg-interactive focus:ring-2 focus:ring-ui-fg-interactive"
|
|
831
|
-
}
|
|
832
|
-
),
|
|
833
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "send-notification", className: "cursor-pointer", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", children: "Send notification to customer about exchange" }) })
|
|
834
|
-
] }),
|
|
835
|
-
exchangeError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-error bg-ui-bg-error-subtle p-3", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-error", children: exchangeError }) }),
|
|
836
|
-
exchangeSuccess && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-ui-border-success bg-ui-bg-success-subtle p-3", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-success", children: "Exchange created successfully!" }) }),
|
|
837
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
838
|
-
ui.Button,
|
|
839
|
-
{
|
|
840
|
-
variant: "primary",
|
|
841
|
-
onClick: handleCreateExchange,
|
|
842
|
-
disabled: isCreatingExchange,
|
|
843
|
-
isLoading: isCreatingExchange,
|
|
844
|
-
children: "Confirm & Create Exchange"
|
|
845
|
-
}
|
|
846
|
-
) })
|
|
847
|
-
] })
|
|
848
|
-
] }),
|
|
849
608
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
850
609
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
851
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
610
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
852
611
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
853
612
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
854
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
855
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
613
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
614
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
856
615
|
] }),
|
|
857
616
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
858
617
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
859
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
618
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
|
|
860
619
|
] }),
|
|
861
620
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
862
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
863
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
621
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund Amount" }),
|
|
622
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.refund_amount ? `${((_b = returnOrder.order) == null ? void 0 : _b.currency_code) || "$"}${Number(returnOrder.refund_amount).toFixed(2)}` : "—" })
|
|
864
623
|
] }),
|
|
865
|
-
|
|
624
|
+
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
866
625
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
867
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
626
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
868
627
|
] }),
|
|
869
|
-
|
|
628
|
+
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
870
629
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
871
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
630
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
872
631
|
] }),
|
|
873
632
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
874
633
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
875
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
634
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
876
635
|
] }),
|
|
877
636
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
878
637
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
879
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
880
|
-
] }),
|
|
881
|
-
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
882
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
883
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
638
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
884
639
|
] })
|
|
885
640
|
] })
|
|
886
641
|
] }),
|
|
@@ -891,18 +646,23 @@ const SwapDetailPage = () => {
|
|
|
891
646
|
{
|
|
892
647
|
className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
|
|
893
648
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
894
|
-
/* @__PURE__ */ jsxRuntime.
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
649
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
650
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
651
|
+
ui.Badge,
|
|
652
|
+
{
|
|
653
|
+
size: "2xsmall",
|
|
654
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.to)}`,
|
|
655
|
+
children: entry.to.replace("_", " ")
|
|
656
|
+
}
|
|
657
|
+
),
|
|
658
|
+
entry.from && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
659
|
+
"from ",
|
|
660
|
+
entry.from.replace("_", " ")
|
|
661
|
+
] })
|
|
662
|
+
] }),
|
|
902
663
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
903
|
-
new Date(entry.
|
|
904
|
-
entry.
|
|
905
|
-
entry.reason && ` - ${entry.reason}`
|
|
664
|
+
new Date(entry.changed_at).toLocaleString(),
|
|
665
|
+
entry.changed_by && ` by ${entry.changed_by}`
|
|
906
666
|
] })
|
|
907
667
|
] })
|
|
908
668
|
},
|
|
@@ -910,62 +670,76 @@ const SwapDetailPage = () => {
|
|
|
910
670
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
911
671
|
] })
|
|
912
672
|
] }),
|
|
913
|
-
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
673
|
+
returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
914
674
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
915
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
916
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
917
|
-
/* @__PURE__ */ jsxRuntime.
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
/* @__PURE__ */ jsxRuntime.
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
/* @__PURE__ */ jsxRuntime.
|
|
926
|
-
|
|
675
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
676
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
677
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
678
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
679
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
680
|
+
] }),
|
|
681
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
682
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
683
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
684
|
+
] }),
|
|
685
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
686
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
687
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.customer) == null ? void 0 : _c.email) || returnOrder.order.email || "—" })
|
|
688
|
+
] }),
|
|
689
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
691
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.total).toFixed(2)}` : "—" })
|
|
692
|
+
] })
|
|
927
693
|
] }),
|
|
928
|
-
|
|
929
|
-
/* @__PURE__ */ jsxRuntime.
|
|
930
|
-
|
|
931
|
-
order.currency_code || "$"
|
|
932
|
-
|
|
694
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
695
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
696
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Subtotal" }),
|
|
697
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.subtotal ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.subtotal).toFixed(2)}` : "—" })
|
|
698
|
+
] }),
|
|
699
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
700
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Tax Total" }),
|
|
701
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.tax_total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.tax_total).toFixed(2)}` : "—" })
|
|
702
|
+
] }),
|
|
703
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
704
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Shipping Total" }),
|
|
705
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.shipping_total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.shipping_total).toFixed(2)}` : "—" })
|
|
706
|
+
] }),
|
|
707
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
708
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Created" }),
|
|
709
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.created_at ? new Date(returnOrder.order.created_at).toLocaleString() : "—" })
|
|
933
710
|
] })
|
|
934
711
|
] })
|
|
935
712
|
] })
|
|
936
713
|
] }),
|
|
937
|
-
|
|
714
|
+
returnOrder.items && returnOrder.items.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
938
715
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
939
716
|
/* @__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: [
|
|
940
717
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
941
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item
|
|
942
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
943
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
944
|
-
] }) }),
|
|
945
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
946
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
947
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
948
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
949
|
-
] }, item.id || index)) })
|
|
950
|
-
] }) })
|
|
951
|
-
] }),
|
|
952
|
-
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: [
|
|
953
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
954
|
-
/* @__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: [
|
|
955
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
956
|
-
/* @__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" }),
|
|
718
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item" }),
|
|
957
719
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
958
720
|
] }) }),
|
|
959
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
960
|
-
|
|
961
|
-
/* @__PURE__ */ jsxRuntime.
|
|
962
|
-
|
|
721
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.items.map((item) => {
|
|
722
|
+
var _a2, _b2;
|
|
723
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
724
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: ((_a2 = item.item) == null ? void 0 : _a2.title) || ((_b2 = item.item) == null ? void 0 : _b2.id) || item.id }),
|
|
725
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
726
|
+
] }, item.id);
|
|
727
|
+
}) })
|
|
963
728
|
] }) })
|
|
729
|
+
] }),
|
|
730
|
+
returnOrder.metadata && Object.keys(returnOrder.metadata).filter(
|
|
731
|
+
(key) => key !== "status_history"
|
|
732
|
+
).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
733
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Metadata" }),
|
|
734
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: Object.entries(returnOrder.metadata).filter(([key]) => key !== "status_history").map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between", children: [
|
|
735
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: key }),
|
|
736
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "font-medium", children: typeof value === "string" ? value : JSON.stringify(value) })
|
|
737
|
+
] }, key)) })
|
|
964
738
|
] })
|
|
965
739
|
] }) });
|
|
966
740
|
};
|
|
967
741
|
const config$1 = adminSdk.defineRouteConfig({
|
|
968
|
-
label: "
|
|
742
|
+
label: "Return Order Details",
|
|
969
743
|
icon: icons.ArrowPath
|
|
970
744
|
});
|
|
971
745
|
const getStatusBadgeClass = (status) => {
|
|
@@ -973,65 +747,67 @@ const getStatusBadgeClass = (status) => {
|
|
|
973
747
|
if (statusLower === "requested") {
|
|
974
748
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
975
749
|
}
|
|
976
|
-
if (statusLower === "
|
|
750
|
+
if (statusLower === "approved") {
|
|
977
751
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
978
752
|
}
|
|
979
|
-
if (statusLower === "
|
|
753
|
+
if (statusLower === "rejected") {
|
|
980
754
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
981
755
|
}
|
|
982
756
|
if (statusLower === "completed") {
|
|
983
757
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
984
758
|
}
|
|
985
|
-
if (statusLower === "
|
|
759
|
+
if (statusLower === "cancelled") {
|
|
986
760
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
987
761
|
}
|
|
988
762
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
989
763
|
};
|
|
990
|
-
const
|
|
991
|
-
var _a, _b
|
|
764
|
+
const SwapDetailPage = () => {
|
|
765
|
+
var _a, _b;
|
|
992
766
|
const navigate = reactRouterDom.useNavigate();
|
|
993
767
|
const { id } = reactRouterDom.useParams();
|
|
994
|
-
const [
|
|
768
|
+
const [swap, setSwap] = react.useState(null);
|
|
769
|
+
const [order, setOrder] = react.useState(null);
|
|
995
770
|
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
996
771
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
997
772
|
const [isUpdating, setIsUpdating] = react.useState(false);
|
|
773
|
+
const [isApproving, setIsApproving] = react.useState(false);
|
|
774
|
+
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
998
775
|
const [error, setError] = react.useState(null);
|
|
999
776
|
const [updateError, setUpdateError] = react.useState(null);
|
|
1000
777
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
"canceled"
|
|
1007
|
-
];
|
|
778
|
+
const [showShippingModal, setShowShippingModal] = react.useState(false);
|
|
779
|
+
const [shippingOptions, setShippingOptions] = react.useState([]);
|
|
780
|
+
const [selectedShippingOptionId, setSelectedShippingOptionId] = react.useState("");
|
|
781
|
+
const [isLoadingShippingOptions, setIsLoadingShippingOptions] = react.useState(false);
|
|
782
|
+
const availableStatuses = ["requested", "approved", "rejected"];
|
|
1008
783
|
react.useEffect(() => {
|
|
1009
784
|
if (!id) {
|
|
1010
|
-
navigate("/
|
|
785
|
+
navigate("/swaps");
|
|
1011
786
|
return;
|
|
1012
787
|
}
|
|
1013
|
-
const
|
|
788
|
+
const loadSwap = async () => {
|
|
1014
789
|
try {
|
|
1015
790
|
setIsLoading(true);
|
|
1016
791
|
setError(null);
|
|
1017
|
-
const response = await fetch(`/admin/
|
|
792
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
1018
793
|
credentials: "include"
|
|
1019
794
|
});
|
|
1020
795
|
if (!response.ok) {
|
|
1021
796
|
const message = await response.text();
|
|
1022
|
-
throw new Error(message || "Unable to load
|
|
797
|
+
throw new Error(message || "Unable to load swap");
|
|
1023
798
|
}
|
|
1024
799
|
const payload = await response.json();
|
|
1025
|
-
|
|
800
|
+
setSwap(payload.swap);
|
|
801
|
+
setOrder(payload.order || null);
|
|
1026
802
|
setSelectedStatus("");
|
|
1027
803
|
} catch (loadError) {
|
|
1028
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
804
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
1029
805
|
setError(message);
|
|
1030
806
|
} finally {
|
|
1031
807
|
setIsLoading(false);
|
|
1032
808
|
}
|
|
1033
809
|
};
|
|
1034
|
-
void
|
|
810
|
+
void loadSwap();
|
|
1035
811
|
}, [id, navigate]);
|
|
1036
812
|
const handleStatusUpdate = async () => {
|
|
1037
813
|
if (!id || !selectedStatus) {
|
|
@@ -1041,7 +817,7 @@ const ReturnDetailPage = () => {
|
|
|
1041
817
|
setIsUpdating(true);
|
|
1042
818
|
setUpdateError(null);
|
|
1043
819
|
setUpdateSuccess(false);
|
|
1044
|
-
const response = await fetch(`/admin/
|
|
820
|
+
const response = await fetch(`/admin/swaps/${id}/status`, {
|
|
1045
821
|
method: "POST",
|
|
1046
822
|
headers: {
|
|
1047
823
|
"Content-Type": "application/json"
|
|
@@ -1054,16 +830,17 @@ const ReturnDetailPage = () => {
|
|
|
1054
830
|
throw new Error(message || "Unable to update status");
|
|
1055
831
|
}
|
|
1056
832
|
const payload = await response.json();
|
|
1057
|
-
|
|
833
|
+
setSwap(payload.swap);
|
|
1058
834
|
setSelectedStatus("");
|
|
1059
835
|
setUpdateSuccess(true);
|
|
1060
836
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1061
|
-
const detailResponse = await fetch(`/admin/
|
|
837
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
1062
838
|
credentials: "include"
|
|
1063
839
|
});
|
|
1064
840
|
if (detailResponse.ok) {
|
|
1065
841
|
const detailPayload = await detailResponse.json();
|
|
1066
|
-
|
|
842
|
+
setSwap(detailPayload.swap);
|
|
843
|
+
setOrder(detailPayload.order || null);
|
|
1067
844
|
}
|
|
1068
845
|
} catch (updateErr) {
|
|
1069
846
|
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
@@ -1072,260 +849,445 @@ const ReturnDetailPage = () => {
|
|
|
1072
849
|
setIsUpdating(false);
|
|
1073
850
|
}
|
|
1074
851
|
};
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
852
|
+
const handleApproveClick = async () => {
|
|
853
|
+
if (!id) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
setShowShippingModal(true);
|
|
857
|
+
setSelectedShippingOptionId("");
|
|
858
|
+
setUpdateError(null);
|
|
859
|
+
try {
|
|
860
|
+
setIsLoadingShippingOptions(true);
|
|
861
|
+
const response = await fetch(`/admin/swaps/${id}/shipping-options`, {
|
|
862
|
+
credentials: "include"
|
|
863
|
+
});
|
|
864
|
+
if (!response.ok) {
|
|
865
|
+
const message = await response.text();
|
|
866
|
+
throw new Error(message || "Unable to fetch shipping options");
|
|
867
|
+
}
|
|
868
|
+
const payload = await response.json();
|
|
869
|
+
setShippingOptions(payload.shipping_options || []);
|
|
870
|
+
} catch (fetchError) {
|
|
871
|
+
const message = fetchError instanceof Error ? fetchError.message : "Unable to fetch shipping options";
|
|
872
|
+
setUpdateError(message);
|
|
873
|
+
setShowShippingModal(false);
|
|
874
|
+
} finally {
|
|
875
|
+
setIsLoadingShippingOptions(false);
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
const handleApproveConfirm = async () => {
|
|
879
|
+
if (!id || !selectedShippingOptionId) {
|
|
880
|
+
setUpdateError("Please select a shipping option");
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
try {
|
|
884
|
+
setIsApproving(true);
|
|
885
|
+
setUpdateError(null);
|
|
886
|
+
setUpdateSuccess(false);
|
|
887
|
+
const response = await fetch(`/admin/swaps/${id}/approve`, {
|
|
888
|
+
method: "POST",
|
|
889
|
+
headers: {
|
|
890
|
+
"Content-Type": "application/json"
|
|
891
|
+
},
|
|
892
|
+
credentials: "include",
|
|
893
|
+
body: JSON.stringify({
|
|
894
|
+
shipping_option_id: selectedShippingOptionId
|
|
895
|
+
})
|
|
896
|
+
});
|
|
897
|
+
if (!response.ok) {
|
|
898
|
+
const errorData = await response.json().catch(() => ({ message: "Unable to approve swap" }));
|
|
899
|
+
throw new Error(errorData.message || errorData.error || "Unable to approve swap");
|
|
900
|
+
}
|
|
901
|
+
const payload = await response.json();
|
|
902
|
+
setSwap(payload.swap);
|
|
903
|
+
setUpdateSuccess(true);
|
|
904
|
+
setShowShippingModal(false);
|
|
905
|
+
setSelectedShippingOptionId("");
|
|
906
|
+
setTimeout(() => setUpdateSuccess(false), 5e3);
|
|
907
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
908
|
+
credentials: "include"
|
|
909
|
+
});
|
|
910
|
+
if (detailResponse.ok) {
|
|
911
|
+
const detailPayload = await detailResponse.json();
|
|
912
|
+
setSwap(detailPayload.swap);
|
|
913
|
+
setOrder(detailPayload.order || null);
|
|
914
|
+
}
|
|
915
|
+
} catch (updateErr) {
|
|
916
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to approve swap";
|
|
917
|
+
setUpdateError(message);
|
|
918
|
+
} finally {
|
|
919
|
+
setIsApproving(false);
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
const handleReject = async () => {
|
|
923
|
+
if (!id) {
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
try {
|
|
927
|
+
setIsRejecting(true);
|
|
928
|
+
setUpdateError(null);
|
|
929
|
+
setUpdateSuccess(false);
|
|
930
|
+
const response = await fetch(`/admin/swaps/${id}/reject`, {
|
|
931
|
+
method: "POST",
|
|
932
|
+
headers: {
|
|
933
|
+
"Content-Type": "application/json"
|
|
934
|
+
},
|
|
935
|
+
credentials: "include",
|
|
936
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
937
|
+
});
|
|
938
|
+
if (!response.ok) {
|
|
939
|
+
const message = await response.text();
|
|
940
|
+
throw new Error(message || "Unable to reject swap");
|
|
941
|
+
}
|
|
942
|
+
const payload = await response.json();
|
|
943
|
+
setSwap(payload.swap);
|
|
944
|
+
setUpdateSuccess(true);
|
|
945
|
+
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
946
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
947
|
+
credentials: "include"
|
|
948
|
+
});
|
|
949
|
+
if (detailResponse.ok) {
|
|
950
|
+
const detailPayload = await response.json();
|
|
951
|
+
setSwap(detailPayload.swap);
|
|
952
|
+
setOrder(detailPayload.order || null);
|
|
953
|
+
}
|
|
954
|
+
} catch (updateErr) {
|
|
955
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject swap";
|
|
956
|
+
setUpdateError(message);
|
|
957
|
+
} finally {
|
|
958
|
+
setIsRejecting(false);
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
if (isLoading) {
|
|
962
|
+
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..." }) }) }) });
|
|
963
|
+
}
|
|
964
|
+
if (error || !swap) {
|
|
965
|
+
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: [
|
|
966
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
967
|
+
/* @__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" }) })
|
|
968
|
+
] }) }) });
|
|
969
|
+
}
|
|
970
|
+
const statusHistory = ((_a = swap.metadata) == null ? void 0 : _a.status_history) || [];
|
|
971
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full p-6", children: [
|
|
972
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: [
|
|
973
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
974
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
975
|
+
ui.Button,
|
|
1107
976
|
{
|
|
977
|
+
variant: "transparent",
|
|
1108
978
|
size: "small",
|
|
1109
|
-
|
|
1110
|
-
|
|
979
|
+
onClick: () => navigate("/swaps"),
|
|
980
|
+
className: "w-fit",
|
|
981
|
+
children: [
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
983
|
+
"Back to list"
|
|
984
|
+
]
|
|
1111
985
|
}
|
|
1112
|
-
)
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1121
|
-
"select",
|
|
986
|
+
),
|
|
987
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
988
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
989
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Swap Details" }),
|
|
990
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
991
|
+
] }),
|
|
992
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
993
|
+
ui.Badge,
|
|
1122
994
|
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
children: [
|
|
1127
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
1128
|
-
availableStatuses.filter((status) => status !== returnOrder.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace("_", " ").toUpperCase() }, status))
|
|
1129
|
-
]
|
|
995
|
+
size: "small",
|
|
996
|
+
className: `uppercase ${getStatusBadgeClass(swap.status)}`,
|
|
997
|
+
children: swap.status.replace(/_/g, " ")
|
|
1130
998
|
}
|
|
1131
999
|
)
|
|
1132
|
-
] })
|
|
1000
|
+
] })
|
|
1001
|
+
] }),
|
|
1002
|
+
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
1133
1003
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1134
1004
|
ui.Button,
|
|
1135
1005
|
{
|
|
1136
1006
|
variant: "primary",
|
|
1137
|
-
onClick:
|
|
1138
|
-
disabled:
|
|
1139
|
-
isLoading:
|
|
1140
|
-
children: "
|
|
1007
|
+
onClick: handleApproveClick,
|
|
1008
|
+
disabled: isApproving || isRejecting,
|
|
1009
|
+
isLoading: isApproving,
|
|
1010
|
+
children: "Approve Swap"
|
|
1011
|
+
}
|
|
1012
|
+
),
|
|
1013
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1014
|
+
ui.Button,
|
|
1015
|
+
{
|
|
1016
|
+
variant: "secondary",
|
|
1017
|
+
onClick: handleReject,
|
|
1018
|
+
disabled: isApproving || isRejecting,
|
|
1019
|
+
isLoading: isRejecting,
|
|
1020
|
+
children: "Reject Swap"
|
|
1141
1021
|
}
|
|
1142
1022
|
)
|
|
1143
1023
|
] }),
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.refund_amount ? `${((_b = returnOrder.order) == null ? void 0 : _b.currency_code) || "$"}${Number(returnOrder.refund_amount).toFixed(2)}` : "—" })
|
|
1162
|
-
] }),
|
|
1163
|
-
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1164
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
1165
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
1166
|
-
] }),
|
|
1167
|
-
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1168
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
1169
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
1024
|
+
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1025
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Update Status" }),
|
|
1026
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end", children: [
|
|
1027
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
1028
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-2 block text-sm font-medium text-ui-fg-base", children: "New Status" }),
|
|
1029
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1030
|
+
"select",
|
|
1031
|
+
{
|
|
1032
|
+
value: selectedStatus,
|
|
1033
|
+
onChange: (event) => setSelectedStatus(event.target.value),
|
|
1034
|
+
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",
|
|
1035
|
+
children: [
|
|
1036
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
1037
|
+
availableStatuses.filter((status) => status !== swap.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1038
|
+
]
|
|
1039
|
+
}
|
|
1040
|
+
)
|
|
1170
1041
|
] }),
|
|
1042
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1043
|
+
ui.Button,
|
|
1044
|
+
{
|
|
1045
|
+
variant: "primary",
|
|
1046
|
+
onClick: handleStatusUpdate,
|
|
1047
|
+
disabled: !selectedStatus || isUpdating,
|
|
1048
|
+
isLoading: isUpdating,
|
|
1049
|
+
children: "Update Status"
|
|
1050
|
+
}
|
|
1051
|
+
)
|
|
1052
|
+
] }),
|
|
1053
|
+
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
1054
|
+
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
1055
|
+
] }),
|
|
1056
|
+
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1057
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
1058
|
+
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1171
1059
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1172
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1173
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1060
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1061
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1174
1062
|
] }),
|
|
1175
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1063
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1064
|
+
ui.Button,
|
|
1065
|
+
{
|
|
1066
|
+
variant: "secondary",
|
|
1067
|
+
onClick: () => {
|
|
1068
|
+
window.open(`/app/orders/${swap.order_id}/exchanges/${swap.exchange_id}`, "_blank");
|
|
1069
|
+
},
|
|
1070
|
+
children: "View Exchange"
|
|
1071
|
+
}
|
|
1072
|
+
) })
|
|
1073
|
+
] }) : /* @__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." }) })
|
|
1180
1074
|
] }),
|
|
1181
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1182
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1183
|
-
|
|
1184
|
-
"div",
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1075
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1076
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1077
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Swap Information" }),
|
|
1078
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1079
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1080
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Swap ID" }),
|
|
1081
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
1082
|
+
] }),
|
|
1083
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1084
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
|
|
1086
|
+
] }),
|
|
1087
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1088
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
1089
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
1090
|
+
] }),
|
|
1091
|
+
swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1092
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
1093
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
|
|
1094
|
+
] }),
|
|
1095
|
+
swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1096
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
|
|
1098
|
+
] }),
|
|
1099
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1100
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
1101
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
1102
|
+
] }),
|
|
1103
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1104
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
1105
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
1106
|
+
] }),
|
|
1107
|
+
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1108
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1109
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1110
|
+
] })
|
|
1111
|
+
] })
|
|
1112
|
+
] }),
|
|
1113
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1114
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Status History" }),
|
|
1115
|
+
statusHistory.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: statusHistory.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1116
|
+
"div",
|
|
1117
|
+
{
|
|
1118
|
+
className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
|
|
1119
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1120
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1190
1121
|
ui.Badge,
|
|
1191
1122
|
{
|
|
1192
1123
|
size: "2xsmall",
|
|
1193
|
-
className: `uppercase ${getStatusBadgeClass(entry.
|
|
1194
|
-
children: entry.
|
|
1124
|
+
className: `uppercase ${getStatusBadgeClass(entry.status)}`,
|
|
1125
|
+
children: entry.status.replace(/_/g, " ")
|
|
1195
1126
|
}
|
|
1196
|
-
),
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
entry.
|
|
1127
|
+
) }),
|
|
1128
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1129
|
+
new Date(entry.timestamp).toLocaleString(),
|
|
1130
|
+
entry.admin_id && ` by ${entry.admin_id}`,
|
|
1131
|
+
entry.reason && ` - ${entry.reason}`
|
|
1200
1132
|
] })
|
|
1201
|
-
] }),
|
|
1202
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1203
|
-
new Date(entry.changed_at).toLocaleString(),
|
|
1204
|
-
entry.changed_by && ` by ${entry.changed_by}`
|
|
1205
1133
|
] })
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
] })
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
1214
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1134
|
+
},
|
|
1135
|
+
index
|
|
1136
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
1137
|
+
] })
|
|
1138
|
+
] }),
|
|
1139
|
+
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1140
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
1215
1141
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1216
1142
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1217
1143
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
1218
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1144
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
1219
1145
|
] }),
|
|
1220
1146
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1221
1147
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
1222
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1148
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
1223
1149
|
] }),
|
|
1224
1150
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1225
1151
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
1226
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((
|
|
1152
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = order.customer) == null ? void 0 : _b.email) || order.email || "—" })
|
|
1227
1153
|
] }),
|
|
1228
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1154
|
+
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1229
1155
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
1230
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1235
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Subtotal" }),
|
|
1236
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.subtotal ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.subtotal).toFixed(2)}` : "—" })
|
|
1237
|
-
] }),
|
|
1238
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1239
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Tax Total" }),
|
|
1240
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.tax_total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.tax_total).toFixed(2)}` : "—" })
|
|
1241
|
-
] }),
|
|
1242
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1243
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Shipping Total" }),
|
|
1244
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.shipping_total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.shipping_total).toFixed(2)}` : "—" })
|
|
1245
|
-
] }),
|
|
1246
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1247
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Created" }),
|
|
1248
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.created_at ? new Date(returnOrder.order.created_at).toLocaleString() : "—" })
|
|
1156
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
1157
|
+
order.currency_code || "$",
|
|
1158
|
+
(Number(order.total) / 100).toFixed(2)
|
|
1159
|
+
] })
|
|
1249
1160
|
] })
|
|
1250
1161
|
] })
|
|
1251
|
-
] })
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4
|
|
1162
|
+
] }),
|
|
1163
|
+
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: [
|
|
1164
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
1165
|
+
/* @__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: [
|
|
1166
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1167
|
+
/* @__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" }),
|
|
1168
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
1169
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
1170
|
+
] }) }),
|
|
1171
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1172
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
1173
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
1174
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
1175
|
+
] }, item.id || index)) })
|
|
1176
|
+
] }) })
|
|
1177
|
+
] }),
|
|
1178
|
+
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: [
|
|
1179
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
1180
|
+
/* @__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: [
|
|
1181
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1182
|
+
/* @__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" }),
|
|
1183
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
1184
|
+
] }) }),
|
|
1185
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1186
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
1264
1187
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
1265
|
-
] }, item.
|
|
1266
|
-
}) })
|
|
1267
|
-
] })
|
|
1188
|
+
] }, item.variant_id || index)) })
|
|
1189
|
+
] }) })
|
|
1190
|
+
] })
|
|
1268
1191
|
] }),
|
|
1269
|
-
|
|
1270
|
-
(
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1192
|
+
showShippingModal && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-md rounded-lg border border-ui-border-base bg-ui-bg-base p-6 shadow-lg", children: [
|
|
1193
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
|
|
1194
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "text-lg", children: "Select Shipping Option" }),
|
|
1195
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Please select a shipping option for the exchange. This is required to create the exchange." })
|
|
1196
|
+
] }),
|
|
1197
|
+
isLoadingShippingOptions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading shipping options..." }) }) : shippingOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error", children: "No shipping options available for this order's region." }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
|
|
1198
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-2 block text-sm font-medium text-ui-fg-base", children: "Shipping Option" }),
|
|
1199
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1200
|
+
ui.Select,
|
|
1201
|
+
{
|
|
1202
|
+
value: selectedShippingOptionId,
|
|
1203
|
+
onValueChange: setSelectedShippingOptionId,
|
|
1204
|
+
children: [
|
|
1205
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Select a shipping option" }) }),
|
|
1206
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: shippingOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: option.id, children: option.name }, option.id)) })
|
|
1207
|
+
]
|
|
1208
|
+
}
|
|
1209
|
+
)
|
|
1210
|
+
] }),
|
|
1211
|
+
updateError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-error", children: updateError }) }),
|
|
1212
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
1213
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1214
|
+
ui.Button,
|
|
1215
|
+
{
|
|
1216
|
+
variant: "secondary",
|
|
1217
|
+
onClick: () => {
|
|
1218
|
+
setShowShippingModal(false);
|
|
1219
|
+
setSelectedShippingOptionId("");
|
|
1220
|
+
setUpdateError(null);
|
|
1221
|
+
},
|
|
1222
|
+
disabled: isApproving,
|
|
1223
|
+
className: "flex-1",
|
|
1224
|
+
children: "Cancel"
|
|
1225
|
+
}
|
|
1226
|
+
),
|
|
1227
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1228
|
+
ui.Button,
|
|
1229
|
+
{
|
|
1230
|
+
variant: "primary",
|
|
1231
|
+
onClick: handleApproveConfirm,
|
|
1232
|
+
disabled: !selectedShippingOptionId || isApproving || isLoadingShippingOptions,
|
|
1233
|
+
isLoading: isApproving,
|
|
1234
|
+
className: "flex-1",
|
|
1235
|
+
children: "Confirm & Approve"
|
|
1236
|
+
}
|
|
1237
|
+
)
|
|
1238
|
+
] })
|
|
1239
|
+
] }) })
|
|
1240
|
+
] });
|
|
1279
1241
|
};
|
|
1280
1242
|
const config = adminSdk.defineRouteConfig({
|
|
1281
|
-
label: "
|
|
1243
|
+
label: "Swap Details",
|
|
1282
1244
|
icon: icons.ArrowPath
|
|
1283
1245
|
});
|
|
1284
1246
|
const i18nTranslations0 = {};
|
|
1285
1247
|
const widgetModule = { widgets: [] };
|
|
1286
1248
|
const routeModule = {
|
|
1287
1249
|
routes: [
|
|
1288
|
-
{
|
|
1289
|
-
Component: SwapsPage,
|
|
1290
|
-
path: "/swaps"
|
|
1291
|
-
},
|
|
1292
1250
|
{
|
|
1293
1251
|
Component: ReturnsPage,
|
|
1294
1252
|
path: "/returns"
|
|
1295
1253
|
},
|
|
1296
1254
|
{
|
|
1297
|
-
Component:
|
|
1298
|
-
path: "/swaps
|
|
1255
|
+
Component: SwapsPage,
|
|
1256
|
+
path: "/swaps"
|
|
1299
1257
|
},
|
|
1300
1258
|
{
|
|
1301
1259
|
Component: ReturnDetailPage,
|
|
1302
1260
|
path: "/returns/:id"
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
Component: SwapDetailPage,
|
|
1264
|
+
path: "/swaps/:id"
|
|
1303
1265
|
}
|
|
1304
1266
|
]
|
|
1305
1267
|
};
|
|
1306
1268
|
const menuItemModule = {
|
|
1307
1269
|
menuItems: [
|
|
1308
1270
|
{
|
|
1309
|
-
label: config$
|
|
1310
|
-
icon: config$
|
|
1271
|
+
label: config$2.label,
|
|
1272
|
+
icon: config$2.icon,
|
|
1311
1273
|
path: "/swaps",
|
|
1312
1274
|
nested: void 0
|
|
1313
1275
|
},
|
|
1314
1276
|
{
|
|
1315
|
-
label: config$
|
|
1316
|
-
icon: config$
|
|
1277
|
+
label: config$3.label,
|
|
1278
|
+
icon: config$3.icon,
|
|
1317
1279
|
path: "/returns",
|
|
1318
1280
|
nested: void 0
|
|
1319
1281
|
},
|
|
1320
1282
|
{
|
|
1321
|
-
label: config
|
|
1322
|
-
icon: config
|
|
1283
|
+
label: config.label,
|
|
1284
|
+
icon: config.icon,
|
|
1323
1285
|
path: "/swaps/:id",
|
|
1324
1286
|
nested: void 0
|
|
1325
1287
|
},
|
|
1326
1288
|
{
|
|
1327
|
-
label: config.label,
|
|
1328
|
-
icon: config.icon,
|
|
1289
|
+
label: config$1.label,
|
|
1290
|
+
icon: config$1.icon,
|
|
1329
1291
|
path: "/returns/:id",
|
|
1330
1292
|
nested: void 0
|
|
1331
1293
|
}
|