order-management 0.0.102 → 0.0.103
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.
|
@@ -2,7 +2,7 @@ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
|
|
3
3
|
import { useState, useEffect, useRef, useMemo, useCallback } from "react";
|
|
4
4
|
import { Text, Container, Heading, Badge, Button, Label, Select, Textarea, Popover, clx, Input, Copy, Skeleton, Tooltip, toast } from "@medusajs/ui";
|
|
5
|
-
import { CashSolid, PencilSquareSolid, Trash, ChevronDownMini, Check, ArrowPath, InformationCircle, ExclamationCircle, MagnifierAlert, ChevronRightMini,
|
|
5
|
+
import { CashSolid, PencilSquareSolid, Trash, ChevronDownMini, Check, ArrowPath, InformationCircle, ExclamationCircle, MagnifierAlert, ChevronRightMini, Receipt, CreditCard, ArrowLeft, ClockSolid, ShieldCheck, SquareTwoStack, CheckCircle } from "@medusajs/icons";
|
|
6
6
|
import { useNavigate, useLocation, useSearchParams, useParams } from "react-router-dom";
|
|
7
7
|
function roundRectPath(ctx, x, y, w, h, r) {
|
|
8
8
|
ctx.beginPath();
|
|
@@ -2228,19 +2228,27 @@ const getStatusBadgeClass$7 = (status) => {
|
|
|
2228
2228
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2229
2229
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2230
2230
|
};
|
|
2231
|
-
const
|
|
2231
|
+
const RefundsPage = () => {
|
|
2232
2232
|
const navigate = useNavigate();
|
|
2233
2233
|
const [items, setItems] = useState([]);
|
|
2234
|
-
const [statusFilter, setStatusFilter] = useState("all");
|
|
2235
2234
|
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
2236
2235
|
const debouncedOrderId = useDebounce$3(orderIdSearch, 300);
|
|
2236
|
+
const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
|
|
2237
|
+
const [providerSearch, setProviderSearch] = useState("");
|
|
2238
|
+
const debouncedProvider = useDebounce$3(providerSearch, 300);
|
|
2239
|
+
const [currencySearch, setCurrencySearch] = useState("");
|
|
2240
|
+
const debouncedCurrency = useDebounce$3(currencySearch, 300);
|
|
2241
|
+
const [dateFrom, setDateFrom] = useState("");
|
|
2242
|
+
const [dateTo, setDateTo] = useState("");
|
|
2243
|
+
const [amountMin, setAmountMin] = useState("");
|
|
2244
|
+
const [amountMax, setAmountMax] = useState("");
|
|
2237
2245
|
const [isLoading, setIsLoading] = useState(true);
|
|
2238
2246
|
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
2239
2247
|
const [error, setError] = useState(null);
|
|
2240
2248
|
const [offset, setOffset] = useState(0);
|
|
2241
2249
|
const [count, setCount] = useState(0);
|
|
2242
2250
|
const limit = 50;
|
|
2243
|
-
const
|
|
2251
|
+
const loadRefunds = useCallback(
|
|
2244
2252
|
async (nextOffset, replace) => {
|
|
2245
2253
|
try {
|
|
2246
2254
|
if (replace) setIsLoading(true);
|
|
@@ -2249,18 +2257,25 @@ const PaymentsPage = () => {
|
|
|
2249
2257
|
const params = new URLSearchParams();
|
|
2250
2258
|
params.set("limit", String(limit));
|
|
2251
2259
|
params.set("offset", String(nextOffset));
|
|
2252
|
-
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
2253
2260
|
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
);
|
|
2261
|
+
if (paymentStatusFilter !== "all") params.set("payment_status", paymentStatusFilter);
|
|
2262
|
+
if (debouncedProvider.trim()) params.set("provider_id", debouncedProvider.trim());
|
|
2263
|
+
if (debouncedCurrency.trim()) params.set("currency_code", debouncedCurrency.trim());
|
|
2264
|
+
if (dateFrom.trim()) params.set("date_from", dateFrom.trim());
|
|
2265
|
+
if (dateTo.trim()) params.set("date_to", dateTo.trim());
|
|
2266
|
+
const min = amountMin.trim() ? Number(amountMin) : void 0;
|
|
2267
|
+
const max = amountMax.trim() ? Number(amountMax) : void 0;
|
|
2268
|
+
if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
|
|
2269
|
+
if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
|
|
2270
|
+
const response = await fetch(`/admin/refunds?${params.toString()}`, {
|
|
2271
|
+
credentials: "include"
|
|
2272
|
+
});
|
|
2258
2273
|
if (!response.ok) {
|
|
2259
2274
|
const text = await response.text();
|
|
2260
|
-
throw new Error(text || "Failed to load
|
|
2275
|
+
throw new Error(text || "Failed to load refunds");
|
|
2261
2276
|
}
|
|
2262
2277
|
const payload = await response.json();
|
|
2263
|
-
const list = payload.
|
|
2278
|
+
const list = payload.refunds ?? [];
|
|
2264
2279
|
setCount(payload.count ?? 0);
|
|
2265
2280
|
setOffset(nextOffset + list.length);
|
|
2266
2281
|
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
@@ -2271,46 +2286,75 @@ const PaymentsPage = () => {
|
|
|
2271
2286
|
setIsFetchingMore(false);
|
|
2272
2287
|
}
|
|
2273
2288
|
},
|
|
2274
|
-
[
|
|
2289
|
+
[
|
|
2290
|
+
debouncedOrderId,
|
|
2291
|
+
paymentStatusFilter,
|
|
2292
|
+
debouncedProvider,
|
|
2293
|
+
debouncedCurrency,
|
|
2294
|
+
dateFrom,
|
|
2295
|
+
dateTo,
|
|
2296
|
+
amountMin,
|
|
2297
|
+
amountMax
|
|
2298
|
+
]
|
|
2275
2299
|
);
|
|
2276
2300
|
useEffect(() => {
|
|
2277
|
-
void
|
|
2278
|
-
}, [
|
|
2301
|
+
void loadRefunds(0, true);
|
|
2302
|
+
}, [loadRefunds]);
|
|
2279
2303
|
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
2280
|
-
const
|
|
2281
|
-
const
|
|
2282
|
-
return
|
|
2304
|
+
const displayAmount = (r) => {
|
|
2305
|
+
const code = (r.currency_code ?? "USD").toUpperCase();
|
|
2306
|
+
return `${code} ${Number(r.amount)}`;
|
|
2283
2307
|
};
|
|
2284
|
-
const
|
|
2285
|
-
const
|
|
2286
|
-
return
|
|
2308
|
+
const displayStatus = (r) => {
|
|
2309
|
+
const s2 = r.payment_status ?? "";
|
|
2310
|
+
return s2 !== "" ? s2 : "—";
|
|
2287
2311
|
};
|
|
2288
2312
|
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: [
|
|
2289
2313
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2290
2314
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2291
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
2292
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2315
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Refunds" }),
|
|
2316
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Refund records — amount, order, payment status" })
|
|
2293
2317
|
] }),
|
|
2294
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () =>
|
|
2318
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadRefunds(0, true), children: "Refresh" })
|
|
2295
2319
|
] }),
|
|
2296
|
-
/* @__PURE__ */
|
|
2320
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2297
2321
|
/* @__PURE__ */ jsx(
|
|
2298
2322
|
Input,
|
|
2299
2323
|
{
|
|
2300
|
-
placeholder: "
|
|
2324
|
+
placeholder: "Order ID",
|
|
2301
2325
|
value: orderIdSearch,
|
|
2302
2326
|
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
2303
|
-
className: "md:max-w-
|
|
2304
|
-
"aria-label": "
|
|
2327
|
+
className: "md:max-w-[180px]",
|
|
2328
|
+
"aria-label": "Filter by order ID"
|
|
2305
2329
|
}
|
|
2306
2330
|
),
|
|
2307
|
-
/* @__PURE__ */ jsx(
|
|
2331
|
+
/* @__PURE__ */ jsx(
|
|
2332
|
+
Input,
|
|
2333
|
+
{
|
|
2334
|
+
placeholder: "Provider",
|
|
2335
|
+
value: providerSearch,
|
|
2336
|
+
onChange: (e) => setProviderSearch(e.target.value),
|
|
2337
|
+
className: "md:max-w-[140px]",
|
|
2338
|
+
"aria-label": "Filter by provider"
|
|
2339
|
+
}
|
|
2340
|
+
),
|
|
2341
|
+
/* @__PURE__ */ jsx(
|
|
2342
|
+
Input,
|
|
2343
|
+
{
|
|
2344
|
+
placeholder: "Currency",
|
|
2345
|
+
value: currencySearch,
|
|
2346
|
+
onChange: (e) => setCurrencySearch(e.target.value),
|
|
2347
|
+
className: "md:max-w-[100px]",
|
|
2348
|
+
"aria-label": "Filter by currency"
|
|
2349
|
+
}
|
|
2350
|
+
),
|
|
2351
|
+
/* @__PURE__ */ jsxs(
|
|
2308
2352
|
"select",
|
|
2309
2353
|
{
|
|
2310
|
-
value:
|
|
2311
|
-
onChange: (e) =>
|
|
2312
|
-
className: "h-9 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 md:max-w-
|
|
2313
|
-
"aria-label": "Filter by status",
|
|
2354
|
+
value: paymentStatusFilter,
|
|
2355
|
+
onChange: (e) => setPaymentStatusFilter(e.target.value),
|
|
2356
|
+
className: "h-9 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 md:max-w-[160px]",
|
|
2357
|
+
"aria-label": "Filter by payment status",
|
|
2314
2358
|
children: [
|
|
2315
2359
|
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
2316
2360
|
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
@@ -2321,52 +2365,103 @@ const PaymentsPage = () => {
|
|
|
2321
2365
|
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
2322
2366
|
]
|
|
2323
2367
|
}
|
|
2324
|
-
)
|
|
2325
|
-
|
|
2368
|
+
),
|
|
2369
|
+
/* @__PURE__ */ jsx(
|
|
2370
|
+
Input,
|
|
2371
|
+
{
|
|
2372
|
+
type: "date",
|
|
2373
|
+
placeholder: "From",
|
|
2374
|
+
value: dateFrom,
|
|
2375
|
+
onChange: (e) => setDateFrom(e.target.value),
|
|
2376
|
+
className: "md:max-w-[140px]",
|
|
2377
|
+
"aria-label": "Date from"
|
|
2378
|
+
}
|
|
2379
|
+
),
|
|
2380
|
+
/* @__PURE__ */ jsx(
|
|
2381
|
+
Input,
|
|
2382
|
+
{
|
|
2383
|
+
type: "date",
|
|
2384
|
+
placeholder: "To",
|
|
2385
|
+
value: dateTo,
|
|
2386
|
+
onChange: (e) => setDateTo(e.target.value),
|
|
2387
|
+
className: "md:max-w-[140px]",
|
|
2388
|
+
"aria-label": "Date to"
|
|
2389
|
+
}
|
|
2390
|
+
),
|
|
2391
|
+
/* @__PURE__ */ jsx(
|
|
2392
|
+
Input,
|
|
2393
|
+
{
|
|
2394
|
+
placeholder: "Amount min",
|
|
2395
|
+
value: amountMin,
|
|
2396
|
+
onChange: (e) => setAmountMin(e.target.value),
|
|
2397
|
+
type: "number",
|
|
2398
|
+
min: 0,
|
|
2399
|
+
className: "md:max-w-[100px]",
|
|
2400
|
+
"aria-label": "Refund amount minimum"
|
|
2401
|
+
}
|
|
2402
|
+
),
|
|
2403
|
+
/* @__PURE__ */ jsx(
|
|
2404
|
+
Input,
|
|
2405
|
+
{
|
|
2406
|
+
placeholder: "Amount max",
|
|
2407
|
+
value: amountMax,
|
|
2408
|
+
onChange: (e) => setAmountMax(e.target.value),
|
|
2409
|
+
type: "number",
|
|
2410
|
+
min: 0,
|
|
2411
|
+
className: "md:max-w-[100px]",
|
|
2412
|
+
"aria-label": "Refund amount maximum"
|
|
2413
|
+
}
|
|
2414
|
+
)
|
|
2415
|
+
] }) }),
|
|
2326
2416
|
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2327
2417
|
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2328
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () =>
|
|
2418
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadRefunds(0, true), children: "Try again" }) })
|
|
2329
2419
|
] }) : null,
|
|
2330
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
2331
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No
|
|
2332
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
2333
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "overflow-
|
|
2420
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading refunds…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
2421
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No refunds yet" }),
|
|
2422
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Refund records will appear here." })
|
|
2423
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto rounded-xl border border-ui-border-base", children: /* @__PURE__ */ jsxs("table", { className: "w-full table-fixed divide-y divide-ui-border-base", style: { minWidth: 0 }, children: [
|
|
2334
2424
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2335
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2336
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2337
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2338
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2339
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2340
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2341
|
-
/* @__PURE__ */ jsx("th", { className: "px-
|
|
2425
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Refund ID" }),
|
|
2426
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
2427
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment ID" }),
|
|
2428
|
+
/* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
2429
|
+
/* @__PURE__ */ jsx("th", { className: "w-[6%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Currency" }),
|
|
2430
|
+
/* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
2431
|
+
/* @__PURE__ */ jsx("th", { className: "w-[10%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Payment Status" }),
|
|
2432
|
+
/* @__PURE__ */ jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
|
|
2433
|
+
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2434
|
+
/* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
2342
2435
|
] }) }),
|
|
2343
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
2436
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((r) => /* @__PURE__ */ jsxs(
|
|
2344
2437
|
"tr",
|
|
2345
2438
|
{
|
|
2346
|
-
className: "hover:bg-ui-bg-subtle/60
|
|
2347
|
-
onClick: () => navigate(`/
|
|
2439
|
+
className: "cursor-pointer hover:bg-ui-bg-subtle/60",
|
|
2440
|
+
onClick: () => navigate(`/refunds/${r.refund_id}`),
|
|
2348
2441
|
children: [
|
|
2349
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
2350
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
2351
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
2352
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
2442
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-base", title: r.refund_id, children: r.refund_id }),
|
|
2443
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-medium text-ui-fg-base", title: r.order_id ?? void 0, children: r.order_id ?? "—" }),
|
|
2444
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 font-mono text-sm text-ui-fg-subtle", title: r.payment_id, children: r.payment_id }),
|
|
2445
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", children: displayAmount(r) }),
|
|
2446
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
|
|
2447
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
|
|
2448
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsx(
|
|
2353
2449
|
Badge,
|
|
2354
2450
|
{
|
|
2355
2451
|
size: "2xsmall",
|
|
2356
|
-
className: `uppercase ${getStatusBadgeClass$7(displayStatus(
|
|
2357
|
-
children: displayStatus(
|
|
2452
|
+
className: `uppercase ${getStatusBadgeClass$7(displayStatus(r))}`,
|
|
2453
|
+
children: displayStatus(r) !== "—" ? displayStatus(r).replace(/_/g, " ") : "—"
|
|
2358
2454
|
}
|
|
2359
2455
|
) }),
|
|
2360
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
2361
|
-
/* @__PURE__ */ jsx("td", { className: "px-
|
|
2362
|
-
year: "numeric",
|
|
2456
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.note ?? void 0, children: r.note ?? "—" }),
|
|
2457
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle text-xs", children: new Date(r.created_at).toLocaleDateString("en-US", {
|
|
2363
2458
|
month: "short",
|
|
2364
2459
|
day: "numeric",
|
|
2365
2460
|
hour: "numeric",
|
|
2366
2461
|
minute: "2-digit",
|
|
2367
2462
|
hour12: true
|
|
2368
2463
|
}) }),
|
|
2369
|
-
/* @__PURE__ */
|
|
2464
|
+
/* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
2370
2465
|
/* @__PURE__ */ jsx(
|
|
2371
2466
|
Button,
|
|
2372
2467
|
{
|
|
@@ -2374,27 +2469,27 @@ const PaymentsPage = () => {
|
|
|
2374
2469
|
size: "small",
|
|
2375
2470
|
onClick: (e) => {
|
|
2376
2471
|
e.stopPropagation();
|
|
2377
|
-
navigate(`/
|
|
2472
|
+
navigate(`/refunds/${r.refund_id}`);
|
|
2378
2473
|
},
|
|
2379
|
-
children: "
|
|
2474
|
+
children: "Details"
|
|
2380
2475
|
}
|
|
2381
2476
|
),
|
|
2382
|
-
|
|
2477
|
+
r.order_id ? /* @__PURE__ */ jsx(
|
|
2383
2478
|
Button,
|
|
2384
2479
|
{
|
|
2385
2480
|
variant: "transparent",
|
|
2386
2481
|
size: "small",
|
|
2387
2482
|
onClick: (e) => {
|
|
2388
2483
|
e.stopPropagation();
|
|
2389
|
-
navigate(`/orders/${
|
|
2484
|
+
navigate(`/orders/${r.order_id}`);
|
|
2390
2485
|
},
|
|
2391
2486
|
children: "Order"
|
|
2392
2487
|
}
|
|
2393
2488
|
) : null
|
|
2394
|
-
] })
|
|
2489
|
+
] }) })
|
|
2395
2490
|
]
|
|
2396
2491
|
},
|
|
2397
|
-
|
|
2492
|
+
r.refund_id
|
|
2398
2493
|
)) })
|
|
2399
2494
|
] }) }),
|
|
2400
2495
|
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
@@ -2402,15 +2497,15 @@ const PaymentsPage = () => {
|
|
|
2402
2497
|
{
|
|
2403
2498
|
variant: "secondary",
|
|
2404
2499
|
isLoading: isFetchingMore,
|
|
2405
|
-
onClick: () =>
|
|
2500
|
+
onClick: () => loadRefunds(offset, false),
|
|
2406
2501
|
children: "Load more"
|
|
2407
2502
|
}
|
|
2408
2503
|
) }) : null
|
|
2409
2504
|
] }) });
|
|
2410
2505
|
};
|
|
2411
2506
|
const config$8 = defineRouteConfig({
|
|
2412
|
-
label: "
|
|
2413
|
-
icon:
|
|
2507
|
+
label: "Refunds",
|
|
2508
|
+
icon: Receipt
|
|
2414
2509
|
});
|
|
2415
2510
|
const useDebounce$2 = (value, delay) => {
|
|
2416
2511
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
@@ -2428,27 +2523,19 @@ const getStatusBadgeClass$6 = (status) => {
|
|
|
2428
2523
|
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
2429
2524
|
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
2430
2525
|
};
|
|
2431
|
-
const
|
|
2526
|
+
const PaymentsPage = () => {
|
|
2432
2527
|
const navigate = useNavigate();
|
|
2433
2528
|
const [items, setItems] = useState([]);
|
|
2529
|
+
const [statusFilter, setStatusFilter] = useState("all");
|
|
2434
2530
|
const [orderIdSearch, setOrderIdSearch] = useState("");
|
|
2435
2531
|
const debouncedOrderId = useDebounce$2(orderIdSearch, 300);
|
|
2436
|
-
const [paymentStatusFilter, setPaymentStatusFilter] = useState("all");
|
|
2437
|
-
const [providerSearch, setProviderSearch] = useState("");
|
|
2438
|
-
const debouncedProvider = useDebounce$2(providerSearch, 300);
|
|
2439
|
-
const [currencySearch, setCurrencySearch] = useState("");
|
|
2440
|
-
const debouncedCurrency = useDebounce$2(currencySearch, 300);
|
|
2441
|
-
const [dateFrom, setDateFrom] = useState("");
|
|
2442
|
-
const [dateTo, setDateTo] = useState("");
|
|
2443
|
-
const [amountMin, setAmountMin] = useState("");
|
|
2444
|
-
const [amountMax, setAmountMax] = useState("");
|
|
2445
2532
|
const [isLoading, setIsLoading] = useState(true);
|
|
2446
2533
|
const [isFetchingMore, setIsFetchingMore] = useState(false);
|
|
2447
2534
|
const [error, setError] = useState(null);
|
|
2448
2535
|
const [offset, setOffset] = useState(0);
|
|
2449
2536
|
const [count, setCount] = useState(0);
|
|
2450
2537
|
const limit = 50;
|
|
2451
|
-
const
|
|
2538
|
+
const loadTransactions = useCallback(
|
|
2452
2539
|
async (nextOffset, replace) => {
|
|
2453
2540
|
try {
|
|
2454
2541
|
if (replace) setIsLoading(true);
|
|
@@ -2457,25 +2544,18 @@ const RefundsPage = () => {
|
|
|
2457
2544
|
const params = new URLSearchParams();
|
|
2458
2545
|
params.set("limit", String(limit));
|
|
2459
2546
|
params.set("offset", String(nextOffset));
|
|
2547
|
+
if (statusFilter !== "all") params.set("status", statusFilter);
|
|
2460
2548
|
if (debouncedOrderId.trim()) params.set("order_id", debouncedOrderId.trim());
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
if (dateTo.trim()) params.set("date_to", dateTo.trim());
|
|
2466
|
-
const min = amountMin.trim() ? Number(amountMin) : void 0;
|
|
2467
|
-
const max = amountMax.trim() ? Number(amountMax) : void 0;
|
|
2468
|
-
if (min != null && !Number.isNaN(min)) params.set("amount_min", String(min));
|
|
2469
|
-
if (max != null && !Number.isNaN(max)) params.set("amount_max", String(max));
|
|
2470
|
-
const response = await fetch(`/admin/refunds?${params.toString()}`, {
|
|
2471
|
-
credentials: "include"
|
|
2472
|
-
});
|
|
2549
|
+
const response = await fetch(
|
|
2550
|
+
`/admin/payment-transactions?${params.toString()}`,
|
|
2551
|
+
{ credentials: "include" }
|
|
2552
|
+
);
|
|
2473
2553
|
if (!response.ok) {
|
|
2474
2554
|
const text = await response.text();
|
|
2475
|
-
throw new Error(text || "Failed to load
|
|
2555
|
+
throw new Error(text || "Failed to load payment transactions");
|
|
2476
2556
|
}
|
|
2477
2557
|
const payload = await response.json();
|
|
2478
|
-
const list = payload.
|
|
2558
|
+
const list = payload.transactions ?? [];
|
|
2479
2559
|
setCount(payload.count ?? 0);
|
|
2480
2560
|
setOffset(nextOffset + list.length);
|
|
2481
2561
|
setItems((prev) => replace ? list : [...prev, ...list]);
|
|
@@ -2486,182 +2566,102 @@ const RefundsPage = () => {
|
|
|
2486
2566
|
setIsFetchingMore(false);
|
|
2487
2567
|
}
|
|
2488
2568
|
},
|
|
2489
|
-
[
|
|
2490
|
-
debouncedOrderId,
|
|
2491
|
-
paymentStatusFilter,
|
|
2492
|
-
debouncedProvider,
|
|
2493
|
-
debouncedCurrency,
|
|
2494
|
-
dateFrom,
|
|
2495
|
-
dateTo,
|
|
2496
|
-
amountMin,
|
|
2497
|
-
amountMax
|
|
2498
|
-
]
|
|
2569
|
+
[statusFilter, debouncedOrderId]
|
|
2499
2570
|
);
|
|
2500
2571
|
useEffect(() => {
|
|
2501
|
-
void
|
|
2502
|
-
}, [
|
|
2572
|
+
void loadTransactions(0, true);
|
|
2573
|
+
}, [loadTransactions]);
|
|
2503
2574
|
const hasMore = useMemo(() => offset < count, [offset, count]);
|
|
2504
|
-
const
|
|
2505
|
-
const
|
|
2506
|
-
return `${code} ${Number(r.amount)}`;
|
|
2507
|
-
};
|
|
2508
|
-
const displayStatus = (r) => {
|
|
2509
|
-
const s2 = r.payment_status ?? "";
|
|
2575
|
+
const displayStatus = (t) => {
|
|
2576
|
+
const s2 = t.payment_id != null && t.payment_status != null && t.payment_status !== "" ? t.payment_status : t.session_status ?? "";
|
|
2510
2577
|
return s2 !== "" ? s2 : "—";
|
|
2511
2578
|
};
|
|
2579
|
+
const displayAmount = (t) => {
|
|
2580
|
+
const code = (t.currency_code ?? "USD").toUpperCase();
|
|
2581
|
+
return `${code} ${Number(t.amount)}`;
|
|
2582
|
+
};
|
|
2512
2583
|
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: [
|
|
2513
2584
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2514
2585
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
2515
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "
|
|
2516
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "
|
|
2586
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payments" }),
|
|
2587
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "All payment attempts — completed, pending, failed, requires action" })
|
|
2517
2588
|
] }),
|
|
2518
|
-
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () =>
|
|
2589
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", onClick: () => loadTransactions(0, true), children: "Refresh" })
|
|
2519
2590
|
] }),
|
|
2520
|
-
/* @__PURE__ */
|
|
2591
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
2521
2592
|
/* @__PURE__ */ jsx(
|
|
2522
2593
|
Input,
|
|
2523
2594
|
{
|
|
2524
|
-
placeholder: "Order ID",
|
|
2595
|
+
placeholder: "Search by Order ID",
|
|
2525
2596
|
value: orderIdSearch,
|
|
2526
2597
|
onChange: (e) => setOrderIdSearch(e.target.value),
|
|
2527
|
-
className: "md:max-w-
|
|
2528
|
-
"aria-label": "
|
|
2529
|
-
}
|
|
2530
|
-
),
|
|
2531
|
-
/* @__PURE__ */ jsx(
|
|
2532
|
-
Input,
|
|
2533
|
-
{
|
|
2534
|
-
placeholder: "Provider",
|
|
2535
|
-
value: providerSearch,
|
|
2536
|
-
onChange: (e) => setProviderSearch(e.target.value),
|
|
2537
|
-
className: "md:max-w-[140px]",
|
|
2538
|
-
"aria-label": "Filter by provider"
|
|
2539
|
-
}
|
|
2540
|
-
),
|
|
2541
|
-
/* @__PURE__ */ jsx(
|
|
2542
|
-
Input,
|
|
2543
|
-
{
|
|
2544
|
-
placeholder: "Currency",
|
|
2545
|
-
value: currencySearch,
|
|
2546
|
-
onChange: (e) => setCurrencySearch(e.target.value),
|
|
2547
|
-
className: "md:max-w-[100px]",
|
|
2548
|
-
"aria-label": "Filter by currency"
|
|
2598
|
+
className: "md:max-w-sm",
|
|
2599
|
+
"aria-label": "Search by order ID"
|
|
2549
2600
|
}
|
|
2550
2601
|
),
|
|
2551
|
-
/* @__PURE__ */ jsxs(
|
|
2602
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-3", children: /* @__PURE__ */ jsxs(
|
|
2552
2603
|
"select",
|
|
2553
2604
|
{
|
|
2554
|
-
value:
|
|
2555
|
-
onChange: (e) =>
|
|
2556
|
-
className: "h-9 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 md:max-w-
|
|
2557
|
-
"aria-label": "Filter by
|
|
2558
|
-
children: [
|
|
2559
|
-
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
2560
|
-
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
2561
|
-
/* @__PURE__ */ jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
2562
|
-
/* @__PURE__ */ jsx("option", { value: "error", children: "Error" }),
|
|
2563
|
-
/* @__PURE__ */ jsx("option", { value: "canceled", children: "Canceled" }),
|
|
2564
|
-
/* @__PURE__ */ jsx("option", { value: "authorized", children: "Authorized" }),
|
|
2565
|
-
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
2566
|
-
]
|
|
2567
|
-
}
|
|
2568
|
-
),
|
|
2569
|
-
/* @__PURE__ */ jsx(
|
|
2570
|
-
Input,
|
|
2571
|
-
{
|
|
2572
|
-
type: "date",
|
|
2573
|
-
placeholder: "From",
|
|
2574
|
-
value: dateFrom,
|
|
2575
|
-
onChange: (e) => setDateFrom(e.target.value),
|
|
2576
|
-
className: "md:max-w-[140px]",
|
|
2577
|
-
"aria-label": "Date from"
|
|
2578
|
-
}
|
|
2579
|
-
),
|
|
2580
|
-
/* @__PURE__ */ jsx(
|
|
2581
|
-
Input,
|
|
2582
|
-
{
|
|
2583
|
-
type: "date",
|
|
2584
|
-
placeholder: "To",
|
|
2585
|
-
value: dateTo,
|
|
2586
|
-
onChange: (e) => setDateTo(e.target.value),
|
|
2587
|
-
className: "md:max-w-[140px]",
|
|
2588
|
-
"aria-label": "Date to"
|
|
2589
|
-
}
|
|
2590
|
-
),
|
|
2591
|
-
/* @__PURE__ */ jsx(
|
|
2592
|
-
Input,
|
|
2593
|
-
{
|
|
2594
|
-
placeholder: "Amount min",
|
|
2595
|
-
value: amountMin,
|
|
2596
|
-
onChange: (e) => setAmountMin(e.target.value),
|
|
2597
|
-
type: "number",
|
|
2598
|
-
min: 0,
|
|
2599
|
-
className: "md:max-w-[100px]",
|
|
2600
|
-
"aria-label": "Refund amount minimum"
|
|
2601
|
-
}
|
|
2602
|
-
),
|
|
2603
|
-
/* @__PURE__ */ jsx(
|
|
2604
|
-
Input,
|
|
2605
|
-
{
|
|
2606
|
-
placeholder: "Amount max",
|
|
2607
|
-
value: amountMax,
|
|
2608
|
-
onChange: (e) => setAmountMax(e.target.value),
|
|
2609
|
-
type: "number",
|
|
2610
|
-
min: 0,
|
|
2611
|
-
className: "md:max-w-[100px]",
|
|
2612
|
-
"aria-label": "Refund amount maximum"
|
|
2605
|
+
value: statusFilter,
|
|
2606
|
+
onChange: (e) => setStatusFilter(e.target.value),
|
|
2607
|
+
className: "h-9 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 md:max-w-xs",
|
|
2608
|
+
"aria-label": "Filter by status",
|
|
2609
|
+
children: [
|
|
2610
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: "All statuses" }),
|
|
2611
|
+
/* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
2612
|
+
/* @__PURE__ */ jsx("option", { value: "requires_more", children: "Requires more" }),
|
|
2613
|
+
/* @__PURE__ */ jsx("option", { value: "error", children: "Error" }),
|
|
2614
|
+
/* @__PURE__ */ jsx("option", { value: "canceled", children: "Canceled" }),
|
|
2615
|
+
/* @__PURE__ */ jsx("option", { value: "authorized", children: "Authorized" }),
|
|
2616
|
+
/* @__PURE__ */ jsx("option", { value: "captured", children: "Captured" })
|
|
2617
|
+
]
|
|
2613
2618
|
}
|
|
2614
|
-
)
|
|
2615
|
-
] })
|
|
2619
|
+
) })
|
|
2620
|
+
] }),
|
|
2616
2621
|
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
2617
2622
|
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
2618
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () =>
|
|
2623
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 flex justify-center", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => loadTransactions(0, true), children: "Try again" }) })
|
|
2619
2624
|
] }) : null,
|
|
2620
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading
|
|
2621
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No
|
|
2622
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "
|
|
2623
|
-
] }) : /* @__PURE__ */ jsx("div", { className: "
|
|
2625
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading payments…" }) }) : items.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed border-ui-border-strong p-10 text-center", children: [
|
|
2626
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-xl", children: "No payment transactions yet" }),
|
|
2627
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "mt-2 text-ui-fg-subtle", children: "Payment attempts will appear here." })
|
|
2628
|
+
] }) : /* @__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: [
|
|
2624
2629
|
/* @__PURE__ */ jsx("thead", { className: "bg-ui-bg-subtle", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2625
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2626
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2627
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2628
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2629
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2630
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2631
|
-
/* @__PURE__ */ jsx("th", { className: "
|
|
2632
|
-
/* @__PURE__ */ jsx("th", { className: "w-[14%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Note" }),
|
|
2633
|
-
/* @__PURE__ */ jsx("th", { className: "w-[11%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2634
|
-
/* @__PURE__ */ jsx("th", { className: "w-[8%] min-w-0 px-3 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
2630
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Order ID" }),
|
|
2631
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Amount" }),
|
|
2632
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Provider" }),
|
|
2633
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Status" }),
|
|
2634
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Finalized" }),
|
|
2635
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Created" }),
|
|
2636
|
+
/* @__PURE__ */ jsx("th", { className: "px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-ui-fg-muted", children: "Actions" })
|
|
2635
2637
|
] }) }),
|
|
2636
|
-
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((
|
|
2638
|
+
/* @__PURE__ */ jsx("tbody", { className: "divide-y divide-ui-border-subtle", children: items.map((t) => /* @__PURE__ */ jsxs(
|
|
2637
2639
|
"tr",
|
|
2638
2640
|
{
|
|
2639
|
-
className: "
|
|
2640
|
-
onClick: () => navigate(`/
|
|
2641
|
+
className: "hover:bg-ui-bg-subtle/60 cursor-pointer",
|
|
2642
|
+
onClick: () => navigate(`/payments/${t.payment_session_id}`),
|
|
2641
2643
|
children: [
|
|
2642
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
2643
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
2644
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
2645
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
2646
|
-
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle uppercase", children: r.currency_code || "—" }),
|
|
2647
|
-
/* @__PURE__ */ jsx("td", { className: "min-w-0 truncate px-3 py-3 text-ui-fg-subtle", title: r.provider_id || void 0, children: r.provider_id || "—" }),
|
|
2648
|
-
/* @__PURE__ */ jsx("td", { className: "min-w-0 px-3 py-3", children: /* @__PURE__ */ jsx(
|
|
2644
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 font-medium text-ui-fg-base", children: t.order_id ?? "—" }),
|
|
2645
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: displayAmount(t) }),
|
|
2646
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.provider_id }),
|
|
2647
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4", children: /* @__PURE__ */ jsx(
|
|
2649
2648
|
Badge,
|
|
2650
2649
|
{
|
|
2651
2650
|
size: "2xsmall",
|
|
2652
|
-
className: `uppercase ${getStatusBadgeClass$6(displayStatus(
|
|
2653
|
-
children: displayStatus(
|
|
2651
|
+
className: `uppercase ${getStatusBadgeClass$6(displayStatus(t))}`,
|
|
2652
|
+
children: displayStatus(t) !== "—" ? displayStatus(t).replace(/_/g, " ") : "—"
|
|
2654
2653
|
}
|
|
2655
2654
|
) }),
|
|
2656
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
2657
|
-
/* @__PURE__ */ jsx("td", { className: "
|
|
2655
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: t.payment_id != null ? "Yes" : "No" }),
|
|
2656
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-4 text-ui-fg-subtle", children: new Date(t.created_at).toLocaleDateString("en-US", {
|
|
2657
|
+
year: "numeric",
|
|
2658
2658
|
month: "short",
|
|
2659
2659
|
day: "numeric",
|
|
2660
2660
|
hour: "numeric",
|
|
2661
2661
|
minute: "2-digit",
|
|
2662
2662
|
hour12: true
|
|
2663
2663
|
}) }),
|
|
2664
|
-
/* @__PURE__ */
|
|
2664
|
+
/* @__PURE__ */ jsxs("td", { className: "px-4 py-4", children: [
|
|
2665
2665
|
/* @__PURE__ */ jsx(
|
|
2666
2666
|
Button,
|
|
2667
2667
|
{
|
|
@@ -2669,27 +2669,27 @@ const RefundsPage = () => {
|
|
|
2669
2669
|
size: "small",
|
|
2670
2670
|
onClick: (e) => {
|
|
2671
2671
|
e.stopPropagation();
|
|
2672
|
-
navigate(`/
|
|
2672
|
+
navigate(`/payments/${t.payment_session_id}`);
|
|
2673
2673
|
},
|
|
2674
|
-
children: "
|
|
2674
|
+
children: "View details"
|
|
2675
2675
|
}
|
|
2676
2676
|
),
|
|
2677
|
-
|
|
2677
|
+
t.order_id ? /* @__PURE__ */ jsx(
|
|
2678
2678
|
Button,
|
|
2679
2679
|
{
|
|
2680
2680
|
variant: "transparent",
|
|
2681
2681
|
size: "small",
|
|
2682
2682
|
onClick: (e) => {
|
|
2683
2683
|
e.stopPropagation();
|
|
2684
|
-
navigate(`/orders/${
|
|
2684
|
+
navigate(`/orders/${t.order_id}`);
|
|
2685
2685
|
},
|
|
2686
2686
|
children: "Order"
|
|
2687
2687
|
}
|
|
2688
2688
|
) : null
|
|
2689
|
-
] })
|
|
2689
|
+
] })
|
|
2690
2690
|
]
|
|
2691
2691
|
},
|
|
2692
|
-
|
|
2692
|
+
t.payment_session_id
|
|
2693
2693
|
)) })
|
|
2694
2694
|
] }) }),
|
|
2695
2695
|
hasMore ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
@@ -2697,15 +2697,15 @@ const RefundsPage = () => {
|
|
|
2697
2697
|
{
|
|
2698
2698
|
variant: "secondary",
|
|
2699
2699
|
isLoading: isFetchingMore,
|
|
2700
|
-
onClick: () =>
|
|
2700
|
+
onClick: () => loadTransactions(offset, false),
|
|
2701
2701
|
children: "Load more"
|
|
2702
2702
|
}
|
|
2703
2703
|
) }) : null
|
|
2704
2704
|
] }) });
|
|
2705
2705
|
};
|
|
2706
2706
|
const config$7 = defineRouteConfig({
|
|
2707
|
-
label: "
|
|
2708
|
-
icon:
|
|
2707
|
+
label: "Payments",
|
|
2708
|
+
icon: CreditCard
|
|
2709
2709
|
});
|
|
2710
2710
|
const useDebounce$1 = (value, delay) => {
|
|
2711
2711
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
@@ -3837,207 +3837,89 @@ const DetailContent = ({ audit }) => {
|
|
|
3837
3837
|
" ",
|
|
3838
3838
|
guidance.headline
|
|
3839
3839
|
] }),
|
|
3840
|
-
/* @__PURE__ */ jsxs("li", { children: [
|
|
3841
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
|
|
3842
|
-
" ",
|
|
3843
|
-
guidance.recreate
|
|
3844
|
-
] }),
|
|
3845
|
-
/* @__PURE__ */ jsxs("li", { children: [
|
|
3846
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
|
|
3847
|
-
" Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
|
|
3848
|
-
] })
|
|
3849
|
-
] }),
|
|
3850
|
-
guidance.adminSection || related.length ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
3851
|
-
guidance.adminSection ? /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
|
|
3852
|
-
related.map((link) => /* @__PURE__ */ jsxs(
|
|
3853
|
-
Button,
|
|
3854
|
-
{
|
|
3855
|
-
variant: "transparent",
|
|
3856
|
-
size: "small",
|
|
3857
|
-
onClick: () => navigate(link.path),
|
|
3858
|
-
title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
|
|
3859
|
-
children: [
|
|
3860
|
-
"Open related ",
|
|
3861
|
-
link.label.toLowerCase(),
|
|
3862
|
-
/* @__PURE__ */ jsx(ChevronRightMini, {})
|
|
3863
|
-
]
|
|
3864
|
-
},
|
|
3865
|
-
link.path
|
|
3866
|
-
))
|
|
3867
|
-
] }) : null,
|
|
3868
|
-
related.length ? /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Related records open only if they haven’t been deleted too." }) : null
|
|
3869
|
-
] }) })
|
|
3870
|
-
] });
|
|
3871
|
-
};
|
|
3872
|
-
const Section = ({
|
|
3873
|
-
title,
|
|
3874
|
-
description,
|
|
3875
|
-
actions,
|
|
3876
|
-
children
|
|
3877
|
-
}) => /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3878
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
|
|
3879
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3880
|
-
/* @__PURE__ */ jsx(Heading, { level: "h2", children: title }),
|
|
3881
|
-
description ? /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
|
|
3882
|
-
] }),
|
|
3883
|
-
actions
|
|
3884
|
-
] }),
|
|
3885
|
-
children
|
|
3886
|
-
] });
|
|
3887
|
-
const Field = ({ label, children }) => /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
3888
|
-
/* @__PURE__ */ jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
|
|
3889
|
-
/* @__PURE__ */ jsx("dd", { className: "min-w-0", children })
|
|
3890
|
-
] });
|
|
3891
|
-
const DetailSkeleton = () => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
|
|
3892
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3893
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-24 rounded-full" }),
|
|
3894
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-64" }),
|
|
3895
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-48" })
|
|
3896
|
-
] }),
|
|
3897
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-14 w-full" }),
|
|
3898
|
-
Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3899
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-40" }),
|
|
3900
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: Array.from({ length: 4 }).map((__, j) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3901
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-20" }),
|
|
3902
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-36" })
|
|
3903
|
-
] }, j)) })
|
|
3904
|
-
] }, i))
|
|
3905
|
-
] });
|
|
3906
|
-
const DetailError = ({
|
|
3907
|
-
notFound,
|
|
3908
|
-
message,
|
|
3909
|
-
onRetry,
|
|
3910
|
-
onBack
|
|
3911
|
-
}) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-ui-border-base px-6 py-12 text-center", children: [
|
|
3912
|
-
/* @__PURE__ */ jsx(ExclamationCircle, { className: clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
|
|
3913
|
-
/* @__PURE__ */ jsx(Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
|
|
3914
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "max-w-md text-ui-fg-subtle", children: notFound ? "This audit entry doesn’t exist. The link may be incorrect." : "We couldn’t retrieve the audit entry right now. Check your connection and try again." }),
|
|
3915
|
-
!notFound ? /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
|
|
3916
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex gap-2", children: [
|
|
3917
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
|
|
3918
|
-
!notFound ? /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
|
|
3919
|
-
] })
|
|
3920
|
-
] });
|
|
3921
|
-
const config$4 = defineRouteConfig({});
|
|
3922
|
-
const getStatusBadgeClass$3 = (status) => {
|
|
3923
|
-
const s2 = status.toLowerCase();
|
|
3924
|
-
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
3925
|
-
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
3926
|
-
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
3927
|
-
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
3928
|
-
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
3929
|
-
};
|
|
3930
|
-
const PaymentDetailPage = () => {
|
|
3931
|
-
const navigate = useNavigate();
|
|
3932
|
-
const params = useParams();
|
|
3933
|
-
const id = params?.id?.trim();
|
|
3934
|
-
const [detail, setDetail] = useState(null);
|
|
3935
|
-
const [loading, setLoading] = useState(!!id);
|
|
3936
|
-
const [error, setError] = useState(null);
|
|
3937
|
-
useEffect(() => {
|
|
3938
|
-
if (!id) {
|
|
3939
|
-
setLoading(false);
|
|
3940
|
-
return;
|
|
3941
|
-
}
|
|
3942
|
-
let cancelled = false;
|
|
3943
|
-
setLoading(true);
|
|
3944
|
-
setError(null);
|
|
3945
|
-
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
3946
|
-
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
3947
|
-
return res.json();
|
|
3948
|
-
}).then((data) => {
|
|
3949
|
-
if (!cancelled) setDetail(data);
|
|
3950
|
-
}).catch((e) => {
|
|
3951
|
-
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
3952
|
-
}).finally(() => {
|
|
3953
|
-
if (!cancelled) setLoading(false);
|
|
3954
|
-
});
|
|
3955
|
-
return () => {
|
|
3956
|
-
cancelled = true;
|
|
3957
|
-
};
|
|
3958
|
-
}, [id]);
|
|
3959
|
-
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
3960
|
-
const sessionStatusRaw = detail?.session_status ?? "—";
|
|
3961
|
-
const paymentStatusRaw = detail?.payment_id != null ? detail?.payment_status ?? "—" : "—";
|
|
3962
|
-
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
3963
|
-
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
3964
|
-
/* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3965
|
-
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
3966
|
-
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payment session" }),
|
|
3967
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
3968
|
-
] }) }),
|
|
3969
|
-
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
3970
|
-
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
3971
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
3972
|
-
] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
3973
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
3974
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3975
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
3976
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsx(
|
|
3977
|
-
Button,
|
|
3978
|
-
{
|
|
3979
|
-
variant: "transparent",
|
|
3980
|
-
size: "small",
|
|
3981
|
-
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
3982
|
-
children: detail.order_id
|
|
3983
|
-
}
|
|
3984
|
-
) : /* @__PURE__ */ jsx(Text, { children: "—" }) })
|
|
3985
|
-
] }),
|
|
3986
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3987
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
3988
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
|
|
3989
|
-
] }),
|
|
3990
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3991
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
3992
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
|
|
3993
|
-
] }),
|
|
3994
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3995
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
3996
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
3997
|
-
Badge,
|
|
3998
|
-
{
|
|
3999
|
-
size: "2xsmall",
|
|
4000
|
-
className: `uppercase ${getStatusBadgeClass$3(displayStatus)}`,
|
|
4001
|
-
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
4002
|
-
}
|
|
4003
|
-
) })
|
|
4004
|
-
] }),
|
|
4005
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
4006
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
4007
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
4008
|
-
] }),
|
|
4009
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
4010
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
4011
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
4012
|
-
] }),
|
|
4013
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
4014
|
-
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
4015
|
-
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
3840
|
+
/* @__PURE__ */ jsxs("li", { children: [
|
|
3841
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-ui-fg-base", children: "If it needs to come back:" }),
|
|
3842
|
+
" ",
|
|
3843
|
+
guidance.recreate
|
|
4016
3844
|
] }),
|
|
4017
|
-
/* @__PURE__ */ jsxs("
|
|
4018
|
-
/* @__PURE__ */ jsx(
|
|
4019
|
-
|
|
4020
|
-
year: "numeric",
|
|
4021
|
-
month: "short",
|
|
4022
|
-
day: "numeric",
|
|
4023
|
-
hour: "numeric",
|
|
4024
|
-
minute: "2-digit",
|
|
4025
|
-
hour12: true
|
|
4026
|
-
}) })
|
|
3845
|
+
/* @__PURE__ */ jsxs("li", { children: [
|
|
3846
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-ui-fg-base", children: "Need the details?" }),
|
|
3847
|
+
" Use “View full record” above to see or copy everything that was stored. Sensitive values stay hidden."
|
|
4027
3848
|
] })
|
|
4028
|
-
] })
|
|
4029
|
-
|
|
4030
|
-
/* @__PURE__ */ jsx(
|
|
4031
|
-
/* @__PURE__ */
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
3849
|
+
] }),
|
|
3850
|
+
guidance.adminSection || related.length ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
3851
|
+
guidance.adminSection ? /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => navigate(guidance.adminSection.path), children: guidance.adminSection.label }) : null,
|
|
3852
|
+
related.map((link) => /* @__PURE__ */ jsxs(
|
|
3853
|
+
Button,
|
|
3854
|
+
{
|
|
3855
|
+
variant: "transparent",
|
|
3856
|
+
size: "small",
|
|
3857
|
+
onClick: () => navigate(link.path),
|
|
3858
|
+
title: `Opens ${link.label.toLowerCase()} ${link.id} if it still exists`,
|
|
3859
|
+
children: [
|
|
3860
|
+
"Open related ",
|
|
3861
|
+
link.label.toLowerCase(),
|
|
3862
|
+
/* @__PURE__ */ jsx(ChevronRightMini, {})
|
|
3863
|
+
]
|
|
3864
|
+
},
|
|
3865
|
+
link.path
|
|
3866
|
+
))
|
|
3867
|
+
] }) : null,
|
|
3868
|
+
related.length ? /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "text-ui-fg-muted", children: "Related records open only if they haven’t been deleted too." }) : null
|
|
3869
|
+
] }) })
|
|
3870
|
+
] });
|
|
4035
3871
|
};
|
|
4036
|
-
const
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
3872
|
+
const Section = ({
|
|
3873
|
+
title,
|
|
3874
|
+
description,
|
|
3875
|
+
actions,
|
|
3876
|
+
children
|
|
3877
|
+
}) => /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3878
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
|
|
3879
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
3880
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", children: title }),
|
|
3881
|
+
description ? /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: description }) : null
|
|
3882
|
+
] }),
|
|
3883
|
+
actions
|
|
3884
|
+
] }),
|
|
3885
|
+
children
|
|
3886
|
+
] });
|
|
3887
|
+
const Field = ({ label, children }) => /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
3888
|
+
/* @__PURE__ */ jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-ui-fg-muted", children: label }),
|
|
3889
|
+
/* @__PURE__ */ jsx("dd", { className: "min-w-0", children })
|
|
3890
|
+
] });
|
|
3891
|
+
const DetailSkeleton = () => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", "aria-busy": "true", children: [
|
|
3892
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
3893
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-24 rounded-full" }),
|
|
3894
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-64" }),
|
|
3895
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-48" })
|
|
3896
|
+
] }),
|
|
3897
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-14 w-full" }),
|
|
3898
|
+
Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 rounded-lg border border-ui-border-base p-5", children: [
|
|
3899
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-40" }),
|
|
3900
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: Array.from({ length: 4 }).map((__, j) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
3901
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-20" }),
|
|
3902
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-36" })
|
|
3903
|
+
] }, j)) })
|
|
3904
|
+
] }, i))
|
|
3905
|
+
] });
|
|
3906
|
+
const DetailError = ({
|
|
3907
|
+
notFound,
|
|
3908
|
+
message,
|
|
3909
|
+
onRetry,
|
|
3910
|
+
onBack
|
|
3911
|
+
}) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-ui-border-base px-6 py-12 text-center", children: [
|
|
3912
|
+
/* @__PURE__ */ jsx(ExclamationCircle, { className: clx(notFound ? "text-ui-fg-muted" : "text-ui-fg-error") }),
|
|
3913
|
+
/* @__PURE__ */ jsx(Heading, { level: "h3", children: notFound ? "Audit entry not found" : "Unable to load this deleted record" }),
|
|
3914
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "max-w-md text-ui-fg-subtle", children: notFound ? "This audit entry doesn’t exist. The link may be incorrect." : "We couldn’t retrieve the audit entry right now. Check your connection and try again." }),
|
|
3915
|
+
!notFound ? /* @__PURE__ */ jsx(Text, { size: "xsmall", className: "max-w-md font-mono text-ui-fg-muted", children: message }) : null,
|
|
3916
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex gap-2", children: [
|
|
3917
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: onBack, children: "Back to Deleted Records" }),
|
|
3918
|
+
!notFound ? /* @__PURE__ */ jsx(Button, { variant: "primary", size: "small", onClick: onRetry, children: "Try again" }) : null
|
|
3919
|
+
] })
|
|
3920
|
+
] });
|
|
3921
|
+
const config$4 = defineRouteConfig({});
|
|
3922
|
+
const getStatusBadgeClass$3 = (status) => {
|
|
4041
3923
|
const s2 = status.toLowerCase();
|
|
4042
3924
|
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4043
3925
|
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
@@ -4147,7 +4029,7 @@ const RefundDetailPage = () => {
|
|
|
4147
4029
|
Badge,
|
|
4148
4030
|
{
|
|
4149
4031
|
size: "2xsmall",
|
|
4150
|
-
className: `uppercase ${getStatusBadgeClass$
|
|
4032
|
+
className: `uppercase ${getStatusBadgeClass$3(paymentStatus)}`,
|
|
4151
4033
|
children: paymentStatus !== "—" ? paymentStatus.replace(/_/g, " ") : "—"
|
|
4152
4034
|
}
|
|
4153
4035
|
) })
|
|
@@ -4224,10 +4106,128 @@ const RefundDetailPage = () => {
|
|
|
4224
4106
|
] }) : null
|
|
4225
4107
|
] }) });
|
|
4226
4108
|
};
|
|
4227
|
-
const config$
|
|
4109
|
+
const config$3 = defineRouteConfig({
|
|
4228
4110
|
label: "Refund details",
|
|
4229
4111
|
icon: Receipt
|
|
4230
4112
|
});
|
|
4113
|
+
const getStatusBadgeClass$2 = (status) => {
|
|
4114
|
+
const s2 = status.toLowerCase();
|
|
4115
|
+
if (s2 === "captured" || s2 === "completed") return "bg-ui-tag-green-bg text-ui-tag-green-text";
|
|
4116
|
+
if (s2 === "authorized") return "bg-ui-tag-blue-bg text-ui-tag-blue-text";
|
|
4117
|
+
if (s2 === "error" || s2 === "canceled" || s2 === "cancelled") return "bg-ui-tag-red-bg text-ui-tag-red-text";
|
|
4118
|
+
if (s2 === "pending" || s2 === "requires_more") return "bg-ui-tag-orange-bg text-ui-tag-orange-text";
|
|
4119
|
+
return "bg-ui-tag-purple-bg text-ui-tag-purple-text";
|
|
4120
|
+
};
|
|
4121
|
+
const PaymentDetailPage = () => {
|
|
4122
|
+
const navigate = useNavigate();
|
|
4123
|
+
const params = useParams();
|
|
4124
|
+
const id = params?.id?.trim();
|
|
4125
|
+
const [detail, setDetail] = useState(null);
|
|
4126
|
+
const [loading, setLoading] = useState(!!id);
|
|
4127
|
+
const [error, setError] = useState(null);
|
|
4128
|
+
useEffect(() => {
|
|
4129
|
+
if (!id) {
|
|
4130
|
+
setLoading(false);
|
|
4131
|
+
return;
|
|
4132
|
+
}
|
|
4133
|
+
let cancelled = false;
|
|
4134
|
+
setLoading(true);
|
|
4135
|
+
setError(null);
|
|
4136
|
+
fetch(`/admin/payment-transactions/${id}`, { credentials: "include" }).then((res) => {
|
|
4137
|
+
if (!res.ok) throw new Error(res.statusText || "Failed to load");
|
|
4138
|
+
return res.json();
|
|
4139
|
+
}).then((data) => {
|
|
4140
|
+
if (!cancelled) setDetail(data);
|
|
4141
|
+
}).catch((e) => {
|
|
4142
|
+
if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load");
|
|
4143
|
+
}).finally(() => {
|
|
4144
|
+
if (!cancelled) setLoading(false);
|
|
4145
|
+
});
|
|
4146
|
+
return () => {
|
|
4147
|
+
cancelled = true;
|
|
4148
|
+
};
|
|
4149
|
+
}, [id]);
|
|
4150
|
+
const displayStatus = detail ? (detail.payment_id != null && detail.payment_status != null && detail.payment_status !== "" ? detail.payment_status : detail.session_status ?? "") || "—" : "";
|
|
4151
|
+
const sessionStatusRaw = detail?.session_status ?? "—";
|
|
4152
|
+
const paymentStatusRaw = detail?.payment_id != null ? detail?.payment_status ?? "—" : "—";
|
|
4153
|
+
const displayAmount = detail ? `${(detail.currency_code ?? "USD").toUpperCase()} ${Number(detail.amount)}` : "";
|
|
4154
|
+
return /* @__PURE__ */ jsx("div", { className: "w-full p-6", children: /* @__PURE__ */ jsxs(Container, { className: "mx-auto flex w-full max-w-4xl flex-col gap-6 p-6", children: [
|
|
4155
|
+
/* @__PURE__ */ jsx("header", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
4156
|
+
/* @__PURE__ */ jsx(Button, { variant: "transparent", size: "small", onClick: () => navigate("/payments"), children: "← Payments" }),
|
|
4157
|
+
/* @__PURE__ */ jsx(Heading, { level: "h1", children: "Payment session" }),
|
|
4158
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: id ?? "—" })
|
|
4159
|
+
] }) }),
|
|
4160
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-ui-border-strong p-6 text-center", children: [
|
|
4161
|
+
/* @__PURE__ */ jsx(Text, { weight: "plus", className: "text-ui-fg-error", children: error }),
|
|
4162
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: () => navigate("/payments"), children: "Back to list" })
|
|
4163
|
+
] }) : loading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-16", children: /* @__PURE__ */ jsx(Text, { children: "Loading…" }) }) : detail ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
4164
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6 flex flex-col gap-4", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
4165
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4166
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Order ID" }),
|
|
4167
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: detail.order_id ? /* @__PURE__ */ jsx(
|
|
4168
|
+
Button,
|
|
4169
|
+
{
|
|
4170
|
+
variant: "transparent",
|
|
4171
|
+
size: "small",
|
|
4172
|
+
onClick: () => navigate(`/orders/${detail.order_id}`),
|
|
4173
|
+
children: detail.order_id
|
|
4174
|
+
}
|
|
4175
|
+
) : /* @__PURE__ */ jsx(Text, { children: "—" }) })
|
|
4176
|
+
] }),
|
|
4177
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4178
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Amount" }),
|
|
4179
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: displayAmount })
|
|
4180
|
+
] }),
|
|
4181
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4182
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Provider" }),
|
|
4183
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.provider_id })
|
|
4184
|
+
] }),
|
|
4185
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4186
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Status" }),
|
|
4187
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(
|
|
4188
|
+
Badge,
|
|
4189
|
+
{
|
|
4190
|
+
size: "2xsmall",
|
|
4191
|
+
className: `uppercase ${getStatusBadgeClass$2(displayStatus)}`,
|
|
4192
|
+
children: displayStatus !== "—" ? displayStatus.replace(/_/g, " ") : "—"
|
|
4193
|
+
}
|
|
4194
|
+
) })
|
|
4195
|
+
] }),
|
|
4196
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4197
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Session status (DB)" }),
|
|
4198
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: sessionStatusRaw })
|
|
4199
|
+
] }),
|
|
4200
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4201
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Payment status (DB)" }),
|
|
4202
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: paymentStatusRaw })
|
|
4203
|
+
] }),
|
|
4204
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4205
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Finalized" }),
|
|
4206
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: detail.payment_id != null ? "Yes" : "No" })
|
|
4207
|
+
] }),
|
|
4208
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4209
|
+
/* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "Created" }),
|
|
4210
|
+
/* @__PURE__ */ jsx(Text, { className: "mt-1 block", children: new Date(detail.created_at).toLocaleDateString("en-US", {
|
|
4211
|
+
year: "numeric",
|
|
4212
|
+
month: "short",
|
|
4213
|
+
day: "numeric",
|
|
4214
|
+
hour: "numeric",
|
|
4215
|
+
minute: "2-digit",
|
|
4216
|
+
hour12: true
|
|
4217
|
+
}) })
|
|
4218
|
+
] })
|
|
4219
|
+
] }) }),
|
|
4220
|
+
Object.keys(detail.data ?? {}).length > 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-ui-border-base p-6", children: [
|
|
4221
|
+
/* @__PURE__ */ jsx(Heading, { level: "h2", className: "text-lg mb-4", children: "Provider data" }),
|
|
4222
|
+
/* @__PURE__ */ jsx("pre", { className: "text-xs bg-ui-bg-subtle p-4 rounded-lg overflow-auto max-h-96", children: JSON.stringify(detail.data, null, 2) })
|
|
4223
|
+
] }) : /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-ui-border-base p-6", children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-muted", children: "No provider data for this session." }) })
|
|
4224
|
+
] }) : null
|
|
4225
|
+
] }) });
|
|
4226
|
+
};
|
|
4227
|
+
const config$2 = defineRouteConfig({
|
|
4228
|
+
label: "Payment details",
|
|
4229
|
+
icon: CreditCard
|
|
4230
|
+
});
|
|
4231
4231
|
const getStatusBadgeClass$1 = (status) => {
|
|
4232
4232
|
const statusLower = status.toLowerCase();
|
|
4233
4233
|
if (statusLower === "requested") {
|
|
@@ -4809,13 +4809,13 @@ const routeModule = {
|
|
|
4809
4809
|
handle: { label: config$9.label, translationNs: config$9.translationNs }
|
|
4810
4810
|
},
|
|
4811
4811
|
{
|
|
4812
|
-
Component:
|
|
4813
|
-
path: "/
|
|
4812
|
+
Component: RefundsPage,
|
|
4813
|
+
path: "/refunds",
|
|
4814
4814
|
handle: { label: config$8.label, translationNs: config$8.translationNs }
|
|
4815
4815
|
},
|
|
4816
4816
|
{
|
|
4817
|
-
Component:
|
|
4818
|
-
path: "/
|
|
4817
|
+
Component: PaymentsPage,
|
|
4818
|
+
path: "/payments",
|
|
4819
4819
|
handle: { label: config$7.label, translationNs: config$7.translationNs }
|
|
4820
4820
|
},
|
|
4821
4821
|
{
|
|
@@ -4834,13 +4834,13 @@ const routeModule = {
|
|
|
4834
4834
|
handle: { label: config$4.label, translationNs: config$4.translationNs }
|
|
4835
4835
|
},
|
|
4836
4836
|
{
|
|
4837
|
-
Component:
|
|
4838
|
-
path: "/
|
|
4837
|
+
Component: RefundDetailPage,
|
|
4838
|
+
path: "/refunds/:id",
|
|
4839
4839
|
handle: { label: config$3.label, translationNs: config$3.translationNs }
|
|
4840
4840
|
},
|
|
4841
4841
|
{
|
|
4842
|
-
Component:
|
|
4843
|
-
path: "/
|
|
4842
|
+
Component: PaymentDetailPage,
|
|
4843
|
+
path: "/payments/:id",
|
|
4844
4844
|
handle: { label: config$2.label, translationNs: config$2.translationNs }
|
|
4845
4845
|
},
|
|
4846
4846
|
{
|
|
@@ -4866,16 +4866,16 @@ const menuItemModule = {
|
|
|
4866
4866
|
translationNs: void 0
|
|
4867
4867
|
},
|
|
4868
4868
|
{
|
|
4869
|
-
label: config$
|
|
4870
|
-
icon: config$
|
|
4869
|
+
label: config$7.label,
|
|
4870
|
+
icon: config$7.icon,
|
|
4871
4871
|
path: "/payments",
|
|
4872
4872
|
nested: void 0,
|
|
4873
4873
|
rank: void 0,
|
|
4874
4874
|
translationNs: void 0
|
|
4875
4875
|
},
|
|
4876
4876
|
{
|
|
4877
|
-
label: config$
|
|
4878
|
-
icon: config$
|
|
4877
|
+
label: config$8.label,
|
|
4878
|
+
icon: config$8.icon,
|
|
4879
4879
|
path: "/refunds",
|
|
4880
4880
|
nested: void 0,
|
|
4881
4881
|
rank: void 0,
|
|
@@ -4898,16 +4898,16 @@ const menuItemModule = {
|
|
|
4898
4898
|
translationNs: void 0
|
|
4899
4899
|
},
|
|
4900
4900
|
{
|
|
4901
|
-
label: config$
|
|
4902
|
-
icon: config$
|
|
4901
|
+
label: config$2.label,
|
|
4902
|
+
icon: config$2.icon,
|
|
4903
4903
|
path: "/payments/:id",
|
|
4904
4904
|
nested: void 0,
|
|
4905
4905
|
rank: void 0,
|
|
4906
4906
|
translationNs: void 0
|
|
4907
4907
|
},
|
|
4908
4908
|
{
|
|
4909
|
-
label: config$
|
|
4910
|
-
icon: config$
|
|
4909
|
+
label: config$3.label,
|
|
4910
|
+
icon: config$3.icon,
|
|
4911
4911
|
path: "/refunds/:id",
|
|
4912
4912
|
nested: void 0,
|
|
4913
4913
|
rank: void 0,
|