@burdenoff/microfe-subscriberbot 2026.827.1 → 2026.1014.1

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.
Files changed (56) hide show
  1. package/dist/subscriberbot/admin/AdminDashboardPage.d.ts.map +1 -1
  2. package/dist/subscriberbot/admin/AdminDashboardPage.js +80 -83
  3. package/dist/subscriberbot/admin/AdminDashboardPage.js.map +1 -1
  4. package/dist/subscriberbot/hooks/index.d.ts +1 -0
  5. package/dist/subscriberbot/hooks/index.d.ts.map +1 -1
  6. package/dist/subscriberbot/hooks/index.js +1 -0
  7. package/dist/subscriberbot/hooks/useTr.d.ts +17 -0
  8. package/dist/subscriberbot/hooks/useTr.d.ts.map +1 -0
  9. package/dist/subscriberbot/hooks/useTr.js +14 -0
  10. package/dist/subscriberbot/hooks/useTr.js.map +1 -0
  11. package/dist/subscriberbot/pages/AssetVaultPage.d.ts.map +1 -1
  12. package/dist/subscriberbot/pages/AssetVaultPage.js +111 -109
  13. package/dist/subscriberbot/pages/AssetVaultPage.js.map +1 -1
  14. package/dist/subscriberbot/pages/DashboardPage.d.ts.map +1 -1
  15. package/dist/subscriberbot/pages/DashboardPage.js +113 -105
  16. package/dist/subscriberbot/pages/DashboardPage.js.map +1 -1
  17. package/dist/subscriberbot/pages/InboxPage.d.ts.map +1 -1
  18. package/dist/subscriberbot/pages/InboxPage.js +404 -369
  19. package/dist/subscriberbot/pages/InboxPage.js.map +1 -1
  20. package/dist/subscriberbot/pages/InsightsPage.d.ts.map +1 -1
  21. package/dist/subscriberbot/pages/InsightsPage.js +94 -93
  22. package/dist/subscriberbot/pages/InsightsPage.js.map +1 -1
  23. package/dist/subscriberbot/pages/InvoicesPage.d.ts.map +1 -1
  24. package/dist/subscriberbot/pages/InvoicesPage.js +360 -366
  25. package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -1
  26. package/dist/subscriberbot/pages/WorkflowsPage.d.ts.map +1 -1
  27. package/dist/subscriberbot/pages/WorkflowsPage.js +209 -193
  28. package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -1
  29. package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts.map +1 -1
  30. package/dist/subscriberbot/pages/agents/AgentDetailPage.js +268 -236
  31. package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
  32. package/dist/subscriberbot/pages/agents/AgentNewPage.d.ts.map +1 -1
  33. package/dist/subscriberbot/pages/agents/AgentNewPage.js +96 -76
  34. package/dist/subscriberbot/pages/agents/AgentNewPage.js.map +1 -1
  35. package/dist/subscriberbot/pages/agents/AgentsListPage.d.ts.map +1 -1
  36. package/dist/subscriberbot/pages/agents/AgentsListPage.js +145 -161
  37. package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -1
  38. package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts.map +1 -1
  39. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +514 -441
  40. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -1
  41. package/dist/subscriberbot/pages/providers/ProviderNewPage.d.ts.map +1 -1
  42. package/dist/subscriberbot/pages/providers/ProviderNewPage.js +167 -129
  43. package/dist/subscriberbot/pages/providers/ProviderNewPage.js.map +1 -1
  44. package/dist/subscriberbot/pages/providers/ProvidersListPage.d.ts.map +1 -1
  45. package/dist/subscriberbot/pages/providers/ProvidersListPage.js +171 -218
  46. package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -1
  47. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.d.ts.map +1 -1
  48. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +340 -279
  49. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
  50. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.d.ts.map +1 -1
  51. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js +185 -166
  52. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js.map +1 -1
  53. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.d.ts.map +1 -1
  54. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js +153 -182
  55. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -1
  56. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboardPage.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/admin/AdminDashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAsB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAsCpD,eAAO,MAAM,kBAAkB,EAAE,EA6ahC,CAAC"}
1
+ {"version":3,"file":"AdminDashboardPage.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/admin/AdminDashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAsB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAuCpD,eAAO,MAAM,kBAAkB,EAAE,EA0dhC,CAAC"}
@@ -1,38 +1,39 @@
1
1
  import { PageLayout as e } from "../components/PageLayout.js";
2
2
  import { formatDate as t } from "../utils/formatters.js";
3
3
  import { StatusBadge as n } from "../components/StatusBadge.js";
4
- import { useAdapterSubmissions as r, useApproveAdapter as i, useMarketplaceReports as ee, useModerateListing as a, useProviders as te, useRejectAdapter as ne, useUpdateProvider as o } from "../hooks/useSubscriberBotApi.js";
4
+ import { useAdapterSubmissions as r, useApproveAdapter as i, useMarketplaceReports as a, useModerateListing as ee, useProviders as te, useRejectAdapter as ne, useUpdateProvider as re } from "../hooks/useSubscriberBotApi.js";
5
+ import { useTr as o } from "../hooks/useTr.js";
5
6
  import "../hooks/index.js";
6
7
  import { Fragment as s, useState as c } from "react";
7
- import { CheckCircle2 as l, Plug as u, Settings2 as re, Store as d, XCircle as ie } from "lucide-react";
8
+ import { CheckCircle2 as l, Plug as u, Settings2 as ie, Store as d, XCircle as ae } from "lucide-react";
8
9
  import { jsx as f, jsxs as p } from "react/jsx-runtime";
9
- import { Button as m, Card as h, CardContent as g, CardDescription as _, CardHeader as v, CardTitle as y, EmptyState as b, Spinner as x, Table as S, TableBody as C, TableCell as w, TableHead as T, TableHeader as E, TableRow as D, Tabs as O, TabsContent as k, TabsList as A, TabsTrigger as j, Textarea as M } from "@burdenoff/fe-libs/ui";
10
+ import { Button as m, Card as h, CardContent as g, CardDescription as _, CardHeader as v, CardTitle as y, EmptyState as b, Spinner as x, Table as S, TableBody as C, TableCell as w, TableHead as T, TableHeader as E, TableRow as D, Tabs as oe, TabsContent as O, TabsList as se, TabsTrigger as k, Textarea as A } from "@burdenoff/fe-libs/ui";
10
11
  //#region src/subscriberbot/admin/AdminDashboardPage.tsx
