@burdenoff/microfe-devportal 2026.611.1 → 2026.614.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/devportal/components/SectionNav.js +105 -41
  2. package/dist/devportal/components/SectionNav.js.map +1 -1
  3. package/dist/devportal/hooks/useGraphQL.js +1 -1
  4. package/dist/devportal/pages/AdminReviewPage.js +36 -36
  5. package/dist/devportal/pages/AnalyticsDashboardPage.js +150 -150
  6. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  7. package/dist/devportal/pages/ApiKeysPage.js +184 -172
  8. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  9. package/dist/devportal/pages/AppLogsPage.js +9 -9
  10. package/dist/devportal/pages/ApplicationDetailPage.js +414 -414
  11. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  12. package/dist/devportal/pages/ApplicationVersionsPage.js +44 -44
  13. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  14. package/dist/devportal/pages/ApplicationsPage.js +118 -118
  15. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  16. package/dist/devportal/pages/CreateApiKeyPage.js +20 -20
  17. package/dist/devportal/pages/CreateApplicationPage.js +32 -32
  18. package/dist/devportal/pages/CreateOAuthClientPage.js +20 -20
  19. package/dist/devportal/pages/CreateOrganizationPage.js +109 -422
  20. package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
  21. package/dist/devportal/pages/CreateWebhookPage.js +25 -25
  22. package/dist/devportal/pages/DashboardPage.js +160 -145
  23. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  24. package/dist/devportal/pages/DelegationsPage.js +22 -22
  25. package/dist/devportal/pages/EditApplicationPage.js +283 -283
  26. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  27. package/dist/devportal/pages/ListingPreviewPage.js +9 -9
  28. package/dist/devportal/pages/OAuthClientDetailPage.js +17 -17
  29. package/dist/devportal/pages/OAuthClientsPage.js +16 -16
  30. package/dist/devportal/pages/OrganizationDetailPage.js +78 -78
  31. package/dist/devportal/pages/OrganizationMembersPage.js +260 -260
  32. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  33. package/dist/devportal/pages/OrganizationsPage.js +18 -18
  34. package/dist/devportal/pages/PublishPage.js +16 -16
  35. package/dist/devportal/pages/PublisherProfilePage.js +156 -146
  36. package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
  37. package/dist/devportal/pages/RevenueDashboardPage.js +528 -322
  38. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  39. package/dist/devportal/pages/SettingsPage.js +17 -17
  40. package/dist/devportal/pages/SetupPage.js +99 -99
  41. package/dist/devportal/pages/SetupPage.js.map +1 -1
  42. package/dist/devportal/pages/WebhookDetailPage.js +143 -143
  43. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  44. package/dist/devportal/pages/WebhooksPage.js +140 -140
  45. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  46. package/dist/devportal/providers/DevportalProvider.js +46 -33
  47. package/dist/devportal/providers/DevportalProvider.js.map +1 -1
  48. package/dist/devportal/types/index.js.map +1 -1
  49. package/dist/generated/global-operations.js +99 -59
  50. package/dist/generated/global-operations.js.map +1 -1
  51. package/package.json +1 -1
@@ -1,259 +1,274 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
2
  import { EmptyState as t } from "../components/EmptyState.js";
3
- import { PageLayout as n, PageSection as r } from "../components/PageLayout.js";
4
- import { StatCard as i, StatCardGrid as a } from "../components/StatCard.js";
5
- import { AppListItem as o } from "../components/AppCard.js";
6
- import { useGetDevportalDashboardBootstrapQuery as s } from "../../generated/global-operations.js";
3
+ import { useGetDevportalDashboardBootstrapQuery as n } from "../../generated/global-operations.js";
4
+ import { PageLayout as r, PageSection as i } from "../components/PageLayout.js";
5
+ import { StatCard as a, StatCardGrid as o } from "../components/StatCard.js";
6
+ import { AppListItem as s } from "../components/AppCard.js";
7
7
  import { PermissionGuard as c } from "../components/PermissionGuard.js";
8
8
  import "../components/index.js";
9
9
  import { DEVPORTAL_PERMISSIONS as l } from "../constants/permissions.js";
10
10
  import "../hooks/index.js";
11
11
  import { useEffect as u } from "react";
12
12
  import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
13
- import { Activity as f, AppWindow as p, ArrowRight as m, Building2 as h, DollarSign as g, Key as _, Loader2 as v, Plus as y, TrendingUp as b, Users as x, Webhook as S } from "lucide-react";
14
- import { jsx as C, jsxs as w } from "react/jsx-runtime";
13
+ import { Activity as f, AppWindow as p, ArrowRight as m, Building2 as h, DollarSign as g, Key as _, Loader2 as v, Plus as y, Store as b, TrendingUp as x, Users as S, Webhook as C } from "lucide-react";
14
+ import { jsx as w, jsxs as T } from "react/jsx-runtime";
15
15
  //#region src/devportal/pages/DashboardPage.tsx
