@burdenoff/microfe-devportal 2026.830.1 → 2026.831.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 (104) hide show
  1. package/dist/devportal/AdminDevportalRoot.d.ts.map +1 -1
  2. package/dist/devportal/AdminDevportalRoot.js +16 -19
  3. package/dist/devportal/AdminDevportalRoot.js.map +1 -1
  4. package/dist/devportal/DevportalRoot.d.ts.map +1 -1
  5. package/dist/devportal/DevportalRoot.js +36 -39
  6. package/dist/devportal/DevportalRoot.js.map +1 -1
  7. package/dist/devportal/components/AppCard.js +41 -41
  8. package/dist/devportal/components/ConfirmDialog.d.ts.map +1 -1
  9. package/dist/devportal/components/ConfirmDialog.js +19 -22
  10. package/dist/devportal/components/ConfirmDialog.js.map +1 -1
  11. package/dist/devportal/components/DataTable.d.ts.map +1 -1
  12. package/dist/devportal/components/DataTable.js +31 -34
  13. package/dist/devportal/components/DataTable.js.map +1 -1
  14. package/dist/devportal/components/FeatureFlaggedRoute.js +8 -8
  15. package/dist/devportal/components/FormField.d.ts.map +1 -1
  16. package/dist/devportal/components/FormField.js +26 -32
  17. package/dist/devportal/components/FormField.js.map +1 -1
  18. package/dist/devportal/components/GrantDelegationModal.js +64 -64
  19. package/dist/devportal/components/GrantDelegationModal.js.map +1 -1
  20. package/dist/devportal/components/LoadingState.d.ts.map +1 -1
  21. package/dist/devportal/components/LoadingState.js +5 -8
  22. package/dist/devportal/components/LoadingState.js.map +1 -1
  23. package/dist/devportal/components/PageLayout.d.ts.map +1 -1
  24. package/dist/devportal/components/PageLayout.js +10 -13
  25. package/dist/devportal/components/PageLayout.js.map +1 -1
  26. package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
  27. package/dist/devportal/components/PermissionGuard.js +11 -14
  28. package/dist/devportal/components/PermissionGuard.js.map +1 -1
  29. package/dist/devportal/components/SecretDisplay.d.ts.map +1 -1
  30. package/dist/devportal/components/SecretDisplay.js +24 -30
  31. package/dist/devportal/components/SecretDisplay.js.map +1 -1
  32. package/dist/devportal/components/SectionNav.d.ts.map +1 -1
  33. package/dist/devportal/components/SectionNav.js +24 -27
  34. package/dist/devportal/components/SectionNav.js.map +1 -1
  35. package/dist/devportal/components/StatusBadge.d.ts.map +1 -1
  36. package/dist/devportal/components/StatusBadge.js +24 -33
  37. package/dist/devportal/components/StatusBadge.js.map +1 -1
  38. package/dist/devportal/index.d.ts +1 -0
  39. package/dist/devportal/index.d.ts.map +1 -1
  40. package/dist/devportal/index.js +1 -0
  41. package/dist/devportal/pages/AdminReviewPage.js +172 -172
  42. package/dist/devportal/pages/AnalyticsDashboardPage.js +43 -43
  43. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  44. package/dist/devportal/pages/ApiKeysPage.js +119 -119
  45. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  46. package/dist/devportal/pages/AppLogsPage.js +45 -45
  47. package/dist/devportal/pages/ApplicationDetailPage.js +607 -607
  48. package/dist/devportal/pages/ApplicationVersionsPage.js +13 -13
  49. package/dist/devportal/pages/ApplicationsPage.d.ts.map +1 -1
  50. package/dist/devportal/pages/ApplicationsPage.js +104 -101
  51. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  52. package/dist/devportal/pages/CreateApiKeyPage.js +45 -45
  53. package/dist/devportal/pages/CreateApplicationPage.js +38 -38
  54. package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
  55. package/dist/devportal/pages/CreateOAuthClientPage.js +52 -52
  56. package/dist/devportal/pages/CreateOrganizationPage.js +26 -26
  57. package/dist/devportal/pages/CreateWebhookPage.d.ts.map +1 -1
  58. package/dist/devportal/pages/CreateWebhookPage.js +48 -48
  59. package/dist/devportal/pages/CreateWebhookPage.js.map +1 -1
  60. package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
  61. package/dist/devportal/pages/DashboardPage.js +66 -72
  62. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  63. package/dist/devportal/pages/DelegationsPage.js +174 -174
  64. package/dist/devportal/pages/DocumentationPage.js +93 -93
  65. package/dist/devportal/pages/EditApplicationPage.js +14 -14
  66. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  67. package/dist/devportal/pages/ListingPreviewPage.js +76 -76
  68. package/dist/devportal/pages/OAuthClientDetailPage.js +75 -75
  69. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  70. package/dist/devportal/pages/OAuthClientsPage.js +64 -64
  71. package/dist/devportal/pages/OrganizationDetailPage.js +189 -189
  72. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  73. package/dist/devportal/pages/OrganizationMembersPage.js +10 -10
  74. package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
  75. package/dist/devportal/pages/OrganizationsPage.js +163 -154
  76. package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
  77. package/dist/devportal/pages/PublishPage.js +104 -104
  78. package/dist/devportal/pages/PublishPage.js.map +1 -1
  79. package/dist/devportal/pages/PublisherProfilePage.js +55 -55
  80. package/dist/devportal/pages/ResourcesPage.js +60 -60
  81. package/dist/devportal/pages/RevenueDashboardPage.js +60 -60
  82. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  83. package/dist/devportal/pages/SellerDashboardPage.js +83 -83
  84. package/dist/devportal/pages/SellerItemsPage.js +163 -163
  85. package/dist/devportal/pages/SellerItemsPage.js.map +1 -1
  86. package/dist/devportal/pages/SellerOrdersPage.js +63 -63
  87. package/dist/devportal/pages/SettingsPage.js +21 -21
  88. package/dist/devportal/pages/SetupPage.js +183 -183
  89. package/dist/devportal/pages/SetupPage.js.map +1 -1
  90. package/dist/devportal/pages/StoreSubmissionPage.js +5 -5
  91. package/dist/devportal/pages/WebhookDetailPage.js +123 -123
  92. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  93. package/dist/devportal/pages/WebhooksPage.js +118 -118
  94. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  95. package/dist/devportal/utils/i18n.d.ts +9 -2
  96. package/dist/devportal/utils/i18n.d.ts.map +1 -1
  97. package/dist/devportal/utils/i18n.js +13 -10
  98. package/dist/devportal/utils/i18n.js.map +1 -1
  99. package/dist/index.js +2 -1
  100. package/dist/translations/en.d.ts +1251 -0
  101. package/dist/translations/en.d.ts.map +1 -0
  102. package/dist/translations/en.js +1235 -0
  103. package/dist/translations/en.js.map +1 -0
  104. package/package.json +2 -2
