@burdenoff/microfe-store 2026.714.5 → 2026.714.6

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.
@@ -8,7 +8,7 @@ import { jsx as _, jsxs as v } from "react/jsx-runtime";
8
8
  import { useNavigate as se } from "react-router-dom";
9
9
  import { IllustratedEmptyState as y, PagePurpose as ce } from "@burdenoff/fe-libs/ui";
10
10
  //#region src/pages/AdminSubmissionsQueuePage.tsx
11
- var le = "\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendingReviewProducts(limit: $limit, offset: $offset) {\n totalCount\n products {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n }\n", ue = "\n query AdminProducts($limit: Int, $offset: Int, $status: ProductStatus) {\n products(filter: { status: $status }, limit: $limit, offset: $offset) {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n", de = "\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n", fe = "\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n", pe = "\n query AdminAppPackageUrl($id: ID!) {\n application(id: $id) {\n id\n versions(first: 1) {\n edges {\n node {\n packageUrl\n }\n }\n }\n }\n }\n", me = "\n query AdminPendingVersionApps($limit: Int, $offset: Int) {\n applicationsWithPendingVersions(limit: $limit, offset: $offset) {\n totalCount\n edges {\n node {\n id\n name\n slug\n iconUrl\n shortDescription\n description\n versions(first: 5) {\n edges {\n node {\n id\n version\n status\n releaseNotes\n packageUrl\n packageSize\n isLatest\n reviewNotes\n manifest\n createdAt\n }\n }\n }\n }\n }\n }\n }\n", he = "\n mutation AdminApproveApplicationVersion($id: ID!, $notes: String) {\n approveApplicationVersion(id: $id, notes: $notes) {\n id\n status\n }\n }\n", ge = "\n mutation AdminRejectApplicationVersion($id: ID!, $reason: String!) {\n rejectApplicationVersion(id: $id, reason: $reason) {\n id\n status\n }\n }\n", _e = [
11
+ var le = "\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendingReviewProducts(limit: $limit, offset: $offset) {\n totalCount\n products {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n }\n", ue = "\n query AdminProducts($limit: Int, $offset: Int, $status: ProductStatus) {\n products(filter: { status: $status }, limit: $limit, offset: $offset) {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n", de = "\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n", fe = "\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n", pe = "\n query AdminAppPackageUrl($id: ID!) {\n application(id: $id) {\n id\n versions(first: 1) {\n edges {\n node {\n id\n packageUrl\n }\n }\n }\n }\n }\n", me = "\n mutation RefreshApplicationVersionPackageUrl($id: ID!) {\n refreshApplicationVersionPackageUrl(id: $id)\n }\n", he = "\n query AdminPendingVersionApps($limit: Int, $offset: Int) {\n applicationsWithPendingVersions(limit: $limit, offset: $offset) {\n totalCount\n edges {\n node {\n id\n name\n slug\n iconUrl\n shortDescription\n description\n versions(first: 5) {\n edges {\n node {\n id\n version\n status\n releaseNotes\n packageUrl\n packageSize\n isLatest\n reviewNotes\n manifest\n createdAt\n }\n }\n }\n }\n }\n }\n }\n", ge = "\n mutation AdminApproveApplicationVersion($id: ID!, $notes: String) {\n approveApplicationVersion(id: $id, notes: $notes) {\n id\n status\n }\n }\n", _e = "\n mutation AdminRejectApplicationVersion($id: ID!, $reason: String!) {\n rejectApplicationVersion(id: $id, reason: $reason) {\n id\n status\n }\n }\n", ve = [
12
12
  {
13
13
  label: "Pending review",
14
14
  value: "PENDING_REVIEW"
@@ -46,10 +46,10 @@ var le = "\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pend
46
46
  "DATASINK",
47
47
  "CONSOLE"
48
48
  ]);
49
- function ve(e) {
49
+ function ye(e) {
50
50
  return b[e] ?? "bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]";
51
51
  }
52
- function ye(e) {
52
+ function be(e) {
53
53
  return x[e] ?? "bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]";
54
54
  }
55
55
  function C(e) {
@@ -62,12 +62,12 @@ function C(e) {
62
62
  }) : "—";
63
63
  }
64
64
  var w = () => {
65
- let b = se(), { authToken: x, basePath: w } = e(), [T, E] = a([]), [D, O] = a(0), [k, A] = a(!1), [j, M] = a(null), [N, P] = a(null), [F, be] = a("PENDING_REVIEW"), [xe, I] = a(null), [L, R] = a(""), [z, B] = a(null), [V, H] = a(null), [U, Se] = a([]), [W, Ce] = a(0), [G, K] = a(null), [q, J] = a(null), [Y, X] = a(""), [we, Z] = a(null), [Te, Ee] = a({}), Q = r(async () => {
65
+ let b = se(), { authToken: x, basePath: w } = e(), [T, E] = a([]), [D, O] = a(0), [k, A] = a(!1), [j, M] = a(null), [N, P] = a(null), [F, xe] = a("PENDING_REVIEW"), [Se, I] = a(null), [L, R] = a(""), [z, B] = a(null), [V, H] = a(null), [U, Ce] = a([]), [we, Te] = a(0), [W, G] = a(null), [Ee, K] = a(null), [q, J] = a(""), [De, Y] = a(null), [Oe, ke] = a({}), [X, Z] = a(null), Q = r(async () => {
66
66
  A(!0), M(null);
67
67
  try {
68
68
  let e = await g({
69
69
  gateway: "global",
70
- query: me,
70
+ query: he,
71
71
  variables: {
72
72
  limit: 50,
73
73
  offset: 0
@@ -75,18 +75,18 @@ var w = () => {
75
75
  authToken: x || void 0
76
76
  });
77
77
  if (e.errors?.length) throw Error(e.errors[0]?.message ?? "Failed to load version updates");
78
- Se((e.data?.applicationsWithPendingVersions.edges ?? []).map((e) => e.node)), Ce(e.data?.applicationsWithPendingVersions.totalCount ?? 0);
78
+ Ce((e.data?.applicationsWithPendingVersions.edges ?? []).map((e) => e.node)), Te(e.data?.applicationsWithPendingVersions.totalCount ?? 0);
79
79
  } catch (e) {
80
80
  M(e instanceof Error ? e.message : "Failed to load version updates");
81
81
  } finally {
82
82
  A(!1);
83
83
  }
84
- }, [x]), De = async (e, t, n) => {
85
- K(e), M(null);
84
+ }, [x]), Ae = async (e, t, n) => {
85
+ G(e), M(null);
86
86
  try {
87
87
  let t = await g({
88
88
  gateway: "global",
89
- query: he,
89
+ query: ge,
90
90
  variables: {
91
91
  id: e,
92
92
  notes: n || null
@@ -98,18 +98,18 @@ var w = () => {
98
98
  } catch (e) {
99
99
  M(e instanceof Error ? e.message : "Approval failed");
100
100
  } finally {
101
- K(null);
101
+ G(null);
102
102
  }
103
- }, Oe = async (e, t, n) => {
103
+ }, je = async (e, t, n) => {
104
104
  if (!n.trim()) {
105
105
  M("Rejection reason is required");
106
106
  return;
107
107
  }
108
- K(e), M(null);
108
+ G(e), M(null);
109
109
  try {
110
110
  let t = await g({
111
111
  gateway: "global",
112
- query: ge,
112
+ query: _e,
113
113
  variables: {
114
114
  id: e,
115
115
  reason: n.trim()
@@ -117,11 +117,11 @@ var w = () => {
117
117
  authToken: x || void 0
118
118
  });
119
119
  if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Rejection failed");
120
- J(null), X(""), Z(null), await Q();
120
+ K(null), J(""), Y(null), await Q();
121
121
  } catch (e) {
122
122
  M(e instanceof Error ? e.message : "Rejection failed");
123
123
  } finally {
124
- K(null);
124
+ G(null);
125
125
  }
126
126
  }, $ = r(async (e) => {
127
127
  if (e === "VERSION_UPDATES") {
@@ -176,18 +176,36 @@ var w = () => {
176
176
  variables: { id: e.productId },
177
177
  authToken: x || void 0
178
178
  })));
179
- Ee((n) => {
179
+ ke((n) => {
180
180
  let r = { ...n };
181
181
  return t.forEach((t, n) => {
182
182
  if (t.status === "fulfilled") {
183
- let i = t.value.data?.application?.versions?.edges?.[0]?.node?.packageUrl, a = e[n].productId;
184
- i && a && (r[a] = i);
183
+ let i = t.value.data?.application?.versions?.edges?.[0]?.node, a = e[n].productId;
184
+ i?.id && i.packageUrl && a && (r[a] = {
185
+ versionId: i.id,
186
+ packageUrl: i.packageUrl
187
+ });
185
188
  }
186
189
  }), r;
187
190
  });
188
191
  })();
189
192
  }, [T, x]);
190
- let ke = async (e) => {
193
+ let Me = async (e) => {
194
+ Z(e);
195
+ try {
196
+ let t = (await g({
197
+ gateway: "global",
198
+ query: me,
199
+ variables: { id: e },
200
+ authToken: x || void 0
201
+ })).data?.refreshApplicationVersionPackageUrl;
202
+ t ? window.open(t, "_blank", "noreferrer") : M("Could not generate a download URL. S3 credentials may not be configured.");
203
+ } catch (e) {
204
+ M(e instanceof Error ? e.message : "Failed to refresh download URL");
205
+ } finally {
206
+ Z(null);
207
+ }
208
+ }, Ne = async (e) => {
191
209
  P(e), M(null);
192
210
  try {
193
211
  let t = await g({
@@ -206,7 +224,7 @@ var w = () => {
206
224
  } finally {
207
225
  P(null);
208
226
  }
209
- }, Ae = async (e) => {
227
+ }, Pe = async (e) => {
210
228
  if (!L.trim()) {
211
229
  M("Rejection reason is required");
212
230
  return;
@@ -229,7 +247,7 @@ var w = () => {
229
247
  } finally {
230
248
  P(null);
231
249
  }
232
- }, je = T.filter((e) => e.status === "PENDING_REVIEW").length;
250
+ }, Fe = T.filter((e) => e.status === "PENDING_REVIEW").length;
233
251
  return /* @__PURE__ */ v("div", {
234
252
  className: "min-h-screen bg-[var(--color-surface-default)]",
235
253
  children: [
@@ -268,19 +286,19 @@ var w = () => {
268
286
  })]
269
287
  }), /* @__PURE__ */ _("div", {
270
288
  className: "mt-3 flex gap-1.5 flex-wrap",
271
- children: _e.map((e) => /* @__PURE__ */ v("button", {
289
+ children: ve.map((e) => /* @__PURE__ */ v("button", {
272
290
  type: "button",
273
- onClick: () => be(e.value),
291
+ onClick: () => xe(e.value),
274
292
  className: `rounded-full px-3.5 py-1 text-xs font-medium transition-colors ${F === e.value ? "bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]" : "bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)]"}`,
275
293
  children: [
276
294
  e.label,
277
- e.value === "PENDING_REVIEW" && je > 0 && F !== "PENDING_REVIEW" && /* @__PURE__ */ _("span", {
295
+ e.value === "PENDING_REVIEW" && Fe > 0 && F !== "PENDING_REVIEW" && /* @__PURE__ */ _("span", {
278
296
  className: "ml-1.5 rounded-full bg-[var(--color-status-warning-text)] px-1.5 py-0.5 text-[10px] text-white",
279
- children: je
297
+ children: Fe
280
298
  }),
281
- e.value === "VERSION_UPDATES" && W > 0 && F !== "VERSION_UPDATES" && /* @__PURE__ */ _("span", {
299
+ e.value === "VERSION_UPDATES" && we > 0 && F !== "VERSION_UPDATES" && /* @__PURE__ */ _("span", {
282
300
  className: "ml-1.5 rounded-full bg-[var(--color-status-info-text)] px-1.5 py-0.5 text-[10px] text-white",
283
- children: W
301
+ children: we
284
302
  })
285
303
  ]
286
304
  }, e.value))
@@ -386,14 +404,13 @@ var w = () => {
386
404
  }),
387
405
  /* @__PURE__ */ v("div", {
388
406
  className: "flex flex-wrap gap-2",
389
- children: [t.packageUrl && /* @__PURE__ */ v("a", {
390
- href: t.packageUrl,
391
- download: !0,
392
- target: "_blank",
393
- rel: "noreferrer",
394
- className: "inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors",
407
+ children: [t.packageUrl && /* @__PURE__ */ v("button", {
408
+ type: "button",
409
+ onClick: () => void Me(t.id),
410
+ disabled: X === t.id,
411
+ className: "inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors disabled:opacity-50",
395
412
  children: [
396
- /* @__PURE__ */ _(u, { className: "size-3.5" }),
413
+ X === t.id ? /* @__PURE__ */ _(m, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ _(u, { className: "size-3.5" }),
397
414
  "Download Package",
398
415
  t.packageSize != null && /* @__PURE__ */ v("span", {
399
416
  className: "text-[var(--color-text-muted)]",
@@ -419,7 +436,7 @@ var w = () => {
419
436
  className: "overflow-x-auto rounded-lg border border-[var(--color-border-seam)] bg-[var(--color-surface-default)] p-4 text-[11px] leading-relaxed text-[var(--color-text-primary)] max-h-48 overflow-y-auto",
420
437
  children: JSON.stringify(t.manifest, null, 2)
421
438
  }),
422
- q === t.id && we === e.id && /* @__PURE__ */ v("div", {
439
+ Ee === t.id && De === e.id && /* @__PURE__ */ v("div", {
423
440
  className: "rounded-lg border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)]/30 p-3 space-y-2",
424
441
  children: [
425
442
  /* @__PURE__ */ _("p", {
@@ -427,8 +444,8 @@ var w = () => {
427
444
  children: "Rejection reason (the developer will see this)"
428
445
  }),
429
446
  /* @__PURE__ */ _("textarea", {
430
- value: Y,
431
- onChange: (e) => X(e.target.value),
447
+ value: q,
448
+ onChange: (e) => J(e.target.value),
432
449
  rows: 2,
433
450
  className: "w-full rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none",
434
451
  placeholder: "Be specific — what needs to change before this version can be approved…"
@@ -438,14 +455,14 @@ var w = () => {
438
455
  children: [/* @__PURE__ */ _("button", {
439
456
  type: "button",
440
457
  onClick: () => {
441
- J(null), X(""), Z(null);
458
+ K(null), J(""), Y(null);
442
459
  },
443
460
  className: "rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors",
444
461
  children: "Cancel"
445
462
  }), /* @__PURE__ */ _("button", {
446
463
  type: "button",
447
- onClick: () => void Oe(t.id, e.id, Y),
448
- disabled: !Y.trim() || G === t.id,
464
+ onClick: () => void je(t.id, e.id, q),
465
+ disabled: !q.trim() || W === t.id,
449
466
  className: "rounded-md bg-[var(--color-surface-danger)] px-3 py-1.5 text-xs font-semibold text-[var(--color-text-on-danger)] hover:opacity-90 disabled:opacity-50 transition-opacity",
450
467
  children: "Submit rejection"
451
468
  })]
@@ -456,16 +473,16 @@ var w = () => {
456
473
  className: "flex items-center gap-2",
457
474
  children: [/* @__PURE__ */ v("button", {
458
475
  type: "button",
459
- onClick: () => void De(t.id, e.id, ""),
460
- disabled: G === t.id,
476
+ onClick: () => void Ae(t.id, e.id, ""),
477
+ disabled: W === t.id,
461
478
  className: "inline-flex items-center gap-1.5 rounded-md bg-[var(--color-surface-success)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-on-success)] hover:opacity-90 disabled:opacity-50 transition-opacity",
462
- children: [G === t.id ? /* @__PURE__ */ _(m, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ _(o, { className: "size-3.5" }), "Approve version"]
463
- }), q !== t.id && /* @__PURE__ */ v("button", {
479
+ children: [W === t.id ? /* @__PURE__ */ _(m, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ _(o, { className: "size-3.5" }), "Approve version"]
480
+ }), Ee !== t.id && /* @__PURE__ */ v("button", {
464
481
  type: "button",
465
482
  onClick: () => {
466
- J(t.id), X(""), Z(e.id);
483
+ K(t.id), J(""), Y(e.id);
467
484
  },
468
- disabled: G === t.id,
485
+ disabled: W === t.id,
469
486
  className: "inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-danger)] hover:bg-[var(--color-surface-danger)] hover:text-[var(--color-text-on-danger)] disabled:opacity-50 transition-colors",
470
487
  children: [/* @__PURE__ */ _(h, { className: "size-3.5" }), "Reject version"]
471
488
  })]
@@ -507,11 +524,11 @@ var w = () => {
507
524
  children: e.name
508
525
  }),
509
526
  /* @__PURE__ */ _("span", {
510
- className: `rounded-full px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${ve(e.type)}`,
527
+ className: `rounded-full px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${ye(e.type)}`,
511
528
  children: e.type
512
529
  }),
513
530
  /* @__PURE__ */ _("span", {
514
- className: `rounded-full px-2 py-0.5 text-[11px] font-medium ${ye(e.status)}`,
531
+ className: `rounded-full px-2 py-0.5 text-[11px] font-medium ${be(e.status)}`,
515
532
  children: e.status.replace("_", " ")
516
533
  })
517
534
  ]
@@ -571,15 +588,23 @@ var w = () => {
571
588
  children: [/* @__PURE__ */ _(d, { className: "size-3.5" }), "Devportal"]
572
589
  }),
573
590
  S.has(e.type) && (() => {
574
- let t = e.zipFileUrl ?? (e.productId ? Te[e.productId] ?? null : null) ?? U.find((t) => t.id === e.productId)?.versions?.edges?.[0]?.node?.packageUrl ?? null;
575
- return t ? /* @__PURE__ */ v("a", {
576
- href: t,
591
+ let t = e.productId ? Oe[e.productId]?.versionId ?? U.find((t) => t.id === e.productId)?.versions?.edges?.[0]?.node?.id : void 0;
592
+ if (!t && !e.zipFileUrl) return null;
593
+ let n = X === t;
594
+ return t ? /* @__PURE__ */ v("button", {
595
+ type: "button",
596
+ onClick: () => void Me(t),
597
+ disabled: n,
598
+ className: "inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors disabled:opacity-50",
599
+ children: [n ? /* @__PURE__ */ _(m, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ _(u, { className: "size-3.5" }), "Download Package"]
600
+ }) : /* @__PURE__ */ v("a", {
601
+ href: e.zipFileUrl,
577
602
  download: !0,
578
603
  target: "_blank",
579
604
  rel: "noreferrer",
580
605
  className: "inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors",
581
606
  children: [/* @__PURE__ */ _(u, { className: "size-3.5" }), "Download Package"]
582
- }) : null;
607
+ });
583
608
  })(),
584
609
  S.has(e.type) && /* @__PURE__ */ v("button", {
585
610
  type: "button",
@@ -602,7 +627,7 @@ var w = () => {
602
627
  className: "flex items-center gap-2",
603
628
  children: [e.status !== "PUBLISHED" && /* @__PURE__ */ v("button", {
604
629
  type: "button",
605
- onClick: () => void ke(e.id),
630
+ onClick: () => void Ne(e.id),
606
631
  disabled: N === e.id,
607
632
  className: "inline-flex items-center gap-1.5 rounded-md bg-[var(--color-surface-success)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-on-success)] hover:opacity-90 disabled:opacity-50 transition-opacity",
608
633
  children: [/* @__PURE__ */ _(o, { className: "size-3.5" }), "Approve"]
@@ -708,7 +733,7 @@ var w = () => {
708
733
  })] })
709
734
  ]
710
735
  }),
711
- xe === e.id && /* @__PURE__ */ v("div", {
736
+ Se === e.id && /* @__PURE__ */ v("div", {
712
737
  className: "border-t border-[var(--color-border-seam)] bg-[var(--color-surface-danger-muted)]/30 px-5 py-4",
713
738
  children: [
714
739
  /* @__PURE__ */ _("p", {
@@ -737,7 +762,7 @@ var w = () => {
737
762
  children: "Cancel"
738
763
  }), /* @__PURE__ */ _("button", {
739
764
  type: "button",
740
- onClick: () => void Ae(e.id),
765
+ onClick: () => void Pe(e.id),
741
766
  disabled: !L.trim() || N === e.id,
742
767
  className: "rounded-md bg-[var(--color-surface-danger)] px-3 py-1.5 text-xs font-semibold text-[var(--color-text-on-danger)] hover:opacity-90 disabled:opacity-50 transition-opacity",
743
768
  children: "Submit rejection"
@@ -1 +1 @@
1
- {"version":3,"file":"AdminSubmissionsQueuePage.js","names":[],"sources":["../../src/pages/AdminSubmissionsQueuePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport {\n ArrowLeft,\n Check,\n X,\n RefreshCw,\n PackageCheck,\n ChevronDown,\n ChevronUp,\n ExternalLink,\n FileJson,\n ShieldCheck,\n FlaskConical,\n Download,\n Clock,\n Tag,\n User,\n Hash,\n GitBranch,\n} from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate } from 'react-router-dom';\nimport { useStore } from '../providers/StoreProvider';\nimport { formatPriceForModel } from '../utils';\nimport { PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { InstallAppModal } from '../components/InstallAppModal';\n\ntype PendingProduct = {\n id: string;\n slug: string;\n name: string;\n type: string;\n nature: string;\n status: string;\n pricingModel: string;\n price: number;\n currency: string;\n description?: string | null;\n submittedAt?: string | null;\n submittedBy?: string | null;\n category?: string | null;\n icon?: string | null;\n productId?: string | null;\n zipFileUrl?: string | null;\n manifest?: Record<string, unknown> | null;\n requiredPermissions?: string[] | null;\n publisher?: { id: string; name: string; email: string } | null;\n};\n\ntype ProductStatus = 'PENDING_REVIEW' | 'PUBLISHED' | 'REJECTED' | 'ALL' | 'VERSION_UPDATES';\n\ntype PendingVersion = {\n id: string;\n version: string;\n status: string;\n releaseNotes?: string | null;\n packageUrl?: string | null;\n packageSize?: number | null;\n isLatest?: boolean | null;\n reviewNotes?: string | null;\n manifest?: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype VersionUpdateApp = {\n id: string;\n name: string;\n slug: string;\n iconUrl?: string | null;\n shortDescription?: string | null;\n description?: string | null;\n versions: { edges: Array<{ node: PendingVersion }> };\n};\n\nconst PENDING_PRODUCTS_QUERY = /* GraphQL */ `\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendingReviewProducts(limit: $limit, offset: $offset) {\n totalCount\n products {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n }\n`;\n\nconst ALL_PRODUCTS_QUERY = /* GraphQL */ `\n query AdminProducts($limit: Int, $offset: Int, $status: ProductStatus) {\n products(filter: { status: $status }, limit: $limit, offset: $offset) {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n`;\n\nconst APPROVE_PRODUCT_MUTATION = /* GraphQL */ `\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n`;\n\nconst REJECT_PRODUCT_MUTATION = /* GraphQL */ `\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n`;\n\nconst APP_PACKAGE_URL_QUERY = /* GraphQL */ `\n query AdminAppPackageUrl($id: ID!) {\n application(id: $id) {\n id\n versions(first: 1) {\n edges {\n node {\n packageUrl\n }\n }\n }\n }\n }\n`;\n\nconst VERSION_UPDATES_QUERY = /* GraphQL */ `\n query AdminPendingVersionApps($limit: Int, $offset: Int) {\n applicationsWithPendingVersions(limit: $limit, offset: $offset) {\n totalCount\n edges {\n node {\n id\n name\n slug\n iconUrl\n shortDescription\n description\n versions(first: 5) {\n edges {\n node {\n id\n version\n status\n releaseNotes\n packageUrl\n packageSize\n isLatest\n reviewNotes\n manifest\n createdAt\n }\n }\n }\n }\n }\n }\n }\n`;\n\nconst APPROVE_VERSION_MUTATION = /* GraphQL */ `\n mutation AdminApproveApplicationVersion($id: ID!, $notes: String) {\n approveApplicationVersion(id: $id, notes: $notes) {\n id\n status\n }\n }\n`;\n\nconst REJECT_VERSION_MUTATION = /* GraphQL */ `\n mutation AdminRejectApplicationVersion($id: ID!, $reason: String!) {\n rejectApplicationVersion(id: $id, reason: $reason) {\n id\n status\n }\n }\n`;\n\nconst STATUS_FILTERS: Array<{ label: string; value: ProductStatus }> = [\n { label: 'Pending review', value: 'PENDING_REVIEW' },\n { label: 'Published', value: 'PUBLISHED' },\n { label: 'Rejected', value: 'REJECTED' },\n { label: 'Version Updates', value: 'VERSION_UPDATES' },\n { label: 'All', value: 'ALL' },\n];\n\nconst TYPE_COLORS: Record<string, string> = {\n NODE: 'bg-[var(--color-status-info-bg-subtle)] text-[var(--color-status-info-text)]',\n WORKFLOW: 'bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]',\n INTEGRATION: 'bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]',\n VIBEMODULE: 'bg-[var(--color-surface-accent-muted)] text-[var(--color-text-accent)]',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n PENDING_REVIEW:\n 'bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]',\n PUBLISHED: 'bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]',\n REJECTED: 'bg-[var(--color-status-error-bg-subtle)] text-[var(--color-status-error-text)]',\n};\n\nconst PACKAGE_TYPES = new Set(['NODE', 'WORKFLOW', 'VIBEMODULE', 'PARSER', 'DATASINK', 'CONSOLE']);\n\nfunction typeColor(type: string) {\n return TYPE_COLORS[type] ?? 'bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]';\n}\n\nfunction statusColor(status: string) {\n return (\n STATUS_COLORS[status] ?? 'bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]'\n );\n}\n\nfunction formatDate(iso?: string | null) {\n if (!iso) return '—';\n return new Date(iso).toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport const AdminSubmissionsQueuePage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n const [products, setProducts] = useState<PendingProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [actingId, setActingId] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState<ProductStatus>('PENDING_REVIEW');\n const [rejectingId, setRejectingId] = useState<string | null>(null);\n const [rejectReason, setRejectReason] = useState('');\n const [viewingId, setViewingId] = useState<string | null>(null);\n const [testingProduct, setTestingProduct] = useState<PendingProduct | null>(null);\n const [versionApps, setVersionApps] = useState<VersionUpdateApp[]>([]);\n const [versionUpdateCount, setVersionUpdateCount] = useState(0);\n const [versionActingId, setVersionActingId] = useState<string | null>(null);\n const [versionRejectingId, setVersionRejectingId] = useState<string | null>(null);\n const [versionRejectReason, setVersionRejectReason] = useState('');\n const [versionRejectAppId, setVersionRejectAppId] = useState<string | null>(null);\n // productId → packageUrl for existing submissions where zipFileUrl was not populated\n const [appVersionUrls, setAppVersionUrls] = useState<Record<string, string>>({});\n\n const loadVersionApps = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n applicationsWithPendingVersions: {\n totalCount: number;\n edges: Array<{ node: VersionUpdateApp }>;\n };\n }>({\n gateway: 'global',\n query: VERSION_UPDATES_QUERY,\n variables: { limit: 50, offset: 0 },\n authToken: authToken || undefined,\n });\n if (result.errors?.length)\n throw new Error(result.errors[0]?.message ?? 'Failed to load version updates');\n const edges = result.data?.applicationsWithPendingVersions.edges ?? [];\n setVersionApps(edges.map((e) => e.node));\n setVersionUpdateCount(result.data?.applicationsWithPendingVersions.totalCount ?? 0);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load version updates');\n } finally {\n setLoading(false);\n }\n }, [authToken]);\n\n const approveVersion = async (versionId: string, appId: string, notes: string) => {\n setVersionActingId(versionId);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: APPROVE_VERSION_MUTATION,\n variables: { id: versionId, notes: notes || null },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) throw new Error(result.errors[0]?.message ?? 'Approval failed');\n await loadVersionApps();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Approval failed');\n } finally {\n setVersionActingId(null);\n }\n };\n\n const rejectVersion = async (versionId: string, appId: string, reason: string) => {\n if (!reason.trim()) {\n setError('Rejection reason is required');\n return;\n }\n setVersionActingId(versionId);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: REJECT_VERSION_MUTATION,\n variables: { id: versionId, reason: reason.trim() },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) throw new Error(result.errors[0]?.message ?? 'Rejection failed');\n setVersionRejectingId(null);\n setVersionRejectReason('');\n setVersionRejectAppId(null);\n await loadVersionApps();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Rejection failed');\n } finally {\n setVersionActingId(null);\n }\n };\n\n const loadProducts = useCallback(\n async (filter: ProductStatus) => {\n if (filter === 'VERSION_UPDATES') {\n await loadVersionApps();\n return;\n }\n setLoading(true);\n setError(null);\n try {\n if (filter === 'PENDING_REVIEW') {\n const result = await graphqlFetch<{\n pendingReviewProducts: { totalCount: number; products: PendingProduct[] };\n }>({\n gateway: 'global',\n query: PENDING_PRODUCTS_QUERY,\n variables: { limit: 100, offset: 0 },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load pending products');\n }\n setProducts(result.data?.pendingReviewProducts.products ?? []);\n setTotalCount(result.data?.pendingReviewProducts.totalCount ?? 0);\n } else {\n const result = await graphqlFetch<{ products: PendingProduct[] }>({\n gateway: 'global',\n query: ALL_PRODUCTS_QUERY,\n variables: {\n limit: 100,\n offset: 0,\n ...(filter !== 'ALL' && { status: filter }),\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load products');\n }\n const list = result.data?.products ?? [];\n setProducts(list);\n setTotalCount(list.length);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load products');\n } finally {\n setLoading(false);\n }\n },\n [authToken, loadVersionApps]\n );\n\n useEffect(() => {\n void loadProducts(statusFilter);\n }, [loadProducts, statusFilter]);\n\n // Keep version update count fresh for the badge even when not on that tab\n useEffect(() => {\n void loadVersionApps();\n }, [loadVersionApps]);\n\n // For PACKAGE_TYPES products whose zipFileUrl was not populated at submission time,\n // fetch the latest version package URL directly from the devportal.\n useEffect(() => {\n const targets = products.filter(\n (p) => PACKAGE_TYPES.has(p.type) && p.productId && !p.zipFileUrl\n );\n if (targets.length === 0) return;\n void (async () => {\n const results = await Promise.allSettled(\n targets.map((p) =>\n graphqlFetch<{\n application: {\n id: string;\n versions: { edges: Array<{ node: { packageUrl?: string | null } }> };\n } | null;\n }>({\n gateway: 'global',\n query: APP_PACKAGE_URL_QUERY,\n variables: { id: p.productId },\n authToken: authToken || undefined,\n })\n )\n );\n setAppVersionUrls((prev) => {\n const next = { ...prev };\n results.forEach((r, i) => {\n if (r.status === 'fulfilled') {\n const url = r.value.data?.application?.versions?.edges?.[0]?.node?.packageUrl;\n const productId = targets[i].productId;\n if (url && productId) next[productId] = url;\n }\n });\n return next;\n });\n })();\n }, [products, authToken]);\n\n const approve = async (id: string) => {\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: APPROVE_PRODUCT_MUTATION,\n variables: { id, notes: null },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Approval failed');\n }\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Approval failed');\n } finally {\n setActingId(null);\n }\n };\n\n const reject = async (id: string) => {\n if (!rejectReason.trim()) {\n setError('Rejection reason is required');\n return;\n }\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: REJECT_PRODUCT_MUTATION,\n variables: { id, reason: rejectReason.trim() },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Rejection failed');\n }\n setRejectingId(null);\n setRejectReason('');\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Rejection failed');\n } finally {\n setActingId(null);\n }\n };\n\n const pendingCount = products.filter((p) => p.status === 'PENDING_REVIEW').length;\n\n return (\n <div className=\"min-h-screen bg-[var(--color-surface-default)]\">\n {/* Header */}\n <header className=\"sticky top-0 z-10 border-b border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)]\">\n <div className=\"mx-auto max-w-5xl px-6 py-4\">\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex items-center gap-3 min-w-0\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-sm text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n <ArrowLeft className=\"size-4 shrink-0\" />\n Back\n </button>\n <div className=\"h-5 w-px bg-[var(--color-border-seam)]\" />\n <PackageCheck className=\"size-5 shrink-0 text-[var(--color-text-primary)]\" />\n <h1 className=\"text-lg font-semibold text-[var(--color-text-primary)] truncate\">\n Submission Queue\n </h1>\n {totalCount > 0 && (\n <span className=\"shrink-0 rounded-full bg-[var(--color-status-warning-bg-subtle)] px-2 py-0.5 text-xs font-semibold text-[var(--color-status-warning-text)]\">\n {totalCount}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => void loadProducts(statusFilter)}\n className=\"shrink-0 inline-flex items-center gap-2 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors disabled:opacity-50\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n\n {/* Status filter pills */}\n <div className=\"mt-3 flex gap-1.5 flex-wrap\">\n {STATUS_FILTERS.map((f) => (\n <button\n key={f.value}\n type=\"button\"\n onClick={() => setStatusFilter(f.value)}\n className={`rounded-full px-3.5 py-1 text-xs font-medium transition-colors ${\n statusFilter === f.value\n ? 'bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]'\n : 'bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)]'\n }`}\n >\n {f.label}\n {f.value === 'PENDING_REVIEW' &&\n pendingCount > 0 &&\n statusFilter !== 'PENDING_REVIEW' && (\n <span className=\"ml-1.5 rounded-full bg-[var(--color-status-warning-text)] px-1.5 py-0.5 text-[10px] text-white\">\n {pendingCount}\n </span>\n )}\n {f.value === 'VERSION_UPDATES' &&\n versionUpdateCount > 0 &&\n statusFilter !== 'VERSION_UPDATES' && (\n <span className=\"ml-1.5 rounded-full bg-[var(--color-status-info-text)] px-1.5 py-0.5 text-[10px] text-white\">\n {versionUpdateCount}\n </span>\n )}\n </button>\n ))}\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-5xl space-y-4 p-6\">\n <PagePurpose className=\"mb-2\">\n Every publisher submission lands here for your review. Inspect the manifest, permissions,\n and package details — then approve to publish or reject with a clear reason the developer\n will see.\n </PagePurpose>\n\n {error && (\n <div\n role=\"alert\"\n className=\"rounded-lg border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-3 text-sm text-[var(--color-text-danger)]\"\n >\n {error}\n </div>\n )}\n\n {statusFilter === 'VERSION_UPDATES' ? (\n loading && versionApps.length === 0 ? (\n <div className=\"flex items-center justify-center py-24\">\n <RefreshCw className=\"size-6 animate-spin text-[var(--color-text-muted)]\" />\n </div>\n ) : versionApps.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No pending version updates\"\n description=\"All published apps are up to date. When a developer submits a new version, it will appear here for your review.\"\n />\n ) : (\n <ul className=\"space-y-4\">\n {versionApps.map((app) => {\n const pendingVersions = app.versions.edges\n .map((e) => e.node)\n .filter((v) => v.status === 'pending_review');\n if (pendingVersions.length === 0) return null;\n return (\n <li\n key={app.id}\n className=\"overflow-hidden rounded-xl border border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)]\"\n >\n {/* App header */}\n <div className=\"flex items-center gap-4 p-5 border-b border-[var(--color-border-seam)]\">\n {app.iconUrl ? (\n <img\n src={app.iconUrl}\n alt=\"\"\n className=\"size-12 shrink-0 rounded-xl object-cover shadow-sm\"\n />\n ) : (\n <div className=\"flex size-12 shrink-0 items-center justify-center rounded-xl bg-[var(--color-surface-muted)] text-sm font-bold text-[var(--color-text-muted)] uppercase\">\n {app.name.slice(0, 2)}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h3 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {app.name}\n </h3>\n <span className=\"inline-flex items-center gap-1 rounded-full bg-[var(--color-status-info-bg-subtle)] px-2 py-0.5 text-[11px] font-semibold text-[var(--color-status-info-text)]\">\n <GitBranch className=\"size-3\" />\n {pendingVersions.length} version\n {pendingVersions.length !== 1 ? 's' : ''} pending\n </span>\n </div>\n {(app.shortDescription ?? app.description) && (\n <p className=\"mt-0.5 text-sm text-[var(--color-text-secondary)] line-clamp-1\">\n {app.shortDescription ?? app.description}\n </p>\n )}\n </div>\n <a\n href={`/devportal/apps/${app.id}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"shrink-0 inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <ExternalLink className=\"size-3.5\" />\n Devportal\n </a>\n </div>\n\n {/* Pending versions */}\n <div className=\"divide-y divide-[var(--color-border-seam)]\">\n {pendingVersions.map((ver) => (\n <div key={ver.id} className=\"p-5 space-y-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <GitBranch className=\"size-4 text-[var(--color-text-secondary)] shrink-0\" />\n <span className=\"font-mono font-semibold text-sm text-[var(--color-text-primary)]\">\n {ver.version}\n </span>\n {ver.isLatest && (\n <span className=\"rounded-full bg-[var(--color-surface-muted)] px-2 py-0.5 text-[10px] text-[var(--color-text-secondary)]\">\n Latest\n </span>\n )}\n <span className=\"rounded-full bg-[var(--color-status-warning-bg-subtle)] px-2 py-0.5 text-[10px] font-medium text-[var(--color-status-warning-text)] uppercase\">\n New Version\n </span>\n <span className=\"ml-auto flex items-center gap-1 text-xs text-[var(--color-text-secondary)]\">\n <Clock className=\"size-3\" />\n {formatDate(ver.createdAt)}\n </span>\n </div>\n\n {ver.releaseNotes && (\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {ver.releaseNotes}\n </p>\n )}\n\n <div className=\"flex flex-wrap gap-2\">\n {ver.packageUrl && (\n <a\n href={ver.packageUrl}\n download\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <Download className=\"size-3.5\" />\n Download Package\n {ver.packageSize != null && (\n <span className=\"text-[var(--color-text-muted)]\">\n ({ver.packageSize} bytes)\n </span>\n )}\n </a>\n )}\n {ver.manifest && (\n <button\n type=\"button\"\n onClick={() => setViewingId(viewingId === ver.id ? null : ver.id)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <FileJson className=\"size-3.5\" />\n {viewingId === ver.id ? 'Hide manifest' : 'View manifest'}\n {viewingId === ver.id ? (\n <ChevronUp className=\"size-3\" />\n ) : (\n <ChevronDown className=\"size-3\" />\n )}\n </button>\n )}\n </div>\n\n {viewingId === ver.id && ver.manifest && (\n <pre className=\"overflow-x-auto rounded-lg border border-[var(--color-border-seam)] bg-[var(--color-surface-default)] p-4 text-[11px] leading-relaxed text-[var(--color-text-primary)] max-h-48 overflow-y-auto\">\n {JSON.stringify(ver.manifest, null, 2)}\n </pre>\n )}\n\n {/* Reject reason input */}\n {versionRejectingId === ver.id && versionRejectAppId === app.id && (\n <div className=\"rounded-lg border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)]/30 p-3 space-y-2\">\n <p className=\"text-xs font-semibold text-[var(--color-text-danger)]\">\n Rejection reason (the developer will see this)\n </p>\n <textarea\n value={versionRejectReason}\n onChange={(e) => setVersionRejectReason(e.target.value)}\n rows={2}\n className=\"w-full rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n placeholder=\"Be specific — what needs to change before this version can be approved…\"\n />\n <div className=\"flex gap-2 justify-end\">\n <button\n type=\"button\"\n onClick={() => {\n setVersionRejectingId(null);\n setVersionRejectReason('');\n setVersionRejectAppId(null);\n }}\n className=\"rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() =>\n void rejectVersion(ver.id, app.id, versionRejectReason)\n }\n disabled={\n !versionRejectReason.trim() || versionActingId === ver.id\n }\n className=\"rounded-md bg-[var(--color-surface-danger)] px-3 py-1.5 text-xs font-semibold text-[var(--color-text-on-danger)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n Submit rejection\n </button>\n </div>\n </div>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => void approveVersion(ver.id, app.id, '')}\n disabled={versionActingId === ver.id}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-[var(--color-surface-success)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-on-success)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {versionActingId === ver.id ? (\n <RefreshCw className=\"size-3.5 animate-spin\" />\n ) : (\n <Check className=\"size-3.5\" />\n )}\n Approve version\n </button>\n {versionRejectingId !== ver.id && (\n <button\n type=\"button\"\n onClick={() => {\n setVersionRejectingId(ver.id);\n setVersionRejectReason('');\n setVersionRejectAppId(app.id);\n }}\n disabled={versionActingId === ver.id}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-danger)] hover:bg-[var(--color-surface-danger)] hover:text-[var(--color-text-on-danger)] disabled:opacity-50 transition-colors\"\n >\n <X className=\"size-3.5\" />\n Reject version\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n </li>\n );\n })}\n </ul>\n )\n ) : loading && products.length === 0 ? (\n <div className=\"flex items-center justify-center py-24\">\n <RefreshCw className=\"size-6 animate-spin text-[var(--color-text-muted)]\" />\n </div>\n ) : products.length === 0 ? (\n <IllustratedEmptyState\n illustration={statusFilter === 'PENDING_REVIEW' ? 'empty-notifications' : 'empty-data'}\n title={\n statusFilter === 'PENDING_REVIEW' ? 'Queue is clear' : 'No products match this filter'\n }\n description={\n statusFilter === 'PENDING_REVIEW'\n ? 'No submissions are awaiting review. New submissions will appear here as publishers send them in.'\n : 'Nothing matches the current filter. Try switching to a different status above.'\n }\n />\n ) : (\n <ul className=\"space-y-3\">\n {products.map((p) => (\n <li\n key={p.id}\n className=\"overflow-hidden rounded-xl border border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)] transition-[box-shadow,border-color] hover:border-[var(--color-border-strong)] hover:shadow-[var(--shadow-elevation-2)]\"\n >\n {/* Card body */}\n <div className=\"flex items-start gap-4 p-5\">\n {/* App icon */}\n {p.icon ? (\n <img\n src={p.icon}\n alt=\"\"\n className=\"size-14 shrink-0 rounded-xl object-cover shadow-sm\"\n />\n ) : (\n <div className=\"flex size-14 shrink-0 items-center justify-center rounded-xl bg-[var(--color-surface-muted)] text-sm font-bold text-[var(--color-text-muted)] uppercase\">\n {p.type.slice(0, 2)}\n </div>\n )}\n\n {/* Main info */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h3 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {p.name}\n </h3>\n <span\n className={`rounded-full px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${typeColor(p.type)}`}\n >\n {p.type}\n </span>\n <span\n className={`rounded-full px-2 py-0.5 text-[11px] font-medium ${statusColor(p.status)}`}\n >\n {p.status.replace('_', ' ')}\n </span>\n </div>\n\n <div className=\"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--color-text-secondary)]\">\n <span className=\"flex items-center gap-1\">\n <Hash className=\"size-3\" />\n <span className=\"font-mono\">{p.slug}</span>\n </span>\n {p.publisher && (\n <span className=\"flex items-center gap-1\">\n <User className=\"size-3\" />\n {p.publisher.name}\n {p.publisher.email && (\n <span className=\"text-[var(--color-text-muted)]\">\n ({p.publisher.email})\n </span>\n )}\n </span>\n )}\n {p.submittedAt && (\n <span className=\"flex items-center gap-1\">\n <Clock className=\"size-3\" />\n {formatDate(p.submittedAt)}\n </span>\n )}\n <span className=\"flex items-center gap-1\">\n <Tag className=\"size-3\" />\n {formatPriceForModel(p.price, p.currency, p.pricingModel)}\n </span>\n </div>\n\n {p.description && (\n <p className=\"mt-2 line-clamp-2 text-sm text-[var(--color-text-secondary)]\">\n {p.description}\n </p>\n )}\n </div>\n </div>\n\n {/* Action bar */}\n <div className=\"flex flex-wrap items-center justify-between gap-2 border-t border-[var(--color-border-seam)] bg-[var(--color-surface-muted)] px-5 py-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n {/* View in devportal */}\n {p.productId && (\n <a\n href={`/devportal/apps/${p.productId}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n <ExternalLink className=\"size-3.5\" />\n Devportal\n </a>\n )}\n\n {/* Package download for NODE/WORKFLOW — prefer zipFileUrl on the product,\n then check appVersionUrls (fetched per-app for legacy submissions),\n then fall back to versionApps (apps with pending devportal versions) */}\n {PACKAGE_TYPES.has(p.type) &&\n (() => {\n const pkgUrl =\n p.zipFileUrl ??\n (p.productId ? (appVersionUrls[p.productId] ?? null) : null) ??\n versionApps.find((va) => va.id === p.productId)?.versions?.edges?.[0]\n ?.node?.packageUrl ??\n null;\n if (!pkgUrl) return null;\n return (\n <a\n href={pkgUrl}\n download\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n <Download className=\"size-3.5\" />\n Download Package\n </a>\n );\n })()}\n\n {/* Test in workspace for NODE/WORKFLOW */}\n {PACKAGE_TYPES.has(p.type) && (\n <button\n type=\"button\"\n onClick={() => setTestingProduct(p)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-accent)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-accent)] hover:bg-[var(--color-surface-accent-muted)] transition-colors\"\n >\n <FlaskConical className=\"size-3.5\" />\n Test in workspace\n </button>\n )}\n\n {/* Show manifest / details toggle */}\n <button\n type=\"button\"\n onClick={() => setViewingId(viewingId === p.id ? null : p.id)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <FileJson className=\"size-3.5\" />\n {viewingId === p.id ? 'Hide details' : 'Inspect details'}\n {viewingId === p.id ? (\n <ChevronUp className=\"size-3\" />\n ) : (\n <ChevronDown className=\"size-3\" />\n )}\n </button>\n </div>\n\n <div className=\"flex items-center gap-2\">\n {p.status !== 'PUBLISHED' && (\n <button\n type=\"button\"\n onClick={() => void approve(p.id)}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-[var(--color-surface-success)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-on-success)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n <Check className=\"size-3.5\" />\n Approve\n </button>\n )}\n {p.status !== 'REJECTED' && (\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(p.id);\n setRejectReason('');\n }}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-danger)] hover:bg-[var(--color-surface-danger)] hover:text-[var(--color-text-on-danger)] disabled:opacity-50 transition-colors\"\n >\n <X className=\"size-3.5\" />\n Reject\n </button>\n )}\n </div>\n </div>\n\n {/* Details panel */}\n {viewingId === p.id && (\n <div className=\"border-t border-[var(--color-border-seam)] bg-[var(--color-surface-muted)] p-5 space-y-5\">\n {/* Metadata grid */}\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-3 text-xs sm:grid-cols-3\">\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Store product ID\n </dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)] break-all\">\n {p.id}\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">Slug</dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)]\">\n {p.slug}\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Type / Nature\n </dt>\n <dd className=\"mt-0.5 text-[var(--color-text-primary)]\">\n {p.type} · {p.nature}\n </dd>\n </div>\n {p.category && (\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Category\n </dt>\n <dd className=\"mt-0.5 text-[var(--color-text-primary)]\">{p.category}</dd>\n </div>\n )}\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">Pricing</dt>\n <dd className=\"mt-0.5 text-[var(--color-text-primary)]\">\n {formatPriceForModel(p.price, p.currency, p.pricingModel)}{' '}\n <span className=\"text-[var(--color-text-muted)]\">({p.pricingModel})</span>\n </dd>\n </div>\n {p.productId && (\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Devportal app ID\n </dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)] break-all\">\n {p.productId}\n </dd>\n </div>\n )}\n {p.submittedBy && (\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Submitted by (actor)\n </dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)] break-all\">\n {p.submittedBy}\n </dd>\n </div>\n )}\n </div>\n\n {/* Required permissions */}\n {p.requiredPermissions && p.requiredPermissions.length > 0 && (\n <div>\n <h4 className=\"mb-2 flex items-center gap-1.5 text-xs font-semibold text-[var(--color-text-secondary)] uppercase tracking-wide\">\n <ShieldCheck className=\"size-3.5 text-[var(--color-status-success-text)]\" />\n Required Permissions\n </h4>\n <div className=\"flex flex-wrap gap-1.5\">\n {p.requiredPermissions.map((perm) => (\n <span\n key={perm}\n className=\"inline-flex items-center gap-1 rounded-md bg-[var(--color-surface-default)] border border-[var(--color-border-seam)] px-2 py-1 text-xs font-mono text-[var(--color-text-primary)]\"\n >\n {perm}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Manifest JSON */}\n {p.manifest && (\n <div>\n <h4 className=\"mb-2 flex items-center gap-1.5 text-xs font-semibold text-[var(--color-text-secondary)] uppercase tracking-wide\">\n <FileJson className=\"size-3.5\" />\n Manifest\n </h4>\n <pre className=\"overflow-x-auto rounded-lg border border-[var(--color-border-seam)] bg-[var(--color-surface-default)] p-4 text-[11px] leading-relaxed text-[var(--color-text-primary)] max-h-72 overflow-y-auto scrollbar-thin\">\n {JSON.stringify(p.manifest, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n\n {/* Rejection form */}\n {rejectingId === p.id && (\n <div className=\"border-t border-[var(--color-border-seam)] bg-[var(--color-surface-danger-muted)]/30 px-5 py-4\">\n <p className=\"mb-2 text-xs font-semibold text-[var(--color-text-danger)]\">\n Reject — provide a reason (the publisher will see this)\n </p>\n <textarea\n id={`reject-reason-${p.id}`}\n aria-label=\"Rejection reason\"\n value={rejectReason}\n onChange={(e) => setRejectReason(e.target.value)}\n rows={3}\n required\n aria-required=\"true\"\n className=\"w-full rounded-lg border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] focus:border-[var(--color-border-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n placeholder=\"Be specific — e.g. 'Manifest is missing the identity.version field' or 'ZIP file is empty'…\"\n />\n <div className=\"mt-2 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(null);\n setRejectReason('');\n }}\n className=\"rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void reject(p.id)}\n disabled={!rejectReason.trim() || actingId === p.id}\n className=\"rounded-md bg-[var(--color-surface-danger)] px-3 py-1.5 text-xs font-semibold text-[var(--color-text-on-danger)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n Submit rejection\n </button>\n </div>\n </div>\n )}\n </li>\n ))}\n </ul>\n )}\n </main>\n\n {/* Test in workspace modal */}\n {testingProduct && (\n <InstallAppModal\n isOpen={true}\n onClose={() => setTestingProduct(null)}\n app={{\n id: testingProduct.id,\n name: testingProduct.name,\n slug: testingProduct.slug,\n icon: testingProduct.icon ?? undefined,\n type: testingProduct.type,\n permissions: testingProduct.requiredPermissions?.length\n ? testingProduct.requiredPermissions\n : undefined,\n }}\n purchaseState=\"free\"\n onInstallSuccess={() => {\n setTestingProduct(null);\n }}\n onInstallError={() => {}}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminSubmissionsQueuePage.js","names":[],"sources":["../../src/pages/AdminSubmissionsQueuePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport {\n ArrowLeft,\n Check,\n X,\n RefreshCw,\n PackageCheck,\n ChevronDown,\n ChevronUp,\n ExternalLink,\n FileJson,\n ShieldCheck,\n FlaskConical,\n Download,\n Clock,\n Tag,\n User,\n Hash,\n GitBranch,\n} from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useNavigate } from 'react-router-dom';\nimport { useStore } from '../providers/StoreProvider';\nimport { formatPriceForModel } from '../utils';\nimport { PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { InstallAppModal } from '../components/InstallAppModal';\n\ntype PendingProduct = {\n id: string;\n slug: string;\n name: string;\n type: string;\n nature: string;\n status: string;\n pricingModel: string;\n price: number;\n currency: string;\n description?: string | null;\n submittedAt?: string | null;\n submittedBy?: string | null;\n category?: string | null;\n icon?: string | null;\n productId?: string | null;\n zipFileUrl?: string | null;\n manifest?: Record<string, unknown> | null;\n requiredPermissions?: string[] | null;\n publisher?: { id: string; name: string; email: string } | null;\n};\n\ntype ProductStatus = 'PENDING_REVIEW' | 'PUBLISHED' | 'REJECTED' | 'ALL' | 'VERSION_UPDATES';\n\ntype PendingVersion = {\n id: string;\n version: string;\n status: string;\n releaseNotes?: string | null;\n packageUrl?: string | null;\n packageSize?: number | null;\n isLatest?: boolean | null;\n reviewNotes?: string | null;\n manifest?: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype VersionUpdateApp = {\n id: string;\n name: string;\n slug: string;\n iconUrl?: string | null;\n shortDescription?: string | null;\n description?: string | null;\n versions: { edges: Array<{ node: PendingVersion }> };\n};\n\nconst PENDING_PRODUCTS_QUERY = /* GraphQL */ `\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendingReviewProducts(limit: $limit, offset: $offset) {\n totalCount\n products {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n }\n`;\n\nconst ALL_PRODUCTS_QUERY = /* GraphQL */ `\n query AdminProducts($limit: Int, $offset: Int, $status: ProductStatus) {\n products(filter: { status: $status }, limit: $limit, offset: $offset) {\n id\n slug\n name\n type\n nature\n status\n pricingModel\n price\n currency\n description\n submittedAt\n submittedBy\n category\n icon\n productId\n zipFileUrl\n manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n`;\n\nconst APPROVE_PRODUCT_MUTATION = /* GraphQL */ `\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n`;\n\nconst REJECT_PRODUCT_MUTATION = /* GraphQL */ `\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n`;\n\nconst APP_PACKAGE_URL_QUERY = /* GraphQL */ `\n query AdminAppPackageUrl($id: ID!) {\n application(id: $id) {\n id\n versions(first: 1) {\n edges {\n node {\n id\n packageUrl\n }\n }\n }\n }\n }\n`;\n\nconst REFRESH_PACKAGE_URL_MUTATION = /* GraphQL */ `\n mutation RefreshApplicationVersionPackageUrl($id: ID!) {\n refreshApplicationVersionPackageUrl(id: $id)\n }\n`;\n\nconst VERSION_UPDATES_QUERY = /* GraphQL */ `\n query AdminPendingVersionApps($limit: Int, $offset: Int) {\n applicationsWithPendingVersions(limit: $limit, offset: $offset) {\n totalCount\n edges {\n node {\n id\n name\n slug\n iconUrl\n shortDescription\n description\n versions(first: 5) {\n edges {\n node {\n id\n version\n status\n releaseNotes\n packageUrl\n packageSize\n isLatest\n reviewNotes\n manifest\n createdAt\n }\n }\n }\n }\n }\n }\n }\n`;\n\nconst APPROVE_VERSION_MUTATION = /* GraphQL */ `\n mutation AdminApproveApplicationVersion($id: ID!, $notes: String) {\n approveApplicationVersion(id: $id, notes: $notes) {\n id\n status\n }\n }\n`;\n\nconst REJECT_VERSION_MUTATION = /* GraphQL */ `\n mutation AdminRejectApplicationVersion($id: ID!, $reason: String!) {\n rejectApplicationVersion(id: $id, reason: $reason) {\n id\n status\n }\n }\n`;\n\nconst STATUS_FILTERS: Array<{ label: string; value: ProductStatus }> = [\n { label: 'Pending review', value: 'PENDING_REVIEW' },\n { label: 'Published', value: 'PUBLISHED' },\n { label: 'Rejected', value: 'REJECTED' },\n { label: 'Version Updates', value: 'VERSION_UPDATES' },\n { label: 'All', value: 'ALL' },\n];\n\nconst TYPE_COLORS: Record<string, string> = {\n NODE: 'bg-[var(--color-status-info-bg-subtle)] text-[var(--color-status-info-text)]',\n WORKFLOW: 'bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]',\n INTEGRATION: 'bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]',\n VIBEMODULE: 'bg-[var(--color-surface-accent-muted)] text-[var(--color-text-accent)]',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n PENDING_REVIEW:\n 'bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]',\n PUBLISHED: 'bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]',\n REJECTED: 'bg-[var(--color-status-error-bg-subtle)] text-[var(--color-status-error-text)]',\n};\n\nconst PACKAGE_TYPES = new Set(['NODE', 'WORKFLOW', 'VIBEMODULE', 'PARSER', 'DATASINK', 'CONSOLE']);\n\nfunction typeColor(type: string) {\n return TYPE_COLORS[type] ?? 'bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]';\n}\n\nfunction statusColor(status: string) {\n return (\n STATUS_COLORS[status] ?? 'bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]'\n );\n}\n\nfunction formatDate(iso?: string | null) {\n if (!iso) return '—';\n return new Date(iso).toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport const AdminSubmissionsQueuePage: FC = () => {\n const navigate = useNavigate();\n const { authToken, basePath } = useStore();\n const [products, setProducts] = useState<PendingProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [actingId, setActingId] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState<ProductStatus>('PENDING_REVIEW');\n const [rejectingId, setRejectingId] = useState<string | null>(null);\n const [rejectReason, setRejectReason] = useState('');\n const [viewingId, setViewingId] = useState<string | null>(null);\n const [testingProduct, setTestingProduct] = useState<PendingProduct | null>(null);\n const [versionApps, setVersionApps] = useState<VersionUpdateApp[]>([]);\n const [versionUpdateCount, setVersionUpdateCount] = useState(0);\n const [versionActingId, setVersionActingId] = useState<string | null>(null);\n const [versionRejectingId, setVersionRejectingId] = useState<string | null>(null);\n const [versionRejectReason, setVersionRejectReason] = useState('');\n const [versionRejectAppId, setVersionRejectAppId] = useState<string | null>(null);\n // productId → { versionId, packageUrl } for legacy submissions where zipFileUrl was not populated\n const [appVersionInfo, setAppVersionInfo] = useState<\n Record<string, { versionId: string; packageUrl: string }>\n >({});\n const [downloadingVersionId, setDownloadingVersionId] = useState<string | null>(null);\n\n const loadVersionApps = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n applicationsWithPendingVersions: {\n totalCount: number;\n edges: Array<{ node: VersionUpdateApp }>;\n };\n }>({\n gateway: 'global',\n query: VERSION_UPDATES_QUERY,\n variables: { limit: 50, offset: 0 },\n authToken: authToken || undefined,\n });\n if (result.errors?.length)\n throw new Error(result.errors[0]?.message ?? 'Failed to load version updates');\n const edges = result.data?.applicationsWithPendingVersions.edges ?? [];\n setVersionApps(edges.map((e) => e.node));\n setVersionUpdateCount(result.data?.applicationsWithPendingVersions.totalCount ?? 0);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load version updates');\n } finally {\n setLoading(false);\n }\n }, [authToken]);\n\n const approveVersion = async (versionId: string, appId: string, notes: string) => {\n setVersionActingId(versionId);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: APPROVE_VERSION_MUTATION,\n variables: { id: versionId, notes: notes || null },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) throw new Error(result.errors[0]?.message ?? 'Approval failed');\n await loadVersionApps();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Approval failed');\n } finally {\n setVersionActingId(null);\n }\n };\n\n const rejectVersion = async (versionId: string, appId: string, reason: string) => {\n if (!reason.trim()) {\n setError('Rejection reason is required');\n return;\n }\n setVersionActingId(versionId);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: REJECT_VERSION_MUTATION,\n variables: { id: versionId, reason: reason.trim() },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) throw new Error(result.errors[0]?.message ?? 'Rejection failed');\n setVersionRejectingId(null);\n setVersionRejectReason('');\n setVersionRejectAppId(null);\n await loadVersionApps();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Rejection failed');\n } finally {\n setVersionActingId(null);\n }\n };\n\n const loadProducts = useCallback(\n async (filter: ProductStatus) => {\n if (filter === 'VERSION_UPDATES') {\n await loadVersionApps();\n return;\n }\n setLoading(true);\n setError(null);\n try {\n if (filter === 'PENDING_REVIEW') {\n const result = await graphqlFetch<{\n pendingReviewProducts: { totalCount: number; products: PendingProduct[] };\n }>({\n gateway: 'global',\n query: PENDING_PRODUCTS_QUERY,\n variables: { limit: 100, offset: 0 },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load pending products');\n }\n setProducts(result.data?.pendingReviewProducts.products ?? []);\n setTotalCount(result.data?.pendingReviewProducts.totalCount ?? 0);\n } else {\n const result = await graphqlFetch<{ products: PendingProduct[] }>({\n gateway: 'global',\n query: ALL_PRODUCTS_QUERY,\n variables: {\n limit: 100,\n offset: 0,\n ...(filter !== 'ALL' && { status: filter }),\n },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load products');\n }\n const list = result.data?.products ?? [];\n setProducts(list);\n setTotalCount(list.length);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load products');\n } finally {\n setLoading(false);\n }\n },\n [authToken, loadVersionApps]\n );\n\n useEffect(() => {\n void loadProducts(statusFilter);\n }, [loadProducts, statusFilter]);\n\n // Keep version update count fresh for the badge even when not on that tab\n useEffect(() => {\n void loadVersionApps();\n }, [loadVersionApps]);\n\n // For PACKAGE_TYPES products whose zipFileUrl was not populated at submission time,\n // fetch the latest version ID + package URL directly from the devportal.\n useEffect(() => {\n const targets = products.filter(\n (p) => PACKAGE_TYPES.has(p.type) && p.productId && !p.zipFileUrl\n );\n if (targets.length === 0) return;\n void (async () => {\n const results = await Promise.allSettled(\n targets.map((p) =>\n graphqlFetch<{\n application: {\n id: string;\n versions: { edges: Array<{ node: { id: string; packageUrl?: string | null } }> };\n } | null;\n }>({\n gateway: 'global',\n query: APP_PACKAGE_URL_QUERY,\n variables: { id: p.productId },\n authToken: authToken || undefined,\n })\n )\n );\n setAppVersionInfo((prev) => {\n const next = { ...prev };\n results.forEach((r, i) => {\n if (r.status === 'fulfilled') {\n const node = r.value.data?.application?.versions?.edges?.[0]?.node;\n const productId = targets[i].productId;\n if (node?.id && node.packageUrl && productId) {\n next[productId] = { versionId: node.id, packageUrl: node.packageUrl };\n }\n }\n });\n return next;\n });\n })();\n }, [products, authToken]);\n\n const downloadPackage = async (versionId: string) => {\n setDownloadingVersionId(versionId);\n try {\n const result = await graphqlFetch<{ refreshApplicationVersionPackageUrl: string | null }>({\n gateway: 'global',\n query: REFRESH_PACKAGE_URL_MUTATION,\n variables: { id: versionId },\n authToken: authToken || undefined,\n });\n const freshUrl = result.data?.refreshApplicationVersionPackageUrl;\n if (freshUrl) {\n window.open(freshUrl, '_blank', 'noreferrer');\n } else {\n setError('Could not generate a download URL. S3 credentials may not be configured.');\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to refresh download URL');\n } finally {\n setDownloadingVersionId(null);\n }\n };\n\n const approve = async (id: string) => {\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: APPROVE_PRODUCT_MUTATION,\n variables: { id, notes: null },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Approval failed');\n }\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Approval failed');\n } finally {\n setActingId(null);\n }\n };\n\n const reject = async (id: string) => {\n if (!rejectReason.trim()) {\n setError('Rejection reason is required');\n return;\n }\n setActingId(id);\n setError(null);\n try {\n const result = await graphqlFetch({\n gateway: 'global',\n query: REJECT_PRODUCT_MUTATION,\n variables: { id, reason: rejectReason.trim() },\n authToken: authToken || undefined,\n });\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Rejection failed');\n }\n setRejectingId(null);\n setRejectReason('');\n await loadProducts(statusFilter);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Rejection failed');\n } finally {\n setActingId(null);\n }\n };\n\n const pendingCount = products.filter((p) => p.status === 'PENDING_REVIEW').length;\n\n return (\n <div className=\"min-h-screen bg-[var(--color-surface-default)]\">\n {/* Header */}\n <header className=\"sticky top-0 z-10 border-b border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)]\">\n <div className=\"mx-auto max-w-5xl px-6 py-4\">\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex items-center gap-3 min-w-0\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/dashboard`)}\n className=\"inline-flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-sm text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n <ArrowLeft className=\"size-4 shrink-0\" />\n Back\n </button>\n <div className=\"h-5 w-px bg-[var(--color-border-seam)]\" />\n <PackageCheck className=\"size-5 shrink-0 text-[var(--color-text-primary)]\" />\n <h1 className=\"text-lg font-semibold text-[var(--color-text-primary)] truncate\">\n Submission Queue\n </h1>\n {totalCount > 0 && (\n <span className=\"shrink-0 rounded-full bg-[var(--color-status-warning-bg-subtle)] px-2 py-0.5 text-xs font-semibold text-[var(--color-status-warning-text)]\">\n {totalCount}\n </span>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => void loadProducts(statusFilter)}\n className=\"shrink-0 inline-flex items-center gap-2 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-sm text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors disabled:opacity-50\"\n disabled={loading}\n >\n <RefreshCw className={`size-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n </div>\n\n {/* Status filter pills */}\n <div className=\"mt-3 flex gap-1.5 flex-wrap\">\n {STATUS_FILTERS.map((f) => (\n <button\n key={f.value}\n type=\"button\"\n onClick={() => setStatusFilter(f.value)}\n className={`rounded-full px-3.5 py-1 text-xs font-medium transition-colors ${\n statusFilter === f.value\n ? 'bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]'\n : 'bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)]'\n }`}\n >\n {f.label}\n {f.value === 'PENDING_REVIEW' &&\n pendingCount > 0 &&\n statusFilter !== 'PENDING_REVIEW' && (\n <span className=\"ml-1.5 rounded-full bg-[var(--color-status-warning-text)] px-1.5 py-0.5 text-[10px] text-white\">\n {pendingCount}\n </span>\n )}\n {f.value === 'VERSION_UPDATES' &&\n versionUpdateCount > 0 &&\n statusFilter !== 'VERSION_UPDATES' && (\n <span className=\"ml-1.5 rounded-full bg-[var(--color-status-info-text)] px-1.5 py-0.5 text-[10px] text-white\">\n {versionUpdateCount}\n </span>\n )}\n </button>\n ))}\n </div>\n </div>\n </header>\n\n <main className=\"mx-auto max-w-5xl space-y-4 p-6\">\n <PagePurpose className=\"mb-2\">\n Every publisher submission lands here for your review. Inspect the manifest, permissions,\n and package details — then approve to publish or reject with a clear reason the developer\n will see.\n </PagePurpose>\n\n {error && (\n <div\n role=\"alert\"\n className=\"rounded-lg border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-3 text-sm text-[var(--color-text-danger)]\"\n >\n {error}\n </div>\n )}\n\n {statusFilter === 'VERSION_UPDATES' ? (\n loading && versionApps.length === 0 ? (\n <div className=\"flex items-center justify-center py-24\">\n <RefreshCw className=\"size-6 animate-spin text-[var(--color-text-muted)]\" />\n </div>\n ) : versionApps.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No pending version updates\"\n description=\"All published apps are up to date. When a developer submits a new version, it will appear here for your review.\"\n />\n ) : (\n <ul className=\"space-y-4\">\n {versionApps.map((app) => {\n const pendingVersions = app.versions.edges\n .map((e) => e.node)\n .filter((v) => v.status === 'pending_review');\n if (pendingVersions.length === 0) return null;\n return (\n <li\n key={app.id}\n className=\"overflow-hidden rounded-xl border border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)]\"\n >\n {/* App header */}\n <div className=\"flex items-center gap-4 p-5 border-b border-[var(--color-border-seam)]\">\n {app.iconUrl ? (\n <img\n src={app.iconUrl}\n alt=\"\"\n className=\"size-12 shrink-0 rounded-xl object-cover shadow-sm\"\n />\n ) : (\n <div className=\"flex size-12 shrink-0 items-center justify-center rounded-xl bg-[var(--color-surface-muted)] text-sm font-bold text-[var(--color-text-muted)] uppercase\">\n {app.name.slice(0, 2)}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h3 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {app.name}\n </h3>\n <span className=\"inline-flex items-center gap-1 rounded-full bg-[var(--color-status-info-bg-subtle)] px-2 py-0.5 text-[11px] font-semibold text-[var(--color-status-info-text)]\">\n <GitBranch className=\"size-3\" />\n {pendingVersions.length} version\n {pendingVersions.length !== 1 ? 's' : ''} pending\n </span>\n </div>\n {(app.shortDescription ?? app.description) && (\n <p className=\"mt-0.5 text-sm text-[var(--color-text-secondary)] line-clamp-1\">\n {app.shortDescription ?? app.description}\n </p>\n )}\n </div>\n <a\n href={`/devportal/apps/${app.id}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"shrink-0 inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <ExternalLink className=\"size-3.5\" />\n Devportal\n </a>\n </div>\n\n {/* Pending versions */}\n <div className=\"divide-y divide-[var(--color-border-seam)]\">\n {pendingVersions.map((ver) => (\n <div key={ver.id} className=\"p-5 space-y-3\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <GitBranch className=\"size-4 text-[var(--color-text-secondary)] shrink-0\" />\n <span className=\"font-mono font-semibold text-sm text-[var(--color-text-primary)]\">\n {ver.version}\n </span>\n {ver.isLatest && (\n <span className=\"rounded-full bg-[var(--color-surface-muted)] px-2 py-0.5 text-[10px] text-[var(--color-text-secondary)]\">\n Latest\n </span>\n )}\n <span className=\"rounded-full bg-[var(--color-status-warning-bg-subtle)] px-2 py-0.5 text-[10px] font-medium text-[var(--color-status-warning-text)] uppercase\">\n New Version\n </span>\n <span className=\"ml-auto flex items-center gap-1 text-xs text-[var(--color-text-secondary)]\">\n <Clock className=\"size-3\" />\n {formatDate(ver.createdAt)}\n </span>\n </div>\n\n {ver.releaseNotes && (\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {ver.releaseNotes}\n </p>\n )}\n\n <div className=\"flex flex-wrap gap-2\">\n {ver.packageUrl && (\n <button\n type=\"button\"\n onClick={() => void downloadPackage(ver.id)}\n disabled={downloadingVersionId === ver.id}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors disabled:opacity-50\"\n >\n {downloadingVersionId === ver.id ? (\n <RefreshCw className=\"size-3.5 animate-spin\" />\n ) : (\n <Download className=\"size-3.5\" />\n )}\n Download Package\n {ver.packageSize != null && (\n <span className=\"text-[var(--color-text-muted)]\">\n ({ver.packageSize} bytes)\n </span>\n )}\n </button>\n )}\n {ver.manifest && (\n <button\n type=\"button\"\n onClick={() => setViewingId(viewingId === ver.id ? null : ver.id)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <FileJson className=\"size-3.5\" />\n {viewingId === ver.id ? 'Hide manifest' : 'View manifest'}\n {viewingId === ver.id ? (\n <ChevronUp className=\"size-3\" />\n ) : (\n <ChevronDown className=\"size-3\" />\n )}\n </button>\n )}\n </div>\n\n {viewingId === ver.id && ver.manifest && (\n <pre className=\"overflow-x-auto rounded-lg border border-[var(--color-border-seam)] bg-[var(--color-surface-default)] p-4 text-[11px] leading-relaxed text-[var(--color-text-primary)] max-h-48 overflow-y-auto\">\n {JSON.stringify(ver.manifest, null, 2)}\n </pre>\n )}\n\n {/* Reject reason input */}\n {versionRejectingId === ver.id && versionRejectAppId === app.id && (\n <div className=\"rounded-lg border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)]/30 p-3 space-y-2\">\n <p className=\"text-xs font-semibold text-[var(--color-text-danger)]\">\n Rejection reason (the developer will see this)\n </p>\n <textarea\n value={versionRejectReason}\n onChange={(e) => setVersionRejectReason(e.target.value)}\n rows={2}\n className=\"w-full rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n placeholder=\"Be specific — what needs to change before this version can be approved…\"\n />\n <div className=\"flex gap-2 justify-end\">\n <button\n type=\"button\"\n onClick={() => {\n setVersionRejectingId(null);\n setVersionRejectReason('');\n setVersionRejectAppId(null);\n }}\n className=\"rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() =>\n void rejectVersion(ver.id, app.id, versionRejectReason)\n }\n disabled={\n !versionRejectReason.trim() || versionActingId === ver.id\n }\n className=\"rounded-md bg-[var(--color-surface-danger)] px-3 py-1.5 text-xs font-semibold text-[var(--color-text-on-danger)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n Submit rejection\n </button>\n </div>\n </div>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => void approveVersion(ver.id, app.id, '')}\n disabled={versionActingId === ver.id}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-[var(--color-surface-success)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-on-success)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n {versionActingId === ver.id ? (\n <RefreshCw className=\"size-3.5 animate-spin\" />\n ) : (\n <Check className=\"size-3.5\" />\n )}\n Approve version\n </button>\n {versionRejectingId !== ver.id && (\n <button\n type=\"button\"\n onClick={() => {\n setVersionRejectingId(ver.id);\n setVersionRejectReason('');\n setVersionRejectAppId(app.id);\n }}\n disabled={versionActingId === ver.id}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-danger)] hover:bg-[var(--color-surface-danger)] hover:text-[var(--color-text-on-danger)] disabled:opacity-50 transition-colors\"\n >\n <X className=\"size-3.5\" />\n Reject version\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n </li>\n );\n })}\n </ul>\n )\n ) : loading && products.length === 0 ? (\n <div className=\"flex items-center justify-center py-24\">\n <RefreshCw className=\"size-6 animate-spin text-[var(--color-text-muted)]\" />\n </div>\n ) : products.length === 0 ? (\n <IllustratedEmptyState\n illustration={statusFilter === 'PENDING_REVIEW' ? 'empty-notifications' : 'empty-data'}\n title={\n statusFilter === 'PENDING_REVIEW' ? 'Queue is clear' : 'No products match this filter'\n }\n description={\n statusFilter === 'PENDING_REVIEW'\n ? 'No submissions are awaiting review. New submissions will appear here as publishers send them in.'\n : 'Nothing matches the current filter. Try switching to a different status above.'\n }\n />\n ) : (\n <ul className=\"space-y-3\">\n {products.map((p) => (\n <li\n key={p.id}\n className=\"overflow-hidden rounded-xl border border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)] transition-[box-shadow,border-color] hover:border-[var(--color-border-strong)] hover:shadow-[var(--shadow-elevation-2)]\"\n >\n {/* Card body */}\n <div className=\"flex items-start gap-4 p-5\">\n {/* App icon */}\n {p.icon ? (\n <img\n src={p.icon}\n alt=\"\"\n className=\"size-14 shrink-0 rounded-xl object-cover shadow-sm\"\n />\n ) : (\n <div className=\"flex size-14 shrink-0 items-center justify-center rounded-xl bg-[var(--color-surface-muted)] text-sm font-bold text-[var(--color-text-muted)] uppercase\">\n {p.type.slice(0, 2)}\n </div>\n )}\n\n {/* Main info */}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h3 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {p.name}\n </h3>\n <span\n className={`rounded-full px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${typeColor(p.type)}`}\n >\n {p.type}\n </span>\n <span\n className={`rounded-full px-2 py-0.5 text-[11px] font-medium ${statusColor(p.status)}`}\n >\n {p.status.replace('_', ' ')}\n </span>\n </div>\n\n <div className=\"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--color-text-secondary)]\">\n <span className=\"flex items-center gap-1\">\n <Hash className=\"size-3\" />\n <span className=\"font-mono\">{p.slug}</span>\n </span>\n {p.publisher && (\n <span className=\"flex items-center gap-1\">\n <User className=\"size-3\" />\n {p.publisher.name}\n {p.publisher.email && (\n <span className=\"text-[var(--color-text-muted)]\">\n ({p.publisher.email})\n </span>\n )}\n </span>\n )}\n {p.submittedAt && (\n <span className=\"flex items-center gap-1\">\n <Clock className=\"size-3\" />\n {formatDate(p.submittedAt)}\n </span>\n )}\n <span className=\"flex items-center gap-1\">\n <Tag className=\"size-3\" />\n {formatPriceForModel(p.price, p.currency, p.pricingModel)}\n </span>\n </div>\n\n {p.description && (\n <p className=\"mt-2 line-clamp-2 text-sm text-[var(--color-text-secondary)]\">\n {p.description}\n </p>\n )}\n </div>\n </div>\n\n {/* Action bar */}\n <div className=\"flex flex-wrap items-center justify-between gap-2 border-t border-[var(--color-border-seam)] bg-[var(--color-surface-muted)] px-5 py-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n {/* View in devportal */}\n {p.productId && (\n <a\n href={`/devportal/apps/${p.productId}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n <ExternalLink className=\"size-3.5\" />\n Devportal\n </a>\n )}\n\n {/* Package download for NODE/WORKFLOW. Always calls the refresh mutation\n to get a fresh presigned URL (stored URLs expire in 1h). */}\n {PACKAGE_TYPES.has(p.type) &&\n (() => {\n // Resolve the version ID to use with the refresh mutation\n const versionId = p.productId\n ? (appVersionInfo[p.productId]?.versionId ??\n versionApps.find((va) => va.id === p.productId)?.versions?.edges?.[0]\n ?.node?.id)\n : undefined;\n // If we have no version ID yet, check if we at least have zipFileUrl\n // (new submissions populated by the backend fix)\n if (!versionId && !p.zipFileUrl) return null;\n const isLoading = downloadingVersionId === versionId;\n if (versionId) {\n return (\n <button\n type=\"button\"\n onClick={() => void downloadPackage(versionId)}\n disabled={isLoading}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors disabled:opacity-50\"\n >\n {isLoading ? (\n <RefreshCw className=\"size-3.5 animate-spin\" />\n ) : (\n <Download className=\"size-3.5\" />\n )}\n Download Package\n </button>\n );\n }\n // Fallback: direct link when we have zipFileUrl but no versionId yet\n return (\n <a\n href={p.zipFileUrl!}\n download\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)] transition-colors\"\n >\n <Download className=\"size-3.5\" />\n Download Package\n </a>\n );\n })()}\n\n {/* Test in workspace for NODE/WORKFLOW */}\n {PACKAGE_TYPES.has(p.type) && (\n <button\n type=\"button\"\n onClick={() => setTestingProduct(p)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-accent)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-accent)] hover:bg-[var(--color-surface-accent-muted)] transition-colors\"\n >\n <FlaskConical className=\"size-3.5\" />\n Test in workspace\n </button>\n )}\n\n {/* Show manifest / details toggle */}\n <button\n type=\"button\"\n onClick={() => setViewingId(viewingId === p.id ? null : p.id)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n <FileJson className=\"size-3.5\" />\n {viewingId === p.id ? 'Hide details' : 'Inspect details'}\n {viewingId === p.id ? (\n <ChevronUp className=\"size-3\" />\n ) : (\n <ChevronDown className=\"size-3\" />\n )}\n </button>\n </div>\n\n <div className=\"flex items-center gap-2\">\n {p.status !== 'PUBLISHED' && (\n <button\n type=\"button\"\n onClick={() => void approve(p.id)}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-[var(--color-surface-success)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-on-success)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n <Check className=\"size-3.5\" />\n Approve\n </button>\n )}\n {p.status !== 'REJECTED' && (\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(p.id);\n setRejectReason('');\n }}\n disabled={actingId === p.id}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)] px-4 py-1.5 text-xs font-semibold text-[var(--color-text-danger)] hover:bg-[var(--color-surface-danger)] hover:text-[var(--color-text-on-danger)] disabled:opacity-50 transition-colors\"\n >\n <X className=\"size-3.5\" />\n Reject\n </button>\n )}\n </div>\n </div>\n\n {/* Details panel */}\n {viewingId === p.id && (\n <div className=\"border-t border-[var(--color-border-seam)] bg-[var(--color-surface-muted)] p-5 space-y-5\">\n {/* Metadata grid */}\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-3 text-xs sm:grid-cols-3\">\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Store product ID\n </dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)] break-all\">\n {p.id}\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">Slug</dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)]\">\n {p.slug}\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Type / Nature\n </dt>\n <dd className=\"mt-0.5 text-[var(--color-text-primary)]\">\n {p.type} · {p.nature}\n </dd>\n </div>\n {p.category && (\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Category\n </dt>\n <dd className=\"mt-0.5 text-[var(--color-text-primary)]\">{p.category}</dd>\n </div>\n )}\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">Pricing</dt>\n <dd className=\"mt-0.5 text-[var(--color-text-primary)]\">\n {formatPriceForModel(p.price, p.currency, p.pricingModel)}{' '}\n <span className=\"text-[var(--color-text-muted)]\">({p.pricingModel})</span>\n </dd>\n </div>\n {p.productId && (\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Devportal app ID\n </dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)] break-all\">\n {p.productId}\n </dd>\n </div>\n )}\n {p.submittedBy && (\n <div>\n <dt className=\"font-medium text-[var(--color-text-secondary)]\">\n Submitted by (actor)\n </dt>\n <dd className=\"mt-0.5 font-mono text-[var(--color-text-primary)] break-all\">\n {p.submittedBy}\n </dd>\n </div>\n )}\n </div>\n\n {/* Required permissions */}\n {p.requiredPermissions && p.requiredPermissions.length > 0 && (\n <div>\n <h4 className=\"mb-2 flex items-center gap-1.5 text-xs font-semibold text-[var(--color-text-secondary)] uppercase tracking-wide\">\n <ShieldCheck className=\"size-3.5 text-[var(--color-status-success-text)]\" />\n Required Permissions\n </h4>\n <div className=\"flex flex-wrap gap-1.5\">\n {p.requiredPermissions.map((perm) => (\n <span\n key={perm}\n className=\"inline-flex items-center gap-1 rounded-md bg-[var(--color-surface-default)] border border-[var(--color-border-seam)] px-2 py-1 text-xs font-mono text-[var(--color-text-primary)]\"\n >\n {perm}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Manifest JSON */}\n {p.manifest && (\n <div>\n <h4 className=\"mb-2 flex items-center gap-1.5 text-xs font-semibold text-[var(--color-text-secondary)] uppercase tracking-wide\">\n <FileJson className=\"size-3.5\" />\n Manifest\n </h4>\n <pre className=\"overflow-x-auto rounded-lg border border-[var(--color-border-seam)] bg-[var(--color-surface-default)] p-4 text-[11px] leading-relaxed text-[var(--color-text-primary)] max-h-72 overflow-y-auto scrollbar-thin\">\n {JSON.stringify(p.manifest, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n\n {/* Rejection form */}\n {rejectingId === p.id && (\n <div className=\"border-t border-[var(--color-border-seam)] bg-[var(--color-surface-danger-muted)]/30 px-5 py-4\">\n <p className=\"mb-2 text-xs font-semibold text-[var(--color-text-danger)]\">\n Reject — provide a reason (the publisher will see this)\n </p>\n <textarea\n id={`reject-reason-${p.id}`}\n aria-label=\"Rejection reason\"\n value={rejectReason}\n onChange={(e) => setRejectReason(e.target.value)}\n rows={3}\n required\n aria-required=\"true\"\n className=\"w-full rounded-lg border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] focus:border-[var(--color-border-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n placeholder=\"Be specific — e.g. 'Manifest is missing the identity.version field' or 'ZIP file is empty'…\"\n />\n <div className=\"mt-2 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setRejectingId(null);\n setRejectReason('');\n }}\n className=\"rounded-md border border-[var(--color-border-default)] bg-[var(--color-surface-default)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)] transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void reject(p.id)}\n disabled={!rejectReason.trim() || actingId === p.id}\n className=\"rounded-md bg-[var(--color-surface-danger)] px-3 py-1.5 text-xs font-semibold text-[var(--color-text-on-danger)] hover:opacity-90 disabled:opacity-50 transition-opacity\"\n >\n Submit rejection\n </button>\n </div>\n </div>\n )}\n </li>\n ))}\n </ul>\n )}\n </main>\n\n {/* Test in workspace modal */}\n {testingProduct && (\n <InstallAppModal\n isOpen={true}\n onClose={() => setTestingProduct(null)}\n app={{\n id: testingProduct.id,\n name: testingProduct.name,\n slug: testingProduct.slug,\n icon: testingProduct.icon ?? undefined,\n type: testingProduct.type,\n permissions: testingProduct.requiredPermissions?.length\n ? testingProduct.requiredPermissions\n : undefined,\n }}\n purchaseState=\"free\"\n onInstallSuccess={() => {\n setTestingProduct(null);\n }}\n onInstallError={() => {}}\n />\n )}\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.714.5",
3
+ "version": "2026.714.6",
4
4
  "description": "Store microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [