@burdenoff/microfe-devportal 2026.626.7 → 2026.629.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":"OrganizationDetailPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState, useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Building2,\n Users,\n AppWindow,\n DollarSign,\n Settings,\n ExternalLink,\n CheckCircle,\n BarChart3,\n TrendingUp,\n ArrowRight,\n Plus,\n Edit,\n Shield,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { EmphasisPanel, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { DataTable, DetailList } from \"../components/DataTable\";\nimport { AppListItem } from \"../components/AppCard\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type {\n DeveloperOrganization,\n Application,\n DeveloperOrgMember,\n} from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport {\n useGetOrganizationQuery,\n useGetApplicationsQuery,\n useRequestOrgVerificationMutation,\n} from \"../../generated/global-operations\";\nimport type {\n OrganizationFieldsFragment,\n OrgMemberFieldsFragment,\n ApplicationFieldsFragment,\n} from \"../../generated/global-operations\";\n\n/**\n * Map GraphQL organization fragment to local type\n */\nfunction mapOrganization(\n org: OrganizationFieldsFragment,\n): DeveloperOrganization {\n return {\n id: org.id,\n name: org.name,\n slug: org.slug,\n description: org.description ?? undefined,\n logoUrl: org.logoUrl ?? undefined,\n bannerUrl: org.bannerUrl ?? undefined,\n websiteUrl: org.websiteUrl ?? undefined,\n contactEmail: org.contactEmail ?? undefined,\n supportEmail: org.supportEmail ?? undefined,\n tier: org.tier as DeveloperOrganization[\"tier\"],\n partnerTier:\n (org.partnerTier as DeveloperOrganization[\"partnerTier\"]) ?? undefined,\n partnerSince: org.partnerSince ?? undefined,\n isVerified: org.isVerified ?? false,\n verifiedAt: org.verifiedAt ?? undefined,\n isCertified: org.isCertified ?? false,\n certifiedAt: org.certifiedAt ?? undefined,\n totalApps: org.totalApps ?? 0,\n publishedApps: org.publishedApps ?? 0,\n totalInstalls: org.totalInstalls ?? 0,\n activeInstalls: org.activeInstalls ?? 0,\n totalApiCalls: org.totalApiCalls ?? \"0\",\n averageRating: org.averageRating ?? undefined,\n totalRevenue: org.totalRevenue ?? 0,\n totalPlatformFees: org.totalPlatformFees ?? 0,\n totalPayouts: org.totalPayouts ?? 0,\n pendingBalance: org.pendingBalance ?? 0,\n lifetimeRevenue: org.lifetimeRevenue ?? 0,\n platformFeeRate: org.platformFeeRate ?? 0.3,\n apiCallsLimit: org.apiCallsLimit ?? 100000,\n storageLimit: org.storageLimit ?? \"1073741824\",\n apiCallsUsed: org.apiCallsUsed ?? \"0\",\n storageUsed: org.storageUsed ?? \"0\",\n taxId: org.taxId ?? undefined,\n taxCountry: org.taxCountry ?? undefined,\n taxFormVerified: org.taxFormVerified ?? false,\n legalEntityName: org.legalEntityName ?? undefined,\n legalEntityType: org.legalEntityType ?? undefined,\n createdAt: org.createdAt,\n updatedAt: org.updatedAt,\n };\n}\n\n/**\n * Map GraphQL member fragment to local type\n */\nfunction mapMember(member: OrgMemberFieldsFragment): DeveloperOrgMember {\n return {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n email: member.email ?? undefined,\n role: member.role as DeveloperOrgMember[\"role\"],\n isActive: member.isActive ?? true,\n isSuspended: member.isSuspended ?? false,\n suspendedAt: member.suspendedAt ?? undefined,\n suspendedReason: member.suspendedReason ?? undefined,\n joinedAt: member.joinedAt,\n lastActiveAt: member.lastActiveAt ?? undefined,\n permissions: member.permissions ?? undefined,\n invitedBy: member.invitedBy ?? undefined,\n invitationId: member.invitationId ?? undefined,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n };\n}\n\ntype TabId = \"overview\" | \"apps\" | \"members\" | \"settings\";\n\n/**\n * Organization detail page\n */\nexport const OrganizationDetailPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { orgId: id } = useParams<{ orgId: string }>();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canUpdate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_UPDATE,\n );\n const [activeTab, setActiveTab] = useState<TabId>(\"overview\");\n\n const tabs: Array<{ id: TabId; label: string; icon: FC<{ size?: number }> }> =\n [\n {\n id: \"overview\",\n label: tr(\"devportal.overview\", \"Overview\"),\n icon: Building2,\n },\n {\n id: \"apps\",\n label: tr(\"devportal.applications\", \"Applications\"),\n icon: AppWindow,\n },\n { id: \"members\", label: tr(\"devportal.members\", \"Members\"), icon: Users },\n {\n id: \"settings\",\n label: tr(\"devportal.settings\", \"Settings\"),\n icon: Settings,\n },\n ];\n\n // Fetch organization data\n const { data, previousData, loading, error } = useGetOrganizationQuery({\n variables: { id: id! },\n skip: !id,\n });\n const resolvedData = data ?? previousData;\n\n // Fetch applications (filtered client-side for this org until organizationId filter is published to gateway)\n const { data: appsData } = useGetApplicationsQuery({\n variables: { limit: 50 },\n fetchPolicy: \"cache-and-network\",\n });\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Register org name in breadcrumb registry so the URL ID shows as the org name\n useEffect(() => {\n const name = resolvedData?.developerOrganization?.name;\n if (!id || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(id, name);\n return () => reg?.unregister(id);\n }, [id, data?.developerOrganization?.name]);\n\n // Loading state — only block on initial load, not refetches (keeps SettingsTab mounted)\n if (loading && !resolvedData) {\n return (\n <PageLayout\n title={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error || !resolvedData?.developerOrganization) {\n return (\n <PageLayout\n title={tr(\"devportal.organizationNotFound\", \"Organization Not Found\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex flex-col items-center justify-center py-12 gap-4\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <h2 className=\"text-lg font-semibold\">\n {tr(\n \"devportal.organizationNotFoundLower\",\n \"Organization not found\",\n )}\n </h2>\n <p className=\"text-text-secondary\">\n {error?.message ||\n tr(\n \"devportal.organizationNotFoundDescription\",\n \"The organization you're looking for doesn't exist or you don't have access to it.\",\n )}\n </p>\n <button\n onClick={() => handleNavigate(\"/organizations\")}\n className=\"mt-4 inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n // Map GraphQL data to local types\n const org = mapOrganization(resolvedData!.developerOrganization!);\n const members = (resolvedData!.developerOrganization!.members ?? []).map(\n mapMember,\n );\n // Filter apps by this org client-side (until organizationId query filter is in gateway supergraph)\n const allApps = (appsData?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? []) as Application[];\n const apps = id\n ? allApps.filter((app) => app.developerOrganizationId === id)\n : allApps;\n\n // Calculate usage percentages\n const apiCallsUsedNum = parseInt(org.apiCallsUsed);\n const apiCallsPercent = (apiCallsUsedNum / org.apiCallsLimit) * 100;\n const storageUsedNum = parseInt(org.storageUsed);\n const storageLimitNum = parseInt(org.storageLimit);\n const storagePercent = (storageUsedNum / storageLimitNum) * 100;\n\n return (\n <PageLayout\n title={org.name}\n description={org.description}\n purpose={tr(\n \"devportal.orgDetailPurpose\",\n \"This is the home for one organization — the apps it owns, the people who can work on them, and its store and billing settings. Invite teammates, add apps, and verify the org so your published listings look trustworthy.\",\n )}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() =>\n navigate?.(\n `/billing/earnings?developerOrgId=${encodeURIComponent(org.id)}&developerOrgName=${encodeURIComponent(org.name)}`,\n )\n }\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n <DollarSign size={16} />\n {tr(\"devportal.revenue\", \"Revenue\")}\n </button>\n <button\n onClick={() => setActiveTab(\"settings\")}\n disabled={!canUpdate}\n aria-disabled={!canUpdate}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n <Edit size={16} />\n {tr(\"devportal.settings\", \"Settings\")}\n </button>\n </div>\n }\n >\n {/* Tabs */}\n <div className=\"border-b\">\n <nav\n className=\"-mb-px flex gap-4 overflow-x-auto\"\n role=\"tablist\"\n aria-label={tr(\n \"devportal.organizationSections\",\n \"Organization sections\",\n )}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n return (\n <button\n key={tab.id}\n id={`organization-tab-${tab.id}`}\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n aria-controls={`organization-panel-${tab.id}`}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n \"flex items-center gap-2 border-b-2 px-1 py-3 text-sm font-medium transition-colors\",\n activeTab === tab.id\n ? \"border-primary text-primary\"\n : \"border-transparent text-text-secondary hover:text-text-primary hover:border-muted-foreground\",\n )}\n >\n <Icon size={16} />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n\n {/* Guided next steps (dismissable) */}\n <NextSteps\n className=\"mt-6\"\n storageKey={`devportal-org-${org.id}`}\n steps={[\n {\n id: \"invite-members\",\n label: tr(\"devportal.inviteMembers\", \"Invite members\"),\n description: tr(\n \"devportal.orgStepInvite\",\n \"Add teammates so they can build alongside you\",\n ),\n icon: <Users size={16} />,\n onClick: () => setActiveTab(\"members\"),\n },\n {\n id: \"create-app\",\n label: tr(\"devportal.createApp\", \"Create App\"),\n description: tr(\n \"devportal.orgStepCreateApp\",\n \"Build a new application under this organization\",\n ),\n icon: <AppWindow size={16} />,\n onClick: () => handleNavigate(\"/apps/new\"),\n },\n {\n id: \"settings\",\n label: tr(\n \"devportal.orgStepVerify\",\n \"Complete organization profile\",\n ),\n description: tr(\n \"devportal.orgStepVerifyDesc\",\n \"Add a logo and details, then request verification\",\n ),\n icon: <Edit size={16} />,\n onClick: () => setActiveTab(\"settings\"),\n done: Boolean(org.isVerified),\n },\n ]}\n />\n\n {/* Tab content */}\n <div\n className=\"mt-6\"\n id={`organization-panel-${activeTab}`}\n role=\"tabpanel\"\n aria-labelledby={`organization-tab-${activeTab}`}\n tabIndex={0}\n >\n {activeTab === \"overview\" && (\n <OverviewTab\n org={org}\n apps={apps}\n members={members}\n apiCallsPercent={apiCallsPercent}\n storagePercent={storagePercent}\n onNavigate={handleNavigate}\n onShowApps={() => setActiveTab(\"apps\")}\n />\n )}\n {activeTab === \"apps\" && (\n <AppsTab apps={apps} onNavigate={handleNavigate} />\n )}\n {activeTab === \"members\" && (\n <MembersTab\n members={members}\n onNavigate={handleNavigate}\n orgId={org.id}\n />\n )}\n {activeTab === \"settings\" && <SettingsTab org={org} />}\n </div>\n </PageLayout>\n );\n};\n\n// Overview Tab\nconst OverviewTab: FC<{\n org: DeveloperOrganization;\n apps: Application[];\n members: DeveloperOrgMember[];\n apiCallsPercent: number;\n storagePercent: number;\n onNavigate: (path: string) => void;\n onShowApps: () => void;\n}> = ({\n org,\n apps,\n members,\n apiCallsPercent,\n storagePercent,\n onNavigate,\n onShowApps,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Stats — primary emphasis zone */}\n <EmphasisPanel>\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.publishedApps\", \"Published Apps\")}\n value={`${org.publishedApps}/${org.totalApps}`}\n icon={<AppWindow size={20} />}\n />\n <StatCard\n title={tr(\"devportal.totalInstalls\", \"Total Installs\")}\n value={org.totalInstalls.toLocaleString()}\n icon={<TrendingUp size={20} />}\n trend={{\n value: 12,\n label: tr(\"devportal.thisMonth\", \"this month\"),\n }}\n />\n <StatCard\n title={tr(\"devportal.totalRevenue\", \"Total Revenue\")}\n value={`$${org.totalRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n <StatCard\n title={tr(\"devportal.avgRating\", \"Avg Rating\")}\n value={\n org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")\n }\n icon={<BarChart3 size={20} />}\n />\n </StatCardGrid>\n </EmphasisPanel>\n\n {/* Recent Apps */}\n <PageSection\n title={tr(\"devportal.recentApplications\", \"Recent Applications\")}\n actions={\n <button\n onClick={onShowApps}\n className=\"text-sm text-primary hover:underline flex items-center gap-1\"\n >\n {tr(\"devportal.viewAll\", \"View all\")} <ArrowRight size={14} />\n </button>\n }\n >\n {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.slice(0, 3).map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={24} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createYourFirstApplication\",\n \"Create your first application\",\n )}\n />\n )}\n </PageSection>\n\n {/* Usage Quotas */}\n <PageSection title={tr(\"devportal.usageAndQuotas\", \"Usage & Quotas\")}>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <UsageCard\n label={tr(\"devportal.apiCalls\", \"API Calls\")}\n used={parseInt(org.apiCallsUsed)}\n limit={org.apiCallsLimit}\n percent={apiCallsPercent}\n format=\"number\"\n />\n <UsageCard\n label={tr(\"devportal.storage\", \"Storage\")}\n used={parseInt(org.storageUsed)}\n limit={parseInt(org.storageLimit)}\n percent={storagePercent}\n format=\"bytes\"\n />\n </div>\n {org.quotaResetAt && (\n <p className=\"text-xs text-text-secondary mt-2\">\n {tr(\"devportal.quotasResetOn\", \"Quotas reset on\")}{\" \"}\n {new Date(org.quotaResetAt).toLocaleDateString()}\n </p>\n )}\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Stats */}\n <PageSection title={tr(\"devportal.revenueSummary\", \"Revenue Summary\")}>\n <DetailList\n items={[\n {\n label: tr(\"devportal.totalRevenue\", \"Total Revenue\"),\n value: `$${org.totalRevenue.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.platformFees\", \"Platform Fees\"),\n value: `$${org.totalPlatformFees.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.netPayouts\", \"Net Payouts\"),\n value: `$${org.totalPayouts.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.pendingBalance\", \"Pending Balance\"),\n value: `$${org.pendingBalance.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.lifetimeRevenue\", \"Lifetime Revenue\"),\n value: `$${org.lifetimeRevenue.toLocaleString()}`,\n },\n ]}\n />\n </PageSection>\n\n {/* Team */}\n <PageSection\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n actions={\n <button\n onClick={() => onNavigate(`/organizations/${org.id}/members`)}\n className=\"text-sm text-primary hover:underline\"\n >\n {tr(\"devportal.manage\", \"Manage\")}\n </button>\n }\n >\n <div className=\"space-y-2\">\n {members.slice(0, 3).map((member) => (\n <div\n key={member.id}\n className=\"flex items-center justify-between py-2\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <div>\n <p className=\"text-sm font-medium\">{member.email}</p>\n <p className=\"text-xs text-text-secondary\">\n {ORG_ROLE_LABELS[member.role]}\n </p>\n </div>\n </div>\n </div>\n ))}\n {members.length > 3 && (\n <p className=\"text-xs text-text-secondary\">\n +{members.length - 3}{\" \"}\n {tr(\"devportal.moreMembers\", \"more members\")}\n </p>\n )}\n </div>\n </PageSection>\n\n {/* Links */}\n <PageSection title={tr(\"devportal.links\", \"Links\")}>\n <div className=\"space-y-2\">\n {org.websiteUrl && (\n <a\n href={org.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {tr(\"devportal.website\", \"Website\")}\n </a>\n )}\n {org.contactEmail && (\n <a\n href={`mailto:${org.contactEmail}`}\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {org.contactEmail}\n </a>\n )}\n </div>\n </PageSection>\n </div>\n </div>\n );\n};\n\n// Apps Tab\nconst AppsTab: FC<{\n apps: Application[];\n onNavigate: (path: string) => void;\n}> = ({ apps, onNavigate }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n return (\n <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {apps.length}{\" \"}\n {apps.length !== 1\n ? tr(\"devportal.applications\", \"applications\")\n : tr(\"devportal.application\", \"application\")}\n </p>\n <button\n onClick={() => onNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n </div>\n\n {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={32} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createFirstAppForOrg\",\n \"Create your first application for this organization\",\n )}\n action={\n <button\n onClick={() => onNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n }\n />\n )}\n </div>\n );\n};\n\n// Members Tab\nconst MembersTab: FC<{\n members: DeveloperOrgMember[];\n onNavigate: (path: string) => void;\n orgId: string;\n}> = ({ members, onNavigate, orgId }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n return (\n <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {members.length}{\" \"}\n {members.length !== 1\n ? tr(\"devportal.membersLower\", \"members\")\n : tr(\"devportal.memberLower\", \"member\")}\n </p>\n <button\n onClick={() => onNavigate(`/organizations/${orgId}/members`)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.inviteMember\", \"Invite Member\")}\n </button>\n </div>\n\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => (\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <span className=\"font-medium\">{member.email}</span>\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium\",\n member.role === \"OWNER\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : member.role === \"ADMIN\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : member.role === \"DEVELOPER\"\n ? \"bg-status-success-bg-subtle text-status-success-text\"\n : \"bg-bg-sunken text-text-primary\",\n )}\n >\n {ORG_ROLE_LABELS[member.role]}\n </span>\n ),\n },\n {\n key: \"joinedAt\",\n header: tr(\"devportal.joinedColumn\", \"Joined\"),\n render: (member) => new Date(member.joinedAt).toLocaleDateString(),\n },\n {\n key: \"lastActiveAt\",\n header: tr(\"devportal.lastActiveColumn\", \"Last Active\"),\n render: (member) =>\n member.lastActiveAt\n ? new Date(member.lastActiveAt).toLocaleDateString()\n : tr(\"devportal.never\", \"Never\"),\n },\n ]}\n />\n </div>\n );\n};\n\n// Settings Tab\nconst SettingsTab: FC<{ org: DeveloperOrganization }> = ({ org }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [verifyMethod, setVerifyMethod] = useState<string>(\"manual\");\n const [verifySuccess, setVerifySuccess] = useState(false);\n const [requestVerification, { loading: verifying }] =\n useRequestOrgVerificationMutation({\n onCompleted: () => setVerifySuccess(true),\n });\n return (\n <div className=\"space-y-6 max-w-2xl\">\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.organizationId\", \"Organization ID\"),\n value: <code className=\"text-xs\">{org.id}</code>,\n },\n { label: tr(\"devportal.slug\", \"Slug\"), value: org.slug },\n { label: tr(\"devportal.tier\", \"Tier\"), value: org.tier },\n {\n label: tr(\"devportal.partnerTier\", \"Partner Tier\"),\n value: org.partnerTier || tr(\"devportal.none\", \"None\"),\n },\n {\n label: tr(\"devportal.created\", \"Created\"),\n value: new Date(org.createdAt).toLocaleDateString(),\n },\n {\n label: tr(\"devportal.platformFeeRate\", \"Platform Fee Rate\"),\n value: `${(org.platformFeeRate * 100).toFixed(0)}%`,\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.legalInformation\", \"Legal Information\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.legalEntityName\", \"Legal Entity Name\"),\n value:\n org.legalEntityName ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.entityType\", \"Entity Type\"),\n value:\n org.legalEntityType ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxId\", \"Tax ID\"),\n value: org.taxId\n ? `•••••${org.taxId.slice(-4)}`\n : tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxCountry\", \"Tax Country\"),\n value:\n org.taxCountry || tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxForm\", \"Tax Form\"),\n value:\n org.taxFormType ||\n tr(\"devportal.notSubmitted\", \"Not submitted\"),\n },\n {\n label: tr(\"devportal.taxFormStatus\", \"Tax Form Status\"),\n value: org.taxFormVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verified\", \"Verified\")}\n </span>\n ) : (\n tr(\"devportal.pendingVerification\", \"Pending verification\")\n ),\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.verificationStatus\", \"Verification Status\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.verifiedLabel\", \"Verified\"),\n value: org.isVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verifiedVia\", \"Verified via\")}{\" \"}\n {org.verificationMethod}\n </span>\n ) : (\n tr(\"devportal.notVerified\", \"Not verified\")\n ),\n },\n {\n label: tr(\"devportal.certifiedLabel\", \"Certified\"),\n value: org.isCertified ? (\n <span className=\"text-accent-blue flex items-center gap-1\">\n <Shield size={14} />{\" \"}\n {tr(\"devportal.certifiedUntil\", \"Certified until\")}{\" \"}\n {org.certificationExpiry\n ? new Date(org.certificationExpiry).toLocaleDateString()\n : \"N/A\"}\n </span>\n ) : (\n tr(\"devportal.notCertified\", \"Not certified\")\n ),\n },\n ]}\n />\n {!org.isVerified && (\n <div className=\"mt-4 rounded-md border border-border-subtle p-4 space-y-3\">\n {verifySuccess ? (\n <p className=\"text-sm text-status-success-text flex items-center gap-2\">\n <CheckCircle size={14} />\n {tr(\n \"devportal.verificationRequested\",\n \"Verification request submitted. Our team will review and contact you.\",\n )}\n </p>\n ) : (\n <>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.requestVerificationHint\",\n \"Get your organization verified to build trust with users. Choose a verification method:\",\n )}\n </p>\n <div className=\"flex gap-2 flex-wrap\">\n {[\"domain\", \"document\", \"manual\"].map((m) => (\n <button\n key={m}\n type=\"button\"\n onClick={() => setVerifyMethod(m)}\n className={`rounded-md border px-3 py-1 text-xs font-medium transition-colors ${\n verifyMethod === m\n ? \"bg-action-primary-bg text-action-primary-text border-primary\"\n : \"border-border-subtle hover:bg-bg-sunken\"\n }`}\n >\n {m === \"domain\"\n ? tr(\"devportal.domainVerification\", \"Domain\")\n : m === \"document\"\n ? tr(\"devportal.documentVerification\", \"Document\")\n : tr(\"devportal.manualVerification\", \"Manual review\")}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n disabled={verifying}\n onClick={() =>\n requestVerification({\n variables: { id: org.id, method: verifyMethod },\n })\n }\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {verifying ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : (\n <Shield size={14} />\n )}\n {tr(\"devportal.requestVerification\", \"Request Verification\")}\n </button>\n </>\n )}\n </div>\n )}\n </PageSection>\n </div>\n );\n};\n\n// Usage Card Component\nconst UsageCard: FC<{\n label: string;\n used: number;\n limit: number;\n percent: number;\n format: \"number\" | \"bytes\";\n}> = ({ label, used, limit, percent, format }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const formatValue = (value: number): string => {\n if (format === \"bytes\") {\n const gb = value / (1024 * 1024 * 1024);\n return `${gb.toFixed(1)} GB`;\n }\n if (value >= 1000000) {\n return `${(value / 1000000).toFixed(1)}M`;\n }\n if (value >= 1000) {\n return `${(value / 1000).toFixed(1)}K`;\n }\n return value.toLocaleString();\n };\n\n return (\n <div className=\"rounded-card border border-border-seam p-4\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-medium\">{label}</span>\n <span className=\"text-xs text-text-secondary\">\n {formatValue(used)} / {formatValue(limit)}\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={cn(\n \"h-full rounded-full transition-all\",\n percent > 90\n ? \"bg-status-error-bg-subtle\"\n : percent > 70\n ? \"bg-status-warning-bg-subtle\"\n : \"bg-action-primary-bg\",\n )}\n style={{ width: `${Math.min(percent, 100)}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary mt-1\">\n {percent.toFixed(1)}% {tr(\"devportal.used\", \"used\")}\n </p>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OrganizationDetailPage.js","names":[],"sources":["../../../src/devportal/pages/OrganizationDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState, useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Building2,\n Users,\n AppWindow,\n DollarSign,\n Settings,\n ExternalLink,\n CheckCircle,\n BarChart3,\n TrendingUp,\n ArrowRight,\n Plus,\n Edit,\n Shield,\n Loader2,\n AlertCircle,\n} from \"lucide-react\";\nimport { EmphasisPanel, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { DataTable, DetailList } from \"../components/DataTable\";\nimport { AppListItem } from \"../components/AppCard\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport type {\n DeveloperOrganization,\n Application,\n DeveloperOrgMember,\n} from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { ORG_ROLE_LABELS } from \"../utils/constants\";\nimport {\n useGetOrganizationQuery,\n useGetApplicationsQuery,\n useRequestOrgVerificationMutation,\n} from \"../../generated/global-operations\";\nimport type {\n OrganizationFieldsFragment,\n OrgMemberFieldsFragment,\n ApplicationFieldsFragment,\n} from \"../../generated/global-operations\";\n\n/**\n * Map GraphQL organization fragment to local type\n */\nfunction mapOrganization(\n org: OrganizationFieldsFragment,\n): DeveloperOrganization {\n return {\n id: org.id,\n name: org.name,\n slug: org.slug,\n description: org.description ?? undefined,\n logoUrl: org.logoUrl ?? undefined,\n bannerUrl: org.bannerUrl ?? undefined,\n websiteUrl: org.websiteUrl ?? undefined,\n contactEmail: org.contactEmail ?? undefined,\n supportEmail: org.supportEmail ?? undefined,\n tier: org.tier as DeveloperOrganization[\"tier\"],\n partnerTier:\n (org.partnerTier as DeveloperOrganization[\"partnerTier\"]) ?? undefined,\n partnerSince: org.partnerSince ?? undefined,\n isVerified: org.isVerified ?? false,\n verifiedAt: org.verifiedAt ?? undefined,\n isCertified: org.isCertified ?? false,\n certifiedAt: org.certifiedAt ?? undefined,\n totalApps: org.totalApps ?? 0,\n publishedApps: org.publishedApps ?? 0,\n totalInstalls: org.totalInstalls ?? 0,\n activeInstalls: org.activeInstalls ?? 0,\n totalApiCalls: org.totalApiCalls ?? \"0\",\n averageRating: org.averageRating ?? undefined,\n totalRevenue: org.totalRevenue ?? 0,\n totalPlatformFees: org.totalPlatformFees ?? 0,\n totalPayouts: org.totalPayouts ?? 0,\n pendingBalance: org.pendingBalance ?? 0,\n lifetimeRevenue: org.lifetimeRevenue ?? 0,\n platformFeeRate: org.platformFeeRate ?? 0.3,\n apiCallsLimit: org.apiCallsLimit ?? 100000,\n storageLimit: org.storageLimit ?? \"1073741824\",\n apiCallsUsed: org.apiCallsUsed ?? \"0\",\n storageUsed: org.storageUsed ?? \"0\",\n taxId: org.taxId ?? undefined,\n taxCountry: org.taxCountry ?? undefined,\n taxFormVerified: org.taxFormVerified ?? false,\n legalEntityName: org.legalEntityName ?? undefined,\n legalEntityType: org.legalEntityType ?? undefined,\n createdAt: org.createdAt,\n updatedAt: org.updatedAt,\n };\n}\n\n/**\n * Map GraphQL member fragment to local type\n */\nfunction mapMember(member: OrgMemberFieldsFragment): DeveloperOrgMember {\n return {\n id: member.id,\n organizationId: member.organizationId,\n userId: member.userId,\n email: member.email ?? undefined,\n role: member.role as DeveloperOrgMember[\"role\"],\n isActive: member.isActive ?? true,\n isSuspended: member.isSuspended ?? false,\n suspendedAt: member.suspendedAt ?? undefined,\n suspendedReason: member.suspendedReason ?? undefined,\n joinedAt: member.joinedAt,\n lastActiveAt: member.lastActiveAt ?? undefined,\n permissions: member.permissions ?? undefined,\n invitedBy: member.invitedBy ?? undefined,\n invitationId: member.invitationId ?? undefined,\n createdAt: member.createdAt,\n updatedAt: member.updatedAt,\n };\n}\n\ntype TabId = \"overview\" | \"apps\" | \"members\" | \"settings\";\n\n/**\n * Organization detail page\n */\nexport const OrganizationDetailPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { orgId: id } = useParams<{ orgId: string }>();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { allowed: canUpdate } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.ORG_UPDATE,\n );\n const [activeTab, setActiveTab] = useState<TabId>(\"overview\");\n\n const tabs: Array<{ id: TabId; label: string; icon: FC<{ size?: number }> }> =\n [\n {\n id: \"overview\",\n label: tr(\"devportal.overview\", \"Overview\"),\n icon: Building2,\n },\n {\n id: \"apps\",\n label: tr(\"devportal.applications\", \"Applications\"),\n icon: AppWindow,\n },\n { id: \"members\", label: tr(\"devportal.members\", \"Members\"), icon: Users },\n {\n id: \"settings\",\n label: tr(\"devportal.settings\", \"Settings\"),\n icon: Settings,\n },\n ];\n\n // Fetch organization data\n const { data, previousData, loading, error } = useGetOrganizationQuery({\n variables: { id: id! },\n skip: !id,\n });\n const resolvedData = data ?? previousData;\n\n const { data: appsData } = useGetApplicationsQuery({\n variables: { limit: 50, organizationId: id },\n skip: !id,\n fetchPolicy: \"cache-and-network\",\n });\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Register org name in breadcrumb registry so the URL ID shows as the org name\n useEffect(() => {\n const name = resolvedData?.developerOrganization?.name;\n if (!id || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(id, name);\n return () => reg?.unregister(id);\n }, [id, data?.developerOrganization?.name]);\n\n // Loading state — only block on initial load, not refetches (keeps SettingsTab mounted)\n if (loading && !resolvedData) {\n return (\n <PageLayout\n title={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n // Error state\n if (error || !resolvedData?.developerOrganization) {\n return (\n <PageLayout\n title={tr(\"devportal.organizationNotFound\", \"Organization Not Found\")}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <div className=\"flex flex-col items-center justify-center py-12 gap-4\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <h2 className=\"text-lg font-semibold\">\n {tr(\n \"devportal.organizationNotFoundLower\",\n \"Organization not found\",\n )}\n </h2>\n <p className=\"text-text-secondary\">\n {error?.message ||\n tr(\n \"devportal.organizationNotFoundDescription\",\n \"The organization you're looking for doesn't exist or you don't have access to it.\",\n )}\n </p>\n <button\n onClick={() => handleNavigate(\"/organizations\")}\n className=\"mt-4 inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n // Map GraphQL data to local types\n const org = mapOrganization(resolvedData!.developerOrganization!);\n const members = (resolvedData!.developerOrganization!.members ?? []).map(\n mapMember,\n );\n const apps = (appsData?.applications?.edges?.map(\n (e: { node: ApplicationFieldsFragment }) => e.node,\n ) ?? []) as Application[];\n\n // Calculate usage percentages\n const apiCallsUsedNum = parseInt(org.apiCallsUsed);\n const apiCallsPercent = (apiCallsUsedNum / org.apiCallsLimit) * 100;\n const storageUsedNum = parseInt(org.storageUsed);\n const storageLimitNum = parseInt(org.storageLimit);\n const storagePercent = (storageUsedNum / storageLimitNum) * 100;\n\n return (\n <PageLayout\n title={org.name}\n description={org.description}\n purpose={tr(\n \"devportal.orgDetailPurpose\",\n \"This is the home for one organization — the apps it owns, the people who can work on them, and its store and billing settings. Invite teammates, add apps, and verify the org so your published listings look trustworthy.\",\n )}\n backLink={`${basePath}/organizations`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() =>\n navigate?.(\n `/billing/earnings?developerOrgId=${encodeURIComponent(org.id)}&developerOrgName=${encodeURIComponent(org.name)}`,\n )\n }\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors\"\n >\n <DollarSign size={16} />\n {tr(\"devportal.revenue\", \"Revenue\")}\n </button>\n <button\n onClick={() => setActiveTab(\"settings\")}\n disabled={!canUpdate}\n aria-disabled={!canUpdate}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n <Edit size={16} />\n {tr(\"devportal.settings\", \"Settings\")}\n </button>\n </div>\n }\n >\n {/* Tabs */}\n <div className=\"border-b\">\n <nav\n className=\"-mb-px flex gap-4 overflow-x-auto\"\n role=\"tablist\"\n aria-label={tr(\n \"devportal.organizationSections\",\n \"Organization sections\",\n )}\n >\n {tabs.map((tab) => {\n const Icon = tab.icon;\n return (\n <button\n key={tab.id}\n id={`organization-tab-${tab.id}`}\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n aria-controls={`organization-panel-${tab.id}`}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n \"flex items-center gap-2 border-b-2 px-1 py-3 text-sm font-medium transition-colors\",\n activeTab === tab.id\n ? \"border-primary text-primary\"\n : \"border-transparent text-text-secondary hover:text-text-primary hover:border-muted-foreground\",\n )}\n >\n <Icon size={16} />\n {tab.label}\n </button>\n );\n })}\n </nav>\n </div>\n\n {/* Guided next steps (dismissable) */}\n <NextSteps\n className=\"mt-6\"\n storageKey={`devportal-org-${org.id}`}\n steps={[\n {\n id: \"invite-members\",\n label: tr(\"devportal.inviteMembers\", \"Invite members\"),\n description: tr(\n \"devportal.orgStepInvite\",\n \"Add teammates so they can build alongside you\",\n ),\n icon: <Users size={16} />,\n onClick: () => setActiveTab(\"members\"),\n },\n {\n id: \"create-app\",\n label: tr(\"devportal.createApp\", \"Create App\"),\n description: tr(\n \"devportal.orgStepCreateApp\",\n \"Build a new application under this organization\",\n ),\n icon: <AppWindow size={16} />,\n onClick: () => handleNavigate(\"/apps/new\"),\n },\n {\n id: \"settings\",\n label: tr(\n \"devportal.orgStepVerify\",\n \"Complete organization profile\",\n ),\n description: tr(\n \"devportal.orgStepVerifyDesc\",\n \"Add a logo and details, then request verification\",\n ),\n icon: <Edit size={16} />,\n onClick: () => setActiveTab(\"settings\"),\n done: Boolean(org.isVerified),\n },\n ]}\n />\n\n {/* Tab content */}\n <div\n className=\"mt-6\"\n id={`organization-panel-${activeTab}`}\n role=\"tabpanel\"\n aria-labelledby={`organization-tab-${activeTab}`}\n tabIndex={0}\n >\n {activeTab === \"overview\" && (\n <OverviewTab\n org={org}\n apps={apps}\n members={members}\n apiCallsPercent={apiCallsPercent}\n storagePercent={storagePercent}\n onNavigate={handleNavigate}\n onShowApps={() => setActiveTab(\"apps\")}\n />\n )}\n {activeTab === \"apps\" && (\n <AppsTab apps={apps} onNavigate={handleNavigate} />\n )}\n {activeTab === \"members\" && (\n <MembersTab\n members={members}\n onNavigate={handleNavigate}\n orgId={org.id}\n />\n )}\n {activeTab === \"settings\" && <SettingsTab org={org} />}\n </div>\n </PageLayout>\n );\n};\n\n// Overview Tab\nconst OverviewTab: FC<{\n org: DeveloperOrganization;\n apps: Application[];\n members: DeveloperOrgMember[];\n apiCallsPercent: number;\n storagePercent: number;\n onNavigate: (path: string) => void;\n onShowApps: () => void;\n}> = ({\n org,\n apps,\n members,\n apiCallsPercent,\n storagePercent,\n onNavigate,\n onShowApps,\n}) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Stats — primary emphasis zone */}\n <EmphasisPanel>\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.publishedApps\", \"Published Apps\")}\n value={`${org.publishedApps}/${org.totalApps}`}\n icon={<AppWindow size={20} />}\n />\n <StatCard\n title={tr(\"devportal.totalInstalls\", \"Total Installs\")}\n value={org.totalInstalls.toLocaleString()}\n icon={<TrendingUp size={20} />}\n trend={{\n value: 12,\n label: tr(\"devportal.thisMonth\", \"this month\"),\n }}\n />\n <StatCard\n title={tr(\"devportal.totalRevenue\", \"Total Revenue\")}\n value={`$${org.totalRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n <StatCard\n title={tr(\"devportal.avgRating\", \"Avg Rating\")}\n value={\n org.averageRating\n ? `${org.averageRating.toFixed(1)} ★`\n : tr(\"devportal.notAvailable\", \"N/A\")\n }\n icon={<BarChart3 size={20} />}\n />\n </StatCardGrid>\n </EmphasisPanel>\n\n {/* Recent Apps */}\n <PageSection\n title={tr(\"devportal.recentApplications\", \"Recent Applications\")}\n actions={\n <button\n onClick={onShowApps}\n className=\"text-sm text-primary hover:underline flex items-center gap-1\"\n >\n {tr(\"devportal.viewAll\", \"View all\")} <ArrowRight size={14} />\n </button>\n }\n >\n {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.slice(0, 3).map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={24} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createYourFirstApplication\",\n \"Create your first application\",\n )}\n />\n )}\n </PageSection>\n\n {/* Usage Quotas */}\n <PageSection title={tr(\"devportal.usageAndQuotas\", \"Usage & Quotas\")}>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <UsageCard\n label={tr(\"devportal.apiCalls\", \"API Calls\")}\n used={parseInt(org.apiCallsUsed)}\n limit={org.apiCallsLimit}\n percent={apiCallsPercent}\n format=\"number\"\n />\n <UsageCard\n label={tr(\"devportal.storage\", \"Storage\")}\n used={parseInt(org.storageUsed)}\n limit={parseInt(org.storageLimit)}\n percent={storagePercent}\n format=\"bytes\"\n />\n </div>\n {org.quotaResetAt && (\n <p className=\"text-xs text-text-secondary mt-2\">\n {tr(\"devportal.quotasResetOn\", \"Quotas reset on\")}{\" \"}\n {new Date(org.quotaResetAt).toLocaleDateString()}\n </p>\n )}\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Quick Stats */}\n <PageSection title={tr(\"devportal.revenueSummary\", \"Revenue Summary\")}>\n <DetailList\n items={[\n {\n label: tr(\"devportal.totalRevenue\", \"Total Revenue\"),\n value: `$${org.totalRevenue.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.platformFees\", \"Platform Fees\"),\n value: `$${org.totalPlatformFees.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.netPayouts\", \"Net Payouts\"),\n value: `$${org.totalPayouts.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.pendingBalance\", \"Pending Balance\"),\n value: `$${org.pendingBalance.toLocaleString()}`,\n },\n {\n label: tr(\"devportal.lifetimeRevenue\", \"Lifetime Revenue\"),\n value: `$${org.lifetimeRevenue.toLocaleString()}`,\n },\n ]}\n />\n </PageSection>\n\n {/* Team */}\n <PageSection\n title={tr(\"devportal.teamMembers\", \"Team Members\")}\n actions={\n <button\n onClick={() => onNavigate(`/organizations/${org.id}/members`)}\n className=\"text-sm text-primary hover:underline\"\n >\n {tr(\"devportal.manage\", \"Manage\")}\n </button>\n }\n >\n <div className=\"space-y-2\">\n {members.slice(0, 3).map((member) => (\n <div\n key={member.id}\n className=\"flex items-center justify-between py-2\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <div>\n <p className=\"text-sm font-medium\">{member.email}</p>\n <p className=\"text-xs text-text-secondary\">\n {ORG_ROLE_LABELS[member.role]}\n </p>\n </div>\n </div>\n </div>\n ))}\n {members.length > 3 && (\n <p className=\"text-xs text-text-secondary\">\n +{members.length - 3}{\" \"}\n {tr(\"devportal.moreMembers\", \"more members\")}\n </p>\n )}\n </div>\n </PageSection>\n\n {/* Links */}\n <PageSection title={tr(\"devportal.links\", \"Links\")}>\n <div className=\"space-y-2\">\n {org.websiteUrl && (\n <a\n href={org.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {tr(\"devportal.website\", \"Website\")}\n </a>\n )}\n {org.contactEmail && (\n <a\n href={`mailto:${org.contactEmail}`}\n className=\"flex items-center gap-2 text-sm text-primary hover:underline\"\n >\n <ExternalLink size={14} />\n {org.contactEmail}\n </a>\n )}\n </div>\n </PageSection>\n </div>\n </div>\n );\n};\n\n// Apps Tab\nconst AppsTab: FC<{\n apps: Application[];\n onNavigate: (path: string) => void;\n}> = ({ apps, onNavigate }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n return (\n <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {apps.length}{\" \"}\n {apps.length !== 1\n ? tr(\"devportal.applications\", \"applications\")\n : tr(\"devportal.application\", \"application\")}\n </p>\n <button\n onClick={() => onNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n </div>\n\n {apps.length > 0 ? (\n <div className=\"space-y-2\">\n {apps.map((app) => (\n <AppListItem\n key={app.id}\n app={app}\n onClick={() => onNavigate(`/apps/${app.id}`)}\n />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<AppWindow size={32} />}\n title={tr(\"devportal.noApplications\", \"No applications\")}\n description={tr(\n \"devportal.createFirstAppForOrg\",\n \"Create your first application for this organization\",\n )}\n action={\n <button\n onClick={() => onNavigate(\"/apps/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.createApp\", \"Create App\")}\n </button>\n }\n />\n )}\n </div>\n );\n};\n\n// Members Tab\nconst MembersTab: FC<{\n members: DeveloperOrgMember[];\n onNavigate: (path: string) => void;\n orgId: string;\n}> = ({ members, onNavigate, orgId }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n return (\n <div className=\"space-y-6\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {members.length}{\" \"}\n {members.length !== 1\n ? tr(\"devportal.membersLower\", \"members\")\n : tr(\"devportal.memberLower\", \"member\")}\n </p>\n <button\n onClick={() => onNavigate(`/organizations/${orgId}/members`)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n <Plus size={16} />\n {tr(\"devportal.inviteMember\", \"Invite Member\")}\n </button>\n </div>\n\n <DataTable\n data={members}\n keyField=\"id\"\n columns={[\n {\n key: \"email\",\n header: tr(\"devportal.memberColumn\", \"Member\"),\n render: (member) => (\n <div className=\"flex items-center gap-3\">\n <div className=\"h-8 w-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center text-sm font-medium text-primary\">\n {member.email?.charAt(0).toUpperCase() || \"U\"}\n </div>\n <span className=\"font-medium\">{member.email}</span>\n </div>\n ),\n },\n {\n key: \"role\",\n header: tr(\"devportal.roleColumn\", \"Role\"),\n render: (member) => (\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium\",\n member.role === \"OWNER\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : member.role === \"ADMIN\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : member.role === \"DEVELOPER\"\n ? \"bg-status-success-bg-subtle text-status-success-text\"\n : \"bg-bg-sunken text-text-primary\",\n )}\n >\n {ORG_ROLE_LABELS[member.role]}\n </span>\n ),\n },\n {\n key: \"joinedAt\",\n header: tr(\"devportal.joinedColumn\", \"Joined\"),\n render: (member) => new Date(member.joinedAt).toLocaleDateString(),\n },\n {\n key: \"lastActiveAt\",\n header: tr(\"devportal.lastActiveColumn\", \"Last Active\"),\n render: (member) =>\n member.lastActiveAt\n ? new Date(member.lastActiveAt).toLocaleDateString()\n : tr(\"devportal.never\", \"Never\"),\n },\n ]}\n />\n </div>\n );\n};\n\n// Settings Tab\nconst SettingsTab: FC<{ org: DeveloperOrganization }> = ({ org }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const [verifyMethod, setVerifyMethod] = useState<string>(\"manual\");\n const [verifySuccess, setVerifySuccess] = useState(false);\n const [requestVerification, { loading: verifying }] =\n useRequestOrgVerificationMutation({\n onCompleted: () => setVerifySuccess(true),\n });\n return (\n <div className=\"space-y-6 max-w-2xl\">\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.organizationId\", \"Organization ID\"),\n value: <code className=\"text-xs\">{org.id}</code>,\n },\n { label: tr(\"devportal.slug\", \"Slug\"), value: org.slug },\n { label: tr(\"devportal.tier\", \"Tier\"), value: org.tier },\n {\n label: tr(\"devportal.partnerTier\", \"Partner Tier\"),\n value: org.partnerTier || tr(\"devportal.none\", \"None\"),\n },\n {\n label: tr(\"devportal.created\", \"Created\"),\n value: new Date(org.createdAt).toLocaleDateString(),\n },\n {\n label: tr(\"devportal.platformFeeRate\", \"Platform Fee Rate\"),\n value: `${(org.platformFeeRate * 100).toFixed(0)}%`,\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.legalInformation\", \"Legal Information\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.legalEntityName\", \"Legal Entity Name\"),\n value:\n org.legalEntityName ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.entityType\", \"Entity Type\"),\n value:\n org.legalEntityType ||\n tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxId\", \"Tax ID\"),\n value: org.taxId\n ? `•••••${org.taxId.slice(-4)}`\n : tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxCountry\", \"Tax Country\"),\n value:\n org.taxCountry || tr(\"devportal.notProvided\", \"Not provided\"),\n },\n {\n label: tr(\"devportal.taxForm\", \"Tax Form\"),\n value:\n org.taxFormType ||\n tr(\"devportal.notSubmitted\", \"Not submitted\"),\n },\n {\n label: tr(\"devportal.taxFormStatus\", \"Tax Form Status\"),\n value: org.taxFormVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verified\", \"Verified\")}\n </span>\n ) : (\n tr(\"devportal.pendingVerification\", \"Pending verification\")\n ),\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.verificationStatus\", \"Verification Status\")}\n >\n <DetailList\n items={[\n {\n label: tr(\"devportal.verifiedLabel\", \"Verified\"),\n value: org.isVerified ? (\n <span className=\"text-status-success-text flex items-center gap-1\">\n <CheckCircle size={14} />{\" \"}\n {tr(\"devportal.verifiedVia\", \"Verified via\")}{\" \"}\n {org.verificationMethod}\n </span>\n ) : (\n tr(\"devportal.notVerified\", \"Not verified\")\n ),\n },\n {\n label: tr(\"devportal.certifiedLabel\", \"Certified\"),\n value: org.isCertified ? (\n <span className=\"text-accent-blue flex items-center gap-1\">\n <Shield size={14} />{\" \"}\n {tr(\"devportal.certifiedUntil\", \"Certified until\")}{\" \"}\n {org.certificationExpiry\n ? new Date(org.certificationExpiry).toLocaleDateString()\n : \"N/A\"}\n </span>\n ) : (\n tr(\"devportal.notCertified\", \"Not certified\")\n ),\n },\n ]}\n />\n {!org.isVerified && (\n <div className=\"mt-4 rounded-md border border-border-subtle p-4 space-y-3\">\n {verifySuccess ? (\n <p className=\"text-sm text-status-success-text flex items-center gap-2\">\n <CheckCircle size={14} />\n {tr(\n \"devportal.verificationRequested\",\n \"Verification request submitted. Our team will review and contact you.\",\n )}\n </p>\n ) : (\n <>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.requestVerificationHint\",\n \"Get your organization verified to build trust with users. Choose a verification method:\",\n )}\n </p>\n <div className=\"flex gap-2 flex-wrap\">\n {[\"domain\", \"document\", \"manual\"].map((m) => (\n <button\n key={m}\n type=\"button\"\n onClick={() => setVerifyMethod(m)}\n className={`rounded-md border px-3 py-1 text-xs font-medium transition-colors ${\n verifyMethod === m\n ? \"bg-action-primary-bg text-action-primary-text border-primary\"\n : \"border-border-subtle hover:bg-bg-sunken\"\n }`}\n >\n {m === \"domain\"\n ? tr(\"devportal.domainVerification\", \"Domain\")\n : m === \"document\"\n ? tr(\"devportal.documentVerification\", \"Document\")\n : tr(\"devportal.manualVerification\", \"Manual review\")}\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n disabled={verifying}\n onClick={() =>\n requestVerification({\n variables: { id: org.id, method: verifyMethod },\n })\n }\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {verifying ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : (\n <Shield size={14} />\n )}\n {tr(\"devportal.requestVerification\", \"Request Verification\")}\n </button>\n </>\n )}\n </div>\n )}\n </PageSection>\n </div>\n );\n};\n\n// Usage Card Component\nconst UsageCard: FC<{\n label: string;\n used: number;\n limit: number;\n percent: number;\n format: \"number\" | \"bytes\";\n}> = ({ label, used, limit, percent, format }) => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const formatValue = (value: number): string => {\n if (format === \"bytes\") {\n const gb = value / (1024 * 1024 * 1024);\n return `${gb.toFixed(1)} GB`;\n }\n if (value >= 1000000) {\n return `${(value / 1000000).toFixed(1)}M`;\n }\n if (value >= 1000) {\n return `${(value / 1000).toFixed(1)}K`;\n }\n return value.toLocaleString();\n };\n\n return (\n <div className=\"rounded-card border border-border-seam p-4\">\n <div className=\"flex items-center justify-between mb-2\">\n <span className=\"text-sm font-medium\">{label}</span>\n <span className=\"text-xs text-text-secondary\">\n {formatValue(used)} / {formatValue(limit)}\n </span>\n </div>\n <div className=\"h-2 rounded-full bg-bg-sunken overflow-hidden\">\n <div\n className={cn(\n \"h-full rounded-full transition-all\",\n percent > 90\n ? \"bg-status-error-bg-subtle\"\n : percent > 70\n ? \"bg-status-warning-bg-subtle\"\n : \"bg-action-primary-bg\",\n )}\n style={{ width: `${Math.min(percent, 100)}%` }}\n />\n </div>\n <p className=\"text-xs text-text-secondary mt-1\">\n {percent.toFixed(1)}% {tr(\"devportal.used\", \"used\")}\n </p>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -553,13 +553,14 @@ function ie(e) {
553
553
  return t.useQuery(y, r);
554
554
  }
555
555
  var b = e`
556
- query GetApplications($limit: Int, $offset: Int, $status: AppStatus, $visibility: AppVisibility, $developerId: ID) {
556
+ query GetApplications($limit: Int, $offset: Int, $status: AppStatus, $visibility: AppVisibility, $developerId: ID, $organizationId: ID) {
557
557
  applications(
558
558
  limit: $limit
559
559
  offset: $offset
560
560
  status: $status
561
561
  visibility: $visibility
562
562
  developerId: $developerId
563
+ organizationId: $organizationId
563
564
  ) {
564
565
  totalCount
565
566
  edges {
@@ -1197,11 +1198,11 @@ e`
1197
1198
  }
1198
1199
  `;
1199
1200
  var Y = e`
1200
- query GetDevportalDashboardBootstrap {
1201
+ query GetDevportalDashboardBootstrap($organizationId: ID) {
1201
1202
  myDeveloperOrganizations {
1202
1203
  ...OrganizationFields
1203
1204
  }
1204
- applications(limit: 5) {
1205
+ applications(limit: 5, organizationId: $organizationId) {
1205
1206
  totalCount
1206
1207
  edges {
1207
1208
  node {