order-management 0.0.33 → 0.0.35
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 +436 -1126
- package/.medusa/server/src/admin/index.mjs +438 -1128
- package/.medusa/server/src/api/admin/swaps/[id]/create-exchange/route.js +328 -1
- package/.medusa/server/src/api/store/guest-orders/[id]/cancel/route.js +114 -0
- package/.medusa/server/src/api/store/guest-orders/[id]/reorder/route.js +114 -0
- package/.medusa/server/src/api/store/orders/[order_id]/swaps/route.js +6 -6
- package/.medusa/server/src/api/store/swaps/[id]/cancel/route.js +8 -8
- package/.medusa/server/src/api/store/swaps/[id]/route.js +52 -31
- package/.medusa/server/src/modules/swap/service.js +15 -4
- package/.medusa/server/src/workflows/index.js +4 -2
- package/.medusa/server/src/workflows/steps/swap/index.js +4 -2
- package/.medusa/server/src/workflows/steps/swap/update-swap-step.js +52 -0
- package/.medusa/server/src/workflows/steps/swap/validate-eligibility-step.js +4 -3
- package/.medusa/server/src/workflows/steps/swap/validate-swap-items-step.js +71 -11
- package/.medusa/server/src/workflows/swaps/update-swap-workflow.js +66 -0
- package/README.md +14 -3
- package/package.json +1 -1
- package/.medusa/server/src/api/admin/swaps/[id]/prepare-exchange/route.js +0 -265
|
@@ -1,706 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const adminSdk = require("@medusajs/admin-sdk");
|
|
3
|
-
const react = require("react");
|
|
4
2
|
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const react = require("react");
|
|
4
|
+
const adminSdk = require("@medusajs/admin-sdk");
|
|
5
5
|
const ui = require("@medusajs/ui");
|
|
6
6
|
const icons = require("@medusajs/icons");
|
|
7
7
|
const reactRouterDom = require("react-router-dom");
|
|
8
|
-
const ExchangeAutofillWidget = () => {
|
|
9
|
-
const hasProcessedRef = react.useRef(false);
|
|
10
|
-
react.useEffect(() => {
|
|
11
|
-
if (hasProcessedRef.current) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
const path = window.location.pathname;
|
|
15
|
-
const isExchangePage = path.includes("/orders/") && path.includes("/exchanges");
|
|
16
|
-
if (!isExchangePage) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
console.log("[Exchange Autofill] Widget loaded on exchange page:", path);
|
|
20
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
21
|
-
const inboundParam = searchParams.get("inbound");
|
|
22
|
-
const outboundParam = searchParams.get("outbound");
|
|
23
|
-
console.log("[Exchange Autofill] Query params:", { inboundParam: !!inboundParam, outboundParam: !!outboundParam });
|
|
24
|
-
if (!inboundParam && !outboundParam) {
|
|
25
|
-
console.log("[Exchange Autofill] No query parameters found, exiting");
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
let inboundItems = [];
|
|
29
|
-
let outboundItems = [];
|
|
30
|
-
try {
|
|
31
|
-
if (inboundParam) {
|
|
32
|
-
const decoded = atob(decodeURIComponent(inboundParam));
|
|
33
|
-
inboundItems = JSON.parse(decoded);
|
|
34
|
-
}
|
|
35
|
-
if (outboundParam) {
|
|
36
|
-
const decoded = atob(decodeURIComponent(outboundParam));
|
|
37
|
-
outboundItems = JSON.parse(decoded);
|
|
38
|
-
}
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error("[Exchange Autofill] Failed to decode query parameters:", error);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
console.log("[Exchange Autofill] Decoded items:", {
|
|
44
|
-
inboundCount: inboundItems.length,
|
|
45
|
-
outboundCount: outboundItems.length,
|
|
46
|
-
inboundItems,
|
|
47
|
-
outboundItems
|
|
48
|
-
});
|
|
49
|
-
if (inboundItems.length === 0 && outboundItems.length === 0) {
|
|
50
|
-
console.log("[Exchange Autofill] No items to fill, exiting");
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
hasProcessedRef.current = true;
|
|
54
|
-
const fillForm = () => {
|
|
55
|
-
try {
|
|
56
|
-
let attempts = 0;
|
|
57
|
-
const maxAttempts = 30;
|
|
58
|
-
let inboundFilled = false;
|
|
59
|
-
let outboundFilled = false;
|
|
60
|
-
const tryFill = () => {
|
|
61
|
-
attempts++;
|
|
62
|
-
console.log(`[Exchange Autofill] Attempt ${attempts}/${maxAttempts}`);
|
|
63
|
-
const inboundSection = findInboundSection();
|
|
64
|
-
const outboundSection = findOutboundSection();
|
|
65
|
-
console.log("[Exchange Autofill] Sections found:", {
|
|
66
|
-
inbound: !!inboundSection,
|
|
67
|
-
outbound: !!outboundSection
|
|
68
|
-
});
|
|
69
|
-
if (!inboundFilled && inboundItems.length > 0) {
|
|
70
|
-
if (inboundSection) {
|
|
71
|
-
fillInboundItems(inboundItems);
|
|
72
|
-
inboundFilled = true;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (!outboundFilled && outboundItems.length > 0) {
|
|
76
|
-
if (outboundSection) {
|
|
77
|
-
fillOutboundItems(outboundItems);
|
|
78
|
-
outboundFilled = true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (attempts < maxAttempts && (!inboundFilled || !outboundFilled)) {
|
|
82
|
-
setTimeout(tryFill, 500);
|
|
83
|
-
} else if (attempts >= maxAttempts) {
|
|
84
|
-
console.warn("[Exchange Autofill] Max attempts reached. Sections found:", {
|
|
85
|
-
inbound: !!inboundSection,
|
|
86
|
-
outbound: !!outboundSection
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
tryFill();
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error("[Exchange Autofill] Error filling form:", error);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
setTimeout(fillForm, 1500);
|
|
96
|
-
}, []);
|
|
97
|
-
return null;
|
|
98
|
-
};
|
|
99
|
-
function fillInboundItems(items) {
|
|
100
|
-
var _a;
|
|
101
|
-
if (items.length === 0) return;
|
|
102
|
-
console.log("[Exchange Autofill] Attempting to fill inbound items:", items);
|
|
103
|
-
try {
|
|
104
|
-
const inboundSection = findInboundSection();
|
|
105
|
-
console.log("[Exchange Autofill] Found inbound section:", !!inboundSection);
|
|
106
|
-
if (!inboundSection) {
|
|
107
|
-
console.warn("[Exchange Autofill] Could not find inbound section");
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const allLinks = inboundSection.querySelectorAll("a, button");
|
|
111
|
-
let addItemsButton = null;
|
|
112
|
-
for (const link of Array.from(allLinks)) {
|
|
113
|
-
const text = ((_a = link.textContent) == null ? void 0 : _a.toLowerCase().trim()) || "";
|
|
114
|
-
if (text.includes("add") && (text.includes("item") || text.includes("items"))) {
|
|
115
|
-
addItemsButton = link;
|
|
116
|
-
console.log("[Exchange Autofill] Found Add items button:", text);
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (addItemsButton) {
|
|
121
|
-
const existingItems = inboundSection.querySelectorAll('[data-testid*="item"], [data-testid*="line-item"], table tbody tr, [class*="item"]');
|
|
122
|
-
console.log("[Exchange Autofill] Existing items count:", existingItems.length);
|
|
123
|
-
if (existingItems.length === 0) {
|
|
124
|
-
console.log("[Exchange Autofill] Clicking Add items button");
|
|
125
|
-
addItemsButton.click();
|
|
126
|
-
setTimeout(() => {
|
|
127
|
-
waitForModal(8e3).then((modal) => {
|
|
128
|
-
if (modal) {
|
|
129
|
-
console.log("[Exchange Autofill] Modal appeared, waiting for content to load...");
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
console.log("[Exchange Autofill] Selecting items within modal");
|
|
132
|
-
selectInboundItems(items, modal);
|
|
133
|
-
}, 1500);
|
|
134
|
-
} else {
|
|
135
|
-
console.warn("[Exchange Autofill] Modal did not appear, trying direct selection");
|
|
136
|
-
selectInboundItems(items);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
}, 500);
|
|
140
|
-
} else {
|
|
141
|
-
console.log("[Exchange Autofill] Items already added, skipping");
|
|
142
|
-
}
|
|
143
|
-
} else {
|
|
144
|
-
console.warn("[Exchange Autofill] Could not find Add items button, trying direct selection");
|
|
145
|
-
selectInboundItems(items);
|
|
146
|
-
}
|
|
147
|
-
} catch (error) {
|
|
148
|
-
console.error("[Exchange Autofill] Error filling inbound items:", error);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
function fillOutboundItems(items) {
|
|
152
|
-
var _a;
|
|
153
|
-
if (items.length === 0) return;
|
|
154
|
-
console.log("[Exchange Autofill] Attempting to fill outbound items:", items);
|
|
155
|
-
try {
|
|
156
|
-
const outboundSection = findOutboundSection();
|
|
157
|
-
console.log("[Exchange Autofill] Found outbound section:", !!outboundSection);
|
|
158
|
-
if (!outboundSection) {
|
|
159
|
-
console.warn("[Exchange Autofill] Could not find outbound section");
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
const allLinks = outboundSection.querySelectorAll("a, button");
|
|
163
|
-
let addItemsButton = null;
|
|
164
|
-
for (const link of Array.from(allLinks)) {
|
|
165
|
-
const text = ((_a = link.textContent) == null ? void 0 : _a.toLowerCase().trim()) || "";
|
|
166
|
-
if (text.includes("add") && (text.includes("item") || text.includes("items"))) {
|
|
167
|
-
addItemsButton = link;
|
|
168
|
-
console.log("[Exchange Autofill] Found Add items button:", text);
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
if (addItemsButton) {
|
|
173
|
-
const existingItems = outboundSection.querySelectorAll('[data-testid*="item"], [data-testid*="variant"], table tbody tr, [class*="item"]');
|
|
174
|
-
console.log("[Exchange Autofill] Existing items count:", existingItems.length);
|
|
175
|
-
if (existingItems.length === 0) {
|
|
176
|
-
console.log("[Exchange Autofill] Clicking Add items button");
|
|
177
|
-
addItemsButton.click();
|
|
178
|
-
setTimeout(() => {
|
|
179
|
-
waitForModal(8e3).then((modal) => {
|
|
180
|
-
if (modal) {
|
|
181
|
-
console.log("[Exchange Autofill] Modal appeared, waiting for content to load...");
|
|
182
|
-
setTimeout(() => {
|
|
183
|
-
console.log("[Exchange Autofill] Selecting items within modal");
|
|
184
|
-
selectOutboundItems(items, modal);
|
|
185
|
-
}, 1500);
|
|
186
|
-
} else {
|
|
187
|
-
console.warn("[Exchange Autofill] Modal did not appear, trying direct selection");
|
|
188
|
-
selectOutboundItems(items);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
}, 500);
|
|
192
|
-
} else {
|
|
193
|
-
console.log("[Exchange Autofill] Items already added, skipping");
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
console.warn("[Exchange Autofill] Could not find Add items button, trying direct selection");
|
|
197
|
-
selectOutboundItems(items);
|
|
198
|
-
}
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error("[Exchange Autofill] Error filling outbound items:", error);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
function waitForModal(timeout = 5e3) {
|
|
204
|
-
return new Promise((resolve) => {
|
|
205
|
-
const startTime = Date.now();
|
|
206
|
-
let attemptCount = 0;
|
|
207
|
-
const checkForModal = () => {
|
|
208
|
-
var _a;
|
|
209
|
-
attemptCount++;
|
|
210
|
-
console.log(`[Exchange Autofill] Checking for modal (attempt ${attemptCount})...`);
|
|
211
|
-
const modalSelectors = [
|
|
212
|
-
'[role="dialog"]',
|
|
213
|
-
"[data-modal]",
|
|
214
|
-
'[data-testid*="modal"]',
|
|
215
|
-
'[data-testid*="dialog"]',
|
|
216
|
-
'[class*="Modal"]',
|
|
217
|
-
'[class*="Dialog"]',
|
|
218
|
-
'[class*="modal"]',
|
|
219
|
-
'[class*="dialog"]',
|
|
220
|
-
'[id*="modal"]',
|
|
221
|
-
'[id*="dialog"]'
|
|
222
|
-
];
|
|
223
|
-
for (const selector of modalSelectors) {
|
|
224
|
-
try {
|
|
225
|
-
const modal = document.querySelector(selector);
|
|
226
|
-
if (modal) {
|
|
227
|
-
const isVisible = modal.offsetParent !== null || window.getComputedStyle(modal).display !== "none" || window.getComputedStyle(modal).visibility !== "hidden";
|
|
228
|
-
if (isVisible) {
|
|
229
|
-
console.log(`[Exchange Autofill] Found modal via selector: ${selector}`);
|
|
230
|
-
console.log(`[Exchange Autofill] Modal element:`, modal);
|
|
231
|
-
resolve(modal);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
} catch {
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
const allElements = document.querySelectorAll("div, section");
|
|
239
|
-
for (const element of Array.from(allElements)) {
|
|
240
|
-
const htmlElement = element;
|
|
241
|
-
const style = window.getComputedStyle(htmlElement);
|
|
242
|
-
const zIndex = parseInt(style.zIndex || "0", 10);
|
|
243
|
-
if (zIndex > 1e3 && htmlElement.offsetParent !== null) {
|
|
244
|
-
const text = ((_a = htmlElement.textContent) == null ? void 0 : _a.toLowerCase()) || "";
|
|
245
|
-
if (text.includes("add") || text.includes("select") || text.includes("item")) {
|
|
246
|
-
console.log("[Exchange Autofill] Found modal via z-index and content");
|
|
247
|
-
resolve(htmlElement);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
if (Date.now() - startTime >= timeout) {
|
|
253
|
-
console.warn(`[Exchange Autofill] Modal not found within ${timeout}ms timeout after ${attemptCount} attempts`);
|
|
254
|
-
console.log(`[Exchange Autofill] Current page structure - dialogs:`, document.querySelectorAll('[role="dialog"]').length);
|
|
255
|
-
console.log(`[Exchange Autofill] Current page structure - modals:`, document.querySelectorAll('[class*="modal" i]').length);
|
|
256
|
-
resolve(null);
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
setTimeout(checkForModal, 300);
|
|
260
|
-
};
|
|
261
|
-
checkForModal();
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
function findInboundSection() {
|
|
265
|
-
var _a, _b;
|
|
266
|
-
const selectors = [
|
|
267
|
-
'[data-testid*="inbound"]',
|
|
268
|
-
'[aria-label*="inbound" i]',
|
|
269
|
-
'h2:contains("Inbound"), h3:contains("Inbound")'
|
|
270
|
-
];
|
|
271
|
-
for (const selector of selectors) {
|
|
272
|
-
try {
|
|
273
|
-
const element = document.querySelector(selector);
|
|
274
|
-
if (element) {
|
|
275
|
-
return element.closest("div, section, fieldset") || element;
|
|
276
|
-
}
|
|
277
|
-
} catch {
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="heading"]');
|
|
281
|
-
for (const heading of Array.from(headings)) {
|
|
282
|
-
const text = ((_a = heading.textContent) == null ? void 0 : _a.toLowerCase()) || "";
|
|
283
|
-
if (text.includes("inbound")) {
|
|
284
|
-
const container = heading.closest("div, section, fieldset, form");
|
|
285
|
-
if (container) {
|
|
286
|
-
console.log("[Exchange Autofill] Found inbound section via heading:", text);
|
|
287
|
-
return container;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
const allElements = document.querySelectorAll('section, div[class*="section"], fieldset');
|
|
292
|
-
for (const element of Array.from(allElements)) {
|
|
293
|
-
const text = ((_b = element.textContent) == null ? void 0 : _b.toLowerCase()) || "";
|
|
294
|
-
if (text.includes("inbound") && (text.includes("add items") || text.includes("add item") || text.includes("add"))) {
|
|
295
|
-
console.log("[Exchange Autofill] Found inbound section via text search");
|
|
296
|
-
return element;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
return null;
|
|
300
|
-
}
|
|
301
|
-
function findOutboundSection() {
|
|
302
|
-
var _a, _b;
|
|
303
|
-
const selectors = [
|
|
304
|
-
'[data-testid*="outbound"]',
|
|
305
|
-
'[aria-label*="outbound" i]',
|
|
306
|
-
'h2:contains("Outbound"), h3:contains("Outbound")'
|
|
307
|
-
];
|
|
308
|
-
for (const selector of selectors) {
|
|
309
|
-
try {
|
|
310
|
-
const element = document.querySelector(selector);
|
|
311
|
-
if (element) {
|
|
312
|
-
return element.closest("div, section, fieldset") || element;
|
|
313
|
-
}
|
|
314
|
-
} catch {
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6, [class*="heading"]');
|
|
319
|
-
for (const heading of Array.from(headings)) {
|
|
320
|
-
const text = ((_a = heading.textContent) == null ? void 0 : _a.toLowerCase()) || "";
|
|
321
|
-
if (text.includes("outbound")) {
|
|
322
|
-
const container = heading.closest("div, section, fieldset, form");
|
|
323
|
-
if (container) {
|
|
324
|
-
console.log("[Exchange Autofill] Found outbound section via heading:", text);
|
|
325
|
-
return container;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
const allElements = document.querySelectorAll('section, div[class*="section"], fieldset');
|
|
330
|
-
for (const element of Array.from(allElements)) {
|
|
331
|
-
const text = ((_b = element.textContent) == null ? void 0 : _b.toLowerCase()) || "";
|
|
332
|
-
if (text.includes("outbound") && (text.includes("add items") || text.includes("add item") || text.includes("add"))) {
|
|
333
|
-
console.log("[Exchange Autofill] Found outbound section via text search");
|
|
334
|
-
return element;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return null;
|
|
338
|
-
}
|
|
339
|
-
function selectInboundItems(items, modalContainer) {
|
|
340
|
-
var _a, _b, _c, _d;
|
|
341
|
-
let itemsSelected = 0;
|
|
342
|
-
const searchRoot = modalContainer || document;
|
|
343
|
-
console.log("[Exchange Autofill] Selecting inbound items:", items);
|
|
344
|
-
console.log("[Exchange Autofill] Search root:", modalContainer ? "modal container" : "entire document");
|
|
345
|
-
if (modalContainer) {
|
|
346
|
-
console.log("[Exchange Autofill] Modal container HTML:", modalContainer.outerHTML.substring(0, 500));
|
|
347
|
-
}
|
|
348
|
-
for (const item of items) {
|
|
349
|
-
try {
|
|
350
|
-
const selectors = [
|
|
351
|
-
`input[value="${item.id}"]`,
|
|
352
|
-
`input[data-item-id="${item.id}"]`,
|
|
353
|
-
`[data-line-item-id="${item.id}"]`,
|
|
354
|
-
`[data-testid*="${item.id}"]`,
|
|
355
|
-
`[id*="${item.id}"]`
|
|
356
|
-
];
|
|
357
|
-
let itemInput = null;
|
|
358
|
-
for (const selector of selectors) {
|
|
359
|
-
try {
|
|
360
|
-
itemInput = searchRoot.querySelector(selector);
|
|
361
|
-
if (itemInput) {
|
|
362
|
-
console.log(`[Exchange Autofill] Found inbound item input via selector: ${selector}`);
|
|
363
|
-
break;
|
|
364
|
-
}
|
|
365
|
-
} catch (e) {
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
if (!itemInput) {
|
|
369
|
-
const allInputs = searchRoot.querySelectorAll('input[type="checkbox"], input[type="radio"], input[type="text"], input');
|
|
370
|
-
console.log(`[Exchange Autofill] Checking ${allInputs.length} inputs for item ${item.id}`);
|
|
371
|
-
for (const input of Array.from(allInputs)) {
|
|
372
|
-
const row = input.closest('tr, div, li, [role="row"], td, th');
|
|
373
|
-
const rowText = (row == null ? void 0 : row.textContent) || "";
|
|
374
|
-
const inputValue = input.value || "";
|
|
375
|
-
const inputId = input.id || "";
|
|
376
|
-
const inputName = input.name || "";
|
|
377
|
-
if (rowText.includes(item.id) || inputValue.includes(item.id) || inputId.includes(item.id) || inputName.includes(item.id) || rowText.includes(item.id.substring(0, 15))) {
|
|
378
|
-
itemInput = input;
|
|
379
|
-
console.log(`[Exchange Autofill] Found inbound item input via text search - row text: ${rowText.substring(0, 100)}`);
|
|
380
|
-
break;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
if (!itemInput) {
|
|
385
|
-
const allRows = searchRoot.querySelectorAll('tr, [role="row"], li, div[class*="item"], div[class*="row"], div[class*="Item"], td, [data-testid*="row"]');
|
|
386
|
-
console.log(`[Exchange Autofill] Checking ${allRows.length} rows for item ${item.id}`);
|
|
387
|
-
for (const row of Array.from(allRows)) {
|
|
388
|
-
const rowText = row.textContent || "";
|
|
389
|
-
if (rowText.includes(item.id) || rowText.includes(item.id.substring(0, 15)) || rowText.includes(item.id.substring(item.id.length - 10))) {
|
|
390
|
-
itemInput = row.querySelector('input[type="checkbox"], input[type="radio"], input');
|
|
391
|
-
if (!itemInput) {
|
|
392
|
-
const clickable = row.querySelector('button, [role="button"], div[onclick], div[class*="select"]');
|
|
393
|
-
if (clickable) {
|
|
394
|
-
console.log(`[Exchange Autofill] Found clickable element in row, clicking it`);
|
|
395
|
-
clickable.click();
|
|
396
|
-
setTimeout(() => {
|
|
397
|
-
itemInput = row.querySelector('input[type="checkbox"], input[type="radio"], input');
|
|
398
|
-
}, 300);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
if (itemInput) {
|
|
402
|
-
console.log(`[Exchange Autofill] Found inbound item input in row containing: ${rowText.substring(0, 100)}`);
|
|
403
|
-
break;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
if (!itemInput) {
|
|
409
|
-
const clickableElements = searchRoot.querySelectorAll('button, div[role="button"], div[class*="select"], div[class*="item"], span, label');
|
|
410
|
-
console.log(`[Exchange Autofill] Checking ${clickableElements.length} clickable elements for item ${item.id}`);
|
|
411
|
-
for (const element of Array.from(clickableElements)) {
|
|
412
|
-
const elementText = element.textContent || "";
|
|
413
|
-
if (elementText.includes(item.id) || elementText.includes(item.id.substring(0, 15))) {
|
|
414
|
-
const nearbyInput = element.querySelector("input") || ((_a = element.closest("tr, div, li")) == null ? void 0 : _a.querySelector("input")) || ((_b = element.parentElement) == null ? void 0 : _b.querySelector("input"));
|
|
415
|
-
if (nearbyInput) {
|
|
416
|
-
itemInput = nearbyInput;
|
|
417
|
-
console.log(`[Exchange Autofill] Found inbound item input near clickable element`);
|
|
418
|
-
break;
|
|
419
|
-
} else {
|
|
420
|
-
console.log(`[Exchange Autofill] Clicking element containing item ID: ${elementText.substring(0, 50)}`);
|
|
421
|
-
element.click();
|
|
422
|
-
setTimeout(() => {
|
|
423
|
-
const newInput = searchRoot.querySelector(`input[value*="${item.id.substring(0, 10)}"]`);
|
|
424
|
-
if (newInput) {
|
|
425
|
-
itemInput = newInput;
|
|
426
|
-
}
|
|
427
|
-
}, 500);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
if (itemInput) {
|
|
433
|
-
if (itemInput.type === "checkbox" || itemInput.type === "radio") {
|
|
434
|
-
itemInput.checked = true;
|
|
435
|
-
const nativeInputValueSetter = (_c = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")) == null ? void 0 : _c.set;
|
|
436
|
-
if (nativeInputValueSetter) {
|
|
437
|
-
nativeInputValueSetter.call(itemInput, itemInput.value);
|
|
438
|
-
}
|
|
439
|
-
itemInput.dispatchEvent(new Event("input", { bubbles: true }));
|
|
440
|
-
itemInput.dispatchEvent(new Event("change", { bubbles: true }));
|
|
441
|
-
itemInput.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
442
|
-
} else {
|
|
443
|
-
itemInput.click();
|
|
444
|
-
}
|
|
445
|
-
const row = itemInput.closest('tr, div, li, [role="row"]');
|
|
446
|
-
if (row) {
|
|
447
|
-
const quantityInput = row.querySelector('input[type="number"]');
|
|
448
|
-
if (quantityInput) {
|
|
449
|
-
quantityInput.value = String(item.quantity);
|
|
450
|
-
const nativeInputValueSetter = (_d = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")) == null ? void 0 : _d.set;
|
|
451
|
-
if (nativeInputValueSetter) {
|
|
452
|
-
nativeInputValueSetter.call(quantityInput, String(item.quantity));
|
|
453
|
-
}
|
|
454
|
-
quantityInput.dispatchEvent(new Event("input", { bubbles: true }));
|
|
455
|
-
quantityInput.dispatchEvent(new Event("change", { bubbles: true }));
|
|
456
|
-
console.log(`[Exchange Autofill] Set quantity for inbound item ${item.id}: ${item.quantity}`);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
itemsSelected++;
|
|
460
|
-
console.log(`[Exchange Autofill] Selected inbound item: ${item.id}`);
|
|
461
|
-
} else {
|
|
462
|
-
console.warn(`[Exchange Autofill] Could not find input for inbound item ${item.id}`);
|
|
463
|
-
const allElements = searchRoot.querySelectorAll("*");
|
|
464
|
-
for (const element of Array.from(allElements)) {
|
|
465
|
-
const text = element.textContent || "";
|
|
466
|
-
const elementId = element.id || "";
|
|
467
|
-
const elementClass = element.className || "";
|
|
468
|
-
if (text.includes(item.id) || elementId.includes(item.id) || elementClass.includes(item.id.substring(0, 10))) {
|
|
469
|
-
console.log(`[Exchange Autofill] Found element containing item ID, attempting to click:`, {
|
|
470
|
-
tag: element.tagName,
|
|
471
|
-
id: elementId,
|
|
472
|
-
text: text.substring(0, 50)
|
|
473
|
-
});
|
|
474
|
-
element.click();
|
|
475
|
-
setTimeout(() => {
|
|
476
|
-
;
|
|
477
|
-
element.dispatchEvent(new MouseEvent("dblclick", { bubbles: true }));
|
|
478
|
-
}, 200);
|
|
479
|
-
break;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
if (searchRoot !== document) {
|
|
483
|
-
const allText = searchRoot.textContent || "";
|
|
484
|
-
console.log(`[Exchange Autofill] Modal content preview (first 500 chars):`, allText.substring(0, 500));
|
|
485
|
-
const allInputs = searchRoot.querySelectorAll("input");
|
|
486
|
-
console.log(`[Exchange Autofill] Found ${allInputs.length} inputs in modal`);
|
|
487
|
-
const allRows = searchRoot.querySelectorAll('tr, [role="row"], li, div');
|
|
488
|
-
console.log(`[Exchange Autofill] Found ${allRows.length} potential rows in modal`);
|
|
489
|
-
Array.from(allRows).slice(0, 5).forEach((row, idx) => {
|
|
490
|
-
var _a2;
|
|
491
|
-
console.log(`[Exchange Autofill] Row ${idx} text:`, (_a2 = row.textContent) == null ? void 0 : _a2.substring(0, 100));
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
} catch (error) {
|
|
496
|
-
console.warn(`[Exchange Autofill] Error selecting inbound item ${item.id}:`, error);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
if (itemsSelected > 0) {
|
|
500
|
-
setTimeout(() => {
|
|
501
|
-
var _a2;
|
|
502
|
-
const buttons = searchRoot.querySelectorAll('button, [role="button"]');
|
|
503
|
-
for (const buttonEl of Array.from(buttons)) {
|
|
504
|
-
const text = ((_a2 = buttonEl.textContent) == null ? void 0 : _a2.toLowerCase().trim()) || "";
|
|
505
|
-
if (text.includes("add") || text.includes("confirm") || text.includes("select") || text.includes("save")) {
|
|
506
|
-
const button = buttonEl;
|
|
507
|
-
const buttonType = "type" in button ? button.type : void 0;
|
|
508
|
-
if (!buttonType || buttonType === "submit" || buttonType === "button") {
|
|
509
|
-
console.log("[Exchange Autofill] Clicking button:", text);
|
|
510
|
-
button.click();
|
|
511
|
-
break;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}, 1e3);
|
|
516
|
-
} else {
|
|
517
|
-
console.warn("[Exchange Autofill] No inbound items were selected");
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
function selectOutboundItems(items, modalContainer) {
|
|
521
|
-
var _a, _b, _c, _d;
|
|
522
|
-
let itemsSelected = 0;
|
|
523
|
-
const searchRoot = modalContainer || document;
|
|
524
|
-
console.log("[Exchange Autofill] Selecting outbound items:", items);
|
|
525
|
-
console.log("[Exchange Autofill] Search root:", modalContainer ? "modal container" : "entire document");
|
|
526
|
-
if (modalContainer) {
|
|
527
|
-
console.log("[Exchange Autofill] Modal container HTML:", modalContainer.outerHTML.substring(0, 500));
|
|
528
|
-
}
|
|
529
|
-
for (const item of items) {
|
|
530
|
-
try {
|
|
531
|
-
const selectors = [
|
|
532
|
-
`input[value="${item.variant_id}"]`,
|
|
533
|
-
`input[data-variant-id="${item.variant_id}"]`,
|
|
534
|
-
`[data-variant-id="${item.variant_id}"]`,
|
|
535
|
-
`[data-testid*="${item.variant_id}"]`,
|
|
536
|
-
`[id*="${item.variant_id}"]`
|
|
537
|
-
];
|
|
538
|
-
let variantInput = null;
|
|
539
|
-
for (const selector of selectors) {
|
|
540
|
-
try {
|
|
541
|
-
variantInput = searchRoot.querySelector(selector);
|
|
542
|
-
if (variantInput) {
|
|
543
|
-
console.log(`[Exchange Autofill] Found outbound item input via selector: ${selector}`);
|
|
544
|
-
break;
|
|
545
|
-
}
|
|
546
|
-
} catch (e) {
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
if (!variantInput) {
|
|
550
|
-
const allInputs = searchRoot.querySelectorAll('input[type="checkbox"], input[type="radio"], input[type="text"], input');
|
|
551
|
-
console.log(`[Exchange Autofill] Checking ${allInputs.length} inputs for variant ${item.variant_id}`);
|
|
552
|
-
for (const input of Array.from(allInputs)) {
|
|
553
|
-
const row = input.closest('tr, div, li, [role="row"], td, th');
|
|
554
|
-
const rowText = (row == null ? void 0 : row.textContent) || "";
|
|
555
|
-
const inputValue = input.value || "";
|
|
556
|
-
const inputId = input.id || "";
|
|
557
|
-
const inputName = input.name || "";
|
|
558
|
-
if (rowText.includes(item.variant_id) || inputValue.includes(item.variant_id) || inputId.includes(item.variant_id) || inputName.includes(item.variant_id) || rowText.includes(item.variant_id.substring(0, 15))) {
|
|
559
|
-
variantInput = input;
|
|
560
|
-
console.log(`[Exchange Autofill] Found outbound item input via text search - row text: ${rowText.substring(0, 100)}`);
|
|
561
|
-
break;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
if (!variantInput) {
|
|
566
|
-
const allRows = searchRoot.querySelectorAll('tr, [role="row"], li, div[class*="item"], div[class*="variant"], div[class*="Variant"], td, [data-testid*="row"]');
|
|
567
|
-
console.log(`[Exchange Autofill] Checking ${allRows.length} rows for variant ${item.variant_id}`);
|
|
568
|
-
for (const row of Array.from(allRows)) {
|
|
569
|
-
const rowText = row.textContent || "";
|
|
570
|
-
if (rowText.includes(item.variant_id) || rowText.includes(item.variant_id.substring(0, 15)) || rowText.includes(item.variant_id.substring(item.variant_id.length - 10))) {
|
|
571
|
-
variantInput = row.querySelector('input[type="checkbox"], input[type="radio"], input');
|
|
572
|
-
if (!variantInput) {
|
|
573
|
-
const clickable = row.querySelector('button, [role="button"], div[onclick], div[class*="select"]');
|
|
574
|
-
if (clickable) {
|
|
575
|
-
console.log(`[Exchange Autofill] Found clickable element in row, clicking it`);
|
|
576
|
-
clickable.click();
|
|
577
|
-
setTimeout(() => {
|
|
578
|
-
variantInput = row.querySelector('input[type="checkbox"], input[type="radio"], input');
|
|
579
|
-
}, 300);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
if (variantInput) {
|
|
583
|
-
console.log(`[Exchange Autofill] Found outbound item input in row containing: ${rowText.substring(0, 100)}`);
|
|
584
|
-
break;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
if (!variantInput) {
|
|
590
|
-
const clickableElements = searchRoot.querySelectorAll('button, div[role="button"], div[class*="select"], div[class*="variant"], span, label');
|
|
591
|
-
console.log(`[Exchange Autofill] Checking ${clickableElements.length} clickable elements for variant ${item.variant_id}`);
|
|
592
|
-
for (const element of Array.from(clickableElements)) {
|
|
593
|
-
const elementText = element.textContent || "";
|
|
594
|
-
if (elementText.includes(item.variant_id) || elementText.includes(item.variant_id.substring(0, 15))) {
|
|
595
|
-
const nearbyInput = element.querySelector("input") || ((_a = element.closest("tr, div, li")) == null ? void 0 : _a.querySelector("input")) || ((_b = element.parentElement) == null ? void 0 : _b.querySelector("input"));
|
|
596
|
-
if (nearbyInput) {
|
|
597
|
-
variantInput = nearbyInput;
|
|
598
|
-
console.log(`[Exchange Autofill] Found outbound item input near clickable element`);
|
|
599
|
-
break;
|
|
600
|
-
} else {
|
|
601
|
-
console.log(`[Exchange Autofill] Clicking element containing variant ID: ${elementText.substring(0, 50)}`);
|
|
602
|
-
element.click();
|
|
603
|
-
setTimeout(() => {
|
|
604
|
-
const newInput = searchRoot.querySelector(`input[value*="${item.variant_id.substring(0, 10)}"]`);
|
|
605
|
-
if (newInput) {
|
|
606
|
-
variantInput = newInput;
|
|
607
|
-
}
|
|
608
|
-
}, 500);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
if (variantInput) {
|
|
614
|
-
if (variantInput.type === "checkbox" || variantInput.type === "radio") {
|
|
615
|
-
variantInput.checked = true;
|
|
616
|
-
const nativeInputValueSetter = (_c = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")) == null ? void 0 : _c.set;
|
|
617
|
-
if (nativeInputValueSetter) {
|
|
618
|
-
nativeInputValueSetter.call(variantInput, variantInput.value);
|
|
619
|
-
}
|
|
620
|
-
variantInput.dispatchEvent(new Event("input", { bubbles: true }));
|
|
621
|
-
variantInput.dispatchEvent(new Event("change", { bubbles: true }));
|
|
622
|
-
variantInput.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
|
623
|
-
} else {
|
|
624
|
-
variantInput.click();
|
|
625
|
-
}
|
|
626
|
-
const row = variantInput.closest('tr, div, li, [role="row"]');
|
|
627
|
-
if (row) {
|
|
628
|
-
const quantityInput = row.querySelector('input[type="number"]');
|
|
629
|
-
if (quantityInput) {
|
|
630
|
-
quantityInput.value = String(item.quantity);
|
|
631
|
-
const nativeInputValueSetter = (_d = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")) == null ? void 0 : _d.set;
|
|
632
|
-
if (nativeInputValueSetter) {
|
|
633
|
-
nativeInputValueSetter.call(quantityInput, String(item.quantity));
|
|
634
|
-
}
|
|
635
|
-
quantityInput.dispatchEvent(new Event("input", { bubbles: true }));
|
|
636
|
-
quantityInput.dispatchEvent(new Event("change", { bubbles: true }));
|
|
637
|
-
console.log(`[Exchange Autofill] Set quantity for outbound item ${item.variant_id}: ${item.quantity}`);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
itemsSelected++;
|
|
641
|
-
console.log(`[Exchange Autofill] Selected outbound item: ${item.variant_id}`);
|
|
642
|
-
} else {
|
|
643
|
-
console.warn(`[Exchange Autofill] Could not find input for outbound item ${item.variant_id}`);
|
|
644
|
-
const allElements = searchRoot.querySelectorAll("*");
|
|
645
|
-
for (const element of Array.from(allElements)) {
|
|
646
|
-
const text = element.textContent || "";
|
|
647
|
-
const elementId = element.id || "";
|
|
648
|
-
const elementClass = element.className || "";
|
|
649
|
-
if (text.includes(item.variant_id) || elementId.includes(item.variant_id) || elementClass.includes(item.variant_id.substring(0, 10))) {
|
|
650
|
-
console.log(`[Exchange Autofill] Found element containing variant ID, attempting to click:`, {
|
|
651
|
-
tag: element.tagName,
|
|
652
|
-
id: elementId,
|
|
653
|
-
text: text.substring(0, 50)
|
|
654
|
-
});
|
|
655
|
-
element.click();
|
|
656
|
-
setTimeout(() => {
|
|
657
|
-
;
|
|
658
|
-
element.dispatchEvent(new MouseEvent("dblclick", { bubbles: true }));
|
|
659
|
-
}, 200);
|
|
660
|
-
break;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
if (searchRoot !== document) {
|
|
664
|
-
const allText = searchRoot.textContent || "";
|
|
665
|
-
console.log(`[Exchange Autofill] Modal content preview (first 500 chars):`, allText.substring(0, 500));
|
|
666
|
-
const allInputs = searchRoot.querySelectorAll("input");
|
|
667
|
-
console.log(`[Exchange Autofill] Found ${allInputs.length} inputs in modal`);
|
|
668
|
-
const allRows = searchRoot.querySelectorAll('tr, [role="row"], li, div');
|
|
669
|
-
console.log(`[Exchange Autofill] Found ${allRows.length} potential rows in modal`);
|
|
670
|
-
Array.from(allRows).slice(0, 5).forEach((row, idx) => {
|
|
671
|
-
var _a2;
|
|
672
|
-
console.log(`[Exchange Autofill] Row ${idx} text:`, (_a2 = row.textContent) == null ? void 0 : _a2.substring(0, 100));
|
|
673
|
-
});
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
} catch (error) {
|
|
677
|
-
console.warn(`[Exchange Autofill] Error selecting outbound item ${item.variant_id}:`, error);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
if (itemsSelected > 0) {
|
|
681
|
-
setTimeout(() => {
|
|
682
|
-
var _a2;
|
|
683
|
-
const buttons = searchRoot.querySelectorAll('button, [role="button"]');
|
|
684
|
-
for (const buttonEl of Array.from(buttons)) {
|
|
685
|
-
const text = ((_a2 = buttonEl.textContent) == null ? void 0 : _a2.toLowerCase().trim()) || "";
|
|
686
|
-
if (text.includes("add") || text.includes("confirm") || text.includes("select") || text.includes("save")) {
|
|
687
|
-
const button = buttonEl;
|
|
688
|
-
const buttonType = "type" in button ? button.type : void 0;
|
|
689
|
-
if (!buttonType || buttonType === "submit" || buttonType === "button") {
|
|
690
|
-
console.log("[Exchange Autofill] Clicking button:", text);
|
|
691
|
-
button.click();
|
|
692
|
-
break;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}, 1e3);
|
|
697
|
-
} else {
|
|
698
|
-
console.warn("[Exchange Autofill] No outbound items were selected");
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
adminSdk.defineWidgetConfig({
|
|
702
|
-
zone: "order.details.before"
|
|
703
|
-
});
|
|
704
8
|
const useDebounce$1 = (value, delay) => {
|
|
705
9
|
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
706
10
|
react.useEffect(() => {
|
|
@@ -714,21 +18,21 @@ const getStatusBadgeClass$3 = (status) => {
|
|
|
714
18
|
if (statusLower === "requested") {
|
|
715
19
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
716
20
|
}
|
|
717
|
-
if (statusLower === "
|
|
21
|
+
if (statusLower === "approved") {
|
|
718
22
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
719
23
|
}
|
|
720
|
-
if (statusLower === "
|
|
24
|
+
if (statusLower === "rejected") {
|
|
721
25
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
722
26
|
}
|
|
723
27
|
if (statusLower === "completed") {
|
|
724
28
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
725
29
|
}
|
|
726
|
-
if (statusLower === "
|
|
30
|
+
if (statusLower === "cancelled") {
|
|
727
31
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
728
32
|
}
|
|
729
33
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
730
34
|
};
|
|
731
|
-
const
|
|
35
|
+
const SwapsPage = () => {
|
|
732
36
|
const navigate = reactRouterDom.useNavigate();
|
|
733
37
|
const [items, setItems] = react.useState([]);
|
|
734
38
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
@@ -740,7 +44,7 @@ const ReturnsPage = () => {
|
|
|
740
44
|
const [offset, setOffset] = react.useState(0);
|
|
741
45
|
const [count, setCount] = react.useState(0);
|
|
742
46
|
const limit = 50;
|
|
743
|
-
const
|
|
47
|
+
const loadSwaps = react.useCallback(
|
|
744
48
|
async (nextOffset, replace = false) => {
|
|
745
49
|
var _a;
|
|
746
50
|
try {
|
|
@@ -757,25 +61,24 @@ const ReturnsPage = () => {
|
|
|
757
61
|
params.set("status", statusFilter);
|
|
758
62
|
}
|
|
759
63
|
if (debouncedSearchQuery.trim()) {
|
|
760
|
-
params.set("
|
|
64
|
+
params.set("order_id", debouncedSearchQuery.trim());
|
|
761
65
|
}
|
|
762
|
-
params.set("order", "created_at");
|
|
763
66
|
const response = await fetch(
|
|
764
|
-
`/admin/
|
|
67
|
+
`/admin/swaps?${params.toString()}`,
|
|
765
68
|
{ credentials: "include" }
|
|
766
69
|
);
|
|
767
70
|
if (!response.ok) {
|
|
768
71
|
const message = await response.text();
|
|
769
|
-
throw new Error(message || "Unable to load
|
|
72
|
+
throw new Error(message || "Unable to load swaps");
|
|
770
73
|
}
|
|
771
74
|
const payload = await response.json();
|
|
772
75
|
setCount(payload.count ?? 0);
|
|
773
|
-
setOffset(nextOffset + (((_a = payload.
|
|
76
|
+
setOffset(nextOffset + (((_a = payload.swaps) == null ? void 0 : _a.length) ?? 0));
|
|
774
77
|
setItems(
|
|
775
|
-
(prev) => replace ? payload.
|
|
78
|
+
(prev) => replace ? payload.swaps ?? [] : [...prev, ...payload.swaps ?? []]
|
|
776
79
|
);
|
|
777
80
|
} catch (loadError) {
|
|
778
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
81
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swaps";
|
|
779
82
|
setError(message);
|
|
780
83
|
} finally {
|
|
781
84
|
setIsLoading(false);
|
|
@@ -785,8 +88,8 @@ const ReturnsPage = () => {
|
|
|
785
88
|
[statusFilter, debouncedSearchQuery]
|
|
786
89
|
);
|
|
787
90
|
react.useEffect(() => {
|
|
788
|
-
void
|
|
789
|
-
}, [statusFilter, debouncedSearchQuery,
|
|
91
|
+
void loadSwaps(0, true);
|
|
92
|
+
}, [statusFilter, debouncedSearchQuery, loadSwaps]);
|
|
790
93
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
791
94
|
const availableStatuses = react.useMemo(() => {
|
|
792
95
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -796,16 +99,16 @@ const ReturnsPage = () => {
|
|
|
796
99
|
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: [
|
|
797
100
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
798
101
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
799
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
800
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
102
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Swaps" }),
|
|
103
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer swap requests" })
|
|
801
104
|
] }),
|
|
802
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
105
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadSwaps(0, true), children: "Refresh" })
|
|
803
106
|
] }),
|
|
804
107
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
805
108
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
806
109
|
ui.Input,
|
|
807
110
|
{
|
|
808
|
-
placeholder: "Search by
|
|
111
|
+
placeholder: "Search by swap ID or order ID",
|
|
809
112
|
value: searchQuery,
|
|
810
113
|
onChange: (event) => setSearchQuery(event.target.value),
|
|
811
114
|
className: "md:max-w-sm"
|
|
@@ -830,51 +133,50 @@ const ReturnsPage = () => {
|
|
|
830
133
|
ui.Button,
|
|
831
134
|
{
|
|
832
135
|
variant: "secondary",
|
|
833
|
-
onClick: () =>
|
|
136
|
+
onClick: () => loadSwaps(0, true),
|
|
834
137
|
children: "Try again"
|
|
835
138
|
}
|
|
836
139
|
) })
|
|
837
140
|
] }) : null,
|
|
838
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
839
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
840
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
141
|
+
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: [
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No swaps yet" }),
|
|
143
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Swap requests created by customers will appear here." })
|
|
841
144
|
] }) : /* @__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: [
|
|
842
145
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
843
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", 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: "Swap ID" }),
|
|
844
147
|
/* @__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" }),
|
|
845
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Customer" }),
|
|
846
148
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
847
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "
|
|
149
|
+
/* @__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" }),
|
|
848
150
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
849
151
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
850
152
|
] }) }),
|
|
851
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
153
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((swap) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
852
154
|
"tr",
|
|
853
155
|
{
|
|
854
156
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
855
|
-
onClick: () => navigate(`/
|
|
157
|
+
onClick: () => navigate(`/swaps/${swap.id}`),
|
|
856
158
|
children: [
|
|
857
|
-
/* @__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:
|
|
858
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children:
|
|
859
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
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: swap.id }) }) }),
|
|
160
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: swap.order_id }),
|
|
860
161
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
861
162
|
ui.Badge,
|
|
862
163
|
{
|
|
863
164
|
size: "2xsmall",
|
|
864
|
-
className: `uppercase ${getStatusBadgeClass$3(
|
|
865
|
-
children:
|
|
165
|
+
className: `uppercase ${getStatusBadgeClass$3(swap.status)}`,
|
|
166
|
+
children: swap.status.replace(/_/g, " ")
|
|
866
167
|
}
|
|
867
168
|
) }),
|
|
868
169
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
869
|
-
const amount =
|
|
170
|
+
const amount = swap.difference_due;
|
|
870
171
|
if (amount == null || amount === void 0) {
|
|
871
172
|
return "—";
|
|
872
173
|
}
|
|
873
174
|
const displayAmount = Number(amount) / 100;
|
|
874
|
-
const currency =
|
|
875
|
-
|
|
175
|
+
const currency = swap.currency_code || "$";
|
|
176
|
+
const sign = displayAmount >= 0 ? "+" : "";
|
|
177
|
+
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
876
178
|
})() }),
|
|
877
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(
|
|
179
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(swap.created_at).toLocaleDateString("en-US", {
|
|
878
180
|
year: "numeric",
|
|
879
181
|
month: "short",
|
|
880
182
|
day: "numeric",
|
|
@@ -889,14 +191,14 @@ const ReturnsPage = () => {
|
|
|
889
191
|
size: "small",
|
|
890
192
|
onClick: (e) => {
|
|
891
193
|
e.stopPropagation();
|
|
892
|
-
navigate(`/
|
|
194
|
+
navigate(`/swaps/${swap.id}`);
|
|
893
195
|
},
|
|
894
196
|
children: "View"
|
|
895
197
|
}
|
|
896
198
|
) })
|
|
897
199
|
]
|
|
898
200
|
},
|
|
899
|
-
|
|
201
|
+
swap.id
|
|
900
202
|
)) })
|
|
901
203
|
] }) }),
|
|
902
204
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -904,14 +206,14 @@ const ReturnsPage = () => {
|
|
|
904
206
|
{
|
|
905
207
|
variant: "secondary",
|
|
906
208
|
isLoading: isFetchingMore,
|
|
907
|
-
onClick: () =>
|
|
209
|
+
onClick: () => loadSwaps(offset, false),
|
|
908
210
|
children: "Load more"
|
|
909
211
|
}
|
|
910
212
|
) }) : null
|
|
911
213
|
] }) });
|
|
912
214
|
};
|
|
913
215
|
const config$3 = adminSdk.defineRouteConfig({
|
|
914
|
-
label: "
|
|
216
|
+
label: "Swaps",
|
|
915
217
|
icon: icons.ArrowPath
|
|
916
218
|
});
|
|
917
219
|
const useDebounce = (value, delay) => {
|
|
@@ -927,21 +229,21 @@ const getStatusBadgeClass$2 = (status) => {
|
|
|
927
229
|
if (statusLower === "requested") {
|
|
928
230
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
929
231
|
}
|
|
930
|
-
if (statusLower === "
|
|
232
|
+
if (statusLower === "received") {
|
|
931
233
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
932
234
|
}
|
|
933
|
-
if (statusLower === "
|
|
235
|
+
if (statusLower === "requires_action") {
|
|
934
236
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
935
237
|
}
|
|
936
238
|
if (statusLower === "completed") {
|
|
937
239
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
938
240
|
}
|
|
939
|
-
if (statusLower === "
|
|
241
|
+
if (statusLower === "canceled") {
|
|
940
242
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
941
243
|
}
|
|
942
244
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
943
245
|
};
|
|
944
|
-
const
|
|
246
|
+
const ReturnsPage = () => {
|
|
945
247
|
const navigate = reactRouterDom.useNavigate();
|
|
946
248
|
const [items, setItems] = react.useState([]);
|
|
947
249
|
const [statusFilter, setStatusFilter] = react.useState("all");
|
|
@@ -953,7 +255,7 @@ const SwapsPage = () => {
|
|
|
953
255
|
const [offset, setOffset] = react.useState(0);
|
|
954
256
|
const [count, setCount] = react.useState(0);
|
|
955
257
|
const limit = 50;
|
|
956
|
-
const
|
|
258
|
+
const loadReturns = react.useCallback(
|
|
957
259
|
async (nextOffset, replace = false) => {
|
|
958
260
|
var _a;
|
|
959
261
|
try {
|
|
@@ -970,24 +272,25 @@ const SwapsPage = () => {
|
|
|
970
272
|
params.set("status", statusFilter);
|
|
971
273
|
}
|
|
972
274
|
if (debouncedSearchQuery.trim()) {
|
|
973
|
-
params.set("
|
|
275
|
+
params.set("q", debouncedSearchQuery.trim());
|
|
974
276
|
}
|
|
277
|
+
params.set("order", "created_at");
|
|
975
278
|
const response = await fetch(
|
|
976
|
-
`/admin/
|
|
279
|
+
`/admin/returns?${params.toString()}`,
|
|
977
280
|
{ credentials: "include" }
|
|
978
281
|
);
|
|
979
282
|
if (!response.ok) {
|
|
980
283
|
const message = await response.text();
|
|
981
|
-
throw new Error(message || "Unable to load
|
|
284
|
+
throw new Error(message || "Unable to load return orders");
|
|
982
285
|
}
|
|
983
286
|
const payload = await response.json();
|
|
984
287
|
setCount(payload.count ?? 0);
|
|
985
|
-
setOffset(nextOffset + (((_a = payload.
|
|
288
|
+
setOffset(nextOffset + (((_a = payload.returns) == null ? void 0 : _a.length) ?? 0));
|
|
986
289
|
setItems(
|
|
987
|
-
(prev) => replace ? payload.
|
|
290
|
+
(prev) => replace ? payload.returns ?? [] : [...prev, ...payload.returns ?? []]
|
|
988
291
|
);
|
|
989
292
|
} catch (loadError) {
|
|
990
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
293
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return orders";
|
|
991
294
|
setError(message);
|
|
992
295
|
} finally {
|
|
993
296
|
setIsLoading(false);
|
|
@@ -997,8 +300,8 @@ const SwapsPage = () => {
|
|
|
997
300
|
[statusFilter, debouncedSearchQuery]
|
|
998
301
|
);
|
|
999
302
|
react.useEffect(() => {
|
|
1000
|
-
void
|
|
1001
|
-
}, [statusFilter, debouncedSearchQuery,
|
|
303
|
+
void loadReturns(0, true);
|
|
304
|
+
}, [statusFilter, debouncedSearchQuery, loadReturns]);
|
|
1002
305
|
const hasMore = react.useMemo(() => offset < count, [offset, count]);
|
|
1003
306
|
const availableStatuses = react.useMemo(() => {
|
|
1004
307
|
const statuses = /* @__PURE__ */ new Set();
|
|
@@ -1008,16 +311,16 @@ const SwapsPage = () => {
|
|
|
1008
311
|
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: [
|
|
1009
312
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1010
313
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1011
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1012
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer
|
|
314
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Orders" }),
|
|
315
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "View and manage all customer return orders" })
|
|
1013
316
|
] }),
|
|
1014
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () =>
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "primary", onClick: () => loadReturns(0, true), children: "Refresh" })
|
|
1015
318
|
] }),
|
|
1016
319
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
1017
320
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1018
321
|
ui.Input,
|
|
1019
322
|
{
|
|
1020
|
-
placeholder: "Search by
|
|
323
|
+
placeholder: "Search by return ID, order ID, or customer email",
|
|
1021
324
|
value: searchQuery,
|
|
1022
325
|
onChange: (event) => setSearchQuery(event.target.value),
|
|
1023
326
|
className: "md:max-w-sm"
|
|
@@ -1042,50 +345,51 @@ const SwapsPage = () => {
|
|
|
1042
345
|
ui.Button,
|
|
1043
346
|
{
|
|
1044
347
|
variant: "secondary",
|
|
1045
|
-
onClick: () =>
|
|
348
|
+
onClick: () => loadReturns(0, true),
|
|
1046
349
|
children: "Try again"
|
|
1047
350
|
}
|
|
1048
351
|
) })
|
|
1049
352
|
] }) : null,
|
|
1050
|
-
isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading
|
|
1051
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No
|
|
1052
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
353
|
+
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: [
|
|
354
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-xl", children: "No return orders yet" }),
|
|
355
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Return orders created by customers will appear here." })
|
|
1053
356
|
] }) : /* @__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: [
|
|
1054
357
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1055
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", 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: "Return ID" }),
|
|
1056
359
|
/* @__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" }),
|
|
1057
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" }),
|
|
1058
|
-
/* @__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: "Refund Amount" }),
|
|
1059
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" }),
|
|
1060
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" })
|
|
1061
365
|
] }) }),
|
|
1062
|
-
/* @__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((returnOrder) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1063
367
|
"tr",
|
|
1064
368
|
{
|
|
1065
369
|
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
1066
|
-
onClick: () => navigate(`/
|
|
370
|
+
onClick: () => navigate(`/returns/${returnOrder.id}`),
|
|
1067
371
|
children: [
|
|
1068
|
-
/* @__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:
|
|
1069
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", 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: returnOrder.id }) }) }),
|
|
373
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.order_id }),
|
|
374
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: returnOrder.customer_email || returnOrder.order_email || "—" }),
|
|
1070
375
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1071
376
|
ui.Badge,
|
|
1072
377
|
{
|
|
1073
378
|
size: "2xsmall",
|
|
1074
|
-
className: `uppercase ${getStatusBadgeClass$2(
|
|
1075
|
-
children:
|
|
379
|
+
className: `uppercase ${getStatusBadgeClass$2(returnOrder.status)}`,
|
|
380
|
+
children: returnOrder.status.replace(/_/g, " ")
|
|
1076
381
|
}
|
|
1077
382
|
) }),
|
|
1078
383
|
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: (() => {
|
|
1079
|
-
const amount =
|
|
384
|
+
const amount = returnOrder.refund_amount;
|
|
1080
385
|
if (amount == null || amount === void 0) {
|
|
1081
386
|
return "—";
|
|
1082
387
|
}
|
|
1083
388
|
const displayAmount = Number(amount) / 100;
|
|
1084
|
-
const currency =
|
|
1085
|
-
|
|
1086
|
-
return `${sign}${currency}${displayAmount.toFixed(2)}`;
|
|
389
|
+
const currency = returnOrder.currency_code || "$";
|
|
390
|
+
return `${currency}${displayAmount.toFixed(2)}`;
|
|
1087
391
|
})() }),
|
|
1088
|
-
/* @__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(returnOrder.created_at).toLocaleDateString("en-US", {
|
|
1089
393
|
year: "numeric",
|
|
1090
394
|
month: "short",
|
|
1091
395
|
day: "numeric",
|
|
@@ -1100,14 +404,14 @@ const SwapsPage = () => {
|
|
|
1100
404
|
size: "small",
|
|
1101
405
|
onClick: (e) => {
|
|
1102
406
|
e.stopPropagation();
|
|
1103
|
-
navigate(`/
|
|
407
|
+
navigate(`/returns/${returnOrder.id}`);
|
|
1104
408
|
},
|
|
1105
409
|
children: "View"
|
|
1106
410
|
}
|
|
1107
411
|
) })
|
|
1108
412
|
]
|
|
1109
413
|
},
|
|
1110
|
-
|
|
414
|
+
returnOrder.id
|
|
1111
415
|
)) })
|
|
1112
416
|
] }) }),
|
|
1113
417
|
hasMore ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1115,14 +419,14 @@ const SwapsPage = () => {
|
|
|
1115
419
|
{
|
|
1116
420
|
variant: "secondary",
|
|
1117
421
|
isLoading: isFetchingMore,
|
|
1118
|
-
onClick: () =>
|
|
422
|
+
onClick: () => loadReturns(offset, false),
|
|
1119
423
|
children: "Load more"
|
|
1120
424
|
}
|
|
1121
425
|
) }) : null
|
|
1122
426
|
] }) });
|
|
1123
427
|
};
|
|
1124
428
|
const config$2 = adminSdk.defineRouteConfig({
|
|
1125
|
-
label: "
|
|
429
|
+
label: "Return Orders",
|
|
1126
430
|
icon: icons.ArrowPath
|
|
1127
431
|
});
|
|
1128
432
|
const getStatusBadgeClass$1 = (status) => {
|
|
@@ -1130,65 +434,63 @@ const getStatusBadgeClass$1 = (status) => {
|
|
|
1130
434
|
if (statusLower === "requested") {
|
|
1131
435
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1132
436
|
}
|
|
1133
|
-
if (statusLower === "
|
|
437
|
+
if (statusLower === "approved") {
|
|
1134
438
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1135
439
|
}
|
|
1136
|
-
if (statusLower === "
|
|
440
|
+
if (statusLower === "rejected") {
|
|
1137
441
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1138
442
|
}
|
|
1139
443
|
if (statusLower === "completed") {
|
|
1140
444
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1141
445
|
}
|
|
1142
|
-
if (statusLower === "
|
|
446
|
+
if (statusLower === "cancelled") {
|
|
1143
447
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1144
448
|
}
|
|
1145
449
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1146
450
|
};
|
|
1147
|
-
const
|
|
1148
|
-
var _a, _b
|
|
451
|
+
const SwapDetailPage = () => {
|
|
452
|
+
var _a, _b;
|
|
1149
453
|
const navigate = reactRouterDom.useNavigate();
|
|
1150
454
|
const { id } = reactRouterDom.useParams();
|
|
1151
|
-
const [
|
|
455
|
+
const [swap, setSwap] = react.useState(null);
|
|
456
|
+
const [order, setOrder] = react.useState(null);
|
|
1152
457
|
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
1153
458
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1154
459
|
const [isUpdating, setIsUpdating] = react.useState(false);
|
|
460
|
+
const [isApproving, setIsApproving] = react.useState(false);
|
|
461
|
+
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
1155
462
|
const [error, setError] = react.useState(null);
|
|
1156
463
|
const [updateError, setUpdateError] = react.useState(null);
|
|
1157
464
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
1158
|
-
const availableStatuses = [
|
|
1159
|
-
"requested",
|
|
1160
|
-
"received",
|
|
1161
|
-
"requires_action",
|
|
1162
|
-
"completed",
|
|
1163
|
-
"canceled"
|
|
1164
|
-
];
|
|
465
|
+
const availableStatuses = ["requested", "approved", "rejected"];
|
|
1165
466
|
react.useEffect(() => {
|
|
1166
467
|
if (!id) {
|
|
1167
|
-
navigate("/
|
|
468
|
+
navigate("/swaps");
|
|
1168
469
|
return;
|
|
1169
470
|
}
|
|
1170
|
-
const
|
|
471
|
+
const loadSwap = async () => {
|
|
1171
472
|
try {
|
|
1172
473
|
setIsLoading(true);
|
|
1173
474
|
setError(null);
|
|
1174
|
-
const response = await fetch(`/admin/
|
|
475
|
+
const response = await fetch(`/admin/swaps/${id}`, {
|
|
1175
476
|
credentials: "include"
|
|
1176
477
|
});
|
|
1177
478
|
if (!response.ok) {
|
|
1178
479
|
const message = await response.text();
|
|
1179
|
-
throw new Error(message || "Unable to load
|
|
480
|
+
throw new Error(message || "Unable to load swap");
|
|
1180
481
|
}
|
|
1181
482
|
const payload = await response.json();
|
|
1182
|
-
|
|
483
|
+
setSwap(payload.swap);
|
|
484
|
+
setOrder(payload.order || null);
|
|
1183
485
|
setSelectedStatus("");
|
|
1184
486
|
} catch (loadError) {
|
|
1185
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
487
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load swap";
|
|
1186
488
|
setError(message);
|
|
1187
489
|
} finally {
|
|
1188
490
|
setIsLoading(false);
|
|
1189
491
|
}
|
|
1190
492
|
};
|
|
1191
|
-
void
|
|
493
|
+
void loadSwap();
|
|
1192
494
|
}, [id, navigate]);
|
|
1193
495
|
const handleStatusUpdate = async () => {
|
|
1194
496
|
if (!id || !selectedStatus) {
|
|
@@ -1198,7 +500,7 @@ const ReturnDetailPage = () => {
|
|
|
1198
500
|
setIsUpdating(true);
|
|
1199
501
|
setUpdateError(null);
|
|
1200
502
|
setUpdateSuccess(false);
|
|
1201
|
-
const response = await fetch(`/admin/
|
|
503
|
+
const response = await fetch(`/admin/swaps/${id}/status`, {
|
|
1202
504
|
method: "POST",
|
|
1203
505
|
headers: {
|
|
1204
506
|
"Content-Type": "application/json"
|
|
@@ -1211,16 +513,17 @@ const ReturnDetailPage = () => {
|
|
|
1211
513
|
throw new Error(message || "Unable to update status");
|
|
1212
514
|
}
|
|
1213
515
|
const payload = await response.json();
|
|
1214
|
-
|
|
516
|
+
setSwap(payload.swap);
|
|
1215
517
|
setSelectedStatus("");
|
|
1216
518
|
setUpdateSuccess(true);
|
|
1217
519
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1218
|
-
const detailResponse = await fetch(`/admin/
|
|
520
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
1219
521
|
credentials: "include"
|
|
1220
522
|
});
|
|
1221
523
|
if (detailResponse.ok) {
|
|
1222
524
|
const detailPayload = await detailResponse.json();
|
|
1223
|
-
|
|
525
|
+
setSwap(detailPayload.swap);
|
|
526
|
+
setOrder(detailPayload.order || null);
|
|
1224
527
|
}
|
|
1225
528
|
} catch (updateErr) {
|
|
1226
529
|
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
@@ -1229,16 +532,93 @@ const ReturnDetailPage = () => {
|
|
|
1229
532
|
setIsUpdating(false);
|
|
1230
533
|
}
|
|
1231
534
|
};
|
|
535
|
+
const handleAutoCreateExchange = async () => {
|
|
536
|
+
if (!id) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
try {
|
|
540
|
+
setIsApproving(true);
|
|
541
|
+
setUpdateError(null);
|
|
542
|
+
setUpdateSuccess(false);
|
|
543
|
+
const response = await fetch(`/admin/swaps/${id}/create-exchange`, {
|
|
544
|
+
method: "POST",
|
|
545
|
+
headers: {
|
|
546
|
+
"Content-Type": "application/json"
|
|
547
|
+
},
|
|
548
|
+
credentials: "include"
|
|
549
|
+
});
|
|
550
|
+
if (!response.ok) {
|
|
551
|
+
const message = await response.text();
|
|
552
|
+
throw new Error(message || "Unable to create exchange from swap");
|
|
553
|
+
}
|
|
554
|
+
const payload = await response.json();
|
|
555
|
+
setSwap(payload.swap);
|
|
556
|
+
setUpdateSuccess(true);
|
|
557
|
+
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
558
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
559
|
+
credentials: "include"
|
|
560
|
+
});
|
|
561
|
+
if (detailResponse.ok) {
|
|
562
|
+
const detailPayload = await detailResponse.json();
|
|
563
|
+
setSwap(detailPayload.swap);
|
|
564
|
+
setOrder(detailPayload.order || null);
|
|
565
|
+
}
|
|
566
|
+
} catch (approveErr) {
|
|
567
|
+
const message = approveErr instanceof Error ? approveErr.message : "Unable to create exchange from swap";
|
|
568
|
+
setUpdateError(message);
|
|
569
|
+
} finally {
|
|
570
|
+
setIsApproving(false);
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
const handleReject = async () => {
|
|
574
|
+
if (!id) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
setIsRejecting(true);
|
|
579
|
+
setUpdateError(null);
|
|
580
|
+
setUpdateSuccess(false);
|
|
581
|
+
const response = await fetch(`/admin/swaps/${id}/reject`, {
|
|
582
|
+
method: "POST",
|
|
583
|
+
headers: {
|
|
584
|
+
"Content-Type": "application/json"
|
|
585
|
+
},
|
|
586
|
+
credentials: "include",
|
|
587
|
+
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
588
|
+
});
|
|
589
|
+
if (!response.ok) {
|
|
590
|
+
const message = await response.text();
|
|
591
|
+
throw new Error(message || "Unable to reject swap");
|
|
592
|
+
}
|
|
593
|
+
const payload = await response.json();
|
|
594
|
+
setSwap(payload.swap);
|
|
595
|
+
setUpdateSuccess(true);
|
|
596
|
+
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
597
|
+
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
598
|
+
credentials: "include"
|
|
599
|
+
});
|
|
600
|
+
if (detailResponse.ok) {
|
|
601
|
+
const detailPayload = await response.json();
|
|
602
|
+
setSwap(detailPayload.swap);
|
|
603
|
+
setOrder(detailPayload.order || null);
|
|
604
|
+
}
|
|
605
|
+
} catch (updateErr) {
|
|
606
|
+
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject swap";
|
|
607
|
+
setUpdateError(message);
|
|
608
|
+
} finally {
|
|
609
|
+
setIsRejecting(false);
|
|
610
|
+
}
|
|
611
|
+
};
|
|
1232
612
|
if (isLoading) {
|
|
1233
|
-
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
|
|
613
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading swap..." }) }) }) });
|
|
1234
614
|
}
|
|
1235
|
-
if (error || !
|
|
615
|
+
if (error || !swap) {
|
|
1236
616
|
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: [
|
|
1237
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
1238
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
617
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Swap not found" }),
|
|
618
|
+
/* @__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" }) })
|
|
1239
619
|
] }) }) });
|
|
1240
620
|
}
|
|
1241
|
-
const statusHistory = ((_a =
|
|
621
|
+
const statusHistory = ((_a = swap.metadata) == null ? void 0 : _a.status_history) || [];
|
|
1242
622
|
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: [
|
|
1243
623
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
1244
624
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1246,7 +626,7 @@ const ReturnDetailPage = () => {
|
|
|
1246
626
|
{
|
|
1247
627
|
variant: "transparent",
|
|
1248
628
|
size: "small",
|
|
1249
|
-
onClick: () => navigate("/
|
|
629
|
+
onClick: () => navigate("/swaps"),
|
|
1250
630
|
className: "w-fit",
|
|
1251
631
|
children: [
|
|
1252
632
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -1256,20 +636,45 @@ const ReturnDetailPage = () => {
|
|
|
1256
636
|
),
|
|
1257
637
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
1258
638
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1259
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1260
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
639
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Swap Details" }),
|
|
640
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: swap.id })
|
|
1261
641
|
] }),
|
|
1262
642
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1263
643
|
ui.Badge,
|
|
1264
644
|
{
|
|
1265
645
|
size: "small",
|
|
1266
|
-
className: `uppercase ${getStatusBadgeClass$1(
|
|
1267
|
-
children:
|
|
646
|
+
className: `uppercase ${getStatusBadgeClass$1(swap.status)}`,
|
|
647
|
+
children: swap.status.replace(/_/g, " ")
|
|
1268
648
|
}
|
|
1269
649
|
)
|
|
1270
650
|
] })
|
|
1271
651
|
] }),
|
|
1272
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
652
|
+
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
653
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
654
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
655
|
+
ui.Button,
|
|
656
|
+
{
|
|
657
|
+
variant: "primary",
|
|
658
|
+
onClick: handleAutoCreateExchange,
|
|
659
|
+
disabled: isApproving || isRejecting,
|
|
660
|
+
isLoading: isApproving,
|
|
661
|
+
children: "Approve & Create Exchange"
|
|
662
|
+
}
|
|
663
|
+
),
|
|
664
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
665
|
+
ui.Button,
|
|
666
|
+
{
|
|
667
|
+
variant: "danger",
|
|
668
|
+
onClick: handleReject,
|
|
669
|
+
disabled: isApproving || isRejecting,
|
|
670
|
+
isLoading: isRejecting,
|
|
671
|
+
children: "Reject Swap"
|
|
672
|
+
}
|
|
673
|
+
)
|
|
674
|
+
] }),
|
|
675
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Approving will automatically create an exchange with return items and new items from the swap request" })
|
|
676
|
+
] }),
|
|
677
|
+
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1273
678
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Update Status" }),
|
|
1274
679
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end", children: [
|
|
1275
680
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
@@ -1282,7 +687,7 @@ const ReturnDetailPage = () => {
|
|
|
1282
687
|
className: "h-9 w-full rounded-md border border-ui-border-base bg-transparent px-3 text-sm text-ui-fg-base outline-none transition focus:ring-2 focus:ring-ui-fg-interactive",
|
|
1283
688
|
children: [
|
|
1284
689
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
1285
|
-
availableStatuses.filter((status) => status !==
|
|
690
|
+
availableStatuses.filter((status) => status !== swap.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace(/_/g, " ").toUpperCase() }, status))
|
|
1286
691
|
]
|
|
1287
692
|
}
|
|
1288
693
|
)
|
|
@@ -1301,37 +706,60 @@ const ReturnDetailPage = () => {
|
|
|
1301
706
|
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
1302
707
|
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
1303
708
|
] }),
|
|
709
|
+
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
710
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
711
|
+
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
712
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
713
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
714
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
715
|
+
] }),
|
|
716
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
717
|
+
ui.Button,
|
|
718
|
+
{
|
|
719
|
+
variant: "secondary",
|
|
720
|
+
onClick: () => {
|
|
721
|
+
window.open(`/app/orders/${swap.order_id}/exchanges/${swap.exchange_id}`, "_blank");
|
|
722
|
+
},
|
|
723
|
+
children: "View Exchange"
|
|
724
|
+
}
|
|
725
|
+
) })
|
|
726
|
+
] }) : /* @__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." }) })
|
|
727
|
+
] }),
|
|
1304
728
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1305
729
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1306
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
730
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Swap Information" }),
|
|
1307
731
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1308
732
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1309
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1310
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
733
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Swap ID" }),
|
|
734
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.id })
|
|
1311
735
|
] }),
|
|
1312
736
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1313
737
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
1314
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
738
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.status })
|
|
1315
739
|
] }),
|
|
1316
740
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1317
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1318
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Difference Due" }),
|
|
742
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.difference_due != null ? `${swap.currency_code || "$"}${(Number(swap.difference_due) / 100).toFixed(2)}` : "—" })
|
|
1319
743
|
] }),
|
|
1320
|
-
|
|
744
|
+
swap.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1321
745
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
1322
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
746
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.reason })
|
|
1323
747
|
] }),
|
|
1324
|
-
|
|
748
|
+
swap.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1325
749
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
1326
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
750
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.note })
|
|
1327
751
|
] }),
|
|
1328
752
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1329
753
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
1330
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
754
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.created_at).toLocaleString() })
|
|
1331
755
|
] }),
|
|
1332
756
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1333
757
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
1334
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
758
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(swap.updated_at).toLocaleString() })
|
|
759
|
+
] }),
|
|
760
|
+
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
761
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
762
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1335
763
|
] })
|
|
1336
764
|
] })
|
|
1337
765
|
] }),
|
|
@@ -1342,23 +770,18 @@ const ReturnDetailPage = () => {
|
|
|
1342
770
|
{
|
|
1343
771
|
className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
|
|
1344
772
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1345
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
),
|
|
1354
|
-
entry.from && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1355
|
-
"from ",
|
|
1356
|
-
entry.from.replace("_", " ")
|
|
1357
|
-
] })
|
|
1358
|
-
] }),
|
|
773
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
774
|
+
ui.Badge,
|
|
775
|
+
{
|
|
776
|
+
size: "2xsmall",
|
|
777
|
+
className: `uppercase ${getStatusBadgeClass$1(entry.status)}`,
|
|
778
|
+
children: entry.status.replace(/_/g, " ")
|
|
779
|
+
}
|
|
780
|
+
) }),
|
|
1359
781
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1360
|
-
new Date(entry.
|
|
1361
|
-
entry.
|
|
782
|
+
new Date(entry.timestamp).toLocaleString(),
|
|
783
|
+
entry.admin_id && ` by ${entry.admin_id}`,
|
|
784
|
+
entry.reason && ` - ${entry.reason}`
|
|
1362
785
|
] })
|
|
1363
786
|
] })
|
|
1364
787
|
},
|
|
@@ -1366,76 +789,62 @@ const ReturnDetailPage = () => {
|
|
|
1366
789
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
1367
790
|
] })
|
|
1368
791
|
] }),
|
|
1369
|
-
|
|
792
|
+
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1370
793
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
1371
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1372
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
1373
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1374
|
-
|
|
1375
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
1376
|
-
] }),
|
|
1377
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1378
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
1379
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
1380
|
-
] }),
|
|
1381
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1382
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
1383
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.customer) == null ? void 0 : _c.email) || returnOrder.order.email || "—" })
|
|
1384
|
-
] }),
|
|
1385
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1386
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
1387
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.total).toFixed(2)}` : "—" })
|
|
1388
|
-
] })
|
|
794
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
795
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
796
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
797
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.id })
|
|
1389
798
|
] }),
|
|
1390
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
1391
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1404
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Created" }),
|
|
1405
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.created_at ? new Date(returnOrder.order.created_at).toLocaleString() : "—" })
|
|
799
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
800
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
801
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: order.status || "—" })
|
|
802
|
+
] }),
|
|
803
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
804
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
805
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_b = order.customer) == null ? void 0 : _b.email) || order.email || "—" })
|
|
806
|
+
] }),
|
|
807
|
+
order.total && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
808
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
809
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "font-medium", children: [
|
|
810
|
+
order.currency_code || "$",
|
|
811
|
+
(Number(order.total) / 100).toFixed(2)
|
|
1406
812
|
] })
|
|
1407
813
|
] })
|
|
1408
814
|
] })
|
|
1409
815
|
] }),
|
|
1410
|
-
|
|
816
|
+
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: [
|
|
1411
817
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
1412
818
|
/* @__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: [
|
|
1413
819
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1414
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item" }),
|
|
1415
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
820
|
+
/* @__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" }),
|
|
821
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
822
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
1416
823
|
] }) }),
|
|
1417
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
] }, item.id);
|
|
1423
|
-
}) })
|
|
824
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
825
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
826
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
827
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
828
|
+
] }, item.id || index)) })
|
|
1424
829
|
] }) })
|
|
1425
830
|
] }),
|
|
1426
|
-
|
|
1427
|
-
(
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
831
|
+
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: [
|
|
832
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
833
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "min-w-full divide-y divide-ui-border-base", children: [
|
|
834
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
835
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Variant ID" }),
|
|
836
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
837
|
+
] }) }),
|
|
838
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.new_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
839
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.variant_id }),
|
|
840
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
841
|
+
] }, item.variant_id || index)) })
|
|
842
|
+
] }) })
|
|
1434
843
|
] })
|
|
1435
844
|
] }) });
|
|
1436
845
|
};
|
|
1437
846
|
const config$1 = adminSdk.defineRouteConfig({
|
|
1438
|
-
label: "
|
|
847
|
+
label: "Swap Details",
|
|
1439
848
|
icon: icons.ArrowPath
|
|
1440
849
|
});
|
|
1441
850
|
const getStatusBadgeClass = (status) => {
|
|
@@ -1443,63 +852,65 @@ const getStatusBadgeClass = (status) => {
|
|
|
1443
852
|
if (statusLower === "requested") {
|
|
1444
853
|
return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
1445
854
|
}
|
|
1446
|
-
if (statusLower === "
|
|
855
|
+
if (statusLower === "received") {
|
|
1447
856
|
return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
1448
857
|
}
|
|
1449
|
-
if (statusLower === "
|
|
858
|
+
if (statusLower === "requires_action") {
|
|
1450
859
|
return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
1451
860
|
}
|
|
1452
861
|
if (statusLower === "completed") {
|
|
1453
862
|
return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
1454
863
|
}
|
|
1455
|
-
if (statusLower === "
|
|
864
|
+
if (statusLower === "canceled") {
|
|
1456
865
|
return "bg-ui-tag-grey-bg text-ui-tag-grey-text";
|
|
1457
866
|
}
|
|
1458
867
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
1459
868
|
};
|
|
1460
|
-
const
|
|
1461
|
-
var _a, _b;
|
|
869
|
+
const ReturnDetailPage = () => {
|
|
870
|
+
var _a, _b, _c;
|
|
1462
871
|
const navigate = reactRouterDom.useNavigate();
|
|
1463
872
|
const { id } = reactRouterDom.useParams();
|
|
1464
|
-
const [
|
|
1465
|
-
const [order, setOrder] = react.useState(null);
|
|
873
|
+
const [returnOrder, setReturnOrder] = react.useState(null);
|
|
1466
874
|
const [selectedStatus, setSelectedStatus] = react.useState("");
|
|
1467
875
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
1468
876
|
const [isUpdating, setIsUpdating] = react.useState(false);
|
|
1469
|
-
const [isApproving, setIsApproving] = react.useState(false);
|
|
1470
|
-
const [isRejecting, setIsRejecting] = react.useState(false);
|
|
1471
877
|
const [error, setError] = react.useState(null);
|
|
1472
878
|
const [updateError, setUpdateError] = react.useState(null);
|
|
1473
879
|
const [updateSuccess, setUpdateSuccess] = react.useState(false);
|
|
1474
|
-
const availableStatuses = [
|
|
880
|
+
const availableStatuses = [
|
|
881
|
+
"requested",
|
|
882
|
+
"received",
|
|
883
|
+
"requires_action",
|
|
884
|
+
"completed",
|
|
885
|
+
"canceled"
|
|
886
|
+
];
|
|
1475
887
|
react.useEffect(() => {
|
|
1476
888
|
if (!id) {
|
|
1477
|
-
navigate("/
|
|
889
|
+
navigate("/returns");
|
|
1478
890
|
return;
|
|
1479
891
|
}
|
|
1480
|
-
const
|
|
892
|
+
const loadReturn = async () => {
|
|
1481
893
|
try {
|
|
1482
894
|
setIsLoading(true);
|
|
1483
895
|
setError(null);
|
|
1484
|
-
const response = await fetch(`/admin/
|
|
896
|
+
const response = await fetch(`/admin/returns/${id}`, {
|
|
1485
897
|
credentials: "include"
|
|
1486
898
|
});
|
|
1487
899
|
if (!response.ok) {
|
|
1488
900
|
const message = await response.text();
|
|
1489
|
-
throw new Error(message || "Unable to load
|
|
901
|
+
throw new Error(message || "Unable to load return order");
|
|
1490
902
|
}
|
|
1491
903
|
const payload = await response.json();
|
|
1492
|
-
|
|
1493
|
-
setOrder(payload.order || null);
|
|
904
|
+
setReturnOrder(payload.return);
|
|
1494
905
|
setSelectedStatus("");
|
|
1495
906
|
} catch (loadError) {
|
|
1496
|
-
const message = loadError instanceof Error ? loadError.message : "Unable to load
|
|
907
|
+
const message = loadError instanceof Error ? loadError.message : "Unable to load return order";
|
|
1497
908
|
setError(message);
|
|
1498
909
|
} finally {
|
|
1499
910
|
setIsLoading(false);
|
|
1500
911
|
}
|
|
1501
912
|
};
|
|
1502
|
-
void
|
|
913
|
+
void loadReturn();
|
|
1503
914
|
}, [id, navigate]);
|
|
1504
915
|
const handleStatusUpdate = async () => {
|
|
1505
916
|
if (!id || !selectedStatus) {
|
|
@@ -1509,7 +920,7 @@ const SwapDetailPage = () => {
|
|
|
1509
920
|
setIsUpdating(true);
|
|
1510
921
|
setUpdateError(null);
|
|
1511
922
|
setUpdateSuccess(false);
|
|
1512
|
-
const response = await fetch(`/admin/
|
|
923
|
+
const response = await fetch(`/admin/returns/${id}/status`, {
|
|
1513
924
|
method: "POST",
|
|
1514
925
|
headers: {
|
|
1515
926
|
"Content-Type": "application/json"
|
|
@@ -1522,17 +933,16 @@ const SwapDetailPage = () => {
|
|
|
1522
933
|
throw new Error(message || "Unable to update status");
|
|
1523
934
|
}
|
|
1524
935
|
const payload = await response.json();
|
|
1525
|
-
|
|
936
|
+
setReturnOrder(payload.return);
|
|
1526
937
|
setSelectedStatus("");
|
|
1527
938
|
setUpdateSuccess(true);
|
|
1528
939
|
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1529
|
-
const detailResponse = await fetch(`/admin/
|
|
940
|
+
const detailResponse = await fetch(`/admin/returns/${id}`, {
|
|
1530
941
|
credentials: "include"
|
|
1531
942
|
});
|
|
1532
943
|
if (detailResponse.ok) {
|
|
1533
944
|
const detailPayload = await detailResponse.json();
|
|
1534
|
-
|
|
1535
|
-
setOrder(detailPayload.order || null);
|
|
945
|
+
setReturnOrder(detailPayload.return);
|
|
1536
946
|
}
|
|
1537
947
|
} catch (updateErr) {
|
|
1538
948
|
const message = updateErr instanceof Error ? updateErr.message : "Unable to update status";
|
|
@@ -1541,85 +951,16 @@ const SwapDetailPage = () => {
|
|
|
1541
951
|
setIsUpdating(false);
|
|
1542
952
|
}
|
|
1543
953
|
};
|
|
1544
|
-
const handleApproveClick = async () => {
|
|
1545
|
-
if (!id) {
|
|
1546
|
-
return;
|
|
1547
|
-
}
|
|
1548
|
-
try {
|
|
1549
|
-
setIsApproving(true);
|
|
1550
|
-
setUpdateError(null);
|
|
1551
|
-
setUpdateSuccess(false);
|
|
1552
|
-
const response = await fetch(`/admin/swaps/${id}/prepare-exchange`, {
|
|
1553
|
-
method: "POST",
|
|
1554
|
-
headers: {
|
|
1555
|
-
"Content-Type": "application/json"
|
|
1556
|
-
},
|
|
1557
|
-
credentials: "include"
|
|
1558
|
-
});
|
|
1559
|
-
if (!response.ok) {
|
|
1560
|
-
const message = await response.text();
|
|
1561
|
-
throw new Error(message || "Unable to prepare swap for exchange");
|
|
1562
|
-
}
|
|
1563
|
-
const payload = await response.json();
|
|
1564
|
-
setSwap(payload.swap);
|
|
1565
|
-
const redirectUrl = payload.redirect_url.startsWith("http") ? payload.redirect_url : `${window.location.origin}${payload.redirect_url}`;
|
|
1566
|
-
window.location.href = redirectUrl;
|
|
1567
|
-
} catch (approveErr) {
|
|
1568
|
-
const message = approveErr instanceof Error ? approveErr.message : "Unable to prepare swap for exchange";
|
|
1569
|
-
setUpdateError(message);
|
|
1570
|
-
} finally {
|
|
1571
|
-
setIsApproving(false);
|
|
1572
|
-
}
|
|
1573
|
-
};
|
|
1574
|
-
const handleReject = async () => {
|
|
1575
|
-
if (!id) {
|
|
1576
|
-
return;
|
|
1577
|
-
}
|
|
1578
|
-
try {
|
|
1579
|
-
setIsRejecting(true);
|
|
1580
|
-
setUpdateError(null);
|
|
1581
|
-
setUpdateSuccess(false);
|
|
1582
|
-
const response = await fetch(`/admin/swaps/${id}/reject`, {
|
|
1583
|
-
method: "POST",
|
|
1584
|
-
headers: {
|
|
1585
|
-
"Content-Type": "application/json"
|
|
1586
|
-
},
|
|
1587
|
-
credentials: "include",
|
|
1588
|
-
body: JSON.stringify({ reason: "Rejected by admin" })
|
|
1589
|
-
});
|
|
1590
|
-
if (!response.ok) {
|
|
1591
|
-
const message = await response.text();
|
|
1592
|
-
throw new Error(message || "Unable to reject swap");
|
|
1593
|
-
}
|
|
1594
|
-
const payload = await response.json();
|
|
1595
|
-
setSwap(payload.swap);
|
|
1596
|
-
setUpdateSuccess(true);
|
|
1597
|
-
setTimeout(() => setUpdateSuccess(false), 3e3);
|
|
1598
|
-
const detailResponse = await fetch(`/admin/swaps/${id}`, {
|
|
1599
|
-
credentials: "include"
|
|
1600
|
-
});
|
|
1601
|
-
if (detailResponse.ok) {
|
|
1602
|
-
const detailPayload = await response.json();
|
|
1603
|
-
setSwap(detailPayload.swap);
|
|
1604
|
-
setOrder(detailPayload.order || null);
|
|
1605
|
-
}
|
|
1606
|
-
} catch (updateErr) {
|
|
1607
|
-
const message = updateErr instanceof Error ? updateErr.message : "Unable to reject swap";
|
|
1608
|
-
setUpdateError(message);
|
|
1609
|
-
} finally {
|
|
1610
|
-
setIsRejecting(false);
|
|
1611
|
-
}
|
|
1612
|
-
};
|
|
1613
954
|
if (isLoading) {
|
|
1614
|
-
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
|
|
955
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "mx-auto flex w-full max-w-5xl flex-col gap-6 p-6", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Loading return order..." }) }) }) });
|
|
1615
956
|
}
|
|
1616
|
-
if (error || !
|
|
957
|
+
if (error || !returnOrder) {
|
|
1617
958
|
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: [
|
|
1618
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "
|
|
1619
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: () => navigate("/
|
|
959
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "plus", className: "text-ui-fg-error", children: error || "Return order not found" }),
|
|
960
|
+
/* @__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" }) })
|
|
1620
961
|
] }) }) });
|
|
1621
962
|
}
|
|
1622
|
-
const statusHistory = ((_a =
|
|
963
|
+
const statusHistory = ((_a = returnOrder.metadata) == null ? void 0 : _a.status_history) || [];
|
|
1623
964
|
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: [
|
|
1624
965
|
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-col gap-3", children: [
|
|
1625
966
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1627,7 +968,7 @@ const SwapDetailPage = () => {
|
|
|
1627
968
|
{
|
|
1628
969
|
variant: "transparent",
|
|
1629
970
|
size: "small",
|
|
1630
|
-
onClick: () => navigate("/
|
|
971
|
+
onClick: () => navigate("/returns"),
|
|
1631
972
|
className: "w-fit",
|
|
1632
973
|
children: [
|
|
1633
974
|
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, { className: "mr-2" }),
|
|
@@ -1637,42 +978,20 @@ const SwapDetailPage = () => {
|
|
|
1637
978
|
),
|
|
1638
979
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 md:flex-row md:items-center md:justify-between", children: [
|
|
1639
980
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1640
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "
|
|
1641
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children:
|
|
981
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Return Order Details" }),
|
|
982
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: returnOrder.id })
|
|
1642
983
|
] }),
|
|
1643
984
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1644
985
|
ui.Badge,
|
|
1645
986
|
{
|
|
1646
987
|
size: "small",
|
|
1647
|
-
className: `uppercase ${getStatusBadgeClass(
|
|
1648
|
-
children:
|
|
988
|
+
className: `uppercase ${getStatusBadgeClass(returnOrder.status)}`,
|
|
989
|
+
children: returnOrder.status.replace("_", " ")
|
|
1649
990
|
}
|
|
1650
991
|
)
|
|
1651
992
|
] })
|
|
1652
993
|
] }),
|
|
1653
|
-
|
|
1654
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1655
|
-
ui.Button,
|
|
1656
|
-
{
|
|
1657
|
-
variant: "primary",
|
|
1658
|
-
onClick: handleApproveClick,
|
|
1659
|
-
disabled: isApproving || isRejecting,
|
|
1660
|
-
isLoading: isApproving,
|
|
1661
|
-
children: "Approve Swap"
|
|
1662
|
-
}
|
|
1663
|
-
),
|
|
1664
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1665
|
-
ui.Button,
|
|
1666
|
-
{
|
|
1667
|
-
variant: "secondary",
|
|
1668
|
-
onClick: handleReject,
|
|
1669
|
-
disabled: isApproving || isRejecting,
|
|
1670
|
-
isLoading: isRejecting,
|
|
1671
|
-
children: "Reject Swap"
|
|
1672
|
-
}
|
|
1673
|
-
)
|
|
1674
|
-
] }),
|
|
1675
|
-
swap.status === "requested" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
994
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1676
995
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Update Status" }),
|
|
1677
996
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-end", children: [
|
|
1678
997
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
|
|
@@ -1685,7 +1004,7 @@ const SwapDetailPage = () => {
|
|
|
1685
1004
|
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",
|
|
1686
1005
|
children: [
|
|
1687
1006
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select new status" }),
|
|
1688
|
-
availableStatuses.filter((status) => status !==
|
|
1007
|
+
availableStatuses.filter((status) => status !== returnOrder.status).map((status) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: status, children: status.replace("_", " ").toUpperCase() }, status))
|
|
1689
1008
|
]
|
|
1690
1009
|
}
|
|
1691
1010
|
)
|
|
@@ -1704,60 +1023,37 @@ const SwapDetailPage = () => {
|
|
|
1704
1023
|
updateError && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-error", children: updateError }),
|
|
1705
1024
|
updateSuccess && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "mt-2 text-ui-fg-success", children: "Status updated successfully" })
|
|
1706
1025
|
] }),
|
|
1707
|
-
swap.status === "approved" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1708
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Exchange Information" }),
|
|
1709
|
-
swap.exchange_id ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1710
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1711
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1712
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1713
|
-
] }),
|
|
1714
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1715
|
-
ui.Button,
|
|
1716
|
-
{
|
|
1717
|
-
variant: "secondary",
|
|
1718
|
-
onClick: () => {
|
|
1719
|
-
window.open(`/app/orders/${swap.order_id}/exchanges/${swap.exchange_id}`, "_blank");
|
|
1720
|
-
},
|
|
1721
|
-
children: "View Exchange"
|
|
1722
|
-
}
|
|
1723
|
-
) })
|
|
1724
|
-
] }) : /* @__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." }) })
|
|
1725
|
-
] }),
|
|
1726
1026
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1727
1027
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1728
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "
|
|
1028
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Information" }),
|
|
1729
1029
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1730
1030
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1731
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1732
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Return ID" }),
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.id })
|
|
1733
1033
|
] }),
|
|
1734
1034
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1735
1035
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Status" }),
|
|
1736
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1036
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.status })
|
|
1737
1037
|
] }),
|
|
1738
1038
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1739
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
1740
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1039
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund Amount" }),
|
|
1040
|
+
/* @__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)}` : "—" })
|
|
1741
1041
|
] }),
|
|
1742
|
-
|
|
1042
|
+
returnOrder.reason && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1743
1043
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Reason" }),
|
|
1744
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1044
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.reason })
|
|
1745
1045
|
] }),
|
|
1746
|
-
|
|
1046
|
+
returnOrder.note && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1747
1047
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Note" }),
|
|
1748
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children:
|
|
1048
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.note })
|
|
1749
1049
|
] }),
|
|
1750
1050
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1751
1051
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Created" }),
|
|
1752
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
1052
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.created_at).toLocaleString() })
|
|
1753
1053
|
] }),
|
|
1754
1054
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1755
1055
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Last Updated" }),
|
|
1756
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(
|
|
1757
|
-
] }),
|
|
1758
|
-
swap.exchange_id && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1759
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Exchange ID" }),
|
|
1760
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: swap.exchange_id })
|
|
1056
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: new Date(returnOrder.updated_at).toLocaleString() })
|
|
1761
1057
|
] })
|
|
1762
1058
|
] })
|
|
1763
1059
|
] }),
|
|
@@ -1768,18 +1064,23 @@ const SwapDetailPage = () => {
|
|
|
1768
1064
|
{
|
|
1769
1065
|
className: "flex items-center justify-between border-b border-ui-border-subtle pb-2 last:border-0",
|
|
1770
1066
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1771
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1067
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1068
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1069
|
+
ui.Badge,
|
|
1070
|
+
{
|
|
1071
|
+
size: "2xsmall",
|
|
1072
|
+
className: `uppercase ${getStatusBadgeClass(entry.to)}`,
|
|
1073
|
+
children: entry.to.replace("_", " ")
|
|
1074
|
+
}
|
|
1075
|
+
),
|
|
1076
|
+
entry.from && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1077
|
+
"from ",
|
|
1078
|
+
entry.from.replace("_", " ")
|
|
1079
|
+
] })
|
|
1080
|
+
] }),
|
|
1779
1081
|
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
|
|
1780
|
-
new Date(entry.
|
|
1781
|
-
entry.
|
|
1782
|
-
entry.reason && ` - ${entry.reason}`
|
|
1082
|
+
new Date(entry.changed_at).toLocaleString(),
|
|
1083
|
+
entry.changed_by && ` by ${entry.changed_by}`
|
|
1783
1084
|
] })
|
|
1784
1085
|
] })
|
|
1785
1086
|
},
|
|
@@ -1787,114 +1088,123 @@ const SwapDetailPage = () => {
|
|
|
1787
1088
|
)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "No status history available" })
|
|
1788
1089
|
] })
|
|
1789
1090
|
] }),
|
|
1790
|
-
order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1091
|
+
returnOrder.order && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1791
1092
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Related Order Information" }),
|
|
1792
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1793
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1794
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1803
|
-
|
|
1093
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [
|
|
1094
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1095
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1096
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order ID" }),
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.id })
|
|
1098
|
+
] }),
|
|
1099
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1100
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Status" }),
|
|
1101
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.status || "—" })
|
|
1102
|
+
] }),
|
|
1103
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1104
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Customer" }),
|
|
1105
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: ((_c = returnOrder.order.customer) == null ? void 0 : _c.email) || returnOrder.order.email || "—" })
|
|
1106
|
+
] }),
|
|
1107
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1108
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Total" }),
|
|
1109
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.total).toFixed(2)}` : "—" })
|
|
1110
|
+
] })
|
|
1804
1111
|
] }),
|
|
1805
|
-
|
|
1806
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1807
|
-
|
|
1808
|
-
order.currency_code || "$"
|
|
1809
|
-
|
|
1112
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
1113
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1114
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Subtotal" }),
|
|
1115
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.subtotal ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.subtotal).toFixed(2)}` : "—" })
|
|
1116
|
+
] }),
|
|
1117
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1118
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Tax Total" }),
|
|
1119
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.tax_total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.tax_total).toFixed(2)}` : "—" })
|
|
1120
|
+
] }),
|
|
1121
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1122
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Shipping Total" }),
|
|
1123
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.shipping_total ? `${returnOrder.order.currency_code || "$"}${Number(returnOrder.order.shipping_total).toFixed(2)}` : "—" })
|
|
1124
|
+
] }),
|
|
1125
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1126
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Order Created" }),
|
|
1127
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium", children: returnOrder.order.created_at ? new Date(returnOrder.order.created_at).toLocaleString() : "—" })
|
|
1810
1128
|
] })
|
|
1811
1129
|
] })
|
|
1812
1130
|
] })
|
|
1813
1131
|
] }),
|
|
1814
|
-
|
|
1132
|
+
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: [
|
|
1815
1133
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Return Items" }),
|
|
1816
1134
|
/* @__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: [
|
|
1817
1135
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1818
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item
|
|
1819
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" }),
|
|
1820
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Reason" })
|
|
1821
|
-
] }) }),
|
|
1822
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: swap.return_items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1823
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: item.id }),
|
|
1824
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity }),
|
|
1825
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.reason || "—" })
|
|
1826
|
-
] }, item.id || index)) })
|
|
1827
|
-
] }) })
|
|
1828
|
-
] }),
|
|
1829
|
-
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: [
|
|
1830
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "New Items" }),
|
|
1831
|
-
/* @__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: [
|
|
1832
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1833
|
-
/* @__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" }),
|
|
1136
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Item" }),
|
|
1834
1137
|
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Quantity" })
|
|
1835
1138
|
] }) }),
|
|
1836
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children:
|
|
1837
|
-
|
|
1838
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1839
|
-
|
|
1139
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: returnOrder.items.map((item) => {
|
|
1140
|
+
var _a2, _b2;
|
|
1141
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1142
|
+
/* @__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 }),
|
|
1143
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: item.quantity })
|
|
1144
|
+
] }, item.id);
|
|
1145
|
+
}) })
|
|
1840
1146
|
] }) })
|
|
1147
|
+
] }),
|
|
1148
|
+
returnOrder.metadata && Object.keys(returnOrder.metadata).filter(
|
|
1149
|
+
(key) => key !== "status_history"
|
|
1150
|
+
).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-ui-border-base bg-ui-bg-base p-6", children: [
|
|
1151
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", className: "mb-4 text-lg", children: "Metadata" }),
|
|
1152
|
+
/* @__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: [
|
|
1153
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: key }),
|
|
1154
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "font-medium", children: typeof value === "string" ? value : JSON.stringify(value) })
|
|
1155
|
+
] }, key)) })
|
|
1841
1156
|
] })
|
|
1842
1157
|
] }) });
|
|
1843
1158
|
};
|
|
1844
1159
|
const config = adminSdk.defineRouteConfig({
|
|
1845
|
-
label: "
|
|
1160
|
+
label: "Return Order Details",
|
|
1846
1161
|
icon: icons.ArrowPath
|
|
1847
1162
|
});
|
|
1848
1163
|
const i18nTranslations0 = {};
|
|
1849
|
-
const widgetModule = { widgets: [
|
|
1850
|
-
{
|
|
1851
|
-
Component: ExchangeAutofillWidget,
|
|
1852
|
-
zone: ["order.details.before"]
|
|
1853
|
-
}
|
|
1854
|
-
] };
|
|
1164
|
+
const widgetModule = { widgets: [] };
|
|
1855
1165
|
const routeModule = {
|
|
1856
1166
|
routes: [
|
|
1857
|
-
{
|
|
1858
|
-
Component: ReturnsPage,
|
|
1859
|
-
path: "/returns"
|
|
1860
|
-
},
|
|
1861
1167
|
{
|
|
1862
1168
|
Component: SwapsPage,
|
|
1863
1169
|
path: "/swaps"
|
|
1864
1170
|
},
|
|
1865
1171
|
{
|
|
1866
|
-
Component:
|
|
1867
|
-
path: "/returns
|
|
1172
|
+
Component: ReturnsPage,
|
|
1173
|
+
path: "/returns"
|
|
1868
1174
|
},
|
|
1869
1175
|
{
|
|
1870
1176
|
Component: SwapDetailPage,
|
|
1871
1177
|
path: "/swaps/:id"
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
Component: ReturnDetailPage,
|
|
1181
|
+
path: "/returns/:id"
|
|
1872
1182
|
}
|
|
1873
1183
|
]
|
|
1874
1184
|
};
|
|
1875
1185
|
const menuItemModule = {
|
|
1876
1186
|
menuItems: [
|
|
1877
1187
|
{
|
|
1878
|
-
label: config$
|
|
1879
|
-
icon: config$
|
|
1188
|
+
label: config$2.label,
|
|
1189
|
+
icon: config$2.icon,
|
|
1880
1190
|
path: "/returns",
|
|
1881
1191
|
nested: void 0
|
|
1882
1192
|
},
|
|
1883
1193
|
{
|
|
1884
|
-
label: config$
|
|
1885
|
-
icon: config$
|
|
1194
|
+
label: config$3.label,
|
|
1195
|
+
icon: config$3.icon,
|
|
1886
1196
|
path: "/swaps",
|
|
1887
1197
|
nested: void 0
|
|
1888
1198
|
},
|
|
1889
1199
|
{
|
|
1890
|
-
label: config
|
|
1891
|
-
icon: config
|
|
1200
|
+
label: config.label,
|
|
1201
|
+
icon: config.icon,
|
|
1892
1202
|
path: "/returns/:id",
|
|
1893
1203
|
nested: void 0
|
|
1894
1204
|
},
|
|
1895
1205
|
{
|
|
1896
|
-
label: config.label,
|
|
1897
|
-
icon: config.icon,
|
|
1206
|
+
label: config$1.label,
|
|
1207
|
+
icon: config$1.icon,
|
|
1898
1208
|
path: "/swaps/:id",
|
|
1899
1209
|
nested: void 0
|
|
1900
1210
|
}
|