@burdenoff/microfe-devportal 2026.801.1 → 2026.801.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 (70) hide show
  1. package/dist/devportal/AdminDevportalRoutes.js +14 -14
  2. package/dist/devportal/DevportalRoutes.js +115 -115
  3. package/dist/devportal/DevportalRoutes.js.map +1 -1
  4. package/dist/devportal/components/SectionNav.js +1 -0
  5. package/dist/devportal/components/SectionNav.js.map +1 -1
  6. package/dist/devportal/components/TelemetryErrorBoundary.js +7 -7
  7. package/dist/devportal/pages/AnalyticsDashboardPage.js +41 -41
  8. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  9. package/dist/devportal/pages/AppLogsPage.js +27 -27
  10. package/dist/devportal/pages/ApplicationDetailPage.js +929 -929
  11. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  12. package/dist/devportal/pages/ApplicationVersionsPage.js +39 -39
  13. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  14. package/dist/devportal/pages/CreateWebhookPage.js +55 -55
  15. package/dist/devportal/pages/EditApplicationPage.js +36 -36
  16. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  17. package/dist/devportal/pages/EditPhysicalItemPage.js +40 -40
  18. package/dist/devportal/pages/InvitationDecisionPage.js +25 -25
  19. package/dist/devportal/pages/ListingPreviewPage.js +36 -36
  20. package/dist/devportal/pages/OAuthCallbackPage.js +10 -10
  21. package/dist/devportal/pages/OAuthClientDetailPage.js +27 -27
  22. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  23. package/dist/devportal/pages/OrganizationDetailPage.js +329 -329
  24. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  25. package/dist/devportal/pages/OrganizationMembersPage.js +181 -181
  26. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  27. package/dist/devportal/pages/PublishPage.js +43 -43
  28. package/dist/devportal/pages/PublishPage.js.map +1 -1
  29. package/dist/devportal/pages/RevenueDashboardPage.js +65 -65
  30. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  31. package/dist/devportal/pages/StoreSubmissionPage.js +126 -126
  32. package/dist/devportal/pages/StoreSubmissionPage.js.map +1 -1
  33. package/dist/devportal/pages/WebhookDetailPage.js +28 -28
  34. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  35. package/dist/devportal/pages/WebhooksPage.js +47 -47
  36. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  37. package/dist/devportal/providers/DevportalProvider.js +12 -12
  38. package/package.json +1 -1
  39. package/dist/node_modules/react-router/dist/production/lib/components.js +0 -124
  40. package/dist/node_modules/react-router/dist/production/lib/components.js.map +0 -1
  41. package/dist/node_modules/react-router/dist/production/lib/context.js +0 -32
  42. package/dist/node_modules/react-router/dist/production/lib/context.js.map +0 -1
  43. package/dist/node_modules/react-router/dist/production/lib/dom/dom.js +0 -83
  44. package/dist/node_modules/react-router/dist/production/lib/dom/dom.js.map +0 -1
  45. package/dist/node_modules/react-router/dist/production/lib/dom/lib.js +0 -358
  46. package/dist/node_modules/react-router/dist/production/lib/dom/lib.js.map +0 -1
  47. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/components.js +0 -188
  48. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/components.js.map +0 -1
  49. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/invariant.js +0 -8
  50. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/invariant.js.map +0 -1
  51. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/links.js +0 -75
  52. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/links.js.map +0 -1
  53. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/markup.js +0 -15
  54. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/markup.js.map +0 -1
  55. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/routeModules.js +0 -18
  56. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/routeModules.js.map +0 -1
  57. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/single-fetch.js +0 -10
  58. package/dist/node_modules/react-router/dist/production/lib/dom/ssr/single-fetch.js.map +0 -1
  59. package/dist/node_modules/react-router/dist/production/lib/errors.js +0 -19
  60. package/dist/node_modules/react-router/dist/production/lib/errors.js.map +0 -1
  61. package/dist/node_modules/react-router/dist/production/lib/hooks.js +0 -296
  62. package/dist/node_modules/react-router/dist/production/lib/hooks.js.map +0 -1
  63. package/dist/node_modules/react-router/dist/production/lib/router/history.js +0 -166
  64. package/dist/node_modules/react-router/dist/production/lib/router/history.js.map +0 -1
  65. package/dist/node_modules/react-router/dist/production/lib/router/router.js +0 -33
  66. package/dist/node_modules/react-router/dist/production/lib/router/router.js.map +0 -1
  67. package/dist/node_modules/react-router/dist/production/lib/router/url.js +0 -9
  68. package/dist/node_modules/react-router/dist/production/lib/router/url.js.map +0 -1
  69. package/dist/node_modules/react-router/dist/production/lib/router/utils.js +0 -236
  70. package/dist/node_modules/react-router/dist/production/lib/router/utils.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { useInRouterContext as e, useLocation as t } from "../../node_modules/react-router/dist/production/lib/hooks.js";
2
- import { useDevportalEventBus as n } from "../events/index.js";
3
- import { Component as r } from "react";
1
+ import { useDevportalEventBus as e } from "../events/index.js";
2
+ import { Component as t } from "react";
3
+ import { useInRouterContext as n, useLocation as r } from "react-router";
4
4
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
5
  //#region src/devportal/components/TelemetryErrorBoundary.tsx
