@burdenoff/microfe-devportal 2026.707.1 → 2026.711.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/devportal/AdminDevportalRoot.js +33 -27
  2. package/dist/devportal/AdminDevportalRoot.js.map +1 -1
  3. package/dist/devportal/AdminDevportalRoutes.js +9 -5
  4. package/dist/devportal/AdminDevportalRoutes.js.map +1 -1
  5. package/dist/devportal/DevportalRoutes.js +125 -105
  6. package/dist/devportal/DevportalRoutes.js.map +1 -1
  7. package/dist/devportal/pages/AdminOrganizationVerificationPage.js +169 -0
  8. package/dist/devportal/pages/AdminOrganizationVerificationPage.js.map +1 -0
  9. package/dist/devportal/pages/CreatePhysicalItemPage.js +494 -0
  10. package/dist/devportal/pages/CreatePhysicalItemPage.js.map +1 -0
  11. package/dist/devportal/pages/EditPhysicalItemPage.js +419 -0
  12. package/dist/devportal/pages/EditPhysicalItemPage.js.map +1 -0
  13. package/dist/devportal/pages/InvitationDecisionPage.js.map +1 -1
  14. package/dist/devportal/pages/OrganizationDetailPage.js +441 -295
  15. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  16. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  17. package/dist/devportal/pages/RevenueDashboardPage.js +72 -54
  18. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  19. package/dist/devportal/pages/SellerDashboardPage.js +364 -0
  20. package/dist/devportal/pages/SellerDashboardPage.js.map +1 -0
  21. package/dist/devportal/pages/SellerItemsPage.js +533 -0
  22. package/dist/devportal/pages/SellerItemsPage.js.map +1 -0
  23. package/dist/devportal/pages/SellerOrdersPage.js +411 -0
  24. package/dist/devportal/pages/SellerOrdersPage.js.map +1 -0
  25. package/dist/devportal/types/index.js.map +1 -1
  26. package/dist/generated/global-operations.js +48 -55
  27. package/dist/generated/global-operations.js.map +1 -1
  28. package/package.json +1 -1
@@ -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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"}
@@ -1,26 +1,26 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
2
  import { cn as t } from "../utils/cn.js";
3
3
  import { EmptyState as n } from "../components/EmptyState.js";
4
- import { useGetBillingAccountsByOrgQuery as ee, useGetMyOrganizationsQuery as r, useGetRevenueDashboardDataQuery as te, useLinkDevOrgBillingAccountMutation as ne } from "../../generated/global-operations.js";
5
- import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
- import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
7
- import { StatusBadge as s } from "../components/StatusBadge.js";
8
- import { StatCard as c, StatCardGrid as re } from "../components/StatCard.js";
9
- import { DataTable as l } from "../components/DataTable.js";
4
+ import { useGetBillingAccountsByOrgQuery as ee, useGetMyOrganizationsQuery as te, useGetRevenueDashboardDataQuery as ne, useLinkDevOrgBillingAccountMutation as re } from "../../generated/global-operations.js";
5
+ import { getErrorMessage as r } from "../hooks/useGraphQL.js";
6
+ import { PageLayout as i, PageSection as a } from "../components/PageLayout.js";
7
+ import { StatusBadge as o } from "../components/StatusBadge.js";
8
+ import { StatCard as s, StatCardGrid as ie } from "../components/StatCard.js";
9
+ import { DataTable as c } from "../components/DataTable.js";
10
10
  import "../hooks/index.js";
