@burdenoff/microfe-store 2026.703.1 → 2026.703.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,14 @@
1
1
  import { useStore as e } from "../providers/StoreProvider.js";
2
2
  import { formatPriceForModel as t } from "../utils/index.js";
3
- import { useCallback as n, useEffect as r, useState as i } from "react";
4
- import { ArrowLeft as a, Check as o, ChevronDown as s, ChevronUp as c, PackageCheck as l, RefreshCw as u, X as d } from "lucide-react";
5
- import { graphqlFetch as f } from "@burdenoff/fe-libs/shared/graphql";
6
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
7
- import { useNavigate as h } from "react-router-dom";
8
- import { IllustratedEmptyState as g, NextSteps as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
3
+ import { InstallAppModal as n } from "../components/InstallAppModal.js";
4
+ import { useCallback as r, useEffect as i, useState as a } from "react";
5
+ import { ArrowLeft as ee, Check as o, ChevronDown as s, ChevronUp as c, Clock as l, Download as u, ExternalLink as d, FileJson as f, FlaskConical as te, GitBranch as p, Hash as ne, PackageCheck as re, RefreshCw as m, ShieldCheck as ie, Tag as ae, User as oe, X as h } from "lucide-react";
6
+ import { graphqlFetch as g } from "@burdenoff/fe-libs/shared/graphql";
7
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
8
+ import { useNavigate as se } from "react-router-dom";
9
+ import { IllustratedEmptyState as ce, PagePurpose as le } from "@burdenoff/fe-libs/ui";
9
10
  //#region src/pages/AdminSubmissionsQueuePage.tsx
10
- var y = "\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 publisher {\n id\n name\n email\n }\n }\n }\n }\n", b = "\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 publisher {\n id\n name\n email\n }\n }\n }\n", x = "\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n", S = "\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\n }\n }\n", C = [
11
+ var ue = "\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 manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n }\n", de = "\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 manifest\n requiredPermissions\n publisher {\n id\n name\n email\n }\n }\n }\n", fe = "\n mutation ApproveProduct($id: ID!, $notes: String) {\n approveProduct(id: $id, notes: $notes) {\n id\n status\n publishedAt\n }\n }\n", pe = "\n mutation RejectProduct($id: ID!, $reason: String!) {\n rejectProduct(id: $id, reason: $reason) {\n id\n status\n rejectedReason\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
12
  {
12
13
  label: "Pending review",
13
14
  value: "PENDING_REVIEW"
@@ -20,397 +21,733 @@ var y = "\n query PendingReviewProducts($limit: Int, $offset: Int) {\n pendi
20
21
  label: "Rejected",
21
22
  value: "REJECTED"
22
23
  },
24
+ {
25
+ label: "Version Updates",
26
+ value: "VERSION_UPDATES"
27
+ },
23
28
  {
24
29
  label: "All",
25
30
  value: "ALL"
26
31
  }
27
- ], w = () => {
28
- let w = h(), { authToken: T, basePath: E } = e(), [D, O] = i([]), [k, A] = i(0), [j, M] = i(!1), [N, P] = i(null), [F, I] = i(null), [L, R] = i("PENDING_REVIEW"), [z, B] = i(null), [V, H] = i(""), [U, W] = i(null), G = n(async (e) => {
29
- M(!0), P(null);
32
+ ], y = {
33
+ NODE: "bg-[var(--color-status-info-bg-subtle)] text-[var(--color-status-info-text)]",
34
+ WORKFLOW: "bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]",
35
+ INTEGRATION: "bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]",
36
+ VIBEMODULE: "bg-[var(--color-surface-accent-muted)] text-[var(--color-text-accent)]"
37
+ }, b = {
38
+ PENDING_REVIEW: "bg-[var(--color-status-warning-bg-subtle)] text-[var(--color-status-warning-text)]",
39
+ PUBLISHED: "bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]",
40
+ REJECTED: "bg-[var(--color-status-error-bg-subtle)] text-[var(--color-status-error-text)]"
41
+ }, x = new Set([
42
+ "NODE",
43
+ "WORKFLOW",
44
+ "VIBEMODULE",
45
+ "PARSER",
46
+ "DATASINK",
47
+ "CONSOLE"
48
+ ]);
49
+ function ve(e) {
50
+ return y[e] ?? "bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]";
51
+ }
52
+ function ye(e) {
53
+ return b[e] ?? "bg-[var(--color-surface-muted)] text-[var(--color-text-secondary)]";
54
+ }
55
+ function S(e) {
56
+ return e ? new Date(e).toLocaleString(void 0, {
57
+ month: "short",
58
+ day: "numeric",
59
+ year: "numeric",
60
+ hour: "2-digit",
61
+ minute: "2-digit"
62
+ }) : "—";
63
+ }
64
+ var C = () => {
65
+ let y = se(), { authToken: b, basePath: C } = e(), [w, T] = a([]), [E, D] = a(0), [O, k] = a(!1), [A, j] = a(null), [M, N] = a(null), [P, be] = a("PENDING_REVIEW"), [xe, F] = a(null), [I, L] = a(""), [R, z] = a(null), [B, V] = a(null), [H, Se] = a([]), [U, Ce] = a(0), [W, G] = a(null), [K, q] = a(null), [J, Y] = a(""), [we, X] = a(null), Z = r(async () => {
66
+ k(!0), j(null);
67
+ try {
68
+ let e = await g({
69
+ gateway: "global",
70
+ query: me,
71
+ variables: {
72
+ limit: 50,
73
+ offset: 0
74
+ },
75
+ authToken: b || void 0
76
+ });
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);
79
+ } catch (e) {
80
+ j(e instanceof Error ? e.message : "Failed to load version updates");
81
+ } finally {
82
+ k(!1);
83
+ }
84
+ }, [b]), Te = async (e, t, n) => {
85
+ G(e), j(null);
86
+ try {
87
+ let t = await g({
88
+ gateway: "global",
89
+ query: he,
90
+ variables: {
91
+ id: e,
92
+ notes: n || null
93
+ },
94
+ authToken: b || void 0
95
+ });
96
+ if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Approval failed");
97
+ await Z();
98
+ } catch (e) {
99
+ j(e instanceof Error ? e.message : "Approval failed");
100
+ } finally {
101
+ G(null);
102
+ }
103
+ }, Ee = async (e, t, n) => {
104
+ if (!n.trim()) {
105
+ j("Rejection reason is required");
106
+ return;
107
+ }
108
+ G(e), j(null);
109
+ try {
110
+ let t = await g({
111
+ gateway: "global",
112
+ query: ge,
113
+ variables: {
114
+ id: e,
115
+ reason: n.trim()
116
+ },
117
+ authToken: b || void 0
118
+ });
119
+ if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Rejection failed");
120
+ q(null), Y(""), X(null), await Z();
121
+ } catch (e) {
122
+ j(e instanceof Error ? e.message : "Rejection failed");
123
+ } finally {
124
+ G(null);
125
+ }
126
+ }, Q = r(async (e) => {
127
+ if (e === "VERSION_UPDATES") {
128
+ await Z();
129
+ return;
130
+ }
131
+ k(!0), j(null);
30
132
  try {
31
133
  if (e === "PENDING_REVIEW") {
32
- let e = await f({
134
+ let e = await g({
33
135
  gateway: "global",
34
- query: y,
136
+ query: ue,
35
137
  variables: {
36
138
  limit: 100,
37
139
  offset: 0
38
140
  },
39
- authToken: T || void 0
141
+ authToken: b || void 0
40
142
  });
41
143
  if (e.errors?.length) throw Error(e.errors[0]?.message ?? "Failed to load pending products");
42
- O(e.data?.pendingReviewProducts.products ?? []), A(e.data?.pendingReviewProducts.totalCount ?? 0);
144
+ T(e.data?.pendingReviewProducts.products ?? []), D(e.data?.pendingReviewProducts.totalCount ?? 0);
43
145
  } else {
44
- let t = await f({
146
+ let t = await g({
45
147
  gateway: "global",
46
- query: b,
148
+ query: de,
47
149
  variables: {
48
150
  limit: 100,
49
151
  offset: 0,
50
152
  ...e !== "ALL" && { status: e }
51
153
  },
52
- authToken: T || void 0
154
+ authToken: b || void 0
53
155
  });
54
156
  if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Failed to load products");
55
157
  let n = t.data?.products ?? [];
56
- O(n), A(n.length);
158
+ T(n), D(n.length);
57
159
  }
58
160
  } catch (e) {
59
- P(e instanceof Error ? e.message : "Failed to load products");
161
+ j(e instanceof Error ? e.message : "Failed to load products");
60
162
  } finally {
61
- M(!1);
163
+ k(!1);
62
164
  }
63
- }, [T]);
64
- r(() => {
65
- G(L);
66
- }, [G, L]);
67
- let K = async (e) => {
68
- I(e), P(null);
165
+ }, [b, Z]);
166
+ i(() => {
167
+ Q(P);
168
+ }, [Q, P]), i(() => {
169
+ Z();
170
+ }, [Z]);
171
+ let De = async (e) => {
172
+ N(e), j(null);
69
173
  try {
70
- let t = await f({
174
+ let t = await g({
71
175
  gateway: "global",
72
- query: x,
176
+ query: fe,
73
177
  variables: {
74
178
  id: e,
75
179
  notes: null
76
180
  },
77
- authToken: T || void 0
181
+ authToken: b || void 0
78
182
  });
79
183
  if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Approval failed");
80
- await G(L);
184
+ await Q(P);
81
185
  } catch (e) {
82
- P(e instanceof Error ? e.message : "Approval failed");
186
+ j(e instanceof Error ? e.message : "Approval failed");
83
187
  } finally {
84
- I(null);
188
+ N(null);
85
189
  }
86
- }, q = async (e) => {
87
- if (!V.trim()) {
88
- P("Rejection reason is required");
190
+ }, Oe = async (e) => {
191
+ if (!I.trim()) {
192
+ j("Rejection reason is required");
89
193
  return;
90
194
  }
91
- I(e), P(null);
195
+ N(e), j(null);
92
196
  try {
93
- let t = await f({
197
+ let t = await g({
94
198
  gateway: "global",
95
- query: S,
199
+ query: pe,
96
200
  variables: {
97
201
  id: e,
98
- reason: V.trim()
202
+ reason: I.trim()
99
203
  },
100
- authToken: T || void 0
204
+ authToken: b || void 0
101
205
  });
102
206
  if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Rejection failed");
103
- B(null), H(""), await G(L);
207
+ F(null), L(""), await Q(P);
104
208
  } catch (e) {
105
- P(e instanceof Error ? e.message : "Rejection failed");
209
+ j(e instanceof Error ? e.message : "Rejection failed");
106
210
  } finally {
107
- I(null);
211
+ N(null);
108
212
  }
109
- };
110
- return /* @__PURE__ */ m("div", {
111
- className: "min-h-screen bg-surface-default",
112
- children: [/* @__PURE__ */ p("header", {
113
- className: "border-b border-border-seam bg-surface-raised",
114
- children: /* @__PURE__ */ m("div", {
115
- className: "mx-auto max-w-7xl px-6 py-4",
116
- children: [/* @__PURE__ */ m("div", {
117
- className: "flex items-center justify-between",
118
- children: [/* @__PURE__ */ m("div", {
119
- className: "flex items-center gap-3",
120
- children: [/* @__PURE__ */ m("button", {
121
- type: "button",
122
- onClick: () => w(`${E}/dashboard`),
123
- className: "inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover hover:text-text-primary",
124
- children: [/* @__PURE__ */ p(a, { className: "size-4" }), "Back"]
125
- }), /* @__PURE__ */ m("div", {
126
- className: "flex items-center gap-2",
213
+ }, $ = w.filter((e) => e.status === "PENDING_REVIEW").length;
214
+ return /* @__PURE__ */ v("div", {
215
+ className: "min-h-screen bg-[var(--color-surface-default)]",
216
+ children: [
217
+ /* @__PURE__ */ _("header", {
218
+ className: "sticky top-0 z-10 border-b border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)]",
219
+ children: /* @__PURE__ */ v("div", {
220
+ className: "mx-auto max-w-5xl px-6 py-4",
221
+ children: [/* @__PURE__ */ v("div", {
222
+ className: "flex items-center justify-between gap-4",
223
+ children: [/* @__PURE__ */ v("div", {
224
+ className: "flex items-center gap-3 min-w-0",
127
225
  children: [
128
- /* @__PURE__ */ p(l, { className: "size-5 text-text-primary" }),
129
- /* @__PURE__ */ p("h1", {
130
- className: "text-xl font-semibold text-text-primary",
131
- children: "Submission queue"
226
+ /* @__PURE__ */ v("button", {
227
+ type: "button",
228
+ onClick: () => y(`${C}/dashboard`),
229
+ 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",
230
+ children: [/* @__PURE__ */ _(ee, { className: "size-4 shrink-0" }), "Back"]
132
231
  }),
133
- /* @__PURE__ */ p("span", {
134
- className: "rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent",
135
- children: k
232
+ /* @__PURE__ */ _("div", { className: "h-5 w-px bg-[var(--color-border-seam)]" }),
233
+ /* @__PURE__ */ _(re, { className: "size-5 shrink-0 text-[var(--color-text-primary)]" }),
234
+ /* @__PURE__ */ _("h1", {
235
+ className: "text-lg font-semibold text-[var(--color-text-primary)] truncate",
236
+ children: "Submission Queue"
237
+ }),
238
+ E > 0 && /* @__PURE__ */ _("span", {
239
+ 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)]",
240
+ children: E
136
241
  })
137
242
  ]
243
+ }), /* @__PURE__ */ v("button", {
244
+ type: "button",
245
+ onClick: () => void Q(P),
246
+ 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",
247
+ disabled: O,
248
+ children: [/* @__PURE__ */ _(m, { className: `size-4 ${O ? "animate-spin" : ""}` }), "Refresh"]
138
249
  })]
139
- }), /* @__PURE__ */ m("button", {
140
- type: "button",
141
- onClick: () => void G(L),
142
- className: "inline-flex items-center gap-2 rounded-md border border-border-default bg-surface-default px-3 py-1.5 text-sm text-text-primary hover:bg-surface-hover",
143
- disabled: j,
144
- children: [/* @__PURE__ */ p(u, { className: `size-4 ${j ? "animate-spin" : ""}` }), "Refresh"]
250
+ }), /* @__PURE__ */ _("div", {
251
+ className: "mt-3 flex gap-1.5 flex-wrap",
252
+ children: _e.map((e) => /* @__PURE__ */ v("button", {
253
+ type: "button",
254
+ onClick: () => be(e.value),
255
+ className: `rounded-full px-3.5 py-1 text-xs font-medium transition-colors ${P === 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)]"}`,
256
+ children: [
257
+ e.label,
258
+ e.value === "PENDING_REVIEW" && $ > 0 && P !== "PENDING_REVIEW" && /* @__PURE__ */ _("span", {
259
+ className: "ml-1.5 rounded-full bg-[var(--color-status-warning-text)] px-1.5 py-0.5 text-[10px] text-white",
260
+ children: $
261
+ }),
262
+ e.value === "VERSION_UPDATES" && U > 0 && P !== "VERSION_UPDATES" && /* @__PURE__ */ _("span", {
263
+ className: "ml-1.5 rounded-full bg-[var(--color-status-info-text)] px-1.5 py-0.5 text-[10px] text-white",
264
+ children: U
265
+ })
266
+ ]
267
+ }, e.value))
145
268
  })]
146
- }), /* @__PURE__ */ p("div", {
147
- className: "mt-4 flex gap-2",
148
- children: C.map((e) => /* @__PURE__ */ p("button", {
149
- type: "button",
150
- onClick: () => R(e.value),
151
- className: `rounded-full px-3 py-1 text-xs font-medium transition-colors ${L === e.value ? "bg-surface-accent text-text-on-accent" : "bg-surface-muted text-text-secondary hover:bg-surface-hover"}`,
152
- children: e.label
153
- }, e.value))
154
- })]
155
- })
156
- }), /* @__PURE__ */ m("main", {
157
- className: "mx-auto max-w-7xl p-6",
158
- children: [
159
- /* @__PURE__ */ p(v, {
160
- className: "mb-4",
161
- children: "This is the marketplace gatekeeper. Every product a publisher submits lands here for review before customers can see it — open each one to inspect its details, pricing and publisher, then approve it to go live or reject it with a clear reason the publisher will read. Keeping this queue empty means new apps reach customers quickly."
162
- }),
163
- /* @__PURE__ */ p(_, {
164
- storageKey: "store-admin-submissions",
165
- steps: [
166
- {
167
- id: "review-pending",
168
- label: "Review the pending queue",
169
- description: "Start with submissions awaiting review and expand Details to inspect.",
170
- onClick: () => R("PENDING_REVIEW")
171
- },
172
- {
173
- id: "approve",
174
- label: "Approve solid submissions",
175
- description: "Approve a product to publish it instantly to the marketplace.",
176
- done: L === "PUBLISHED" && D.length > 0
177
- },
178
- {
179
- id: "reject-clear",
180
- label: "Reject with a clear reason",
181
- description: "Rejections require a reason publishers see it, so be specific."
182
- }
183
- ]
184
- }),
185
- N && /* @__PURE__ */ p("div", {
186
- role: "alert",
187
- className: "mb-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger",
188
- children: N
189
- }),
190
- j && D.length === 0 ? /* @__PURE__ */ p("output", {
191
- className: "block py-16 text-center text-text-secondary",
192
- children: "Loading submissions…"
193
- }) : D.length === 0 ? /* @__PURE__ */ p(g, {
194
- illustration: L === "PENDING_REVIEW" ? "empty-notifications" : "empty-data",
195
- title: L === "PENDING_REVIEW" ? "Queue is clear" : "No products match this filter",
196
- description: L === "PENDING_REVIEW" ? "There are no submissions awaiting review right now. New submissions will appear here as publishers send them in." : "Nothing matches the current status filter. Switch filters above to see products in other states."
197
- }) : /* @__PURE__ */ p("ul", {
198
- className: "space-y-3",
199
- children: D.map((e) => /* @__PURE__ */ m("li", {
200
- className: "overflow-hidden rounded-lg border border-border-seam bg-surface-raised transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]",
201
- children: [
202
- /* @__PURE__ */ m("div", {
203
- className: "flex items-start gap-4 p-4",
204
- children: [
205
- e.icon ? /* @__PURE__ */ p("img", {
269
+ })
270
+ }),
271
+ /* @__PURE__ */ v("main", {
272
+ className: "mx-auto max-w-5xl space-y-4 p-6",
273
+ children: [
274
+ /* @__PURE__ */ _(le, {
275
+ className: "mb-2",
276
+ children: "Every publisher submission lands here for your review. Inspect the manifest, permissions, and package details — then approve to publish or reject with a clear reason the developer will see."
277
+ }),
278
+ A && /* @__PURE__ */ _("div", {
279
+ role: "alert",
280
+ 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)]",
281
+ children: A
282
+ }),
283
+ P === "VERSION_UPDATES" ? O && H.length === 0 ? /* @__PURE__ */ _("div", {
284
+ className: "flex items-center justify-center py-24",
285
+ children: /* @__PURE__ */ _(m, { className: "size-6 animate-spin text-[var(--color-text-muted)]" })
286
+ }) : H.length === 0 ? /* @__PURE__ */ _(ce, {
287
+ illustration: "empty-data",
288
+ title: "No pending version updates",
289
+ description: "All published apps are up to date. When a developer submits a new version, it will appear here for your review."
290
+ }) : /* @__PURE__ */ _("ul", {
291
+ className: "space-y-4",
292
+ children: H.map((e) => {
293
+ let t = e.versions.edges.map((e) => e.node).filter((e) => e.status === "pending_review");
294
+ return t.length === 0 ? null : /* @__PURE__ */ v("li", {
295
+ className: "overflow-hidden rounded-xl border border-[var(--color-border-seam)] bg-[var(--color-surface-raised)] shadow-[var(--shadow-elevation-1)]",
296
+ children: [/* @__PURE__ */ v("div", {
297
+ className: "flex items-center gap-4 p-5 border-b border-[var(--color-border-seam)]",
298
+ children: [
299
+ e.iconUrl ? /* @__PURE__ */ _("img", {
300
+ src: e.iconUrl,
301
+ alt: "",
302
+ className: "size-12 shrink-0 rounded-xl object-cover shadow-sm"
303
+ }) : /* @__PURE__ */ _("div", {
304
+ 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",
305
+ children: e.name.slice(0, 2)
306
+ }),
307
+ /* @__PURE__ */ v("div", {
308
+ className: "flex-1 min-w-0",
309
+ children: [/* @__PURE__ */ v("div", {
310
+ className: "flex items-center gap-2 flex-wrap",
311
+ children: [/* @__PURE__ */ _("h3", {
312
+ className: "text-base font-semibold text-[var(--color-text-primary)]",
313
+ children: e.name
314
+ }), /* @__PURE__ */ v("span", {
315
+ 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)]",
316
+ children: [
317
+ /* @__PURE__ */ _(p, { className: "size-3" }),
318
+ t.length,
319
+ " version",
320
+ t.length === 1 ? "" : "s",
321
+ " pending"
322
+ ]
323
+ })]
324
+ }), (e.shortDescription ?? e.description) && /* @__PURE__ */ _("p", {
325
+ className: "mt-0.5 text-sm text-[var(--color-text-secondary)] line-clamp-1",
326
+ children: e.shortDescription ?? e.description
327
+ })]
328
+ }),
329
+ /* @__PURE__ */ v("a", {
330
+ href: `/devportal/apps/${e.id}`,
331
+ target: "_blank",
332
+ rel: "noreferrer",
333
+ 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",
334
+ children: [/* @__PURE__ */ _(d, { className: "size-3.5" }), "Devportal"]
335
+ })
336
+ ]
337
+ }), /* @__PURE__ */ _("div", {
338
+ className: "divide-y divide-[var(--color-border-seam)]",
339
+ children: t.map((t) => /* @__PURE__ */ v("div", {
340
+ className: "p-5 space-y-3",
341
+ children: [
342
+ /* @__PURE__ */ v("div", {
343
+ className: "flex items-center gap-2 flex-wrap",
344
+ children: [
345
+ /* @__PURE__ */ _(p, { className: "size-4 text-[var(--color-text-secondary)] shrink-0" }),
346
+ /* @__PURE__ */ _("span", {
347
+ className: "font-mono font-semibold text-sm text-[var(--color-text-primary)]",
348
+ children: t.version
349
+ }),
350
+ t.isLatest && /* @__PURE__ */ _("span", {
351
+ className: "rounded-full bg-[var(--color-surface-muted)] px-2 py-0.5 text-[10px] text-[var(--color-text-secondary)]",
352
+ children: "Latest"
353
+ }),
354
+ /* @__PURE__ */ _("span", {
355
+ 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",
356
+ children: "New Version"
357
+ }),
358
+ /* @__PURE__ */ v("span", {
359
+ className: "ml-auto flex items-center gap-1 text-xs text-[var(--color-text-secondary)]",
360
+ children: [/* @__PURE__ */ _(l, { className: "size-3" }), S(t.createdAt)]
361
+ })
362
+ ]
363
+ }),
364
+ t.releaseNotes && /* @__PURE__ */ _("p", {
365
+ className: "text-sm text-[var(--color-text-secondary)]",
366
+ children: t.releaseNotes
367
+ }),
368
+ /* @__PURE__ */ v("div", {
369
+ className: "flex flex-wrap gap-2",
370
+ children: [t.packageUrl && /* @__PURE__ */ v("a", {
371
+ href: t.packageUrl,
372
+ download: !0,
373
+ target: "_blank",
374
+ rel: "noreferrer",
375
+ 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",
376
+ children: [
377
+ /* @__PURE__ */ _(u, { className: "size-3.5" }),
378
+ "Download Package",
379
+ t.packageSize != null && /* @__PURE__ */ v("span", {
380
+ className: "text-[var(--color-text-muted)]",
381
+ children: [
382
+ "(",
383
+ t.packageSize,
384
+ " bytes)"
385
+ ]
386
+ })
387
+ ]
388
+ }), t.manifest && /* @__PURE__ */ v("button", {
389
+ type: "button",
390
+ onClick: () => z(R === t.id ? null : t.id),
391
+ 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",
392
+ children: [
393
+ /* @__PURE__ */ _(f, { className: "size-3.5" }),
394
+ R === t.id ? "Hide manifest" : "View manifest",
395
+ R === t.id ? /* @__PURE__ */ _(c, { className: "size-3" }) : /* @__PURE__ */ _(s, { className: "size-3" })
396
+ ]
397
+ })]
398
+ }),
399
+ R === t.id && t.manifest && /* @__PURE__ */ _("pre", {
400
+ 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",
401
+ children: JSON.stringify(t.manifest, null, 2)
402
+ }),
403
+ K === t.id && we === e.id && /* @__PURE__ */ v("div", {
404
+ className: "rounded-lg border border-[var(--color-border-danger)] bg-[var(--color-surface-danger-muted)]/30 p-3 space-y-2",
405
+ children: [
406
+ /* @__PURE__ */ _("p", {
407
+ className: "text-xs font-semibold text-[var(--color-text-danger)]",
408
+ children: "Rejection reason (the developer will see this)"
409
+ }),
410
+ /* @__PURE__ */ _("textarea", {
411
+ value: J,
412
+ onChange: (e) => Y(e.target.value),
413
+ rows: 2,
414
+ 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",
415
+ placeholder: "Be specific — what needs to change before this version can be approved…"
416
+ }),
417
+ /* @__PURE__ */ v("div", {
418
+ className: "flex gap-2 justify-end",
419
+ children: [/* @__PURE__ */ _("button", {
420
+ type: "button",
421
+ onClick: () => {
422
+ q(null), Y(""), X(null);
423
+ },
424
+ 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",
425
+ children: "Cancel"
426
+ }), /* @__PURE__ */ _("button", {
427
+ type: "button",
428
+ onClick: () => void Ee(t.id, e.id, J),
429
+ disabled: !J.trim() || W === t.id,
430
+ 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",
431
+ children: "Submit rejection"
432
+ })]
433
+ })
434
+ ]
435
+ }),
436
+ /* @__PURE__ */ v("div", {
437
+ className: "flex items-center gap-2",
438
+ children: [/* @__PURE__ */ v("button", {
439
+ type: "button",
440
+ onClick: () => void Te(t.id, e.id, ""),
441
+ disabled: W === t.id,
442
+ 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",
443
+ children: [W === t.id ? /* @__PURE__ */ _(m, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ _(o, { className: "size-3.5" }), "Approve version"]
444
+ }), K !== t.id && /* @__PURE__ */ v("button", {
445
+ type: "button",
446
+ onClick: () => {
447
+ q(t.id), Y(""), X(e.id);
448
+ },
449
+ disabled: W === t.id,
450
+ 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",
451
+ children: [/* @__PURE__ */ _(h, { className: "size-3.5" }), "Reject version"]
452
+ })]
453
+ })
454
+ ]
455
+ }, t.id))
456
+ })]
457
+ }, e.id);
458
+ })
459
+ }) : O && w.length === 0 ? /* @__PURE__ */ _("div", {
460
+ className: "flex items-center justify-center py-24",
461
+ children: /* @__PURE__ */ _(m, { className: "size-6 animate-spin text-[var(--color-text-muted)]" })
462
+ }) : w.length === 0 ? /* @__PURE__ */ _(ce, {
463
+ illustration: P === "PENDING_REVIEW" ? "empty-notifications" : "empty-data",
464
+ title: P === "PENDING_REVIEW" ? "Queue is clear" : "No products match this filter",
465
+ description: P === "PENDING_REVIEW" ? "No submissions are awaiting review. New submissions will appear here as publishers send them in." : "Nothing matches the current filter. Try switching to a different status above."
466
+ }) : /* @__PURE__ */ _("ul", {
467
+ className: "space-y-3",
468
+ children: w.map((e) => /* @__PURE__ */ v("li", {
469
+ 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)]",
470
+ children: [
471
+ /* @__PURE__ */ v("div", {
472
+ className: "flex items-start gap-4 p-5",
473
+ children: [e.icon ? /* @__PURE__ */ _("img", {
206
474
  src: e.icon,
207
475
  alt: "",
208
- className: "size-14 flex-shrink-0 rounded-md object-cover"
209
- }) : /* @__PURE__ */ p("div", {
210
- className: "flex size-14 flex-shrink-0 items-center justify-center rounded-md bg-surface-muted text-xs text-text-secondary",
211
- children: e.type
212
- }),
213
- /* @__PURE__ */ m("div", {
476
+ className: "size-14 shrink-0 rounded-xl object-cover shadow-sm"
477
+ }) : /* @__PURE__ */ _("div", {
478
+ 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",
479
+ children: e.type.slice(0, 2)
480
+ }), /* @__PURE__ */ v("div", {
214
481
  className: "min-w-0 flex-1",
215
482
  children: [
216
- /* @__PURE__ */ m("div", {
217
- className: "flex items-center gap-2",
483
+ /* @__PURE__ */ v("div", {
484
+ className: "flex flex-wrap items-center gap-2",
218
485
  children: [
219
- /* @__PURE__ */ p("h3", {
220
- className: "truncate text-base font-semibold text-text-primary",
486
+ /* @__PURE__ */ _("h3", {
487
+ className: "text-base font-semibold text-[var(--color-text-primary)]",
221
488
  children: e.name
222
489
  }),
223
- /* @__PURE__ */ p("span", {
224
- className: "rounded-full bg-surface-accent-muted px-2 py-0.5 text-xs font-medium text-text-accent",
490
+ /* @__PURE__ */ _("span", {
491
+ className: `rounded-full px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide ${ve(e.type)}`,
225
492
  children: e.type
226
493
  }),
227
- /* @__PURE__ */ p("span", {
228
- className: "rounded-full bg-surface-muted px-2 py-0.5 text-xs font-medium text-text-secondary",
229
- children: e.nature
494
+ /* @__PURE__ */ _("span", {
495
+ className: `rounded-full px-2 py-0.5 text-[11px] font-medium ${ye(e.status)}`,
496
+ children: e.status.replace("_", " ")
230
497
  })
231
498
  ]
232
499
  }),
233
- /* @__PURE__ */ p("div", {
234
- className: "mt-0.5 text-xs text-text-tertiary",
235
- children: e.slug
236
- }),
237
- /* @__PURE__ */ m("div", {
238
- className: "mt-1 flex items-center gap-3 text-xs text-text-secondary",
500
+ /* @__PURE__ */ v("div", {
501
+ className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-[var(--color-text-secondary)]",
239
502
  children: [
240
- /* @__PURE__ */ m("span", { children: ["Publisher: ", e.publisher?.name ?? "Unknown"] }),
241
- /* @__PURE__ */ m("span", { children: ["Price: ", t(e.price, e.currency, e.pricingModel)] }),
242
- e.submittedAt && /* @__PURE__ */ m("span", { children: ["Submitted ", new Date(e.submittedAt).toLocaleString()] })
503
+ /* @__PURE__ */ v("span", {
504
+ className: "flex items-center gap-1",
505
+ children: [/* @__PURE__ */ _(ne, { className: "size-3" }), /* @__PURE__ */ _("span", {
506
+ className: "font-mono",
507
+ children: e.slug
508
+ })]
509
+ }),
510
+ e.publisher && /* @__PURE__ */ v("span", {
511
+ className: "flex items-center gap-1",
512
+ children: [
513
+ /* @__PURE__ */ _(oe, { className: "size-3" }),
514
+ e.publisher.name,
515
+ e.publisher.email && /* @__PURE__ */ v("span", {
516
+ className: "text-[var(--color-text-muted)]",
517
+ children: [
518
+ "(",
519
+ e.publisher.email,
520
+ ")"
521
+ ]
522
+ })
523
+ ]
524
+ }),
525
+ e.submittedAt && /* @__PURE__ */ v("span", {
526
+ className: "flex items-center gap-1",
527
+ children: [/* @__PURE__ */ _(l, { className: "size-3" }), S(e.submittedAt)]
528
+ }),
529
+ /* @__PURE__ */ v("span", {
530
+ className: "flex items-center gap-1",
531
+ children: [/* @__PURE__ */ _(ae, { className: "size-3" }), t(e.price, e.currency, e.pricingModel)]
532
+ })
243
533
  ]
244
534
  }),
245
- e.description && /* @__PURE__ */ p("p", {
246
- className: "mt-2 line-clamp-2 text-sm text-text-secondary",
535
+ e.description && /* @__PURE__ */ _("p", {
536
+ className: "mt-2 line-clamp-2 text-sm text-[var(--color-text-secondary)]",
247
537
  children: e.description
248
538
  })
249
539
  ]
250
- }),
251
- /* @__PURE__ */ m("div", {
252
- className: "flex flex-shrink-0 flex-col gap-2",
540
+ })]
541
+ }),
542
+ /* @__PURE__ */ v("div", {
543
+ 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",
544
+ children: [/* @__PURE__ */ v("div", {
545
+ className: "flex flex-wrap items-center gap-2",
253
546
  children: [
254
- /* @__PURE__ */ m("button", {
255
- type: "button",
256
- onClick: () => W(U === e.id ? null : e.id),
257
- className: "inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-hover",
258
- children: [U === e.id ? /* @__PURE__ */ p(c, { className: "size-3.5" }) : /* @__PURE__ */ p(s, { className: "size-3.5" }), "Details"]
547
+ e.productId && /* @__PURE__ */ v("a", {
548
+ href: `/devportal/apps/${e.productId}`,
549
+ target: "_blank",
550
+ rel: "noreferrer",
551
+ 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",
552
+ children: [/* @__PURE__ */ _(d, { className: "size-3.5" }), "Devportal"]
259
553
  }),
260
- /* @__PURE__ */ m("button", {
554
+ x.has(e.type) && e.productId && /* @__PURE__ */ v("a", {
555
+ href: `/devportal/apps/${e.productId}`,
556
+ target: "_blank",
557
+ rel: "noreferrer",
558
+ 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",
559
+ children: [/* @__PURE__ */ _(u, { className: "size-3.5" }), "Package File"]
560
+ }),
561
+ x.has(e.type) && /* @__PURE__ */ v("button", {
261
562
  type: "button",
262
- onClick: () => void K(e.id),
263
- disabled: F === e.id,
264
- className: "inline-flex items-center gap-1 rounded-md bg-surface-success px-3 py-1.5 text-xs font-medium text-text-on-success hover:bg-surface-success-hover disabled:opacity-60",
265
- children: [/* @__PURE__ */ p(o, { className: "size-3.5" }), "Approve"]
563
+ onClick: () => V(e),
564
+ 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",
565
+ children: [/* @__PURE__ */ _(te, { className: "size-3.5" }), "Test in workspace"]
266
566
  }),
267
- /* @__PURE__ */ m("button", {
567
+ /* @__PURE__ */ v("button", {
268
568
  type: "button",
269
- onClick: () => {
270
- B(e.id), H("");
271
- },
272
- disabled: F === e.id,
273
- className: "inline-flex items-center gap-1 rounded-md border border-border-danger bg-surface-danger-muted px-3 py-1.5 text-xs font-medium text-text-danger hover:bg-surface-danger hover:text-text-on-danger disabled:opacity-60",
274
- children: [/* @__PURE__ */ p(d, { className: "size-3.5" }), "Reject"]
569
+ onClick: () => z(R === e.id ? null : e.id),
570
+ 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",
571
+ children: [
572
+ /* @__PURE__ */ _(f, { className: "size-3.5" }),
573
+ R === e.id ? "Hide details" : "Inspect details",
574
+ R === e.id ? /* @__PURE__ */ _(c, { className: "size-3" }) : /* @__PURE__ */ _(s, { className: "size-3" })
575
+ ]
275
576
  })
276
577
  ]
277
- })
278
- ]
279
- }),
280
- U === e.id && /* @__PURE__ */ p("div", {
281
- className: "border-t border-border-seam bg-surface-muted p-4",
282
- children: /* @__PURE__ */ m("dl", {
283
- className: "grid grid-cols-2 gap-x-6 gap-y-3 text-xs sm:grid-cols-3",
578
+ }), /* @__PURE__ */ v("div", {
579
+ className: "flex items-center gap-2",
580
+ children: [e.status !== "PUBLISHED" && /* @__PURE__ */ v("button", {
581
+ type: "button",
582
+ onClick: () => void De(e.id),
583
+ disabled: M === e.id,
584
+ 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",
585
+ children: [/* @__PURE__ */ _(o, { className: "size-3.5" }), "Approve"]
586
+ }), e.status !== "REJECTED" && /* @__PURE__ */ v("button", {
587
+ type: "button",
588
+ onClick: () => {
589
+ F(e.id), L("");
590
+ },
591
+ disabled: M === e.id,
592
+ 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",
593
+ children: [/* @__PURE__ */ _(h, { className: "size-3.5" }), "Reject"]
594
+ })]
595
+ })]
596
+ }),
597
+ R === e.id && /* @__PURE__ */ v("div", {
598
+ className: "border-t border-[var(--color-border-seam)] bg-[var(--color-surface-muted)] p-5 space-y-5",
284
599
  children: [
285
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
286
- className: "font-medium text-text-secondary",
287
- children: "Slug"
288
- }), /* @__PURE__ */ p("dd", {
289
- className: "mt-0.5 font-mono text-text-primary",
290
- children: e.slug
291
- })] }),
292
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
293
- className: "font-medium text-text-secondary",
294
- children: "Type"
295
- }), /* @__PURE__ */ p("dd", {
296
- className: "mt-0.5 text-text-primary",
297
- children: e.type
298
- })] }),
299
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
300
- className: "font-medium text-text-secondary",
301
- children: "Nature"
302
- }), /* @__PURE__ */ p("dd", {
303
- className: "mt-0.5 text-text-primary",
304
- children: e.nature
305
- })] }),
306
- e.category && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
307
- className: "font-medium text-text-secondary",
308
- children: "Category"
309
- }), /* @__PURE__ */ p("dd", {
310
- className: "mt-0.5 text-text-primary",
311
- children: e.category
312
- })] }),
313
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
314
- className: "font-medium text-text-secondary",
315
- children: "Pricing"
316
- }), /* @__PURE__ */ m("dd", {
317
- className: "mt-0.5 text-text-primary",
600
+ /* @__PURE__ */ v("div", {
601
+ className: "grid grid-cols-2 gap-x-8 gap-y-3 text-xs sm:grid-cols-3",
318
602
  children: [
319
- t(e.price, e.currency, e.pricingModel),
320
- " ",
321
- /* @__PURE__ */ m("span", {
322
- className: "text-text-tertiary",
603
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
604
+ className: "font-medium text-[var(--color-text-secondary)]",
605
+ children: "Store product ID"
606
+ }), /* @__PURE__ */ _("dd", {
607
+ className: "mt-0.5 font-mono text-[var(--color-text-primary)] break-all",
608
+ children: e.id
609
+ })] }),
610
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
611
+ className: "font-medium text-[var(--color-text-secondary)]",
612
+ children: "Slug"
613
+ }), /* @__PURE__ */ _("dd", {
614
+ className: "mt-0.5 font-mono text-[var(--color-text-primary)]",
615
+ children: e.slug
616
+ })] }),
617
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
618
+ className: "font-medium text-[var(--color-text-secondary)]",
619
+ children: "Type / Nature"
620
+ }), /* @__PURE__ */ v("dd", {
621
+ className: "mt-0.5 text-[var(--color-text-primary)]",
622
+ children: [
623
+ e.type,
624
+ " · ",
625
+ e.nature
626
+ ]
627
+ })] }),
628
+ e.category && /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
629
+ className: "font-medium text-[var(--color-text-secondary)]",
630
+ children: "Category"
631
+ }), /* @__PURE__ */ _("dd", {
632
+ className: "mt-0.5 text-[var(--color-text-primary)]",
633
+ children: e.category
634
+ })] }),
635
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
636
+ className: "font-medium text-[var(--color-text-secondary)]",
637
+ children: "Pricing"
638
+ }), /* @__PURE__ */ v("dd", {
639
+ className: "mt-0.5 text-[var(--color-text-primary)]",
323
640
  children: [
324
- "(",
325
- e.pricingModel,
326
- ")"
641
+ t(e.price, e.currency, e.pricingModel),
642
+ " ",
643
+ /* @__PURE__ */ v("span", {
644
+ className: "text-[var(--color-text-muted)]",
645
+ children: [
646
+ "(",
647
+ e.pricingModel,
648
+ ")"
649
+ ]
650
+ })
327
651
  ]
328
- })
652
+ })] }),
653
+ e.productId && /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
654
+ className: "font-medium text-[var(--color-text-secondary)]",
655
+ children: "Devportal app ID"
656
+ }), /* @__PURE__ */ _("dd", {
657
+ className: "mt-0.5 font-mono text-[var(--color-text-primary)] break-all",
658
+ children: e.productId
659
+ })] }),
660
+ e.submittedBy && /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("dt", {
661
+ className: "font-medium text-[var(--color-text-secondary)]",
662
+ children: "Submitted by (actor)"
663
+ }), /* @__PURE__ */ _("dd", {
664
+ className: "mt-0.5 font-mono text-[var(--color-text-primary)] break-all",
665
+ children: e.submittedBy
666
+ })] })
329
667
  ]
668
+ }),
669
+ e.requiredPermissions && e.requiredPermissions.length > 0 && /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("h4", {
670
+ className: "mb-2 flex items-center gap-1.5 text-xs font-semibold text-[var(--color-text-secondary)] uppercase tracking-wide",
671
+ children: [/* @__PURE__ */ _(ie, { className: "size-3.5 text-[var(--color-status-success-text)]" }), "Required Permissions"]
672
+ }), /* @__PURE__ */ _("div", {
673
+ className: "flex flex-wrap gap-1.5",
674
+ children: e.requiredPermissions.map((e) => /* @__PURE__ */ _("span", {
675
+ 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)]",
676
+ children: e
677
+ }, e))
330
678
  })] }),
331
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
332
- className: "font-medium text-text-secondary",
333
- children: "Publisher"
334
- }), /* @__PURE__ */ m("dd", {
335
- className: "mt-0.5 text-text-primary",
336
- children: [e.publisher?.name ?? "—", e.publisher?.email && /* @__PURE__ */ p("span", {
337
- className: "block text-text-tertiary",
338
- children: e.publisher.email
339
- })]
340
- })] }),
341
- e.submittedBy && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
342
- className: "font-medium text-text-secondary",
343
- children: "Submitted by"
344
- }), /* @__PURE__ */ p("dd", {
345
- className: "mt-0.5 font-mono text-text-primary",
346
- children: e.submittedBy
347
- })] }),
348
- e.submittedAt && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("dt", {
349
- className: "font-medium text-text-secondary",
350
- children: "Submitted at"
351
- }), /* @__PURE__ */ p("dd", {
352
- className: "mt-0.5 text-text-primary",
353
- children: new Date(e.submittedAt).toLocaleString()
354
- })] }),
355
- e.description && /* @__PURE__ */ m("div", {
356
- className: "col-span-2 sm:col-span-3",
357
- children: [/* @__PURE__ */ p("dt", {
358
- className: "font-medium text-text-secondary",
359
- children: "Description"
360
- }), /* @__PURE__ */ p("dd", {
361
- className: "mt-0.5 whitespace-pre-wrap text-text-primary",
362
- children: e.description
679
+ e.manifest && /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ v("h4", {
680
+ className: "mb-2 flex items-center gap-1.5 text-xs font-semibold text-[var(--color-text-secondary)] uppercase tracking-wide",
681
+ children: [/* @__PURE__ */ _(f, { className: "size-3.5" }), "Manifest"]
682
+ }), /* @__PURE__ */ _("pre", {
683
+ 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",
684
+ children: JSON.stringify(e.manifest, null, 2)
685
+ })] })
686
+ ]
687
+ }),
688
+ xe === e.id && /* @__PURE__ */ v("div", {
689
+ className: "border-t border-[var(--color-border-seam)] bg-[var(--color-surface-danger-muted)]/30 px-5 py-4",
690
+ children: [
691
+ /* @__PURE__ */ _("p", {
692
+ className: "mb-2 text-xs font-semibold text-[var(--color-text-danger)]",
693
+ children: "Reject provide a reason (the publisher will see this)"
694
+ }),
695
+ /* @__PURE__ */ _("textarea", {
696
+ id: `reject-reason-${e.id}`,
697
+ "aria-label": "Rejection reason",
698
+ value: I,
699
+ onChange: (e) => L(e.target.value),
700
+ rows: 3,
701
+ required: !0,
702
+ "aria-required": "true",
703
+ 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",
704
+ placeholder: "Be specific — e.g. 'Manifest is missing the identity.version field' or 'ZIP file is empty'…"
705
+ }),
706
+ /* @__PURE__ */ v("div", {
707
+ className: "mt-2 flex items-center justify-end gap-2",
708
+ children: [/* @__PURE__ */ _("button", {
709
+ type: "button",
710
+ onClick: () => {
711
+ F(null), L("");
712
+ },
713
+ 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",
714
+ children: "Cancel"
715
+ }), /* @__PURE__ */ _("button", {
716
+ type: "button",
717
+ onClick: () => void Oe(e.id),
718
+ disabled: !I.trim() || M === e.id,
719
+ 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",
720
+ children: "Submit rejection"
363
721
  })]
364
722
  })
365
723
  ]
366
724
  })
