@burdenoff/microfe-devportal 2026.1113.1 → 2026.1113.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.
Files changed (55) hide show
  1. package/dist/devportal/DevportalRoot.js +65 -119
  2. package/dist/devportal/DevportalRoot.js.map +1 -1
  3. package/dist/devportal/components/AppCard.js +4 -4
  4. package/dist/devportal/components/DeveloperSettingsHub.d.ts +6 -0
  5. package/dist/devportal/components/DeveloperSettingsHub.js +59 -0
  6. package/dist/devportal/components/DeveloperSettingsHub.js.map +1 -0
  7. package/dist/devportal/components/SectionNav.d.ts +1 -1
  8. package/dist/devportal/components/SectionNav.js +60 -36
  9. package/dist/devportal/components/SectionNav.js.map +1 -1
  10. package/dist/devportal/pages/AnalyticsDashboardPage.js +186 -179
  11. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  12. package/dist/devportal/pages/ApiKeysPage.js +113 -111
  13. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  14. package/dist/devportal/pages/AppLogsPage.js +80 -84
  15. package/dist/devportal/pages/AppLogsPage.js.map +1 -1
  16. package/dist/devportal/pages/ApplicationDetailPage.js +529 -504
  17. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  18. package/dist/devportal/pages/ApplicationsPage.js +68 -67
  19. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  20. package/dist/devportal/pages/CreateApiKeyPage.js +163 -166
  21. package/dist/devportal/pages/CreateApiKeyPage.js.map +1 -1
  22. package/dist/devportal/pages/CreateOAuthClientPage.js +134 -130
  23. package/dist/devportal/pages/CreateOAuthClientPage.js.map +1 -1
  24. package/dist/devportal/pages/DelegationsPage.js +11 -11
  25. package/dist/devportal/pages/DocumentationPage.js +100 -94
  26. package/dist/devportal/pages/DocumentationPage.js.map +1 -1
  27. package/dist/devportal/pages/EditApplicationPage.js +379 -377
  28. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  29. package/dist/devportal/pages/InvitationDecisionPage.js +83 -79
  30. package/dist/devportal/pages/InvitationDecisionPage.js.map +1 -1
  31. package/dist/devportal/pages/OAuthClientDetailPage.js +76 -76
  32. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  33. package/dist/devportal/pages/OAuthClientsPage.js +126 -124
  34. package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
  35. package/dist/devportal/pages/OrganizationDetailPage.js +19 -19
  36. package/dist/devportal/pages/OrganizationMembersPage.js +223 -204
  37. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  38. package/dist/devportal/pages/ResourcesPage.d.ts +6 -0
  39. package/dist/devportal/pages/ResourcesPage.js +171 -155
  40. package/dist/devportal/pages/ResourcesPage.js.map +1 -1
  41. package/dist/devportal/pages/SellerDashboardPage.js +13 -13
  42. package/dist/devportal/pages/SellerItemsPage.js +4 -4
  43. package/dist/devportal/pages/SettingsPage.js +330 -315
  44. package/dist/devportal/pages/SettingsPage.js.map +1 -1
  45. package/dist/devportal/pages/SetupPage.js +5 -5
  46. package/dist/devportal/pages/WebhookDetailPage.js +6 -6
  47. package/dist/devportal/pages/WebhooksPage.js +39 -39
  48. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  49. package/dist/devportal/utils/appDetailTabs.d.ts +73 -0
  50. package/dist/devportal/utils/appDetailTabs.js +62 -0
  51. package/dist/devportal/utils/appDetailTabs.js.map +1 -0
  52. package/dist/devportal/utils/developerNav.d.ts +39 -0
  53. package/dist/devportal/utils/developerNav.js +304 -0
  54. package/dist/devportal/utils/developerNav.js.map +1 -0
  55. package/package.json +2 -2
@@ -4,22 +4,22 @@ import { ActiveIndicator as n } from "../components/StatusBadge.js";
4
4
  import { useCurrentUserAppsQuery as r } from "../../generated/global-operations.js";
5
5
  import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
6
  import { EmptyState as a } from "../components/EmptyState.js";
7
- import { useDevportal as o } from "../providers/DevportalProvider.js";
7
+ import { useDevportal as o, useIsFluidgridsVariant as s } from "../providers/DevportalProvider.js";
8
8
  import "../components/index.js";
9
- import { PermissionGuard as s } from "../components/PermissionGuard.js";
10
- import { cn as c } from "../utils/cn.js";
9
+ import { PermissionGuard as c } from "../components/PermissionGuard.js";
10
+ import { cn as l } from "../utils/cn.js";
11
11
  import "../hooks/index.js";
12
- import { useState as l } from "react";
13
- import { AlertCircle as u, Loader2 as d, Plus as f, Search as p, Shield as m } from "lucide-react";
14
- import { jsx as h, jsxs as g } from "react/jsx-runtime";
15
- import { useI18n as _ } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
+ import { useState as u } from "react";
13
+ import { AlertCircle as d, Loader2 as f, Plus as p, Search as m, Shield as h } from "lucide-react";
14
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
16
15
  import { EmphasisPanel as v, GlassCard as y } from "@burdenoff/fe-libs/ui";
