@burdenoff/microfe-devportal 2026.629.3 → 2026.629.5
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.
|
@@ -80,100 +80,102 @@ function V(e) {
|
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
var H = () => {
|
|
83
|
-
let { navigate: n, basePath: a } = e(), { orgId:
|
|
84
|
-
let n =
|
|
83
|
+
let { navigate: n, basePath: a, setActiveOrgId: s } = e(), { orgId: c } = P(), { t: l } = v(), u = (e, t) => {
|
|
84
|
+
let n = l(e);
|
|
85
85
|
return n === e ? t : n;
|
|
86
|
-
}, { allowed:
|
|
86
|
+
}, { allowed: d } = h(m.ORG_UPDATE), [f, p] = _("overview"), x = [
|
|
87
87
|
{
|
|
88
88
|
id: "overview",
|
|
89
|
-
label:
|
|
89
|
+
label: u("devportal.overview", "Overview"),
|
|
90
90
|
icon: C
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
93
|
id: "apps",
|
|
94
|
-
label:
|
|
94
|
+
label: u("devportal.applications", "Applications"),
|
|
95
95
|
icon: b
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
id: "members",
|
|
99
|
-
label:
|
|
99
|
+
label: u("devportal.members", "Members"),
|
|
100
100
|
icon: N
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
id: "settings",
|
|
104
|
-
label:
|
|
104
|
+
label: u("devportal.settings", "Settings"),
|
|
105
105
|
icon: A
|
|
106
106
|
}
|
|
107
|
-
], { data:
|
|
108
|
-
variables: { id:
|
|
109
|
-
skip: !
|
|
110
|
-
}),
|
|
107
|
+
], { data: S, previousData: w, loading: D, error: k } = i({
|
|
108
|
+
variables: { id: c },
|
|
109
|
+
skip: !c
|
|
110
|
+
}), j = S ?? w, { data: M } = r({
|
|
111
111
|
variables: {
|
|
112
112
|
limit: 50,
|
|
113
|
-
organizationId:
|
|
113
|
+
organizationId: c
|
|
114
114
|
},
|
|
115
|
-
skip: !
|
|
115
|
+
skip: !c,
|
|
116
116
|
fetchPolicy: "cache-and-network"
|
|
117
|
-
}),
|
|
117
|
+
}), F = (e) => {
|
|
118
118
|
n?.(`${a}${e}`);
|
|
119
119
|
};
|
|
120
120
|
if (g(() => {
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
c && s(c);
|
|
122
|
+
}, [c, s]), g(() => {
|
|
123
|
+
let e = j?.developerOrganization?.name;
|
|
124
|
+
if (!c || !e) return;
|
|
123
125
|
let t = window.__breadcrumbRegistry;
|
|
124
|
-
return t?.register(
|
|
125
|
-
}, [
|
|
126
|
-
title:
|
|
126
|
+
return t?.register(c, e), () => t?.unregister(c);
|
|
127
|
+
}, [c, S?.developerOrganization?.name]), D && !j) return /* @__PURE__ */ I(o, {
|
|
128
|
+
title: u("devportal.loadingDots", "Loading..."),
|
|
127
129
|
backLink: `${a}/organizations`,
|
|
128
|
-
backLabel:
|
|
130
|
+
backLabel: u("devportal.backToOrganizations", "Back to Organizations"),
|
|
129
131
|
children: /* @__PURE__ */ I("div", {
|
|
130
132
|
className: "flex items-center justify-center py-12",
|
|
131
133
|
children: /* @__PURE__ */ I(O, { className: "h-8 w-8 animate-spin text-text-secondary" })
|
|
132
134
|
})
|
|
133
135
|
});
|
|
134
|
-
if (
|
|
135
|
-
title:
|
|
136
|
+
if (k || !j?.developerOrganization) return /* @__PURE__ */ I(o, {
|
|
137
|
+
title: u("devportal.organizationNotFound", "Organization Not Found"),
|
|
136
138
|
backLink: `${a}/organizations`,
|
|
137
|
-
backLabel:
|
|
139
|
+
backLabel: u("devportal.backToOrganizations", "Back to Organizations"),
|
|
138
140
|
children: /* @__PURE__ */ L("div", {
|
|
139
141
|
className: "flex flex-col items-center justify-center py-12 gap-4",
|
|
140
142
|
children: [
|
|
141
143
|
/* @__PURE__ */ I(y, { className: "h-12 w-12 text-status-error-text" }),
|
|
142
144
|
/* @__PURE__ */ I("h2", {
|
|
143
145
|
className: "text-lg font-semibold",
|
|
144
|
-
children:
|
|
146
|
+
children: u("devportal.organizationNotFoundLower", "Organization not found")
|
|
145
147
|
}),
|
|
146
148
|
/* @__PURE__ */ I("p", {
|
|
147
149
|
className: "text-text-secondary",
|
|
148
|
-
children:
|
|
150
|
+
children: k?.message || u("devportal.organizationNotFoundDescription", "The organization you're looking for doesn't exist or you don't have access to it.")
|
|
149
151
|
}),
|
|
150
152
|
/* @__PURE__ */ I("button", {
|
|
151
|
-
onClick: () =>
|
|
153
|
+
onClick: () => F("/organizations"),
|
|
152
154
|
className: "mt-4 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",
|
|
153
|
-
children:
|
|
155
|
+
children: u("devportal.backToOrganizations", "Back to Organizations")
|
|
154
156
|
})
|
|
155
157
|
]
|
|
156
158
|
})
|
|
157
159
|
});
|
|
158
|
-
let
|
|
160
|
+
let R = B(j.developerOrganization), H = (j.developerOrganization.members ?? []).map(V), q = M?.applications?.edges?.map((e) => e.node) ?? [], J = parseInt(R.apiCallsUsed) / R.apiCallsLimit * 100, Y = parseInt(R.storageUsed) / parseInt(R.storageLimit) * 100;
|
|
159
161
|
return /* @__PURE__ */ L(o, {
|
|
160
|
-
title:
|
|
161
|
-
description:
|
|
162
|
-
purpose:
|
|
162
|
+
title: R.name,
|
|
163
|
+
description: R.description,
|
|
164
|
+
purpose: u("devportal.orgDetailPurpose", "This is the home for one organization — the apps it owns, the people who can work on them, and its store and billing settings. Invite teammates, add apps, and verify the org so your published listings look trustworthy."),
|
|
163
165
|
backLink: `${a}/organizations`,
|
|
164
|
-
backLabel:
|
|
166
|
+
backLabel: u("devportal.backToOrganizations", "Back to Organizations"),
|
|
165
167
|
actions: /* @__PURE__ */ L("div", {
|
|
166
168
|
className: "flex items-center gap-2",
|
|
167
169
|
children: [/* @__PURE__ */ L("button", {
|
|
168
|
-
onClick: () => n?.(`/billing/earnings?developerOrgId=${encodeURIComponent(
|
|
170
|
+
onClick: () => n?.(`/billing/earnings?developerOrgId=${encodeURIComponent(R.id)}&developerOrgName=${encodeURIComponent(R.name)}`),
|
|
169
171
|
className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors",
|
|
170
|
-
children: [/* @__PURE__ */ I(T, { size: 16 }),
|
|
172
|
+
children: [/* @__PURE__ */ I(T, { size: 16 }), u("devportal.revenue", "Revenue")]
|
|
171
173
|
}), /* @__PURE__ */ L("button", {
|
|
172
|
-
onClick: () =>
|
|
173
|
-
disabled: !
|
|
174
|
-
"aria-disabled": !
|
|
174
|
+
onClick: () => p("settings"),
|
|
175
|
+
disabled: !d,
|
|
176
|
+
"aria-disabled": !d,
|
|
175
177
|
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 disabled:opacity-50",
|
|
176
|
-
children: [/* @__PURE__ */ I(E, { size: 16 }),
|
|
178
|
+
children: [/* @__PURE__ */ I(E, { size: 16 }), u("devportal.settings", "Settings")]
|
|
177
179
|
})]
|
|
178
180
|
}),
|
|
179
181
|
children: [
|
|
@@ -182,16 +184,16 @@ var H = () => {
|
|
|
182
184
|
children: /* @__PURE__ */ I("nav", {
|
|
183
185
|
className: "-mb-px flex gap-4 overflow-x-auto",
|
|
184
186
|
role: "tablist",
|
|
185
|
-
"aria-label":
|
|
186
|
-
children:
|
|
187
|
+
"aria-label": u("devportal.organizationSections", "Organization sections"),
|
|
188
|
+
children: x.map((e) => {
|
|
187
189
|
let n = e.icon;
|
|
188
190
|
return /* @__PURE__ */ L("button", {
|
|
189
191
|
id: `organization-tab-${e.id}`,
|
|
190
192
|
role: "tab",
|
|
191
|
-
"aria-selected":
|
|
193
|
+
"aria-selected": f === e.id,
|
|
192
194
|
"aria-controls": `organization-panel-${e.id}`,
|
|
193
|
-
onClick: () =>
|
|
194
|
-
className: t("flex items-center gap-2 border-b-2 px-1 py-3 text-sm font-medium transition-colors",
|
|
195
|
+
onClick: () => p(e.id),
|
|
196
|
+
className: t("flex items-center gap-2 border-b-2 px-1 py-3 text-sm font-medium transition-colors", f === e.id ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary hover:border-muted-foreground"),
|
|
195
197
|
children: [/* @__PURE__ */ I(n, { size: 16 }), e.label]
|
|
196
198
|
}, e.id);
|
|
197
199
|
})
|
|
@@ -199,58 +201,58 @@ var H = () => {
|
|
|
199
201
|
}),
|
|
200
202
|
/* @__PURE__ */ I(z, {
|
|
201
203
|
className: "mt-6",
|
|
202
|
-
storageKey: `devportal-org-${
|
|
204
|
+
storageKey: `devportal-org-${R.id}`,
|
|
203
205
|
steps: [
|
|
204
206
|
{
|
|
205
207
|
id: "invite-members",
|
|
206
|
-
label:
|
|
207
|
-
description:
|
|
208
|
+
label: u("devportal.inviteMembers", "Invite members"),
|
|
209
|
+
description: u("devportal.orgStepInvite", "Add teammates so they can build alongside you"),
|
|
208
210
|
icon: /* @__PURE__ */ I(N, { size: 16 }),
|
|
209
|
-
onClick: () =>
|
|
211
|
+
onClick: () => p("members")
|
|
210
212
|
},
|
|
211
213
|
{
|
|
212
214
|
id: "create-app",
|
|
213
|
-
label:
|
|
214
|
-
description:
|
|
215
|
+
label: u("devportal.createApp", "Create App"),
|
|
216
|
+
description: u("devportal.orgStepCreateApp", "Build a new application under this organization"),
|
|
215
217
|
icon: /* @__PURE__ */ I(b, { size: 16 }),
|
|
216
|
-
onClick: () =>
|
|
218
|
+
onClick: () => F("/apps/new")
|
|
217
219
|
},
|
|
218
220
|
{
|
|
219
221
|
id: "settings",
|
|
220
|
-
label:
|
|
221
|
-
description:
|
|
222
|
+
label: u("devportal.orgStepVerify", "Complete organization profile"),
|
|
223
|
+
description: u("devportal.orgStepVerifyDesc", "Add a logo and details, then request verification"),
|
|
222
224
|
icon: /* @__PURE__ */ I(E, { size: 16 }),
|
|
223
|
-
onClick: () =>
|
|
224
|
-
done: !!
|
|
225
|
+
onClick: () => p("settings"),
|
|
226
|
+
done: !!R.isVerified
|
|
225
227
|
}
|
|
226
228
|
]
|
|
227
229
|
}),
|
|
228
230
|
/* @__PURE__ */ L("div", {
|
|
229
231
|
className: "mt-6",
|
|
230
|
-
id: `organization-panel-${
|
|
232
|
+
id: `organization-panel-${f}`,
|
|
231
233
|
role: "tabpanel",
|
|
232
|
-
"aria-labelledby": `organization-tab-${
|
|
234
|
+
"aria-labelledby": `organization-tab-${f}`,
|
|
233
235
|
tabIndex: 0,
|
|
234
236
|
children: [
|
|
235
|
-
|
|
236
|
-
org:
|
|
237
|
-
apps:
|
|
238
|
-
members:
|
|
239
|
-
apiCallsPercent:
|
|
240
|
-
storagePercent:
|
|
241
|
-
onNavigate:
|
|
242
|
-
onShowApps: () =>
|
|
237
|
+
f === "overview" && /* @__PURE__ */ I(U, {
|
|
238
|
+
org: R,
|
|
239
|
+
apps: q,
|
|
240
|
+
members: H,
|
|
241
|
+
apiCallsPercent: J,
|
|
242
|
+
storagePercent: Y,
|
|
243
|
+
onNavigate: F,
|
|
244
|
+
onShowApps: () => p("apps")
|
|
243
245
|
}),
|
|
244
|
-
|
|
245
|
-
apps:
|
|
246
|
-
onNavigate:
|
|
246
|
+
f === "apps" && /* @__PURE__ */ I(W, {
|
|
247
|
+
apps: q,
|
|
248
|
+
onNavigate: F
|
|
247
249
|
}),
|
|
248
|
-
|
|
249
|
-
members:
|
|
250
|
-
onNavigate:
|
|
251
|
-
orgId:
|
|
250
|
+
f === "members" && /* @__PURE__ */ I(G, {
|
|
251
|
+
members: H,
|
|
252
|
+
onNavigate: F,
|
|
253
|
+
orgId: R.id
|
|
252
254
|
}),
|
|
253
|
-
|
|
255
|
+
f === "settings" && /* @__PURE__ */ I(K, { org: R })
|
|
254
256
|
]
|
|
255
257
|
})
|
|
256
258
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrganizationDetailPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState, useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Building2,\n Users,\n AppWindow,\n DollarSign,\n Settings,\n ExternalLink,\n CheckCircle,\n BarChart3,\n TrendingUp,\n ArrowRight,\n Plus,\n Edit,\n Shield,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { EmphasisPanel, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { DataTable, DetailList } from \"../components/DataTable\";\nimport { AppListItem } from \"../components/AppCard\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type {\n DeveloperOrganization,\n Application,\n DeveloperOrgMember,\n} from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport {\n useGetOrganizationQuery,\n useGetApplicationsQuery,\n useRequestOrgVerificationMutation,\n} from \"../../generated/global-operations\";\nimport type {\n OrganizationFieldsFragment,\n OrgMemberFieldsFragment,\n ApplicationFieldsFragment,\n} from \"../../generated/global-operations\";\n\n/**\n * Map GraphQL organization fragment to local type\n */\nfunction mapOrganization(\n org: OrganizationFieldsFragment,\n): DeveloperOrganization {\n return {\n id: org.id,\n name: org.name,\n slug: org.slug,\n description: org.description ?? undefined,\n logoUrl: org.logoUrl ?? undefined,\n bannerUrl: org.bannerUrl ?? undefined,\n websiteUrl: org.websiteUrl ?? undefined,\n contactEmail: org.contactEmail ?? undefined,\n supportEmail: org.supportEmail ?? undefined,\n tier: org.tier as DeveloperOrganization[\"tier\"],\n partnerTier:\n (org.partnerTier as DeveloperOrganization[\"partnerTier\"]) ?? undefined,\n partnerSince: org.partnerSince ?? undefined,\n isVerified: org.isVerified ?? false,\n verifiedAt: org.verifiedAt ?? undefined,\n isCertified: org.isCertified ?? false,\n certifiedAt: org.certifiedAt ?? undefined,\n totalApps: org.totalApps ?? 0,\n publishedApps: org.publishedApps ?? 0,\n totalInstalls: org.totalInstalls ?? 0,\n activeInstalls: org.activeInstalls ?? 0,\n totalApiCalls: org.totalApiCalls ?? \"0\",\n averageRating: org.averageRating ?? undefined,\n totalRevenue: org.totalRevenue ?? 0,\n totalPlatformFees: org.totalPlatformFees ?? 0,\n totalPayouts: org.totalPayouts ?? 0,\n pendingBalance: org.pendingBalance ?? 0,\n lifetimeRevenue: org.lifetimeRevenue ?? 0,\n platformFeeRate: org.platformFeeRate ?? 0.3,\n apiCallsLimit: org.apiCallsLimit ?? 100000,\n storageLimit: org.storageLimit ?? \"1073741824\",\n apiCallsUsed: org.apiCallsUsed ?? \"0\",\n storageUsed: org.storageUsed ?? \"0\",\n taxId: org.taxId ?? undefined,\n taxCountry: org.taxCountry ?? undefined,\n taxFormVerified: org.taxFormVerified ?? false,\n legalEntityName: org.legalEntityName ?? undefined,\n legalEntityType: org.legalEntityType ?? undefined,\n createdAt: org.createdAt,\n updatedAt: org.updatedAt,\n };\n}\n\n/**\n * Map GraphQL member fragment to local type\n */\nfunction mapMember(member: OrgMemberFieldsFragment): DeveloperOrgMember {\n return {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n email: member.email ?? undefined,\n role: member.role as DeveloperOrgMember[\"role\"],\n isActive: member.isActive ?? true,\n isSuspended: member.isSuspended ?? false,\n suspendedAt: member.suspendedAt ?? undefined,\n suspendedReason: member.suspendedReason ?? undefined,\n joinedAt: member.joinedAt,\n lastActiveAt: member.lastActiveAt ?? undefined,\n permissions: member.permissions ?? undefined,\n invitedBy: member.invitedBy ?? undefined,\n invitationId: member.invitationId ?? undefined,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n };\n}\n\ntype TabId = \"overview\" | \"apps\" | \"members\" | \"settings\";\n\n/**\n * Organization detail page\n */\nexport const OrganizationDetailPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { orgId: id } = useParams<{ orgId: string }>();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canUpdate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_UPDATE,\n );\n const [activeTab, setActiveTab] = useState<TabId>(\"overview\");\n\n const tabs: Array<{ id: TabId; label: string; icon: FC<{ size?: number }> }> =\n [\n {\n id: \"overview\",\n label: tr(\"devportal.overview\", \"Overview\"),\n icon: Building2,\n },\n {\n id: \"apps\",\n label: tr(\"devportal.applications\", \"Applications\"),\n icon: AppWindow,\n },\n { id: \"members\", label: tr(\"devportal.members\", \"Members\"), icon: Users },\n {\n id: \"settings\",\n label: tr(\"devportal.settings\", \"Settings\"),\n icon: Settings,\n },\n ];\n\n // Fetch organization data\n const { data, previousData, loading, error } = useGetOrganizationQuery({\n variables: { id: id! },\n skip: !id,\n });\n const resolvedData = data ?? previousData;\n\n const { data: appsData } = useGetApplicationsQuery({\n variables: { limit: 50, organizationId: id },\n skip: !id,\n fetchPolicy: \"cache-and-network\",\n });\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Register org name in breadcrumb registry so the URL ID shows as the org name\n useEffect(() => {\n const name = resolvedData?.developerOrganization?.name;\n if (!id || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(id, name);\n return () => reg?.unregister(id);\n }, [id, data?.developerOrganization?.name]);\n\n // Loading state — only block on initial load, not refetches (keeps SettingsTab mounted)\n if (loading && !resolvedData) {\n return (\n <PageLayout\n title={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error || !resolvedData?.developerOrganization) {\n return (\n <PageLayout\n title={tr(\"devportal.organizationNotFound\", \"Organization Not Found\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex flex-col items-center justify-center py-12 gap-4\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <h2 className=\"text-lg font-semibold\">\n {tr(\n \"devportal.organizationNotFoundLower\",\n \"Organization not found\",\n )}\n </h2>\n <p className=\"text-text-secondary\">\n {error?.message ||\n tr(\n \"devportal.organizationNotFoundDescription\",\n \"The organization you're looking for doesn't exist or you don't have access to it.\",\n )}\n </p>\n <button\n onClick={() => handleNavigate(\"/organizations\")}\n className=\"mt-4 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 {tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n // Map GraphQL data to local types\n const org = mapOrganization(resolvedData!.developerOrganization!);\n const members = (resolvedData!.developerOrganization!.members ?? []).map(\n mapMember,\n );\n const apps = (appsData?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? []) as Application[];\n\n // Calculate usage percentages\n const apiCallsUsedNum = parseInt(org.apiCallsUsed);\n const apiCallsPercent = (apiCallsUsedNum / org.apiCallsLimit) * 100;\n const storageUsedNum = parseInt(org.storageUsed);\n const storageLimitNum = parseInt(org.storageLimit);\n const storagePercent = (storageUsedNum / storageLimitNum) * 100;\n\n return (\n <PageLayout\n title={org.name}\n description={org.description}\n purpose={tr(\n \"devportal.orgDetailPurpose\",\n \"This is the home for one organization — the apps it owns, the people who can work on them, and its store and billing settings. Invite teammates, add apps, and verify the org so your published listings look trustworthy.\",\n )}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() =>\n navigate?.(\n `/billing/earnings?developerOrgId=${encodeURIComponent(org.id)}&developerOrgName=${encodeURIComponent(org.name)}`,\n )\n }\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n <DollarSign size={16} />\n {tr(\"devportal.revenue\", \"Revenue\")}\n </button>\n <button\n onClick={() => setActiveTab(\"settings\")}\n disabled={!canUpdate}\n aria-disabled={!canUpdate}\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 disabled:opacity-50\"\n >\n <Edit size={16} />\n {tr(\"devportal.settings\", \"Settings\")}\n </button>\n </div>\n }\n >\n {/* Tabs */}\n <div className=\"border-b\">\n <nav\n className=\"-mb-px flex gap-4 overflow-x-auto\"\n role=\"tablist\"\n aria-label={tr(\n \"devportal.organizationSections\",\n \"Organization sections\",\n )}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n return (\n <button\n key={tab.id}\n id={`organization-tab-${tab.id}`}\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n aria-controls={`organization-panel-${tab.id}`}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n \"flex items-center gap-2 border-b-2 px-1 py-3 text-sm font-medium transition-colors\",\n activeTab === tab.id\n ? \"border-primary text-primary\"\n : \"border-transparent text-text-secondary hover:text-text-primary hover:border-muted-foreground\",\n )}\n >\n <Icon size={16} />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n\n {/* Guided next steps (dismissable) */}\n <NextSteps\n className=\"mt-6\"\n storageKey={`devportal-org-${org.id}`}\n steps={[\n {\n id: \"invite-members\",\n label: tr(\"devportal.inviteMembers\", \"Invite members\"),\n description: tr(\n \"devportal.orgStepInvite\",\n \"Add teammates so they can build alongside you\",\n ),\n icon: <Users size={16} />,\n onClick: () => setActiveTab(\"members\"),\n },\n {\n id: \"create-app\",\n label: tr(\"devportal.createApp\", \"Create App\"),\n description: tr(\n \"devportal.orgStepCreateApp\",\n \"Build a new application under this organization\",\n ),\n icon: <AppWindow size={16} />,\n onClick: () => handleNavigate(\"/apps/new\"),\n },\n {\n id: \"settings\",\n label: tr(\n \"devportal.orgStepVerify\",\n \"Complete organization profile\",\n ),\n description: tr(\n \"devportal.orgStepVerifyDesc\",\n \"Add a logo and details, then request verification\",\n ),\n icon: <Edit size={16} />,\n onClick: () => setActiveTab(\"settings\"),\n done: Boolean(org.isVerified),\n },\n ]}\n />\n\n {/* Tab content */}\n <div\n className=\"mt-6\"\n id={`organization-panel-${activeTab}`}\n role=\"tabpanel\"\n aria-labelledby={`organization-tab-${activeTab}`}\n tabIndex={0}\n >\n {activeTab === \"overview\" && (\n <OverviewTab\n org={org}\n apps={apps}\n members={members}\n apiCallsPercent={apiCallsPercent}\n storagePercent={storagePercent}\n onNavigate={handleNavigate}\n onShowApps={() => setActiveTab(\"apps\")}\n />\n )}\n {activeTab === \"apps\" && (\n <AppsTab apps={apps} onNavigate={handleNavigate} />\n )}\n {activeTab === \"members\" && (\n <MembersTab\n members={members}\n onNavigate={handleNavigate}\n orgId={org.id}\n />\n )}\n {activeTab === \"settings\" && <SettingsTab org={org} />}\n </div>\n </PageLayout>\n );\n};\n\n// Overview Tab\nconst OverviewTab: FC<{\n org: DeveloperOrganization;\n apps: Application[];\n members: DeveloperOrgMember[];\n apiCallsPercent: number;\n storagePercent: number;\n onNavigate: (path: string) => void;\n onShowApps: () => void;\n}> = ({\n org,\n apps,\n members,\n apiCallsPercent,\n storagePercent,\n onNavigate,\n onShowApps,\n}) => {\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 return (\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Stats — primary emphasis zone */}\n <EmphasisPanel>\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.publishedApps\", \"Published Apps\")}\n value={`${org.publishedApps}/${org.totalApps}`}\n icon={<AppWindow size={20} />}\n />\n <StatCard\n title={tr(\"devportal.totalInstalls\", \"Total Installs\")}\n value={org.totalInstalls.toLocaleString()}\n icon={<TrendingUp size={20} />}\n trend={{\n value: 12,\n label: tr(\"devportal.thisMonth\", \"this month\"),\n }}\n />\n <StatCard\n title={tr(\"devportal.totalRevenue\", \"Total Revenue\")}\n value={`$${org.totalRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n <StatCard\n title={tr(\"devportal.avgRating\", \"Avg Rating\")}\n value={\n org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")\n }\n icon={<BarChart3 size={20} />}\n />\n </StatCardGrid>\n </EmphasisPanel>\n\n {/* Recent Apps */}\n <PageSection\n title={tr(\"devportal.recentApplications\", \"Recent Applications\")}\n actions={\n <button\n onClick={onShowApps}\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 {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.slice(0, 3).map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={24} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createYourFirstApplication\",\n \"Create your first application\",\n )}\n />\n )}\n </PageSection>\n\n {/* Usage Quotas */}\n <PageSection title={tr(\"devportal.usageAndQuotas\", \"Usage & Quotas\")}>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <UsageCard\n label={tr(\"devportal.apiCalls\", \"API Calls\")}\n used={parseInt(org.apiCallsUsed)}\n limit={org.apiCallsLimit}\n percent={apiCallsPercent}\n format=\"number\"\n />\n <UsageCard\n label={tr(\"devportal.storage\", \"Storage\")}\n used={parseInt(org.storageUsed)}\n limit={parseInt(org.storageLimit)}\n percent={storagePercent}\n format=\"bytes\"\n />\n </div>\n {org.quotaResetAt && (\n <p className=\"text-xs text-text-secondary mt-2\">\n {tr(\"devportal.quotasResetOn\", \"Quotas reset on\")}{\" \"}\n {new Date(org.quotaResetAt).toLocaleDateString()}\n </p>\n )}\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Stats */}\n <PageSection title={tr(\"devportal.revenueSummary\", \"Revenue Summary\")}>\n <DetailList\n items={[\n {\n label: tr(\"devportal.totalRevenue\", \"Total Revenue\"),\n value: `$${org.totalRevenue.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.platformFees\", \"Platform Fees\"),\n value: `$${org.totalPlatformFees.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.netPayouts\", \"Net Payouts\"),\n value: `$${org.totalPayouts.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.pendingBalance\", \"Pending Balance\"),\n value: `$${org.pendingBalance.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.lifetimeRevenue\", \"Lifetime Revenue\"),\n value: `$${org.lifetimeRevenue.toLocaleString()}`,\n },\n ]}\n />\n </PageSection>\n\n {/* Team */}\n <PageSection\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n actions={\n <button\n onClick={() => onNavigate(`/organizations/${org.id}/members`)}\n className=\"text-sm text-primary hover:underline\"\n >\n {tr(\"devportal.manage\", \"Manage\")}\n </button>\n }\n >\n <div className=\"space-y-2\">\n {members.slice(0, 3).map((member) => (\n <div\n key={member.id}\n className=\"flex items-center justify-between py-2\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <div>\n <p className=\"text-sm font-medium\">{member.email}</p>\n <p className=\"text-xs text-text-secondary\">\n {ORG_ROLE_LABELS[member.role]}\n </p>\n </div>\n </div>\n </div>\n ))}\n {members.length > 3 && (\n <p className=\"text-xs text-text-secondary\">\n +{members.length - 3}{\" \"}\n {tr(\"devportal.moreMembers\", \"more members\")}\n </p>\n )}\n </div>\n </PageSection>\n\n {/* Links */}\n <PageSection title={tr(\"devportal.links\", \"Links\")}>\n <div className=\"space-y-2\">\n {org.websiteUrl && (\n <a\n href={org.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {tr(\"devportal.website\", \"Website\")}\n </a>\n )}\n {org.contactEmail && (\n <a\n href={`mailto:${org.contactEmail}`}\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {org.contactEmail}\n </a>\n )}\n </div>\n </PageSection>\n </div>\n </div>\n );\n};\n\n// Apps Tab\nconst AppsTab: FC<{\n apps: Application[];\n onNavigate: (path: string) => void;\n}> = ({ apps, onNavigate }) => {\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 <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {apps.length}{\" \"}\n {apps.length !== 1\n ? tr(\"devportal.applications\", \"applications\")\n : tr(\"devportal.application\", \"application\")}\n </p>\n <button\n onClick={() => onNavigate(\"/apps/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.createApp\", \"Create App\")}\n </button>\n </div>\n\n {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={32} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createFirstAppForOrg\",\n \"Create your first application for this organization\",\n )}\n action={\n <button\n onClick={() => onNavigate(\"/apps/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.createApp\", \"Create App\")}\n </button>\n }\n />\n )}\n </div>\n );\n};\n\n// Members Tab\nconst MembersTab: FC<{\n members: DeveloperOrgMember[];\n onNavigate: (path: string) => void;\n orgId: string;\n}> = ({ members, onNavigate, orgId }) => {\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 <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {members.length}{\" \"}\n {members.length !== 1\n ? tr(\"devportal.membersLower\", \"members\")\n : tr(\"devportal.memberLower\", \"member\")}\n </p>\n <button\n onClick={() => onNavigate(`/organizations/${orgId}/members`)}\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.inviteMember\", \"Invite Member\")}\n </button>\n </div>\n\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => (\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <span className=\"font-medium\">{member.email}</span>\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium\",\n member.role === \"OWNER\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : member.role === \"ADMIN\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : member.role === \"DEVELOPER\"\n ? \"bg-status-success-bg-subtle text-status-success-text\"\n : \"bg-bg-sunken text-text-primary\",\n )}\n >\n {ORG_ROLE_LABELS[member.role]}\n </span>\n ),\n },\n {\n key: \"joinedAt\",\n header: tr(\"devportal.joinedColumn\", \"Joined\"),\n render: (member) => new Date(member.joinedAt).toLocaleDateString(),\n },\n {\n key: \"lastActiveAt\",\n header: tr(\"devportal.lastActiveColumn\", \"Last Active\"),\n render: (member) =>\n member.lastActiveAt\n ? new Date(member.lastActiveAt).toLocaleDateString()\n : tr(\"devportal.never\", \"Never\"),\n },\n ]}\n />\n </div>\n );\n};\n\n// Settings Tab\nconst SettingsTab: FC<{ org: DeveloperOrganization }> = ({ org }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [verifyMethod, setVerifyMethod] = useState<string>(\"manual\");\n const [verifySuccess, setVerifySuccess] = useState(false);\n const [requestVerification, { loading: verifying }] =\n useRequestOrgVerificationMutation({\n onCompleted: () => setVerifySuccess(true),\n });\n return (\n <div className=\"space-y-6 max-w-2xl\">\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.organizationId\", \"Organization ID\"),\n value: <code className=\"text-xs\">{org.id}</code>,\n },\n { label: tr(\"devportal.slug\", \"Slug\"), value: org.slug },\n { label: tr(\"devportal.tier\", \"Tier\"), value: org.tier },\n {\n label: tr(\"devportal.partnerTier\", \"Partner Tier\"),\n value: org.partnerTier || tr(\"devportal.none\", \"None\"),\n },\n {\n label: tr(\"devportal.created\", \"Created\"),\n value: new Date(org.createdAt).toLocaleDateString(),\n },\n {\n label: tr(\"devportal.platformFeeRate\", \"Platform Fee Rate\"),\n value: `${(org.platformFeeRate * 100).toFixed(0)}%`,\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.legalInformation\", \"Legal Information\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.legalEntityName\", \"Legal Entity Name\"),\n value:\n org.legalEntityName ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.entityType\", \"Entity Type\"),\n value:\n org.legalEntityType ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxId\", \"Tax ID\"),\n value: org.taxId\n ? `•••••${org.taxId.slice(-4)}`\n : tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxCountry\", \"Tax Country\"),\n value:\n org.taxCountry || tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxForm\", \"Tax Form\"),\n value:\n org.taxFormType ||\n tr(\"devportal.notSubmitted\", \"Not submitted\"),\n },\n {\n label: tr(\"devportal.taxFormStatus\", \"Tax Form Status\"),\n value: org.taxFormVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verified\", \"Verified\")}\n </span>\n ) : (\n tr(\"devportal.pendingVerification\", \"Pending verification\")\n ),\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.verificationStatus\", \"Verification Status\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.verifiedLabel\", \"Verified\"),\n value: org.isVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verifiedVia\", \"Verified via\")}{\" \"}\n {org.verificationMethod}\n </span>\n ) : (\n tr(\"devportal.notVerified\", \"Not verified\")\n ),\n },\n {\n label: tr(\"devportal.certifiedLabel\", \"Certified\"),\n value: org.isCertified ? (\n <span className=\"text-accent-blue flex items-center gap-1\">\n <Shield size={14} />{\" \"}\n {tr(\"devportal.certifiedUntil\", \"Certified until\")}{\" \"}\n {org.certificationExpiry\n ? new Date(org.certificationExpiry).toLocaleDateString()\n : \"N/A\"}\n </span>\n ) : (\n tr(\"devportal.notCertified\", \"Not certified\")\n ),\n },\n ]}\n />\n {!org.isVerified && (\n <div className=\"mt-4 rounded-md border border-border-subtle p-4 space-y-3\">\n {verifySuccess ? (\n <p className=\"text-sm text-status-success-text flex items-center gap-2\">\n <CheckCircle size={14} />\n {tr(\n \"devportal.verificationRequested\",\n \"Verification request submitted. Our team will review and contact you.\",\n )}\n </p>\n ) : (\n <>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.requestVerificationHint\",\n \"Get your organization verified to build trust with users. Choose a verification method:\",\n )}\n </p>\n <div className=\"flex gap-2 flex-wrap\">\n {[\"domain\", \"document\", \"manual\"].map((m) => (\n <button\n key={m}\n type=\"button\"\n onClick={() => setVerifyMethod(m)}\n className={`rounded-md border px-3 py-1 text-xs font-medium transition-colors ${\n verifyMethod === m\n ? \"bg-action-primary-bg text-action-primary-text border-primary\"\n : \"border-border-subtle hover:bg-bg-sunken\"\n }`}\n >\n {m === \"domain\"\n ? tr(\"devportal.domainVerification\", \"Domain\")\n : m === \"document\"\n ? tr(\"devportal.documentVerification\", \"Document\")\n : tr(\"devportal.manualVerification\", \"Manual review\")}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n disabled={verifying}\n onClick={() =>\n requestVerification({\n variables: { id: org.id, method: verifyMethod },\n })\n }\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 disabled:opacity-50\"\n >\n {verifying ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : (\n <Shield size={14} />\n )}\n {tr(\"devportal.requestVerification\", \"Request Verification\")}\n </button>\n </>\n )}\n </div>\n )}\n </PageSection>\n </div>\n );\n};\n\n// Usage Card Component\nconst UsageCard: FC<{\n label: string;\n used: number;\n limit: number;\n percent: number;\n format: \"number\" | \"bytes\";\n}> = ({ label, used, limit, percent, format }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const formatValue = (value: number): string => {\n if (format === \"bytes\") {\n const gb = value / (1024 * 1024 * 1024);\n return `${gb.toFixed(1)} GB`;\n }\n if (value >= 1000000) {\n return `${(value / 1000000).toFixed(1)}M`;\n }\n if (value >= 1000) {\n return `${(value / 1000).toFixed(1)}K`;\n }\n return value.toLocaleString();\n };\n\n return (\n <div className=\"rounded-card border border-border-seam p-4\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-medium\">{label}</span>\n <span className=\"text-xs text-text-secondary\">\n {formatValue(used)} / {formatValue(limit)}\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={cn(\n \"h-full rounded-full transition-all\",\n percent > 90\n ? \"bg-status-error-bg-subtle\"\n : percent > 70\n ? \"bg-status-warning-bg-subtle\"\n : \"bg-action-primary-bg\",\n )}\n style={{ width: `${Math.min(percent, 100)}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary mt-1\">\n {percent.toFixed(1)}% {tr(\"devportal.used\", \"used\")}\n </p>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OrganizationDetailPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState, useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Building2,\n Users,\n AppWindow,\n DollarSign,\n Settings,\n ExternalLink,\n CheckCircle,\n BarChart3,\n TrendingUp,\n ArrowRight,\n Plus,\n Edit,\n Shield,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { EmphasisPanel, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { DataTable, DetailList } from \"../components/DataTable\";\nimport { AppListItem } from \"../components/AppCard\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type {\n DeveloperOrganization,\n Application,\n DeveloperOrgMember,\n} from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport {\n useGetOrganizationQuery,\n useGetApplicationsQuery,\n useRequestOrgVerificationMutation,\n} from \"../../generated/global-operations\";\nimport type {\n OrganizationFieldsFragment,\n OrgMemberFieldsFragment,\n ApplicationFieldsFragment,\n} from \"../../generated/global-operations\";\n\n/**\n * Map GraphQL organization fragment to local type\n */\nfunction mapOrganization(\n org: OrganizationFieldsFragment,\n): DeveloperOrganization {\n return {\n id: org.id,\n name: org.name,\n slug: org.slug,\n description: org.description ?? undefined,\n logoUrl: org.logoUrl ?? undefined,\n bannerUrl: org.bannerUrl ?? undefined,\n websiteUrl: org.websiteUrl ?? undefined,\n contactEmail: org.contactEmail ?? undefined,\n supportEmail: org.supportEmail ?? undefined,\n tier: org.tier as DeveloperOrganization[\"tier\"],\n partnerTier:\n (org.partnerTier as DeveloperOrganization[\"partnerTier\"]) ?? undefined,\n partnerSince: org.partnerSince ?? undefined,\n isVerified: org.isVerified ?? false,\n verifiedAt: org.verifiedAt ?? undefined,\n isCertified: org.isCertified ?? false,\n certifiedAt: org.certifiedAt ?? undefined,\n totalApps: org.totalApps ?? 0,\n publishedApps: org.publishedApps ?? 0,\n totalInstalls: org.totalInstalls ?? 0,\n activeInstalls: org.activeInstalls ?? 0,\n totalApiCalls: org.totalApiCalls ?? \"0\",\n averageRating: org.averageRating ?? undefined,\n totalRevenue: org.totalRevenue ?? 0,\n totalPlatformFees: org.totalPlatformFees ?? 0,\n totalPayouts: org.totalPayouts ?? 0,\n pendingBalance: org.pendingBalance ?? 0,\n lifetimeRevenue: org.lifetimeRevenue ?? 0,\n platformFeeRate: org.platformFeeRate ?? 0.3,\n apiCallsLimit: org.apiCallsLimit ?? 100000,\n storageLimit: org.storageLimit ?? \"1073741824\",\n apiCallsUsed: org.apiCallsUsed ?? \"0\",\n storageUsed: org.storageUsed ?? \"0\",\n taxId: org.taxId ?? undefined,\n taxCountry: org.taxCountry ?? undefined,\n taxFormVerified: org.taxFormVerified ?? false,\n legalEntityName: org.legalEntityName ?? undefined,\n legalEntityType: org.legalEntityType ?? undefined,\n createdAt: org.createdAt,\n updatedAt: org.updatedAt,\n };\n}\n\n/**\n * Map GraphQL member fragment to local type\n */\nfunction mapMember(member: OrgMemberFieldsFragment): DeveloperOrgMember {\n return {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n email: member.email ?? undefined,\n role: member.role as DeveloperOrgMember[\"role\"],\n isActive: member.isActive ?? true,\n isSuspended: member.isSuspended ?? false,\n suspendedAt: member.suspendedAt ?? undefined,\n suspendedReason: member.suspendedReason ?? undefined,\n joinedAt: member.joinedAt,\n lastActiveAt: member.lastActiveAt ?? undefined,\n permissions: member.permissions ?? undefined,\n invitedBy: member.invitedBy ?? undefined,\n invitationId: member.invitationId ?? undefined,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n };\n}\n\ntype TabId = \"overview\" | \"apps\" | \"members\" | \"settings\";\n\n/**\n * Organization detail page\n */\nexport const OrganizationDetailPage: FC = () => {\n const { navigate, basePath, setActiveOrgId } = useDevportal();\n const { orgId: id } = useParams<{ orgId: string }>();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canUpdate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_UPDATE,\n );\n const [activeTab, setActiveTab] = useState<TabId>(\"overview\");\n\n const tabs: Array<{ id: TabId; label: string; icon: FC<{ size?: number }> }> =\n [\n {\n id: \"overview\",\n label: tr(\"devportal.overview\", \"Overview\"),\n icon: Building2,\n },\n {\n id: \"apps\",\n label: tr(\"devportal.applications\", \"Applications\"),\n icon: AppWindow,\n },\n { id: \"members\", label: tr(\"devportal.members\", \"Members\"), icon: Users },\n {\n id: \"settings\",\n label: tr(\"devportal.settings\", \"Settings\"),\n icon: Settings,\n },\n ];\n\n // Fetch organization data\n const { data, previousData, loading, error } = useGetOrganizationQuery({\n variables: { id: id! },\n skip: !id,\n });\n const resolvedData = data ?? previousData;\n\n const { data: appsData } = useGetApplicationsQuery({\n variables: { limit: 50, organizationId: id },\n skip: !id,\n fetchPolicy: \"cache-and-network\",\n });\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Sync activeOrgId so the dashboard scopes to whichever org the user is browsing\n useEffect(() => {\n if (id) setActiveOrgId(id);\n }, [id, setActiveOrgId]);\n\n // Register org name in breadcrumb registry so the URL ID shows as the org name\n useEffect(() => {\n const name = resolvedData?.developerOrganization?.name;\n if (!id || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(id, name);\n return () => reg?.unregister(id);\n }, [id, data?.developerOrganization?.name]);\n\n // Loading state — only block on initial load, not refetches (keeps SettingsTab mounted)\n if (loading && !resolvedData) {\n return (\n <PageLayout\n title={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error || !resolvedData?.developerOrganization) {\n return (\n <PageLayout\n title={tr(\"devportal.organizationNotFound\", \"Organization Not Found\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex flex-col items-center justify-center py-12 gap-4\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <h2 className=\"text-lg font-semibold\">\n {tr(\n \"devportal.organizationNotFoundLower\",\n \"Organization not found\",\n )}\n </h2>\n <p className=\"text-text-secondary\">\n {error?.message ||\n tr(\n \"devportal.organizationNotFoundDescription\",\n \"The organization you're looking for doesn't exist or you don't have access to it.\",\n )}\n </p>\n <button\n onClick={() => handleNavigate(\"/organizations\")}\n className=\"mt-4 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 {tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n // Map GraphQL data to local types\n const org = mapOrganization(resolvedData!.developerOrganization!);\n const members = (resolvedData!.developerOrganization!.members ?? []).map(\n mapMember,\n );\n const apps = (appsData?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? []) as Application[];\n\n // Calculate usage percentages\n const apiCallsUsedNum = parseInt(org.apiCallsUsed);\n const apiCallsPercent = (apiCallsUsedNum / org.apiCallsLimit) * 100;\n const storageUsedNum = parseInt(org.storageUsed);\n const storageLimitNum = parseInt(org.storageLimit);\n const storagePercent = (storageUsedNum / storageLimitNum) * 100;\n\n return (\n <PageLayout\n title={org.name}\n description={org.description}\n purpose={tr(\n \"devportal.orgDetailPurpose\",\n \"This is the home for one organization — the apps it owns, the people who can work on them, and its store and billing settings. Invite teammates, add apps, and verify the org so your published listings look trustworthy.\",\n )}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() =>\n navigate?.(\n `/billing/earnings?developerOrgId=${encodeURIComponent(org.id)}&developerOrgName=${encodeURIComponent(org.name)}`,\n )\n }\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n <DollarSign size={16} />\n {tr(\"devportal.revenue\", \"Revenue\")}\n </button>\n <button\n onClick={() => setActiveTab(\"settings\")}\n disabled={!canUpdate}\n aria-disabled={!canUpdate}\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 disabled:opacity-50\"\n >\n <Edit size={16} />\n {tr(\"devportal.settings\", \"Settings\")}\n </button>\n </div>\n }\n >\n {/* Tabs */}\n <div className=\"border-b\">\n <nav\n className=\"-mb-px flex gap-4 overflow-x-auto\"\n role=\"tablist\"\n aria-label={tr(\n \"devportal.organizationSections\",\n \"Organization sections\",\n )}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n return (\n <button\n key={tab.id}\n id={`organization-tab-${tab.id}`}\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n aria-controls={`organization-panel-${tab.id}`}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n \"flex items-center gap-2 border-b-2 px-1 py-3 text-sm font-medium transition-colors\",\n activeTab === tab.id\n ? \"border-primary text-primary\"\n : \"border-transparent text-text-secondary hover:text-text-primary hover:border-muted-foreground\",\n )}\n >\n <Icon size={16} />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n\n {/* Guided next steps (dismissable) */}\n <NextSteps\n className=\"mt-6\"\n storageKey={`devportal-org-${org.id}`}\n steps={[\n {\n id: \"invite-members\",\n label: tr(\"devportal.inviteMembers\", \"Invite members\"),\n description: tr(\n \"devportal.orgStepInvite\",\n \"Add teammates so they can build alongside you\",\n ),\n icon: <Users size={16} />,\n onClick: () => setActiveTab(\"members\"),\n },\n {\n id: \"create-app\",\n label: tr(\"devportal.createApp\", \"Create App\"),\n description: tr(\n \"devportal.orgStepCreateApp\",\n \"Build a new application under this organization\",\n ),\n icon: <AppWindow size={16} />,\n onClick: () => handleNavigate(\"/apps/new\"),\n },\n {\n id: \"settings\",\n label: tr(\n \"devportal.orgStepVerify\",\n \"Complete organization profile\",\n ),\n description: tr(\n \"devportal.orgStepVerifyDesc\",\n \"Add a logo and details, then request verification\",\n ),\n icon: <Edit size={16} />,\n onClick: () => setActiveTab(\"settings\"),\n done: Boolean(org.isVerified),\n },\n ]}\n />\n\n {/* Tab content */}\n <div\n className=\"mt-6\"\n id={`organization-panel-${activeTab}`}\n role=\"tabpanel\"\n aria-labelledby={`organization-tab-${activeTab}`}\n tabIndex={0}\n >\n {activeTab === \"overview\" && (\n <OverviewTab\n org={org}\n apps={apps}\n members={members}\n apiCallsPercent={apiCallsPercent}\n storagePercent={storagePercent}\n onNavigate={handleNavigate}\n onShowApps={() => setActiveTab(\"apps\")}\n />\n )}\n {activeTab === \"apps\" && (\n <AppsTab apps={apps} onNavigate={handleNavigate} />\n )}\n {activeTab === \"members\" && (\n <MembersTab\n members={members}\n onNavigate={handleNavigate}\n orgId={org.id}\n />\n )}\n {activeTab === \"settings\" && <SettingsTab org={org} />}\n </div>\n </PageLayout>\n );\n};\n\n// Overview Tab\nconst OverviewTab: FC<{\n org: DeveloperOrganization;\n apps: Application[];\n members: DeveloperOrgMember[];\n apiCallsPercent: number;\n storagePercent: number;\n onNavigate: (path: string) => void;\n onShowApps: () => void;\n}> = ({\n org,\n apps,\n members,\n apiCallsPercent,\n storagePercent,\n onNavigate,\n onShowApps,\n}) => {\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 return (\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Stats — primary emphasis zone */}\n <EmphasisPanel>\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.publishedApps\", \"Published Apps\")}\n value={`${org.publishedApps}/${org.totalApps}`}\n icon={<AppWindow size={20} />}\n />\n <StatCard\n title={tr(\"devportal.totalInstalls\", \"Total Installs\")}\n value={org.totalInstalls.toLocaleString()}\n icon={<TrendingUp size={20} />}\n trend={{\n value: 12,\n label: tr(\"devportal.thisMonth\", \"this month\"),\n }}\n />\n <StatCard\n title={tr(\"devportal.totalRevenue\", \"Total Revenue\")}\n value={`$${org.totalRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n <StatCard\n title={tr(\"devportal.avgRating\", \"Avg Rating\")}\n value={\n org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")\n }\n icon={<BarChart3 size={20} />}\n />\n </StatCardGrid>\n </EmphasisPanel>\n\n {/* Recent Apps */}\n <PageSection\n title={tr(\"devportal.recentApplications\", \"Recent Applications\")}\n actions={\n <button\n onClick={onShowApps}\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 {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.slice(0, 3).map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={24} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createYourFirstApplication\",\n \"Create your first application\",\n )}\n />\n )}\n </PageSection>\n\n {/* Usage Quotas */}\n <PageSection title={tr(\"devportal.usageAndQuotas\", \"Usage & Quotas\")}>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <UsageCard\n label={tr(\"devportal.apiCalls\", \"API Calls\")}\n used={parseInt(org.apiCallsUsed)}\n limit={org.apiCallsLimit}\n percent={apiCallsPercent}\n format=\"number\"\n />\n <UsageCard\n label={tr(\"devportal.storage\", \"Storage\")}\n used={parseInt(org.storageUsed)}\n limit={parseInt(org.storageLimit)}\n percent={storagePercent}\n format=\"bytes\"\n />\n </div>\n {org.quotaResetAt && (\n <p className=\"text-xs text-text-secondary mt-2\">\n {tr(\"devportal.quotasResetOn\", \"Quotas reset on\")}{\" \"}\n {new Date(org.quotaResetAt).toLocaleDateString()}\n </p>\n )}\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Stats */}\n <PageSection title={tr(\"devportal.revenueSummary\", \"Revenue Summary\")}>\n <DetailList\n items={[\n {\n label: tr(\"devportal.totalRevenue\", \"Total Revenue\"),\n value: `$${org.totalRevenue.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.platformFees\", \"Platform Fees\"),\n value: `$${org.totalPlatformFees.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.netPayouts\", \"Net Payouts\"),\n value: `$${org.totalPayouts.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.pendingBalance\", \"Pending Balance\"),\n value: `$${org.pendingBalance.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.lifetimeRevenue\", \"Lifetime Revenue\"),\n value: `$${org.lifetimeRevenue.toLocaleString()}`,\n },\n ]}\n />\n </PageSection>\n\n {/* Team */}\n <PageSection\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n actions={\n <button\n onClick={() => onNavigate(`/organizations/${org.id}/members`)}\n className=\"text-sm text-primary hover:underline\"\n >\n {tr(\"devportal.manage\", \"Manage\")}\n </button>\n }\n >\n <div className=\"space-y-2\">\n {members.slice(0, 3).map((member) => (\n <div\n key={member.id}\n className=\"flex items-center justify-between py-2\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <div>\n <p className=\"text-sm font-medium\">{member.email}</p>\n <p className=\"text-xs text-text-secondary\">\n {ORG_ROLE_LABELS[member.role]}\n </p>\n </div>\n </div>\n </div>\n ))}\n {members.length > 3 && (\n <p className=\"text-xs text-text-secondary\">\n +{members.length - 3}{\" \"}\n {tr(\"devportal.moreMembers\", \"more members\")}\n </p>\n )}\n </div>\n </PageSection>\n\n {/* Links */}\n <PageSection title={tr(\"devportal.links\", \"Links\")}>\n <div className=\"space-y-2\">\n {org.websiteUrl && (\n <a\n href={org.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {tr(\"devportal.website\", \"Website\")}\n </a>\n )}\n {org.contactEmail && (\n <a\n href={`mailto:${org.contactEmail}`}\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {org.contactEmail}\n </a>\n )}\n </div>\n </PageSection>\n </div>\n </div>\n );\n};\n\n// Apps Tab\nconst AppsTab: FC<{\n apps: Application[];\n onNavigate: (path: string) => void;\n}> = ({ apps, onNavigate }) => {\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 <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {apps.length}{\" \"}\n {apps.length !== 1\n ? tr(\"devportal.applications\", \"applications\")\n : tr(\"devportal.application\", \"application\")}\n </p>\n <button\n onClick={() => onNavigate(\"/apps/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.createApp\", \"Create App\")}\n </button>\n </div>\n\n {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={32} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createFirstAppForOrg\",\n \"Create your first application for this organization\",\n )}\n action={\n <button\n onClick={() => onNavigate(\"/apps/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.createApp\", \"Create App\")}\n </button>\n }\n />\n )}\n </div>\n );\n};\n\n// Members Tab\nconst MembersTab: FC<{\n members: DeveloperOrgMember[];\n onNavigate: (path: string) => void;\n orgId: string;\n}> = ({ members, onNavigate, orgId }) => {\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 <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {members.length}{\" \"}\n {members.length !== 1\n ? tr(\"devportal.membersLower\", \"members\")\n : tr(\"devportal.memberLower\", \"member\")}\n </p>\n <button\n onClick={() => onNavigate(`/organizations/${orgId}/members`)}\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.inviteMember\", \"Invite Member\")}\n </button>\n </div>\n\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => (\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <span className=\"font-medium\">{member.email}</span>\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium\",\n member.role === \"OWNER\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : member.role === \"ADMIN\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : member.role === \"DEVELOPER\"\n ? \"bg-status-success-bg-subtle text-status-success-text\"\n : \"bg-bg-sunken text-text-primary\",\n )}\n >\n {ORG_ROLE_LABELS[member.role]}\n </span>\n ),\n },\n {\n key: \"joinedAt\",\n header: tr(\"devportal.joinedColumn\", \"Joined\"),\n render: (member) => new Date(member.joinedAt).toLocaleDateString(),\n },\n {\n key: \"lastActiveAt\",\n header: tr(\"devportal.lastActiveColumn\", \"Last Active\"),\n render: (member) =>\n member.lastActiveAt\n ? new Date(member.lastActiveAt).toLocaleDateString()\n : tr(\"devportal.never\", \"Never\"),\n },\n ]}\n />\n </div>\n );\n};\n\n// Settings Tab\nconst SettingsTab: FC<{ org: DeveloperOrganization }> = ({ org }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [verifyMethod, setVerifyMethod] = useState<string>(\"manual\");\n const [verifySuccess, setVerifySuccess] = useState(false);\n const [requestVerification, { loading: verifying }] =\n useRequestOrgVerificationMutation({\n onCompleted: () => setVerifySuccess(true),\n });\n return (\n <div className=\"space-y-6 max-w-2xl\">\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.organizationId\", \"Organization ID\"),\n value: <code className=\"text-xs\">{org.id}</code>,\n },\n { label: tr(\"devportal.slug\", \"Slug\"), value: org.slug },\n { label: tr(\"devportal.tier\", \"Tier\"), value: org.tier },\n {\n label: tr(\"devportal.partnerTier\", \"Partner Tier\"),\n value: org.partnerTier || tr(\"devportal.none\", \"None\"),\n },\n {\n label: tr(\"devportal.created\", \"Created\"),\n value: new Date(org.createdAt).toLocaleDateString(),\n },\n {\n label: tr(\"devportal.platformFeeRate\", \"Platform Fee Rate\"),\n value: `${(org.platformFeeRate * 100).toFixed(0)}%`,\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.legalInformation\", \"Legal Information\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.legalEntityName\", \"Legal Entity Name\"),\n value:\n org.legalEntityName ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.entityType\", \"Entity Type\"),\n value:\n org.legalEntityType ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxId\", \"Tax ID\"),\n value: org.taxId\n ? `•••••${org.taxId.slice(-4)}`\n : tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxCountry\", \"Tax Country\"),\n value:\n org.taxCountry || tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxForm\", \"Tax Form\"),\n value:\n org.taxFormType ||\n tr(\"devportal.notSubmitted\", \"Not submitted\"),\n },\n {\n label: tr(\"devportal.taxFormStatus\", \"Tax Form Status\"),\n value: org.taxFormVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verified\", \"Verified\")}\n </span>\n ) : (\n tr(\"devportal.pendingVerification\", \"Pending verification\")\n ),\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.verificationStatus\", \"Verification Status\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.verifiedLabel\", \"Verified\"),\n value: org.isVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verifiedVia\", \"Verified via\")}{\" \"}\n {org.verificationMethod}\n </span>\n ) : (\n tr(\"devportal.notVerified\", \"Not verified\")\n ),\n },\n {\n label: tr(\"devportal.certifiedLabel\", \"Certified\"),\n value: org.isCertified ? (\n <span className=\"text-accent-blue flex items-center gap-1\">\n <Shield size={14} />{\" \"}\n {tr(\"devportal.certifiedUntil\", \"Certified until\")}{\" \"}\n {org.certificationExpiry\n ? new Date(org.certificationExpiry).toLocaleDateString()\n : \"N/A\"}\n </span>\n ) : (\n tr(\"devportal.notCertified\", \"Not certified\")\n ),\n },\n ]}\n />\n {!org.isVerified && (\n <div className=\"mt-4 rounded-md border border-border-subtle p-4 space-y-3\">\n {verifySuccess ? (\n <p className=\"text-sm text-status-success-text flex items-center gap-2\">\n <CheckCircle size={14} />\n {tr(\n \"devportal.verificationRequested\",\n \"Verification request submitted. Our team will review and contact you.\",\n )}\n </p>\n ) : (\n <>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.requestVerificationHint\",\n \"Get your organization verified to build trust with users. Choose a verification method:\",\n )}\n </p>\n <div className=\"flex gap-2 flex-wrap\">\n {[\"domain\", \"document\", \"manual\"].map((m) => (\n <button\n key={m}\n type=\"button\"\n onClick={() => setVerifyMethod(m)}\n className={`rounded-md border px-3 py-1 text-xs font-medium transition-colors ${\n verifyMethod === m\n ? \"bg-action-primary-bg text-action-primary-text border-primary\"\n : \"border-border-subtle hover:bg-bg-sunken\"\n }`}\n >\n {m === \"domain\"\n ? tr(\"devportal.domainVerification\", \"Domain\")\n : m === \"document\"\n ? tr(\"devportal.documentVerification\", \"Document\")\n : tr(\"devportal.manualVerification\", \"Manual review\")}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n disabled={verifying}\n onClick={() =>\n requestVerification({\n variables: { id: org.id, method: verifyMethod },\n })\n }\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 disabled:opacity-50\"\n >\n {verifying ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : (\n <Shield size={14} />\n )}\n {tr(\"devportal.requestVerification\", \"Request Verification\")}\n </button>\n </>\n )}\n </div>\n )}\n </PageSection>\n </div>\n );\n};\n\n// Usage Card Component\nconst UsageCard: FC<{\n label: string;\n used: number;\n limit: number;\n percent: number;\n format: \"number\" | \"bytes\";\n}> = ({ label, used, limit, percent, format }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const formatValue = (value: number): string => {\n if (format === \"bytes\") {\n const gb = value / (1024 * 1024 * 1024);\n return `${gb.toFixed(1)} GB`;\n }\n if (value >= 1000000) {\n return `${(value / 1000000).toFixed(1)}M`;\n }\n if (value >= 1000) {\n return `${(value / 1000).toFixed(1)}K`;\n }\n return value.toLocaleString();\n };\n\n return (\n <div className=\"rounded-card border border-border-seam p-4\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-medium\">{label}</span>\n <span className=\"text-xs text-text-secondary\">\n {formatValue(used)} / {formatValue(limit)}\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={cn(\n \"h-full rounded-full transition-all\",\n percent > 90\n ? \"bg-status-error-bg-subtle\"\n : percent > 70\n ? \"bg-status-warning-bg-subtle\"\n : \"bg-action-primary-bg\",\n )}\n style={{ width: `${Math.min(percent, 100)}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary mt-1\">\n {percent.toFixed(1)}% {tr(\"devportal.used\", \"used\")}\n </p>\n </div>\n );\n};\n"],"mappings":"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"}
|