@burdenoff/microfe-store 2026.915.1 → 2026.915.2

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.
@@ -5,8 +5,8 @@ import { Suspense as i, lazy as a } from "react";
5
5
  import { Navigate as o, Route as s, Routes as c } from "react-router";
6
6
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
7
  //#region src/StoreAdminRoutes.tsx
8
- var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default: e.AdminDashboardPage }))), f = a(() => import("./pages/AdminSubmissionsQueuePage.js").then((e) => ({ default: e.AdminSubmissionsQueuePage }))), p = a(() => import("./pages/AdminStoresPage.js").then((e) => ({ default: e.AdminStoresPage }))), m = a(() => import("./pages/AdminReviewModerationPage.js").then((e) => ({ default: e.AdminReviewModerationPage }))), h = a(() => import("./pages/AdminOrdersPage.js").then((e) => ({ default: e.AdminOrdersPage }))), g = () => {
9
- let { hasPermission: a } = t(), g = a(e.REVIEW_ADMIN) || a(e.PRODUCT_ADMIN);
8
+ var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default: e.AdminDashboardPage }))), f = a(() => import("./pages/AdminSubmissionsQueuePage.js").then((e) => ({ default: e.AdminSubmissionsQueuePage }))), p = a(() => import("./pages/AdminStoresPage.js").then((e) => ({ default: e.AdminStoresPage }))), m = a(() => import("./pages/AdminReviewModerationPage.js").then((e) => ({ default: e.AdminReviewModerationPage }))), h = a(() => import("./pages/AdminOrdersPage.js").then((e) => ({ default: e.AdminOrdersPage }))), g = a(() => import("./pages/AdminFulfillmentLogsPage.js").then((e) => ({ default: e.AdminFulfillmentLogsPage }))), _ = () => {
9
+ let { hasPermission: a } = t(), _ = a(e.REVIEW_ADMIN) || a(e.PRODUCT_ADMIN);
10
10
  return /* @__PURE__ */ u(c, { children: [
11
11
  /* @__PURE__ */ l(s, {
12
12
  index: !0,
@@ -18,7 +18,7 @@ var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default:
18
18
  /* @__PURE__ */ l(s, {
19
19
  path: "dashboard",
20
20
  element: /* @__PURE__ */ l(n, {
21
- allowed: g,
21
+ allowed: _,
22
22
  children: /* @__PURE__ */ l(i, {
23
23
  fallback: /* @__PURE__ */ l(r, {}),
24
24
  children: /* @__PURE__ */ l(d, {})
@@ -28,7 +28,7 @@ var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default:
28
28
  /* @__PURE__ */ l(s, {
29
29
  path: "submissions",
30
30
  element: /* @__PURE__ */ l(n, {
31
- allowed: g,
31
+ allowed: _,
32
32
  children: /* @__PURE__ */ l(i, {
33
33
  fallback: /* @__PURE__ */ l(r, {}),
34
34
  children: /* @__PURE__ */ l(f, {})
@@ -38,7 +38,7 @@ var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default:
38
38
  /* @__PURE__ */ l(s, {
39
39
  path: "stores",
40
40
  element: /* @__PURE__ */ l(n, {
41
- allowed: g,
41
+ allowed: _,
42
42
  children: /* @__PURE__ */ l(i, {
43
43
  fallback: /* @__PURE__ */ l(r, {}),
44
44
  children: /* @__PURE__ */ l(p, {})
@@ -48,13 +48,23 @@ var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default:
48
48
  /* @__PURE__ */ l(s, {
49
49
  path: "orders",
50
50
  element: /* @__PURE__ */ l(n, {
51
- allowed: g,
51
+ allowed: _,
52
52
  children: /* @__PURE__ */ l(i, {
53
53
  fallback: /* @__PURE__ */ l(r, {}),
54
54
  children: /* @__PURE__ */ l(h, {})
55
55
  })
56
56
  })
57
57
  }),
58
+ /* @__PURE__ */ l(s, {
59
+ path: "fulfillment-logs",
60
+ element: /* @__PURE__ */ l(n, {
61
+ allowed: _,
62
+ children: /* @__PURE__ */ l(i, {
63
+ fallback: /* @__PURE__ */ l(r, {}),
64
+ children: /* @__PURE__ */ l(g, {})
65
+ })
66
+ })
67
+ }),
58
68
  /* @__PURE__ */ l(s, {
59
69
  path: "reviews",
60
70
  element: /* @__PURE__ */ l(n, {
@@ -75,6 +85,6 @@ var d = a(() => import("./pages/AdminDashboardPage.js").then((e) => ({ default:
75
85
  ] });
76
86
  };
77
87
  //#endregion
78
- export { g as StoreAdminRoutes };
88
+ export { _ as StoreAdminRoutes };
79
89
 
80
90
  //# sourceMappingURL=StoreAdminRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StoreAdminRoutes.js","names":[],"sources":["../src/StoreAdminRoutes.tsx"],"sourcesContent":["import { lazy, Suspense, type FC } from 'react';\nimport { Routes, Route, Navigate } from 'react-router';\nimport { useStorePermissions, STORE_PERMISSIONS } from './hooks/useStorePermissions';\nimport { PageLoadingFallback, PermissionGuard } from './components/RouteGuards';\n\nconst AdminDashboardPage = lazy(() =>\n import('./pages/AdminDashboardPage').then((m) => ({\n default: m.AdminDashboardPage,\n }))\n);\n\nconst AdminSubmissionsQueuePage = lazy(() =>\n import('./pages/AdminSubmissionsQueuePage').then((m) => ({\n default: m.AdminSubmissionsQueuePage,\n }))\n);\n\nconst AdminStoresPage = lazy(() =>\n import('./pages/AdminStoresPage').then((m) => ({\n default: m.AdminStoresPage,\n }))\n);\n\nconst AdminReviewModerationPage = lazy(() =>\n import('./pages/AdminReviewModerationPage').then((m) => ({\n default: m.AdminReviewModerationPage,\n }))\n);\n\nconst AdminOrdersPage = lazy(() =>\n import('./pages/AdminOrdersPage').then((m) => ({\n default: m.AdminOrdersPage,\n }))\n);\n\n/**\n * StoreAdminRoutes component\n *\n * Admin-only routing for the Store microfrontend.\n * Mounted by the admin app shell via StoreAdminRoot.\n */\nexport const StoreAdminRoutes: FC = () => {\n const { hasPermission } = useStorePermissions();\n const isAdmin =\n hasPermission(STORE_PERMISSIONS.REVIEW_ADMIN) || hasPermission(STORE_PERMISSIONS.PRODUCT_ADMIN);\n\n return (\n <Routes>\n {/* Default redirect to dashboard */}\n <Route index element={<Navigate to=\"dashboard\" replace />} />\n\n <Route\n path=\"dashboard\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminDashboardPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"submissions\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminSubmissionsQueuePage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"stores\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminStoresPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"orders\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminOrdersPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"reviews\"\n element={\n <PermissionGuard allowed={hasPermission(STORE_PERMISSIONS.REVIEW_ADMIN)}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminReviewModerationPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n {/* Catch-all redirect */}\n <Route path=\"*\" element={<Navigate to=\"dashboard\" replace />} />\n </Routes>\n );\n};\n"],"mappings":";;;;;;;AAKA,IAAM,IAAqB,QACzB,OAAO,iCAA8B,MAAM,OAAO,EAChD,SAAS,EAAE,oBACZ,EAAE,CACJ,EAEK,IAA4B,QAChC,OAAO,wCAAqC,MAAM,OAAO,EACvD,SAAS,EAAE,2BACZ,EAAE,CACJ,EAEK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAC7C,SAAS,EAAE,iBACZ,EAAE,CACJ,EAEK,IAA4B,QAChC,OAAO,wCAAqC,MAAM,OAAO,EACvD,SAAS,EAAE,2BACZ,EAAE,CACJ,EAEK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAC7C,SAAS,EAAE,iBACZ,EAAE,CACJ,EAQY,UAA6B;CACxC,IAAM,EAAE,qBAAkB,GAAqB,EACzC,IACJ,EAAc,EAAkB,aAAa,IAAI,EAAc,EAAkB,cAAc;AAEjG,QACE,kBAAC,GAAD,EAAA,UAAA;EAEE,kBAAC,GAAD;GAAO,OAAA;GAAM,SAAS,kBAAC,GAAD;IAAU,IAAG;IAAY,SAAA;IAAU,CAAA;GAAI,CAAA;EAE7D,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAAsB,CAAA;KACb,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAA6B,CAAA;KACpB,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAAmB,CAAA;KACV,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAAmB,CAAA;KACV,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS,EAAc,EAAkB,aAAa;cACrE,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAA6B,CAAA;KACpB,CAAA;IACK,CAAA;GAEpB,CAAA;EAGF,kBAAC,GAAD;GAAO,MAAK;GAAI,SAAS,kBAAC,GAAD;IAAU,IAAG;IAAY,SAAA;IAAU,CAAA;GAAI,CAAA;EACzD,EAAA,CAAA"}
1
+ {"version":3,"file":"StoreAdminRoutes.js","names":[],"sources":["../src/StoreAdminRoutes.tsx"],"sourcesContent":["import { lazy, Suspense, type FC } from 'react';\nimport { Routes, Route, Navigate } from 'react-router';\nimport { useStorePermissions, STORE_PERMISSIONS } from './hooks/useStorePermissions';\nimport { PageLoadingFallback, PermissionGuard } from './components/RouteGuards';\n\nconst AdminDashboardPage = lazy(() =>\n import('./pages/AdminDashboardPage').then((m) => ({\n default: m.AdminDashboardPage,\n }))\n);\n\nconst AdminSubmissionsQueuePage = lazy(() =>\n import('./pages/AdminSubmissionsQueuePage').then((m) => ({\n default: m.AdminSubmissionsQueuePage,\n }))\n);\n\nconst AdminStoresPage = lazy(() =>\n import('./pages/AdminStoresPage').then((m) => ({\n default: m.AdminStoresPage,\n }))\n);\n\nconst AdminReviewModerationPage = lazy(() =>\n import('./pages/AdminReviewModerationPage').then((m) => ({\n default: m.AdminReviewModerationPage,\n }))\n);\n\nconst AdminOrdersPage = lazy(() =>\n import('./pages/AdminOrdersPage').then((m) => ({\n default: m.AdminOrdersPage,\n }))\n);\n\nconst AdminFulfillmentLogsPage = lazy(() =>\n import('./pages/AdminFulfillmentLogsPage').then((m) => ({\n default: m.AdminFulfillmentLogsPage,\n }))\n);\n\n/**\n * StoreAdminRoutes component\n *\n * Admin-only routing for the Store microfrontend.\n * Mounted by the admin app shell via StoreAdminRoot.\n */\nexport const StoreAdminRoutes: FC = () => {\n const { hasPermission } = useStorePermissions();\n const isAdmin =\n hasPermission(STORE_PERMISSIONS.REVIEW_ADMIN) || hasPermission(STORE_PERMISSIONS.PRODUCT_ADMIN);\n\n return (\n <Routes>\n {/* Default redirect to dashboard */}\n <Route index element={<Navigate to=\"dashboard\" replace />} />\n\n <Route\n path=\"dashboard\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminDashboardPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"submissions\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminSubmissionsQueuePage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"stores\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminStoresPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"orders\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminOrdersPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"fulfillment-logs\"\n element={\n <PermissionGuard allowed={isAdmin}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminFulfillmentLogsPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n <Route\n path=\"reviews\"\n element={\n <PermissionGuard allowed={hasPermission(STORE_PERMISSIONS.REVIEW_ADMIN)}>\n <Suspense fallback={<PageLoadingFallback />}>\n <AdminReviewModerationPage />\n </Suspense>\n </PermissionGuard>\n }\n />\n\n {/* Catch-all redirect */}\n <Route path=\"*\" element={<Navigate to=\"dashboard\" replace />} />\n </Routes>\n );\n};\n"],"mappings":";;;;;;;AAKA,IAAM,IAAqB,QACzB,OAAO,iCAA8B,MAAM,OAAO,EAChD,SAAS,EAAE,oBACZ,EAAE,CACJ,EAEK,IAA4B,QAChC,OAAO,wCAAqC,MAAM,OAAO,EACvD,SAAS,EAAE,2BACZ,EAAE,CACJ,EAEK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAC7C,SAAS,EAAE,iBACZ,EAAE,CACJ,EAEK,IAA4B,QAChC,OAAO,wCAAqC,MAAM,OAAO,EACvD,SAAS,EAAE,2BACZ,EAAE,CACJ,EAEK,IAAkB,QACtB,OAAO,8BAA2B,MAAM,OAAO,EAC7C,SAAS,EAAE,iBACZ,EAAE,CACJ,EAEK,IAA2B,QAC/B,OAAO,uCAAoC,MAAM,OAAO,EACtD,SAAS,EAAE,0BACZ,EAAE,CACJ,EAQY,UAA6B;CACxC,IAAM,EAAE,qBAAkB,GAAqB,EACzC,IACJ,EAAc,EAAkB,aAAa,IAAI,EAAc,EAAkB,cAAc;AAEjG,QACE,kBAAC,GAAD,EAAA,UAAA;EAEE,kBAAC,GAAD;GAAO,OAAA;GAAM,SAAS,kBAAC,GAAD;IAAU,IAAG;IAAY,SAAA;IAAU,CAAA;GAAI,CAAA;EAE7D,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAAsB,CAAA;KACb,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAA6B,CAAA;KACpB,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAAmB,CAAA;KACV,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAAmB,CAAA;KACV,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS;cACxB,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAA4B,CAAA;KACnB,CAAA;IACK,CAAA;GAEpB,CAAA;EAEF,kBAAC,GAAD;GACE,MAAK;GACL,SACE,kBAAC,GAAD;IAAiB,SAAS,EAAc,EAAkB,aAAa;cACrE,kBAAC,GAAD;KAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;eACzC,kBAAC,GAAD,EAA6B,CAAA;KACpB,CAAA;IACK,CAAA;GAEpB,CAAA;EAGF,kBAAC,GAAD;GAAO,MAAK;GAAI,SAAS,kBAAC,GAAD;IAAU,IAAG;IAAY,SAAA;IAAU,CAAA;GAAI,CAAA;EACzD,EAAA,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { FC } from 'react';
2
+
3
+ /**
4
+ * Admin-only log of every carrier shipment-creation attempt (every Temporal
5
+ * retry, not just the last failure) — the "why did this order's shipment
6
+ * fail" debugging surface that OrderFulfillment.failureReason alone can't
7
+ * answer, since it only ever holds the last attempt's message.
8
+ */
9
+ export declare const AdminFulfillmentLogsPage: FC;
@@ -0,0 +1,278 @@
1
+ import { useStore as e } from "../providers/StoreProvider.js";
2
+ import { useCallback as t, useEffect as n, useState as r } from "react";
3
+ import { useNavigate as i, useSearchParams as a } from "react-router";
4
+ import { ArrowLeft as o, CheckCircle2 as s, RefreshCw as c, Truck as l, XCircle as u } from "lucide-react";
5
+ import { graphqlFetch as d } from "@burdenoff/fe-libs/shared/graphql";
6
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
7
+ import { IllustratedEmptyState as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
8
+ //#region src/pages/AdminFulfillmentLogsPage.tsx
9
+ var _ = [
10
+ {
11
+ value: "",
12
+ label: "All results"
13
+ },
14
+ {
15
+ value: "false",
16
+ label: "Failed only"
17
+ },
18
+ {
19
+ value: "true",
20
+ label: "Succeeded only"
21
+ }
22
+ ], v = "\n query AdminOrderFulfillmentAttempts(\n $limit: Int!\n $offset: Int!\n $orderId: ID\n $carrier: String\n $succeeded: Boolean\n ) {\n orderFulfillmentAttempts(\n limit: $limit\n offset: $offset\n orderId: $orderId\n carrier: $carrier\n succeeded: $succeeded\n ) {\n totalCount\n attempts {\n id\n attemptNumber\n carrier\n succeeded\n errorMessage\n errorStatusCode\n durationMs\n occurredAt\n }\n }\n }\n", y = 25;
23
+ function b(e) {
24
+ return new Date(e).toLocaleString("en-US", {
25
+ year: "numeric",
26
+ month: "short",
27
+ day: "numeric",
28
+ hour: "2-digit",
29
+ minute: "2-digit",
30
+ second: "2-digit"
31
+ });
32
+ }
33
+ var x = () => {
34
+ let x = i(), { authToken: S, basePath: C } = e(), [w] = a(), [T, E] = r([]), [D, O] = r(0), [k, A] = r(!1), [j, M] = r(null), [N, P] = r(0), [F, I] = r(""), [L, R] = r(""), [z, B] = r(w.get("orderId") ?? ""), V = t(async () => {
35
+ A(!0), M(null);
36
+ try {
37
+ let e = await d({
38
+ gateway: "global",
39
+ query: v,
40
+ variables: {
41
+ limit: y,
42
+ offset: N * y,
43
+ orderId: z.trim() || void 0,
44
+ carrier: L.trim() || void 0,
45
+ succeeded: F === "" ? void 0 : F === "true"
46
+ },
47
+ authToken: S || void 0
48
+ });
49
+ if (e.errors?.length) throw Error(e.errors[0]?.message ?? "Failed to load fulfillment logs");
50
+ O(e.data?.orderFulfillmentAttempts.totalCount ?? 0), E(e.data?.orderFulfillmentAttempts.attempts ?? []);
51
+ } catch (e) {
52
+ M(e instanceof Error ? e.message : "Failed to load fulfillment logs");
53
+ } finally {
54
+ A(!1);
55
+ }
56
+ }, [
57
+ S,
58
+ N,
59
+ z,
60
+ L,
61
+ F
62
+ ]);
63
+ return n(() => {
64
+ V();
65
+ }, [V]), /* @__PURE__ */ m("div", {
66
+ className: "min-h-screen bg-surface-default",
67
+ children: [/* @__PURE__ */ p("header", {
68
+ className: "border-b border-border-seam bg-surface-raised",
69
+ children: /* @__PURE__ */ p("div", {
70
+ className: "mx-auto max-w-7xl px-6 py-4",
71
+ children: /* @__PURE__ */ m("div", {
72
+ className: "flex items-center justify-between",
73
+ children: [/* @__PURE__ */ m("div", {
74
+ className: "flex items-center gap-3",
75
+ children: [/* @__PURE__ */ m("button", {
76
+ type: "button",
77
+ onClick: () => x(`${C}/dashboard`),
78
+ className: "inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary",
79
+ children: [/* @__PURE__ */ p(o, { className: "size-4" }), "Back"]
80
+ }), /* @__PURE__ */ m("div", {
81
+ className: "flex items-center gap-2",
82
+ children: [
83
+ /* @__PURE__ */ p(l, { className: "size-5 text-text-primary" }),
84
+ /* @__PURE__ */ p("h1", {
85
+ className: "text-xl font-semibold text-text-primary",
86
+ children: "Fulfillment logs"
87
+ }),
88
+ /* @__PURE__ */ p("span", {
89
+ className: "rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent",
90
+ children: D
91
+ })
92
+ ]
93
+ })]
94
+ }), /* @__PURE__ */ m("button", {
95
+ type: "button",
96
+ onClick: () => void V(),
97
+ className: "inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover",
98
+ disabled: k,
99
+ children: [/* @__PURE__ */ p(c, { className: `size-4 ${k ? "animate-spin" : ""}` }), "Refresh"]
100
+ })]
101
+ })
102
+ })
103
+ }), /* @__PURE__ */ m("main", {
104
+ className: "mx-auto max-w-7xl p-6",
105
+ children: [
106
+ /* @__PURE__ */ p(g, {
107
+ className: "mb-4",
108
+ children: "Every carrier shipment-creation attempt for every physical order — including retries Temporal made after a failure — so you can see what happened, why, and whether it eventually succeeded. OrderFulfillment.failureReason only ever shows the last attempt; this is the full history."
109
+ }),
110
+ /* @__PURE__ */ m("div", {
111
+ className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center",
112
+ children: [
113
+ /* @__PURE__ */ p("select", {
114
+ "aria-label": "Filter by result",
115
+ value: F,
116
+ onChange: (e) => {
117
+ I(e.target.value), P(0);
118
+ },
119
+ className: "rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary",
120
+ children: _.map((e) => /* @__PURE__ */ p("option", {
121
+ value: e.value,
122
+ children: e.label
123
+ }, e.value))
124
+ }),
125
+ /* @__PURE__ */ p("input", {
126
+ type: "text",
127
+ "aria-label": "Filter by carrier",
128
+ placeholder: "Carrier (e.g. shiprocket)…",
129
+ value: L,
130
+ onChange: (e) => {
131
+ R(e.target.value), P(0);
132
+ },
133
+ className: "rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary sm:w-48"
134
+ }),
135
+ /* @__PURE__ */ p("input", {
136
+ type: "search",
137
+ "aria-label": "Filter by order ID",
138
+ placeholder: "Order ID…",
139
+ value: z,
140
+ onChange: (e) => {
141
+ B(e.target.value), P(0);
142
+ },
143
+ className: "flex-1 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary"
144
+ })
145
+ ]
146
+ }),
147
+ j && /* @__PURE__ */ p("div", {
148
+ role: "alert",
149
+ className: "mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger",
150
+ children: j
151
+ }),
152
+ k && T.length === 0 ? /* @__PURE__ */ p("output", {
153
+ className: "block py-16 text-center text-text-secondary",
154
+ children: "Loading fulfillment logs…"
155
+ }) : T.length === 0 ? /* @__PURE__ */ p(h, {
156
+ illustration: "empty-generic",
157
+ title: "No fulfillment attempts",
158
+ description: "Carrier shipment-creation attempts will show up here as physical orders are placed."
159
+ }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", {
160
+ className: "overflow-hidden rounded-lg border border-border-seam",
161
+ children: /* @__PURE__ */ m("table", {
162
+ className: "w-full text-sm",
163
+ children: [/* @__PURE__ */ p("thead", {
164
+ className: "bg-surface-muted text-left text-xs uppercase tracking-wide text-text-secondary",
165
+ children: /* @__PURE__ */ m("tr", { children: [
166
+ /* @__PURE__ */ p("th", {
167
+ className: "px-4 py-2",
168
+ children: "Attempt #"
169
+ }),
170
+ /* @__PURE__ */ p("th", {
171
+ className: "px-4 py-2",
172
+ children: "Carrier"
173
+ }),
174
+ /* @__PURE__ */ p("th", {
175
+ className: "px-4 py-2",
176
+ children: "Result"
177
+ }),
178
+ /* @__PURE__ */ p("th", {
179
+ className: "px-4 py-2",
180
+ children: "Error"
181
+ }),
182
+ /* @__PURE__ */ p("th", {
183
+ className: "px-4 py-2 text-right",
184
+ children: "Duration"
185
+ }),
186
+ /* @__PURE__ */ p("th", {
187
+ className: "px-4 py-2",
188
+ children: "Occurred"
189
+ })
190
+ ] })
191
+ }), /* @__PURE__ */ p("tbody", {
192
+ className: "divide-y divide-border-seam bg-surface-raised",
193
+ children: T.map((e) => /* @__PURE__ */ m("tr", {
194
+ className: "text-text-primary align-top",
195
+ children: [
196
+ /* @__PURE__ */ p("td", {
197
+ className: "px-4 py-2 font-mono text-xs",
198
+ children: e.attemptNumber
199
+ }),
200
+ /* @__PURE__ */ p("td", {
201
+ className: "px-4 py-2 text-xs",
202
+ children: e.carrier
203
+ }),
204
+ /* @__PURE__ */ p("td", {
205
+ className: "px-4 py-2",
206
+ children: e.succeeded ? /* @__PURE__ */ m("span", {
207
+ className: "inline-flex items-center gap-1 rounded-full bg-surface-success-muted px-2 py-0.5 text-xs font-medium text-text-success",
208
+ children: [/* @__PURE__ */ p(s, { className: "size-3" }), "Succeeded"]
209
+ }) : /* @__PURE__ */ m("span", {
210
+ className: "inline-flex items-center gap-1 rounded-full bg-surface-danger-muted px-2 py-0.5 text-xs font-medium text-text-danger",
211
+ children: [
212
+ /* @__PURE__ */ p(u, { className: "size-3" }),
213
+ "Failed",
214
+ e.errorStatusCode ? ` (${e.errorStatusCode})` : ""
215
+ ]
216
+ })
217
+ }),
218
+ /* @__PURE__ */ p("td", {
219
+ className: "max-w-md px-4 py-2 text-xs text-text-secondary",
220
+ children: e.errorMessage ? /* @__PURE__ */ p("span", {
221
+ title: e.errorMessage,
222
+ className: "line-clamp-2",
223
+ children: e.errorMessage
224
+ }) : /* @__PURE__ */ p("span", {
225
+ className: "text-text-muted",
226
+ children: "—"
227
+ })
228
+ }),
229
+ /* @__PURE__ */ p("td", {
230
+ className: "px-4 py-2 text-right tabular-nums text-xs text-text-secondary",
231
+ children: e.durationMs === null ? "—" : `${e.durationMs}ms`
232
+ }),
233
+ /* @__PURE__ */ p("td", {
234
+ className: "px-4 py-2 text-xs text-text-secondary whitespace-nowrap",
235
+ children: b(e.occurredAt)
236
+ })
237
+ ]
238
+ }, e.id))
239
+ })]
240
+ })
241
+ }), D > y && /* @__PURE__ */ m("div", {
242
+ className: "mt-4 flex items-center justify-between text-sm",
243
+ children: [/* @__PURE__ */ m("span", {
244
+ className: "text-text-secondary",
245
+ children: [
246
+ "Showing ",
247
+ N * y + 1,
248
+ "–",
249
+ Math.min((N + 1) * y, D),
250
+ " of",
251
+ " ",
252
+ D
253
+ ]
254
+ }), /* @__PURE__ */ m("div", {
255
+ className: "flex items-center gap-2",
256
+ children: [/* @__PURE__ */ p("button", {
257
+ type: "button",
258
+ disabled: N === 0,
259
+ onClick: () => P((e) => e - 1),
260
+ className: "rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40",
261
+ children: "Previous"
262
+ }), /* @__PURE__ */ p("button", {
263
+ type: "button",
264
+ disabled: (N + 1) * y >= D,
265
+ onClick: () => P((e) => e + 1),
266
+ className: "rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40",
267
+ children: "Next"
268
+ })]
269
+ })]
270
+ })] })
271
+ ]
272
+ })]
273
+ });
274
+ };
275
+ //#endregion
276
+ export { x as AdminFulfillmentLogsPage };
277
+
278
+ //# sourceMappingURL=AdminFulfillmentLogsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminFulfillmentLogsPage.js","names":[],"sources":["../../src/pages/AdminFulfillmentLogsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { ArrowLeft, RefreshCw, Truck, CheckCircle2, XCircle } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate, useSearchParams } from 'react-router';\nimport { useStore } from '../providers/StoreProvider';\nimport { PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\n\ninterface FulfillmentAttempt {\n id: string;\n attemptNumber: number;\n carrier: string;\n succeeded: boolean;\n errorMessage: string | null;\n errorStatusCode: number | null;\n durationMs: number | null;\n occurredAt: string;\n}\n\nconst SUCCEEDED_OPTIONS: { value: '' | 'true' | 'false'; label: string }[] = [\n { value: '', label: 'All results' },\n { value: 'false', label: 'Failed only' },\n { value: 'true', label: 'Succeeded only' },\n];\n\nconst ORDER_FULFILLMENT_ATTEMPTS_QUERY = /* GraphQL */ `\n query AdminOrderFulfillmentAttempts(\n $limit: Int!\n $offset: Int!\n $orderId: ID\n $carrier: String\n $succeeded: Boolean\n ) {\n orderFulfillmentAttempts(\n limit: $limit\n offset: $offset\n orderId: $orderId\n carrier: $carrier\n succeeded: $succeeded\n ) {\n totalCount\n attempts {\n id\n attemptNumber\n carrier\n succeeded\n errorMessage\n errorStatusCode\n durationMs\n occurredAt\n }\n }\n }\n`;\n\nconst PAGE_SIZE = 25;\n\nfunction formatDate(iso: string): string {\n return new Date(iso).toLocaleString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\n/**\n * Admin-only log of every carrier shipment-creation attempt (every Temporal\n * retry, not just the last failure) — the \"why did this order's shipment\n * fail\" debugging surface that OrderFulfillment.failureReason alone can't\n * answer, since it only ever holds the last attempt's message.\n */\nexport const AdminFulfillmentLogsPage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n const [searchParams] = useSearchParams();\n\n const [attempts, setAttempts] = useState<FulfillmentAttempt[]>([]);\n const [total, setTotal] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [page, setPage] = useState(0);\n const [succeededFilter, setSucceededFilter] = useState<'' | 'true' | 'false'>('');\n const [carrierFilter, setCarrierFilter] = useState('');\n const [orderId, setOrderId] = useState(searchParams.get('orderId') ?? '');\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n orderFulfillmentAttempts: { totalCount: number; attempts: FulfillmentAttempt[] };\n }>({\n gateway: 'global',\n query: ORDER_FULFILLMENT_ATTEMPTS_QUERY,\n variables: {\n limit: PAGE_SIZE,\n offset: page * PAGE_SIZE,\n orderId: orderId.trim() || undefined,\n carrier: carrierFilter.trim() || undefined,\n succeeded: succeededFilter === '' ? undefined : succeededFilter === 'true',\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load fulfillment logs');\n }\n setTotal(result.data?.orderFulfillmentAttempts.totalCount ?? 0);\n setAttempts(result.data?.orderFulfillmentAttempts.attempts ?? []);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load fulfillment logs');\n } finally {\n setLoading(false);\n }\n }, [authToken, page, orderId, carrierFilter, succeededFilter]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n return (\n <div className=\"min-h-screen bg-surface-default\">\n <header className=\"border-b border-border-seam bg-surface-raised\">\n <div className=\"mx-auto max-w-7xl px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n <div className=\"flex items-center gap-2\">\n <Truck className=\"size-5 text-text-primary\" />\n <h1 className=\"text-xl font-semibold text-text-primary\">Fulfillment logs</h1>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {total}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => void load()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-7xl p-6\">\n <PagePurpose className=\"mb-4\">\n Every carrier shipment-creation attempt for every physical order — including retries\n Temporal made after a failure — so you can see what happened, why, and whether it\n eventually succeeded. OrderFulfillment.failureReason only ever shows the last attempt;\n this is the full history.\n </PagePurpose>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <select\n aria-label=\"Filter by result\"\n value={succeededFilter}\n onChange={(e) => {\n setSucceededFilter(e.target.value as '' | 'true' | 'false');\n setPage(0);\n }}\n className=\"rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary\"\n >\n {SUCCEEDED_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <input\n type=\"text\"\n aria-label=\"Filter by carrier\"\n placeholder=\"Carrier (e.g. shiprocket)…\"\n value={carrierFilter}\n onChange={(e) => {\n setCarrierFilter(e.target.value);\n setPage(0);\n }}\n className=\"rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary sm:w-48\"\n />\n <input\n type=\"search\"\n aria-label=\"Filter by order ID\"\n placeholder=\"Order ID…\"\n value={orderId}\n onChange={(e) => {\n setOrderId(e.target.value);\n setPage(0);\n }}\n className=\"flex-1 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary\"\n />\n </div>\n\n {error && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading && attempts.length === 0 ? (\n <output className=\"block py-16 text-center text-text-secondary\">\n Loading fulfillment logs…\n </output>\n ) : attempts.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No fulfillment attempts\"\n description=\"Carrier shipment-creation attempts will show up here as physical orders are placed.\"\n />\n ) : (\n <>\n <div className=\"overflow-hidden rounded-lg border border-border-seam\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-surface-muted text-left text-xs uppercase tracking-wide text-text-secondary\">\n <tr>\n <th className=\"px-4 py-2\">Attempt #</th>\n <th className=\"px-4 py-2\">Carrier</th>\n <th className=\"px-4 py-2\">Result</th>\n <th className=\"px-4 py-2\">Error</th>\n <th className=\"px-4 py-2 text-right\">Duration</th>\n <th className=\"px-4 py-2\">Occurred</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam bg-surface-raised\">\n {attempts.map((attempt) => (\n <tr key={attempt.id} className=\"text-text-primary align-top\">\n <td className=\"px-4 py-2 font-mono text-xs\">{attempt.attemptNumber}</td>\n <td className=\"px-4 py-2 text-xs\">{attempt.carrier}</td>\n <td className=\"px-4 py-2\">\n {attempt.succeeded ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-surface-success-muted px-2 py-0.5 text-xs font-medium text-text-success\">\n <CheckCircle2 className=\"size-3\" />\n Succeeded\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-surface-danger-muted px-2 py-0.5 text-xs font-medium text-text-danger\">\n <XCircle className=\"size-3\" />\n Failed{attempt.errorStatusCode ? ` (${attempt.errorStatusCode})` : ''}\n </span>\n )}\n </td>\n <td className=\"max-w-md px-4 py-2 text-xs text-text-secondary\">\n {attempt.errorMessage ? (\n <span title={attempt.errorMessage} className=\"line-clamp-2\">\n {attempt.errorMessage}\n </span>\n ) : (\n <span className=\"text-text-muted\">—</span>\n )}\n </td>\n <td className=\"px-4 py-2 text-right tabular-nums text-xs text-text-secondary\">\n {attempt.durationMs !== null ? `${attempt.durationMs}ms` : '—'}\n </td>\n <td className=\"px-4 py-2 text-xs text-text-secondary whitespace-nowrap\">\n {formatDate(attempt.occurredAt)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {total > PAGE_SIZE && (\n <div className=\"mt-4 flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">\n Showing {page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, total)} of{' '}\n {total}\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => setPage((p) => p - 1)}\n className=\"rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n disabled={(page + 1) * PAGE_SIZE >= total}\n onClick={() => setPage((p) => p + 1)}\n className=\"rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40\"\n >\n Next\n </button>\n </div>\n </div>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -2,12 +2,12 @@ import { useStore as e } from "../providers/StoreProvider.js";
2
2
  import { formatPrice as t } from "../utils/index.js";
3
3
  import { useCallback as n, useEffect as r, useState as i } from "react";
4
4
  import { useNavigate as a } from "react-router";
5
- import { ArrowLeft as o, ExternalLink as s, Flag as c, Loader2 as l, Package as u, RefreshCw as d } from "lucide-react";
6
- import { graphqlFetch as f } from "@burdenoff/fe-libs/shared/graphql";
7
- import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
8
- import { IllustratedEmptyState as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
5
+ import { ArrowLeft as o, ExternalLink as s, Flag as c, Loader2 as l, Package as u, RefreshCw as d, ScrollText as f } from "lucide-react";
6
+ import { graphqlFetch as p } from "@burdenoff/fe-libs/shared/graphql";
7
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
8
+ import { IllustratedEmptyState as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
9
9
  //#region src/pages/AdminOrdersPage.tsx
10
- var v = [
10
+ var y = [
11
11
  {
12
12
  value: "",
13
13
  label: "All statuses"
@@ -28,7 +28,7 @@ var v = [
28
28
  value: "REFUNDED",
29
29
  label: "Refunded"
30
30
  }
31
- ], y = {
31
+ ], b = {
32
32
  PENDING: "bg-surface-warning-muted text-text-warning",
33
33
  PROCESSING: "bg-surface-warning-muted text-text-warning",
34
34
  READY_TO_SHIP: "bg-surface-accent-muted text-text-accent",
@@ -39,13 +39,13 @@ var v = [
39
39
  FAILED: "bg-surface-danger-muted text-text-danger",
40
40
  RETURNED: "bg-surface-danger-muted text-text-danger",
41
41
  CANCELLED: "bg-surface-muted text-text-secondary"
42
- }, b = {
42
+ }, x = {
43
43
  OUT_OF_STOCK: "Out of stock",
44
44
  CANNOT_FULFILL: "Cannot fulfill",
45
45
  WRONG_ADDRESS: "Wrong address",
46
46
  OTHER: "Other"
47
- }, x = "\n query AdminPhysicalOrders($page: Int!, $limit: Int!, $status: OrderStatus, $search: String) {\n adminPhysicalOrders(page: $page, limit: $limit, status: $status, search: $search) {\n total\n orders {\n id\n status\n userId\n total\n currency\n createdAt\n fulfillment {\n status\n carrier\n trackingNumber\n trackingUrl\n }\n issueFlags {\n id\n category\n note\n status\n raisedByOrgId\n createdAt\n }\n }\n }\n }\n", S = "\n mutation AdminResolveOrderIssue($id: ID!) {\n resolveOrderIssueFlag(id: $id) {\n id\n status\n }\n }\n", C = 25;
48
- function w(e) {
47
+ }, S = "\n query AdminPhysicalOrders($page: Int!, $limit: Int!, $status: OrderStatus, $search: String) {\n adminPhysicalOrders(page: $page, limit: $limit, status: $status, search: $search) {\n total\n orders {\n id\n status\n userId\n total\n currency\n createdAt\n fulfillment {\n status\n carrier\n trackingNumber\n trackingUrl\n }\n issueFlags {\n id\n category\n note\n status\n raisedByOrgId\n createdAt\n }\n }\n }\n }\n", C = "\n mutation AdminResolveOrderIssue($id: ID!) {\n resolveOrderIssueFlag(id: $id) {\n id\n status\n }\n }\n", w = 25;
48
+ function T(e) {
49
49
  return new Date(e).toLocaleDateString("en-US", {
50
50
  year: "numeric",
51
51
  month: "short",
@@ -54,276 +54,286 @@ function w(e) {
54
54
  minute: "2-digit"
55
55
  });
56
56
  }
57
- var T = () => {
58
- let T = a(), { authToken: E, basePath: D } = e(), [O, k] = i([]), [A, j] = i(0), [M, N] = i(!1), [P, F] = i(null), [I, L] = i(0), [R, z] = i(""), [B, V] = i(""), [H, U] = i(null), W = n(async () => {
59
- N(!0), F(null);
57
+ var E = () => {
58
+ let E = a(), { authToken: D, basePath: O } = e(), [k, A] = i([]), [j, M] = i(0), [N, P] = i(!1), [F, I] = i(null), [L, R] = i(0), [z, B] = i(""), [V, H] = i(""), [U, W] = i(null), G = n(async () => {
59
+ P(!0), I(null);
60
60
  try {
61
- let e = await f({
61
+ let e = await p({
62
62
  gateway: "global",
63
- query: x,
63
+ query: S,
64
64
  variables: {
65
- page: I + 1,
66
- limit: C,
67
- status: R || void 0,
68
- search: B.trim() || void 0
65
+ page: L + 1,
66
+ limit: w,
67
+ status: z || void 0,
68
+ search: V.trim() || void 0
69
69
  },
70
- authToken: E || void 0
70
+ authToken: D || void 0
71
71
  });
72
72
  if (e.errors?.length) throw Error(e.errors[0]?.message ?? "Failed to load orders");
73
- j(e.data?.adminPhysicalOrders.total ?? 0), k(e.data?.adminPhysicalOrders.orders ?? []);
73
+ M(e.data?.adminPhysicalOrders.total ?? 0), A(e.data?.adminPhysicalOrders.orders ?? []);
74
74
  } catch (e) {
75
- F(e instanceof Error ? e.message : "Failed to load orders");
75
+ I(e instanceof Error ? e.message : "Failed to load orders");
76
76
  } finally {
77
- N(!1);
77
+ P(!1);
78
78
  }
79
79
  }, [
80
- E,
81
- I,
82
- R,
83
- B
80
+ D,
81
+ L,
82
+ z,
83
+ V
84
84
  ]);
85
85
  r(() => {
86
- W();
87
- }, [W]);
88
- let G = async (e) => {
89
- U(e);
86
+ G();
87
+ }, [G]);
88
+ let K = async (e) => {
89
+ W(e);
90
90
  try {
91
- await f({
91
+ await p({
92
92
  gateway: "global",
93
- query: S,
93
+ query: C,
94
94
  variables: { id: e },
95
- authToken: E || void 0
96
- }), await W();
95
+ authToken: D || void 0
96
+ }), await G();
97
97
  } catch (e) {
98
- F(e instanceof Error ? e.message : "Failed to resolve issue");
98
+ I(e instanceof Error ? e.message : "Failed to resolve issue");
99
99
  } finally {
100
- U(null);
100
+ W(null);
101
101
  }
102
102
  };
103
- return /* @__PURE__ */ h("div", {
103
+ return /* @__PURE__ */ g("div", {
104
104
  className: "min-h-screen bg-surface-default",
105
- children: [/* @__PURE__ */ m("header", {
105
+ children: [/* @__PURE__ */ h("header", {
106
106
  className: "border-b border-border-seam bg-surface-raised",
107
- children: /* @__PURE__ */ m("div", {
107
+ children: /* @__PURE__ */ h("div", {
108
108
  className: "mx-auto max-w-7xl px-6 py-4",
109
- children: /* @__PURE__ */ h("div", {
109
+ children: /* @__PURE__ */ g("div", {
110
110
  className: "flex items-center justify-between",
111
- children: [/* @__PURE__ */ h("div", {
111
+ children: [/* @__PURE__ */ g("div", {
112
112
  className: "flex items-center gap-3",
113
- children: [/* @__PURE__ */ h("button", {
113
+ children: [/* @__PURE__ */ g("button", {
114
114
  type: "button",
115
- onClick: () => T(`${D}/dashboard`),
115
+ onClick: () => E(`${O}/dashboard`),
116
116
  className: "inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary",
117
- children: [/* @__PURE__ */ m(o, { className: "size-4" }), "Back"]
118
- }), /* @__PURE__ */ h("div", {
117
+ children: [/* @__PURE__ */ h(o, { className: "size-4" }), "Back"]
118
+ }), /* @__PURE__ */ g("div", {
119
119
  className: "flex items-center gap-2",
120
120
  children: [
121
- /* @__PURE__ */ m(u, { className: "size-5 text-text-primary" }),
122
- /* @__PURE__ */ m("h1", {
121
+ /* @__PURE__ */ h(u, { className: "size-5 text-text-primary" }),
122
+ /* @__PURE__ */ h("h1", {
123
123
  className: "text-xl font-semibold text-text-primary",
124
124
  children: "Physical orders"
125
125
  }),
126
- /* @__PURE__ */ m("span", {
126
+ /* @__PURE__ */ h("span", {
127
127
  className: "rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent",
128
- children: A
128
+ children: j
129
129
  })
130
130
  ]
131
131
  })]
132
- }), /* @__PURE__ */ h("button", {
132
+ }), /* @__PURE__ */ g("button", {
133
133
  type: "button",
134
- onClick: () => void W(),
134
+ onClick: () => void G(),
135
135
  className: "inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover",
136
- disabled: M,
137
- children: [/* @__PURE__ */ m(d, { className: `size-4 ${M ? "animate-spin" : ""}` }), "Refresh"]
136
+ disabled: N,
137
+ children: [/* @__PURE__ */ h(d, { className: `size-4 ${N ? "animate-spin" : ""}` }), "Refresh"]
138
138
  })]
139
139
  })
140
140
  })
141
- }), /* @__PURE__ */ h("main", {
141
+ }), /* @__PURE__ */ g("main", {
142
142
  className: "mx-auto max-w-7xl p-6",
143
143
  children: [
144
- /* @__PURE__ */ m(_, {
144
+ /* @__PURE__ */ h(v, {
145
145
  className: "mb-4",
146
146
  children: "Payment/order status and Shiprocket fulfillment status for every physical order, plus any issue a seller has flagged (out of stock, cannot fulfill, wrong address). Read-only — cancellation and refunds still happen manually via the Shiprocket dashboard for now."
147
147
  }),
148
- /* @__PURE__ */ h("div", {
148
+ /* @__PURE__ */ g("div", {
149
149
  className: "mb-4 flex flex-col gap-3 sm:flex-row sm:items-center",
150
- children: [/* @__PURE__ */ m("select", {
150
+ children: [/* @__PURE__ */ h("select", {
151
151
  "aria-label": "Filter by status",
152
- value: R,
152
+ value: z,
153
153
  onChange: (e) => {
154
- z(e.target.value), L(0);
154
+ B(e.target.value), R(0);
155
155
  },
156
156
  className: "rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary",
157
- children: v.map((e) => /* @__PURE__ */ m("option", {
157
+ children: y.map((e) => /* @__PURE__ */ h("option", {
158
158
  value: e.value,
159
159
  children: e.label
160
160
  }, e.value))
161
- }), /* @__PURE__ */ m("input", {
161
+ }), /* @__PURE__ */ h("input", {
162
162
  type: "search",
163
163
  "aria-label": "Search by order ID, buyer, or tracking number",
164
164
  placeholder: "Search order ID, buyer, or tracking number…",
165
- value: B,
165
+ value: V,
166
166
  onChange: (e) => {
167
- V(e.target.value), L(0);
167
+ H(e.target.value), R(0);
168
168
  },
169
169
  className: "flex-1 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary"
170
170
  })]
171
171
  }),
172
- P && /* @__PURE__ */ m("div", {
172
+ F && /* @__PURE__ */ h("div", {
173
173
  role: "alert",
174
174
  className: "mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger",
175
- children: P
175
+ children: F
176
176
  }),
177
- M && O.length === 0 ? /* @__PURE__ */ m("output", {
177
+ N && k.length === 0 ? /* @__PURE__ */ h("output", {
178
178
  className: "block py-16 text-center text-text-secondary",
179
179
  children: "Loading orders…"
180
- }) : O.length === 0 ? /* @__PURE__ */ m(g, {
180
+ }) : k.length === 0 ? /* @__PURE__ */ h(_, {
181
181
  illustration: "empty-generic",
182
182
  title: "No physical orders",
183
183
  description: "Orders with a physical line item will show up here once customers make purchases."
184
- }) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("div", {
184
+ }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("div", {
185
185
  className: "overflow-hidden rounded-lg border border-border-seam",
186
- children: /* @__PURE__ */ h("table", {
186
+ children: /* @__PURE__ */ g("table", {
187
187
  className: "w-full text-sm",
188
- children: [/* @__PURE__ */ m("thead", {
188
+ children: [/* @__PURE__ */ h("thead", {
189
189
  className: "bg-surface-muted text-left text-xs uppercase tracking-wide text-text-secondary",
190
- children: /* @__PURE__ */ h("tr", { children: [
191
- /* @__PURE__ */ m("th", {
190
+ children: /* @__PURE__ */ g("tr", { children: [
191
+ /* @__PURE__ */ h("th", {
192
192
  className: "px-4 py-2",
193
193
  children: "Order"
194
194
  }),
195
- /* @__PURE__ */ m("th", {
195
+ /* @__PURE__ */ h("th", {
196
196
  className: "px-4 py-2",
197
197
  children: "Buyer"
198
198
  }),
199
- /* @__PURE__ */ m("th", {
199
+ /* @__PURE__ */ h("th", {
200
200
  className: "px-4 py-2 text-right",
201
201
  children: "Total"
202
202
  }),
203
- /* @__PURE__ */ m("th", {
203
+ /* @__PURE__ */ h("th", {
204
204
  className: "px-4 py-2",
205
205
  children: "Status"
206
206
  }),
207
- /* @__PURE__ */ m("th", {
207
+ /* @__PURE__ */ h("th", {
208
208
  className: "px-4 py-2",
209
209
  children: "Fulfillment"
210
210
  }),
211
- /* @__PURE__ */ m("th", {
211
+ /* @__PURE__ */ h("th", {
212
212
  className: "px-4 py-2",
213
213
  children: "Tracking"
214
214
  }),
215
- /* @__PURE__ */ m("th", {
215
+ /* @__PURE__ */ h("th", {
216
216
  className: "px-4 py-2",
217
217
  children: "Issue"
218
218
  }),
219
- /* @__PURE__ */ m("th", {
219
+ /* @__PURE__ */ h("th", {
220
220
  className: "px-4 py-2",
221
221
  children: "Placed"
222
222
  })
223
223
  ] })
224
- }), /* @__PURE__ */ m("tbody", {
224
+ }), /* @__PURE__ */ h("tbody", {
225
225
  className: "divide-y divide-border-seam bg-surface-raised",
226
- children: O.map((e) => {
226
+ children: k.map((e) => {
227
227
  let n = e.issueFlags.find((e) => e.status === "OPEN");
228
- return /* @__PURE__ */ h("tr", {
228
+ return /* @__PURE__ */ g("tr", {
229
229
  className: "text-text-primary align-top",
230
230
  children: [
231
- /* @__PURE__ */ m("td", {
231
+ /* @__PURE__ */ h("td", {
232
232
  className: "px-4 py-2 font-mono text-xs",
233
233
  children: e.id.slice(0, 8).toUpperCase()
234
234
  }),
235
- /* @__PURE__ */ h("td", {
235
+ /* @__PURE__ */ g("td", {
236
236
  className: "px-4 py-2 font-mono text-xs text-text-secondary",
237
237
  children: [e.userId.slice(0, 8), "…"]
238
238
  }),
239
- /* @__PURE__ */ m("td", {
239
+ /* @__PURE__ */ h("td", {
240
240
  className: "px-4 py-2 text-right tabular-nums",
241
241
  children: t(e.total, e.currency)
242
242
  }),
243
- /* @__PURE__ */ m("td", {
243
+ /* @__PURE__ */ h("td", {
244
244
  className: "px-4 py-2",
245
- children: /* @__PURE__ */ m("span", {
245
+ children: /* @__PURE__ */ h("span", {
246
246
  className: "rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent",
247
247
  children: e.status
248
248
  })
249
249
  }),
250
- /* @__PURE__ */ m("td", {
250
+ /* @__PURE__ */ h("td", {
251
251
  className: "px-4 py-2",
252
- children: e.fulfillment ? /* @__PURE__ */ m("span", {
253
- className: `rounded-full px-2 py-0.5 text-xs font-medium ${y[e.fulfillment.status]}`,
254
- children: e.fulfillment.status.replace(/_/g, " ")
255
- }) : /* @__PURE__ */ m("span", {
256
- className: "rounded-full bg-surface-danger-muted px-2 py-0.5 text-xs font-medium text-text-danger",
257
- title: "No fulfillment record — the post-payment fulfillment step never ran for this order",
258
- children: "Not started"
252
+ children: /* @__PURE__ */ g("div", {
253
+ className: "flex items-center gap-1.5",
254
+ children: [e.fulfillment ? /* @__PURE__ */ h("span", {
255
+ className: `rounded-full px-2 py-0.5 text-xs font-medium ${b[e.fulfillment.status]}`,
256
+ children: e.fulfillment.status.replace(/_/g, " ")
257
+ }) : /* @__PURE__ */ h("span", {
258
+ className: "rounded-full bg-surface-danger-muted px-2 py-0.5 text-xs font-medium text-text-danger",
259
+ title: "No fulfillment record — the post-payment fulfillment step never ran for this order",
260
+ children: "Not started"
261
+ }), /* @__PURE__ */ h("button", {
262
+ type: "button",
263
+ title: "View fulfillment logs for this order",
264
+ onClick: () => E(`${O}/fulfillment-logs?orderId=${e.id}`),
265
+ className: "text-text-muted hover:text-text-primary",
266
+ children: /* @__PURE__ */ h(f, { className: "size-3.5" })
267
+ })]
259
268
  })
260
269
  }),
261
- /* @__PURE__ */ m("td", {
270
+ /* @__PURE__ */ h("td", {
262
271
  className: "px-4 py-2 text-xs",
263
- children: e.fulfillment?.trackingNumber ? /* @__PURE__ */ h("a", {
272
+ children: e.fulfillment?.trackingNumber ? /* @__PURE__ */ g("a", {
264
273
  href: e.fulfillment.trackingUrl ?? "#",
265
274
  target: "_blank",
266
275
  rel: "noreferrer",
267
276
  className: "inline-flex items-center gap-1 text-text-accent hover:underline",
268
- children: [e.fulfillment.carrier ?? "Carrier", /* @__PURE__ */ m(s, { className: "size-3" })]
269
- }) : /* @__PURE__ */ m("span", {
277
+ children: [e.fulfillment.carrier ?? "Carrier", /* @__PURE__ */ h(s, { className: "size-3" })]
278
+ }) : /* @__PURE__ */ h("span", {
270
279
  className: "text-text-muted",
271
280
  children: "—"
272
281
  })
273
282
  }),
274
- /* @__PURE__ */ m("td", {
283
+ /* @__PURE__ */ h("td", {
275
284
  className: "px-4 py-2",
276
- children: n ? /* @__PURE__ */ h("div", {
285
+ children: n ? /* @__PURE__ */ g("div", {
277
286
  className: "flex flex-col items-start gap-1",
278
- children: [/* @__PURE__ */ h("span", {
287
+ children: [/* @__PURE__ */ g("span", {
279
288
  title: n.note ?? void 0,
280
289
  className: "flex items-center gap-1 rounded-full bg-surface-warning-muted px-2 py-0.5 text-xs font-medium text-text-warning",
281
- children: [/* @__PURE__ */ m(c, { className: "size-3" }), b[n.category]]
282
- }), /* @__PURE__ */ m("button", {
290
+ children: [/* @__PURE__ */ h(c, { className: "size-3" }), x[n.category]]
291
+ }), /* @__PURE__ */ h("button", {
283
292
  type: "button",
284
- onClick: () => void G(n.id),
285
- disabled: H === n.id,
293
+ onClick: () => void K(n.id),
294
+ disabled: U === n.id,
286
295
  className: "text-xs font-medium text-text-secondary underline hover:text-text-primary disabled:opacity-50",
287
- children: H === n.id ? /* @__PURE__ */ m(l, { className: "size-3 animate-spin" }) : "Mark resolved"
296
+ children: U === n.id ? /* @__PURE__ */ h(l, { className: "size-3 animate-spin" }) : "Mark resolved"
288
297
  })]
289
- }) : /* @__PURE__ */ m("span", {
298
+ }) : /* @__PURE__ */ h("span", {
290
299
  className: "text-text-muted",
291
300
  children: "—"
292
301
  })
293
302
  }),
294
- /* @__PURE__ */ m("td", {
303
+ /* @__PURE__ */ h("td", {
295
304
  className: "px-4 py-2 text-xs text-text-secondary whitespace-nowrap",
296
- children: w(e.createdAt)
305
+ children: T(e.createdAt)
297
306
  })
298
307
  ]
299
308
  }, e.id);
300
309
  })
301
310
  })]
302
311
  })
303
- }), A > C && /* @__PURE__ */ h("div", {
312
+ }), j > w && /* @__PURE__ */ g("div", {
304
313
  className: "mt-4 flex items-center justify-between text-sm",
305
- children: [/* @__PURE__ */ h("span", {
314
+ children: [/* @__PURE__ */ g("span", {
306
315
  className: "text-text-secondary",
307
316
  children: [
308
317
  "Showing ",
309
- I * C + 1,
318
+ L * w + 1,
310
319
  "–",
311
- Math.min((I + 1) * C, A),
312
- " of ",
313
- A
320
+ Math.min((L + 1) * w, j),
321
+ " of",
322
+ " ",
323
+ j
314
324
  ]
315
- }), /* @__PURE__ */ h("div", {
325
+ }), /* @__PURE__ */ g("div", {
316
326
  className: "flex items-center gap-2",
317
- children: [/* @__PURE__ */ m("button", {
327
+ children: [/* @__PURE__ */ h("button", {
318
328
  type: "button",
319
- disabled: I === 0,
320
- onClick: () => L((e) => e - 1),
329
+ disabled: L === 0,
330
+ onClick: () => R((e) => e - 1),
321
331
  className: "rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40",
322
332
  children: "Previous"
323
- }), /* @__PURE__ */ m("button", {
333
+ }), /* @__PURE__ */ h("button", {
324
334
  type: "button",
325
- disabled: (I + 1) * C >= A,
326
- onClick: () => L((e) => e + 1),
335
+ disabled: (L + 1) * w >= j,
336
+ onClick: () => R((e) => e + 1),
327
337
  className: "rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40",
328
338
  children: "Next"
329
339
  })]
@@ -334,6 +344,6 @@ var T = () => {
334
344
  });
335
345
  };
336
346
  //#endregion
337
- export { T as AdminOrdersPage };
347
+ export { E as AdminOrdersPage };
338
348
 
339
349
  //# sourceMappingURL=AdminOrdersPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminOrdersPage.js","names":[],"sources":["../../src/pages/AdminOrdersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { ArrowLeft, RefreshCw, Package, ExternalLink, Flag, Loader2 } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate } from 'react-router';\nimport { useStore } from '../providers/StoreProvider';\nimport { PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { formatPrice } from '../utils';\n\ntype OrderStatus = 'PENDING' | 'PROCESSED' | 'FAILED' | 'REFUNDED';\ntype FulfillmentStatus =\n | 'PENDING'\n | 'PROCESSING'\n | 'READY_TO_SHIP'\n | 'SHIPPED'\n | 'IN_TRANSIT'\n | 'OUT_FOR_DELIVERY'\n | 'DELIVERED'\n | 'FAILED'\n | 'RETURNED'\n | 'CANCELLED';\ntype IssueCategory = 'OUT_OF_STOCK' | 'CANNOT_FULFILL' | 'WRONG_ADDRESS' | 'OTHER';\n\ninterface IssueFlag {\n id: string;\n category: IssueCategory;\n note: string | null;\n status: 'OPEN' | 'RESOLVED';\n raisedByOrgId: string;\n createdAt: string;\n}\n\ninterface Fulfillment {\n status: FulfillmentStatus;\n carrier: string | null;\n trackingNumber: string | null;\n trackingUrl: string | null;\n}\n\ninterface AdminOrder {\n id: string;\n status: OrderStatus;\n userId: string;\n total: number;\n currency: string;\n createdAt: string;\n fulfillment: Fulfillment | null;\n issueFlags: IssueFlag[];\n}\n\nconst ORDER_STATUS_OPTIONS: { value: OrderStatus | ''; label: string }[] = [\n { value: '', label: 'All statuses' },\n { value: 'PENDING', label: 'Pending' },\n { value: 'PROCESSED', label: 'Processed' },\n { value: 'FAILED', label: 'Failed' },\n { value: 'REFUNDED', label: 'Refunded' },\n];\n\nconst FULFILLMENT_STYLES: Record<FulfillmentStatus, string> = {\n PENDING: 'bg-surface-warning-muted text-text-warning',\n PROCESSING: 'bg-surface-warning-muted text-text-warning',\n READY_TO_SHIP: 'bg-surface-accent-muted text-text-accent',\n SHIPPED: 'bg-surface-accent-muted text-text-accent',\n IN_TRANSIT: 'bg-surface-accent-muted text-text-accent',\n OUT_FOR_DELIVERY: 'bg-surface-accent-muted text-text-accent',\n DELIVERED: 'bg-surface-success-muted text-text-success',\n FAILED: 'bg-surface-danger-muted text-text-danger',\n RETURNED: 'bg-surface-danger-muted text-text-danger',\n CANCELLED: 'bg-surface-muted text-text-secondary',\n};\n\nconst ISSUE_CATEGORY_LABELS: Record<IssueCategory, string> = {\n OUT_OF_STOCK: 'Out of stock',\n CANNOT_FULFILL: 'Cannot fulfill',\n WRONG_ADDRESS: 'Wrong address',\n OTHER: 'Other',\n};\n\nconst ADMIN_PHYSICAL_ORDERS_QUERY = /* GraphQL */ `\n query AdminPhysicalOrders($page: Int!, $limit: Int!, $status: OrderStatus, $search: String) {\n adminPhysicalOrders(page: $page, limit: $limit, status: $status, search: $search) {\n total\n orders {\n id\n status\n userId\n total\n currency\n createdAt\n fulfillment {\n status\n carrier\n trackingNumber\n trackingUrl\n }\n issueFlags {\n id\n category\n note\n status\n raisedByOrgId\n createdAt\n }\n }\n }\n }\n`;\n\nconst RESOLVE_ORDER_ISSUE_MUTATION = /* GraphQL */ `\n mutation AdminResolveOrderIssue($id: ID!) {\n resolveOrderIssueFlag(id: $id) {\n id\n status\n }\n }\n`;\n\nconst PAGE_SIZE = 25;\n\nfunction formatDate(iso: string): string {\n return new Date(iso).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\n/**\n * Admin-only visibility into physical (fulfillment-tracked) orders —\n * order/payment status, carrier/tracking, and any seller-reported issue\n * flags. Read-only for now: no cancel or refund action here (differs\n * between credits and Razorpay, waits on a proper store refund flow —\n * see BOFF-7192). Cancellation stays manual via the Shiprocket dashboard.\n */\nexport const AdminOrdersPage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n\n const [orders, setOrders] = useState<AdminOrder[]>([]);\n const [total, setTotal] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [page, setPage] = useState(0);\n const [statusFilter, setStatusFilter] = useState<OrderStatus | ''>('');\n const [search, setSearch] = useState('');\n const [resolvingFlagId, setResolvingFlagId] = useState<string | null>(null);\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n adminPhysicalOrders: { total: number; orders: AdminOrder[] };\n }>({\n gateway: 'global',\n query: ADMIN_PHYSICAL_ORDERS_QUERY,\n variables: {\n page: page + 1,\n limit: PAGE_SIZE,\n status: statusFilter || undefined,\n search: search.trim() || undefined,\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load orders');\n }\n setTotal(result.data?.adminPhysicalOrders.total ?? 0);\n setOrders(result.data?.adminPhysicalOrders.orders ?? []);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load orders');\n } finally {\n setLoading(false);\n }\n }, [authToken, page, statusFilter, search]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const resolveFlag = async (flagId: string) => {\n setResolvingFlagId(flagId);\n try {\n await graphqlFetch({\n gateway: 'global',\n query: RESOLVE_ORDER_ISSUE_MUTATION,\n variables: { id: flagId },\n authToken: authToken || undefined,\n });\n await load();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to resolve issue');\n } finally {\n setResolvingFlagId(null);\n }\n };\n\n return (\n <div className=\"min-h-screen bg-surface-default\">\n <header className=\"border-b border-border-seam bg-surface-raised\">\n <div className=\"mx-auto max-w-7xl px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n <div className=\"flex items-center gap-2\">\n <Package className=\"size-5 text-text-primary\" />\n <h1 className=\"text-xl font-semibold text-text-primary\">Physical orders</h1>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {total}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => void load()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-7xl p-6\">\n <PagePurpose className=\"mb-4\">\n Payment/order status and Shiprocket fulfillment status for every physical order, plus any\n issue a seller has flagged (out of stock, cannot fulfill, wrong address). Read-only —\n cancellation and refunds still happen manually via the Shiprocket dashboard for now.\n </PagePurpose>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <select\n aria-label=\"Filter by status\"\n value={statusFilter}\n onChange={(e) => {\n setStatusFilter(e.target.value as OrderStatus | '');\n setPage(0);\n }}\n className=\"rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary\"\n >\n {ORDER_STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <input\n type=\"search\"\n aria-label=\"Search by order ID, buyer, or tracking number\"\n placeholder=\"Search order ID, buyer, or tracking number…\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPage(0);\n }}\n className=\"flex-1 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary\"\n />\n </div>\n\n {error && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading && orders.length === 0 ? (\n <output className=\"block py-16 text-center text-text-secondary\">Loading orders…</output>\n ) : orders.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No physical orders\"\n description=\"Orders with a physical line item will show up here once customers make purchases.\"\n />\n ) : (\n <>\n <div className=\"overflow-hidden rounded-lg border border-border-seam\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-surface-muted text-left text-xs uppercase tracking-wide text-text-secondary\">\n <tr>\n <th className=\"px-4 py-2\">Order</th>\n <th className=\"px-4 py-2\">Buyer</th>\n <th className=\"px-4 py-2 text-right\">Total</th>\n <th className=\"px-4 py-2\">Status</th>\n <th className=\"px-4 py-2\">Fulfillment</th>\n <th className=\"px-4 py-2\">Tracking</th>\n <th className=\"px-4 py-2\">Issue</th>\n <th className=\"px-4 py-2\">Placed</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam bg-surface-raised\">\n {orders.map((order) => {\n const openFlag = order.issueFlags.find((f) => f.status === 'OPEN');\n return (\n <tr key={order.id} className=\"text-text-primary align-top\">\n <td className=\"px-4 py-2 font-mono text-xs\">\n {order.id.slice(0, 8).toUpperCase()}\n </td>\n <td className=\"px-4 py-2 font-mono text-xs text-text-secondary\">\n {order.userId.slice(0, 8)}…\n </td>\n <td className=\"px-4 py-2 text-right tabular-nums\">\n {formatPrice(order.total, order.currency)}\n </td>\n <td className=\"px-4 py-2\">\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {order.status}\n </span>\n </td>\n <td className=\"px-4 py-2\">\n {order.fulfillment ? (\n <span\n className={`rounded-full px-2 py-0.5 text-xs font-medium ${FULFILLMENT_STYLES[order.fulfillment.status]}`}\n >\n {order.fulfillment.status.replace(/_/g, ' ')}\n </span>\n ) : (\n <span\n className=\"rounded-full bg-surface-danger-muted px-2 py-0.5 text-xs font-medium text-text-danger\"\n title=\"No fulfillment record — the post-payment fulfillment step never ran for this order\"\n >\n Not started\n </span>\n )}\n </td>\n <td className=\"px-4 py-2 text-xs\">\n {order.fulfillment?.trackingNumber ? (\n <a\n href={order.fulfillment.trackingUrl ?? '#'}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 text-text-accent hover:underline\"\n >\n {order.fulfillment.carrier ?? 'Carrier'}\n <ExternalLink className=\"size-3\" />\n </a>\n ) : (\n <span className=\"text-text-muted\">—</span>\n )}\n </td>\n <td className=\"px-4 py-2\">\n {openFlag ? (\n <div className=\"flex flex-col items-start gap-1\">\n <span\n title={openFlag.note ?? undefined}\n className=\"flex items-center gap-1 rounded-full bg-surface-warning-muted px-2 py-0.5 text-xs font-medium text-text-warning\"\n >\n <Flag className=\"size-3\" />\n {ISSUE_CATEGORY_LABELS[openFlag.category]}\n </span>\n <button\n type=\"button\"\n onClick={() => void resolveFlag(openFlag.id)}\n disabled={resolvingFlagId === openFlag.id}\n className=\"text-xs font-medium text-text-secondary underline hover:text-text-primary disabled:opacity-50\"\n >\n {resolvingFlagId === openFlag.id ? (\n <Loader2 className=\"size-3 animate-spin\" />\n ) : (\n 'Mark resolved'\n )}\n </button>\n </div>\n ) : (\n <span className=\"text-text-muted\">—</span>\n )}\n </td>\n <td className=\"px-4 py-2 text-xs text-text-secondary whitespace-nowrap\">\n {formatDate(order.createdAt)}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {total > PAGE_SIZE && (\n <div className=\"mt-4 flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">\n Showing {page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, total)} of {total}\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => setPage((p) => p - 1)}\n className=\"rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n disabled={(page + 1) * PAGE_SIZE >= total}\n onClick={() => setPage((p) => p + 1)}\n className=\"rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40\"\n >\n Next\n </button>\n </div>\n </div>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminOrdersPage.js","names":[],"sources":["../../src/pages/AdminOrdersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport {\n ArrowLeft,\n RefreshCw,\n Package,\n ExternalLink,\n Flag,\n Loader2,\n ScrollText,\n} from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate } from 'react-router';\nimport { useStore } from '../providers/StoreProvider';\nimport { PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { formatPrice } from '../utils';\n\ntype OrderStatus = 'PENDING' | 'PROCESSED' | 'FAILED' | 'REFUNDED';\ntype FulfillmentStatus =\n | 'PENDING'\n | 'PROCESSING'\n | 'READY_TO_SHIP'\n | 'SHIPPED'\n | 'IN_TRANSIT'\n | 'OUT_FOR_DELIVERY'\n | 'DELIVERED'\n | 'FAILED'\n | 'RETURNED'\n | 'CANCELLED';\ntype IssueCategory = 'OUT_OF_STOCK' | 'CANNOT_FULFILL' | 'WRONG_ADDRESS' | 'OTHER';\n\ninterface IssueFlag {\n id: string;\n category: IssueCategory;\n note: string | null;\n status: 'OPEN' | 'RESOLVED';\n raisedByOrgId: string;\n createdAt: string;\n}\n\ninterface Fulfillment {\n status: FulfillmentStatus;\n carrier: string | null;\n trackingNumber: string | null;\n trackingUrl: string | null;\n}\n\ninterface AdminOrder {\n id: string;\n status: OrderStatus;\n userId: string;\n total: number;\n currency: string;\n createdAt: string;\n fulfillment: Fulfillment | null;\n issueFlags: IssueFlag[];\n}\n\nconst ORDER_STATUS_OPTIONS: { value: OrderStatus | ''; label: string }[] = [\n { value: '', label: 'All statuses' },\n { value: 'PENDING', label: 'Pending' },\n { value: 'PROCESSED', label: 'Processed' },\n { value: 'FAILED', label: 'Failed' },\n { value: 'REFUNDED', label: 'Refunded' },\n];\n\nconst FULFILLMENT_STYLES: Record<FulfillmentStatus, string> = {\n PENDING: 'bg-surface-warning-muted text-text-warning',\n PROCESSING: 'bg-surface-warning-muted text-text-warning',\n READY_TO_SHIP: 'bg-surface-accent-muted text-text-accent',\n SHIPPED: 'bg-surface-accent-muted text-text-accent',\n IN_TRANSIT: 'bg-surface-accent-muted text-text-accent',\n OUT_FOR_DELIVERY: 'bg-surface-accent-muted text-text-accent',\n DELIVERED: 'bg-surface-success-muted text-text-success',\n FAILED: 'bg-surface-danger-muted text-text-danger',\n RETURNED: 'bg-surface-danger-muted text-text-danger',\n CANCELLED: 'bg-surface-muted text-text-secondary',\n};\n\nconst ISSUE_CATEGORY_LABELS: Record<IssueCategory, string> = {\n OUT_OF_STOCK: 'Out of stock',\n CANNOT_FULFILL: 'Cannot fulfill',\n WRONG_ADDRESS: 'Wrong address',\n OTHER: 'Other',\n};\n\nconst ADMIN_PHYSICAL_ORDERS_QUERY = /* GraphQL */ `\n query AdminPhysicalOrders($page: Int!, $limit: Int!, $status: OrderStatus, $search: String) {\n adminPhysicalOrders(page: $page, limit: $limit, status: $status, search: $search) {\n total\n orders {\n id\n status\n userId\n total\n currency\n createdAt\n fulfillment {\n status\n carrier\n trackingNumber\n trackingUrl\n }\n issueFlags {\n id\n category\n note\n status\n raisedByOrgId\n createdAt\n }\n }\n }\n }\n`;\n\nconst RESOLVE_ORDER_ISSUE_MUTATION = /* GraphQL */ `\n mutation AdminResolveOrderIssue($id: ID!) {\n resolveOrderIssueFlag(id: $id) {\n id\n status\n }\n }\n`;\n\nconst PAGE_SIZE = 25;\n\nfunction formatDate(iso: string): string {\n return new Date(iso).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\n/**\n * Admin-only visibility into physical (fulfillment-tracked) orders —\n * order/payment status, carrier/tracking, and any seller-reported issue\n * flags. Read-only for now: no cancel or refund action here (differs\n * between credits and Razorpay, waits on a proper store refund flow —\n * see BOFF-7192). Cancellation stays manual via the Shiprocket dashboard.\n */\nexport const AdminOrdersPage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n\n const [orders, setOrders] = useState<AdminOrder[]>([]);\n const [total, setTotal] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [page, setPage] = useState(0);\n const [statusFilter, setStatusFilter] = useState<OrderStatus | ''>('');\n const [search, setSearch] = useState('');\n const [resolvingFlagId, setResolvingFlagId] = useState<string | null>(null);\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n adminPhysicalOrders: { total: number; orders: AdminOrder[] };\n }>({\n gateway: 'global',\n query: ADMIN_PHYSICAL_ORDERS_QUERY,\n variables: {\n page: page + 1,\n limit: PAGE_SIZE,\n status: statusFilter || undefined,\n search: search.trim() || undefined,\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load orders');\n }\n setTotal(result.data?.adminPhysicalOrders.total ?? 0);\n setOrders(result.data?.adminPhysicalOrders.orders ?? []);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load orders');\n } finally {\n setLoading(false);\n }\n }, [authToken, page, statusFilter, search]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const resolveFlag = async (flagId: string) => {\n setResolvingFlagId(flagId);\n try {\n await graphqlFetch({\n gateway: 'global',\n query: RESOLVE_ORDER_ISSUE_MUTATION,\n variables: { id: flagId },\n authToken: authToken || undefined,\n });\n await load();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to resolve issue');\n } finally {\n setResolvingFlagId(null);\n }\n };\n\n return (\n <div className=\"min-h-screen bg-surface-default\">\n <header className=\"border-b border-border-seam bg-surface-raised\">\n <div className=\"mx-auto max-w-7xl px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n <div className=\"flex items-center gap-2\">\n <Package className=\"size-5 text-text-primary\" />\n <h1 className=\"text-xl font-semibold text-text-primary\">Physical orders</h1>\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {total}\n </span>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => void load()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-7xl p-6\">\n <PagePurpose className=\"mb-4\">\n Payment/order status and Shiprocket fulfillment status for every physical order, plus any\n issue a seller has flagged (out of stock, cannot fulfill, wrong address). Read-only —\n cancellation and refunds still happen manually via the Shiprocket dashboard for now.\n </PagePurpose>\n\n <div className=\"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <select\n aria-label=\"Filter by status\"\n value={statusFilter}\n onChange={(e) => {\n setStatusFilter(e.target.value as OrderStatus | '');\n setPage(0);\n }}\n className=\"rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary\"\n >\n {ORDER_STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <input\n type=\"search\"\n aria-label=\"Search by order ID, buyer, or tracking number\"\n placeholder=\"Search order ID, buyer, or tracking number…\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPage(0);\n }}\n className=\"flex-1 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary\"\n />\n </div>\n\n {error && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading && orders.length === 0 ? (\n <output className=\"block py-16 text-center text-text-secondary\">Loading orders…</output>\n ) : orders.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No physical orders\"\n description=\"Orders with a physical line item will show up here once customers make purchases.\"\n />\n ) : (\n <>\n <div className=\"overflow-hidden rounded-lg border border-border-seam\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-surface-muted text-left text-xs uppercase tracking-wide text-text-secondary\">\n <tr>\n <th className=\"px-4 py-2\">Order</th>\n <th className=\"px-4 py-2\">Buyer</th>\n <th className=\"px-4 py-2 text-right\">Total</th>\n <th className=\"px-4 py-2\">Status</th>\n <th className=\"px-4 py-2\">Fulfillment</th>\n <th className=\"px-4 py-2\">Tracking</th>\n <th className=\"px-4 py-2\">Issue</th>\n <th className=\"px-4 py-2\">Placed</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-seam bg-surface-raised\">\n {orders.map((order) => {\n const openFlag = order.issueFlags.find((f) => f.status === 'OPEN');\n return (\n <tr key={order.id} className=\"text-text-primary align-top\">\n <td className=\"px-4 py-2 font-mono text-xs\">\n {order.id.slice(0, 8).toUpperCase()}\n </td>\n <td className=\"px-4 py-2 font-mono text-xs text-text-secondary\">\n {order.userId.slice(0, 8)}…\n </td>\n <td className=\"px-4 py-2 text-right tabular-nums\">\n {formatPrice(order.total, order.currency)}\n </td>\n <td className=\"px-4 py-2\">\n <span className=\"rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent\">\n {order.status}\n </span>\n </td>\n <td className=\"px-4 py-2\">\n <div className=\"flex items-center gap-1.5\">\n {order.fulfillment ? (\n <span\n className={`rounded-full px-2 py-0.5 text-xs font-medium ${FULFILLMENT_STYLES[order.fulfillment.status]}`}\n >\n {order.fulfillment.status.replace(/_/g, ' ')}\n </span>\n ) : (\n <span\n className=\"rounded-full bg-surface-danger-muted px-2 py-0.5 text-xs font-medium text-text-danger\"\n title=\"No fulfillment record — the post-payment fulfillment step never ran for this order\"\n >\n Not started\n </span>\n )}\n <button\n type=\"button\"\n title=\"View fulfillment logs for this order\"\n onClick={() =>\n navigate(`${basePath}/fulfillment-logs?orderId=${order.id}`)\n }\n className=\"text-text-muted hover:text-text-primary\"\n >\n <ScrollText className=\"size-3.5\" />\n </button>\n </div>\n </td>\n <td className=\"px-4 py-2 text-xs\">\n {order.fulfillment?.trackingNumber ? (\n <a\n href={order.fulfillment.trackingUrl ?? '#'}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 text-text-accent hover:underline\"\n >\n {order.fulfillment.carrier ?? 'Carrier'}\n <ExternalLink className=\"size-3\" />\n </a>\n ) : (\n <span className=\"text-text-muted\">—</span>\n )}\n </td>\n <td className=\"px-4 py-2\">\n {openFlag ? (\n <div className=\"flex flex-col items-start gap-1\">\n <span\n title={openFlag.note ?? undefined}\n className=\"flex items-center gap-1 rounded-full bg-surface-warning-muted px-2 py-0.5 text-xs font-medium text-text-warning\"\n >\n <Flag className=\"size-3\" />\n {ISSUE_CATEGORY_LABELS[openFlag.category]}\n </span>\n <button\n type=\"button\"\n onClick={() => void resolveFlag(openFlag.id)}\n disabled={resolvingFlagId === openFlag.id}\n className=\"text-xs font-medium text-text-secondary underline hover:text-text-primary disabled:opacity-50\"\n >\n {resolvingFlagId === openFlag.id ? (\n <Loader2 className=\"size-3 animate-spin\" />\n ) : (\n 'Mark resolved'\n )}\n </button>\n </div>\n ) : (\n <span className=\"text-text-muted\">—</span>\n )}\n </td>\n <td className=\"px-4 py-2 text-xs text-text-secondary whitespace-nowrap\">\n {formatDate(order.createdAt)}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {total > PAGE_SIZE && (\n <div className=\"mt-4 flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">\n Showing {page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, total)} of{' '}\n {total}\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => setPage((p) => p - 1)}\n className=\"rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40\"\n >\n Previous\n </button>\n <button\n type=\"button\"\n disabled={(page + 1) * PAGE_SIZE >= total}\n onClick={() => setPage((p) => p + 1)}\n className=\"rounded-md border border-border-default px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-surface-hover disabled:opacity-40\"\n >\n Next\n </button>\n </div>\n </div>\n )}\n </>\n )}\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-store",
3
- "version": "2026.915.1",
3
+ "version": "2026.915.2",
4
4
  "description": "Store microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [