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