@@ -1,68 +1,65 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
- import { EmptyState as t } from "../components/EmptyState.js";
3
- import { useGetMyOrganizationsQuery as n } from "../../generated/global-operations.js";
4
- import { getErrorMessage as r } from "../hooks/useGraphQL.js";
5
- import { PageLayout as i } from "../components/PageLayout.js";
6
- import { StatusBadge as a, VerifiedBadge as o } from "../components/StatusBadge.js";
7
- import { PermissionGuard as s } from "../components/PermissionGuard.js";
2
+ import { useTr as t } from "../utils/i18n.js";
3
+ import { EmptyState as n } from "../components/EmptyState.js";
4
+ import { useGetMyOrganizationsQuery as r } from "../../generated/global-operations.js";
5
+ import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
+ import { PageLayout as a } from "../components/PageLayout.js";
7
+ import { StatusBadge as o, VerifiedBadge as s } from "../components/StatusBadge.js";
8
+ import { PermissionGuard as c } from "../components/PermissionGuard.js";
8
9
  import "../components/index.js";
9
10
  import "../hooks/index.js";
10
- import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
11
  import { AlertCircle as l, AppWindow as u, Building2 as d, CheckCircle as f, DollarSign as p, Loader2 as m, Plus as h, Users as g } from "lucide-react";
12
12
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
13
13
  import { EmphasisPanel as y, GlassCard as b } from "@burdenoff/fe-libs/ui";
14
14
  //#region src/devportal/pages/OrganizationsPage.tsx
