@burdenoff/microfe-devportal 2026.701.1 → 2026.702.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.
@@ -4,9 +4,9 @@ import "./FeatureFlaggedRoute.js";
4
4
  import "./TelemetryErrorBoundary.js";
5
5
  import "./SectionNav.js";
6
6
  import "./PageLayout.js";
7
- import "./StatCard.js";
8
7
  import "./StatusBadge.js";
9
8
  import "./AppCard.js";
9
+ import "./StatCard.js";
10
10
  import "./SecretDisplay.js";
11
11
  import "./DataTable.js";
12
12
  import "./FormField.js";
@@ -3,22 +3,22 @@ import { EmptyState as t } from "../components/EmptyState.js";
3
3
  import { useGetAnalyticsDashboardOptionsQuery as n, useGetApplicationAnalyticsDashboardQuery as r } from "../../generated/global-operations.js";
4
4
  import { getErrorMessage as i } from "../hooks/useGraphQL.js";
5
5
  import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
6
- import { StatCard as s, StatCardGrid as ee } from "../components/StatCard.js";
7
- import { AppListItem as te } from "../components/AppCard.js";
8
- import { DataTable as ne } from "../components/DataTable.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";
9
9
  import "../hooks/index.js";
10
- import { Tooltip as c } from "../../node_modules/recharts/es6/component/Tooltip.js";
11
- import { ResponsiveContainer as l } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
12
- import { Bar as u } from "../../node_modules/recharts/es6/cartesian/Bar.js";
13
- import { CartesianGrid as d } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
14
- import { Line as f } from "../../node_modules/recharts/es6/cartesian/Line.js";
15
- import { XAxis as p } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
16
- import { YAxis as m } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
17
- import { LineChart as re } from "../../node_modules/recharts/es6/chart/LineChart.js";
18
- import { BarChart as ie } from "../../node_modules/recharts/es6/chart/BarChart.js";
19
- import { useTr as ae } from "../utils/i18n.js";
20
- import { useEffect as h, useMemo as g, useState as _ } from "react";
21
- import { Activity as v, AlertCircle as y, AlertTriangle as oe, BarChart3 as b, Clock as x, Loader2 as S, Users as se } from "lucide-react";
10
+ import { Tooltip as l } from "../../node_modules/recharts/es6/component/Tooltip.js";
11
+ import { ResponsiveContainer as u } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
12
+ import { Bar as d } from "../../node_modules/recharts/es6/cartesian/Bar.js";
13
+ import { CartesianGrid as f } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
14
+ import { Line as p } from "../../node_modules/recharts/es6/cartesian/Line.js";
15
+ import { XAxis as m } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
16
+ import { YAxis as h } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
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
22
  import { useParams as C } from "react-router-dom";
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";
@@ -33,7 +33,7 @@ var ce = {
33
33
  tertiary: "var(--color-chart-4)",
34
34
  negative: "var(--color-chart-negative)"
35
35
  }, A = () => {
36
- let { appId: A } = C(), { navigate: j, basePath: le, activeOrgId: M } = e(), N = ae(), [P, F] = _("30d"), [I, L] = _(A || ""), R = g(() => /* @__PURE__ */ new Date(), []), z = g(() => {
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
39
  }, [R, P]), { data: B, loading: V, error: H } = n({
@@ -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
- h(() => {
52
+ g(() => {
53
53
  let e = q?.name, t = A || I;
54
54
  if (!t || !e) return;
55
55
  let n = window.__breadcrumbRegistry;
@@ -84,7 +84,7 @@ var ce = {
84
84
  title: N("devportal.analytics.title", "Analytics"),
85
85
  description: N("devportal.analytics.description", "Explore live application usage and performance metrics"),
86
86
  children: /* @__PURE__ */ T(t, {
87
- icon: /* @__PURE__ */ T(y, {
87
+ icon: /* @__PURE__ */ T(b, {
88
88
  size: 32,
89
89
  className: "text-status-error-text"
90
90
  }),
@@ -96,13 +96,13 @@ var ce = {
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(te, {
99
+ children: K.map((e) => /* @__PURE__ */ T(s, {
100
100
  app: e,
101
101
  onClick: () => L(e.id)
102
102
  }, e.id))
103
103
  }) : /* @__PURE__ */ T(t, {
104
104
  illustration: "empty-data",
105
- icon: /* @__PURE__ */ T(b, { size: 32 }),
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
  })
@@ -112,7 +112,7 @@ var ce = {
112
112
  backLink: I ? `/apps/${I}` : void 0,
113
113
  backLabel: N("devportal.analytics.backToApplication", "Back to Application"),
114
114
  children: /* @__PURE__ */ T(t, {
115
- icon: /* @__PURE__ */ T(y, {
115
+ icon: /* @__PURE__ */ T(b, {
116
116
  size: 32,
117
117
  className: "text-status-error-text"
118
118
  }),
@@ -166,29 +166,29 @@ var ce = {
166
166
  children: /* @__PURE__ */ E(ee, {
167
167
  columns: 4,
168
168
  children: [
169
- /* @__PURE__ */ T(s, {
169
+ /* @__PURE__ */ T(c, {
170
170
  title: N("devportal.analytics.apiCalls", "API Calls"),
171
171
  value: (Y?.apiCalls ?? 0).toLocaleString(),
172
- icon: /* @__PURE__ */ T(v, { size: 20 })
172
+ icon: /* @__PURE__ */ T(y, { size: 20 })
173
173
  }),
174
- /* @__PURE__ */ T(s, {
174
+ /* @__PURE__ */ T(c, {
175
175
  title: N("devportal.analytics.activeUsers", "Active Users"),
176
176
  value: (Y?.activeUsers ?? 0).toLocaleString(),
177
177
  icon: /* @__PURE__ */ T(se, { size: 20 })
178
178
  }),
179
- /* @__PURE__ */ T(s, {
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")
186
186
  } : void 0
187
187
  }),
188
- /* @__PURE__ */ T(s, {
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(x, { 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")
@@ -204,38 +204,38 @@ var ce = {
204
204
  children: /* @__PURE__ */ T(O, {
205
205
  treatment: "insight",
206
206
  className: "p-4",
207
- children: /* @__PURE__ */ T(l, {
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
- /* @__PURE__ */ T(d, {
213
+ /* @__PURE__ */ T(f, {
214
214
  strokeDasharray: "3 3",
215
215
  stroke: "var(--color-chart-grid)"
216
216
  }),
217
- /* @__PURE__ */ T(p, {
217
+ /* @__PURE__ */ T(m, {
218
218
  dataKey: "date",
219
219
  stroke: "var(--color-chart-axis)",
220
220
  fontSize: 12
221
221
  }),
222
- /* @__PURE__ */ T(m, {
222
+ /* @__PURE__ */ T(h, {
223
223
  stroke: "var(--color-chart-axis)",
224
224
  fontSize: 12
225
225
  }),
226
- /* @__PURE__ */ T(c, { contentStyle: {
226
+ /* @__PURE__ */ T(l, { contentStyle: {
227
227
  backgroundColor: "var(--color-card)",
228
228
  border: "1px solid var(--color-border-default)",
229
229
  borderRadius: 12
230
230
  } }),
231
- /* @__PURE__ */ T(f, {
231
+ /* @__PURE__ */ T(p, {
232
232
  type: "monotone",
233
233
  dataKey: "apiCalls",
234
234
  stroke: k.primary,
235
235
  strokeWidth: 2,
236
236
  dot: !1
237
237
  }),
238
- /* @__PURE__ */ T(f, {
238
+ /* @__PURE__ */ T(p, {
239
239
  type: "monotone",
240
240
  dataKey: "errors",
241
241
  stroke: k.negative,
@@ -251,31 +251,31 @@ var ce = {
251
251
  children: /* @__PURE__ */ T(O, {
252
252
  treatment: "insight",
253
253
  className: "p-4",
254
- children: /* @__PURE__ */ T(l, {
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
- /* @__PURE__ */ T(d, {
260
+ /* @__PURE__ */ T(f, {
261
261
  strokeDasharray: "3 3",
262
262
  stroke: "var(--color-chart-grid)"
263
263
  }),
264
- /* @__PURE__ */ T(p, {
264
+ /* @__PURE__ */ T(m, {
265
265
  dataKey: "date",
266
266
  stroke: "var(--color-chart-axis)",
267
267
  fontSize: 12
268
268
  }),
269
- /* @__PURE__ */ T(m, {
269
+ /* @__PURE__ */ T(h, {
270
270
  stroke: "var(--color-chart-axis)",
271
271
  fontSize: 12
272
272
  }),
273
- /* @__PURE__ */ T(c, { contentStyle: {
273
+ /* @__PURE__ */ T(l, { contentStyle: {
274
274
  backgroundColor: "var(--color-card)",
275
275
  border: "1px solid var(--color-border-default)",
276
276
  borderRadius: 12
277
277
  } }),
278
- /* @__PURE__ */ T(u, {
278
+ /* @__PURE__ */ T(d, {
279
279
  dataKey: "activeUsers",
280
280
  fill: k.primary,
281
281
  radius: [
@@ -285,7 +285,7 @@ var ce = {
285
285
  0
286
286
  ]
287
287
  }),
288
- /* @__PURE__ */ T(u, {
288
+ /* @__PURE__ */ T(d, {
289
289
  dataKey: "newUsers",
290
290
  fill: k.secondary,
291
291
  radius: [
@@ -303,7 +303,7 @@ var ce = {
303
303
  }),
304
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: [
@@ -351,7 +351,7 @@ var ce = {
351
351
  })
352
352
  ] }) : /* @__PURE__ */ T(t, {
353
353
  illustration: "empty-data",
354
- icon: /* @__PURE__ */ T(b, { size: 32 }),
354
+ icon: /* @__PURE__ */ T(x, { size: 32 }),
355
355
  title: N("devportal.analytics.noAnalyticsTitle", "No analytics available yet"),
356
356
  description: N("devportal.analytics.noAnalyticsDescription", "Analytics will appear after this application starts receiving traffic through the public gateway."),
357
357
  action: A ? void 0 : /* @__PURE__ */ T("button", {
@@ -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-dom\";\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-dom\";\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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"}