11
- var N = () => {
12
- let [N, ae] = c("providers"), { data: P, isLoading: oe } = te({ pagination: { limit: 50 } }), F = o(), se = (e) => {
13
- F.mutate({
12
+ var j = () => {
13
+ let j = o(), [M, ce] = c("providers"), { data: le, isLoading: ue } = te({ pagination: { limit: 50 } }), N = re(), P = (e) => {
14
+ N.mutate({
14
15
  id: e,
15
16
  input: { status: "VERIFIED" }
16
17
  });
17
- }, ce = (e) => {
18
- F.mutate({
18
+ }, F = (e) => {
19
+ N.mutate({
19
20
  id: e,
20
21
  input: { status: "DEPRECATED" }
21
22
  });
22
- }, I = P?.items ?? [], { data: L, isLoading: R } = r({ pagination: { limit: 50 } }), z = i(), B = ne(), [V, H] = c(null), [U, W] = c(""), G = L?.items ?? [], le = (e) => {
23
+ }, I = le?.items ?? [], { data: L, isLoading: R } = r({ pagination: { limit: 50 } }), z = i(), B = ne(), [V, H] = c(null), [U, W] = c(""), G = L?.items ?? [], de = (e) => {
23
24
  z.mutate({ id: e });
24
- }, ue = (e) => {
25
+ }, fe = (e) => {
25
26
  H(e), W("");
26
- }, de = (e) => {
27
+ }, pe = (e) => {
27
28
  U.trim() && B.mutate({
28
29
  id: e,
29
30
  reason: U.trim()
30
31
  }, { onSuccess: () => {
31
32
  H(null), W("");
32
33
  } });
33
- }, { data: fe, isLoading: pe } = ee({ pagination: { limit: 50 } }), K = a(), [me, q] = c(null), [J, Y] = c(null), [X, Z] = c(""), Q = fe?.items ?? [], $ = (e, t) => {
34
+ }, { data: me, isLoading: he } = a({ pagination: { limit: 50 } }), K = ee(), [ge, q] = c(null), [J, Y] = c(null), [X, Z] = c(""), Q = me?.items ?? [], $ = (e, t) => {
34
35
  q(e), Y(t), Z("");
35
- }, he = (e) => {
36
+ }, _e = (e) => {
36
37
  !J || !X.trim() || K.mutate({
37
38
  id: e,
38
39
  action: J,
@@ -42,52 +43,52 @@ var N = () => {
42
43
  } });
43
44
  };
44
45
  return /* @__PURE__ */ f(e, {
45
- title: "SubscriberBot Admin",
46
- description: "Provider registry curation, adapter approvals, and marketplace moderation.",
47
- children: /* @__PURE__ */ p(O, {
48
- value: N,
49
- onValueChange: ae,
46
+ title: j("admin.title", "SubscriberBot Admin"),
47
+ description: j("admin.description", "Provider registry curation, adapter approvals, and marketplace moderation."),
48
+ children: /* @__PURE__ */ p(oe, {
49
+ value: M,
50
+ onValueChange: ce,
50
51
  className: "w-full",
51
52
  children: [
52
- /* @__PURE__ */ p(A, {
53
+ /* @__PURE__ */ p(se, {
53
54
  className: "mb-4 grid w-full grid-cols-3 sm:w-auto sm:inline-flex",
54
55
  children: [
55
- /* @__PURE__ */ p(j, {
56
+ /* @__PURE__ */ p(k, {
56
57
  value: "providers",
57
58
  className: "gap-2",
58
- children: [/* @__PURE__ */ f(re, { size: 16 }), "Provider Registry"]
59
+ children: [/* @__PURE__ */ f(ie, { size: 16 }), j("admin.tabs.providers", "Provider Registry")]
59
60
  }),
60
- /* @__PURE__ */ p(j, {
61
+ /* @__PURE__ */ p(k, {
61
62
  value: "adapters",
62
63
  className: "gap-2",
63
- children: [/* @__PURE__ */ f(u, { size: 16 }), "Adapter Approvals"]
64
+ children: [/* @__PURE__ */ f(u, { size: 16 }), j("admin.tabs.adapters", "Adapter Approvals")]
64
65
  }),
65
- /* @__PURE__ */ p(j, {
66
+ /* @__PURE__ */ p(k, {
66
67
  value: "marketplace",
67
68
  className: "gap-2",
68
- children: [/* @__PURE__ */ f(d, { size: 16 }), "Marketplace Moderation"]
69
+ children: [/* @__PURE__ */ f(d, { size: 16 }), j("admin.tabs.marketplace", "Marketplace Moderation")]
69
70
  })
70
71
  ]
71
72
  }),
72
- /* @__PURE__ */ f(k, {
73
+ /* @__PURE__ */ f(O, {
73
74
  value: "providers",
74
- children: /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(y, { children: "Provider registry" }), /* @__PURE__ */ f(_, { children: "Curate the global provider catalog. Verify submitted providers or deprecate stale entries." })] }), /* @__PURE__ */ f(g, { children: oe ? /* @__PURE__ */ f("div", {
75
+ children: /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(y, { children: j("admin.providers.title", "Provider registry") }), /* @__PURE__ */ f(_, { children: j("admin.providers.description", "Curate the global provider catalog. Verify submitted providers or deprecate stale entries.") })] }), /* @__PURE__ */ f(g, { children: ue ? /* @__PURE__ */ f("div", {
75
76
  className: "flex min-h-[200px] items-center justify-center",
76
77
  children: /* @__PURE__ */ f(x, { size: "lg" })
77
78
  }) : I.length === 0 ? /* @__PURE__ */ f(b, {
78
79
  icon: /* @__PURE__ */ f(d, { className: "size-6 text-action-primary-bg" }),
79
- title: "No providers yet",
80
- description: "Once providers are created or claimed they will appear here for curation."
80
+ title: j("admin.providers.emptyTitle", "No providers yet"),
81
+ description: j("admin.providers.emptyDescription", "Once providers are created or claimed they will appear here for curation.")
81
82
  }) : /* @__PURE__ */ f("div", {
82
83
  className: "overflow-x-auto",
83
84
  children: /* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(E, { children: /* @__PURE__ */ p(D, { children: [
84
- /* @__PURE__ */ f(T, { children: "Name" }),
85
- /* @__PURE__ */ f(T, { children: "Category" }),
86
- /* @__PURE__ */ f(T, { children: "Status" }),
87
- /* @__PURE__ */ f(T, { children: "Created" }),
85
+ /* @__PURE__ */ f(T, { children: j("admin.providers.table.name", "Name") }),
86
+ /* @__PURE__ */ f(T, { children: j("admin.providers.table.category", "Category") }),
87
+ /* @__PURE__ */ f(T, { children: j("admin.providers.table.status", "Status") }),
88
+ /* @__PURE__ */ f(T, { children: j("admin.providers.table.created", "Created") }),
88
89
  /* @__PURE__ */ f(T, {
89
90
  className: "text-right",
90
- children: "Actions"
91
+ children: j("admin.providers.table.actions", "Actions")
91
92
  })
92
93
  ] }) }), /* @__PURE__ */ f(C, { children: I.map((e) => /* @__PURE__ */ p(D, { children: [
93
94
  /* @__PURE__ */ f(w, {
@@ -110,43 +111,43 @@ var N = () => {
110
111
  children: [e.status !== "VERIFIED" && /* @__PURE__ */ p(m, {
111
112
  size: "sm",
112
113
  variant: "outline",
113
- onClick: () => se(e.id),
114
- disabled: F.isPending,
114
+ onClick: () => P(e.id),
115
+ disabled: N.isPending,
115
116
  children: [/* @__PURE__ */ f(l, {
116
117
  size: 14,
117
118
  className: "mr-1"
118
- }), "Verify"]
119
+ }), j("admin.providers.verify", "Verify")]
119
120
  }), e.status !== "DEPRECATED" && /* @__PURE__ */ f(m, {
120
121
  size: "sm",
121
122
  variant: "secondary",
122
- onClick: () => ce(e.id),
123
- disabled: F.isPending,
124
- children: "Deprecate"
123
+ onClick: () => F(e.id),
124
+ disabled: N.isPending,
125
+ children: j("admin.providers.deprecate", "Deprecate")
125
126
  })]
126
127
  })
127
128
  })
128
129
  ] }, e.id)) })] })
129
130
  }) })] })
130
131
  }),
131
- /* @__PURE__ */ f(k, {
132
+ /* @__PURE__ */ f(O, {
132
133
  value: "adapters",
133
- children: /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(y, { children: "Adapter approvals" }), /* @__PURE__ */ f(_, { children: "Review submitted integration adapters before they are published to the SubscriberBot adapter marketplace." })] }), /* @__PURE__ */ f(g, { children: R ? /* @__PURE__ */ f("div", {
134
+ children: /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(y, { children: j("admin.adapters.title", "Adapter approvals") }), /* @__PURE__ */ f(_, { children: j("admin.adapters.description", "Review submitted integration adapters before they are published to the SubscriberBot adapter marketplace.") })] }), /* @__PURE__ */ f(g, { children: R ? /* @__PURE__ */ f("div", {
134
135
  className: "flex min-h-[200px] items-center justify-center",
135
136
  children: /* @__PURE__ */ f(x, { size: "lg" })
136
137
  }) : G.length === 0 ? /* @__PURE__ */ f(b, {
137
138
  icon: /* @__PURE__ */ f(u, { className: "size-6 text-action-primary-bg" }),
138
- title: "No adapter submissions",
139
- description: "Submitted integration adapters will appear here for review."
139
+ title: j("admin.adapters.emptyTitle", "No adapter submissions"),
140
+ description: j("admin.adapters.emptyDescription", "Submitted integration adapters will appear here for review.")
140
141
  }) : /* @__PURE__ */ f("div", {
141
142
  className: "overflow-x-auto",
142
143
  children: /* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(E, { children: /* @__PURE__ */ p(D, { children: [
143
- /* @__PURE__ */ f(T, { children: "Adapter" }),
144
- /* @__PURE__ */ f(T, { children: "Submitting workspace" }),
145
- /* @__PURE__ */ f(T, { children: "Submitted" }),
146
- /* @__PURE__ */ f(T, { children: "Status" }),
144
+ /* @__PURE__ */ f(T, { children: j("admin.adapters.table.adapter", "Adapter") }),
145
+ /* @__PURE__ */ f(T, { children: j("admin.adapters.table.workspace", "Submitting workspace") }),
146
+ /* @__PURE__ */ f(T, { children: j("admin.adapters.table.submitted", "Submitted") }),
147
+ /* @__PURE__ */ f(T, { children: j("admin.adapters.table.status", "Status") }),
147
148
  /* @__PURE__ */ f(T, {
148
149
  className: "text-right",
149
- children: "Actions"
150
+ children: j("admin.adapters.table.actions", "Actions")
150
151
  })
151
152
  ] }) }), /* @__PURE__ */ f(C, { children: G.map((e) => /* @__PURE__ */ p(s, { children: [/* @__PURE__ */ p(D, { children: [
152
153
  /* @__PURE__ */ f(w, {
@@ -169,21 +170,21 @@ var N = () => {
169
170
  children: [/* @__PURE__ */ p(m, {
170
171
  size: "sm",
171
172
  variant: "outline",
172
- onClick: () => le(e.id),
173
+ onClick: () => de(e.id),
173
174
  disabled: z.isPending || B.isPending,
174
175
  children: [/* @__PURE__ */ f(l, {
175
176
  size: 14,
176
177
  className: "mr-1"
177
- }), "Approve"]
178
+ }), j("admin.adapters.approve", "Approve")]
178
179
  }), /* @__PURE__ */ p(m, {
179
180
  size: "sm",
180
181
  variant: "secondary",
181
- onClick: () => ue(e.id),
182
+ onClick: () => fe(e.id),
182
183
  disabled: z.isPending || B.isPending,
183
- children: [/* @__PURE__ */ f(ie, {
184
+ children: [/* @__PURE__ */ f(ae, {
184
185
  size: 14,
185
186
  className: "mr-1"
186
- }), "Reject"]
187
+ }), j("admin.adapters.reject", "Reject")]
187
188
  })]
188
189
  })
189
190
  })
@@ -192,10 +193,10 @@ var N = () => {
192
193
  className: "bg-bg-sunken",
193
194
  children: /* @__PURE__ */ p("div", {
194
195
  className: "flex flex-col gap-2 py-1 sm:flex-row sm:items-start",
195
- children: [/* @__PURE__ */ f(M, {
196
+ children: [/* @__PURE__ */ f(A, {
196
197
  value: U,
197
198
  onChange: (e) => W(e.target.value),
198
- placeholder: "Reason for rejecting this adapter submission (required)",
199
+ placeholder: j("admin.adapters.rejectPlaceholder", "Reason for rejecting this adapter submission (required)"),
199
200
  className: "min-h-[60px] flex-1",
200
201
  autoFocus: !0
201
202
  }), /* @__PURE__ */ p("div", {
@@ -203,41 +204,41 @@ var N = () => {
203
204
  children: [/* @__PURE__ */ f(m, {
204
205
  size: "sm",
205
206
  variant: "destructive",
206
- onClick: () => de(e.id),
207
+ onClick: () => pe(e.id),
207
208
  disabled: !U.trim() || B.isPending,
208
- children: "Confirm reject"
209
+ children: j("admin.adapters.confirmReject", "Confirm reject")
209
210
  }), /* @__PURE__ */ f(m, {
210
211
  size: "sm",
211
212
  variant: "outline",
212
213
  onClick: () => H(null),
213
214
  disabled: B.isPending,
214
- children: "Cancel"
215
+ children: j("admin.adapters.cancel", "Cancel")
215
216
  })]
216
217
  })]
217
218
  })
218
219
  }) }, `${e.id}-reject`)] }, e.id)) })] })
219
220
  }) })] })
220
221
  }),
221
- /* @__PURE__ */ f(k, {
222
+ /* @__PURE__ */ f(O, {
222
223
  value: "marketplace",
223
- children: /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(y, { children: "Marketplace moderation" }), /* @__PURE__ */ f(_, { children: "Review reported marketplace listings and take moderation actions." })] }), /* @__PURE__ */ f(g, { children: pe ? /* @__PURE__ */ f("div", {
224
+ children: /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(y, { children: j("admin.marketplace.title", "Marketplace moderation") }), /* @__PURE__ */ f(_, { children: j("admin.marketplace.description", "Review reported marketplace listings and take moderation actions.") })] }), /* @__PURE__ */ f(g, { children: he ? /* @__PURE__ */ f("div", {
224
225
  className: "flex min-h-[200px] items-center justify-center",
225
226
  children: /* @__PURE__ */ f(x, { size: "lg" })
226
227
  }) : Q.length === 0 ? /* @__PURE__ */ f(b, {
227
228
  icon: /* @__PURE__ */ f(d, { className: "size-6 text-action-primary-bg" }),
228
- title: "No reported listings",
229
- description: "Reported marketplace listings will appear here for moderation."
229
+ title: j("admin.marketplace.emptyTitle", "No reported listings"),
230
+ description: j("admin.marketplace.emptyDescription", "Reported marketplace listings will appear here for moderation.")
230
231
  }) : /* @__PURE__ */ f("div", {
231
232
  className: "overflow-x-auto",
232
233
  children: /* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(E, { children: /* @__PURE__ */ p(D, { children: [
233
- /* @__PURE__ */ f(T, { children: "Listing" }),
234
- /* @__PURE__ */ f(T, { children: "Reporting workspace" }),
235
- /* @__PURE__ */ f(T, { children: "Reported" }),
236
- /* @__PURE__ */ f(T, { children: "Reason" }),
237
- /* @__PURE__ */ f(T, { children: "Status" }),
234
+ /* @__PURE__ */ f(T, { children: j("admin.marketplace.table.listing", "Listing") }),
235
+ /* @__PURE__ */ f(T, { children: j("admin.marketplace.table.workspace", "Reporting workspace") }),
236
+ /* @__PURE__ */ f(T, { children: j("admin.marketplace.table.reported", "Reported") }),
237
+ /* @__PURE__ */ f(T, { children: j("admin.marketplace.table.reason", "Reason") }),
238
+ /* @__PURE__ */ f(T, { children: j("admin.marketplace.table.status", "Status") }),
238
239
  /* @__PURE__ */ f(T, {
239
240
  className: "text-right",
240
- children: "Actions"
241
+ children: j("admin.marketplace.table.actions", "Actions")
241
242
  })
242
243
  ] }) }), /* @__PURE__ */ f(C, { children: Q.map((e) => /* @__PURE__ */ p(s, { children: [/* @__PURE__ */ p(D, { children: [
243
244
  /* @__PURE__ */ f(w, {
@@ -266,45 +267,41 @@ var N = () => {
266
267
  variant: "outline",
267
268
  onClick: () => $(e.id, "DISMISS"),
268
269
  disabled: K.isPending,
269
- children: "Dismiss"
270
+ children: j("admin.marketplace.dismiss", "Dismiss")
270
271
  }), /* @__PURE__ */ f(m, {
271
272
  size: "sm",
272
273
  variant: "destructive",
273
274
  onClick: () => $(e.id, "REMOVE_LISTING"),
274
275
  disabled: K.isPending,
275
- children: "Remove"
276
+ children: j("admin.marketplace.remove", "Remove")
276
277
  })]
277
278
  })
278
279
  })
279
- ] }), me === e.id && /* @__PURE__ */ f(D, { children: /* @__PURE__ */ f(w, {
280
+ ] }), ge === e.id && /* @__PURE__ */ f(D, { children: /* @__PURE__ */ f(w, {
280
281
  colSpan: 6,
281
282
  className: "bg-bg-sunken",
282
283
  children: /* @__PURE__ */ p("div", {
283
284
  className: "flex flex-col gap-2 py-1 sm:flex-row sm:items-start",
284
- children: [/* @__PURE__ */ f(M, {
285
+ children: [/* @__PURE__ */ f(A, {
285
286
  value: X,
286
287
  onChange: (e) => Z(e.target.value),
287
- placeholder: `Reason to ${J === "REMOVE_LISTING" ? "remove this listing" : "dismiss this report"} (required)`,
288
+ placeholder: J === "REMOVE_LISTING" ? j("admin.marketplace.reasonPlaceholderRemove", "Reason to remove this listing (required)") : j("admin.marketplace.reasonPlaceholderDismiss", "Reason to dismiss this report (required)"),
288
289
  className: "min-h-[60px] flex-1",
289
290
  autoFocus: !0
290
291
  }), /* @__PURE__ */ p("div", {
291
292
  className: "flex gap-2 sm:flex-col",
292
- children: [/* @__PURE__ */ p(m, {
293
+ children: [/* @__PURE__ */ f(m, {
293
294
  size: "sm",
294
295
  variant: J === "REMOVE_LISTING" ? "destructive" : "outline",
295
- onClick: () => he(e.id),
296
+ onClick: () => _e(e.id),
296
297
  disabled: !X.trim() || K.isPending,
297
- children: [
298
- "Confirm",
299
- " ",
300
- J === "REMOVE_LISTING" ? "removal" : "dismissal"
301
- ]
298
+ children: J === "REMOVE_LISTING" ? j("admin.marketplace.confirmRemoval", "Confirm removal") : j("admin.marketplace.confirmDismissal", "Confirm dismissal")
302
299
  }), /* @__PURE__ */ f(m, {
303
300
  size: "sm",
304
301
  variant: "outline",
305
302
  onClick: () => q(null),
306
303
  disabled: K.isPending,
307
- children: "Cancel"
304
+ children: j("admin.marketplace.cancel", "Cancel")
308
305
  })]
309
306
  })]
310
307
  })
@@ -316,6 +313,6 @@ var N = () => {
316
313
  });
317
314
  };
318
315
  //#endregion
319
- export { N as AdminDashboardPage };
316
+ export { j as AdminDashboardPage };
320
317
 
321
318
  //# sourceMappingURL=AdminDashboardPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminDashboardPage.js","names":[],"sources":["../../../src/subscriberbot/admin/AdminDashboardPage.tsx"],"sourcesContent":["/**\n * SubscriberBot Admin Dashboard\n * @module subscriberbot/admin\n *\n * Product-specific admin surface mounted inside `admin-app`. It exposes the\n * three governance operations requested for SubscriberBot, all wired to the\n * real `wspace-subscriberbot-svc` admin governance schema (BOFF-3237):\n * 1. Provider registry curation — `subListProviders` / `subUpdateProvider`.\n * 2. Adapter approval queue — `subListAdapterSubmissions` /\n * `subApproveAdapter` / `subRejectAdapter`.\n * 3. Marketplace moderation queue — `subListMarketplaceReports` /\n * `subModerateListing`.\n */\n\nimport { Fragment, useState, type FC } from 'react';\nimport {\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n EmptyState,\n Spinner,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle2, Plug, Settings2, Store, XCircle } from 'lucide-react';\n\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport {\n useAdapterSubmissions,\n useApproveAdapter,\n useMarketplaceReports,\n useModerateListing,\n useProviders,\n useRejectAdapter,\n useUpdateProvider,\n} from '../hooks';\nimport { formatDate } from '../utils/formatters';\nimport type { SubModerationAction, SubProvider } from '../types';\n\nexport const AdminDashboardPage: FC = () => {\n const [activeTab, setActiveTab] = useState('providers');\n\n // --- Provider registry ----------------------------------------------\n const { data: providersData, isLoading: providersLoading } = useProviders({\n pagination: { limit: 50 },\n });\n const updateProvider = useUpdateProvider();\n\n const handleVerify = (id: string) => {\n updateProvider.mutate({ id, input: { status: 'VERIFIED' } });\n };\n\n const handleDeprecate = (id: string) => {\n updateProvider.mutate({ id, input: { status: 'DEPRECATED' } });\n };\n\n const providers = providersData?.items ?? [];\n\n // --- Adapter approvals -------------------------------------------------\n const { data: adapterSubmissionsData, isLoading: adaptersLoading } = useAdapterSubmissions({\n pagination: { limit: 50 },\n });\n const approveAdapter = useApproveAdapter();\n const rejectAdapter = useRejectAdapter();\n const [rejectingAdapterId, setRejectingAdapterId] = useState<string | null>(null);\n const [adapterRejectReason, setAdapterRejectReason] = useState('');\n\n const adapterSubmissions = adapterSubmissionsData?.items ?? [];\n\n const handleApproveAdapter = (id: string) => {\n approveAdapter.mutate({ id });\n };\n\n const handleStartRejectAdapter = (id: string) => {\n setRejectingAdapterId(id);\n setAdapterRejectReason('');\n };\n\n const handleConfirmRejectAdapter = (id: string) => {\n if (!adapterRejectReason.trim()) return;\n rejectAdapter.mutate(\n { id, reason: adapterRejectReason.trim() },\n {\n onSuccess: () => {\n setRejectingAdapterId(null);\n setAdapterRejectReason('');\n },\n }\n );\n };\n\n // --- Marketplace moderation ---------------------------------------------\n const { data: marketplaceReportsData, isLoading: reportsLoading } = useMarketplaceReports({\n pagination: { limit: 50 },\n });\n const moderateListing = useModerateListing();\n const [moderatingReportId, setModeratingReportId] = useState<string | null>(null);\n const [moderateAction, setModerateAction] = useState<SubModerationAction | null>(null);\n const [moderateReason, setModerateReason] = useState('');\n\n const marketplaceReports = marketplaceReportsData?.items ?? [];\n\n const handleStartModerate = (id: string, action: SubModerationAction) => {\n setModeratingReportId(id);\n setModerateAction(action);\n setModerateReason('');\n };\n\n const handleConfirmModerate = (id: string) => {\n if (!moderateAction || !moderateReason.trim()) return;\n moderateListing.mutate(\n { id, action: moderateAction, reason: moderateReason.trim() },\n {\n onSuccess: () => {\n setModeratingReportId(null);\n setModerateAction(null);\n setModerateReason('');\n },\n }\n );\n };\n\n return (\n <PageLayout\n title=\"SubscriberBot Admin\"\n description=\"Provider registry curation, adapter approvals, and marketplace moderation.\"\n >\n <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList className=\"mb-4 grid w-full grid-cols-3 sm:w-auto sm:inline-flex\">\n <TabsTrigger value=\"providers\" className=\"gap-2\">\n <Settings2 size={16} />\n Provider Registry\n </TabsTrigger>\n <TabsTrigger value=\"adapters\" className=\"gap-2\">\n <Plug size={16} />\n Adapter Approvals\n </TabsTrigger>\n <TabsTrigger value=\"marketplace\" className=\"gap-2\">\n <Store size={16} />\n Marketplace Moderation\n </TabsTrigger>\n </TabsList>\n\n {/* Provider registry curation — backed by real GraphQL queries. */}\n <TabsContent value=\"providers\">\n <Card>\n <CardHeader>\n <CardTitle>Provider registry</CardTitle>\n <CardDescription>\n Curate the global provider catalog. Verify submitted providers or deprecate stale\n entries.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {providersLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : providers.length === 0 ? (\n <EmptyState\n icon={<Store className=\"size-6 text-action-primary-bg\" />}\n title=\"No providers yet\"\n description=\"Once providers are created or claimed they will appear here for curation.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Category</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Created</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {providers.map((provider: SubProvider) => (\n <TableRow key={provider.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {provider.name}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{provider.category}</TableCell>\n <TableCell>\n <StatusBadge status={provider.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(provider.createdAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex justify-end gap-2\">\n {provider.status !== 'VERIFIED' && (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleVerify(provider.id)}\n disabled={updateProvider.isPending}\n >\n <CheckCircle2 size={14} className=\"mr-1\" />\n Verify\n </Button>\n )}\n {provider.status !== 'DEPRECATED' && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => handleDeprecate(provider.id)}\n disabled={updateProvider.isPending}\n >\n Deprecate\n </Button>\n )}\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Adapter approval queue — backed by real GraphQL queries. */}\n <TabsContent value=\"adapters\">\n <Card>\n <CardHeader>\n <CardTitle>Adapter approvals</CardTitle>\n <CardDescription>\n Review submitted integration adapters before they are published to the SubscriberBot\n adapter marketplace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {adaptersLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : adapterSubmissions.length === 0 ? (\n <EmptyState\n icon={<Plug className=\"size-6 text-action-primary-bg\" />}\n title=\"No adapter submissions\"\n description=\"Submitted integration adapters will appear here for review.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Adapter</TableHead>\n <TableHead>Submitting workspace</TableHead>\n <TableHead>Submitted</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {adapterSubmissions.map((submission) => (\n <Fragment key={submission.id}>\n <TableRow>\n <TableCell className=\"font-medium text-text-primary\">\n {submission.adapterId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {submission.submitterWorkspaceId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(submission.createdAt)}\n </TableCell>\n <TableCell>\n <StatusBadge status={submission.status} />\n </TableCell>\n <TableCell className=\"text-right\">\n {submission.status === 'PENDING' && (\n <div className=\"flex justify-end gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleApproveAdapter(submission.id)}\n disabled={approveAdapter.isPending || rejectAdapter.isPending}\n >\n <CheckCircle2 size={14} className=\"mr-1\" />\n Approve\n </Button>\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => handleStartRejectAdapter(submission.id)}\n disabled={approveAdapter.isPending || rejectAdapter.isPending}\n >\n <XCircle size={14} className=\"mr-1\" />\n Reject\n </Button>\n </div>\n )}\n </TableCell>\n </TableRow>\n {rejectingAdapterId === submission.id && (\n <TableRow key={`${submission.id}-reject`}>\n <TableCell colSpan={5} className=\"bg-bg-sunken\">\n <div className=\"flex flex-col gap-2 py-1 sm:flex-row sm:items-start\">\n <Textarea\n value={adapterRejectReason}\n onChange={(event) => setAdapterRejectReason(event.target.value)}\n placeholder=\"Reason for rejecting this adapter submission (required)\"\n className=\"min-h-[60px] flex-1\"\n autoFocus\n />\n <div className=\"flex gap-2 sm:flex-col\">\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => handleConfirmRejectAdapter(submission.id)}\n disabled={\n !adapterRejectReason.trim() || rejectAdapter.isPending\n }\n >\n Confirm reject\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setRejectingAdapterId(null)}\n disabled={rejectAdapter.isPending}\n >\n Cancel\n </Button>\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Marketplace moderation — backed by real GraphQL queries. */}\n <TabsContent value=\"marketplace\">\n <Card>\n <CardHeader>\n <CardTitle>Marketplace moderation</CardTitle>\n <CardDescription>\n Review reported marketplace listings and take moderation actions.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {reportsLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : marketplaceReports.length === 0 ? (\n <EmptyState\n icon={<Store className=\"size-6 text-action-primary-bg\" />}\n title=\"No reported listings\"\n description=\"Reported marketplace listings will appear here for moderation.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Listing</TableHead>\n <TableHead>Reporting workspace</TableHead>\n <TableHead>Reported</TableHead>\n <TableHead>Reason</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {marketplaceReports.map((report) => (\n <Fragment key={report.id}>\n <TableRow>\n <TableCell className=\"font-medium text-text-primary\">\n {report.listingId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {report.reporterWorkspaceId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(report.createdAt)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{report.reason}</TableCell>\n <TableCell>\n <StatusBadge status={report.status} />\n </TableCell>\n <TableCell className=\"text-right\">\n {report.status === 'PENDING' && (\n <div className=\"flex justify-end gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleStartModerate(report.id, 'DISMISS')}\n disabled={moderateListing.isPending}\n >\n Dismiss\n </Button>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => handleStartModerate(report.id, 'REMOVE_LISTING')}\n disabled={moderateListing.isPending}\n >\n Remove\n </Button>\n </div>\n )}\n </TableCell>\n </TableRow>\n {moderatingReportId === report.id && (\n <TableRow key={`${report.id}-moderate`}>\n <TableCell colSpan={6} className=\"bg-bg-sunken\">\n <div className=\"flex flex-col gap-2 py-1 sm:flex-row sm:items-start\">\n <Textarea\n value={moderateReason}\n onChange={(event) => setModerateReason(event.target.value)}\n placeholder={`Reason to ${moderateAction === 'REMOVE_LISTING' ? 'remove this listing' : 'dismiss this report'} (required)`}\n className=\"min-h-[60px] flex-1\"\n autoFocus\n />\n <div className=\"flex gap-2 sm:flex-col\">\n <Button\n size=\"sm\"\n variant={\n moderateAction === 'REMOVE_LISTING'\n ? 'destructive'\n : 'outline'\n }\n onClick={() => handleConfirmModerate(report.id)}\n disabled={!moderateReason.trim() || moderateListing.isPending}\n >\n Confirm{' '}\n {moderateAction === 'REMOVE_LISTING'\n ? 'removal'\n : 'dismissal'}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setModeratingReportId(null)}\n disabled={moderateListing.isPending}\n >\n Cancel\n </Button>\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminDashboardPage.js","names":[],"sources":["../../../src/subscriberbot/admin/AdminDashboardPage.tsx"],"sourcesContent":["/**\n * SubscriberBot Admin Dashboard\n * @module subscriberbot/admin\n *\n * Product-specific admin surface mounted inside `admin-app`. It exposes the\n * three governance operations requested for SubscriberBot, all wired to the\n * real `wspace-subscriberbot-svc` admin governance schema (BOFF-3237):\n * 1. Provider registry curation — `subListProviders` / `subUpdateProvider`.\n * 2. Adapter approval queue — `subListAdapterSubmissions` /\n * `subApproveAdapter` / `subRejectAdapter`.\n * 3. Marketplace moderation queue — `subListMarketplaceReports` /\n * `subModerateListing`.\n */\n\nimport { Fragment, useState, type FC } from 'react';\nimport {\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n EmptyState,\n Spinner,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle2, Plug, Settings2, Store, XCircle } from 'lucide-react';\n\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport {\n useAdapterSubmissions,\n useApproveAdapter,\n useMarketplaceReports,\n useModerateListing,\n useProviders,\n useRejectAdapter,\n useUpdateProvider,\n} from '../hooks';\nimport { formatDate } from '../utils/formatters';\nimport { useTr } from '../hooks/useTr';\nimport type { SubModerationAction, SubProvider } from '../types';\n\nexport const AdminDashboardPage: FC = () => {\n const tr = useTr();\n const [activeTab, setActiveTab] = useState('providers');\n\n // --- Provider registry ----------------------------------------------\n const { data: providersData, isLoading: providersLoading } = useProviders({\n pagination: { limit: 50 },\n });\n const updateProvider = useUpdateProvider();\n\n const handleVerify = (id: string) => {\n updateProvider.mutate({ id, input: { status: 'VERIFIED' } });\n };\n\n const handleDeprecate = (id: string) => {\n updateProvider.mutate({ id, input: { status: 'DEPRECATED' } });\n };\n\n const providers = providersData?.items ?? [];\n\n // --- Adapter approvals -------------------------------------------------\n const { data: adapterSubmissionsData, isLoading: adaptersLoading } = useAdapterSubmissions({\n pagination: { limit: 50 },\n });\n const approveAdapter = useApproveAdapter();\n const rejectAdapter = useRejectAdapter();\n const [rejectingAdapterId, setRejectingAdapterId] = useState<string | null>(null);\n const [adapterRejectReason, setAdapterRejectReason] = useState('');\n\n const adapterSubmissions = adapterSubmissionsData?.items ?? [];\n\n const handleApproveAdapter = (id: string) => {\n approveAdapter.mutate({ id });\n };\n\n const handleStartRejectAdapter = (id: string) => {\n setRejectingAdapterId(id);\n setAdapterRejectReason('');\n };\n\n const handleConfirmRejectAdapter = (id: string) => {\n if (!adapterRejectReason.trim()) return;\n rejectAdapter.mutate(\n { id, reason: adapterRejectReason.trim() },\n {\n onSuccess: () => {\n setRejectingAdapterId(null);\n setAdapterRejectReason('');\n },\n }\n );\n };\n\n // --- Marketplace moderation ---------------------------------------------\n const { data: marketplaceReportsData, isLoading: reportsLoading } = useMarketplaceReports({\n pagination: { limit: 50 },\n });\n const moderateListing = useModerateListing();\n const [moderatingReportId, setModeratingReportId] = useState<string | null>(null);\n const [moderateAction, setModerateAction] = useState<SubModerationAction | null>(null);\n const [moderateReason, setModerateReason] = useState('');\n\n const marketplaceReports = marketplaceReportsData?.items ?? [];\n\n const handleStartModerate = (id: string, action: SubModerationAction) => {\n setModeratingReportId(id);\n setModerateAction(action);\n setModerateReason('');\n };\n\n const handleConfirmModerate = (id: string) => {\n if (!moderateAction || !moderateReason.trim()) return;\n moderateListing.mutate(\n { id, action: moderateAction, reason: moderateReason.trim() },\n {\n onSuccess: () => {\n setModeratingReportId(null);\n setModerateAction(null);\n setModerateReason('');\n },\n }\n );\n };\n\n return (\n <PageLayout\n title={tr('admin.title', 'SubscriberBot Admin')}\n description={tr(\n 'admin.description',\n 'Provider registry curation, adapter approvals, and marketplace moderation.'\n )}\n >\n <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList className=\"mb-4 grid w-full grid-cols-3 sm:w-auto sm:inline-flex\">\n <TabsTrigger value=\"providers\" className=\"gap-2\">\n <Settings2 size={16} />\n {tr('admin.tabs.providers', 'Provider Registry')}\n </TabsTrigger>\n <TabsTrigger value=\"adapters\" className=\"gap-2\">\n <Plug size={16} />\n {tr('admin.tabs.adapters', 'Adapter Approvals')}\n </TabsTrigger>\n <TabsTrigger value=\"marketplace\" className=\"gap-2\">\n <Store size={16} />\n {tr('admin.tabs.marketplace', 'Marketplace Moderation')}\n </TabsTrigger>\n </TabsList>\n\n {/* Provider registry curation — backed by real GraphQL queries. */}\n <TabsContent value=\"providers\">\n <Card>\n <CardHeader>\n <CardTitle>{tr('admin.providers.title', 'Provider registry')}</CardTitle>\n <CardDescription>\n {tr(\n 'admin.providers.description',\n 'Curate the global provider catalog. Verify submitted providers or deprecate stale entries.'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {providersLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : providers.length === 0 ? (\n <EmptyState\n icon={<Store className=\"size-6 text-action-primary-bg\" />}\n title={tr('admin.providers.emptyTitle', 'No providers yet')}\n description={tr(\n 'admin.providers.emptyDescription',\n 'Once providers are created or claimed they will appear here for curation.'\n )}\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{tr('admin.providers.table.name', 'Name')}</TableHead>\n <TableHead>{tr('admin.providers.table.category', 'Category')}</TableHead>\n <TableHead>{tr('admin.providers.table.status', 'Status')}</TableHead>\n <TableHead>{tr('admin.providers.table.created', 'Created')}</TableHead>\n <TableHead className=\"text-right\">\n {tr('admin.providers.table.actions', 'Actions')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {providers.map((provider: SubProvider) => (\n <TableRow key={provider.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {provider.name}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{provider.category}</TableCell>\n <TableCell>\n <StatusBadge status={provider.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(provider.createdAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex justify-end gap-2\">\n {provider.status !== 'VERIFIED' && (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleVerify(provider.id)}\n disabled={updateProvider.isPending}\n >\n <CheckCircle2 size={14} className=\"mr-1\" />\n {tr('admin.providers.verify', 'Verify')}\n </Button>\n )}\n {provider.status !== 'DEPRECATED' && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => handleDeprecate(provider.id)}\n disabled={updateProvider.isPending}\n >\n {tr('admin.providers.deprecate', 'Deprecate')}\n </Button>\n )}\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Adapter approval queue — backed by real GraphQL queries. */}\n <TabsContent value=\"adapters\">\n <Card>\n <CardHeader>\n <CardTitle>{tr('admin.adapters.title', 'Adapter approvals')}</CardTitle>\n <CardDescription>\n {tr(\n 'admin.adapters.description',\n 'Review submitted integration adapters before they are published to the SubscriberBot adapter marketplace.'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {adaptersLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : adapterSubmissions.length === 0 ? (\n <EmptyState\n icon={<Plug className=\"size-6 text-action-primary-bg\" />}\n title={tr('admin.adapters.emptyTitle', 'No adapter submissions')}\n description={tr(\n 'admin.adapters.emptyDescription',\n 'Submitted integration adapters will appear here for review.'\n )}\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{tr('admin.adapters.table.adapter', 'Adapter')}</TableHead>\n <TableHead>\n {tr('admin.adapters.table.workspace', 'Submitting workspace')}\n </TableHead>\n <TableHead>{tr('admin.adapters.table.submitted', 'Submitted')}</TableHead>\n <TableHead>{tr('admin.adapters.table.status', 'Status')}</TableHead>\n <TableHead className=\"text-right\">\n {tr('admin.adapters.table.actions', 'Actions')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {adapterSubmissions.map((submission) => (\n <Fragment key={submission.id}>\n <TableRow>\n <TableCell className=\"font-medium text-text-primary\">\n {submission.adapterId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {submission.submitterWorkspaceId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(submission.createdAt)}\n </TableCell>\n <TableCell>\n <StatusBadge status={submission.status} />\n </TableCell>\n <TableCell className=\"text-right\">\n {submission.status === 'PENDING' && (\n <div className=\"flex justify-end gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleApproveAdapter(submission.id)}\n disabled={approveAdapter.isPending || rejectAdapter.isPending}\n >\n <CheckCircle2 size={14} className=\"mr-1\" />\n {tr('admin.adapters.approve', 'Approve')}\n </Button>\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => handleStartRejectAdapter(submission.id)}\n disabled={approveAdapter.isPending || rejectAdapter.isPending}\n >\n <XCircle size={14} className=\"mr-1\" />\n {tr('admin.adapters.reject', 'Reject')}\n </Button>\n </div>\n )}\n </TableCell>\n </TableRow>\n {rejectingAdapterId === submission.id && (\n <TableRow key={`${submission.id}-reject`}>\n <TableCell colSpan={5} className=\"bg-bg-sunken\">\n <div className=\"flex flex-col gap-2 py-1 sm:flex-row sm:items-start\">\n <Textarea\n value={adapterRejectReason}\n onChange={(event) => setAdapterRejectReason(event.target.value)}\n placeholder={tr(\n 'admin.adapters.rejectPlaceholder',\n 'Reason for rejecting this adapter submission (required)'\n )}\n className=\"min-h-[60px] flex-1\"\n autoFocus\n />\n <div className=\"flex gap-2 sm:flex-col\">\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => handleConfirmRejectAdapter(submission.id)}\n disabled={\n !adapterRejectReason.trim() || rejectAdapter.isPending\n }\n >\n {tr('admin.adapters.confirmReject', 'Confirm reject')}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setRejectingAdapterId(null)}\n disabled={rejectAdapter.isPending}\n >\n {tr('admin.adapters.cancel', 'Cancel')}\n </Button>\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Marketplace moderation — backed by real GraphQL queries. */}\n <TabsContent value=\"marketplace\">\n <Card>\n <CardHeader>\n <CardTitle>{tr('admin.marketplace.title', 'Marketplace moderation')}</CardTitle>\n <CardDescription>\n {tr(\n 'admin.marketplace.description',\n 'Review reported marketplace listings and take moderation actions.'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n {reportsLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : marketplaceReports.length === 0 ? (\n <EmptyState\n icon={<Store className=\"size-6 text-action-primary-bg\" />}\n title={tr('admin.marketplace.emptyTitle', 'No reported listings')}\n description={tr(\n 'admin.marketplace.emptyDescription',\n 'Reported marketplace listings will appear here for moderation.'\n )}\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{tr('admin.marketplace.table.listing', 'Listing')}</TableHead>\n <TableHead>\n {tr('admin.marketplace.table.workspace', 'Reporting workspace')}\n </TableHead>\n <TableHead>{tr('admin.marketplace.table.reported', 'Reported')}</TableHead>\n <TableHead>{tr('admin.marketplace.table.reason', 'Reason')}</TableHead>\n <TableHead>{tr('admin.marketplace.table.status', 'Status')}</TableHead>\n <TableHead className=\"text-right\">\n {tr('admin.marketplace.table.actions', 'Actions')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {marketplaceReports.map((report) => (\n <Fragment key={report.id}>\n <TableRow>\n <TableCell className=\"font-medium text-text-primary\">\n {report.listingId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {report.reporterWorkspaceId}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(report.createdAt)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{report.reason}</TableCell>\n <TableCell>\n <StatusBadge status={report.status} />\n </TableCell>\n <TableCell className=\"text-right\">\n {report.status === 'PENDING' && (\n <div className=\"flex justify-end gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleStartModerate(report.id, 'DISMISS')}\n disabled={moderateListing.isPending}\n >\n {tr('admin.marketplace.dismiss', 'Dismiss')}\n </Button>\n <Button\n size=\"sm\"\n variant=\"destructive\"\n onClick={() => handleStartModerate(report.id, 'REMOVE_LISTING')}\n disabled={moderateListing.isPending}\n >\n {tr('admin.marketplace.remove', 'Remove')}\n </Button>\n </div>\n )}\n </TableCell>\n </TableRow>\n {moderatingReportId === report.id && (\n <TableRow key={`${report.id}-moderate`}>\n <TableCell colSpan={6} className=\"bg-bg-sunken\">\n <div className=\"flex flex-col gap-2 py-1 sm:flex-row sm:items-start\">\n <Textarea\n value={moderateReason}\n onChange={(event) => setModerateReason(event.target.value)}\n placeholder={\n moderateAction === 'REMOVE_LISTING'\n ? tr(\n 'admin.marketplace.reasonPlaceholderRemove',\n 'Reason to remove this listing (required)'\n )\n : tr(\n 'admin.marketplace.reasonPlaceholderDismiss',\n 'Reason to dismiss this report (required)'\n )\n }\n className=\"min-h-[60px] flex-1\"\n autoFocus\n />\n <div className=\"flex gap-2 sm:flex-col\">\n <Button\n size=\"sm\"\n variant={\n moderateAction === 'REMOVE_LISTING'\n ? 'destructive'\n : 'outline'\n }\n onClick={() => handleConfirmModerate(report.id)}\n disabled={!moderateReason.trim() || moderateListing.isPending}\n >\n {moderateAction === 'REMOVE_LISTING'\n ? tr('admin.marketplace.confirmRemoval', 'Confirm removal')\n : tr(\n 'admin.marketplace.confirmDismissal',\n 'Confirm dismissal'\n )}\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setModeratingReportId(null)}\n disabled={moderateListing.isPending}\n >\n {tr('admin.marketplace.cancel', 'Cancel')}\n </Button>\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;AAqDA,IAAa,UAA+B;CAC1C,IAAM,IAAK,GAAO,EACZ,CAAC,GAAW,MAAgB,EAAS,YAAY,EAGjD,EAAE,MAAM,IAAe,WAAW,OAAqB,GAAa,EACxE,YAAY,EAAE,OAAO,IAAI,EAC1B,CAAC,EACI,IAAiB,IAAmB,EAEpC,KAAgB,MAAe;AACnC,IAAe,OAAO;GAAE;GAAI,OAAO,EAAE,QAAQ,YAAY;GAAE,CAAC;IAGxD,KAAmB,MAAe;AACtC,IAAe,OAAO;GAAE;GAAI,OAAO,EAAE,QAAQ,cAAc;GAAE,CAAC;IAG1D,IAAY,IAAe,SAAS,EAAE,EAGtC,EAAE,MAAM,GAAwB,WAAW,MAAoB,EAAsB,EACzF,YAAY,EAAE,OAAO,IAAI,EAC1B,CAAC,EACI,IAAiB,GAAmB,EACpC,IAAgB,IAAkB,EAClC,CAAC,GAAoB,KAAyB,EAAwB,KAAK,EAC3E,CAAC,GAAqB,KAA0B,EAAS,GAAG,EAE5D,IAAqB,GAAwB,SAAS,EAAE,EAExD,MAAwB,MAAe;AAC3C,IAAe,OAAO,EAAE,OAAI,CAAC;IAGzB,MAA4B,MAAe;AAE/C,EADA,EAAsB,EAAG,EACzB,EAAuB,GAAG;IAGtB,MAA8B,MAAe;AAC5C,IAAoB,MAAM,IAC/B,EAAc,OACZ;GAAE;GAAI,QAAQ,EAAoB,MAAM;GAAE,EAC1C,EACE,iBAAiB;AAEf,GADA,EAAsB,KAAK,EAC3B,EAAuB,GAAG;KAE7B,CACF;IAIG,EAAE,MAAM,IAAwB,WAAW,OAAmB,EAAsB,EACxF,YAAY,EAAE,OAAO,IAAI,EAC1B,CAAC,EACI,IAAkB,IAAoB,EACtC,CAAC,IAAoB,KAAyB,EAAwB,KAAK,EAC3E,CAAC,GAAgB,KAAqB,EAAqC,KAAK,EAChF,CAAC,GAAgB,KAAqB,EAAS,GAAG,EAElD,IAAqB,IAAwB,SAAS,EAAE,EAExD,KAAuB,GAAY,MAAgC;AAGvE,EAFA,EAAsB,EAAG,EACzB,EAAkB,EAAO,EACzB,EAAkB,GAAG;IAGjB,MAAyB,MAAe;AACxC,GAAC,KAAkB,CAAC,EAAe,MAAM,IAC7C,EAAgB,OACd;GAAE;GAAI,QAAQ;GAAgB,QAAQ,EAAe,MAAM;GAAE,EAC7D,EACE,iBAAiB;AAGf,GAFA,EAAsB,KAAK,EAC3B,EAAkB,KAAK,EACvB,EAAkB,GAAG;KAExB,CACF;;AAGH,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,eAAe,sBAAsB;EAC/C,aAAa,EACX,qBACA,6EACD;YAED,kBAAC,IAAD;GAAM,OAAO;GAAW,eAAe;GAAc,WAAU;aAA/D;IACE,kBAAC,IAAD;KAAU,WAAU;eAApB;MACE,kBAAC,GAAD;OAAa,OAAM;OAAY,WAAU;iBAAzC,CACE,kBAAC,IAAD,EAAW,MAAM,IAAM,CAAA,EACtB,EAAG,wBAAwB,oBAAoB,CACpC;;MACd,kBAAC,GAAD;OAAa,OAAM;OAAW,WAAU;iBAAxC,CACE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,uBAAuB,oBAAoB,CACnC;;MACd,kBAAC,GAAD;OAAa,OAAM;OAAc,WAAU;iBAA3C,CACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAClB,EAAG,0BAA0B,yBAAyB,CAC3C;;MACL;;IAGX,kBAAC,GAAD;KAAa,OAAM;eACjB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAY,EAAG,yBAAyB,oBAAoB,EAAa,CAAA,EACzE,kBAAC,GAAD,EAAA,UACG,EACC,+BACA,6FACD,EACe,CAAA,CACP,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAS,MAAK,MAAO,CAAA;MACjB,CAAA,GACJ,EAAU,WAAW,IACvB,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAO,WAAU,iCAAkC,CAAA;MACzD,OAAO,EAAG,8BAA8B,mBAAmB;MAC3D,aAAa,EACX,oCACA,4EACD;MACD,CAAA,GAEF,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD,EAAA,UAAY,EAAG,8BAA8B,OAAO,EAAa,CAAA;OACjE,kBAAC,GAAD,EAAA,UAAY,EAAG,kCAAkC,WAAW,EAAa,CAAA;OACzE,kBAAC,GAAD,EAAA,UAAY,EAAG,gCAAgC,SAAS,EAAa,CAAA;OACrE,kBAAC,GAAD,EAAA,UAAY,EAAG,iCAAiC,UAAU,EAAa,CAAA;OACvE,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAG,iCAAiC,UAAU;QACrC,CAAA;OACH,EAAA,CAAA,EACC,CAAA,EACd,kBAAC,GAAD,EAAA,UACG,EAAU,KAAK,MACd,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAS;QACA,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAAuB,EAAS;QAAqB,CAAA;OAC1E,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAS,QAAU,CAAA,EAC9B,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW,EAAS,UAAU;QACrB,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBACnB,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACG,EAAS,WAAW,cACnB,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,EAAa,EAAS,GAAG;UACxC,UAAU,EAAe;oBAJ3B,CAME,kBAAC,GAAD;WAAc,MAAM;WAAI,WAAU;WAAS,CAAA,EAC1C,EAAG,0BAA0B,SAAS,CAChC;aAEV,EAAS,WAAW,gBACnB,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,EAAgB,EAAS,GAAG;UAC3C,UAAU,EAAe;oBAExB,EAAG,6BAA6B,YAAY;UACtC,CAAA,CAEP;;QACI,CAAA;OACH,EAAA,EApCI,EAAS,GAoCb,CACX,EACQ,CAAA,CACN,EAAA,CAAA;MACJ,CAAA,EAEI,CAAA,CACT,EAAA,CAAA;KACK,CAAA;IAGd,kBAAC,GAAD;KAAa,OAAM;eACjB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAY,EAAG,wBAAwB,oBAAoB,EAAa,CAAA,EACxE,kBAAC,GAAD,EAAA,UACG,EACC,8BACA,4GACD,EACe,CAAA,CACP,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACG,IACC,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAS,MAAK,MAAO,CAAA;MACjB,CAAA,GACJ,EAAmB,WAAW,IAChC,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAM,WAAU,iCAAkC,CAAA;MACxD,OAAO,EAAG,6BAA6B,yBAAyB;MAChE,aAAa,EACX,mCACA,8DACD;MACD,CAAA,GAEF,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD,EAAA,UAAY,EAAG,gCAAgC,UAAU,EAAa,CAAA;OACtE,kBAAC,GAAD,EAAA,UACG,EAAG,kCAAkC,uBAAuB,EACnD,CAAA;OACZ,kBAAC,GAAD,EAAA,UAAY,EAAG,kCAAkC,YAAY,EAAa,CAAA;OAC1E,kBAAC,GAAD,EAAA,UAAY,EAAG,+BAA+B,SAAS,EAAa,CAAA;OACpE,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAG,gCAAgC,UAAU;QACpC,CAAA;OACH,EAAA,CAAA,EACC,CAAA,EACd,kBAAC,GAAD,EAAA,UACG,EAAmB,KAAK,MACvB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW;QACF,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW;QACF,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW,EAAW,UAAU;QACvB,CAAA;OACZ,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAW,QAAU,CAAA,EAChC,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW,WAAW,aACrB,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,GAAqB,EAAW,GAAG;UAClD,UAAU,EAAe,aAAa,EAAc;oBAJtD,CAME,kBAAC,GAAD;WAAc,MAAM;WAAI,WAAU;WAAS,CAAA,EAC1C,EAAG,0BAA0B,UAAU,CACjC;aACT,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,GAAyB,EAAW,GAAG;UACtD,UAAU,EAAe,aAAa,EAAc;oBAJtD,CAME,kBAAC,IAAD;WAAS,MAAM;WAAI,WAAU;WAAS,CAAA,EACrC,EAAG,yBAAyB,SAAS,CAC/B;YACL;;QAEE,CAAA;OACH,EAAA,CAAA,EACV,MAAuB,EAAW,MACjC,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;OAAW,SAAS;OAAG,WAAU;iBAC/B,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SACE,OAAO;SACP,WAAW,MAAU,EAAuB,EAAM,OAAO,MAAM;SAC/D,aAAa,EACX,oCACA,0DACD;SACD,WAAU;SACV,WAAA;SACA,CAAA,EACF,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,GAA2B,EAAW,GAAG;UACxD,UACE,CAAC,EAAoB,MAAM,IAAI,EAAc;oBAG9C,EAAG,gCAAgC,iBAAiB;UAC9C,CAAA,EACT,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,EAAsB,KAAK;UAC1C,UAAU,EAAc;oBAEvB,EAAG,yBAAyB,SAAS;UAC/B,CAAA,CACL;WACF;;OACI,CAAA,EACH,EAnCI,GAAG,EAAW,GAAG,SAmCrB,CAEJ,EAAA,EA7EI,EAAW,GA6Ef,CACX,EACQ,CAAA,CACN,EAAA,CAAA;MACJ,CAAA,EAEI,CAAA,CACT,EAAA,CAAA;KACK,CAAA;IAGd,kBAAC,GAAD;KAAa,OAAM;eACjB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAY,EAAG,2BAA2B,yBAAyB,EAAa,CAAA,EAChF,kBAAC,GAAD,EAAA,UACG,EACC,iCACA,oEACD,EACe,CAAA,CACP,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAS,MAAK,MAAO,CAAA;MACjB,CAAA,GACJ,EAAmB,WAAW,IAChC,kBAAC,GAAD;MACE,MAAM,kBAAC,GAAD,EAAO,WAAU,iCAAkC,CAAA;MACzD,OAAO,EAAG,gCAAgC,uBAAuB;MACjE,aAAa,EACX,sCACA,iEACD;MACD,CAAA,GAEF,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD,EAAA,UAAY,EAAG,mCAAmC,UAAU,EAAa,CAAA;OACzE,kBAAC,GAAD,EAAA,UACG,EAAG,qCAAqC,sBAAsB,EACrD,CAAA;OACZ,kBAAC,GAAD,EAAA,UAAY,EAAG,oCAAoC,WAAW,EAAa,CAAA;OAC3E,kBAAC,GAAD,EAAA,UAAY,EAAG,kCAAkC,SAAS,EAAa,CAAA;OACvE,kBAAC,GAAD,EAAA,UAAY,EAAG,kCAAkC,SAAS,EAAa,CAAA;OACvE,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAG,mCAAmC,UAAU;QACvC,CAAA;OACH,EAAA,CAAA,EACC,CAAA,EACd,kBAAC,GAAD,EAAA,UACG,EAAmB,KAAK,MACvB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA;OACE,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAO;QACE,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAO;QACE,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAW,EAAO,UAAU;QACnB,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAAuB,EAAO;QAAmB,CAAA;OACtE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAa,QAAQ,EAAO,QAAU,CAAA,EAC5B,CAAA;OACZ,kBAAC,GAAD;QAAW,WAAU;kBAClB,EAAO,WAAW,aACjB,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,EAAoB,EAAO,IAAI,UAAU;UACxD,UAAU,EAAgB;oBAEzB,EAAG,6BAA6B,UAAU;UACpC,CAAA,EACT,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,EAAoB,EAAO,IAAI,iBAAiB;UAC/D,UAAU,EAAgB;oBAEzB,EAAG,4BAA4B,SAAS;UAClC,CAAA,CACL;;QAEE,CAAA;OACH,EAAA,CAAA,EACV,OAAuB,EAAO,MAC7B,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;OAAW,SAAS;OAAG,WAAU;iBAC/B,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SACE,OAAO;SACP,WAAW,MAAU,EAAkB,EAAM,OAAO,MAAM;SAC1D,aACE,MAAmB,mBACf,EACE,6CACA,2CACD,GACD,EACE,8CACA,2CACD;SAEP,WAAU;SACV,WAAA;SACA,CAAA,EACF,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,GAAD;UACE,MAAK;UACL,SACE,MAAmB,mBACf,gBACA;UAEN,eAAe,GAAsB,EAAO,GAAG;UAC/C,UAAU,CAAC,EAAe,MAAM,IAAI,EAAgB;oBAEnD,MAAmB,mBAChB,EAAG,oCAAoC,kBAAkB,GACzD,EACE,sCACA,oBACD;UACE,CAAA,EACT,kBAAC,GAAD;UACE,MAAK;UACL,SAAQ;UACR,eAAe,EAAsB,KAAK;UAC1C,UAAU,EAAgB;oBAEzB,EAAG,4BAA4B,SAAS;UAClC,CAAA,CACL;WACF;;OACI,CAAA,EACH,EAjDI,GAAG,EAAO,GAAG,WAiDjB,CAEJ,EAAA,EA1FI,EAAO,GA0FX,CACX,EACQ,CAAA,CACN,EAAA,CAAA;MACJ,CAAA,EAEI,CAAA,CACT,EAAA,CAAA;KACK,CAAA;IACT;;EACI,CAAA"}
@@ -2,6 +2,7 @@
2
2
  * SubscriberBot hooks barrel
3
3
  * @module subscriberbot/hooks
4
4
  */
5
+ export { useTr } from './useTr';
5
6
  export { useRelationships, useRelationship, useCreateRelationship, useUpdateRelationship, useTransitionRelationship, useCancelRelationship, useRenewalEvents, useEntitlements, useCreateEntitlement, useAssets, useCreateAsset, useUploadFile, useFileDownloadUrl, useProviders, useProvider, useCreateProvider, useUpdateProvider, useArchiveProvider, usePlans, useCreatePlan, useBenchmarkDataPoints, useInboxMessages, useMarkMessageRead, useIngestMessage, useInvoices, useMarkInvoicePaid, useCreateInvoice, usePaymentInstruments, useCreatePaymentInstrument, useRemovePaymentInstrument, useChannels, useCreateChannel, useVerifyChannel, useAgents, useAgent, useCreateAgent, useSetAgentStatus, useCreatePolicy, useWorkflows, useCreateWorkflow, useActivateWorkflow, useAdapterSubmissions, useApproveAdapter, useRejectAdapter, useMarketplaceReports, useModerateListing, } from './useSubscriberBotApi';
6
7
  export type { RelationshipListFilters, ProviderListFilters, InboxListFilters, InvoiceListFilters, AgentListFilters, AdapterSubmissionListFilters, MarketplaceReportListFilters, } from './useSubscriberBotApi';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,aAAa,EACb,kBAAkB,EAElB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,sBAAsB,EAEtB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAEhB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAEhB,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAEhB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EAEnB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,OAAO,EAEL,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,SAAS,EACT,cAAc,EACd,aAAa,EACb,kBAAkB,EAElB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,sBAAsB,EAEtB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAEhB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAEhB,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAEhB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EAEnB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC"}
@@ -1 +1,2 @@
1
1
  import "./useSubscriberBotApi.js";
2
+ import "./useTr.js";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * useTr — translation hook with fallback semantics.
3
+ *
4
+ * Wraps `useI18n().t()` so that when a key has no translation (i.e. the
5
+ * provider returns the key itself), the caller's English fallback is used
6
+ * instead. This keeps consumer call sites consistent and avoids leaking
7
+ * untranslated keys into the UI.
8
+ *
9
+ * Supports optional interpolation params using `{{key}}` placeholders.
10
+ *
11
+ * @example
12
+ * const tr = useTr();
13
+ * return <h1>{tr('dashboard.title', 'Overview')}</h1>;
14
+ * return <p>{tr('dashboard.openInvoices.label', '{{count}} open invoices', { count: 5 })}</p>;
15
+ */
16
+ export declare function useTr(): (key: string, fallback: string, params?: Record<string, string | number>) => string;
17
+ //# sourceMappingURL=useTr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTr.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/hooks/useTr.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,IAAI,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KACrC,MAAM,CAcV"}
@@ -0,0 +1,14 @@
1
+ import { useCallback as e } from "react";
2
+ import { useI18n as t } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
+ //#region src/subscriberbot/hooks/useTr.ts
4
+ function n() {
5
+ let { t: n } = t();
6
+ return e((e, t, r) => {
7
+ let i = n(e), a = i === e ? t : i;
8
+ return r ? Object.entries(r).reduce((e, [t, n]) => e.replace(RegExp(`\\{\\{${t}\\}\\}`, "g"), String(n)), a) : a;
9
+ }, [n]);
10
+ }
11
+ //#endregion
12
+ export { n as useTr };
13
+
14
+ //# sourceMappingURL=useTr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTr.js","names":[],"sources":["../../../src/subscriberbot/hooks/useTr.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n/**\n * useTr — translation hook with fallback semantics.\n *\n * Wraps `useI18n().t()` so that when a key has no translation (i.e. the\n * provider returns the key itself), the caller's English fallback is used\n * instead. This keeps consumer call sites consistent and avoids leaking\n * untranslated keys into the UI.\n *\n * Supports optional interpolation params using `{{key}}` placeholders.\n *\n * @example\n * const tr = useTr();\n * return <h1>{tr('dashboard.title', 'Overview')}</h1>;\n * return <p>{tr('dashboard.openInvoices.label', '{{count}} open invoices', { count: 5 })}</p>;\n */\nexport function useTr(): (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string {\n const { t } = useI18n();\n return useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key);\n const raw = translated === key ? fallback : translated;\n if (!params) return raw;\n return Object.entries(params).reduce(\n (str, [k, v]) => str.replace(new RegExp(`\\\\{\\\\{${k}\\\\}\\\\}`, 'g'), String(v)),\n raw\n );\n },\n [t]\n );\n}\n"],"mappings":";;;AAkBA,SAAgB,IAIJ;CACV,IAAM,EAAE,SAAM,GAAS;AACvB,QAAO,GACJ,GAAa,GAAkB,MAAqD;EACnF,IAAM,IAAa,EAAE,EAAI,EACnB,IAAM,MAAe,IAAM,IAAW;AAE5C,SADK,IACE,OAAO,QAAQ,EAAO,CAAC,QAC3B,GAAK,CAAC,GAAG,OAAO,EAAI,QAAY,OAAO,SAAS,EAAE,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,EAC5E,EACD,GAJmB;IAMtB,CAAC,EAAE,CACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssetVaultPage.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/pages/AssetVaultPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAoHnD,eAAO,MAAM,cAAc,EAAE,EAgL5B,CAAC"}
1
+ {"version":3,"file":"AssetVaultPage.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/pages/AssetVaultPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAsHnD,eAAO,MAAM,cAAc,EAAE,EAsM5B,CAAC"}