16
- var T = () => {
17
- let { navigate: T, basePath: O } = e(), { t: k } = d(), A = (e, t) => {
18
- let n = k(e);
16
+ var E = () => {
17
+ let { navigate: E, basePath: k } = e(), { t: A } = d(), j = (e, t) => {
18
+ let n = A(e);
19
19
  return n === e ? t : n;
20
- }, { data: j, loading: M } = s({ fetchPolicy: "cache-and-network" }), N = j?.myDeveloperOrganizations ?? [];
20
+ }, { data: M, loading: N } = n({ fetchPolicy: "cache-and-network" }), P = M?.myDeveloperOrganizations ?? [];
21
21
  u(() => {
22
- if (!(M || !j) && !(N.length > 0)) {
22
+ if (!(N || !M) && !(P.length > 0)) {
23
23
  try {
24
24
  if (localStorage.getItem("devportal_setup_dismissed")) return;
25
25
  } catch {
26
26
  return;
27
27
  }
28
- T?.(`${O}/setup`);
28
+ E?.(`${k}/setup`);
29
29
  }
30
30
  }, [
31
+ N,
31
32
  M,
32
- j,
33
- N.length,
34
- T,
35
- O
33
+ P.length,
34
+ E,
35
+ k
36
36
  ]);
37
- let P = j?.applications?.edges?.map((e) => e.node) ?? [], F = {
38
- totalApps: j?.applications?.totalCount ?? 0,
39
- totalOrgs: N.length,
37
+ let F = M?.applications?.edges?.map((e) => e.node) ?? [], I = {
38
+ totalApps: M?.applications?.totalCount ?? 0,
39
+ totalOrgs: P.length,
40
40
  totalApiKeys: 0,
41
41
  totalWebhooks: 0,
42
- totalApiCalls: N.reduce((e, t) => e + parseInt(t.totalApiCalls || "0"), 0),
43
- activeInstalls: N.reduce((e, t) => e + (t.activeInstalls || 0), 0),
44
- monthlyRevenue: N.reduce((e, t) => e + (t.totalRevenue || 0), 0),
42
+ totalApiCalls: P.reduce((e, t) => e + parseInt(t.totalApiCalls || "0"), 0),
43
+ activeInstalls: P.reduce((e, t) => e + (t.activeInstalls || 0), 0),
44
+ monthlyRevenue: P.reduce((e, t) => e + (t.totalRevenue || 0), 0),
45
45
  errorRate: 0
46
- }, I = (e) => {
47
- T?.(`${O}${e}`);
48
- }, L = M;
49
- return /* @__PURE__ */ C(c, {
46
+ }, L = (e) => {
47
+ E?.(`${k}${e}`);
48
+ }, R = N, z = !R && P.length > 0;
49
+ return /* @__PURE__ */ w(c, {
50
50
  permission: l.APP_READ,
51
- children: /* @__PURE__ */ w(n, {
52
- title: A("devportal.developerPortal", "Developer Portal"),
53
- description: A("devportal.buildManageMonitor", "Build, manage, and monitor your applications"),
54
- actions: /* @__PURE__ */ w("button", {
51
+ children: /* @__PURE__ */ T(r, {
52
+ title: j("devportal.developerPortal", "Developer Portal"),
53
+ description: j("devportal.buildManageMonitor", "Build, manage, and monitor your applications"),
54
+ actions: z ? /* @__PURE__ */ T("button", {
55
55
  "data-tour": "devportal-dashboard-create-app-button",
56
- onClick: () => I("/apps/new"),
56
+ onClick: () => L("/apps/new"),
57
57
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
58
- children: [/* @__PURE__ */ C(y, { size: 16 }), A("devportal.createApp", "Create App")]
58
+ children: [/* @__PURE__ */ w(y, { size: 16 }), j("devportal.createApp", "Create App")]
59
+ }) : R ? null : /* @__PURE__ */ T("button", {
60
+ "data-tour": "devportal-dashboard-create-org-button",
61
+ onClick: () => L("/organizations/new"),
62
+ className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
63
+ children: [/* @__PURE__ */ w(y, { size: 16 }), j("devportal.createOrganization", "Create Organization")]
59
64
  }),
60
65
  children: [
61
- /* @__PURE__ */ C(r, {
66
+ /* @__PURE__ */ w(i, {
62
67
  "data-tour": "devportal-dashboard-stats-overview",
63
- children: /* @__PURE__ */ w(a, {
68
+ children: /* @__PURE__ */ T(o, {
64
69
  columns: 4,
65
70
  children: [
66
- /* @__PURE__ */ C(i, {
67
- title: A("devportal.totalApps", "Total Apps"),
68
- value: L ? /* @__PURE__ */ C(v, { className: "h-5 w-5 animate-spin" }) : F.totalApps,
69
- icon: /* @__PURE__ */ C(p, { size: 20 }),
71
+ /* @__PURE__ */ w(a, {
72
+ title: j("devportal.totalApps", "Total Apps"),
73
+ value: R ? /* @__PURE__ */ w(v, { className: "h-5 w-5 animate-spin" }) : I.totalApps,
74
+ icon: /* @__PURE__ */ w(p, { size: 20 }),
70
75
  trend: void 0
71
76
  }),
72
- /* @__PURE__ */ C(i, {
73
- title: A("devportal.organizations", "Organizations"),
74
- value: L ? /* @__PURE__ */ C(v, { className: "h-5 w-5 animate-spin" }) : F.totalOrgs,
75
- icon: /* @__PURE__ */ C(h, { size: 20 })
77
+ /* @__PURE__ */ w(a, {
78
+ title: j("devportal.organizations", "Organizations"),
79
+ value: R ? /* @__PURE__ */ w(v, { className: "h-5 w-5 animate-spin" }) : I.totalOrgs,
80
+ icon: /* @__PURE__ */ w(h, { size: 20 })
76
81
  }),
77
- /* @__PURE__ */ C(i, {
78
- title: A("devportal.apiKeys", "API Keys"),
79
- value: F.totalApiKeys,
80
- icon: /* @__PURE__ */ C(_, { size: 20 }),
81
- description: A("devportal.activeKeys", "Active keys")
82
+ /* @__PURE__ */ w(a, {
83
+ title: j("devportal.apiKeys", "API Keys"),
84
+ value: I.totalApiKeys,
85
+ icon: /* @__PURE__ */ w(_, { size: 20 }),
86
+ description: j("devportal.activeKeys", "Active keys")
82
87
  }),
83
- /* @__PURE__ */ C(i, {
84
- title: A("devportal.webhooks", "Webhooks"),
85
- value: F.totalWebhooks,
86
- icon: /* @__PURE__ */ C(S, { size: 20 }),
87
- description: A("devportal.configured", "Configured")
88
+ /* @__PURE__ */ w(a, {
89
+ title: j("devportal.webhooks", "Webhooks"),
90
+ value: I.totalWebhooks,
91
+ icon: /* @__PURE__ */ w(C, { size: 20 }),
92
+ description: j("devportal.configured", "Configured")
88
93
  })
89
94
  ]
90
95
  })
91
96
  }),
92
- /* @__PURE__ */ C(r, {
93
- title: A("devportal.usageOverview", "Usage Overview"),
97
+ /* @__PURE__ */ w(i, {
98
+ title: j("devportal.usageOverview", "Usage Overview"),
94
99
  "data-tour": "devportal-dashboard-usage-overview",
95
- children: /* @__PURE__ */ w(a, {
100
+ children: /* @__PURE__ */ T(o, {
96
101
  columns: 4,
97
102
  children: [
98
- /* @__PURE__ */ C(i, {
99
- title: A("devportal.apiCalls", "API Calls"),
100
- value: L ? /* @__PURE__ */ C(v, { className: "h-5 w-5 animate-spin" }) : F.totalApiCalls > 1e6 ? `${(F.totalApiCalls / 1e6).toFixed(1)}M` : F.totalApiCalls > 1e3 ? `${(F.totalApiCalls / 1e3).toFixed(1)}K` : F.totalApiCalls.toString(),
101
- icon: /* @__PURE__ */ C(f, { size: 20 }),
103
+ /* @__PURE__ */ w(a, {
104
+ title: j("devportal.apiCalls", "API Calls"),
105
+ value: R ? /* @__PURE__ */ w(v, { className: "h-5 w-5 animate-spin" }) : I.totalApiCalls > 1e6 ? `${(I.totalApiCalls / 1e6).toFixed(1)}M` : I.totalApiCalls > 1e3 ? `${(I.totalApiCalls / 1e3).toFixed(1)}K` : I.totalApiCalls.toString(),
106
+ icon: /* @__PURE__ */ w(f, { size: 20 }),
102
107
  trend: void 0
103
108
  }),
104
- /* @__PURE__ */ C(i, {
105
- title: A("devportal.activeInstalls", "Active Installs"),
106
- value: L ? /* @__PURE__ */ C(v, { className: "h-5 w-5 animate-spin" }) : F.activeInstalls > 1e3 ? `${(F.activeInstalls / 1e3).toFixed(1)}K` : F.activeInstalls.toString(),
107
- icon: /* @__PURE__ */ C(x, { size: 20 }),
109
+ /* @__PURE__ */ w(a, {
110
+ title: j("devportal.activeInstalls", "Active Installs"),
111
+ value: R ? /* @__PURE__ */ w(v, { className: "h-5 w-5 animate-spin" }) : I.activeInstalls > 1e3 ? `${(I.activeInstalls / 1e3).toFixed(1)}K` : I.activeInstalls.toString(),
112
+ icon: /* @__PURE__ */ w(S, { size: 20 }),
108
113
  trend: void 0
109
114
  }),
110
- /* @__PURE__ */ C(i, {
111
- title: A("devportal.monthlyRevenue", "Monthly Revenue"),
112
- value: L ? /* @__PURE__ */ C(v, { className: "h-5 w-5 animate-spin" }) : `$${F.monthlyRevenue.toLocaleString()}`,
113
- icon: /* @__PURE__ */ C(g, { size: 20 }),
115
+ /* @__PURE__ */ w(a, {
116
+ title: j("devportal.monthlyRevenue", "Monthly Revenue"),
117
+ value: R ? /* @__PURE__ */ w(v, { className: "h-5 w-5 animate-spin" }) : `$${I.monthlyRevenue.toLocaleString()}`,
118
+ icon: /* @__PURE__ */ w(g, { size: 20 }),
114
119
  trend: void 0
115
120
  }),
116
- /* @__PURE__ */ C(i, {
117
- title: A("devportal.errorRate", "Error Rate"),
118
- value: `${F.errorRate}%`,
119
- icon: /* @__PURE__ */ C(b, { size: 20 }),
121
+ /* @__PURE__ */ w(a, {
122
+ title: j("devportal.errorRate", "Error Rate"),
123
+ value: `${I.errorRate}%`,
124
+ icon: /* @__PURE__ */ w(x, { size: 20 }),
120
125
  trend: void 0
121
126
  })
122
127
  ]
123
128
  })
124
129
  }),
125
- /* @__PURE__ */ w("div", {
130
+ /* @__PURE__ */ T("div", {
126
131
  className: "grid gap-6 lg:grid-cols-2",
127
- children: [/* @__PURE__ */ C(r, {
132
+ children: [/* @__PURE__ */ w(i, {
128
133
  "data-tour": "devportal-dashboard-recent-apps",
129
- title: A("devportal.recentApplications", "Recent Applications"),
130
- actions: /* @__PURE__ */ w("button", {
131
- onClick: () => I("/apps"),
134
+ title: j("devportal.recentApplications", "Recent Applications"),
135
+ actions: /* @__PURE__ */ T("button", {
136
+ onClick: () => L("/apps"),
132
137
  className: "text-sm text-primary hover:underline flex items-center gap-1",
133
138
  children: [
134
- A("devportal.viewAll", "View all"),
139
+ j("devportal.viewAll", "View all"),
135
140
  " ",
136
- /* @__PURE__ */ C(m, { size: 14 })
141
+ /* @__PURE__ */ w(m, { size: 14 })
137
142
  ]
138
143
  }),
139
- children: L ? /* @__PURE__ */ C("div", {
144
+ children: R ? /* @__PURE__ */ w("div", {
140
145
  className: "flex items-center justify-center py-8",
141
- children: /* @__PURE__ */ C(v, { className: "h-6 w-6 animate-spin text-muted-foreground" })
142
- }) : P.length > 0 ? /* @__PURE__ */ C("div", {
146
+ children: /* @__PURE__ */ w(v, { className: "h-6 w-6 animate-spin text-muted-foreground" })
147
+ }) : F.length > 0 ? /* @__PURE__ */ w("div", {
143
148
  className: "space-y-2",
144
- children: P.slice(0, 3).map((e) => /* @__PURE__ */ C(o, {
149
+ children: F.slice(0, 3).map((e) => /* @__PURE__ */ w(s, {
145
150
  app: e,
146
- onClick: () => I(`/apps/${e.id}`)
151
+ onClick: () => L(`/apps/${e.id}`)
147
152
  }, e.id))
148
- }) : /* @__PURE__ */ C(t, {
149
- icon: /* @__PURE__ */ C(p, { size: 24 }),
150
- title: A("devportal.noApplicationsYet", "No applications yet"),
151
- description: A("devportal.createFirstApplicationToGetStarted", "Create your first application to get started"),
152
- action: /* @__PURE__ */ w("button", {
153
- onClick: () => I("/apps/new"),
153
+ }) : /* @__PURE__ */ w(t, {
154
+ icon: /* @__PURE__ */ w(p, { size: 24 }),
155
+ title: j("devportal.noApplicationsYet", "No applications yet"),
156
+ description: z ? j("devportal.createFirstApplicationToGetStarted", "Create your first application to get started") : j("devportal.createOrgFirstToPublishApps", "Create an organization first to start publishing apps"),
157
+ action: z ? /* @__PURE__ */ T("button", {
158
+ onClick: () => L("/apps/new"),
159
+ className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
160
+ children: [/* @__PURE__ */ w(y, { size: 16 }), j("devportal.createApp", "Create App")]
161
+ }) : /* @__PURE__ */ T("button", {
162
+ onClick: () => L("/organizations/new"),
154
163
  className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
155
- children: [/* @__PURE__ */ C(y, { size: 16 }), A("devportal.createApp", "Create App")]
164
+ children: [/* @__PURE__ */ w(y, { size: 16 }), j("devportal.createOrganization", "Create Organization")]
156
165
  })
157
166
  })
158
- }), /* @__PURE__ */ C(r, {
159
- title: A("devportal.quickActions", "Quick Actions"),
167
+ }), /* @__PURE__ */ w(i, {
168
+ title: j("devportal.quickActions", "Quick Actions"),
160
169
  "data-tour": "devportal-dashboard-quick-actions",
161
- children: /* @__PURE__ */ w("div", {
170
+ children: /* @__PURE__ */ T("div", {
162
171
  className: "grid gap-3",
163
172
  children: [
164
- /* @__PURE__ */ C(E, {
165
- title: A("devportal.createNewApp", "Create New App"),
166
- description: A("devportal.startBuildingANewApplication", "Start building a new application"),
167
- icon: /* @__PURE__ */ C(p, { size: 20 }),
168
- onClick: () => I("/apps/new")
173
+ z ? /* @__PURE__ */ w(D, {
174
+ title: j("devportal.createNewApp", "Create New App"),
175
+ description: j("devportal.startBuildingANewApplication", "Start building a new application"),
176
+ icon: /* @__PURE__ */ w(p, { size: 20 }),
177
+ onClick: () => L("/apps/new")
178
+ }) : /* @__PURE__ */ w(D, {
179
+ title: j("devportal.createOrganization", "Create Organization"),
180
+ description: j("devportal.setUpATeamToCollaborate", "Set up a team to collaborate"),
181
+ icon: /* @__PURE__ */ w(h, { size: 20 }),
182
+ onClick: () => L("/organizations/new"),
183
+ primary: !0
169
184
  }),
170
- /* @__PURE__ */ C(E, {
171
- title: A("devportal.createOrganization", "Create Organization"),
172
- description: A("devportal.setUpATeamToCollaborate", "Set up a team to collaborate"),
173
- icon: /* @__PURE__ */ C(h, { size: 20 }),
174
- onClick: () => I("/organizations/new")
185
+ z && /* @__PURE__ */ w(D, {
186
+ title: j("devportal.publisherProfile", "Publisher Profile"),
187
+ description: j("devportal.manageYourStorePresence", "Manage your store publisher presence"),
188
+ icon: /* @__PURE__ */ w(b, { size: 20 }),
189
+ onClick: () => L("/publisher/profile")
175
190
  }),
176
- /* @__PURE__ */ C(E, {
177
- title: A("devportal.generateApiKey", "Generate API Key"),
178
- description: A("devportal.createCredentialsForYourApps", "Create credentials for your apps"),
179
- icon: /* @__PURE__ */ C(_, { size: 20 }),
180
- onClick: () => I("/api-keys")
191
+ /* @__PURE__ */ w(D, {
192
+ title: j("devportal.generateApiKey", "Generate API Key"),
193
+ description: j("devportal.createCredentialsForYourApps", "Create credentials for your apps"),
194
+ icon: /* @__PURE__ */ w(_, { size: 20 }),
195
+ onClick: () => L("/api-keys")
181
196
  }),
182
- /* @__PURE__ */ C(E, {
183
- title: A("devportal.configureWebhooks", "Configure Webhooks"),
184
- description: A("devportal.setUpEventNotifications", "Set up event notifications"),
185
- icon: /* @__PURE__ */ C(S, { size: 20 }),
186
- onClick: () => I("/webhooks")
197
+ /* @__PURE__ */ w(D, {
198
+ title: j("devportal.configureWebhooks", "Configure Webhooks"),
199
+ description: j("devportal.setUpEventNotifications", "Set up event notifications"),
200
+ icon: /* @__PURE__ */ w(C, { size: 20 }),
201
+ onClick: () => L("/webhooks")
187
202
  })
188
203
  ]
189
204
  })
190
205
  })]
191
206
  }),
192
- L ? /* @__PURE__ */ C(r, {
207
+ R ? /* @__PURE__ */ w(i, {
193
208
  "data-tour": "devportal-dashboard-organizations",
194
- title: A("devportal.yourOrganizations", "Your Organizations"),
195
- children: /* @__PURE__ */ C("div", {
209
+ title: j("devportal.yourOrganizations", "Your Organizations"),
210
+ children: /* @__PURE__ */ w("div", {
196
211
  className: "flex items-center justify-center py-8",
197
- children: /* @__PURE__ */ C(v, { className: "h-6 w-6 animate-spin text-muted-foreground" })
212
+ children: /* @__PURE__ */ w(v, { className: "h-6 w-6 animate-spin text-muted-foreground" })
198
213
  })
199
- }) : N.length > 0 ? /* @__PURE__ */ C(r, {
200
- title: A("devportal.yourOrganizations", "Your Organizations"),
201
- actions: /* @__PURE__ */ w("button", {
202
- onClick: () => I("/organizations"),
214
+ }) : P.length > 0 ? /* @__PURE__ */ w(i, {
215
+ title: j("devportal.yourOrganizations", "Your Organizations"),
216
+ actions: /* @__PURE__ */ T("button", {
217
+ onClick: () => L("/organizations"),
203
218
  className: "text-sm text-primary hover:underline flex items-center gap-1",
204
219
  children: [
205
- A("devportal.viewAll", "View all"),
220
+ j("devportal.viewAll", "View all"),
206
221
  " ",
207
- /* @__PURE__ */ C(m, { size: 14 })
222
+ /* @__PURE__ */ w(m, { size: 14 })
208
223
  ]
209
224
  }),
210
- children: /* @__PURE__ */ C("div", {
225
+ children: /* @__PURE__ */ w("div", {
211
226
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
212
- children: N.slice(0, 3).map((e) => /* @__PURE__ */ C(D, {
227
+ children: P.slice(0, 3).map((e) => /* @__PURE__ */ w(O, {
213
228
  org: e,
214
- onClick: () => I(`/organizations/${e.id}`)
229
+ onClick: () => L(`/organizations/${e.id}`)
215
230
  }, e.id))
216
231
  })
217
232
  }) : null
218
233
  ]
219
234
  })
220
235
  });
221
- }, E = ({ title: e, description: t, icon: n, onClick: r }) => /* @__PURE__ */ w("button", {
236
+ }, D = ({ title: e, description: t, icon: n, onClick: r, primary: i }) => /* @__PURE__ */ T("button", {
222
237
  onClick: r,
223
- className: "flex items-center gap-4 rounded-lg border bg-card p-4 text-left hover:bg-accent transition-colors",
224
- children: [/* @__PURE__ */ C("div", {
225
- className: "rounded-lg bg-primary/10 p-2 text-primary",
238
+ className: ["flex items-center gap-4 rounded-lg border p-4 text-left transition-colors", i ? "border-primary bg-primary/5 hover:bg-primary/10" : "bg-card hover:bg-accent"].join(" "),
239
+ children: [/* @__PURE__ */ w("div", {
240
+ className: ["rounded-lg p-2", i ? "bg-primary/20 text-primary" : "bg-primary/10 text-primary"].join(" "),
226
241
  children: n
227
- }), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
242
+ }), /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
228
243
  className: "font-medium",
229
244
  children: e
230
- }), /* @__PURE__ */ C("p", {
245
+ }), /* @__PURE__ */ w("p", {
231
246
  className: "text-sm text-muted-foreground",
232
247
  children: t
233
248
  })] })]
234
- }), D = ({ org: e, onClick: t }) => {
249
+ }), O = ({ org: e, onClick: t }) => {
235
250
  let { t: n } = d(), r = (e, t) => {
236
251
  let r = n(e);
237
252
  return r === e ? t : r;
238
253
  };
239
- return /* @__PURE__ */ w("button", {
254
+ return /* @__PURE__ */ T("button", {
240
255
  onClick: t,
241
256
  className: "rounded-lg border bg-card p-4 text-left hover:bg-accent transition-colors",
242
- children: [/* @__PURE__ */ w("div", {
257
+ children: [/* @__PURE__ */ T("div", {
243
258
  className: "flex items-center gap-3",
244
- children: [e.logoUrl ? /* @__PURE__ */ C("img", {
259
+ children: [e.logoUrl ? /* @__PURE__ */ w("img", {
245
260
  src: e.logoUrl,
246
261
  alt: e.name,
247
262
  className: "h-10 w-10 rounded-lg object-cover"
248
- }) : /* @__PURE__ */ C("div", {
263
+ }) : /* @__PURE__ */ w("div", {
249
264
  className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary",
250
- children: /* @__PURE__ */ C(h, { size: 20 })
251
- }), /* @__PURE__ */ w("div", {
265
+ children: /* @__PURE__ */ w(h, { size: 20 })
266
+ }), /* @__PURE__ */ T("div", {
252
267
  className: "flex-1 min-w-0",
253
- children: [/* @__PURE__ */ C("p", {
268
+ children: [/* @__PURE__ */ w("p", {
254
269
  className: "font-medium truncate",
255
270
  children: e.name
256
- }), /* @__PURE__ */ w("p", {
271
+ }), /* @__PURE__ */ T("p", {
257
272
  className: "text-sm text-muted-foreground",
258
273
  children: [
259
274
  e.publishedApps,
@@ -262,13 +277,13 @@ var T = () => {
262
277
  ]
263
278
  })]
264
279
  })]
265
- }), /* @__PURE__ */ w("div", {
280
+ }), /* @__PURE__ */ T("div", {
266
281
  className: "mt-3 flex gap-4 text-sm text-muted-foreground",
267
- children: [/* @__PURE__ */ w("span", { children: [
282
+ children: [/* @__PURE__ */ T("span", { children: [
268
283
  (e.totalInstalls || 0).toLocaleString(),
269
284
  " ",
270
285
  r("devportal.installs", "installs")
271
- ] }), /* @__PURE__ */ w("span", { children: [
286
+ ] }), /* @__PURE__ */ T("span", { children: [
272
287
  "$",
273
288
  (e.totalRevenue || 0).toLocaleString(),
274
289
  " ",
@@ -278,6 +293,6 @@ var T = () => {
278
293
  });
279
294
  };
280
295
  //#endregion
281
- export { T as DashboardPage };
296
+ export { E as DashboardPage };
282
297
 
283
298
  //# sourceMappingURL=DashboardPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/devportal/pages/DashboardPage.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n AppWindow,\n Building2,\n Key,\n Webhook,\n TrendingUp,\n Users,\n DollarSign,\n Activity,\n Plus,\n ArrowRight,\n Loader2,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { AppListItem } from \"../components/AppCard\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport type { Application, DeveloperOrganization } from \"../types\";\nimport {\n useGetDevportalDashboardBootstrapQuery,\n type OrganizationFieldsFragment,\n type ApplicationFieldsFragment,\n} from \"../hooks\";\n\n/**\n * Developer Portal Dashboard Page\n *\n * Shows an overview of the developer's applications, organizations,\n * and key metrics using real data from the GraphQL API.\n */\nexport const DashboardPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Fetch dashboard bootstrap in a single global query\n const { data, loading } = useGetDevportalDashboardBootstrapQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const organizations: OrganizationFieldsFragment[] =\n data?.myDeveloperOrganizations ?? [];\n\n // First-time users: redirect to setup wizard when no org exists and they\n // haven't already dismissed the wizard in this browser.\n useEffect(() => {\n if (loading || !data) return;\n if (organizations.length > 0) return;\n try {\n if (localStorage.getItem(\"devportal_setup_dismissed\")) return;\n } catch {\n // localStorage unavailable — don't redirect\n return;\n }\n navigate?.(`${basePath}/setup`);\n }, [loading, data, organizations.length, navigate, basePath]);\n const applications: ApplicationFieldsFragment[] =\n data?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? [];\n\n // Calculate aggregate stats\n const stats = {\n totalApps: data?.applications?.totalCount ?? 0,\n totalOrgs: organizations.length,\n totalApiKeys: 0,\n totalWebhooks: 0,\n totalApiCalls: organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + parseInt(org.totalApiCalls || \"0\"),\n 0,\n ),\n activeInstalls: organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.activeInstalls || 0),\n 0,\n ),\n monthlyRevenue: organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.totalRevenue || 0),\n 0,\n ),\n errorRate: 0,\n };\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const isLoading = loading;\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.developerPortal\", \"Developer Portal\")}\n description={tr(\n \"devportal.buildManageMonitor\",\n \"Build, manage, and monitor your applications\",\n )}\n actions={\n <button\n data-tour=\"devportal-dashboard-create-app-button\"\n onClick={() => handleNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n }\n >\n {/* Stats Overview */}\n <PageSection data-tour=\"devportal-dashboard-stats-overview\">\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.totalApps\", \"Total Apps\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : (\n stats.totalApps\n )\n }\n icon={<AppWindow size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.organizations\", \"Organizations\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : (\n stats.totalOrgs\n )\n }\n icon={<Building2 size={20} />}\n />\n <StatCard\n title={tr(\"devportal.apiKeys\", \"API Keys\")}\n value={stats.totalApiKeys}\n icon={<Key size={20} />}\n description={tr(\"devportal.activeKeys\", \"Active keys\")}\n />\n <StatCard\n title={tr(\"devportal.webhooks\", \"Webhooks\")}\n value={stats.totalWebhooks}\n icon={<Webhook size={20} />}\n description={tr(\"devportal.configured\", \"Configured\")}\n />\n </StatCardGrid>\n </PageSection>\n\n {/* Usage Stats */}\n <PageSection\n title={tr(\"devportal.usageOverview\", \"Usage Overview\")}\n data-tour=\"devportal-dashboard-usage-overview\"\n >\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.apiCalls\", \"API Calls\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : stats.totalApiCalls > 1000000 ? (\n `${(stats.totalApiCalls / 1000000).toFixed(1)}M`\n ) : stats.totalApiCalls > 1000 ? (\n `${(stats.totalApiCalls / 1000).toFixed(1)}K`\n ) : (\n stats.totalApiCalls.toString()\n )\n }\n icon={<Activity size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.activeInstalls\", \"Active Installs\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : stats.activeInstalls > 1000 ? (\n `${(stats.activeInstalls / 1000).toFixed(1)}K`\n ) : (\n stats.activeInstalls.toString()\n )\n }\n icon={<Users size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.monthlyRevenue\", \"Monthly Revenue\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : (\n `$${stats.monthlyRevenue.toLocaleString()}`\n )\n }\n icon={<DollarSign size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.errorRate\", \"Error Rate\")}\n value={`${stats.errorRate}%`}\n icon={<TrendingUp size={20} />}\n trend={undefined}\n />\n </StatCardGrid>\n </PageSection>\n\n {/* Quick Actions & Recent Items */}\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {/* Recent Apps */}\n <PageSection\n data-tour=\"devportal-dashboard-recent-apps\"\n title={tr(\"devportal.recentApplications\", \"Recent Applications\")}\n actions={\n <button\n onClick={() => handleNavigate(\"/apps\")}\n className=\"text-sm text-primary hover:underline flex items-center gap-1\"\n >\n {tr(\"devportal.viewAll\", \"View all\")} <ArrowRight size={14} />\n </button>\n }\n >\n {isLoading ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n ) : applications.length > 0 ? (\n <div className=\"space-y-2\">\n {applications\n .slice(0, 3)\n .map((app: ApplicationFieldsFragment) => (\n <AppListItem\n key={app.id}\n app={app as Application}\n onClick={() => handleNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<AppWindow size={24} />}\n title={tr(\"devportal.noApplicationsYet\", \"No applications yet\")}\n description={tr(\n \"devportal.createFirstApplicationToGetStarted\",\n \"Create your first application to get started\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n }\n />\n )}\n </PageSection>\n\n {/* Quick Actions */}\n <PageSection\n title={tr(\"devportal.quickActions\", \"Quick Actions\")}\n data-tour=\"devportal-dashboard-quick-actions\"\n >\n <div className=\"grid gap-3\">\n <QuickActionCard\n title={tr(\"devportal.createNewApp\", \"Create New App\")}\n description={tr(\n \"devportal.startBuildingANewApplication\",\n \"Start building a new application\",\n )}\n icon={<AppWindow size={20} />}\n onClick={() => handleNavigate(\"/apps/new\")}\n />\n <QuickActionCard\n title={tr(\n \"devportal.createOrganization\",\n \"Create Organization\",\n )}\n description={tr(\n \"devportal.setUpATeamToCollaborate\",\n \"Set up a team to collaborate\",\n )}\n icon={<Building2 size={20} />}\n onClick={() => handleNavigate(\"/organizations/new\")}\n />\n <QuickActionCard\n title={tr(\"devportal.generateApiKey\", \"Generate API Key\")}\n description={tr(\n \"devportal.createCredentialsForYourApps\",\n \"Create credentials for your apps\",\n )}\n icon={<Key size={20} />}\n onClick={() => handleNavigate(\"/api-keys\")}\n />\n <QuickActionCard\n title={tr(\"devportal.configureWebhooks\", \"Configure Webhooks\")}\n description={tr(\n \"devportal.setUpEventNotifications\",\n \"Set up event notifications\",\n )}\n icon={<Webhook size={20} />}\n onClick={() => handleNavigate(\"/webhooks\")}\n />\n </div>\n </PageSection>\n </div>\n\n {/* Organizations */}\n {isLoading ? (\n <PageSection\n data-tour=\"devportal-dashboard-organizations\"\n title={tr(\"devportal.yourOrganizations\", \"Your Organizations\")}\n >\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n </PageSection>\n ) : organizations.length > 0 ? (\n <PageSection\n title={tr(\"devportal.yourOrganizations\", \"Your Organizations\")}\n actions={\n <button\n onClick={() => handleNavigate(\"/organizations\")}\n className=\"text-sm text-primary hover:underline flex items-center gap-1\"\n >\n {tr(\"devportal.viewAll\", \"View all\")} <ArrowRight size={14} />\n </button>\n }\n >\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {organizations\n .slice(0, 3)\n .map((org: OrganizationFieldsFragment) => (\n <OrgCard\n key={org.id}\n org={org as DeveloperOrganization}\n onClick={() => handleNavigate(`/organizations/${org.id}`)}\n />\n ))}\n </div>\n </PageSection>\n ) : null}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// Quick action card component\nconst QuickActionCard: FC<{\n title: string;\n description: string;\n icon: React.ReactNode;\n onClick: () => void;\n}> = ({ title, description, icon, onClick }) => (\n <button\n onClick={onClick}\n className=\"flex items-center gap-4 rounded-lg border bg-card p-4 text-left hover:bg-accent transition-colors\"\n >\n <div className=\"rounded-lg bg-primary/10 p-2 text-primary\">{icon}</div>\n <div>\n <p className=\"font-medium\">{title}</p>\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n </div>\n </button>\n);\n\n// Organization card component\nconst OrgCard: FC<{\n org: DeveloperOrganization;\n onClick: () => void;\n}> = ({ org, onClick }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n return (\n <button\n onClick={onClick}\n className=\"rounded-lg border bg-card p-4 text-left hover:bg-accent transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n {org.logoUrl ? (\n <img\n src={org.logoUrl}\n alt={org.name}\n className=\"h-10 w-10 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <Building2 size={20} />\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium truncate\">{org.name}</p>\n <p className=\"text-sm text-muted-foreground\">\n {org.publishedApps}{\" \"}\n {tr(\"devportal.appsPublished\", \"apps published\")}\n </p>\n </div>\n </div>\n <div className=\"mt-3 flex gap-4 text-sm text-muted-foreground\">\n <span>\n {(org.totalInstalls || 0).toLocaleString()}{\" \"}\n {tr(\"devportal.installs\", \"installs\")}\n </span>\n <span>\n ${(org.totalRevenue || 0).toLocaleString()}{\" \"}\n {tr(\"devportal.revenue\", \"revenue\")}\n </span>\n </div>\n </button>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/devportal/pages/DashboardPage.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n AppWindow,\n Building2,\n Key,\n Webhook,\n TrendingUp,\n Users,\n DollarSign,\n Activity,\n Plus,\n ArrowRight,\n Loader2,\n Store,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { AppListItem } from \"../components/AppCard\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport type { Application, DeveloperOrganization } from \"../types\";\nimport {\n useGetDevportalDashboardBootstrapQuery,\n type OrganizationFieldsFragment,\n type ApplicationFieldsFragment,\n} from \"../hooks\";\n\n/**\n * Developer Portal Dashboard Page\n *\n * Shows an overview of the developer's applications, organizations,\n * and key metrics using real data from the GraphQL API.\n */\nexport const DashboardPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Fetch dashboard bootstrap in a single global query\n const { data, loading } = useGetDevportalDashboardBootstrapQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const organizations: OrganizationFieldsFragment[] =\n data?.myDeveloperOrganizations ?? [];\n\n // First-time users: redirect to setup wizard when no org exists and they\n // haven't already dismissed the wizard in this browser.\n useEffect(() => {\n if (loading || !data) return;\n if (organizations.length > 0) return;\n try {\n if (localStorage.getItem(\"devportal_setup_dismissed\")) return;\n } catch {\n // localStorage unavailable — don't redirect\n return;\n }\n navigate?.(`${basePath}/setup`);\n }, [loading, data, organizations.length, navigate, basePath]);\n const applications: ApplicationFieldsFragment[] =\n data?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? [];\n\n // Calculate aggregate stats\n const stats = {\n totalApps: data?.applications?.totalCount ?? 0,\n totalOrgs: organizations.length,\n totalApiKeys: 0,\n totalWebhooks: 0,\n totalApiCalls: organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + parseInt(org.totalApiCalls || \"0\"),\n 0,\n ),\n activeInstalls: organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.activeInstalls || 0),\n 0,\n ),\n monthlyRevenue: organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.totalRevenue || 0),\n 0,\n ),\n errorRate: 0,\n };\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const isLoading = loading;\n\n const hasOrgs = !isLoading && organizations.length > 0;\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.APP_READ}>\n <PageLayout\n title={tr(\"devportal.developerPortal\", \"Developer Portal\")}\n description={tr(\n \"devportal.buildManageMonitor\",\n \"Build, manage, and monitor your applications\",\n )}\n actions={\n hasOrgs ? (\n <button\n data-tour=\"devportal-dashboard-create-app-button\"\n onClick={() => handleNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n ) : !isLoading ? (\n <button\n data-tour=\"devportal-dashboard-create-org-button\"\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n ) : null\n }\n >\n {/* Stats Overview */}\n <PageSection data-tour=\"devportal-dashboard-stats-overview\">\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.totalApps\", \"Total Apps\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : (\n stats.totalApps\n )\n }\n icon={<AppWindow size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.organizations\", \"Organizations\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : (\n stats.totalOrgs\n )\n }\n icon={<Building2 size={20} />}\n />\n <StatCard\n title={tr(\"devportal.apiKeys\", \"API Keys\")}\n value={stats.totalApiKeys}\n icon={<Key size={20} />}\n description={tr(\"devportal.activeKeys\", \"Active keys\")}\n />\n <StatCard\n title={tr(\"devportal.webhooks\", \"Webhooks\")}\n value={stats.totalWebhooks}\n icon={<Webhook size={20} />}\n description={tr(\"devportal.configured\", \"Configured\")}\n />\n </StatCardGrid>\n </PageSection>\n\n {/* Usage Stats */}\n <PageSection\n title={tr(\"devportal.usageOverview\", \"Usage Overview\")}\n data-tour=\"devportal-dashboard-usage-overview\"\n >\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.apiCalls\", \"API Calls\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : stats.totalApiCalls > 1000000 ? (\n `${(stats.totalApiCalls / 1000000).toFixed(1)}M`\n ) : stats.totalApiCalls > 1000 ? (\n `${(stats.totalApiCalls / 1000).toFixed(1)}K`\n ) : (\n stats.totalApiCalls.toString()\n )\n }\n icon={<Activity size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.activeInstalls\", \"Active Installs\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : stats.activeInstalls > 1000 ? (\n `${(stats.activeInstalls / 1000).toFixed(1)}K`\n ) : (\n stats.activeInstalls.toString()\n )\n }\n icon={<Users size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.monthlyRevenue\", \"Monthly Revenue\")}\n value={\n isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : (\n `$${stats.monthlyRevenue.toLocaleString()}`\n )\n }\n icon={<DollarSign size={20} />}\n trend={undefined}\n />\n <StatCard\n title={tr(\"devportal.errorRate\", \"Error Rate\")}\n value={`${stats.errorRate}%`}\n icon={<TrendingUp size={20} />}\n trend={undefined}\n />\n </StatCardGrid>\n </PageSection>\n\n {/* Quick Actions & Recent Items */}\n <div className=\"grid gap-6 lg:grid-cols-2\">\n {/* Recent Apps */}\n <PageSection\n data-tour=\"devportal-dashboard-recent-apps\"\n title={tr(\"devportal.recentApplications\", \"Recent Applications\")}\n actions={\n <button\n onClick={() => handleNavigate(\"/apps\")}\n className=\"text-sm text-primary hover:underline flex items-center gap-1\"\n >\n {tr(\"devportal.viewAll\", \"View all\")} <ArrowRight size={14} />\n </button>\n }\n >\n {isLoading ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n ) : applications.length > 0 ? (\n <div className=\"space-y-2\">\n {applications\n .slice(0, 3)\n .map((app: ApplicationFieldsFragment) => (\n <AppListItem\n key={app.id}\n app={app as Application}\n onClick={() => handleNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<AppWindow size={24} />}\n title={tr(\"devportal.noApplicationsYet\", \"No applications yet\")}\n description={\n hasOrgs\n ? tr(\n \"devportal.createFirstApplicationToGetStarted\",\n \"Create your first application to get started\",\n )\n : tr(\n \"devportal.createOrgFirstToPublishApps\",\n \"Create an organization first to start publishing apps\",\n )\n }\n action={\n hasOrgs ? (\n <button\n onClick={() => handleNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n ) : (\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n <Plus size={16} />\n {tr(\n \"devportal.createOrganization\",\n \"Create Organization\",\n )}\n </button>\n )\n }\n />\n )}\n </PageSection>\n\n {/* Quick Actions */}\n <PageSection\n title={tr(\"devportal.quickActions\", \"Quick Actions\")}\n data-tour=\"devportal-dashboard-quick-actions\"\n >\n <div className=\"grid gap-3\">\n {!hasOrgs ? (\n <QuickActionCard\n title={tr(\n \"devportal.createOrganization\",\n \"Create Organization\",\n )}\n description={tr(\n \"devportal.setUpATeamToCollaborate\",\n \"Set up a team to collaborate\",\n )}\n icon={<Building2 size={20} />}\n onClick={() => handleNavigate(\"/organizations/new\")}\n primary\n />\n ) : (\n <QuickActionCard\n title={tr(\"devportal.createNewApp\", \"Create New App\")}\n description={tr(\n \"devportal.startBuildingANewApplication\",\n \"Start building a new application\",\n )}\n icon={<AppWindow size={20} />}\n onClick={() => handleNavigate(\"/apps/new\")}\n />\n )}\n {hasOrgs && (\n <QuickActionCard\n title={tr(\"devportal.publisherProfile\", \"Publisher Profile\")}\n description={tr(\n \"devportal.manageYourStorePresence\",\n \"Manage your store publisher presence\",\n )}\n icon={<Store size={20} />}\n onClick={() => handleNavigate(\"/publisher/profile\")}\n />\n )}\n <QuickActionCard\n title={tr(\"devportal.generateApiKey\", \"Generate API Key\")}\n description={tr(\n \"devportal.createCredentialsForYourApps\",\n \"Create credentials for your apps\",\n )}\n icon={<Key size={20} />}\n onClick={() => handleNavigate(\"/api-keys\")}\n />\n <QuickActionCard\n title={tr(\"devportal.configureWebhooks\", \"Configure Webhooks\")}\n description={tr(\n \"devportal.setUpEventNotifications\",\n \"Set up event notifications\",\n )}\n icon={<Webhook size={20} />}\n onClick={() => handleNavigate(\"/webhooks\")}\n />\n </div>\n </PageSection>\n </div>\n\n {/* Organizations */}\n {isLoading ? (\n <PageSection\n data-tour=\"devportal-dashboard-organizations\"\n title={tr(\"devportal.yourOrganizations\", \"Your Organizations\")}\n >\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n </PageSection>\n ) : organizations.length > 0 ? (\n <PageSection\n title={tr(\"devportal.yourOrganizations\", \"Your Organizations\")}\n actions={\n <button\n onClick={() => handleNavigate(\"/organizations\")}\n className=\"text-sm text-primary hover:underline flex items-center gap-1\"\n >\n {tr(\"devportal.viewAll\", \"View all\")} <ArrowRight size={14} />\n </button>\n }\n >\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {organizations\n .slice(0, 3)\n .map((org: OrganizationFieldsFragment) => (\n <OrgCard\n key={org.id}\n org={org as DeveloperOrganization}\n onClick={() => handleNavigate(`/organizations/${org.id}`)}\n />\n ))}\n </div>\n </PageSection>\n ) : null}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// Quick action card component\nconst QuickActionCard: FC<{\n title: string;\n description: string;\n icon: React.ReactNode;\n onClick: () => void;\n primary?: boolean;\n}> = ({ title, description, icon, onClick, primary }) => (\n <button\n onClick={onClick}\n className={[\n \"flex items-center gap-4 rounded-lg border p-4 text-left transition-colors\",\n primary\n ? \"border-primary bg-primary/5 hover:bg-primary/10\"\n : \"bg-card hover:bg-accent\",\n ].join(\" \")}\n >\n <div\n className={[\n \"rounded-lg p-2\",\n primary ? \"bg-primary/20 text-primary\" : \"bg-primary/10 text-primary\",\n ].join(\" \")}\n >\n {icon}\n </div>\n <div>\n <p className=\"font-medium\">{title}</p>\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n </div>\n </button>\n);\n\n// Organization card component\nconst OrgCard: FC<{\n org: DeveloperOrganization;\n onClick: () => void;\n}> = ({ org, onClick }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n return (\n <button\n onClick={onClick}\n className=\"rounded-lg border bg-card p-4 text-left hover:bg-accent transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n {org.logoUrl ? (\n <img\n src={org.logoUrl}\n alt={org.name}\n className=\"h-10 w-10 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <Building2 size={20} />\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium truncate\">{org.name}</p>\n <p className=\"text-sm text-muted-foreground\">\n {org.publishedApps}{\" \"}\n {tr(\"devportal.appsPublished\", \"apps published\")}\n </p>\n </div>\n </div>\n <div className=\"mt-3 flex gap-4 text-sm text-muted-foreground\">\n <span>\n {(org.totalInstalls || 0).toLocaleString()}{\" \"}\n {tr(\"devportal.installs\", \"installs\")}\n </span>\n <span>\n ${(org.totalRevenue || 0).toLocaleString()}{\" \"}\n {tr(\"devportal.revenue\", \"revenue\")}\n </span>\n </div>\n </button>\n );\n};\n"],"mappings":"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"}