11
- import { Tooltip as u } from "../../node_modules/recharts/es6/component/Tooltip.js";
12
- import { ResponsiveContainer as d } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
13
- import { Bar as ie } from "../../node_modules/recharts/es6/cartesian/Bar.js";
14
- import { CartesianGrid as f } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
15
- import { Line as p } from "../../node_modules/recharts/es6/cartesian/Line.js";
16
- import { XAxis as m } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
17
- import { YAxis as h } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
18
- import { LineChart as ae } from "../../node_modules/recharts/es6/chart/LineChart.js";
11
+ import { Tooltip as l } from "../../node_modules/recharts/es6/component/Tooltip.js";
12
+ import { ResponsiveContainer as u } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
13
+ import { Bar as ae } from "../../node_modules/recharts/es6/cartesian/Bar.js";
14
+ import { CartesianGrid as d } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
15
+ import { Line as f } from "../../node_modules/recharts/es6/cartesian/Line.js";
16
+ import { XAxis as p } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
17
+ import { YAxis as m } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
18
+ import { LineChart as h } from "../../node_modules/recharts/es6/chart/LineChart.js";
19
19
  import { BarChart as oe } from "../../node_modules/recharts/es6/chart/BarChart.js";
20
20
  import { useTr as se } from "../utils/i18n.js";
21
21
  import { useMemo as g, useState as _ } from "react";
22
- import { AlertCircle as v, ArrowDownToLine as ce, Building2 as y, Check as b, CreditCard as x, DollarSign as S, Link2 as C, Loader2 as w, Wallet as T } from "lucide-react";
23
- import { useSearchParams as le } from "react-router-dom";
22
+ import { AlertCircle as v, ArrowDownToLine as ce, Building2 as y, Check as b, CreditCard as x, DollarSign as S, Link2 as C, Loader2 as w, Wallet as le } from "lucide-react";
23
+ import { useSearchParams as T } from "react-router-dom";
24
24
  import { Fragment as ue, jsx as E, jsxs as D } from "react/jsx-runtime";
25
25
  import { EmphasisPanel as de, GlassCard as O } from "@burdenoff/fe-libs/ui";
26
26
  //#region src/devportal/pages/RevenueDashboardPage.tsx
