@burdenoff/microfe-devportal 2026.707.1 → 2026.707.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"InvitationDecisionPage.js","names":[],"sources":["../../../src/devportal/pages/InvitationDecisionPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { CheckCircle, Loader2, Mail, Shield, XCircle } from \"lucide-react\";\n\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useAcceptInvitationMutation,\n useGetInvitationByTokenQuery,\n useRejectInvitationMutation,\n} from \"../hooks\";\n\nexport const InvitationDecisionPage: FC = () => {\n const { token } = useParams<{ token: string }>();\n const { navigate, basePath } = useDevportal();\n\n const { data, loading, error } = useGetInvitationByTokenQuery({\n variables: { token: token ?? \"\" },\n skip: !token,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [acceptInvitation, { loading: accepting, data: acceptedData }] =\n useAcceptInvitationMutation();\n const [rejectInvitation, { loading: rejecting, data: rejectedData }] =\n useRejectInvitationMutation();\n\n const invitation = data?.developerOrgInvitationByToken;\n const acceptedMember = acceptedData?.acceptDeveloperOrgInvitation;\n const rejected = rejectedData?.rejectDeveloperOrgInvitation;\n\n const handleAccept = async () => {\n if (!token) return;\n await acceptInvitation({ variables: { token } });\n };\n\n const handleReject = async () => {\n if (!token) return;\n await rejectInvitation({ variables: { token } });\n };\n\n if (loading && !invitation) {\n return (\n <PageLayout title=\"Developer Team Invitation\">\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !invitation) {\n return (\n <PageLayout title=\"Developer Team Invitation\">\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-error-text\" />}\n title=\"Invitation not available\"\n description={\n error?.message ||\n \"This invitation is invalid, expired, or not available to your signed-in account.\"\n }\n />\n </PageLayout>\n );\n }\n\n if (acceptedMember) {\n return (\n <PageLayout title=\"Invitation accepted\">\n <EmptyState\n icon={<CheckCircle size={32} className=\"text-status-success-text\" />}\n title=\"You joined the developer organization\"\n description={`You now have ${invitation.role.toLowerCase()} access to ${invitation.organization.name}.`}\n action={\n <button\n type=\"button\"\n onClick={() =>\n navigate?.(`${basePath}/organizations/${invitation.organization.id}`)\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\"\n >\n Open organization\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n if (rejected) {\n return (\n <PageLayout title=\"Invitation declined\">\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-warning-text\" />}\n title=\"Invitation declined\"\n description={`You declined the invitation to join ${invitation.organization.name}.`}\n action={\n <button\n type=\"button\"\n onClick={() => navigate?.(`${basePath}`)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n Return to Devportal\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Developer Team Invitation\"\n description=\"Review your invitation to join a developer organization\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <PageSection title=\"Invitation details\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Organization</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {invitation.organization.name}\n </p>\n </div>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invited email</p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Mail size={14} />\n {invitation.invitedEmail}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Role</p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Shield size={14} />\n {invitation.role}\n </p>\n </div>\n </div>\n {invitation.message ? (\n <div>\n <p className=\"text-sm text-text-secondary\">Message</p>\n <p className=\"rounded-md bg-bg-sunken px-3 py-2 text-sm text-text-primary whitespace-pre-line\">\n {invitation.message}\n </p>\n </div>\n ) : null}\n <p className=\"text-xs text-text-secondary\">\n Expires on {new Date(invitation.expiresAt).toLocaleString()}\n </p>\n </div>\n </PageSection>\n\n <div className=\"flex flex-wrap gap-3 justify-end\">\n <button\n type=\"button\"\n onClick={() => void handleReject()}\n disabled={accepting || rejecting}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken disabled:opacity-50\"\n >\n {rejecting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n Decline\n </button>\n <button\n type=\"button\"\n onClick={() => void handleAccept()}\n disabled={accepting || rejecting}\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 {accepting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n Accept invitation\n </button>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvitationDecisionPage.js","names":[],"sources":["../../../src/devportal/pages/InvitationDecisionPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { CheckCircle, Loader2, Mail, Shield, XCircle } from \"lucide-react\";\n\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useAcceptInvitationMutation,\n useGetInvitationByTokenQuery,\n useRejectInvitationMutation,\n} from \"../hooks\";\n\nexport const InvitationDecisionPage: FC = () => {\n const { token } = useParams<{ token: string }>();\n const { navigate, basePath } = useDevportal();\n\n const { data, loading, error } = useGetInvitationByTokenQuery({\n variables: { token: token ?? \"\" },\n skip: !token,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [acceptInvitation, { loading: accepting, data: acceptedData }] =\n useAcceptInvitationMutation();\n const [rejectInvitation, { loading: rejecting, data: rejectedData }] =\n useRejectInvitationMutation();\n\n const invitation = data?.developerOrgInvitationByToken;\n const acceptedMember = acceptedData?.acceptDeveloperOrgInvitation;\n const rejected = rejectedData?.rejectDeveloperOrgInvitation;\n\n const handleAccept = async () => {\n if (!token) return;\n await acceptInvitation({ variables: { token } });\n };\n\n const handleReject = async () => {\n if (!token) return;\n await rejectInvitation({ variables: { token } });\n };\n\n if (loading && !invitation) {\n return (\n <PageLayout title=\"Developer Team Invitation\">\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !invitation) {\n return (\n <PageLayout title=\"Developer Team Invitation\">\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-error-text\" />}\n title=\"Invitation not available\"\n description={\n error?.message ||\n \"This invitation is invalid, expired, or not available to your signed-in account.\"\n }\n />\n </PageLayout>\n );\n }\n\n if (acceptedMember) {\n return (\n <PageLayout title=\"Invitation accepted\">\n <EmptyState\n icon={<CheckCircle size={32} className=\"text-status-success-text\" />}\n title=\"You joined the developer organization\"\n description={`You now have ${invitation.role.toLowerCase()} access to ${invitation.organization.name}.`}\n action={\n <button\n type=\"button\"\n onClick={() =>\n navigate?.(\n `${basePath}/organizations/${invitation.organization.id}`,\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\"\n >\n Open organization\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n if (rejected) {\n return (\n <PageLayout title=\"Invitation declined\">\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-warning-text\" />}\n title=\"Invitation declined\"\n description={`You declined the invitation to join ${invitation.organization.name}.`}\n action={\n <button\n type=\"button\"\n onClick={() => navigate?.(`${basePath}`)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n Return to Devportal\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Developer Team Invitation\"\n description=\"Review your invitation to join a developer organization\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <PageSection title=\"Invitation details\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Organization</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {invitation.organization.name}\n </p>\n </div>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invited email</p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Mail size={14} />\n {invitation.invitedEmail}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Role</p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Shield size={14} />\n {invitation.role}\n </p>\n </div>\n </div>\n {invitation.message ? (\n <div>\n <p className=\"text-sm text-text-secondary\">Message</p>\n <p className=\"rounded-md bg-bg-sunken px-3 py-2 text-sm text-text-primary whitespace-pre-line\">\n {invitation.message}\n </p>\n </div>\n ) : null}\n <p className=\"text-xs text-text-secondary\">\n Expires on {new Date(invitation.expiresAt).toLocaleString()}\n </p>\n </div>\n </PageSection>\n\n <div className=\"flex flex-wrap gap-3 justify-end\">\n <button\n type=\"button\"\n onClick={() => void handleReject()}\n disabled={accepting || rejecting}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken disabled:opacity-50\"\n >\n {rejecting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n Decline\n </button>\n <button\n type=\"button\"\n onClick={() => void handleAccept()}\n disabled={accepting || rejecting}\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 {accepting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n Accept invitation\n </button>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -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 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 { InputField, TextareaField } from \"../components/FormField\";\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 useUpdateOrganizationMutation,\n useUpdateOrgLegalInfoMutation,\n useUpdateOrgTaxInfoMutation,\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 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\nconst ORG_ROLE_PRIORITY: Record<DeveloperOrgMember[\"role\"], number> = {\n VIEWER: 0,\n DEVELOPER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\n/**\n * Organization detail page\n */\nexport const OrganizationDetailPage: FC = () => {\n const { navigate, basePath, setActiveOrgId, currentUser } = 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 [activeTab, setActiveTab] = useState<TabId>(\"overview\");\n\n const allTabs: 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 provisionalMembers: DeveloperOrgMember[] =\n (resolvedData?.developerOrganization?.members ?? []).map(mapMember);\n const currentMembership = currentUser\n ? provisionalMembers.find((member: DeveloperOrgMember) => member.userId === currentUser.id)\n : undefined;\n const currentRole: DeveloperOrgMember[\"role\"] | undefined = currentMembership?.role;\n const canCreateApps =\n currentRole !== undefined &&\n ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.DEVELOPER;\n const canManageOrg =\n currentRole !== undefined && ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.ADMIN;\n const canViewRevenue = canManageOrg;\n const canInviteMembers = canManageOrg;\n\n const tabs = allTabs.filter((tab) => tab.id !== \"settings\" || canManageOrg);\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 useEffect(() => {\n if (activeTab === \"settings\" && !canManageOrg) {\n setActiveTab(\"overview\");\n }\n }, [activeTab, canManageOrg]);\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 = provisionalMembers;\n const apps = (appsData?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? []) as Application[];\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 {canViewRevenue ? (\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 ) : null}\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 ...(canInviteMembers\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 ...(canCreateApps\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 ...(canManageOrg\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: <Settings size={16} />,\n onClick: () => setActiveTab(\"settings\"),\n done: Boolean(org.isVerified),\n }]\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 canCreateApps={canCreateApps}\n canViewRevenue={canViewRevenue}\n onNavigate={handleNavigate}\n onShowApps={() => setActiveTab(\"apps\")}\n />\n )}\n {activeTab === \"apps\" && (\n <AppsTab apps={apps} onNavigate={handleNavigate} canCreateApps={canCreateApps} />\n )}\n {activeTab === \"members\" && (\n <MembersTab\n members={members}\n onNavigate={handleNavigate}\n orgId={org.id}\n canInviteMembers={canInviteMembers}\n />\n )}\n {activeTab === \"settings\" && canManageOrg && <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 canCreateApps: boolean;\n canViewRevenue: boolean;\n onNavigate: (path: string) => void;\n onShowApps: () => void;\n}> = ({\n org,\n apps,\n members,\n canCreateApps,\n canViewRevenue,\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={canViewRevenue ? 4 : 3}>\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 />\n {canViewRevenue ? (\n <StatCard\n title={tr(\"devportal.totalRevenue\", \"Total Revenue\")}\n value={`$${org.totalRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n ) : null}\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 action={\n canCreateApps ? (\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 ) : undefined\n }\n />\n )}\n </PageSection>\n\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Stats */}\n {canViewRevenue ? (\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 ) : null}\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 canCreateApps: boolean;\n}> = ({ apps, onNavigate, canCreateApps }) => {\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 {canCreateApps ? (\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 ) : null}\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 canCreateApps ? (\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 ) : undefined\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 canInviteMembers: boolean;\n}> = ({ members, onNavigate, orgId, canInviteMembers }) => {\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 {canInviteMembers ? (\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 ) : null}\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 />\n </div>\n );\n};\n\n// Settings Tab\nconst SettingsTab: FC<{ org: DeveloperOrganization }> = ({ org }) => {\n const { t } = useI18n();\n const { allowed: canUpdate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_UPDATE,\n );\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [profileForm, setProfileForm] = useState({\n name: org.name,\n description: org.description ?? \"\",\n websiteUrl: org.websiteUrl ?? \"\",\n contactEmail: org.contactEmail ?? \"\",\n supportEmail: org.supportEmail ?? \"\",\n logoUrl: org.logoUrl ?? \"\",\n bannerUrl: org.bannerUrl ?? \"\",\n });\n const [legalForm, setLegalForm] = useState({\n legalEntityName: org.legalEntityName ?? \"\",\n legalEntityType: org.legalEntityType ?? \"\",\n });\n const [taxForm, setTaxForm] = useState({\n taxId: org.taxId ?? \"\",\n taxCountry: org.taxCountry ?? \"\",\n });\n const [saveMessage, setSaveMessage] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [verifyMethod, setVerifyMethod] = useState<string>(\"manual\");\n const [verifySuccess, setVerifySuccess] = useState(false);\n const [updateOrganization, { loading: updatingOrg }] =\n useUpdateOrganizationMutation({\n refetchQueries: [\"GetOrganization\"],\n });\n const [updateOrgLegalInfo, { loading: updatingLegal }] =\n useUpdateOrgLegalInfoMutation({\n refetchQueries: [\"GetOrganization\"],\n });\n const [updateOrgTaxInfo, { loading: updatingTax }] =\n useUpdateOrgTaxInfoMutation({\n refetchQueries: [\"GetOrganization\"],\n });\n const [requestVerification, { loading: verifying }] =\n useRequestOrgVerificationMutation({\n onCompleted: () => setVerifySuccess(true),\n });\n\n useEffect(() => {\n setProfileForm({\n name: org.name,\n description: org.description ?? \"\",\n websiteUrl: org.websiteUrl ?? \"\",\n contactEmail: org.contactEmail ?? \"\",\n supportEmail: org.supportEmail ?? \"\",\n logoUrl: org.logoUrl ?? \"\",\n bannerUrl: org.bannerUrl ?? \"\",\n });\n setLegalForm({\n legalEntityName: org.legalEntityName ?? \"\",\n legalEntityType: org.legalEntityType ?? \"\",\n });\n setTaxForm({\n taxId: org.taxId ?? \"\",\n taxCountry: org.taxCountry ?? \"\",\n });\n }, [org]);\n\n const handleProfileSave = async () => {\n setSaveError(null);\n setSaveMessage(null);\n try {\n await updateOrganization({\n variables: {\n id: org.id,\n input: {\n name: profileForm.name.trim() || undefined,\n description: profileForm.description.trim() || null,\n websiteUrl: profileForm.websiteUrl.trim() || null,\n contactEmail: profileForm.contactEmail.trim() || null,\n supportEmail: profileForm.supportEmail.trim() || null,\n logoUrl: profileForm.logoUrl.trim() || null,\n bannerUrl: profileForm.bannerUrl.trim() || null,\n },\n },\n });\n setSaveMessage(tr(\"devportal.organizationUpdated\", \"Organization details updated\"));\n } catch (error) {\n setSaveError(\n error instanceof Error\n ? error.message\n : tr(\"devportal.failedToUpdateOrganization\", \"Failed to update organization\"),\n );\n }\n };\n\n const handleLegalSave = async () => {\n setSaveError(null);\n setSaveMessage(null);\n try {\n await updateOrgLegalInfo({\n variables: {\n id: org.id,\n input: {\n legalEntityName: legalForm.legalEntityName.trim() || null,\n legalEntityType: legalForm.legalEntityType.trim() || null,\n },\n },\n });\n setSaveMessage(tr(\"devportal.legalInfoUpdated\", \"Legal information updated\"));\n } catch (error) {\n setSaveError(\n error instanceof Error\n ? error.message\n : tr(\"devportal.failedToUpdateLegalInfo\", \"Failed to update legal information\"),\n );\n }\n };\n\n const handleTaxSave = async () => {\n setSaveError(null);\n setSaveMessage(null);\n try {\n await updateOrgTaxInfo({\n variables: {\n id: org.id,\n input: {\n taxId: taxForm.taxId.trim() || null,\n taxCountry: taxForm.taxCountry.trim() || null,\n },\n },\n });\n setSaveMessage(tr(\"devportal.taxInfoUpdated\", \"Tax information updated\"));\n } catch (error) {\n setSaveError(\n error instanceof Error\n ? error.message\n : tr(\"devportal.failedToUpdateTaxInfo\", \"Failed to update tax information\"),\n );\n }\n };\n\n return (\n <div className=\"space-y-6 max-w-2xl\">\n {saveError && (\n <div className=\"rounded-md border border-status-error-bg bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\">\n {saveError}\n </div>\n )}\n {saveMessage && (\n <div className=\"rounded-md border border-status-success-bg bg-status-success-bg-subtle px-4 py-3 text-sm text-status-success-text\">\n {saveMessage}\n </div>\n )}\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n >\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.organizationName\", \"Organization Name\")}\n value={profileForm.name}\n onChange={(event) =>\n setProfileForm((current) => ({ ...current, name: event.target.value }))\n }\n disabled={!canUpdate}\n required\n />\n <InputField\n label={tr(\"devportal.slug\", \"Slug\")}\n value={org.slug}\n disabled\n hint={tr(\"devportal.slugReadOnly\", \"Slug cannot be changed here\")}\n />\n </div>\n <TextareaField\n label={tr(\"devportal.description\", \"Description\")}\n value={profileForm.description}\n onChange={(event) =>\n setProfileForm((current) => ({ ...current, description: event.target.value }))\n }\n disabled={!canUpdate}\n rows={4}\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField label={tr(\"devportal.website\", \"Website\")} type=\"url\" value={profileForm.websiteUrl} onChange={(event) => setProfileForm((current) => ({ ...current, websiteUrl: event.target.value }))} disabled={!canUpdate} />\n <InputField label={tr(\"devportal.contactEmail\", \"Contact Email\")} type=\"email\" value={profileForm.contactEmail} onChange={(event) => setProfileForm((current) => ({ ...current, contactEmail: event.target.value }))} disabled={!canUpdate} />\n <InputField label={tr(\"devportal.supportEmail\", \"Support Email\")} type=\"email\" value={profileForm.supportEmail} onChange={(event) => setProfileForm((current) => ({ ...current, supportEmail: event.target.value }))} disabled={!canUpdate} />\n <InputField label={tr(\"devportal.logoUrl\", \"Logo URL\")} type=\"url\" value={profileForm.logoUrl} onChange={(event) => setProfileForm((current) => ({ ...current, logoUrl: event.target.value }))} disabled={!canUpdate} />\n </div>\n <InputField label={tr(\"devportal.bannerUrl\", \"Banner URL\")} type=\"url\" value={profileForm.bannerUrl} onChange={(event) => setProfileForm((current) => ({ ...current, bannerUrl: event.target.value }))} disabled={!canUpdate} />\n <DetailList\n items={[\n { label: tr(\"devportal.organizationId\", \"Organization ID\"), value: <code className=\"text-xs\">{org.id}</code> },\n { label: tr(\"devportal.tier\", \"Tier\"), value: org.tier },\n { label: tr(\"devportal.partnerTier\", \"Partner Tier\"), value: org.partnerTier || tr(\"devportal.none\", \"None\") },\n { label: tr(\"devportal.created\", \"Created\"), value: new Date(org.createdAt).toLocaleDateString() },\n { label: tr(\"devportal.platformFeeRate\", \"Platform Fee Rate\"), value: `${(org.platformFeeRate * 100).toFixed(0)}%` },\n ]}\n />\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n disabled={!canUpdate || updatingOrg}\n onClick={() => void handleProfileSave()}\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 {updatingOrg ? <Loader2 size={14} className=\"animate-spin\" /> : <Settings size={14} />}\n {tr(\"devportal.saveChanges\", \"Save Changes\")}\n </button>\n </div>\n </div>\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.legalInformation\", \"Legal Information\")}\n >\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.legalEntityName\", \"Legal Entity Name\")}\n value={legalForm.legalEntityName}\n onChange={(event) =>\n setLegalForm((current) => ({ ...current, legalEntityName: event.target.value }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.entityType\", \"Entity Type\")}\n value={legalForm.legalEntityType}\n onChange={(event) =>\n setLegalForm((current) => ({ ...current, legalEntityType: event.target.value }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.taxId\", \"Tax ID\")}\n value={taxForm.taxId}\n onChange={(event) =>\n setTaxForm((current) => ({ ...current, taxId: event.target.value }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.taxCountry\", \"Tax Country\")}\n value={taxForm.taxCountry}\n onChange={(event) =>\n setTaxForm((current) => ({ ...current, taxCountry: event.target.value.toUpperCase() }))\n }\n disabled={!canUpdate}\n />\n </div>\n <DetailList\n items={[\n { label: tr(\"devportal.taxForm\", \"Tax Form\"), value: org.taxFormType || tr(\"devportal.notSubmitted\", \"Not submitted\") },\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} /> {tr(\"devportal.verified\", \"Verified\")}\n </span>\n ) : (\n tr(\"devportal.pendingVerification\", \"Pending verification\")\n ),\n },\n ]}\n />\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={!canUpdate || updatingLegal}\n onClick={() => void handleLegalSave()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken disabled:opacity-50\"\n >\n {updatingLegal ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n {tr(\"devportal.saveLegalInfo\", \"Save Legal Info\")}\n </button>\n <button\n type=\"button\"\n disabled={!canUpdate || updatingTax}\n onClick={() => void handleTaxSave()}\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 {updatingTax ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n {tr(\"devportal.saveTaxInfo\", \"Save Tax Info\")}\n </button>\n </div>\n </div>\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"],"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 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 { InputField, TextareaField } from \"../components/FormField\";\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 useUpdateOrganizationMutation,\n useUpdateOrgLegalInfoMutation,\n useUpdateOrgTaxInfoMutation,\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 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\nconst ORG_ROLE_PRIORITY: Record<DeveloperOrgMember[\"role\"], number> = {\n VIEWER: 0,\n DEVELOPER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\n/**\n * Organization detail page\n */\nexport const OrganizationDetailPage: FC = () => {\n const { navigate, basePath, setActiveOrgId, currentUser } = 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 [activeTab, setActiveTab] = useState<TabId>(\"overview\");\n\n const allTabs: Array<{\n id: TabId;\n label: string;\n 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 provisionalMembers: DeveloperOrgMember[] = (\n resolvedData?.developerOrganization?.members ?? []\n ).map(mapMember);\n const currentMembership = currentUser\n ? provisionalMembers.find(\n (member: DeveloperOrgMember) => member.userId === currentUser.id,\n )\n : undefined;\n const currentRole: DeveloperOrgMember[\"role\"] | undefined =\n currentMembership?.role;\n const canCreateApps =\n currentRole !== undefined &&\n ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.DEVELOPER;\n const canManageOrg =\n currentRole !== undefined &&\n ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.ADMIN;\n const canViewRevenue = canManageOrg;\n const canInviteMembers = canManageOrg;\n\n const tabs = allTabs.filter((tab) => tab.id !== \"settings\" || canManageOrg);\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 useEffect(() => {\n if (activeTab === \"settings\" && !canManageOrg) {\n setActiveTab(\"overview\");\n }\n }, [activeTab, canManageOrg]);\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 = provisionalMembers;\n const apps = (appsData?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? []) as Application[];\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 {canViewRevenue ? (\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 ) : null}\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 ...(canInviteMembers\n ? [\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 : []),\n ...(canCreateApps\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 : []),\n ...(canManageOrg\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: <Settings size={16} />,\n onClick: () => setActiveTab(\"settings\"),\n done: Boolean(org.isVerified),\n },\n ]\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 canCreateApps={canCreateApps}\n canViewRevenue={canViewRevenue}\n onNavigate={handleNavigate}\n onShowApps={() => setActiveTab(\"apps\")}\n />\n )}\n {activeTab === \"apps\" && (\n <AppsTab\n apps={apps}\n onNavigate={handleNavigate}\n canCreateApps={canCreateApps}\n />\n )}\n {activeTab === \"members\" && (\n <MembersTab\n members={members}\n onNavigate={handleNavigate}\n orgId={org.id}\n canInviteMembers={canInviteMembers}\n />\n )}\n {activeTab === \"settings\" && canManageOrg && <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 canCreateApps: boolean;\n canViewRevenue: boolean;\n onNavigate: (path: string) => void;\n onShowApps: () => void;\n}> = ({\n org,\n apps,\n members,\n canCreateApps,\n canViewRevenue,\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={canViewRevenue ? 4 : 3}>\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 />\n {canViewRevenue ? (\n <StatCard\n title={tr(\"devportal.totalRevenue\", \"Total Revenue\")}\n value={`$${org.totalRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n ) : null}\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 action={\n canCreateApps ? (\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 ) : undefined\n }\n />\n )}\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Stats */}\n {canViewRevenue ? (\n <PageSection\n title={tr(\"devportal.revenueSummary\", \"Revenue Summary\")}\n >\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 ) : null}\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 canCreateApps: boolean;\n}> = ({ apps, onNavigate, canCreateApps }) => {\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 {canCreateApps ? (\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 ) : null}\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 canCreateApps ? (\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 ) : undefined\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 canInviteMembers: boolean;\n}> = ({ members, onNavigate, orgId, canInviteMembers }) => {\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 {canInviteMembers ? (\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 ) : null}\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 />\n </div>\n );\n};\n\n// Settings Tab\nconst SettingsTab: FC<{ org: DeveloperOrganization }> = ({ org }) => {\n const { t } = useI18n();\n const { allowed: canUpdate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_UPDATE,\n );\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [profileForm, setProfileForm] = useState({\n name: org.name,\n description: org.description ?? \"\",\n websiteUrl: org.websiteUrl ?? \"\",\n contactEmail: org.contactEmail ?? \"\",\n supportEmail: org.supportEmail ?? \"\",\n logoUrl: org.logoUrl ?? \"\",\n bannerUrl: org.bannerUrl ?? \"\",\n });\n const [legalForm, setLegalForm] = useState({\n legalEntityName: org.legalEntityName ?? \"\",\n legalEntityType: org.legalEntityType ?? \"\",\n });\n const [taxForm, setTaxForm] = useState({\n taxId: org.taxId ?? \"\",\n taxCountry: org.taxCountry ?? \"\",\n });\n const [saveMessage, setSaveMessage] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [verifyMethod, setVerifyMethod] = useState<string>(\"manual\");\n const [verifySuccess, setVerifySuccess] = useState(false);\n const [updateOrganization, { loading: updatingOrg }] =\n useUpdateOrganizationMutation({\n refetchQueries: [\"GetOrganization\"],\n });\n const [updateOrgLegalInfo, { loading: updatingLegal }] =\n useUpdateOrgLegalInfoMutation({\n refetchQueries: [\"GetOrganization\"],\n });\n const [updateOrgTaxInfo, { loading: updatingTax }] =\n useUpdateOrgTaxInfoMutation({\n refetchQueries: [\"GetOrganization\"],\n });\n const [requestVerification, { loading: verifying }] =\n useRequestOrgVerificationMutation({\n onCompleted: () => setVerifySuccess(true),\n });\n\n useEffect(() => {\n setProfileForm({\n name: org.name,\n description: org.description ?? \"\",\n websiteUrl: org.websiteUrl ?? \"\",\n contactEmail: org.contactEmail ?? \"\",\n supportEmail: org.supportEmail ?? \"\",\n logoUrl: org.logoUrl ?? \"\",\n bannerUrl: org.bannerUrl ?? \"\",\n });\n setLegalForm({\n legalEntityName: org.legalEntityName ?? \"\",\n legalEntityType: org.legalEntityType ?? \"\",\n });\n setTaxForm({\n taxId: org.taxId ?? \"\",\n taxCountry: org.taxCountry ?? \"\",\n });\n }, [org]);\n\n const handleProfileSave = async () => {\n setSaveError(null);\n setSaveMessage(null);\n try {\n await updateOrganization({\n variables: {\n id: org.id,\n input: {\n name: profileForm.name.trim() || undefined,\n description: profileForm.description.trim() || null,\n websiteUrl: profileForm.websiteUrl.trim() || null,\n contactEmail: profileForm.contactEmail.trim() || null,\n supportEmail: profileForm.supportEmail.trim() || null,\n logoUrl: profileForm.logoUrl.trim() || null,\n bannerUrl: profileForm.bannerUrl.trim() || null,\n },\n },\n });\n setSaveMessage(\n tr(\"devportal.organizationUpdated\", \"Organization details updated\"),\n );\n } catch (error) {\n setSaveError(\n error instanceof Error\n ? error.message\n : tr(\n \"devportal.failedToUpdateOrganization\",\n \"Failed to update organization\",\n ),\n );\n }\n };\n\n const handleLegalSave = async () => {\n setSaveError(null);\n setSaveMessage(null);\n try {\n await updateOrgLegalInfo({\n variables: {\n id: org.id,\n input: {\n legalEntityName: legalForm.legalEntityName.trim() || null,\n legalEntityType: legalForm.legalEntityType.trim() || null,\n },\n },\n });\n setSaveMessage(\n tr(\"devportal.legalInfoUpdated\", \"Legal information updated\"),\n );\n } catch (error) {\n setSaveError(\n error instanceof Error\n ? error.message\n : tr(\n \"devportal.failedToUpdateLegalInfo\",\n \"Failed to update legal information\",\n ),\n );\n }\n };\n\n const handleTaxSave = async () => {\n setSaveError(null);\n setSaveMessage(null);\n try {\n await updateOrgTaxInfo({\n variables: {\n id: org.id,\n input: {\n taxId: taxForm.taxId.trim() || null,\n taxCountry: taxForm.taxCountry.trim() || null,\n },\n },\n });\n setSaveMessage(tr(\"devportal.taxInfoUpdated\", \"Tax information updated\"));\n } catch (error) {\n setSaveError(\n error instanceof Error\n ? error.message\n : tr(\n \"devportal.failedToUpdateTaxInfo\",\n \"Failed to update tax information\",\n ),\n );\n }\n };\n\n return (\n <div className=\"space-y-6 max-w-2xl\">\n {saveError && (\n <div className=\"rounded-md border border-status-error-bg bg-status-error-bg-subtle px-4 py-3 text-sm text-status-error-text\">\n {saveError}\n </div>\n )}\n {saveMessage && (\n <div className=\"rounded-md border border-status-success-bg bg-status-success-bg-subtle px-4 py-3 text-sm text-status-success-text\">\n {saveMessage}\n </div>\n )}\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n >\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.organizationName\", \"Organization Name\")}\n value={profileForm.name}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n name: event.target.value,\n }))\n }\n disabled={!canUpdate}\n required\n />\n <InputField\n label={tr(\"devportal.slug\", \"Slug\")}\n value={org.slug}\n disabled\n hint={tr(\"devportal.slugReadOnly\", \"Slug cannot be changed here\")}\n />\n </div>\n <TextareaField\n label={tr(\"devportal.description\", \"Description\")}\n value={profileForm.description}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n description: event.target.value,\n }))\n }\n disabled={!canUpdate}\n rows={4}\n />\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.website\", \"Website\")}\n type=\"url\"\n value={profileForm.websiteUrl}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n websiteUrl: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.contactEmail\", \"Contact Email\")}\n type=\"email\"\n value={profileForm.contactEmail}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n contactEmail: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.supportEmail\", \"Support Email\")}\n type=\"email\"\n value={profileForm.supportEmail}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n supportEmail: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.logoUrl\", \"Logo URL\")}\n type=\"url\"\n value={profileForm.logoUrl}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n logoUrl: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n </div>\n <InputField\n label={tr(\"devportal.bannerUrl\", \"Banner URL\")}\n type=\"url\"\n value={profileForm.bannerUrl}\n onChange={(event) =>\n setProfileForm((current) => ({\n ...current,\n bannerUrl: event.target.value,\n }))\n }\n disabled={!canUpdate}\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.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 <div className=\"flex justify-end\">\n <button\n type=\"button\"\n disabled={!canUpdate || updatingOrg}\n onClick={() => void handleProfileSave()}\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 {updatingOrg ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : (\n <Settings size={14} />\n )}\n {tr(\"devportal.saveChanges\", \"Save Changes\")}\n </button>\n </div>\n </div>\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.legalInformation\", \"Legal Information\")}\n >\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.legalEntityName\", \"Legal Entity Name\")}\n value={legalForm.legalEntityName}\n onChange={(event) =>\n setLegalForm((current) => ({\n ...current,\n legalEntityName: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.entityType\", \"Entity Type\")}\n value={legalForm.legalEntityType}\n onChange={(event) =>\n setLegalForm((current) => ({\n ...current,\n legalEntityType: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.taxId\", \"Tax ID\")}\n value={taxForm.taxId}\n onChange={(event) =>\n setTaxForm((current) => ({\n ...current,\n taxId: event.target.value,\n }))\n }\n disabled={!canUpdate}\n />\n <InputField\n label={tr(\"devportal.taxCountry\", \"Tax Country\")}\n value={taxForm.taxCountry}\n onChange={(event) =>\n setTaxForm((current) => ({\n ...current,\n taxCountry: event.target.value.toUpperCase(),\n }))\n }\n disabled={!canUpdate}\n />\n </div>\n <DetailList\n items={[\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 <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={!canUpdate || updatingLegal}\n onClick={() => void handleLegalSave()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken disabled:opacity-50\"\n >\n {updatingLegal ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : null}\n {tr(\"devportal.saveLegalInfo\", \"Save Legal Info\")}\n </button>\n <button\n type=\"button\"\n disabled={!canUpdate || updatingTax}\n onClick={() => void handleTaxSave()}\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 {updatingTax ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : null}\n {tr(\"devportal.saveTaxInfo\", \"Save Tax Info\")}\n </button>\n </div>\n </div>\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"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationMembersPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationMembersPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Users,\n Mail,\n Shield,\n UserMinus,\n RefreshCw,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { InputField, SelectField, TextareaField } from \"../components/FormField\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type { DeveloperOrgRole } from \"../types\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport { format } from \"date-fns\";\nimport {\n useGetOrganizationQuery,\n useGetOrganizationMembersQuery,\n useGetOrganizationInvitationsQuery,\n useInviteMemberMutation,\n useRemoveMemberMutation,\n useSuspendMemberMutation,\n useReactivateMemberMutation,\n useUpdateMemberRoleMutation,\n useTransferOwnershipMutation,\n useCancelInvitationMutation,\n useResendInvitationMutation,\n type OrgMemberFieldsFragment,\n type OrgInvitationFieldsFragment,\n} from \"../hooks\";\n\nconst ORG_ROLE_PRIORITY: Record<DeveloperOrgRole, number> = {\n VIEWER: 0,\n DEVELOPER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\nexport const OrganizationMembersPage: FC = () => {\n const { orgId } = useParams<{ orgId: string }>();\n const { currentUser } = useDevportal();\n const { allowed: canInviteByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_INVITATION_CREATE,\n );\n const { allowed: canManageMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_UPDATE,\n );\n const { allowed: canRemoveMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DELETE,\n );\n const { allowed: canActivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_ACTIVATE,\n );\n const { allowed: canDeactivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DEACTIVATE,\n );\n const resolveMemberLabel = (member: {\n userId: string;\n email?: string | null;\n }): string => {\n if (member.email) return member.email;\n if (currentUser?.id === member.userId && currentUser.email)\n return currentUser.email;\n return member.userId;\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 const [showInviteDialog, setShowInviteDialog] = useState(false);\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [inviteRole, setInviteRole] = useState<DeveloperOrgRole>(\"DEVELOPER\");\n const [inviteMessage, setInviteMessage] = useState(\"\");\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionSuccess, setActionSuccess] = useState<string | null>(null);\n const [selectedMemberIds, setSelectedMemberIds] = useState<Set<string>>(\n new Set(),\n );\n const [selectedInvitationIds, setSelectedInvitationIds] = useState<\n Set<string>\n >(new Set());\n const [showBulkRemoveMembersDialog, setShowBulkRemoveMembersDialog] =\n useState(false);\n const [showBulkCancelInvitationsDialog, setShowBulkCancelInvitationsDialog] =\n useState(false);\n const [transferOwnershipMember, setTransferOwnershipMember] =\n useState<OrgMemberFieldsFragment | null>(null);\n\n const { data: orgData } = useGetOrganizationQuery({\n variables: { id: orgId ?? \"\" },\n skip: !orgId,\n fetchPolicy: \"cache-first\",\n });\n useEffect(() => {\n const name = orgData?.developerOrganization?.name;\n if (!orgId || !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(orgId, name);\n return () => reg?.unregister(orgId);\n }, [orgId, orgData?.developerOrganization?.name]);\n\n // Queries\n const {\n data: membersData,\n loading: membersLoading,\n error: membersError,\n } = useGetOrganizationMembersQuery({\n variables: { organizationId: orgId! },\n skip: !orgId,\n fetchPolicy: \"cache-and-network\",\n });\n\n // Mutations\n const [inviteMember, { loading: inviting }] = useInviteMemberMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [removeMember] = useRemoveMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [suspendMember] = useSuspendMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [reactivateMember] = useReactivateMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [updateMemberRole] = useUpdateMemberRoleMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [transferOwnership] = useTransferOwnershipMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [cancelInvitation] = useCancelInvitationMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [resendInvitation] = useResendInvitationMutation();\n\n // Derived data\n const members: OrgMemberFieldsFragment[] = useMemo(\n () =>\n membersData?.developerOrgMembers?.edges?.map(\n (e: { node: OrgMemberFieldsFragment }) => e.node,\n ) ?? [],\n [membersData?.developerOrgMembers?.edges],\n );\n\n const currentMembership = currentUser\n ? members.find((member) => member.userId === currentUser.id)\n : undefined;\n const currentRole = currentMembership?.role as DeveloperOrgRole | undefined;\n const canManageOrg =\n currentRole !== undefined && ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.ADMIN;\n const canInvite = canManageOrg && canInviteByPermission;\n const canManageMembers = canManageOrg && canManageMembersByPermission;\n const canRemoveMembers = canManageOrg && canRemoveMembersByPermission;\n const canActivateMembers = canManageOrg && canActivateMembersByPermission;\n const canDeactivateMembers = canManageOrg && canDeactivateMembersByPermission;\n\n const {\n data: invitationsData,\n loading: invitationsLoading,\n error: invitationsError,\n } = useGetOrganizationInvitationsQuery({\n variables: { organizationId: orgId!, status: \"PENDING\" as never },\n skip: !orgId || !canManageOrg,\n fetchPolicy: \"cache-and-network\",\n });\n\n const invitations: OrgInvitationFieldsFragment[] = useMemo(\n () =>\n invitationsData?.developerOrgInvitations?.edges?.map(\n (e: { node: OrgInvitationFieldsFragment }) => e.node,\n ) ?? [],\n [invitationsData?.developerOrgInvitations?.edges],\n );\n\n const membersCount = membersData?.developerOrgMembers?.totalCount ?? 0;\n const invitationsCount =\n invitationsData?.developerOrgInvitations?.totalCount ?? 0;\n\n const selectedMembers = useMemo(\n () => members.filter((member) => selectedMemberIds.has(member.id)),\n [members, selectedMemberIds],\n );\n const selectedInvitations = useMemo(\n () =>\n invitations.filter((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ),\n [invitations, selectedInvitationIds],\n );\n\n const selectableMembers = members.filter((member) => member.role !== \"OWNER\");\n const allMembersSelected =\n selectableMembers.length > 0 &&\n selectableMembers.every((member) => selectedMemberIds.has(member.id));\n const partiallySelectedMembers =\n selectableMembers.some((member) => selectedMemberIds.has(member.id)) &&\n !allMembersSelected;\n\n const allInvitationsSelected =\n invitations.length > 0 &&\n invitations.every((invitation) => selectedInvitationIds.has(invitation.id));\n const partiallySelectedInvitations =\n invitations.some((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ) && !allInvitationsSelected;\n\n const suspendableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\" && !member.isSuspended,\n );\n const reactivatableMembers = selectedMembers.filter(\n (member) => member.isSuspended,\n );\n const removableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\",\n );\n\n const handleInvite = async () => {\n if (!orgId || !inviteEmail.trim()) return;\n setActionError(null);\n\n try {\n await inviteMember({\n variables: {\n organizationId: orgId,\n input: {\n email: inviteEmail,\n role: inviteRole as never,\n message: inviteMessage || undefined,\n },\n },\n });\n setShowInviteDialog(false);\n setInviteEmail(\"\");\n setInviteRole(\"DEVELOPER\");\n setInviteMessage(\"\");\n setActionSuccess(\n tr(\n \"devportal.invitationSent\",\n \"Invitation created and email sent to the team member.\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSendInvitation\", \"Failed to send invitation\"),\n );\n }\n };\n\n const handleRemoveMember = async (memberId: string) => {\n setActionError(null);\n try {\n await removeMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToRemoveMember\", \"Failed to remove member\"),\n );\n }\n };\n\n const handleSuspendMember = async (memberId: string, reason?: string) => {\n setActionError(null);\n try {\n await suspendMember({\n variables: { id: memberId, reason: reason || undefined },\n });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSuspendMember\", \"Failed to suspend member\"),\n );\n }\n };\n\n const handleReactivateMember = async (memberId: string) => {\n setActionError(null);\n try {\n await reactivateMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToReactivateMember\",\n \"Failed to reactivate member\",\n ),\n );\n }\n };\n\n const handleUpdateMemberRole = async (\n memberId: string,\n role: DeveloperOrgRole,\n ) => {\n setActionError(null);\n try {\n await updateMemberRole({\n variables: {\n id: memberId,\n role: role as never,\n permissions: undefined,\n },\n });\n setActionSuccess(\n tr(\"devportal.memberRoleUpdated\", \"Member role updated successfully\"),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToUpdateMemberRole\",\n \"Failed to update member role\",\n ),\n );\n }\n };\n\n const handleTransferOwnership = async () => {\n const member = transferOwnershipMember;\n if (!orgId || !member) return;\n setActionError(null);\n\n try {\n await transferOwnership({\n variables: { organizationId: orgId, newOwnerId: member.userId },\n });\n setTransferOwnershipMember(null);\n setActionSuccess(\n tr(\n \"devportal.organizationOwnershipTransferred\",\n \"Organization ownership transferred successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToTransferOwnership\",\n \"Failed to transfer organization ownership\",\n ),\n );\n }\n };\n\n const handleCancelInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await cancelInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToCancelInvitation\",\n \"Failed to cancel invitation\",\n ),\n );\n }\n };\n\n const handleResendInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await resendInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToResendInvitation\",\n \"Failed to resend invitation\",\n ),\n );\n }\n };\n\n const clearSelections = () => {\n setSelectedMemberIds(new Set());\n setSelectedInvitationIds(new Set());\n };\n\n const toggleMemberSelection = (memberId: string, checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(memberId);\n } else {\n next.delete(memberId);\n }\n return next;\n });\n };\n\n const toggleAllMembers = (checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n selectableMembers.forEach((member) => {\n if (checked) {\n next.add(member.id);\n } else {\n next.delete(member.id);\n }\n });\n return next;\n });\n };\n\n const toggleInvitationSelection = (\n invitationId: string,\n checked: boolean,\n ) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(invitationId);\n } else {\n next.delete(invitationId);\n }\n return next;\n });\n };\n\n const toggleAllInvitations = (checked: boolean) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n invitations.forEach((invitation) => {\n if (checked) {\n next.add(invitation.id);\n } else {\n next.delete(invitation.id);\n }\n });\n return next;\n });\n };\n\n const handleBulkSuspendMembers = async () => {\n if (suspendableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n suspendableMembers.map((member) =>\n suspendMember({ variables: { id: member.id, reason: undefined } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.suspended\", \"Suspended\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkReactivateMembers = async () => {\n if (reactivatableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n reactivatableMembers.map((member) =>\n reactivateMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.reactivated\", \"Reactivated\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkRemoveMembers = async () => {\n if (removableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n removableMembers.map((member) =>\n removeMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.removed\", \"Removed\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkRemoveMembersDialog(false);\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkResendInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n resendInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.resent\", \"Resent\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedInvitationIds(new Set());\n };\n\n const handleBulkCancelInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n cancelInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.cancelled\", \"Cancelled\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkCancelInvitationsDialog(false);\n setSelectedInvitationIds(new Set());\n };\n\n const isLoading = membersLoading || invitationsLoading;\n const hasError = membersError || invitationsError;\n\n if (isLoading && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (hasError && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\"devportal.failedToLoadMembers\", \"Failed to load members\")}\n description={\n membersError?.message ||\n invitationsError?.message ||\n tr(\n \"devportal.anErrorOccurredWhileLoadingTeamData\",\n \"An error occurred while loading team data\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.ORG_MEMBER_READ}>\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n purpose={tr(\n \"devportal.teamMembersPurpose\",\n \"Control who can work on this organization's apps and what they can do. Invite teammates by email, assign roles to grant the right level of access, and suspend or remove anyone who should no longer have it.\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n actions={\n canInvite ? (\n <button\n onClick={() => setShowInviteDialog(true)}\n disabled={!canInvite}\n aria-disabled={!canInvite}\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 <Plus size={16} />\n {tr(\"devportal.inviteMember\", \"Invite Member\")}\n </button>\n ) : undefined\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {(selectedMemberIds.size > 0 || selectedInvitationIds.size > 0) && (\n <div className=\"flex flex-wrap items-center gap-3 rounded-card border border-border-seam bg-bg-surface p-4\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedMemberIds.size + selectedInvitationIds.size}{\" \"}\n {tr(\"devportal.selected\", \"selected\")}\n </span>\n <button\n onClick={clearSelections}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr(\"devportal.clearAllSelections\", \"Clear all selections\")}\n </button>\n </div>\n )}\n\n {/* Current Members */}\n <PageSection\n title={`${tr(\"devportal.members\", \"Members\")} (${membersCount})`}\n actions={\n members.length > 0 && canManageOrg ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkSuspendMembers}\n disabled={\n suspendableMembers.length === 0 || !canDeactivateMembers\n }\n aria-disabled={!canDeactivateMembers}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.suspendSelected\", \"Suspend Selected\")}\n {suspendableMembers.length > 0\n ? ` (${suspendableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={handleBulkReactivateMembers}\n disabled={\n reactivatableMembers.length === 0 || !canActivateMembers\n }\n aria-disabled={!canActivateMembers}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.reactivateSelected\", \"Reactivate Selected\")}\n {reactivatableMembers.length > 0\n ? ` (${reactivatableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkRemoveMembersDialog(true)}\n disabled={removableMembers.length === 0 || !canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.removeSelected\", \"Remove Selected\")}\n {removableMembers.length > 0\n ? ` (${removableMembers.length})`\n : \"\"}\n </button>\n </div>\n ) : null\n }\n >\n {members.length > 0 ? (\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n ...(canManageOrg\n ? [{\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allMembersSelected}\n indeterminate={partiallySelectedMembers}\n onChange={toggleAllMembers}\n ariaLabel={tr(\n \"devportal.selectAllMembers\",\n \"Select all members\",\n )}\n />\n ),\n className: \"w-12\",\n render: (member: OrgMemberFieldsFragment) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedMemberIds.has(member.id)}\n disabled={member.role === \"OWNER\"}\n onChange={(checked) =>\n toggleMemberSelection(member.id, checked)\n }\n ariaLabel={`Select member ${resolveMemberLabel(member)}`}\n />\n </div>\n ),\n }]\n : []),\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => {\n const label = resolveMemberLabel(member);\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-action-primary-bg/10 text-primary text-sm font-medium\">\n {label.charAt(0).toUpperCase()}\n </div>\n <div>\n <p className=\"font-medium\">{label}</p>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.joined\", \"Joined\")}{\" \"}\n {format(new Date(member.joinedAt), \"MMM d, yyyy\")}\n </p>\n </div>\n </div>\n );\n },\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <div className=\"flex items-center gap-2\">\n <Shield size={14} className=\"text-text-secondary\" />\n {member.role === \"OWNER\" || !canManageMembers ? (\n <span>\n {ORG_ROLE_LABELS[member.role as DeveloperOrgRole] ??\n member.role}\n </span>\n ) : (\n <select\n value={member.role}\n onChange={(event) =>\n void handleUpdateMemberRole(\n member.id,\n event.target.value as DeveloperOrgRole,\n )\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary\"\n >\n {Object.entries(ORG_ROLE_LABELS)\n .filter(([value]) => value !== \"OWNER\")\n .map(([value, label]) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n )}\n </div>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (member) =>\n member.isSuspended ? (\n <StatusBadge status=\"SUSPENDED\" type=\"app\" />\n ) : member.isActive ? (\n <StatusBadge status=\"ACTIVE\" type=\"app\" />\n ) : (\n <StatusBadge status=\"INACTIVE\" type=\"app\" />\n ),\n },\n ...(canManageOrg\n ? [{\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (member: OrgMemberFieldsFragment) =>\n member.role !== \"OWNER\" && (\n <div className=\"flex gap-1\">\n {member.isSuspended ? (\n <button\n className=\"text-xs text-status-success-text hover:underline disabled:opacity-50\"\n disabled={!canActivateMembers}\n aria-disabled={!canActivateMembers}\n title={tr(\n \"devportal.reactivateMember\",\n \"Reactivate member\",\n )}\n onClick={() => handleReactivateMember(member.id)}\n >\n {tr(\"devportal.reactivate\", \"Reactivate\")}\n </button>\n ) : (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeactivateMembers}\n aria-disabled={!canDeactivateMembers}\n title={tr(\n \"devportal.suspendMember\",\n \"Suspend member\",\n )}\n onClick={() => handleSuspendMember(member.id)}\n >\n {tr(\"devportal.suspend\", \"Suspend\")}\n </button>\n )}\n <button\n className=\"text-xs text-status-error-text hover:underline disabled:opacity-50\"\n disabled={!canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n title={tr(\"devportal.removeMember\", \"Remove member\")}\n onClick={() => handleRemoveMember(member.id)}\n >\n {tr(\"devportal.remove\", \"Remove\")}\n </button>\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canManageMembers}\n aria-disabled={!canManageMembers}\n title={tr(\n \"devportal.transferOwnership\",\n \"Transfer ownership\",\n )}\n onClick={() => setTransferOwnershipMember(member)}\n >\n {tr(\"devportal.makeOwner\", \"Make Owner\")}\n </button>\n </div>\n ),\n }]\n : []),\n ]}\n />\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noMembers\", \"No members\")}\n description={tr(\n \"devportal.inviteTeamMembersToCollaborate\",\n \"Invite team members to collaborate\",\n )}\n />\n )}\n </PageSection>\n\n {/* Pending Invitations */}\n {canManageOrg && invitations.length > 0 && (\n <PageSection\n title={`${tr(\"devportal.pendingInvitations\", \"Pending Invitations\")} (${invitationsCount})`}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkResendInvitations}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-primary/30 px-3 py-2 text-sm font-medium text-primary hover:bg-action-primary-bg/5 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.resendSelected\", \"Resend Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkCancelInvitationsDialog(true)}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.cancelSelected\", \"Cancel Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n </div>\n }\n >\n <DataTable\n data={invitations}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allInvitationsSelected}\n indeterminate={partiallySelectedInvitations}\n onChange={toggleAllInvitations}\n ariaLabel={tr(\n \"devportal.selectAllInvitations\",\n \"Select all invitations\",\n )}\n />\n ),\n className: \"w-12\",\n render: (invitation) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedInvitationIds.has(invitation.id)}\n onChange={(checked) =>\n toggleInvitationSelection(invitation.id, checked)\n }\n ariaLabel={`Select invitation ${invitation.invitedEmail}`}\n />\n </div>\n ),\n },\n {\n key: \"invitedEmail\",\n header: tr(\"devportal.emailColumn\", \"Email\"),\n render: (inv) => (\n <div className=\"flex items-center gap-2\">\n <Mail size={16} className=\"text-text-secondary\" />\n {inv.invitedEmail}\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.invitedRoleColumn\", \"Invited Role\"),\n render: (inv) =>\n ORG_ROLE_LABELS[inv.role as DeveloperOrgRole] ?? inv.role,\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (inv) => (\n <StatusBadge status={inv.status} type=\"invitation\" />\n ),\n },\n {\n key: \"expiresAt\",\n header: tr(\"devportal.expiresColumn\", \"Expires\"),\n render: (inv) =>\n format(new Date(inv.expiresAt), \"MMM d, yyyy\"),\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-24\",\n render: (inv) => (\n <div className=\"flex gap-1\">\n <button\n className=\"rounded p-1 hover:bg-bg-sunken\"\n title={tr(\"devportal.resend\", \"Resend\")}\n onClick={() => handleResendInvitation(inv.id)}\n >\n <RefreshCw size={14} />\n </button>\n <button\n className=\"rounded p-1 hover:bg-bg-sunken text-status-error-text\"\n title={tr(\"devportal.cancel\", \"Cancel\")}\n onClick={() => handleCancelInvitation(inv.id)}\n >\n <UserMinus size={14} />\n </button>\n </div>\n ),\n },\n ]}\n />\n </PageSection>\n )}\n\n {/* Invite Dialog */}\n {showInviteDialog && (\n <ConfirmDialog\n open={showInviteDialog}\n onOpenChange={setShowInviteDialog}\n onConfirm={handleInvite}\n title={tr(\"devportal.inviteTeamMember\", \"Invite Team Member\")}\n confirmLabel={\n inviting\n ? tr(\"devportal.sendingDots\", \"Sending...\")\n : tr(\"devportal.sendInvitation\", \"Send Invitation\")\n }\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.emailAddress\", \"Email Address\")}\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@example.com\"\n hint={tr(\n \"devportal.mustBeExistingVerifiedUser\",\n \"Must be an existing verified user\",\n )}\n required\n />\n <SelectField\n label={tr(\"devportal.roleColumn\", \"Role\")}\n value={inviteRole}\n onChange={(e) =>\n setInviteRole(e.target.value as DeveloperOrgRole)\n }\n options={[\n {\n value: \"ADMIN\",\n label: tr(\n \"devportal.adminFullAccess\",\n \"Admin - Full access\",\n ),\n },\n {\n value: \"DEVELOPER\",\n label: tr(\n \"devportal.developerCreateAndManageApps\",\n \"Developer - Create and manage apps\",\n ),\n },\n {\n value: \"VIEWER\",\n label: tr(\n \"devportal.viewerReadOnlyAccess\",\n \"Viewer - Read-only access\",\n ),\n },\n ]}\n required\n />\n <TextareaField\n label={tr(\"devportal.personalMessage\", \"Personal Message\")}\n value={inviteMessage}\n onChange={(e) => setInviteMessage(e.target.value)}\n placeholder={tr(\n \"devportal.personalMessagePlaceholder\",\n \"Add a short note to include in the invitation email\",\n )}\n rows={3}\n />\n </div>\n </ConfirmDialog>\n )}\n\n <ConfirmDialog\n open={showBulkRemoveMembersDialog}\n onOpenChange={setShowBulkRemoveMembersDialog}\n onConfirm={handleBulkRemoveMembers}\n title={tr(\n \"devportal.removeSelectedMembers\",\n \"Remove selected members\",\n )}\n description={`${tr(\"devportal.removeNSelectedMembers\", \"Remove\")} ${removableMembers.length} ${tr(\"devportal.selectedMembersFromOrg\", \"selected member(s) from this organization? This action cannot be undone.\")}`}\n confirmLabel={tr(\"devportal.removeMembers\", \"Remove Members\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={showBulkCancelInvitationsDialog}\n onOpenChange={setShowBulkCancelInvitationsDialog}\n onConfirm={handleBulkCancelInvitations}\n title={tr(\n \"devportal.cancelSelectedInvitations\",\n \"Cancel selected invitations\",\n )}\n description={`${tr(\"devportal.cancelNPendingInvitations\", \"Cancel\")} ${selectedInvitations.length} ${tr(\"devportal.pendingInvitationsQuestion\", \"pending invitation(s)?\")}`}\n confirmLabel={tr(\"devportal.cancelInvitations\", \"Cancel Invitations\")}\n cancelLabel={tr(\"devportal.keepInvitations\", \"Keep Invitations\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={transferOwnershipMember !== null}\n onOpenChange={(open) => {\n if (!open) setTransferOwnershipMember(null);\n }}\n onConfirm={handleTransferOwnership}\n title={tr(\"devportal.transferOwnership\", \"Transfer ownership\")}\n description={\n transferOwnershipMember\n ? tr(\n \"devportal.transferOwnershipConfirmation\",\n `Transfer organization ownership to ${resolveMemberLabel(transferOwnershipMember)}?`,\n )\n : undefined\n }\n confirmLabel={tr(\"devportal.makeOwner\", \"Make Owner\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"warning\"\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OrganizationMembersPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationMembersPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Users,\n Mail,\n Shield,\n UserMinus,\n RefreshCw,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { ConfirmDialog } from \"../components/ConfirmDialog\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport {\n InputField,\n SelectField,\n TextareaField,\n} from \"../components/FormField\";\nimport { SelectionCheckbox } from \"../components/SelectionCheckbox\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type { DeveloperOrgRole } from \"../types\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport { format } from \"date-fns\";\nimport {\n useGetOrganizationQuery,\n useGetOrganizationMembersQuery,\n useGetOrganizationInvitationsQuery,\n useInviteMemberMutation,\n useRemoveMemberMutation,\n useSuspendMemberMutation,\n useReactivateMemberMutation,\n useUpdateMemberRoleMutation,\n useTransferOwnershipMutation,\n useCancelInvitationMutation,\n useResendInvitationMutation,\n type OrgMemberFieldsFragment,\n type OrgInvitationFieldsFragment,\n} from \"../hooks\";\n\nconst ORG_ROLE_PRIORITY: Record<DeveloperOrgRole, number> = {\n VIEWER: 0,\n DEVELOPER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\nexport const OrganizationMembersPage: FC = () => {\n const { orgId } = useParams<{ orgId: string }>();\n const { currentUser } = useDevportal();\n const { allowed: canInviteByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_INVITATION_CREATE,\n );\n const { allowed: canManageMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_UPDATE,\n );\n const { allowed: canRemoveMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DELETE,\n );\n const { allowed: canActivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_ACTIVATE,\n );\n const { allowed: canDeactivateMembersByPermission } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_MEMBER_DEACTIVATE,\n );\n const resolveMemberLabel = (member: {\n userId: string;\n email?: string | null;\n }): string => {\n if (member.email) return member.email;\n if (currentUser?.id === member.userId && currentUser.email)\n return currentUser.email;\n return member.userId;\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 const [showInviteDialog, setShowInviteDialog] = useState(false);\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [inviteRole, setInviteRole] = useState<DeveloperOrgRole>(\"DEVELOPER\");\n const [inviteMessage, setInviteMessage] = useState(\"\");\n const [actionError, setActionError] = useState<string | null>(null);\n const [actionSuccess, setActionSuccess] = useState<string | null>(null);\n const [selectedMemberIds, setSelectedMemberIds] = useState<Set<string>>(\n new Set(),\n );\n const [selectedInvitationIds, setSelectedInvitationIds] = useState<\n Set<string>\n >(new Set());\n const [showBulkRemoveMembersDialog, setShowBulkRemoveMembersDialog] =\n useState(false);\n const [showBulkCancelInvitationsDialog, setShowBulkCancelInvitationsDialog] =\n useState(false);\n const [transferOwnershipMember, setTransferOwnershipMember] =\n useState<OrgMemberFieldsFragment | null>(null);\n\n const { data: orgData } = useGetOrganizationQuery({\n variables: { id: orgId ?? \"\" },\n skip: !orgId,\n fetchPolicy: \"cache-first\",\n });\n useEffect(() => {\n const name = orgData?.developerOrganization?.name;\n if (!orgId || !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(orgId, name);\n return () => reg?.unregister(orgId);\n }, [orgId, orgData?.developerOrganization?.name]);\n\n // Queries\n const {\n data: membersData,\n loading: membersLoading,\n error: membersError,\n } = useGetOrganizationMembersQuery({\n variables: { organizationId: orgId! },\n skip: !orgId,\n fetchPolicy: \"cache-and-network\",\n });\n\n // Mutations\n const [inviteMember, { loading: inviting }] = useInviteMemberMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [removeMember] = useRemoveMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [suspendMember] = useSuspendMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [reactivateMember] = useReactivateMemberMutation({\n refetchQueries: [\"GetOrganizationMembers\"],\n });\n\n const [updateMemberRole] = useUpdateMemberRoleMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [transferOwnership] = useTransferOwnershipMutation({\n refetchQueries: [\"GetOrganizationMembers\", \"GetOrganization\"],\n });\n\n const [cancelInvitation] = useCancelInvitationMutation({\n refetchQueries: [\"GetOrganizationInvitations\"],\n });\n\n const [resendInvitation] = useResendInvitationMutation();\n\n // Derived data\n const members: OrgMemberFieldsFragment[] = useMemo(\n () =>\n membersData?.developerOrgMembers?.edges?.map(\n (e: { node: OrgMemberFieldsFragment }) => e.node,\n ) ?? [],\n [membersData?.developerOrgMembers?.edges],\n );\n\n const currentMembership = currentUser\n ? members.find((member) => member.userId === currentUser.id)\n : undefined;\n const currentRole = currentMembership?.role as DeveloperOrgRole | undefined;\n const canManageOrg =\n currentRole !== undefined &&\n ORG_ROLE_PRIORITY[currentRole] >= ORG_ROLE_PRIORITY.ADMIN;\n const canInvite = canManageOrg && canInviteByPermission;\n const canManageMembers = canManageOrg && canManageMembersByPermission;\n const canRemoveMembers = canManageOrg && canRemoveMembersByPermission;\n const canActivateMembers = canManageOrg && canActivateMembersByPermission;\n const canDeactivateMembers = canManageOrg && canDeactivateMembersByPermission;\n\n const {\n data: invitationsData,\n loading: invitationsLoading,\n error: invitationsError,\n } = useGetOrganizationInvitationsQuery({\n variables: { organizationId: orgId!, status: \"PENDING\" as never },\n skip: !orgId || !canManageOrg,\n fetchPolicy: \"cache-and-network\",\n });\n\n const invitations: OrgInvitationFieldsFragment[] = useMemo(\n () =>\n invitationsData?.developerOrgInvitations?.edges?.map(\n (e: { node: OrgInvitationFieldsFragment }) => e.node,\n ) ?? [],\n [invitationsData?.developerOrgInvitations?.edges],\n );\n\n const membersCount = membersData?.developerOrgMembers?.totalCount ?? 0;\n const invitationsCount =\n invitationsData?.developerOrgInvitations?.totalCount ?? 0;\n\n const selectedMembers = useMemo(\n () => members.filter((member) => selectedMemberIds.has(member.id)),\n [members, selectedMemberIds],\n );\n const selectedInvitations = useMemo(\n () =>\n invitations.filter((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ),\n [invitations, selectedInvitationIds],\n );\n\n const selectableMembers = members.filter((member) => member.role !== \"OWNER\");\n const allMembersSelected =\n selectableMembers.length > 0 &&\n selectableMembers.every((member) => selectedMemberIds.has(member.id));\n const partiallySelectedMembers =\n selectableMembers.some((member) => selectedMemberIds.has(member.id)) &&\n !allMembersSelected;\n\n const allInvitationsSelected =\n invitations.length > 0 &&\n invitations.every((invitation) => selectedInvitationIds.has(invitation.id));\n const partiallySelectedInvitations =\n invitations.some((invitation) =>\n selectedInvitationIds.has(invitation.id),\n ) && !allInvitationsSelected;\n\n const suspendableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\" && !member.isSuspended,\n );\n const reactivatableMembers = selectedMembers.filter(\n (member) => member.isSuspended,\n );\n const removableMembers = selectedMembers.filter(\n (member) => member.role !== \"OWNER\",\n );\n\n const handleInvite = async () => {\n if (!orgId || !inviteEmail.trim()) return;\n setActionError(null);\n\n try {\n await inviteMember({\n variables: {\n organizationId: orgId,\n input: {\n email: inviteEmail,\n role: inviteRole as never,\n message: inviteMessage || undefined,\n },\n },\n });\n setShowInviteDialog(false);\n setInviteEmail(\"\");\n setInviteRole(\"DEVELOPER\");\n setInviteMessage(\"\");\n setActionSuccess(\n tr(\n \"devportal.invitationSent\",\n \"Invitation created and email sent to the team member.\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSendInvitation\", \"Failed to send invitation\"),\n );\n }\n };\n\n const handleRemoveMember = async (memberId: string) => {\n setActionError(null);\n try {\n await removeMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToRemoveMember\", \"Failed to remove member\"),\n );\n }\n };\n\n const handleSuspendMember = async (memberId: string, reason?: string) => {\n setActionError(null);\n try {\n await suspendMember({\n variables: { id: memberId, reason: reason || undefined },\n });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.failedToSuspendMember\", \"Failed to suspend member\"),\n );\n }\n };\n\n const handleReactivateMember = async (memberId: string) => {\n setActionError(null);\n try {\n await reactivateMember({ variables: { id: memberId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToReactivateMember\",\n \"Failed to reactivate member\",\n ),\n );\n }\n };\n\n const handleUpdateMemberRole = async (\n memberId: string,\n role: DeveloperOrgRole,\n ) => {\n setActionError(null);\n try {\n await updateMemberRole({\n variables: {\n id: memberId,\n role: role as never,\n permissions: undefined,\n },\n });\n setActionSuccess(\n tr(\"devportal.memberRoleUpdated\", \"Member role updated successfully\"),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToUpdateMemberRole\",\n \"Failed to update member role\",\n ),\n );\n }\n };\n\n const handleTransferOwnership = async () => {\n const member = transferOwnershipMember;\n if (!orgId || !member) return;\n setActionError(null);\n\n try {\n await transferOwnership({\n variables: { organizationId: orgId, newOwnerId: member.userId },\n });\n setTransferOwnershipMember(null);\n setActionSuccess(\n tr(\n \"devportal.organizationOwnershipTransferred\",\n \"Organization ownership transferred successfully\",\n ),\n );\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToTransferOwnership\",\n \"Failed to transfer organization ownership\",\n ),\n );\n }\n };\n\n const handleCancelInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await cancelInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToCancelInvitation\",\n \"Failed to cancel invitation\",\n ),\n );\n }\n };\n\n const handleResendInvitation = async (invitationId: string) => {\n setActionError(null);\n try {\n await resendInvitation({ variables: { id: invitationId } });\n } catch (err) {\n setActionError(\n err instanceof Error\n ? err.message\n : tr(\n \"devportal.failedToResendInvitation\",\n \"Failed to resend invitation\",\n ),\n );\n }\n };\n\n const clearSelections = () => {\n setSelectedMemberIds(new Set());\n setSelectedInvitationIds(new Set());\n };\n\n const toggleMemberSelection = (memberId: string, checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(memberId);\n } else {\n next.delete(memberId);\n }\n return next;\n });\n };\n\n const toggleAllMembers = (checked: boolean) => {\n setSelectedMemberIds((prev) => {\n const next = new Set(prev);\n selectableMembers.forEach((member) => {\n if (checked) {\n next.add(member.id);\n } else {\n next.delete(member.id);\n }\n });\n return next;\n });\n };\n\n const toggleInvitationSelection = (\n invitationId: string,\n checked: boolean,\n ) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(invitationId);\n } else {\n next.delete(invitationId);\n }\n return next;\n });\n };\n\n const toggleAllInvitations = (checked: boolean) => {\n setSelectedInvitationIds((prev) => {\n const next = new Set(prev);\n invitations.forEach((invitation) => {\n if (checked) {\n next.add(invitation.id);\n } else {\n next.delete(invitation.id);\n }\n });\n return next;\n });\n };\n\n const handleBulkSuspendMembers = async () => {\n if (suspendableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n suspendableMembers.map((member) =>\n suspendMember({ variables: { id: member.id, reason: undefined } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.suspended\", \"Suspended\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkReactivateMembers = async () => {\n if (reactivatableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n reactivatableMembers.map((member) =>\n reactivateMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.reactivated\", \"Reactivated\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkRemoveMembers = async () => {\n if (removableMembers.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n removableMembers.map((member) =>\n removeMember({ variables: { id: member.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.removed\", \"Removed\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.memberLower\", \"member\") : tr(\"devportal.membersLower\", \"members\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkRemoveMembersDialog(false);\n setSelectedMemberIds(new Set());\n };\n\n const handleBulkResendInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n resendInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.resent\", \"Resent\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setSelectedInvitationIds(new Set());\n };\n\n const handleBulkCancelInvitations = async () => {\n if (selectedInvitations.length === 0) return;\n setActionError(null);\n const results = await Promise.allSettled(\n selectedInvitations.map((invitation) =>\n cancelInvitation({ variables: { id: invitation.id } }),\n ),\n );\n const succeeded = results.filter(\n (result) => result.status === \"fulfilled\",\n ).length;\n const failed = results.length - succeeded;\n setActionSuccess(\n `${tr(\"devportal.cancelled\", \"Cancelled\")} ${succeeded} ${succeeded === 1 ? tr(\"devportal.invitationLower\", \"invitation\") : tr(\"devportal.invitationsLower\", \"invitations\")}${\n failed > 0 ? ` • ${failed} ${tr(\"devportal.failed\", \"failed\")}` : \"\"\n }`,\n );\n setShowBulkCancelInvitationsDialog(false);\n setSelectedInvitationIds(new Set());\n };\n\n const isLoading = membersLoading || invitationsLoading;\n const hasError = membersError || invitationsError;\n\n if (isLoading && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <div className=\"flex items-center justify-center py-16\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (hasError && !membersData && !invitationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\"devportal.failedToLoadMembers\", \"Failed to load members\")}\n description={\n membersError?.message ||\n invitationsError?.message ||\n tr(\n \"devportal.anErrorOccurredWhileLoadingTeamData\",\n \"An error occurred while loading team data\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.ORG_MEMBER_READ}>\n <PageLayout\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n description={tr(\n \"devportal.manageYourOrganizationsTeam\",\n \"Manage your organization's team\",\n )}\n purpose={tr(\n \"devportal.teamMembersPurpose\",\n \"Control who can work on this organization's apps and what they can do. Invite teammates by email, assign roles to grant the right level of access, and suspend or remove anyone who should no longer have it.\",\n )}\n backLink={`/organizations/${orgId}`}\n backLabel={tr(\"devportal.backToOrganization\", \"Back to Organization\")}\n actions={\n canInvite ? (\n <button\n onClick={() => setShowInviteDialog(true)}\n disabled={!canInvite}\n aria-disabled={!canInvite}\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 <Plus size={16} />\n {tr(\"devportal.inviteMember\", \"Invite Member\")}\n </button>\n ) : undefined\n }\n >\n {/* Action Error Banner */}\n {actionError && (\n <div className=\"rounded-lg border border-border-subtle bg-status-error-bg-subtle p-3 flex items-center gap-2 text-sm text-status-error-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionError}\n <button\n onClick={() => setActionError(null)}\n className=\"ml-auto text-status-error-text hover:text-status-error-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {actionSuccess && (\n <div className=\"rounded-lg border border-border-subtle bg-status-success-bg-subtle p-3 flex items-center gap-2 text-sm text-status-success-text\">\n <AlertCircle size={16} className=\"flex-shrink-0\" />\n {actionSuccess}\n <button\n onClick={() => setActionSuccess(null)}\n className=\"ml-auto text-status-success-text hover:text-status-success-text\"\n >\n {tr(\"devportal.dismiss\", \"Dismiss\")}\n </button>\n </div>\n )}\n\n {(selectedMemberIds.size > 0 || selectedInvitationIds.size > 0) && (\n <div className=\"flex flex-wrap items-center gap-3 rounded-card border border-border-seam bg-bg-surface p-4\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedMemberIds.size + selectedInvitationIds.size}{\" \"}\n {tr(\"devportal.selected\", \"selected\")}\n </span>\n <button\n onClick={clearSelections}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr(\"devportal.clearAllSelections\", \"Clear all selections\")}\n </button>\n </div>\n )}\n\n {/* Current Members */}\n <PageSection\n title={`${tr(\"devportal.members\", \"Members\")} (${membersCount})`}\n actions={\n members.length > 0 && canManageOrg ? (\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkSuspendMembers}\n disabled={\n suspendableMembers.length === 0 || !canDeactivateMembers\n }\n aria-disabled={!canDeactivateMembers}\n className=\"rounded-md border border-status-warning-bg px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.suspendSelected\", \"Suspend Selected\")}\n {suspendableMembers.length > 0\n ? ` (${suspendableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={handleBulkReactivateMembers}\n disabled={\n reactivatableMembers.length === 0 || !canActivateMembers\n }\n aria-disabled={!canActivateMembers}\n className=\"rounded-md border border-status-success-bg px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.reactivateSelected\", \"Reactivate Selected\")}\n {reactivatableMembers.length > 0\n ? ` (${reactivatableMembers.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkRemoveMembersDialog(true)}\n disabled={removableMembers.length === 0 || !canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.removeSelected\", \"Remove Selected\")}\n {removableMembers.length > 0\n ? ` (${removableMembers.length})`\n : \"\"}\n </button>\n </div>\n ) : null\n }\n >\n {members.length > 0 ? (\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n ...(canManageOrg\n ? [\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allMembersSelected}\n indeterminate={partiallySelectedMembers}\n onChange={toggleAllMembers}\n ariaLabel={tr(\n \"devportal.selectAllMembers\",\n \"Select all members\",\n )}\n />\n ),\n className: \"w-12\",\n render: (member: OrgMemberFieldsFragment) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedMemberIds.has(member.id)}\n disabled={member.role === \"OWNER\"}\n onChange={(checked) =>\n toggleMemberSelection(member.id, checked)\n }\n ariaLabel={`Select member ${resolveMemberLabel(member)}`}\n />\n </div>\n ),\n },\n ]\n : []),\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => {\n const label = resolveMemberLabel(member);\n return (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-8 w-8 items-center justify-center rounded-full bg-action-primary-bg/10 text-primary text-sm font-medium\">\n {label.charAt(0).toUpperCase()}\n </div>\n <div>\n <p className=\"font-medium\">{label}</p>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.joined\", \"Joined\")}{\" \"}\n {format(new Date(member.joinedAt), \"MMM d, yyyy\")}\n </p>\n </div>\n </div>\n );\n },\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <div className=\"flex items-center gap-2\">\n <Shield size={14} className=\"text-text-secondary\" />\n {member.role === \"OWNER\" || !canManageMembers ? (\n <span>\n {ORG_ROLE_LABELS[member.role as DeveloperOrgRole] ??\n member.role}\n </span>\n ) : (\n <select\n value={member.role}\n onChange={(event) =>\n void handleUpdateMemberRole(\n member.id,\n event.target.value as DeveloperOrgRole,\n )\n }\n className=\"rounded-md border border-border-subtle bg-bg-surface px-2 py-1 text-xs text-text-primary\"\n >\n {Object.entries(ORG_ROLE_LABELS)\n .filter(([value]) => value !== \"OWNER\")\n .map(([value, label]) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n )}\n </div>\n ),\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (member) =>\n member.isSuspended ? (\n <StatusBadge status=\"SUSPENDED\" type=\"app\" />\n ) : member.isActive ? (\n <StatusBadge status=\"ACTIVE\" type=\"app\" />\n ) : (\n <StatusBadge status=\"INACTIVE\" type=\"app\" />\n ),\n },\n ...(canManageOrg\n ? [\n {\n key: \"actions\",\n header: \"\",\n className: \"w-32\",\n render: (member: OrgMemberFieldsFragment) =>\n member.role !== \"OWNER\" && (\n <div className=\"flex gap-1\">\n {member.isSuspended ? (\n <button\n className=\"text-xs text-status-success-text hover:underline disabled:opacity-50\"\n disabled={!canActivateMembers}\n aria-disabled={!canActivateMembers}\n title={tr(\n \"devportal.reactivateMember\",\n \"Reactivate member\",\n )}\n onClick={() =>\n handleReactivateMember(member.id)\n }\n >\n {tr(\"devportal.reactivate\", \"Reactivate\")}\n </button>\n ) : (\n <button\n className=\"text-xs text-status-warning-text hover:underline disabled:opacity-50\"\n disabled={!canDeactivateMembers}\n aria-disabled={!canDeactivateMembers}\n title={tr(\n \"devportal.suspendMember\",\n \"Suspend member\",\n )}\n onClick={() => handleSuspendMember(member.id)}\n >\n {tr(\"devportal.suspend\", \"Suspend\")}\n </button>\n )}\n <button\n className=\"text-xs text-status-error-text hover:underline disabled:opacity-50\"\n disabled={!canRemoveMembers}\n aria-disabled={!canRemoveMembers}\n title={tr(\n \"devportal.removeMember\",\n \"Remove member\",\n )}\n onClick={() => handleRemoveMember(member.id)}\n >\n {tr(\"devportal.remove\", \"Remove\")}\n </button>\n <button\n className=\"text-xs text-primary hover:underline disabled:opacity-50\"\n disabled={!canManageMembers}\n aria-disabled={!canManageMembers}\n title={tr(\n \"devportal.transferOwnership\",\n \"Transfer ownership\",\n )}\n onClick={() =>\n setTransferOwnershipMember(member)\n }\n >\n {tr(\"devportal.makeOwner\", \"Make Owner\")}\n </button>\n </div>\n ),\n },\n ]\n : []),\n ]}\n />\n ) : (\n <EmptyState\n illustration=\"empty-people\"\n title={tr(\"devportal.noMembers\", \"No members\")}\n description={tr(\n \"devportal.inviteTeamMembersToCollaborate\",\n \"Invite team members to collaborate\",\n )}\n />\n )}\n </PageSection>\n\n {/* Pending Invitations */}\n {canManageOrg && invitations.length > 0 && (\n <PageSection\n title={`${tr(\"devportal.pendingInvitations\", \"Pending Invitations\")} (${invitationsCount})`}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n onClick={handleBulkResendInvitations}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-primary/30 px-3 py-2 text-sm font-medium text-primary hover:bg-action-primary-bg/5 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.resendSelected\", \"Resend Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n <button\n onClick={() => setShowBulkCancelInvitationsDialog(true)}\n disabled={selectedInvitations.length === 0}\n className=\"rounded-md border border-status-error-bg px-3 py-2 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {tr(\"devportal.cancelSelected\", \"Cancel Selected\")}\n {selectedInvitations.length > 0\n ? ` (${selectedInvitations.length})`\n : \"\"}\n </button>\n </div>\n }\n >\n <DataTable\n data={invitations}\n keyField=\"id\"\n columns={[\n {\n key: \"select\",\n header: (\n <SelectionCheckbox\n checked={allInvitationsSelected}\n indeterminate={partiallySelectedInvitations}\n onChange={toggleAllInvitations}\n ariaLabel={tr(\n \"devportal.selectAllInvitations\",\n \"Select all invitations\",\n )}\n />\n ),\n className: \"w-12\",\n render: (invitation) => (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selectedInvitationIds.has(invitation.id)}\n onChange={(checked) =>\n toggleInvitationSelection(invitation.id, checked)\n }\n ariaLabel={`Select invitation ${invitation.invitedEmail}`}\n />\n </div>\n ),\n },\n {\n key: \"invitedEmail\",\n header: tr(\"devportal.emailColumn\", \"Email\"),\n render: (inv) => (\n <div className=\"flex items-center gap-2\">\n <Mail size={16} className=\"text-text-secondary\" />\n {inv.invitedEmail}\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.invitedRoleColumn\", \"Invited Role\"),\n render: (inv) =>\n ORG_ROLE_LABELS[inv.role as DeveloperOrgRole] ?? inv.role,\n },\n {\n key: \"status\",\n header: tr(\"devportal.statusColumn\", \"Status\"),\n render: (inv) => (\n <StatusBadge status={inv.status} type=\"invitation\" />\n ),\n },\n {\n key: \"expiresAt\",\n header: tr(\"devportal.expiresColumn\", \"Expires\"),\n render: (inv) =>\n format(new Date(inv.expiresAt), \"MMM d, yyyy\"),\n },\n {\n key: \"actions\",\n header: \"\",\n className: \"w-24\",\n render: (inv) => (\n <div className=\"flex gap-1\">\n <button\n className=\"rounded p-1 hover:bg-bg-sunken\"\n title={tr(\"devportal.resend\", \"Resend\")}\n onClick={() => handleResendInvitation(inv.id)}\n >\n <RefreshCw size={14} />\n </button>\n <button\n className=\"rounded p-1 hover:bg-bg-sunken text-status-error-text\"\n title={tr(\"devportal.cancel\", \"Cancel\")}\n onClick={() => handleCancelInvitation(inv.id)}\n >\n <UserMinus size={14} />\n </button>\n </div>\n ),\n },\n ]}\n />\n </PageSection>\n )}\n\n {/* Invite Dialog */}\n {showInviteDialog && (\n <ConfirmDialog\n open={showInviteDialog}\n onOpenChange={setShowInviteDialog}\n onConfirm={handleInvite}\n title={tr(\"devportal.inviteTeamMember\", \"Invite Team Member\")}\n confirmLabel={\n inviting\n ? tr(\"devportal.sendingDots\", \"Sending...\")\n : tr(\"devportal.sendInvitation\", \"Send Invitation\")\n }\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.emailAddress\", \"Email Address\")}\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@example.com\"\n hint={tr(\n \"devportal.mustBeExistingVerifiedUser\",\n \"Must be an existing verified user\",\n )}\n required\n />\n <SelectField\n label={tr(\"devportal.roleColumn\", \"Role\")}\n value={inviteRole}\n onChange={(e) =>\n setInviteRole(e.target.value as DeveloperOrgRole)\n }\n options={[\n {\n value: \"ADMIN\",\n label: tr(\n \"devportal.adminFullAccess\",\n \"Admin - Full access\",\n ),\n },\n {\n value: \"DEVELOPER\",\n label: tr(\n \"devportal.developerCreateAndManageApps\",\n \"Developer - Create and manage apps\",\n ),\n },\n {\n value: \"VIEWER\",\n label: tr(\n \"devportal.viewerReadOnlyAccess\",\n \"Viewer - Read-only access\",\n ),\n },\n ]}\n required\n />\n <TextareaField\n label={tr(\"devportal.personalMessage\", \"Personal Message\")}\n value={inviteMessage}\n onChange={(e) => setInviteMessage(e.target.value)}\n placeholder={tr(\n \"devportal.personalMessagePlaceholder\",\n \"Add a short note to include in the invitation email\",\n )}\n rows={3}\n />\n </div>\n </ConfirmDialog>\n )}\n\n <ConfirmDialog\n open={showBulkRemoveMembersDialog}\n onOpenChange={setShowBulkRemoveMembersDialog}\n onConfirm={handleBulkRemoveMembers}\n title={tr(\n \"devportal.removeSelectedMembers\",\n \"Remove selected members\",\n )}\n description={`${tr(\"devportal.removeNSelectedMembers\", \"Remove\")} ${removableMembers.length} ${tr(\"devportal.selectedMembersFromOrg\", \"selected member(s) from this organization? This action cannot be undone.\")}`}\n confirmLabel={tr(\"devportal.removeMembers\", \"Remove Members\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={showBulkCancelInvitationsDialog}\n onOpenChange={setShowBulkCancelInvitationsDialog}\n onConfirm={handleBulkCancelInvitations}\n title={tr(\n \"devportal.cancelSelectedInvitations\",\n \"Cancel selected invitations\",\n )}\n description={`${tr(\"devportal.cancelNPendingInvitations\", \"Cancel\")} ${selectedInvitations.length} ${tr(\"devportal.pendingInvitationsQuestion\", \"pending invitation(s)?\")}`}\n confirmLabel={tr(\"devportal.cancelInvitations\", \"Cancel Invitations\")}\n cancelLabel={tr(\"devportal.keepInvitations\", \"Keep Invitations\")}\n variant=\"danger\"\n />\n\n <ConfirmDialog\n open={transferOwnershipMember !== null}\n onOpenChange={(open) => {\n if (!open) setTransferOwnershipMember(null);\n }}\n onConfirm={handleTransferOwnership}\n title={tr(\"devportal.transferOwnership\", \"Transfer ownership\")}\n description={\n transferOwnershipMember\n ? tr(\n \"devportal.transferOwnershipConfirmation\",\n `Transfer organization ownership to ${resolveMemberLabel(transferOwnershipMember)}?`,\n )\n : undefined\n }\n confirmLabel={tr(\"devportal.makeOwner\", \"Make Owner\")}\n cancelLabel={tr(\"devportal.cancel\", \"Cancel\")}\n variant=\"warning\"\n />\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-devportal",
3
- "version": "2026.707.1",
3
+ "version": "2026.707.2",
4
4
  "description": "Burdenoff Developer Portal Microfrontend - Complete developer operations interface",
5
5
  "type": "module",
6
6
  "files": [