15
15
  var x = () => {
16
- let { navigate: a, basePath: o } = e(), { t: u } = c(), d = (e, t) => {
17
- let n = u(e);
18
- return n === e ? t : n;
19
- }, { data: f, loading: p, error: g, refetch: x } = n({ fetchPolicy: "cache-and-network" }), C = f?.myDeveloperOrganizations ?? [], w = (e) => {
20
- a?.(`${o}${e}`);
16
+ let { navigate: o, basePath: s } = e(), u = t(), { data: d, loading: f, error: p, refetch: g } = r({ fetchPolicy: "cache-and-network" }), x = d?.myDeveloperOrganizations ?? [], C = (e) => {
17
+ o?.(`${s}${e}`);
21
18
  };
22
- return p && !f ? /* @__PURE__ */ _(i, {
23
- title: d("devportal.developerOrganizations", "Developer Organizations"),
24
- description: d("devportal.manageYourDevTeams", "Manage your development teams"),
19
+ return f && !d ? /* @__PURE__ */ _(a, {
20
+ title: u("devportal.developerOrganizations", "Developer Organizations"),
21
+ description: u("devportal.manageYourDevTeams", "Manage your development teams"),
25
22
  children: /* @__PURE__ */ v("div", {
26
23
  className: "flex items-center justify-center py-12",
27
24
  children: [/* @__PURE__ */ _(m, { className: "h-8 w-8 animate-spin text-text-secondary" }), /* @__PURE__ */ _("span", {
28
25
  className: "ml-2 text-text-secondary",
29
- children: d("devportal.loadingOrganizations", "Loading organizations...")
26
+ children: u("devportal.loadingOrganizations", "Loading organizations...")
30
27
  })]
31
28
  })
32
- }) : g ? /* @__PURE__ */ _(i, {
33
- title: d("devportal.developerOrganizations", "Developer Organizations"),
34
- description: d("devportal.manageYourDevTeams", "Manage your development teams"),
29
+ }) : p ? /* @__PURE__ */ _(a, {
30
+ title: u("devportal.developerOrganizations", "Developer Organizations"),
31
+ description: u("devportal.manageYourDevTeams", "Manage your development teams"),
35
32
  children: /* @__PURE__ */ v("div", {
36
33
  className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
37
34
  children: [
38
35
  /* @__PURE__ */ _(l, { className: "mx-auto h-8 w-8 text-status-error-text" }),
39
36
  /* @__PURE__ */ _("h3", {
40
37
  className: "mt-2 font-medium text-status-error-text",
41
- children: d("devportal.failedToLoadOrganizations", "Failed to load organizations")
38
+ children: u("devportal.failedToLoadOrganizations", "Failed to load organizations")
42
39
  }),
43
40
  /* @__PURE__ */ _("p", {
44
41
  className: "mt-1 text-sm text-text-secondary",
45
- children: r(g)
42
+ children: i(p)
46
43
  }),
47
44
  /* @__PURE__ */ _("button", {
48
- onClick: () => x(),
45
+ onClick: () => g(),
49
46
  className: "mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
50
- children: d("devportal.tryAgain", "Try Again")
47
+ children: u("devportal.tryAgain", "Try Again")
51
48
  })
52
49
  ]
53
50
  })
54
- }) : /* @__PURE__ */ _(s, {
51
+ }) : /* @__PURE__ */ _(c, {
55
52
  authOnly: !0,
56
- children: /* @__PURE__ */ v(i, {
57
- title: d("devportal.developerOrganizations", "Developer Organizations"),
58
- description: d("devportal.manageYourDevTeams", "Manage your development teams"),
59
- purpose: d("devportal.organizationsPurpose", "An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation."),
53
+ children: /* @__PURE__ */ v(a, {
54
+ title: u("devportal.developerOrganizations", "Developer Organizations"),
55
+ description: u("devportal.manageYourDevTeams", "Manage your development teams"),
56
+ purpose: u("devportal.organizationsPurpose", "An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation."),
60
57
  actions: /* @__PURE__ */ v("button", {
61
- onClick: () => w("/organizations/new"),
58
+ onClick: () => C("/organizations/new"),
62
59
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors",
63
- children: [/* @__PURE__ */ _(h, { size: 16 }), d("devportal.createOrganization", "Create Organization")]
60
+ children: [/* @__PURE__ */ _(h, { size: 16 }), u("devportal.createOrganization", "Create Organization")]
64
61
  }),
65
- children: [C.length > 0 && /* @__PURE__ */ _(y, {
62
+ children: [x.length > 0 && /* @__PURE__ */ _(y, {
66
63
  className: "mb-6",
67
64
  children: /* @__PURE__ */ v("div", {
68
65
  className: "grid grid-cols-2 gap-4 sm:grid-cols-3",
@@ -72,10 +69,10 @@ var x = () => {
72
69
  className: "p-4",
73
70
  children: [/* @__PURE__ */ _("p", {
74
71
  className: "text-sm text-text-secondary",
75
- children: d("devportal.organizations", "Organizations")
72
+ children: u("devportal.organizations", "Organizations")
76
73
  }), /* @__PURE__ */ _("p", {
77
74
  className: "mt-1 text-2xl font-semibold tabular-nums",
78
- children: C.length
75
+ children: x.length
79
76
  })]
80
77
  }),
81
78
  /* @__PURE__ */ v(b, {
@@ -83,10 +80,10 @@ var x = () => {
83
80
  className: "p-4",
84
81
  children: [/* @__PURE__ */ _("p", {
85
82
  className: "text-sm text-text-secondary",
86
- children: d("devportal.totalApps", "Total Apps")
83
+ children: u("devportal.totalApps", "Total Apps")
87
84
  }), /* @__PURE__ */ _("p", {
88
85
  className: "mt-1 text-2xl font-semibold tabular-nums",
89
- children: C.reduce((e, t) => e + (t.totalApps ?? 0), 0)
86
+ children: x.reduce((e, t) => e + (t.totalApps ?? 0), 0)
90
87
  })]
91
88
  }),
92
89
  /* @__PURE__ */ v(b, {
@@ -94,146 +91,158 @@ var x = () => {
94
91
  className: "p-4",
95
92
  children: [/* @__PURE__ */ _("p", {
96
93
  className: "text-sm text-text-secondary",
97
- children: d("devportal.activeInstalls", "Active Installs")
94
+ children: u("devportal.activeInstalls", "Active Installs")
98
95
  }), /* @__PURE__ */ _("p", {
99
96
  className: "mt-1 text-2xl font-semibold tabular-nums",
100
- children: C.reduce((e, t) => e + (t.activeInstalls ?? 0), 0).toLocaleString()
97
+ children: x.reduce((e, t) => e + (t.activeInstalls ?? 0), 0).toLocaleString()
101
98
  })]
102
99
  })
103
100
  ]
104
101
  })
105
- }), C.length > 0 ? /* @__PURE__ */ _("div", {
102
+ }), x.length > 0 ? /* @__PURE__ */ _("div", {
106
103
  className: "grid gap-6",
107
- children: C.map((e) => /* @__PURE__ */ _(S, {
104
+ children: x.map((e) => /* @__PURE__ */ _(S, {
108
105
  org: e,
109
- onClick: () => w(`/organizations/${e.id}`)
106
+ onClick: () => C(`/organizations/${e.id}`)
110
107
  }, e.id))
111
- }) : /* @__PURE__ */ _(t, {
108
+ }) : /* @__PURE__ */ _(n, {
112
109
  illustration: "empty-people",
113
- title: d("devportal.noOrganizationsYet", "No organizations yet"),
114
- description: d("devportal.createOrgToCollaborate", "Create an organization to collaborate with your team and manage apps together"),
110
+ title: u("devportal.noOrganizationsYet", "No organizations yet"),
111
+ description: u("devportal.createOrgToCollaborate", "Create an organization to collaborate with your team and manage apps together"),
115
112
  action: /* @__PURE__ */ v("button", {
116
- onClick: () => w("/organizations/new"),
113
+ onClick: () => C("/organizations/new"),
117
114
  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",
118
- children: [/* @__PURE__ */ _(h, { size: 16 }), d("devportal.createOrganization", "Create Organization")]
115
+ children: [/* @__PURE__ */ _(h, { size: 16 }), u("devportal.createOrganization", "Create Organization")]
119
116
  })
120
117
  })]
121
118
  })
122
119
  });
123
- }, S = ({ org: e, onClick: t }) => /* @__PURE__ */ v("div", {
124
- role: "button",
125
- tabIndex: 0,
126
- onClick: t,
127
- onKeyDown: (e) => {
128
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), t());
129
- },
130
- className: "cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
131
- children: [/* @__PURE__ */ v("div", {
132
- className: "flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
120
+ }, S = ({ org: e, onClick: n }) => {
121
+ let r = t();
122
+ return /* @__PURE__ */ v("div", {
123
+ role: "button",
124
+ tabIndex: 0,
125
+ onClick: n,
126
+ onKeyDown: (e) => {
127
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), n());
128
+ },
129
+ className: "cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
133
130
  children: [/* @__PURE__ */ v("div", {
134
- className: "flex items-start gap-4",
135
- children: [e.logoUrl ? /* @__PURE__ */ _("img", {
136
- src: e.logoUrl,
137
- alt: e.name,
138
- className: "h-16 w-16 rounded-lg object-cover"
139
- }) : /* @__PURE__ */ _("div", {
140
- className: "flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary",
141
- children: /* @__PURE__ */ _(d, { size: 32 })
142
- }), /* @__PURE__ */ v("div", { children: [
143
- /* @__PURE__ */ v("div", {
144
- className: "flex items-center gap-2 flex-wrap",
145
- children: [
146
- /* @__PURE__ */ _("h3", {
147
- className: "text-lg font-semibold",
148
- children: e.name
149
- }),
150
- e.isVerified && /* @__PURE__ */ _(o, { verified: !0 }),
151
- e.isCertified && /* @__PURE__ */ v("span", {
152
- className: "inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text",
153
- children: [/* @__PURE__ */ _(f, { size: 12 }), " Certified"]
154
- })
155
- ]
156
- }),
157
- e.description && /* @__PURE__ */ _("p", {
158
- className: "mt-1 text-sm text-text-secondary",
159
- children: e.description
160
- }),
161
- /* @__PURE__ */ v("div", {
162
- className: "mt-2 flex flex-wrap items-center gap-2",
163
- children: [/* @__PURE__ */ _(a, {
164
- status: e.tier,
165
- type: "tier"
166
- }), e.partnerTier && /* @__PURE__ */ _(a, {
167
- status: e.partnerTier,
168
- type: "partner"
169
- })]
170
- })
171
- ] })]
131
+ className: "flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
132
+ children: [/* @__PURE__ */ v("div", {
133
+ className: "flex items-start gap-4",
134
+ children: [e.logoUrl ? /* @__PURE__ */ _("img", {
135
+ src: e.logoUrl,
136
+ alt: e.name,
137
+ className: "h-16 w-16 rounded-lg object-cover"
138
+ }) : /* @__PURE__ */ _("div", {
139
+ className: "flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary",
140
+ children: /* @__PURE__ */ _(d, { size: 32 })
141
+ }), /* @__PURE__ */ v("div", { children: [
142
+ /* @__PURE__ */ v("div", {
143
+ className: "flex items-center gap-2 flex-wrap",
144
+ children: [
145
+ /* @__PURE__ */ _("h3", {
146
+ className: "text-lg font-semibold",
147
+ children: e.name
148
+ }),
149
+ e.isVerified && /* @__PURE__ */ _(s, { verified: !0 }),
150
+ e.isCertified && /* @__PURE__ */ v("span", {
151
+ className: "inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text",
152
+ children: [
153
+ /* @__PURE__ */ _(f, { size: 12 }),
154
+ " ",
155
+ r("devportal.certified", "Certified")
156
+ ]
157
+ })
158
+ ]
159
+ }),
160
+ e.description && /* @__PURE__ */ _("p", {
161
+ className: "mt-1 text-sm text-text-secondary",
162
+ children: e.description
163
+ }),
164
+ /* @__PURE__ */ v("div", {
165
+ className: "mt-2 flex flex-wrap items-center gap-2",
166
+ children: [/* @__PURE__ */ _(o, {
167
+ status: e.tier,
168
+ type: "tier"
169
+ }), e.partnerTier && /* @__PURE__ */ _(o, {
170
+ status: e.partnerTier,
171
+ type: "partner"
172
+ })]
173
+ })
174
+ ] })]
175
+ }), /* @__PURE__ */ v("div", {
176
+ className: "flex flex-wrap gap-6 text-sm",
177
+ children: [
178
+ /* @__PURE__ */ v("div", {
179
+ className: "flex items-center gap-2",
180
+ children: [/* @__PURE__ */ _(g, {
181
+ size: 16,
182
+ className: "text-text-secondary"
183
+ }), /* @__PURE__ */ v("span", { children: [
184
+ e.members?.length || 0,
185
+ " ",
186
+ r("devportal.membersLower", "members")
187
+ ] })]
188
+ }),
189
+ /* @__PURE__ */ v("div", {
190
+ className: "flex items-center gap-2",
191
+ children: [/* @__PURE__ */ _(u, {
192
+ size: 16,
193
+ className: "text-text-secondary"
194
+ }), /* @__PURE__ */ v("span", { children: [
195
+ e.publishedApps,
196
+ " / ",
197
+ e.totalApps,
198
+ " ",
199
+ r("devportal.appsLower", "apps")
200
+ ] })]
201
+ }),
202
+ /* @__PURE__ */ v("div", {
203
+ className: "flex items-center gap-2",
204
+ children: [/* @__PURE__ */ _(p, {
205
+ size: 16,
206
+ className: "text-text-secondary"
207
+ }), /* @__PURE__ */ v("span", { children: ["$", (e.totalRevenue || 0).toLocaleString()] })]
208
+ })
209
+ ]
210
+ })]
172
211
  }), /* @__PURE__ */ v("div", {
173
- className: "flex flex-wrap gap-6 text-sm",
212
+ className: "mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4",
174
213
  children: [
175
- /* @__PURE__ */ v("div", {
176
- className: "flex items-center gap-2",
177
- children: [/* @__PURE__ */ _(g, {
178
- size: 16,
179
- className: "text-text-secondary"
180
- }), /* @__PURE__ */ v("span", { children: [e.members?.length || 0, " members"] })]
181
- }),
182
- /* @__PURE__ */ v("div", {
183
- className: "flex items-center gap-2",
184
- children: [/* @__PURE__ */ _(u, {
185
- size: 16,
186
- className: "text-text-secondary"
187
- }), /* @__PURE__ */ v("span", { children: [
188
- e.publishedApps,
189
- " / ",
190
- e.totalApps,
191
- " apps"
192
- ] })]
193
- }),
194
- /* @__PURE__ */ v("div", {
195
- className: "flex items-center gap-2",
196
- children: [/* @__PURE__ */ _(p, {
197
- size: 16,
198
- className: "text-text-secondary"
199
- }), /* @__PURE__ */ v("span", { children: ["$", (e.totalRevenue || 0).toLocaleString()] })]
200
- })
214
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
215
+ className: "text-xs text-text-secondary",
216
+ children: r("devportal.totalInstalls", "Total Installs")
217
+ }), /* @__PURE__ */ _("p", {
218
+ className: "text-lg font-semibold",
219
+ children: (e.totalInstalls || 0).toLocaleString()
220
+ })] }),
221
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
222
+ className: "text-xs text-text-secondary",
223
+ children: r("devportal.activeInstalls", "Active Installs")
224
+ }), /* @__PURE__ */ _("p", {
225
+ className: "text-lg font-semibold",
226
+ children: (e.activeInstalls || 0).toLocaleString()
227
+ })] }),
228
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
229
+ className: "text-xs text-text-secondary",
230
+ children: r("devportal.apiCalls", "API Calls")
231
+ }), /* @__PURE__ */ _("p", {
232
+ className: "text-lg font-semibold",
233
+ children: e.totalApiCalls ? `${(parseInt(e.totalApiCalls) / 1e6).toFixed(1)}M` : "0"
234
+ })] }),
235
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
236
+ className: "text-xs text-text-secondary",
237
+ children: r("devportal.avgRating", "Avg Rating")
238
+ }), /* @__PURE__ */ _("p", {
239
+ className: "text-lg font-semibold",
240
+ children: e.averageRating ? `${e.averageRating.toFixed(1)} ★` : r("devportal.notAvailable", "N/A")
241
+ })] })
201
242
  ]