@@ -33,13 +33,13 @@ var k = {
33
33
  "90d": 90,
34
34
  "12m": 365
35
35
  }, A = () => {
36
- let A = se(), { activeOrgId: j, tenantId: pe } = e(), [M, me] = _("90d"), [N, P] = _(!1), [F, I] = _(null), [he] = ne(), [L, R] = _(!1), [z, B] = _(null), [ge] = le(), V = g(() => /* @__PURE__ */ new Date(), []), { data: _e, loading: H } = ee({
36
+ let A = se(), { activeOrgId: j, tenantId: pe } = e(), [M, me] = _("90d"), [N, P] = _(!1), [F, I] = _(null), [he] = re(), [L, R] = _(!1), [z, B] = _(null), [ge] = T(), V = g(() => /* @__PURE__ */ new Date(), []), { data: _e, loading: H } = ee({
37
37
  fetchPolicy: "cache-and-network",
38
38
  context: { headers: { "x-org-id": pe ?? "" } }
39
39
  }), ve = g(() => {
40
40
  let e = new Date(V);
41
41
  return e.setDate(e.getDate() - fe[M]), e.toISOString();
42
- }, [V, M]), { data: U, loading: ye, error: W } = r({ fetchPolicy: "cache-and-network" }), { data: G, loading: be, error: K } = te({
42
+ }, [V, M]), { data: U, loading: ye, error: W } = te({ fetchPolicy: "cache-and-network" }), { data: G, loading: be, error: K } = ne({
43
43
  variables: {
44
44
  organizationId: j ?? "",
45
45
  period: "monthly",
@@ -82,14 +82,14 @@ var k = {
82
82
  refunds: e.refunds,
83
83
  salesCount: e.salesCount
84
84
  }));
85
- return ye && !U ? /* @__PURE__ */ E(a, {
85
+ return ye && !U ? /* @__PURE__ */ E(i, {
86
86
  title: A("devportal.revenue.title", "Revenue"),
87
87
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
88
88
  children: /* @__PURE__ */ E("div", {
89
89
  className: "flex items-center justify-center py-16 text-text-secondary",
90
90
  children: /* @__PURE__ */ E(w, { className: "h-8 w-8 animate-spin" })
91
91
  })
92
- }) : W ? /* @__PURE__ */ E(a, {
92
+ }) : W ? /* @__PURE__ */ E(i, {
93
93
  title: A("devportal.revenue.title", "Revenue"),
94
94
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
95
95
  children: /* @__PURE__ */ E(n, {
@@ -98,9 +98,9 @@ var k = {
98
98
  className: "text-status-error-text"
99
99
  }),
100
100
  title: A("devportal.revenue.errorLoadOrgs", "Unable to load organizations"),
101
- description: i(W)
101
+ description: r(W)
102
102
  })
103
- }) : j ? K ? /* @__PURE__ */ E(a, {
103
+ }) : j ? K ? /* @__PURE__ */ E(i, {
104
104
  title: A("devportal.revenue.title", "Revenue"),
105
105
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
106
106
  children: /* @__PURE__ */ E(n, {
@@ -109,9 +109,9 @@ var k = {
109
109
  className: "text-status-error-text"
110
110
  }),
111
111
  title: A("devportal.revenue.errorLoadData", "Unable to load revenue data"),
112
- description: i(K)
112
+ description: r(K)
113
113
  })
114
- }) : /* @__PURE__ */ D(a, {
114
+ }) : /* @__PURE__ */ D(i, {
115
115
  title: A("devportal.revenue.title", "Revenue"),
116
116
  description: q ? `${A("devportal.revenue.financialPerformanceFor", "Financial performance for")} ${q.name}` : A("devportal.revenue.shortDescription", "Track revenue, sales, and payouts"),
117
117
  purpose: A("devportal.revenue.purpose", "Revenue tracks the money your paid apps earn — gross sales, platform fees, and what gets paid out to your organization. Link a billing account, then use this to reconcile payouts and watch growth across time ranges."),
@@ -322,26 +322,26 @@ var k = {
322
322
  }) : Q ? /* @__PURE__ */ D(ue, { children: [
323
323
  /* @__PURE__ */ E(de, {
324
324
  className: "mb-6",
325
- children: /* @__PURE__ */ D(re, {
325
+ children: /* @__PURE__ */ D(ie, {
326
326
  columns: 4,
327
327
  children: [
328
- /* @__PURE__ */ E(c, {
328
+ /* @__PURE__ */ E(s, {
329
329
  title: A("devportal.revenue.grossRevenue", "Gross Revenue"),
330
330
  value: `$${Q.totalGrossRevenue.toLocaleString()}`,
331
331
  icon: /* @__PURE__ */ E(S, { size: 20 })
332
332
  }),
333
- /* @__PURE__ */ E(c, {
333
+ /* @__PURE__ */ E(s, {
334
334
  title: A("devportal.revenue.netRevenue", "Net Revenue"),
335
335
  value: `$${Q.totalNetRevenue.toLocaleString()}`,
336
- icon: /* @__PURE__ */ E(T, { size: 20 })
336
+ icon: /* @__PURE__ */ E(le, { size: 20 })
337
337
  }),
338
- /* @__PURE__ */ E(c, {
338
+ /* @__PURE__ */ E(s, {
339
339
  title: A("devportal.revenue.pendingBalance", "Pending Balance"),
340
340
  value: `$${Q.pendingBalance.toLocaleString()}`,
341
341
  icon: /* @__PURE__ */ E(x, { size: 20 }),
342
342
  description: Q.nextPayoutDate ? `${A("devportal.revenue.nextPayout", "Next payout")} ${new Date(Q.nextPayoutDate).toLocaleDateString()}` : A("devportal.revenue.noPayoutScheduled", "No payout scheduled")
343
343
  }),
344
- /* @__PURE__ */ E(c, {
344
+ /* @__PURE__ */ E(s, {
345
345
  title: A("devportal.revenue.platformFees", "Platform Fees"),
346
346
  value: `$${Q.totalPlatformFees.toLocaleString()}`,
347
347
  icon: /* @__PURE__ */ E(ce, { size: 20 }),
@@ -352,43 +352,43 @@ var k = {
352
352
  }),
353
353
  /* @__PURE__ */ D("div", {
354
354
  className: "grid gap-6 xl:grid-cols-2",
355
- children: [/* @__PURE__ */ E(o, {
355
+ children: [/* @__PURE__ */ E(a, {
356
356
  title: A("devportal.revenue.revenueTrend", "Revenue trend"),
357
357
  children: /* @__PURE__ */ E(O, {
358
358
  treatment: "insight",
359
359
  className: "p-4",
360
- children: /* @__PURE__ */ E(d, {
360
+ children: $.length > 0 ? /* @__PURE__ */ E(u, {
361
361
  width: "100%",
362
362
  height: 300,
363
- children: /* @__PURE__ */ D(ae, {
363
+ children: /* @__PURE__ */ D(h, {
364
364
  data: $,
365
365
  children: [
366
- /* @__PURE__ */ E(f, {
366
+ /* @__PURE__ */ E(d, {
367
367
  strokeDasharray: "3 3",
368
368
  stroke: "var(--color-chart-grid)"
369
369
  }),
370
- /* @__PURE__ */ E(m, {
370
+ /* @__PURE__ */ E(p, {
371
371
  dataKey: "date",
372
372
  stroke: "var(--color-chart-axis)",
373
373
  fontSize: 12
374
374
  }),
375
- /* @__PURE__ */ E(h, {
375
+ /* @__PURE__ */ E(m, {
376
376
  stroke: "var(--color-chart-axis)",
377
377
  fontSize: 12
378
378
  }),
379
- /* @__PURE__ */ E(u, { contentStyle: {
379
+ /* @__PURE__ */ E(l, { contentStyle: {
380
380
  backgroundColor: "var(--color-card)",
381
381
  border: "1px solid var(--color-border-default)",
382
382
  borderRadius: 12
383
383
  } }),
384
- /* @__PURE__ */ E(p, {
384
+ /* @__PURE__ */ E(f, {
385
385
  type: "monotone",
386
386
  dataKey: "grossRevenue",
387
387
  stroke: k.primary,
388
388
  strokeWidth: 2,
389
389
  dot: !1
390
390
  }),
391
- /* @__PURE__ */ E(p, {
391
+ /* @__PURE__ */ E(f, {
392
392
  type: "monotone",
393
393
  dataKey: "netRevenue",
394
394
  stroke: k.secondary,
@@ -397,9 +397,18 @@ var k = {
397
397
  })
398
398
  ]
399
399
  })
400
+ }) : /* @__PURE__ */ D("div", {
401
+ className: "flex h-[300px] flex-col items-center justify-center gap-2 text-text-secondary",
402
+ children: [/* @__PURE__ */ E("p", {
403
+ className: "text-sm font-medium",
404
+ children: A("devportal.revenue.noTrendData", "No trend data yet")
405
+ }), /* @__PURE__ */ E("p", {
406
+ className: "text-xs text-text-tertiary",
407
+ children: A("devportal.revenue.noTrendDataHint", "Revenue trend appears once daily analytics have been aggregated.")
408
+ })]
400
409
  })
401
410
  })
402
- }), /* @__PURE__ */ E(o, {
411
+ }), /* @__PURE__ */ E(a, {
403
412
  title: A("devportal.revenue.topApps", "Top applications by revenue"),
404
413
  children: Q.topApps.length > 0 ? /* @__PURE__ */ E("div", {
405
414
  className: "space-y-2",
@@ -442,36 +451,36 @@ var k = {
442
451
  })
443
452
  })]
444
453
  }),
445
- /* @__PURE__ */ E(o, {
454
+ /* @__PURE__ */ E(a, {
446
455
  title: A("devportal.revenue.salesVolume", "Sales volume"),
447
456
  children: /* @__PURE__ */ E(O, {
448
457
  treatment: "insight",
449
458
  className: "p-4",
450
- children: /* @__PURE__ */ E(d, {
459
+ children: $.length > 0 ? /* @__PURE__ */ E(u, {
451
460
  width: "100%",
452
461
  height: 280,
453
462
  children: /* @__PURE__ */ D(oe, {
454
463
  data: $,
455
464
  children: [
456
- /* @__PURE__ */ E(f, {
465
+ /* @__PURE__ */ E(d, {
457
466
  strokeDasharray: "3 3",
458
467
  stroke: "var(--color-chart-grid)"
459
468
  }),
460
- /* @__PURE__ */ E(m, {
469
+ /* @__PURE__ */ E(p, {
461
470
  dataKey: "date",
462
471
  stroke: "var(--color-chart-axis)",
463
472
  fontSize: 12
464
473
  }),
465
- /* @__PURE__ */ E(h, {
474
+ /* @__PURE__ */ E(m, {
466
475
  stroke: "var(--color-chart-axis)",
467
476
  fontSize: 12
468
477
  }),
469
- /* @__PURE__ */ E(u, { contentStyle: {
478
+ /* @__PURE__ */ E(l, { contentStyle: {
470
479
  backgroundColor: "var(--color-card)",
471
480
  border: "1px solid var(--color-border-default)",
472
481
  borderRadius: 12
473
482
  } }),
474
- /* @__PURE__ */ E(ie, {
483
+ /* @__PURE__ */ E(ae, {
475
484
  dataKey: "salesCount",
476
485
  fill: k.tertiary,
477
486
  radius: [
@@ -483,14 +492,23 @@ var k = {
483
492
  })
484
493
  ]
485
494
  })
495
+ }) : /* @__PURE__ */ D("div", {
496
+ className: "flex h-[280px] flex-col items-center justify-center gap-2 text-text-secondary",
497
+ children: [/* @__PURE__ */ E("p", {
498
+ className: "text-sm font-medium",
499
+ children: A("devportal.revenue.noVolumeData", "No sales volume data yet")
500
+ }), /* @__PURE__ */ E("p", {
501
+ className: "text-xs text-text-tertiary",
502
+ children: A("devportal.revenue.noVolumeDataHint", "Sales volume by period appears once analytics have been aggregated.")
503
+ })]
486
504
  })
487
505
  })
488
506
  }),
489
507
  /* @__PURE__ */ D("div", {
490
508
  className: "grid gap-6 xl:grid-cols-2",
491
- children: [/* @__PURE__ */ E(o, {
509
+ children: [/* @__PURE__ */ E(a, {
492
510
  title: A("devportal.revenue.recentSales", "Recent sales"),
493
- children: /* @__PURE__ */ E(l, {
511
+ children: /* @__PURE__ */ E(c, {
494
512
  data: Se,
495
513
  keyField: "id",
496
514
  columns: [
@@ -512,16 +530,16 @@ var k = {
512
530
  {
513
531
  key: "status",
514
532
  header: A("devportal.revenue.status", "Status"),
515
- render: (e) => /* @__PURE__ */ E(s, {
533
+ render: (e) => /* @__PURE__ */ E(o, {
516
534
  status: e.status,
517
535
  type: "app"
518
536
  })
519
537
  }
520
538
  ]
521
539
  })
522
- }), /* @__PURE__ */ E(o, {
540
+ }), /* @__PURE__ */ E(a, {
523
541
  title: A("devportal.revenue.payoutHistory", "Payout history"),
524
- children: /* @__PURE__ */ E(l, {
542
+ children: /* @__PURE__ */ E(c, {
525
543
  data: Ce,
526
544
  keyField: "id",
527
545
  columns: [
@@ -538,7 +556,7 @@ var k = {
538
556
  {
539
557
  key: "status",
540
558
  header: A("devportal.revenue.status", "Status"),
541
- render: (e) => /* @__PURE__ */ E(s, {
559
+ render: (e) => /* @__PURE__ */ E(o, {
542
560
  status: e.status,
543
561
  type: "app"
544
562
  })
@@ -554,7 +572,7 @@ var k = {
554
572
  description: A("devportal.revenue.noDataDescription", "Revenue metrics will appear after this organization starts recording marketplace sales.")
555
573
  })
556
574
  ]
557
- }) : /* @__PURE__ */ E(a, {
575
+ }) : /* @__PURE__ */ E(i, {
558
576
  title: A("devportal.revenue.title", "Revenue"),
559
577
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
560
578
  children: /* @__PURE__ */ E(n, {