16
+ import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
17
  // src/devportal/pages/OAuthClientsPage.tsx
18
- var b = () => {
19
- let { navigate: b, basePath: x } = o(), { t: S } = _(), C = (e, t) => {
20
- let n = S(e);
18
+ var x = () => {
19
+ let { navigate: x, basePath: S } = o(), C = s(), { t: w } = b(), T = (e, t) => {
20
+ let n = w(e);
21
21
  return n === e ? t : n;
22
- }, [w, T] = l(""), [E, D] = l(""), { data: O, loading: k, error: A, refetch: j } = r({ fetchPolicy: "cache-and-network" }), M = O?.currentUserApps?.apps.map((e) => ({
22
+ }, E = C ? T("devportal.oauthApps.v2Title", "OAuth apps") : T("devportal.oauthApps", "OAuth Apps"), D = C ? T("devportal.oauthApps.v2Create", "Create OAuth app") : T("devportal.createOAuthApp", "Create OAuth App"), [O, k] = u(""), [A, j] = u(""), { data: M, loading: N, error: P, refetch: F } = r({ fetchPolicy: "cache-and-network" }), I = M?.currentUserApps?.apps.map((e) => ({
23
23
  id: e.id,
24
24
  name: e.name,
25
25
  description: e.description ?? void 0,
@@ -32,65 +32,65 @@ var b = () => {
32
32
  tenantId: e.tenantId ?? "",
33
33
  createdAt: e.createdAt,
34
34
  updatedAt: e.updatedAt
35
- })) ?? [], N = (e) => {
36
- b?.(`${x}${e}`);
37
- }, P = M.filter((e) => {
38
- let t = !w || e.name.toLowerCase().includes(w.toLowerCase()) || e.clientId.toLowerCase().includes(w.toLowerCase()), n = !E || e.type === E;
35
+ })) ?? [], L = (e) => {
36
+ x?.(`${S}${e}`);
37
+ }, R = I.filter((e) => {
38
+ let t = !O || e.name.toLowerCase().includes(O.toLowerCase()) || e.clientId.toLowerCase().includes(O.toLowerCase()), n = !A || e.type === A;
39
39
  return t && n;
40
40
  });
41
- if (k && !O) return /* @__PURE__ */ h(e, {
42
- title: C("devportal.oauthApps", "OAuth Apps"),
43
- description: C("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
44
- children: /* @__PURE__ */ g("div", {
41
+ if (N && !M) return /* @__PURE__ */ g(e, {
42
+ title: E,
43
+ description: T("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
44
+ children: /* @__PURE__ */ _("div", {
45
45
  className: "flex items-center justify-center py-12",
46
- children: [/* @__PURE__ */ h(d, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ h("span", {
46
+ children: [/* @__PURE__ */ g(f, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ g("span", {
47
47
  className: "ml-2 text-text-secondary",
48
- children: C("devportal.loadingApps", "Loading apps...")
48
+ children: T("devportal.loadingApps", "Loading apps...")
49
49
  })]
50
50
  })
51
51
  });
52
- if (A) return /* @__PURE__ */ h(e, {
53
- title: C("devportal.oauthApps", "OAuth Apps"),
54
- description: C("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
55
- children: /* @__PURE__ */ g("div", {
52
+ if (P) return /* @__PURE__ */ g(e, {
53
+ title: E,
54
+ description: T("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
55
+ children: /* @__PURE__ */ _("div", {
56
56
  className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
57
57
  children: [
58
- /* @__PURE__ */ h(u, { className: "mx-auto h-8 w-8 text-status-error-text" }),
59
- /* @__PURE__ */ h("h3", {
58
+ /* @__PURE__ */ g(d, { className: "mx-auto h-8 w-8 text-status-error-text" }),
59
+ /* @__PURE__ */ g("h3", {
60
60
  className: "mt-2 font-medium text-status-error-text",
61
- children: C("devportal.failedToLoadApps", "Failed to load apps")
61
+ children: T("devportal.failedToLoadApps", "Failed to load apps")
62
62
  }),
63
- /* @__PURE__ */ h("p", {
63
+ /* @__PURE__ */ g("p", {
64
64
  className: "mt-1 text-sm text-text-secondary",
65
- children: i(A)
65
+ children: i(P)
66
66
  }),
67
- /* @__PURE__ */ h("button", {
68
- onClick: () => j(),
67
+ /* @__PURE__ */ g("button", {
68
+ onClick: () => F(),
69
69
  className: "mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
70
- children: C("devportal.tryAgain", "Try Again")
70
+ children: T("devportal.tryAgain", "Try Again")
71
71
  })
72
72
  ]
73
73
  })
74
74
  });
75
- let F = [
75
+ let z = [
76
76
  {
77
77
  key: "name",
78
78
  header: "App",
79
- render: (e) => /* @__PURE__ */ g("div", {
79
+ render: (e) => /* @__PURE__ */ _("div", {
80
80
  className: "flex items-center gap-3",
81
- children: [/* @__PURE__ */ h("div", {
82
- className: c("flex h-10 w-10 items-center justify-center rounded-lg", e.status === "ACTIVE" ? "bg-action-primary-bg/10 text-primary" : "bg-bg-sunken text-text-tertiary"),
83
- children: /* @__PURE__ */ h(m, { size: 20 })
84
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ g("div", {
81
+ children: [/* @__PURE__ */ g("div", {
82
+ className: l("flex h-10 w-10 items-center justify-center rounded-lg", e.status === "ACTIVE" ? "bg-action-primary-bg/10 text-primary" : "bg-bg-sunken text-text-tertiary"),
83
+ children: /* @__PURE__ */ g(h, { size: 20 })
84
+ }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("div", {
85
85
  className: "flex items-center gap-2",
86
- children: [/* @__PURE__ */ h("p", {
86
+ children: [/* @__PURE__ */ g("p", {
87
87
  className: "font-medium",
88
88
  children: e.name
89
- }), /* @__PURE__ */ h("span", {
90
- className: c("rounded px-1.5 py-0.5 text-xs", e.type === "SERVICE" ? "bg-accent-purple-subtle text-accent-purple" : e.type === "INTEGRATION" || e.type === "API_INTEGRATION" ? "bg-status-info-bg-subtle text-status-info-text" : "bg-status-success-bg-subtle text-status-success-text"),
89
+ }), /* @__PURE__ */ g("span", {
90
+ className: l("rounded px-1.5 py-0.5 text-xs", e.type === "SERVICE" ? "bg-accent-purple-subtle text-accent-purple" : e.type === "INTEGRATION" || e.type === "API_INTEGRATION" ? "bg-status-info-bg-subtle text-status-info-text" : "bg-status-success-bg-subtle text-status-success-text"),
91
91
  children: e.type
92
92
  })]
93
- }), /* @__PURE__ */ h("code", {
93
+ }), /* @__PURE__ */ g("code", {
94
94
  className: "text-xs text-text-secondary",
95
95
  children: e.clientId
96
96
  })] })]
@@ -99,12 +99,12 @@ var b = () => {
99
99
  {
100
100
  key: "scopes",
101
101
  header: "Scopes",
102
- render: (e) => /* @__PURE__ */ g("div", {
102
+ render: (e) => /* @__PURE__ */ _("div", {
103
103
  className: "flex flex-wrap gap-1",
104
- children: [e.scopes.slice(0, 3).map((e) => /* @__PURE__ */ h("span", {
104
+ children: [e.scopes.slice(0, 3).map((e) => /* @__PURE__ */ g("span", {
105
105
  className: "inline-flex rounded bg-bg-sunken px-1.5 py-0.5 text-xs",
106
106
  children: e
107
- }, e)), e.scopes.length > 3 && /* @__PURE__ */ g("span", {
107
+ }, e)), e.scopes.length > 3 && /* @__PURE__ */ _("span", {
108
108
  className: "text-xs text-text-secondary",
109
109
  children: ["+", e.scopes.length - 3]
110
110
  })]
@@ -113,7 +113,7 @@ var b = () => {
113
113
  {
114
114
  key: "redirectUris",
115
115
  header: "Redirect URIs",
116
- render: (e) => /* @__PURE__ */ g("span", {
116
+ render: (e) => /* @__PURE__ */ _("span", {
117
117
  className: "text-sm",
118
118
  children: [
119
119
  e.redirectUris.length,
@@ -125,169 +125,171 @@ var b = () => {
125
125
  {
126
126
  key: "status",
127
127
  header: "Status",
128
- render: (e) => /* @__PURE__ */ g("div", {
128
+ render: (e) => /* @__PURE__ */ _("div", {
129
129
  className: "flex items-center gap-2",
130
- children: [/* @__PURE__ */ h(n, { active: e.status === "ACTIVE" }), /* @__PURE__ */ h("span", {
130
+ children: [/* @__PURE__ */ g(n, { active: e.status === "ACTIVE" }), /* @__PURE__ */ g("span", {
131
131
  className: "text-sm",
132
132
  children: e.status
133
133
  })]
134
134
  })
135
135
  }
136
- ], I = {
137
- total: M.length,
138
- active: M.filter((e) => e.status === "ACTIVE").length,
139
- integration: M.filter((e) => e.type === "INTEGRATION" || e.type === "API_INTEGRATION").length,
140
- service: M.filter((e) => e.type === "SERVICE").length
136
+ ], B = {
137
+ total: I.length,
138
+ active: I.filter((e) => e.status === "ACTIVE").length,
139
+ integration: I.filter((e) => e.type === "INTEGRATION" || e.type === "API_INTEGRATION").length,
140
+ service: I.filter((e) => e.type === "SERVICE").length
141
141
  };
142
- return /* @__PURE__ */ h(s, {
142
+ return /* @__PURE__ */ g(c, {
143
143
  authOnly: !0,
144
- children: /* @__PURE__ */ g(e, {
145
- title: C("devportal.oauthApps", "OAuth Apps"),
146
- description: C("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
147
- purpose: C("devportal.oauthAppsPurpose", "OAuth apps let external services sign in users and call the API on their behalf. Register one here to get a client ID and secret, set redirect URIs, and choose the scopes your integration may request."),
148
- actions: /* @__PURE__ */ g("button", {
149
- onClick: () => N("/oauth/new"),
144
+ children: /* @__PURE__ */ _(e, {
145
+ title: E,
146
+ description: T("devportal.manageOAuthApps", "Manage your OAuth applications and credentials"),
147
+ backLink: C ? "/settings" : void 0,
148
+ backLabel: T("devportal.developerSettings.back", "Developer settings"),
149
+ purpose: T("devportal.oauthAppsPurpose", "OAuth apps let external services sign in users and call the API on their behalf. Register one here to get a client ID and secret, set redirect URIs, and choose the scopes your integration may request."),
150
+ actions: /* @__PURE__ */ _("button", {
151
+ onClick: () => L("/oauth/new"),
150
152
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
151
- children: [/* @__PURE__ */ h(f, { size: 16 }), C("devportal.createOAuthApp", "Create OAuth App")]
153
+ children: [/* @__PURE__ */ g(p, { size: 16 }), D]
152
154
  }),
153
155
  children: [
154
- /* @__PURE__ */ h("div", {
156
+ /* @__PURE__ */ g("div", {
155
157
  className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
156
- children: /* @__PURE__ */ g("div", {
158
+ children: /* @__PURE__ */ _("div", {
157
159
  className: "flex flex-1 items-center gap-4",
158
- children: [/* @__PURE__ */ g("div", {
160
+ children: [/* @__PURE__ */ _("div", {
159
161
  className: "relative flex-1 max-w-md",
160
- children: [/* @__PURE__ */ h(p, {
162
+ children: [/* @__PURE__ */ g(m, {
161
163
  size: 16,
162
164
  className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary"
163
- }), /* @__PURE__ */ h("input", {
165
+ }), /* @__PURE__ */ g("input", {
164
166
  type: "text",
165
- placeholder: C("devportal.searchByNameOrClientId", "Search by name or client ID..."),
166
- value: w,
167
- onChange: (e) => T(e.target.value),
167
+ placeholder: T("devportal.searchByNameOrClientId", "Search by name or client ID..."),
168
+ value: O,
169
+ onChange: (e) => k(e.target.value),
168
170
  className: "w-full rounded-md border bg-bg-surface pl-9 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary"
169
171
  })]
170
- }), /* @__PURE__ */ g("select", {
171
- value: E,
172
- onChange: (e) => D(e.target.value),
172
+ }), /* @__PURE__ */ _("select", {
173
+ value: A,
174
+ onChange: (e) => j(e.target.value),
173
175
  className: "rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary",
174
176
  children: [
175
- /* @__PURE__ */ h("option", {
177
+ /* @__PURE__ */ g("option", {
176
178
  value: "",
177
- children: C("devportal.allTypes", "All Types")
179
+ children: T("devportal.allTypes", "All Types")
178
180
  }),
179
- /* @__PURE__ */ h("option", {
181
+ /* @__PURE__ */ g("option", {
180
182
  value: "SERVICE",
181
- children: C("devportal.service", "Service")
183
+ children: T("devportal.service", "Service")
182
184
  }),
183
- /* @__PURE__ */ h("option", {
185
+ /* @__PURE__ */ g("option", {
184
186
  value: "INTEGRATION",
185
- children: C("devportal.integration", "Integration")
187
+ children: T("devportal.integration", "Integration")
186
188
  }),
187
- /* @__PURE__ */ h("option", {
189
+ /* @__PURE__ */ g("option", {
188
190
  value: "BOT",
189
- children: C("devportal.bot", "Bot")
191
+ children: T("devportal.bot", "Bot")
190
192
  }),
191
- /* @__PURE__ */ h("option", {
193
+ /* @__PURE__ */ g("option", {
192
194
  value: "WEB_APP",
193
- children: C("devportal.webApp", "Web App")
195
+ children: T("devportal.webApp", "Web App")
194
196
  }),
195
- /* @__PURE__ */ h("option", {
197
+ /* @__PURE__ */ g("option", {
196
198
  value: "AUTOMATION",
197
- children: C("devportal.automation", "Automation")
199
+ children: T("devportal.automation", "Automation")
198
200
  })
199
201
  ]
200
202
  })]
201
203
  })
202
204
  }),
203
- /* @__PURE__ */ h(v, { children: /* @__PURE__ */ g("div", {
205
+ /* @__PURE__ */ g(v, { children: /* @__PURE__ */ _("div", {
204
206
  className: "grid grid-cols-2 gap-4 sm:grid-cols-4",
205
207
  children: [
206
- /* @__PURE__ */ g(y, {
208
+ /* @__PURE__ */ _(y, {
207
209
  treatment: "metric",
208
210
  className: "p-4",
209
- children: [/* @__PURE__ */ g("div", {
211
+ children: [/* @__PURE__ */ _("div", {
210
212
  className: "flex items-center gap-2 text-text-secondary",
211
- children: [/* @__PURE__ */ h(m, { size: 16 }), /* @__PURE__ */ h("span", {
213
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
212
214
  className: "text-sm",
213
- children: C("devportal.totalApps", "Total Apps")
215
+ children: T("devportal.totalApps", "Total Apps")
214
216
  })]
215
- }), /* @__PURE__ */ h("p", {
217
+ }), /* @__PURE__ */ g("p", {
216
218
  className: "mt-1 text-2xl font-semibold tabular-nums",
217
- children: I.total
219
+ children: B.total
218
220
  })]
219
221
  }),
220
- /* @__PURE__ */ g(y, {
222
+ /* @__PURE__ */ _(y, {
221
223
  treatment: "metric",
222
224
  className: "p-4",
223
- children: [/* @__PURE__ */ g("div", {
225
+ children: [/* @__PURE__ */ _("div", {
224
226
  className: "flex items-center gap-2 text-status-success-text",
225
- children: [/* @__PURE__ */ h(m, { size: 16 }), /* @__PURE__ */ h("span", {
227
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
226
228
  className: "text-sm",
227
- children: C("devportal.active", "Active")
229
+ children: T("devportal.active", "Active")
228
230
  })]
229
- }), /* @__PURE__ */ h("p", {
231
+ }), /* @__PURE__ */ g("p", {
230
232
  className: "mt-1 text-2xl font-semibold tabular-nums",
231
- children: I.active
233
+ children: B.active
232
234
  })]
233
235
  }),
234
- /* @__PURE__ */ g(y, {
236
+ /* @__PURE__ */ _(y, {
235
237
  treatment: "metric",
236
238
  className: "p-4",
237
- children: [/* @__PURE__ */ g("div", {
239
+ children: [/* @__PURE__ */ _("div", {
238
240
  className: "flex items-center gap-2 text-accent-blue",
239
- children: [/* @__PURE__ */ h(m, { size: 16 }), /* @__PURE__ */ h("span", {
241
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
240
242
  className: "text-sm",
241
- children: C("devportal.integration", "Integration")
243
+ children: T("devportal.integration", "Integration")
242
244
  })]
243
- }), /* @__PURE__ */ h("p", {
245
+ }), /* @__PURE__ */ g("p", {
244
246
  className: "mt-1 text-2xl font-semibold tabular-nums",
245
- children: I.integration
247
+ children: B.integration
246
248
  })]
247
249
  }),
248
- /* @__PURE__ */ g(y, {
250
+ /* @__PURE__ */ _(y, {
249
251
  treatment: "metric",
250
252
  className: "p-4",
251
- children: [/* @__PURE__ */ g("div", {
253
+ children: [/* @__PURE__ */ _("div", {
252
254
  className: "flex items-center gap-2 text-accent-purple",
253
- children: [/* @__PURE__ */ h(m, { size: 16 }), /* @__PURE__ */ h("span", {
255
+ children: [/* @__PURE__ */ g(h, { size: 16 }), /* @__PURE__ */ g("span", {
254
256
  className: "text-sm",
255
- children: C("devportal.service", "Service")
257
+ children: T("devportal.service", "Service")
256
258
  })]
257
- }), /* @__PURE__ */ h("p", {
259
+ }), /* @__PURE__ */ g("p", {
258
260
  className: "mt-1 text-2xl font-semibold tabular-nums",
259
- children: I.service
261
+ children: B.service
260
262
  })]
261
263
  })
262
264
  ]
263
265
  }) }),
264
- /* @__PURE__ */ g("p", {
266
+ /* @__PURE__ */ _("p", {
265
267
  className: "text-sm text-text-secondary",
266
268
  children: [
267
- P.length,
269
+ R.length,
268
270
  " ",
269
- P.length === 1 ? C("devportal.appFound", "app found") : C("devportal.appsFound", "apps found")
271
+ R.length === 1 ? T("devportal.appFound", "app found") : T("devportal.appsFound", "apps found")
270
272
  ]
271
273
  }),
272
- P.length > 0 ? /* @__PURE__ */ h(t, {
273
- data: P,
274
- columns: F,
274
+ R.length > 0 ? /* @__PURE__ */ g(t, {
275
+ data: R,
276
+ columns: z,
275
277
  keyField: "id",
276
- onRowClick: (e) => N(`/oauth/${e.id}`)
277
- }) : /* @__PURE__ */ h(a, {
278
+ onRowClick: (e) => L(`/oauth/${e.id}`)
279
+ }) : /* @__PURE__ */ g(a, {
278
280
  illustration: "empty-generic",
279
- title: C("devportal.noOAuthAppsFound", "No OAuth apps found"),
280
- description: w || E ? C("devportal.tryAdjustingFilters", "Try adjusting your filters") : C("devportal.createFirstOAuthApp", "Create your first OAuth app to enable authentication"),
281
- action: !w && !E ? /* @__PURE__ */ g("button", {
282
- onClick: () => N("/oauth/new"),
281
+ title: T("devportal.noOAuthAppsFound", "No OAuth apps found"),
282
+ description: O || A ? T("devportal.tryAdjustingFilters", "Try adjusting your filters") : T("devportal.createFirstOAuthApp", "Create your first OAuth app to enable authentication"),
283
+ action: !O && !A ? /* @__PURE__ */ _("button", {
284
+ onClick: () => L("/oauth/new"),
283
285
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
284
- children: [/* @__PURE__ */ h(f, { size: 16 }), C("devportal.createOAuthApp", "Create OAuth App")]
286
+ children: [/* @__PURE__ */ g(p, { size: 16 }), D]
285
287
  }) : void 0
286
288
  })
287
289
  ]
288
290
  })
289
291
  });
290
292
  };
291
- export { b as OAuthClientsPage };
293
+ export { x as OAuthClientsPage };
292
294
 
293
295
  //# sourceMappingURL=OAuthClientsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OAuthClientsPage.js","names":["EmptyState","EmptyState$1","OAuthClientsPage","useDevportal","useI18n","tr","value","t","key","fallback","searchQuery","setSearchQuery","useState","typeFilter","setTypeFilter","useCurrentUserAppsQuery","apps","data","app","handleNavigate","basePath","path","filteredApps","matchesSearch","matchesType","loading","PageLayout","Loader2","error","AlertCircle","getErrorMessage","refetch","columns","cn","Shield","scope","ActiveIndicator","stats","a","PermissionGuard","Plus","Search","EmphasisPanel","GlassCard","DataTable"],"sources":["../../../src/devportal/pages/OAuthClientsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { Plus, Search, Shield, Loader2, AlertCircle } from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { useCurrentUserAppsQuery, getErrorMessage } from \"../hooks\";\n\n/**\n * OAuth Apps listing page\n *\n * Displays the current user's OAuth apps from auth-svc.\n * Previously showed devportal-svc OAuthClients per application;\n * now shows all user-owned apps centrally.\n */\nexport const OAuthClientsPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [typeFilter, setTypeFilter] = useState<string>(\"\");\n\n // Fetch apps from auth-svc (user-scoped, no applicationId needed)\n const { data, loading, error, refetch } = useCurrentUserAppsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const apps: AuthApp[] =\n data?.currentUserApps?.apps.map(\n (app: (typeof data.currentUserApps.apps)[number]) => ({\n id: app.id,\n name: app.name,\n description: app.description ?? undefined,\n clientId: app.clientId,\n type: app.type as AuthApp[\"type\"],\n status: app.status as AuthApp[\"status\"],\n scopes: app.scopes ?? [],\n redirectUris: app.redirectUris ?? [],\n ownerUserId: app.ownerUserId,\n tenantId: app.tenantId ?? \"\",\n createdAt: app.createdAt,\n updatedAt: app.updatedAt,\n }),\n ) ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n const matchesSearch =\n !searchQuery ||\n app.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n app.clientId.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesType = !typeFilter || app.type === typeFilter;\n return matchesSearch && matchesType;\n });\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingApps\", \"Loading apps...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\"devportal.failedToLoadApps\", \"Failed to load apps\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const columns = [\n {\n key: \"name\",\n header: \"App\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-10 w-10 items-center justify-center rounded-lg\",\n app.status === \"ACTIVE\"\n ? \"bg-action-primary-bg/10 text-primary\"\n : \"bg-bg-sunken text-text-tertiary\",\n )}\n >\n <Shield size={20} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium\">{app.name}</p>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-xs\",\n app.type === \"SERVICE\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : app.type === \"INTEGRATION\" ||\n app.type === \"API_INTEGRATION\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : \"bg-status-success-bg-subtle text-status-success-text\",\n )}\n >\n {app.type}\n </span>\n </div>\n <code className=\"text-xs text-text-secondary\">{app.clientId}</code>\n </div>\n </div>\n ),\n },\n {\n key: \"scopes\",\n header: \"Scopes\",\n render: (app: AuthApp) => (\n <div className=\"flex flex-wrap gap-1\">\n {app.scopes.slice(0, 3).map((scope) => (\n <span\n key={scope}\n className=\"inline-flex rounded bg-bg-sunken px-1.5 py-0.5 text-xs\"\n >\n {scope}\n </span>\n ))}\n {app.scopes.length > 3 && (\n <span className=\"text-xs text-text-secondary\">\n +{app.scopes.length - 3}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"redirectUris\",\n header: \"Redirect URIs\",\n render: (app: AuthApp) => (\n <span className=\"text-sm\">\n {app.redirectUris.length} URI\n {app.redirectUris.length !== 1 ? \"s\" : \"\"}\n </span>\n ),\n },\n {\n key: \"status\",\n header: \"Status\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm\">{app.status}</span>\n </div>\n ),\n },\n ];\n\n // Stats\n const stats = {\n total: apps.length,\n active: apps.filter((a) => a.status === \"ACTIVE\").length,\n integration: apps.filter(\n (a) => a.type === \"INTEGRATION\" || a.type === \"API_INTEGRATION\",\n ).length,\n service: apps.filter((a) => a.type === \"SERVICE\").length,\n };\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.oauthApps\", \"OAuth Apps\")}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n purpose={tr(\n \"devportal.oauthAppsPurpose\",\n \"OAuth apps let external services sign in users and call the API on their behalf. Register one here to get a client ID and secret, set redirect URIs, and choose the scopes your integration may request.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n }\n >\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-1 items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n />\n <input\n type=\"text\"\n placeholder={tr(\n \"devportal.searchByNameOrClientId\",\n \"Search by name or client ID...\",\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-md border bg-bg-surface pl-9 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </div>\n <select\n value={typeFilter}\n onChange={(e) => setTypeFilter(e.target.value)}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">{tr(\"devportal.allTypes\", \"All Types\")}</option>\n <option value=\"SERVICE\">\n {tr(\"devportal.service\", \"Service\")}\n </option>\n <option value=\"INTEGRATION\">\n {tr(\"devportal.integration\", \"Integration\")}\n </option>\n <option value=\"BOT\">{tr(\"devportal.bot\", \"Bot\")}</option>\n <option value=\"WEB_APP\">\n {tr(\"devportal.webApp\", \"Web App\")}\n </option>\n <option value=\"AUTOMATION\">\n {tr(\"devportal.automation\", \"Automation\")}\n </option>\n </select>\n </div>\n </div>\n\n {/* Summary Stats — primary emphasis zone */}\n <EmphasisPanel>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-text-secondary\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.total}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-status-success-text\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.active\", \"Active\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.active}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-blue\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.integration\", \"Integration\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.integration}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-purple\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.service\", \"Service\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.service}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n\n <p className=\"text-sm text-text-secondary\">\n {filteredApps.length}{\" \"}\n {filteredApps.length !== 1\n ? tr(\"devportal.appsFound\", \"apps found\")\n : tr(\"devportal.appFound\", \"app found\")}\n </p>\n\n {/* Apps Table */}\n {filteredApps.length > 0 ? (\n <DataTable\n data={filteredApps}\n columns={columns}\n keyField=\"id\"\n onRowClick={(app) => handleNavigate(`/oauth/${app.id}`)}\n />\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={tr(\"devportal.noOAuthAppsFound\", \"No OAuth apps found\")}\n description={\n searchQuery || typeFilter\n ? tr(\n \"devportal.tryAdjustingFilters\",\n \"Try adjusting your filters\",\n )\n : tr(\n \"devportal.createFirstOAuthApp\",\n \"Create your first OAuth app to enable authentication\",\n )\n }\n action={\n !searchQuery && !typeFilter ? (\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOAuthApp\", \"Create OAuth App\")}\n </button>\n ) : undefined\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OAuthClientsPage.js","names":["EmptyState","EmptyState$1","OAuthClientsPage","useDevportal","isFluidgrids","useIsFluidgridsVariant","useI18n","tr","value","t","key","fallback","oauthTitle","createLabel","searchQuery","setSearchQuery","useState","typeFilter","setTypeFilter","useCurrentUserAppsQuery","apps","data","app","handleNavigate","basePath","path","filteredApps","matchesSearch","matchesType","loading","PageLayout","Loader2","error","AlertCircle","getErrorMessage","refetch","columns","cn","Shield","scope","ActiveIndicator","stats","a","PermissionGuard","Plus","Search","EmphasisPanel","GlassCard","DataTable"],"sources":["../../../src/devportal/pages/OAuthClientsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { Plus, Search, Shield, Loader2, AlertCircle } from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport {\n useDevportal,\n useIsFluidgridsVariant,\n} from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { useCurrentUserAppsQuery, getErrorMessage } from \"../hooks\";\n\n/**\n * OAuth Apps listing page\n *\n * Displays the current user's OAuth apps from auth-svc.\n * Previously showed devportal-svc OAuthClients per application;\n * now shows all user-owned apps centrally.\n */\nexport const OAuthClientsPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const isFluidgrids = useIsFluidgridsVariant();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const oauthTitle = isFluidgrids\n ? tr(\"devportal.oauthApps.v2Title\", \"OAuth apps\")\n : tr(\"devportal.oauthApps\", \"OAuth Apps\");\n const createLabel = isFluidgrids\n ? tr(\"devportal.oauthApps.v2Create\", \"Create OAuth app\")\n : tr(\"devportal.createOAuthApp\", \"Create OAuth App\");\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [typeFilter, setTypeFilter] = useState<string>(\"\");\n\n // Fetch apps from auth-svc (user-scoped, no applicationId needed)\n const { data, loading, error, refetch } = useCurrentUserAppsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const apps: AuthApp[] =\n data?.currentUserApps?.apps.map(\n (app: (typeof data.currentUserApps.apps)[number]) => ({\n id: app.id,\n name: app.name,\n description: app.description ?? undefined,\n clientId: app.clientId,\n type: app.type as AuthApp[\"type\"],\n status: app.status as AuthApp[\"status\"],\n scopes: app.scopes ?? [],\n redirectUris: app.redirectUris ?? [],\n ownerUserId: app.ownerUserId,\n tenantId: app.tenantId ?? \"\",\n createdAt: app.createdAt,\n updatedAt: app.updatedAt,\n }),\n ) ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n const matchesSearch =\n !searchQuery ||\n app.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n app.clientId.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesType = !typeFilter || app.type === typeFilter;\n return matchesSearch && matchesType;\n });\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={oauthTitle}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingApps\", \"Loading apps...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={oauthTitle}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\"devportal.failedToLoadApps\", \"Failed to load apps\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const columns = [\n {\n key: \"name\",\n header: \"App\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-3\">\n <div\n className={cn(\n \"flex h-10 w-10 items-center justify-center rounded-lg\",\n app.status === \"ACTIVE\"\n ? \"bg-action-primary-bg/10 text-primary\"\n : \"bg-bg-sunken text-text-tertiary\",\n )}\n >\n <Shield size={20} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium\">{app.name}</p>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-xs\",\n app.type === \"SERVICE\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : app.type === \"INTEGRATION\" ||\n app.type === \"API_INTEGRATION\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : \"bg-status-success-bg-subtle text-status-success-text\",\n )}\n >\n {app.type}\n </span>\n </div>\n <code className=\"text-xs text-text-secondary\">{app.clientId}</code>\n </div>\n </div>\n ),\n },\n {\n key: \"scopes\",\n header: \"Scopes\",\n render: (app: AuthApp) => (\n <div className=\"flex flex-wrap gap-1\">\n {app.scopes.slice(0, 3).map((scope) => (\n <span\n key={scope}\n className=\"inline-flex rounded bg-bg-sunken px-1.5 py-0.5 text-xs\"\n >\n {scope}\n </span>\n ))}\n {app.scopes.length > 3 && (\n <span className=\"text-xs text-text-secondary\">\n +{app.scopes.length - 3}\n </span>\n )}\n </div>\n ),\n },\n {\n key: \"redirectUris\",\n header: \"Redirect URIs\",\n render: (app: AuthApp) => (\n <span className=\"text-sm\">\n {app.redirectUris.length} URI\n {app.redirectUris.length !== 1 ? \"s\" : \"\"}\n </span>\n ),\n },\n {\n key: \"status\",\n header: \"Status\",\n render: (app: AuthApp) => (\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm\">{app.status}</span>\n </div>\n ),\n },\n ];\n\n // Stats\n const stats = {\n total: apps.length,\n active: apps.filter((a) => a.status === \"ACTIVE\").length,\n integration: apps.filter(\n (a) => a.type === \"INTEGRATION\" || a.type === \"API_INTEGRATION\",\n ).length,\n service: apps.filter((a) => a.type === \"SERVICE\").length,\n };\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={oauthTitle}\n description={tr(\n \"devportal.manageOAuthApps\",\n \"Manage your OAuth applications and credentials\",\n )}\n backLink={isFluidgrids ? \"/settings\" : undefined}\n backLabel={tr(\"devportal.developerSettings.back\", \"Developer settings\")}\n purpose={tr(\n \"devportal.oauthAppsPurpose\",\n \"OAuth apps let external services sign in users and call the API on their behalf. Register one here to get a client ID and secret, set redirect URIs, and choose the scopes your integration may request.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {createLabel}\n </button>\n }\n >\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-1 items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n />\n <input\n type=\"text\"\n placeholder={tr(\n \"devportal.searchByNameOrClientId\",\n \"Search by name or client ID...\",\n )}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-md border bg-bg-surface pl-9 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </div>\n <select\n value={typeFilter}\n onChange={(e) => setTypeFilter(e.target.value)}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n <option value=\"\">{tr(\"devportal.allTypes\", \"All Types\")}</option>\n <option value=\"SERVICE\">\n {tr(\"devportal.service\", \"Service\")}\n </option>\n <option value=\"INTEGRATION\">\n {tr(\"devportal.integration\", \"Integration\")}\n </option>\n <option value=\"BOT\">{tr(\"devportal.bot\", \"Bot\")}</option>\n <option value=\"WEB_APP\">\n {tr(\"devportal.webApp\", \"Web App\")}\n </option>\n <option value=\"AUTOMATION\">\n {tr(\"devportal.automation\", \"Automation\")}\n </option>\n </select>\n </div>\n </div>\n\n {/* Summary Stats — primary emphasis zone */}\n <EmphasisPanel>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-text-secondary\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.total}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-status-success-text\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.active\", \"Active\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.active}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-blue\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.integration\", \"Integration\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.integration}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-accent-purple\">\n <Shield size={16} />\n <span className=\"text-sm\">\n {tr(\"devportal.service\", \"Service\")}\n </span>\n </div>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {stats.service}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n\n <p className=\"text-sm text-text-secondary\">\n {filteredApps.length}{\" \"}\n {filteredApps.length !== 1\n ? tr(\"devportal.appsFound\", \"apps found\")\n : tr(\"devportal.appFound\", \"app found\")}\n </p>\n\n {/* Apps Table */}\n {filteredApps.length > 0 ? (\n <DataTable\n data={filteredApps}\n columns={columns}\n keyField=\"id\"\n onRowClick={(app) => handleNavigate(`/oauth/${app.id}`)}\n />\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={tr(\"devportal.noOAuthAppsFound\", \"No OAuth apps found\")}\n description={\n searchQuery || typeFilter\n ? tr(\n \"devportal.tryAdjustingFilters\",\n \"Try adjusting your filters\",\n )\n : tr(\n \"devportal.createFirstOAuthApp\",\n \"Create your first OAuth app to enable authentication\",\n )\n }\n action={\n !searchQuery && !typeFilter ? (\n <button\n onClick={() => handleNavigate(\"/oauth/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {createLabel}\n </button>\n ) : undefined\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}