367
- }),
368
- z === e.id && /* @__PURE__ */ m("div", {
369
- className: "border-t border-border-seam bg-surface-muted px-4 py-3",
370
- children: [
371
- /* @__PURE__ */ p("label", {
372
- htmlFor: `reject-reason-${e.id}`,
373
- className: "block text-xs font-medium text-text-secondary",
374
- children: "Rejection reason (required)"
375
- }),
376
- /* @__PURE__ */ p("textarea", {
377
- id: `reject-reason-${e.id}`,
378
- "aria-label": "Rejection reason",
379
- value: V,
380
- onChange: (e) => H(e.target.value),
381
- rows: 3,
382
- required: !0,
383
- "aria-required": "true",
384
- className: "mt-1 w-full rounded-md border border-border-default bg-surface-default px-3 py-2 text-sm text-text-primary focus:border-border-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]",
385
- placeholder: "Explain why this submission is being rejected…"
386
- }),
387
- /* @__PURE__ */ m("div", {
388
- className: "mt-2 flex justify-end gap-2",
389
- children: [/* @__PURE__ */ p("button", {
390
- type: "button",
391
- onClick: () => {
392
- B(null), H("");
393
- },
394
- className: "rounded-md border border-border-default bg-surface-default px-3 py-1 text-xs text-text-primary hover:bg-surface-hover",
395
- children: "Cancel"
396
- }), /* @__PURE__ */ p("button", {
397
- type: "button",
398
- onClick: () => void q(e.id),
399
- disabled: !V.trim() || F === e.id,
400
- className: "rounded-md bg-surface-danger px-3 py-1 text-xs font-medium text-text-on-danger hover:bg-surface-danger-hover disabled:opacity-60",
401
- children: "Submit rejection"
402
- })]
403
- })
404
- ]
405
- })
406
- ]
407
- }, e.id))
408
- })
409
- ]
410
- })]
725
+ ]
726
+ }, e.id))
727
+ })
728
+ ]
729
+ }),
730
+ B && /* @__PURE__ */ _(n, {
731
+ isOpen: !0,
732
+ onClose: () => V(null),
733
+ app: {
734
+ id: B.id,
735
+ name: B.name,
736
+ slug: B.slug,
737
+ icon: B.icon ?? void 0,
738
+ type: B.type,
739
+ permissions: B.requiredPermissions?.length ? B.requiredPermissions : void 0
740
+ },
741
+ purchaseState: "free",
742
+ onInstallSuccess: () => {
743
+ V(null);
744
+ },
745
+ onInstallError: () => {}
746
+ })
747
+ ]
411
748
  });
412
749
  };
413
750
  //#endregion
414
- export { w as AdminSubmissionsQueuePage };
751
+ export { C as AdminSubmissionsQueuePage };
415
752
 
416
753
  //# sourceMappingURL=AdminSubmissionsQueuePage.js.map