6
- var o = class extends r {
6
+ var o = class extends t {
7
7
  state = { hasError: !1 };
8
8
  static getDerivedStateFromError(e) {
9
9
  return {
@@ -35,14 +35,14 @@ var o = class extends r {
35
35
  }
36
36
  };
37
37
  function s(e) {
38
- let n = t();
38
+ let t = r();
39
39
  return /* @__PURE__ */ i(o, {
40
40
  ...e,
41
- locationKey: n.pathname
41
+ locationKey: t.pathname
42
42
  });
43
43
  }
44
44
  function c({ children: t, fallback: r, scope: a }) {
45
- let c = n(), l = e(), u = (e, t, n) => {
45
+ let c = e(), l = n(), u = (e, t, n) => {
46
46
  c.emit("devportal.error.boundary", {
47
47
  scope: a ?? "unknown",
48
48
  message: e,
@@ -1,12 +1,11 @@
1
- import { useParams as e } from "../../node_modules/react-router/dist/production/lib/hooks.js";
2
- import { useDevportal as t } from "../providers/DevportalProvider.js";
3
- import { EmptyState as n } from "../components/EmptyState.js";
4
- import { useGetAnalyticsDashboardOptionsQuery as r, useGetApplicationAnalyticsDashboardQuery as i } from "../../generated/global-operations.js";
5
- import { getErrorMessage as a } from "../hooks/useGraphQL.js";
6
- import { PageLayout as o, PageSection as s } from "../components/PageLayout.js";
7
- import { AppListItem as ee } from "../components/AppCard.js";
8
- import { StatCard as c, StatCardGrid as te } from "../components/StatCard.js";
9
- import { DataTable as ne } from "../components/DataTable.js";
1
+ import { useDevportal as e } from "../providers/DevportalProvider.js";
2
+ import { EmptyState as t } from "../components/EmptyState.js";
3
+ import { useGetAnalyticsDashboardOptionsQuery as n, useGetApplicationAnalyticsDashboardQuery as r } from "../../generated/global-operations.js";
4
+ import { getErrorMessage as i } from "../hooks/useGraphQL.js";
5
+ import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
6
+ import { AppListItem as s } from "../components/AppCard.js";
7
+ import { StatCard as c, StatCardGrid as ee } from "../components/StatCard.js";
8
+ import { DataTable as te } from "../components/DataTable.js";
10
9
  import "../hooks/index.js";
11
10
  import { Tooltip as l } from "../../node_modules/recharts/es6/component/Tooltip.js";
12
11
  import { ResponsiveContainer as u } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
@@ -15,11 +14,12 @@ import { CartesianGrid as f } from "../../node_modules/recharts/es6/cartesian/Ca
15
14
  import { Line as p } from "../../node_modules/recharts/es6/cartesian/Line.js";
16
15
  import { XAxis as m } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
17
16
  import { YAxis as h } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
18
- import { LineChart as re } from "../../node_modules/recharts/es6/chart/LineChart.js";
19
- import { BarChart as ie } from "../../node_modules/recharts/es6/chart/BarChart.js";
20
- import { useTr as g } from "../utils/i18n.js";
21
- import { useEffect as _, useMemo as v, useState as y } from "react";
22
- import { Activity as ae, AlertCircle as b, AlertTriangle as oe, BarChart3 as x, Clock as se, Loader2 as S, Users as C } from "lucide-react";
17
+ import { LineChart as ne } from "../../node_modules/recharts/es6/chart/LineChart.js";
18
+ import { BarChart as re } from "../../node_modules/recharts/es6/chart/BarChart.js";
19
+ import { useTr as ie } from "../utils/i18n.js";
20
+ import { useEffect as g, useMemo as _, useState as v } from "react";
21
+ import { Activity as y, AlertCircle as b, AlertTriangle as ae, BarChart3 as x, Clock as oe, Loader2 as S, Users as se } from "lucide-react";
22
+ import { useParams as C } from "react-router";
23
23
  import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
24
24
  import { EmphasisPanel as D, GlassCard as O } from "@burdenoff/fe-libs/ui";
25
25
  //#region src/devportal/pages/AnalyticsDashboardPage.tsx
@@ -33,13 +33,13 @@ var ce = {
33
33
  tertiary: "var(--color-chart-4)",
34
34
  negative: "var(--color-chart-negative)"
35
35
  }, A = () => {
36
- let { appId: A } = e(), { navigate: j, basePath: le, activeOrgId: M } = t(), N = g(), [P, F] = y("30d"), [I, L] = y(A || ""), R = v(() => /* @__PURE__ */ new Date(), []), z = v(() => {
36
+ let { appId: A } = C(), { navigate: j, basePath: le, activeOrgId: M } = e(), N = ie(), [P, F] = v("30d"), [I, L] = v(A || ""), R = _(() => /* @__PURE__ */ new Date(), []), z = _(() => {
37
37
  let e = new Date(R);
38
38
  return e.setDate(e.getDate() - ce[P]), e.toISOString();
39
- }, [R, P]), { data: B, loading: V, error: H } = r({
39
+ }, [R, P]), { data: B, loading: V, error: H } = n({
40
40
  skip: !!A,
41
41
  fetchPolicy: "cache-and-network"
42
- }), { data: U, loading: ue, error: W } = i({
42
+ }), { data: U, loading: ue, error: W } = r({
43
43
  variables: {
44
44
  applicationId: I || A || "",
45
45
  period: "daily",
@@ -49,7 +49,7 @@ var ce = {
49
49
  skip: !(I || A),
50
50
  fetchPolicy: "cache-and-network"
51
51
  }), G = B?.applications?.edges?.map((e) => e.node) ?? [], K = M ? G.filter((e) => e.developerOrganizationId === M) : G, q = U?.application;
52
- _(() => {
52
+ g(() => {
53
53
  let e = q?.name, t = A || I;
54
54
  if (!t || !e) return;
55
55
  let n = window.__breadcrumbRegistry;
@@ -73,53 +73,53 @@ var ce = {
73
73
  })), Q = Y && Y.apiCalls > 0 ? Y.errors / Y.apiCalls * 100 : 0, de = X && X.apiCalls > 0 ? X.errors / X.apiCalls * 100 : 0, $ = Y?.avgResponseTime && X?.avgResponseTime ? X.avgResponseTime - Y.avgResponseTime : void 0, fe = (e) => {
74
74
  j?.(`${le}${e}`);
75
75
  };
76
- return !A && V && !B ? /* @__PURE__ */ T(o, {
76
+ return !A && V && !B ? /* @__PURE__ */ T(a, {
77
77
  title: N("devportal.analytics.title", "Analytics"),
78
78
  description: N("devportal.analytics.description", "Explore live application usage and performance metrics"),
79
79
  children: /* @__PURE__ */ T("div", {
80
80
  className: "flex items-center justify-center py-16 text-text-secondary",
81
81
  children: /* @__PURE__ */ T(S, { className: "h-8 w-8 animate-spin" })
82
82
  })
83
- }) : !A && H ? /* @__PURE__ */ T(o, {
83
+ }) : !A && H ? /* @__PURE__ */ T(a, {
84
84
  title: N("devportal.analytics.title", "Analytics"),
85
85
  description: N("devportal.analytics.description", "Explore live application usage and performance metrics"),
86
- children: /* @__PURE__ */ T(n, {
86
+ children: /* @__PURE__ */ T(t, {
87
87
  icon: /* @__PURE__ */ T(b, {
88
88
  size: 32,
89
89
  className: "text-status-error-text"
90
90
  }),
91
91
  title: N("devportal.analytics.errorLoadApps", "Unable to load applications"),
92
- description: a(H)
92
+ description: i(H)
93
93
  })
94
- }) : !A && !I ? /* @__PURE__ */ T(o, {
94
+ }) : !A && !I ? /* @__PURE__ */ T(a, {
95
95
  title: N("devportal.analytics.title", "Analytics"),
96
96
  description: N("devportal.analytics.selectAppDescription", "Select an application to review live usage metrics from the public gateway"),
97
97
  children: K.length > 0 ? /* @__PURE__ */ T("div", {
98
98
  className: "space-y-2",
99
- children: K.map((e) => /* @__PURE__ */ T(ee, {
99
+ children: K.map((e) => /* @__PURE__ */ T(s, {
100
100
  app: e,
101
101
  onClick: () => L(e.id)
102
102
  }, e.id))
103
- }) : /* @__PURE__ */ T(n, {
103
+ }) : /* @__PURE__ */ T(t, {
104
104
  illustration: "empty-data",
105
105
  icon: /* @__PURE__ */ T(x, { size: 32 }),
106
106
  title: N("devportal.analytics.noAppsTitle", "No applications available"),
107
107
  description: N("devportal.analytics.noAppsDescription", "Create an application before viewing analytics.")
108
108
  })
109
- }) : W ? /* @__PURE__ */ T(o, {
109
+ }) : W ? /* @__PURE__ */ T(a, {
110
110
  title: N("devportal.analytics.title", "Analytics"),
111
111
  description: N("devportal.analytics.description", "Explore live application usage and performance metrics"),
112
112
  backLink: I ? `/apps/${I}` : void 0,
113
113
  backLabel: N("devportal.analytics.backToApplication", "Back to Application"),
114
- children: /* @__PURE__ */ T(n, {
114
+ children: /* @__PURE__ */ T(t, {
115
115
  icon: /* @__PURE__ */ T(b, {
116
116
  size: 32,
117
117
  className: "text-status-error-text"
118
118
  }),
119
119
  title: N("devportal.analytics.errorLoadAnalytics", "Unable to load analytics"),
120
- description: a(W)
120
+ description: i(W)
121
121
  })
122
- }) : /* @__PURE__ */ T(o, {
122
+ }) : /* @__PURE__ */ T(a, {
123
123
  title: A ? N("devportal.analytics.appTitle", "Application Analytics") : N("devportal.analytics.title", "Analytics"),
124
124
  description: q ? `${N("devportal.analytics.liveUsageFor", "Live usage and performance for")} ${q.name}` : N("devportal.analytics.description", "Explore live application usage and performance metrics"),
125
125
  purpose: N("devportal.analytics.purpose", "Analytics shows how your apps are actually used — API call volume, active installs, latency, and error rates over time — so you can spot regressions, plan capacity, and prove value to your users. Pick an app and a time range to drill in."),
@@ -163,23 +163,23 @@ var ce = {
163
163
  }) : J.length > 0 ? /* @__PURE__ */ E(w, { children: [
164
164
  /* @__PURE__ */ T(D, {
165
165
  className: "mb-6",
166
- children: /* @__PURE__ */ E(te, {
166
+ children: /* @__PURE__ */ E(ee, {
167
167
  columns: 4,
168
168
  children: [
169
169
  /* @__PURE__ */ T(c, {
170
170
  title: N("devportal.analytics.apiCalls", "API Calls"),
171
171
  value: (Y?.apiCalls ?? 0).toLocaleString(),
172
- icon: /* @__PURE__ */ T(ae, { size: 20 })
172
+ icon: /* @__PURE__ */ T(y, { size: 20 })
173
173
  }),
174
174
  /* @__PURE__ */ T(c, {
175
175
  title: N("devportal.analytics.activeUsers", "Active Users"),
176
176
  value: (Y?.activeUsers ?? 0).toLocaleString(),
177
- icon: /* @__PURE__ */ T(C, { size: 20 })
177
+ icon: /* @__PURE__ */ T(se, { size: 20 })
178
178
  }),
179
179
  /* @__PURE__ */ T(c, {
180
180
  title: N("devportal.analytics.errorRate", "Error Rate"),
181
181
  value: `${Q.toFixed(2)}%`,
182
- icon: /* @__PURE__ */ T(oe, { size: 20 }),
182
+ icon: /* @__PURE__ */ T(ae, { size: 20 }),
183
183
  trend: X ? {
184
184
  value: de - Q,
185
185
  label: N("devportal.analytics.vsPrevious", "vs previous period")
@@ -188,7 +188,7 @@ var ce = {
188
188
  /* @__PURE__ */ T(c, {
189
189
  title: N("devportal.analytics.avgResponseTime", "Avg Response Time"),
190
190
  value: Y?.avgResponseTime ? `${Y.avgResponseTime}ms` : N("devportal.common.na", "N/A"),
191
- icon: /* @__PURE__ */ T(se, { size: 20 }),
191
+ icon: /* @__PURE__ */ T(oe, { size: 20 }),
192
192
  trend: typeof $ == "number" ? {
193
193
  value: $,
194
194
  label: N("devportal.analytics.fasterThanPrevious", "faster than previous")
@@ -199,7 +199,7 @@ var ce = {
199
199
  }),
200
200
  /* @__PURE__ */ E("div", {
201
201
  className: "grid gap-6 xl:grid-cols-2",
202
- children: [/* @__PURE__ */ T(s, {
202
+ children: [/* @__PURE__ */ T(o, {
203
203
  title: N("devportal.analytics.trafficTrend", "Traffic trend"),
204
204
  children: /* @__PURE__ */ T(O, {
205
205
  treatment: "insight",
@@ -207,7 +207,7 @@ var ce = {
207
207
  children: /* @__PURE__ */ T(u, {
208
208
  width: "100%",
209
209
  height: 300,
210
- children: /* @__PURE__ */ E(re, {
210
+ children: /* @__PURE__ */ E(ne, {
211
211
  data: Z,
212
212
  children: [
213
213
  /* @__PURE__ */ T(f, {
@@ -246,7 +246,7 @@ var ce = {
246
246
  })
247
247
  })
248
248
  })
249
- }), /* @__PURE__ */ T(s, {
249
+ }), /* @__PURE__ */ T(o, {
250
250
  title: N("devportal.analytics.userActivity", "User activity"),
251
251
  children: /* @__PURE__ */ T(O, {
252
252
  treatment: "insight",
@@ -254,7 +254,7 @@ var ce = {
254
254
  children: /* @__PURE__ */ T(u, {
255
255
  width: "100%",
256
256
  height: 300,
257
- children: /* @__PURE__ */ E(ie, {
257
+ children: /* @__PURE__ */ E(re, {
258
258
  data: Z,
259
259
  children: [
260
260
  /* @__PURE__ */ T(f, {
@@ -301,9 +301,9 @@ var ce = {
301
301
  })
302
302
  })]
303
303
  }),
304
- /* @__PURE__ */ T(s, {
304
+ /* @__PURE__ */ T(o, {
305
305
  title: N("devportal.analytics.dailyBreakdown", "Daily breakdown"),
306
- children: /* @__PURE__ */ T(ne, {
306
+ children: /* @__PURE__ */ T(te, {
307
307
  data: J,
308
308
  keyField: "id",
309
309
  columns: [
@@ -349,7 +349,7 @@ var ce = {
349
349
  ]
350
350
  })
351
351
  })
352
- ] }) : /* @__PURE__ */ T(n, {
352
+ ] }) : /* @__PURE__ */ T(t, {
353
353
  illustration: "empty-data",
354
354
  icon: /* @__PURE__ */ T(x, { size: 32 }),
355
355
  title: N("devportal.analytics.noAnalyticsTitle", "No analytics available yet"),
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsDashboardPage.js","names":[],"sources":["../../../src/devportal/pages/AnalyticsDashboardPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router\";\nimport {\n Activity,\n AlertCircle,\n AlertTriangle,\n BarChart3,\n Clock,\n Loader2,\n Users,\n} from \"lucide-react\";\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Line,\n LineChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { AppListItem } from \"../components/AppCard\";\nimport type { Application } from \"../types\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n type GetAnalyticsDashboardOptionsQuery,\n getErrorMessage,\n useGetAnalyticsDashboardOptionsQuery,\n useGetApplicationAnalyticsDashboardQuery,\n} from \"../hooks\";\nimport { useTr } from \"../utils/i18n\";\n\ntype TimeRange = \"7d\" | \"30d\" | \"90d\";\n\nconst daysByRange: Record<TimeRange, number> = {\n \"7d\": 7,\n \"30d\": 30,\n \"90d\": 90,\n};\n\nconst chartColors = {\n primary: \"var(--color-chart-1)\",\n secondary: \"var(--color-chart-2)\",\n tertiary: \"var(--color-chart-4)\",\n negative: \"var(--color-chart-negative)\",\n};\n\nexport const AnalyticsDashboardPage: FC = () => {\n const { appId } = useParams<{ appId: string }>();\n const { navigate, basePath, activeOrgId } = useDevportal();\n const tr = useTr();\n const [timeRange, setTimeRange] = useState<TimeRange>(\"30d\");\n const [selectedApplicationId, setSelectedApplicationId] = useState(\n appId || \"\",\n );\n\n const now = useMemo(() => new Date(), []);\n const startDate = useMemo(() => {\n const nextDate = new Date(now);\n nextDate.setDate(nextDate.getDate() - daysByRange[timeRange]);\n return nextDate.toISOString();\n }, [now, timeRange]);\n\n const {\n data: optionsData,\n loading: optionsLoading,\n error: optionsError,\n } = useGetAnalyticsDashboardOptionsQuery({\n skip: !!appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const { data, loading, error } = useGetApplicationAnalyticsDashboardQuery({\n variables: {\n applicationId: selectedApplicationId || appId || \"\",\n period: \"daily\",\n startDate,\n endDate: now.toISOString(),\n },\n skip: !(selectedApplicationId || appId),\n fetchPolicy: \"cache-and-network\",\n });\n\n const allApplications: Application[] =\n optionsData?.applications?.edges?.map(\n (\n edge: GetAnalyticsDashboardOptionsQuery[\"applications\"][\"edges\"][number],\n ) => edge.node as Application,\n ) ?? [];\n // Scope the app picker to the active org when one is selected\n const applications = activeOrgId\n ? allApplications.filter((a) => a.developerOrganizationId === activeOrgId)\n : allApplications;\n const selectedApplication = data?.application;\n\n useEffect(() => {\n const name = selectedApplication?.name;\n const id = appId || selectedApplicationId;\n if (!id || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(id, name);\n return () => reg?.unregister(id);\n }, [appId, selectedApplicationId, selectedApplication?.name]);\n\n const analytics = [...(data?.applicationAnalytics ?? [])].sort(\n (left, right) =>\n new Date(left.date).getTime() - new Date(right.date).getTime(),\n );\n\n const latest = analytics[analytics.length - 1];\n const previous = analytics[analytics.length - 2];\n const chartData = analytics.map((entry) => ({\n date: new Date(entry.date).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n }),\n apiCalls: entry.apiCalls,\n errors: entry.errors,\n activeUsers: entry.activeUsers,\n newUsers: entry.newUsers,\n sessions: entry.sessions,\n avgResponseTime: entry.avgResponseTime ?? 0,\n }));\n\n const errorRate =\n latest && latest.apiCalls > 0 ? (latest.errors / latest.apiCalls) * 100 : 0;\n const previousErrorRate =\n previous && previous.apiCalls > 0\n ? (previous.errors / previous.apiCalls) * 100\n : 0;\n const responseTrend =\n latest?.avgResponseTime && previous?.avgResponseTime\n ? previous.avgResponseTime - latest.avgResponseTime\n : undefined;\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n if (!appId && optionsLoading && !optionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )}\n >\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (!appId && optionsError) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.analytics.errorLoadApps\",\n \"Unable to load applications\",\n )}\n description={getErrorMessage(optionsError)}\n />\n </PageLayout>\n );\n }\n\n if (!appId && !selectedApplicationId) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.selectAppDescription\",\n \"Select an application to review live usage metrics from the public gateway\",\n )}\n >\n {applications.length > 0 ? (\n <div className=\"space-y-2\">\n {applications.map((application) => (\n <AppListItem\n key={application.id}\n app={application}\n onClick={() => setSelectedApplicationId(application.id)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<BarChart3 size={32} />}\n title={tr(\n \"devportal.analytics.noAppsTitle\",\n \"No applications available\",\n )}\n description={tr(\n \"devportal.analytics.noAppsDescription\",\n \"Create an application before viewing analytics.\",\n )}\n />\n )}\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )}\n backLink={\n selectedApplicationId ? `/apps/${selectedApplicationId}` : undefined\n }\n backLabel={tr(\n \"devportal.analytics.backToApplication\",\n \"Back to Application\",\n )}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.analytics.errorLoadAnalytics\",\n \"Unable to load analytics\",\n )}\n description={getErrorMessage(error)}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={\n appId\n ? tr(\"devportal.analytics.appTitle\", \"Application Analytics\")\n : tr(\"devportal.analytics.title\", \"Analytics\")\n }\n description={\n selectedApplication\n ? `${tr(\"devportal.analytics.liveUsageFor\", \"Live usage and performance for\")} ${selectedApplication.name}`\n : tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )\n }\n purpose={tr(\n \"devportal.analytics.purpose\",\n \"Analytics shows how your apps are actually used — API call volume, active installs, latency, and error rates over time — so you can spot regressions, plan capacity, and prove value to your users. Pick an app and a time range to drill in.\",\n )}\n backLink={\n appId && selectedApplication\n ? `/apps/${selectedApplication.id}`\n : undefined\n }\n backLabel={tr(\n \"devportal.analytics.backToApplication\",\n \"Back to Application\",\n )}\n actions={\n <div className=\"flex flex-wrap gap-2\">\n {!appId && applications.length > 0 && (\n <select\n value={selectedApplicationId}\n onChange={(event) => setSelectedApplicationId(event.target.value)}\n aria-label={tr(\n \"devportal.analytics.selectAppAria\",\n \"Select application\",\n )}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n {applications.map((application) => (\n <option key={application.id} value={application.id}>\n {application.name}\n </option>\n ))}\n </select>\n )}\n <select\n value={timeRange}\n onChange={(event) => setTimeRange(event.target.value as TimeRange)}\n aria-label={tr(\n \"devportal.analytics.selectRangeAria\",\n \"Select time range\",\n )}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"7d\">\n {tr(\"devportal.analytics.range.7d\", \"Last 7 days\")}\n </option>\n <option value=\"30d\">\n {tr(\"devportal.analytics.range.30d\", \"Last 30 days\")}\n </option>\n <option value=\"90d\">\n {tr(\"devportal.analytics.range.90d\", \"Last 90 days\")}\n </option>\n </select>\n </div>\n }\n >\n {loading && !analytics.length ? (\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n ) : analytics.length > 0 ? (\n <>\n <EmphasisPanel className=\"mb-6\">\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.analytics.apiCalls\", \"API Calls\")}\n value={(latest?.apiCalls ?? 0).toLocaleString()}\n icon={<Activity size={20} />}\n />\n <StatCard\n title={tr(\"devportal.analytics.activeUsers\", \"Active Users\")}\n value={(latest?.activeUsers ?? 0).toLocaleString()}\n icon={<Users size={20} />}\n />\n <StatCard\n title={tr(\"devportal.analytics.errorRate\", \"Error Rate\")}\n value={`${errorRate.toFixed(2)}%`}\n icon={<AlertTriangle size={20} />}\n trend={\n previous\n ? {\n value: previousErrorRate - errorRate,\n label: tr(\n \"devportal.analytics.vsPrevious\",\n \"vs previous period\",\n ),\n }\n : undefined\n }\n />\n <StatCard\n title={tr(\n \"devportal.analytics.avgResponseTime\",\n \"Avg Response Time\",\n )}\n value={\n latest?.avgResponseTime\n ? `${latest.avgResponseTime}ms`\n : tr(\"devportal.common.na\", \"N/A\")\n }\n icon={<Clock size={20} />}\n trend={\n typeof responseTrend === \"number\"\n ? {\n value: responseTrend,\n label: tr(\n \"devportal.analytics.fasterThanPrevious\",\n \"faster than previous\",\n ),\n }\n : undefined\n }\n />\n </StatCardGrid>\n </EmphasisPanel>\n\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <PageSection\n title={tr(\"devportal.analytics.trafficTrend\", \"Traffic trend\")}\n >\n <GlassCard treatment=\"insight\" className=\"p-4\">\n <ResponsiveContainer width=\"100%\" height={300}>\n <LineChart data={chartData}>\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--color-chart-grid)\"\n />\n <XAxis\n dataKey=\"date\"\n stroke=\"var(--color-chart-axis)\"\n fontSize={12}\n />\n <YAxis stroke=\"var(--color-chart-axis)\" fontSize={12} />\n <Tooltip\n contentStyle={{\n backgroundColor: \"var(--color-card)\",\n border: \"1px solid var(--color-border-default)\",\n borderRadius: 12,\n }}\n />\n <Line\n type=\"monotone\"\n dataKey=\"apiCalls\"\n stroke={chartColors.primary}\n strokeWidth={2}\n dot={false}\n />\n <Line\n type=\"monotone\"\n dataKey=\"errors\"\n stroke={chartColors.negative}\n strokeWidth={2}\n dot={false}\n />\n </LineChart>\n </ResponsiveContainer>\n </GlassCard>\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.analytics.userActivity\", \"User activity\")}\n >\n <GlassCard treatment=\"insight\" className=\"p-4\">\n <ResponsiveContainer width=\"100%\" height={300}>\n <BarChart data={chartData}>\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--color-chart-grid)\"\n />\n <XAxis\n dataKey=\"date\"\n stroke=\"var(--color-chart-axis)\"\n fontSize={12}\n />\n <YAxis stroke=\"var(--color-chart-axis)\" fontSize={12} />\n <Tooltip\n contentStyle={{\n backgroundColor: \"var(--color-card)\",\n border: \"1px solid var(--color-border-default)\",\n borderRadius: 12,\n }}\n />\n <Bar\n dataKey=\"activeUsers\"\n fill={chartColors.primary}\n radius={[6, 6, 0, 0]}\n />\n <Bar\n dataKey=\"newUsers\"\n fill={chartColors.secondary}\n radius={[6, 6, 0, 0]}\n />\n </BarChart>\n </ResponsiveContainer>\n </GlassCard>\n </PageSection>\n </div>\n\n <PageSection\n title={tr(\"devportal.analytics.dailyBreakdown\", \"Daily breakdown\")}\n >\n <DataTable\n data={analytics}\n keyField=\"id\"\n columns={[\n {\n key: \"date\",\n header: tr(\"devportal.analytics.date\", \"Date\"),\n render: (entry) =>\n new Date(entry.date).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n }),\n },\n {\n key: \"apiCalls\",\n header: tr(\"devportal.analytics.apiCalls\", \"API Calls\"),\n render: (entry) => entry.apiCalls.toLocaleString(),\n },\n {\n key: \"errors\",\n header: tr(\"devportal.analytics.errors\", \"Errors\"),\n render: (entry) => entry.errors.toLocaleString(),\n },\n {\n key: \"activeUsers\",\n header: tr(\"devportal.analytics.activeUsers\", \"Active Users\"),\n render: (entry) => entry.activeUsers.toLocaleString(),\n },\n {\n key: \"newUsers\",\n header: tr(\"devportal.analytics.newUsers\", \"New Users\"),\n render: (entry) => entry.newUsers.toLocaleString(),\n },\n {\n key: \"avgResponseTime\",\n header: tr(\"devportal.analytics.avgResponse\", \"Avg Response\"),\n render: (entry) =>\n entry.avgResponseTime\n ? `${entry.avgResponseTime}ms`\n : tr(\"devportal.common.na\", \"N/A\"),\n },\n {\n key: \"sessions\",\n header: tr(\"devportal.analytics.sessions\", \"Sessions\"),\n render: (entry) => entry.sessions.toLocaleString(),\n },\n ]}\n />\n </PageSection>\n </>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<BarChart3 size={32} />}\n title={tr(\n \"devportal.analytics.noAnalyticsTitle\",\n \"No analytics available yet\",\n )}\n description={tr(\n \"devportal.analytics.noAnalyticsDescription\",\n \"Analytics will appear after this application starts receiving traffic through the public gateway.\",\n )}\n action={\n !appId ? (\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"/apps\")}\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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n {tr(\n \"devportal.analytics.viewApplications\",\n \"View applications\",\n )}\n </button>\n ) : undefined\n }\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AnalyticsDashboardPage.js","names":[],"sources":["../../../src/devportal/pages/AnalyticsDashboardPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router\";\nimport {\n Activity,\n AlertCircle,\n AlertTriangle,\n BarChart3,\n Clock,\n Loader2,\n Users,\n} from \"lucide-react\";\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Line,\n LineChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { AppListItem } from \"../components/AppCard\";\nimport type { Application } from \"../types\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n type GetAnalyticsDashboardOptionsQuery,\n getErrorMessage,\n useGetAnalyticsDashboardOptionsQuery,\n useGetApplicationAnalyticsDashboardQuery,\n} from \"../hooks\";\nimport { useTr } from \"../utils/i18n\";\n\ntype TimeRange = \"7d\" | \"30d\" | \"90d\";\n\nconst daysByRange: Record<TimeRange, number> = {\n \"7d\": 7,\n \"30d\": 30,\n \"90d\": 90,\n};\n\nconst chartColors = {\n primary: \"var(--color-chart-1)\",\n secondary: \"var(--color-chart-2)\",\n tertiary: \"var(--color-chart-4)\",\n negative: \"var(--color-chart-negative)\",\n};\n\nexport const AnalyticsDashboardPage: FC = () => {\n const { appId } = useParams<{ appId: string }>();\n const { navigate, basePath, activeOrgId } = useDevportal();\n const tr = useTr();\n const [timeRange, setTimeRange] = useState<TimeRange>(\"30d\");\n const [selectedApplicationId, setSelectedApplicationId] = useState(\n appId || \"\",\n );\n\n const now = useMemo(() => new Date(), []);\n const startDate = useMemo(() => {\n const nextDate = new Date(now);\n nextDate.setDate(nextDate.getDate() - daysByRange[timeRange]);\n return nextDate.toISOString();\n }, [now, timeRange]);\n\n const {\n data: optionsData,\n loading: optionsLoading,\n error: optionsError,\n } = useGetAnalyticsDashboardOptionsQuery({\n skip: !!appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const { data, loading, error } = useGetApplicationAnalyticsDashboardQuery({\n variables: {\n applicationId: selectedApplicationId || appId || \"\",\n period: \"daily\",\n startDate,\n endDate: now.toISOString(),\n },\n skip: !(selectedApplicationId || appId),\n fetchPolicy: \"cache-and-network\",\n });\n\n const allApplications: Application[] =\n optionsData?.applications?.edges?.map(\n (\n edge: GetAnalyticsDashboardOptionsQuery[\"applications\"][\"edges\"][number],\n ) => edge.node as Application,\n ) ?? [];\n // Scope the app picker to the active org when one is selected\n const applications = activeOrgId\n ? allApplications.filter((a) => a.developerOrganizationId === activeOrgId)\n : allApplications;\n const selectedApplication = data?.application;\n\n useEffect(() => {\n const name = selectedApplication?.name;\n const id = appId || selectedApplicationId;\n if (!id || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(id, name);\n return () => reg?.unregister(id);\n }, [appId, selectedApplicationId, selectedApplication?.name]);\n\n const analytics = [...(data?.applicationAnalytics ?? [])].sort(\n (left, right) =>\n new Date(left.date).getTime() - new Date(right.date).getTime(),\n );\n\n const latest = analytics[analytics.length - 1];\n const previous = analytics[analytics.length - 2];\n const chartData = analytics.map((entry) => ({\n date: new Date(entry.date).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n }),\n apiCalls: entry.apiCalls,\n errors: entry.errors,\n activeUsers: entry.activeUsers,\n newUsers: entry.newUsers,\n sessions: entry.sessions,\n avgResponseTime: entry.avgResponseTime ?? 0,\n }));\n\n const errorRate =\n latest && latest.apiCalls > 0 ? (latest.errors / latest.apiCalls) * 100 : 0;\n const previousErrorRate =\n previous && previous.apiCalls > 0\n ? (previous.errors / previous.apiCalls) * 100\n : 0;\n const responseTrend =\n latest?.avgResponseTime && previous?.avgResponseTime\n ? previous.avgResponseTime - latest.avgResponseTime\n : undefined;\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n if (!appId && optionsLoading && !optionsData) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )}\n >\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (!appId && optionsError) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.analytics.errorLoadApps\",\n \"Unable to load applications\",\n )}\n description={getErrorMessage(optionsError)}\n />\n </PageLayout>\n );\n }\n\n if (!appId && !selectedApplicationId) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.selectAppDescription\",\n \"Select an application to review live usage metrics from the public gateway\",\n )}\n >\n {applications.length > 0 ? (\n <div className=\"space-y-2\">\n {applications.map((application) => (\n <AppListItem\n key={application.id}\n app={application}\n onClick={() => setSelectedApplicationId(application.id)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<BarChart3 size={32} />}\n title={tr(\n \"devportal.analytics.noAppsTitle\",\n \"No applications available\",\n )}\n description={tr(\n \"devportal.analytics.noAppsDescription\",\n \"Create an application before viewing analytics.\",\n )}\n />\n )}\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title={tr(\"devportal.analytics.title\", \"Analytics\")}\n description={tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )}\n backLink={\n selectedApplicationId ? `/apps/${selectedApplicationId}` : undefined\n }\n backLabel={tr(\n \"devportal.analytics.backToApplication\",\n \"Back to Application\",\n )}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.analytics.errorLoadAnalytics\",\n \"Unable to load analytics\",\n )}\n description={getErrorMessage(error)}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={\n appId\n ? tr(\"devportal.analytics.appTitle\", \"Application Analytics\")\n : tr(\"devportal.analytics.title\", \"Analytics\")\n }\n description={\n selectedApplication\n ? `${tr(\"devportal.analytics.liveUsageFor\", \"Live usage and performance for\")} ${selectedApplication.name}`\n : tr(\n \"devportal.analytics.description\",\n \"Explore live application usage and performance metrics\",\n )\n }\n purpose={tr(\n \"devportal.analytics.purpose\",\n \"Analytics shows how your apps are actually used — API call volume, active installs, latency, and error rates over time — so you can spot regressions, plan capacity, and prove value to your users. Pick an app and a time range to drill in.\",\n )}\n backLink={\n appId && selectedApplication\n ? `/apps/${selectedApplication.id}`\n : undefined\n }\n backLabel={tr(\n \"devportal.analytics.backToApplication\",\n \"Back to Application\",\n )}\n actions={\n <div className=\"flex flex-wrap gap-2\">\n {!appId && applications.length > 0 && (\n <select\n value={selectedApplicationId}\n onChange={(event) => setSelectedApplicationId(event.target.value)}\n aria-label={tr(\n \"devportal.analytics.selectAppAria\",\n \"Select application\",\n )}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n {applications.map((application) => (\n <option key={application.id} value={application.id}>\n {application.name}\n </option>\n ))}\n </select>\n )}\n <select\n value={timeRange}\n onChange={(event) => setTimeRange(event.target.value as TimeRange)}\n aria-label={tr(\n \"devportal.analytics.selectRangeAria\",\n \"Select time range\",\n )}\n className=\"rounded-md border bg-bg-surface px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"7d\">\n {tr(\"devportal.analytics.range.7d\", \"Last 7 days\")}\n </option>\n <option value=\"30d\">\n {tr(\"devportal.analytics.range.30d\", \"Last 30 days\")}\n </option>\n <option value=\"90d\">\n {tr(\"devportal.analytics.range.90d\", \"Last 90 days\")}\n </option>\n </select>\n </div>\n }\n >\n {loading && !analytics.length ? (\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n ) : analytics.length > 0 ? (\n <>\n <EmphasisPanel className=\"mb-6\">\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.analytics.apiCalls\", \"API Calls\")}\n value={(latest?.apiCalls ?? 0).toLocaleString()}\n icon={<Activity size={20} />}\n />\n <StatCard\n title={tr(\"devportal.analytics.activeUsers\", \"Active Users\")}\n value={(latest?.activeUsers ?? 0).toLocaleString()}\n icon={<Users size={20} />}\n />\n <StatCard\n title={tr(\"devportal.analytics.errorRate\", \"Error Rate\")}\n value={`${errorRate.toFixed(2)}%`}\n icon={<AlertTriangle size={20} />}\n trend={\n previous\n ? {\n value: previousErrorRate - errorRate,\n label: tr(\n \"devportal.analytics.vsPrevious\",\n \"vs previous period\",\n ),\n }\n : undefined\n }\n />\n <StatCard\n title={tr(\n \"devportal.analytics.avgResponseTime\",\n \"Avg Response Time\",\n )}\n value={\n latest?.avgResponseTime\n ? `${latest.avgResponseTime}ms`\n : tr(\"devportal.common.na\", \"N/A\")\n }\n icon={<Clock size={20} />}\n trend={\n typeof responseTrend === \"number\"\n ? {\n value: responseTrend,\n label: tr(\n \"devportal.analytics.fasterThanPrevious\",\n \"faster than previous\",\n ),\n }\n : undefined\n }\n />\n </StatCardGrid>\n </EmphasisPanel>\n\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <PageSection\n title={tr(\"devportal.analytics.trafficTrend\", \"Traffic trend\")}\n >\n <GlassCard treatment=\"insight\" className=\"p-4\">\n <ResponsiveContainer width=\"100%\" height={300}>\n <LineChart data={chartData}>\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--color-chart-grid)\"\n />\n <XAxis\n dataKey=\"date\"\n stroke=\"var(--color-chart-axis)\"\n fontSize={12}\n />\n <YAxis stroke=\"var(--color-chart-axis)\" fontSize={12} />\n <Tooltip\n contentStyle={{\n backgroundColor: \"var(--color-card)\",\n border: \"1px solid var(--color-border-default)\",\n borderRadius: 12,\n }}\n />\n <Line\n type=\"monotone\"\n dataKey=\"apiCalls\"\n stroke={chartColors.primary}\n strokeWidth={2}\n dot={false}\n />\n <Line\n type=\"monotone\"\n dataKey=\"errors\"\n stroke={chartColors.negative}\n strokeWidth={2}\n dot={false}\n />\n </LineChart>\n </ResponsiveContainer>\n </GlassCard>\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.analytics.userActivity\", \"User activity\")}\n >\n <GlassCard treatment=\"insight\" className=\"p-4\">\n <ResponsiveContainer width=\"100%\" height={300}>\n <BarChart data={chartData}>\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--color-chart-grid)\"\n />\n <XAxis\n dataKey=\"date\"\n stroke=\"var(--color-chart-axis)\"\n fontSize={12}\n />\n <YAxis stroke=\"var(--color-chart-axis)\" fontSize={12} />\n <Tooltip\n contentStyle={{\n backgroundColor: \"var(--color-card)\",\n border: \"1px solid var(--color-border-default)\",\n borderRadius: 12,\n }}\n />\n <Bar\n dataKey=\"activeUsers\"\n fill={chartColors.primary}\n radius={[6, 6, 0, 0]}\n />\n <Bar\n dataKey=\"newUsers\"\n fill={chartColors.secondary}\n radius={[6, 6, 0, 0]}\n />\n </BarChart>\n </ResponsiveContainer>\n </GlassCard>\n </PageSection>\n </div>\n\n <PageSection\n title={tr(\"devportal.analytics.dailyBreakdown\", \"Daily breakdown\")}\n >\n <DataTable\n data={analytics}\n keyField=\"id\"\n columns={[\n {\n key: \"date\",\n header: tr(\"devportal.analytics.date\", \"Date\"),\n render: (entry) =>\n new Date(entry.date).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n }),\n },\n {\n key: \"apiCalls\",\n header: tr(\"devportal.analytics.apiCalls\", \"API Calls\"),\n render: (entry) => entry.apiCalls.toLocaleString(),\n },\n {\n key: \"errors\",\n header: tr(\"devportal.analytics.errors\", \"Errors\"),\n render: (entry) => entry.errors.toLocaleString(),\n },\n {\n key: \"activeUsers\",\n header: tr(\"devportal.analytics.activeUsers\", \"Active Users\"),\n render: (entry) => entry.activeUsers.toLocaleString(),\n },\n {\n key: \"newUsers\",\n header: tr(\"devportal.analytics.newUsers\", \"New Users\"),\n render: (entry) => entry.newUsers.toLocaleString(),\n },\n {\n key: \"avgResponseTime\",\n header: tr(\"devportal.analytics.avgResponse\", \"Avg Response\"),\n render: (entry) =>\n entry.avgResponseTime\n ? `${entry.avgResponseTime}ms`\n : tr(\"devportal.common.na\", \"N/A\"),\n },\n {\n key: \"sessions\",\n header: tr(\"devportal.analytics.sessions\", \"Sessions\"),\n render: (entry) => entry.sessions.toLocaleString(),\n },\n ]}\n />\n </PageSection>\n </>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<BarChart3 size={32} />}\n title={tr(\n \"devportal.analytics.noAnalyticsTitle\",\n \"No analytics available yet\",\n )}\n description={tr(\n \"devportal.analytics.noAnalyticsDescription\",\n \"Analytics will appear after this application starts receiving traffic through the public gateway.\",\n )}\n action={\n !appId ? (\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"/apps\")}\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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n {tr(\n \"devportal.analytics.viewApplications\",\n \"View applications\",\n )}\n </button>\n ) : undefined\n }\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
- import { useParams as e } from "../../node_modules/react-router/dist/production/lib/hooks.js";
2
- import { useDevportal as t } from "../providers/DevportalProvider.js";
3
- import { EmptyState as n } from "../components/EmptyState.js";
4
- import { useGetApplicationAuditLogsQuery as r } from "../../generated/global-operations.js";
5
- import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
- import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
1
+ import { useDevportal as e } from "../providers/DevportalProvider.js";
2
+ import { EmptyState as t } from "../components/EmptyState.js";
3
+ import { useGetApplicationAuditLogsQuery as n } from "../../generated/global-operations.js";
4
+ import { getErrorMessage as r } from "../hooks/useGraphQL.js";
5
+ import { PageLayout as i, PageSection as a } from "../components/PageLayout.js";
7
6
  import "../hooks/index.js";
8
- import s from "../../node_modules/date-fns/format.js";
9
- import { useEffect as c, useMemo as l, useState as u } from "react";
10
- import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
- import { AlertCircle as f, Download as p, Filter as m, Loader2 as h, RefreshCw as g } from "lucide-react";
7
+ import o from "../../node_modules/date-fns/format.js";
8
+ import { useEffect as s, useMemo as c, useState as l } from "react";
9
+ import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
+ import { AlertCircle as d, Download as f, Filter as p, Loader2 as m, RefreshCw as h } from "lucide-react";
11
+ import { useParams as g } from "react-router";
12
12
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
13
13
  //#region src/devportal/pages/AppLogsPage.tsx
14
- var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (e) => e.toUpperCase()), S = (e) => {
14
+ var y = 25, b = (e) => o(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (e) => e.toUpperCase()), S = (e) => {
15
15
  if (!e) return "";
16
16
  try {
17
17
  return JSON.stringify(e, null, 2);
@@ -19,7 +19,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
19
19
  return "";
20
20
  }
21
21
  }, C = () => {
22
- let { t: s } = d(), { appId: C } = e(), { navigate: w, basePath: T, currentUser: E } = t(), D = (e) => E?.id === e && E.email ? E.email : e, [O, k] = u("all"), [A, j] = u(""), [M, N] = u(1), { data: P, loading: F, error: I, refetch: L } = r({
22
+ let { t: o } = u(), { appId: C } = g(), { navigate: w, basePath: T, currentUser: E } = e(), D = (e) => E?.id === e && E.email ? E.email : e, [O, k] = l("all"), [A, j] = l(""), [M, N] = l(1), { data: P, loading: F, error: I, refetch: L } = n({
23
23
  variables: {
24
24
  applicationId: C || "",
25
25
  limit: y,
@@ -28,13 +28,13 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
28
28
  skip: !C,
29
29
  fetchPolicy: "cache-and-network"
30
30
  }), R = P?.application;
31
- c(() => {
31
+ s(() => {
32
32
  let e = R?.name;
33
33
  if (!C || !e) return;
34
34
  let t = window.__breadcrumbRegistry;
35
35
  return t?.register(C, e), () => t?.unregister(C);
36
36
  }, [C, R?.name]);
37
- let z = P?.auditLogs?.totalCount ?? 0, B = P?.auditLogs?.edges?.map((e) => e.node) ?? [], V = l(() => Array.from(new Set(B.map((e) => e.action))).sort((e, t) => e.localeCompare(t)), [B]), H = l(() => {
37
+ let z = P?.auditLogs?.totalCount ?? 0, B = P?.auditLogs?.edges?.map((e) => e.node) ?? [], V = c(() => Array.from(new Set(B.map((e) => e.action))).sort((e, t) => e.localeCompare(t)), [B]), H = c(() => {
38
38
  let e = A.trim().toLowerCase();
39
39
  return B.filter((t) => O === "all" || t.action === O ? e ? [
40
40
  t.action,
@@ -48,29 +48,29 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
48
48
  B,
49
49
  A
50
50
  ]);
51
- return F && !P ? /* @__PURE__ */ _(a, {
51
+ return F && !P ? /* @__PURE__ */ _(i, {
52
52
  title: "Application Activity",
53
53
  description: "Loading application audit history",
54
54
  backLink: C ? `/apps/${C}` : "/apps",
55
55
  backLabel: "Back to Application",
56
56
  children: /* @__PURE__ */ _("div", {
57
57
  className: "flex items-center justify-center py-16 text-text-secondary",
58
- children: /* @__PURE__ */ _(h, { className: "h-8 w-8 animate-spin" })
58
+ children: /* @__PURE__ */ _(m, { className: "h-8 w-8 animate-spin" })
59
59
  })
60
- }) : I || !R ? /* @__PURE__ */ _(a, {
60
+ }) : I || !R ? /* @__PURE__ */ _(i, {
61
61
  title: "Application Activity",
62
62
  description: "Review audit events for this application",
63
63
  backLink: C ? `/apps/${C}` : "/apps",
64
64
  backLabel: "Back to Application",
65
- children: /* @__PURE__ */ _(n, {
66
- icon: /* @__PURE__ */ _(f, {
65
+ children: /* @__PURE__ */ _(t, {
66
+ icon: /* @__PURE__ */ _(d, {
67
67
  size: 32,
68
68
  className: "text-status-error-text"
69
69
  }),
70
70
  title: "Unable to load activity",
71
- description: I ? i(I) : "Application not found"
71
+ description: I ? r(I) : "Application not found"
72
72
  })
73
- }) : /* @__PURE__ */ v(a, {
73
+ }) : /* @__PURE__ */ v(i, {
74
74
  title: "Application Activity",
75
75
  description: `Audit events for ${R.name}`,
76
76
  purpose: "A chronological audit trail of everything that happened to this app — config changes, secret rotations, webhook deliveries, and access events. Use it to debug integrations and to answer 'who changed what, and when?'",
@@ -82,7 +82,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
82
82
  type: "button",
83
83
  onClick: () => void L(),
84
84
  className: "inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent",
85
- children: [/* @__PURE__ */ _(g, { size: 16 }), "Refresh"]
85
+ children: [/* @__PURE__ */ _(h, { size: 16 }), "Refresh"]
86
86
  }), /* @__PURE__ */ v("button", {
87
87
  type: "button",
88
88
  onClick: () => {
@@ -90,7 +90,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
90
90
  n.href = t, n.download = `${R?.slug || C || "application"}-audit-log.json`, n.click(), URL.revokeObjectURL(t);
91
91
  },
92
92
  className: "inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-accent",
93
- children: [/* @__PURE__ */ _(p, { size: 16 }), "Export JSON"]
93
+ children: [/* @__PURE__ */ _(f, { size: 16 }), "Export JSON"]
94
94
  })]
95
95
  }),
96
96
  children: [
@@ -101,7 +101,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
101
101
  className: "grid gap-2 text-sm font-medium",
102
102
  children: [/* @__PURE__ */ v("span", {
103
103
  className: "flex items-center gap-2 text-text-secondary",
104
- children: [/* @__PURE__ */ _(m, { size: 16 }), "Filter by action"]
104
+ children: [/* @__PURE__ */ _(p, { size: 16 }), "Filter by action"]
105
105
  }), /* @__PURE__ */ v("select", {
106
106
  value: O,
107
107
  onChange: (e) => k(e.target.value),
@@ -134,7 +134,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
134
134
  })
135
135
  ]
136
136
  }),
137
- /* @__PURE__ */ _(o, { children: H.length > 0 ? /* @__PURE__ */ _("div", {
137
+ /* @__PURE__ */ _(a, { children: H.length > 0 ? /* @__PURE__ */ _("div", {
138
138
  className: "space-y-3 rounded-card border border-border-seam bg-bg-surface p-4",
139
139
  children: H.map((e) => /* @__PURE__ */ v("article", {
140
140
  className: "rounded-card border border-border-seam bg-bg-surface p-4",
@@ -181,7 +181,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
181
181
  })
182
182
  ]
183
183
  }, e.id))
184
- }) : /* @__PURE__ */ _(n, {
184
+ }) : /* @__PURE__ */ _(t, {
185
185
  illustration: "empty-data",
186
186
  title: "No audit events found",
187
187
  description: "Events will appear here after application or webhook actions are performed through the public gateway."
@@ -192,7 +192,7 @@ var y = 25, b = (e) => s(new Date(e), "MMM d, yyyy HH:mm:ss"), x = (e) => e.repl
192
192
  type: "button",
193
193
  onClick: () => N((e) => e + 1),
194
194
  className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-accent",
195
- children: [/* @__PURE__ */ _(g, { size: 16 }), "Next page"]
195
+ children: [/* @__PURE__ */ _(h, { size: 16 }), "Next page"]
196
196
  })
197
197
  })
198
198
  ]