202
243
  })]
203
- }), /* @__PURE__ */ v("div", {
204
- className: "mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4",
205
- children: [
206
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
207
- className: "text-xs text-text-secondary",
208
- children: "Total Installs"
209
- }), /* @__PURE__ */ _("p", {
210
- className: "text-lg font-semibold",
211
- children: (e.totalInstalls || 0).toLocaleString()
212
- })] }),
213
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
214
- className: "text-xs text-text-secondary",
215
- children: "Active Installs"
216
- }), /* @__PURE__ */ _("p", {
217
- className: "text-lg font-semibold",
218
- children: (e.activeInstalls || 0).toLocaleString()
219
- })] }),
220
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
221
- className: "text-xs text-text-secondary",
222
- children: "API Calls"
223
- }), /* @__PURE__ */ _("p", {
224
- className: "text-lg font-semibold",
225
- children: e.totalApiCalls ? `${(parseInt(e.totalApiCalls) / 1e6).toFixed(1)}M` : "0"
226
- })] }),
227
- /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
228
- className: "text-xs text-text-secondary",
229
- children: "Avg Rating"
230
- }), /* @__PURE__ */ _("p", {
231
- className: "text-lg font-semibold",
232
- children: e.averageRating ? `${e.averageRating.toFixed(1)} ★` : "N/A"
233
- })] })
234
- ]
235
- })]
236
- });
244
+ });
245
+ };
237
246
  //#endregion
