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