238
247
  export { x as OrganizationsPage };
239
248
 
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationsPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Building2,\n Users,\n AppWindow,\n DollarSign,\n CheckCircle,\n AlertCircle,\n Loader2,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatusBadge, VerifiedBadge } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport type { DeveloperOrganization } from \"../types\";\nimport {\n useGetMyOrganizationsQuery,\n getErrorMessage,\n type OrganizationFieldsFragment,\n} from \"../hooks\";\n\n/**\n * Organizations listing page\n *\n * Displays all developer organizations the current user is a member of.\n * Uses GraphQL to fetch real data from the DevPortal backend.\n */\nexport const OrganizationsPage: 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 organizations from GraphQL API\n const { data, loading, error, refetch } = useGetMyOrganizationsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const organizations = data?.myDeveloperOrganizations ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingOrganizations\", \"Loading organizations...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\n \"devportal.failedToLoadOrganizations\",\n \"Failed to load organizations\",\n )}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n purpose={tr(\n \"devportal.organizationsPurpose\",\n \"An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n >\n {organizations.length > 0 && (\n <EmphasisPanel className=\"mb-6\">\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.organizations\", \"Organizations\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.totalApps ?? 0),\n 0,\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations\n .reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.activeInstalls ?? 0),\n 0,\n )\n .toLocaleString()}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n )}\n {organizations.length > 0 ? (\n <div className=\"grid gap-6\">\n {organizations.map((org: OrganizationFieldsFragment) => (\n <OrganizationCard\n key={org.id}\n org={org as DeveloperOrganization}\n onClick={() => handleNavigate(`/organizations/${org.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noOrganizationsYet\", \"No organizations yet\")}\n description={tr(\n \"devportal.createOrgToCollaborate\",\n \"Create an organization to collaborate with your team and manage apps together\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// Organization card component\nconst OrganizationCard: FC<{\n org: DeveloperOrganization;\n onClick: () => void;\n}> = ({ org, onClick }) => {\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onClick();\n }\n }}\n className=\"cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n {/* Left side - Info */}\n <div className=\"flex items-start gap-4\">\n {org.logoUrl ? (\n <img\n src={org.logoUrl}\n alt={org.name}\n className=\"h-16 w-16 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary\">\n <Building2 size={32} />\n </div>\n )}\n <div>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h3 className=\"text-lg font-semibold\">{org.name}</h3>\n {org.isVerified && <VerifiedBadge verified />}\n {org.isCertified && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text\">\n <CheckCircle size={12} /> Certified\n </span>\n )}\n </div>\n {org.description && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {org.description}\n </p>\n )}\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <StatusBadge status={org.tier} type=\"tier\" />\n {org.partnerTier && (\n <StatusBadge status={org.partnerTier} type=\"partner\" />\n )}\n </div>\n </div>\n </div>\n\n {/* Right side - Stats */}\n <div className=\"flex flex-wrap gap-6 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Users size={16} className=\"text-text-secondary\" />\n <span>{org.members?.length || 0} members</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <AppWindow size={16} className=\"text-text-secondary\" />\n <span>\n {org.publishedApps} / {org.totalApps} apps\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <DollarSign size={16} className=\"text-text-secondary\" />\n <span>${(org.totalRevenue || 0).toLocaleString()}</span>\n </div>\n </div>\n </div>\n\n {/* Stats bar */}\n <div className=\"mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">Total Installs</p>\n <p className=\"text-lg font-semibold\">\n {(org.totalInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Active Installs</p>\n <p className=\"text-lg font-semibold\">\n {(org.activeInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">API Calls</p>\n <p className=\"text-lg font-semibold\">\n {org.totalApiCalls\n ? `${(parseInt(org.totalApiCalls) / 1000000).toFixed(1)}M`\n : \"0\"}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">Avg Rating</p>\n <p className=\"text-lg font-semibold\">\n {org.averageRating ? `${org.averageRating.toFixed(1)} ★` : \"N/A\"}\n </p>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OrganizationsPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport {\n Plus,\n Building2,\n Users,\n AppWindow,\n DollarSign,\n CheckCircle,\n AlertCircle,\n Loader2,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatusBadge, VerifiedBadge } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { useTr } from \"../utils/i18n\";\nimport type { DeveloperOrganization } from \"../types\";\nimport {\n useGetMyOrganizationsQuery,\n getErrorMessage,\n type OrganizationFieldsFragment,\n} from \"../hooks\";\n\n/**\n * Organizations listing page\n *\n * Displays all developer organizations the current user is a member of.\n * Uses GraphQL to fetch real data from the DevPortal backend.\n */\nexport const OrganizationsPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const tr = useTr();\n\n // Fetch organizations from GraphQL API\n const { data, loading, error, refetch } = useGetMyOrganizationsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const organizations = data?.myDeveloperOrganizations ?? [];\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Loading state\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingOrganizations\", \"Loading organizations...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error) {\n return (\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\n \"devportal.failedToLoadOrganizations\",\n \"Failed to load organizations\",\n )}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n <button\n onClick={() => refetch()}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\n \"devportal.developerOrganizations\",\n \"Developer Organizations\",\n )}\n description={tr(\n \"devportal.manageYourDevTeams\",\n \"Manage your development teams\",\n )}\n purpose={tr(\n \"devportal.organizationsPurpose\",\n \"An organization is the team that owns your apps, members, and revenue. Create one so collaborators can share access to the same applications, billing, and store presence instead of working in isolation.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n >\n {organizations.length > 0 && (\n <EmphasisPanel className=\"mb-6\">\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.organizations\", \"Organizations\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.totalApps\", \"Total Apps\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations.reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.totalApps ?? 0),\n 0,\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {organizations\n .reduce(\n (acc: number, org: OrganizationFieldsFragment) =>\n acc + (org.activeInstalls ?? 0),\n 0,\n )\n .toLocaleString()}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n )}\n {organizations.length > 0 ? (\n <div className=\"grid gap-6\">\n {organizations.map((org: OrganizationFieldsFragment) => (\n <OrganizationCard\n key={org.id}\n org={org as DeveloperOrganization}\n onClick={() => handleNavigate(`/organizations/${org.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noOrganizationsYet\", \"No organizations yet\")}\n description={tr(\n \"devportal.createOrgToCollaborate\",\n \"Create an organization to collaborate with your team and manage apps together\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/organizations/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </button>\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// Organization card component\nconst OrganizationCard: FC<{\n org: DeveloperOrganization;\n onClick: () => void;\n}> = ({ org, onClick }) => {\n const tr = useTr();\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onClick}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onClick();\n }\n }}\n className=\"cursor-pointer rounded-card border border-border-seam bg-bg-surface p-6 shadow-[var(--shadow-pop)] transition-[box-shadow,border-color] hover:shadow-[var(--shadow-pop-hover)] hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n {/* Left side - Info */}\n <div className=\"flex items-start gap-4\">\n {org.logoUrl ? (\n <img\n src={org.logoUrl}\n alt={org.name}\n className=\"h-16 w-16 rounded-lg object-cover\"\n />\n ) : (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-lg bg-action-primary-bg/10 text-primary\">\n <Building2 size={32} />\n </div>\n )}\n <div>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <h3 className=\"text-lg font-semibold\">{org.name}</h3>\n {org.isVerified && <VerifiedBadge verified />}\n {org.isCertified && (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-info-bg-subtle px-2 py-0.5 text-xs font-medium text-status-info-text\">\n <CheckCircle size={12} />{\" \"}\n {tr(\"devportal.certified\", \"Certified\")}\n </span>\n )}\n </div>\n {org.description && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {org.description}\n </p>\n )}\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <StatusBadge status={org.tier} type=\"tier\" />\n {org.partnerTier && (\n <StatusBadge status={org.partnerTier} type=\"partner\" />\n )}\n </div>\n </div>\n </div>\n\n {/* Right side - Stats */}\n <div className=\"flex flex-wrap gap-6 text-sm\">\n <div className=\"flex items-center gap-2\">\n <Users size={16} className=\"text-text-secondary\" />\n <span>\n {org.members?.length || 0}{\" \"}\n {tr(\"devportal.membersLower\", \"members\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <AppWindow size={16} className=\"text-text-secondary\" />\n <span>\n {org.publishedApps} / {org.totalApps}{\" \"}\n {tr(\"devportal.appsLower\", \"apps\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <DollarSign size={16} className=\"text-text-secondary\" />\n <span>${(org.totalRevenue || 0).toLocaleString()}</span>\n </div>\n </div>\n </div>\n\n {/* Stats bar */}\n <div className=\"mt-4 grid grid-cols-2 gap-4 rounded-lg bg-bg-sunken/50 p-4 sm:grid-cols-4\">\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.totalInstalls\", \"Total Installs\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {(org.totalInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.activeInstalls\", \"Active Installs\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {(org.activeInstalls || 0).toLocaleString()}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.apiCalls\", \"API Calls\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {org.totalApiCalls\n ? `${(parseInt(org.totalApiCalls) / 1000000).toFixed(1)}M`\n : \"0\"}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.avgRating\", \"Avg Rating\")}\n </p>\n <p className=\"text-lg font-semibold\">\n {org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")}\n </p>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}