From b1e7fe1714ed61498e2858b2708470a68217eec4 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Mon, 25 May 2026 16:05:23 -0700 Subject: [PATCH 1/4] add switch to org button on plan usage screen --- .../components/sections/PlanUsageSettings.tsx | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx index 9046e271b..4fd6f859a 100644 --- a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx @@ -1,4 +1,4 @@ -import { getAuthenticatedClient } from "@features/auth/hooks/authClient"; +import { useSwitchOrgMutation } from "@features/auth/hooks/authMutations"; import { useAuthStateValue } from "@features/auth/hooks/authQueries"; import { TokenSpendAnalysisBanner } from "@features/billing/components/TokenSpendAnalysisBanner"; import { useUsage } from "@features/billing/hooks/useUsage"; @@ -34,21 +34,6 @@ const log = logger.scope("plan-usage"); const SPEND_ANALYSIS_FLAG = "posthog-code-spend-analysis"; -async function openBillingPage(orgId: string | null): Promise { - if (orgId) { - try { - const client = await getAuthenticatedClient(); - if (client) { - await client.switchOrganization(orgId); - } - } catch (err) { - log.warn("Failed to switch org before opening billing", err); - } - } - const url = getBillingUrl(); - if (url) window.open(url, "_blank"); -} - export function PlanUsageSettings() { const { seat, @@ -65,7 +50,30 @@ export function PlanUsageSettings() { const { fetchSeat, upgradeToPro, cancelSeat, reactivateSeat, clearError } = useSeatStore(); const cloudRegion = useAuthStateValue((state) => state.cloudRegion); + const currentOrgId = useAuthStateValue((state) => state.currentOrgId); + const switchOrgMutation = useSwitchOrgMutation(); const billingUrl = getBillingUrl(cloudRegion); + + async function openBillingPage(orgId: string | null): Promise { + if (orgId && orgId !== currentOrgId) { + try { + await switchOrgMutation.mutateAsync(orgId); + } catch (err) { + log.warn("Failed to switch org before opening billing", err); + } + } + const url = getBillingUrl(); + if (url) window.open(url, "_blank"); + } + + async function switchToBillingOrg(orgId: string): Promise { + try { + await switchOrgMutation.mutateAsync(orgId); + await fetchSeat({ autoProvision: true }); + } catch (err) { + log.warn("Failed to switch to billing org", err); + } + } const redirectFullUrl = redirectUrl ? (getPostHogUrl(redirectUrl, cloudRegion) ?? billingUrl) : null; @@ -177,10 +185,31 @@ export function PlanUsageSettings() { - - You have a Pro plan on{" "} - {seat.organization_name}. Usage on this - page reflects your current organization. + + + + You have a Pro plan on{" "} + {seat.organization_name}. Usage on + this page reflects your current organization. + + {billingOrgId && ( + + )} + )} From 4e081581e57b6c3306661cfdb997ad32f2209667 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Mon, 25 May 2026 16:32:54 -0700 Subject: [PATCH 2/4] use scoped billing url and surface switch errors --- .../components/sections/PlanUsageSettings.tsx | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx index 4fd6f859a..6a721be46 100644 --- a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx @@ -60,19 +60,15 @@ export function PlanUsageSettings() { await switchOrgMutation.mutateAsync(orgId); } catch (err) { log.warn("Failed to switch org before opening billing", err); + return; } } - const url = getBillingUrl(); - if (url) window.open(url, "_blank"); + if (billingUrl) window.open(billingUrl, "_blank"); } async function switchToBillingOrg(orgId: string): Promise { - try { - await switchOrgMutation.mutateAsync(orgId); - await fetchSeat({ autoProvision: true }); - } catch (err) { - log.warn("Failed to switch to billing org", err); - } + await switchOrgMutation.mutateAsync(orgId); + await fetchSeat({ autoProvision: true }); } const redirectFullUrl = redirectUrl ? (getPostHogUrl(redirectUrl, cloudRegion) ?? billingUrl) @@ -193,21 +189,27 @@ export function PlanUsageSettings() { this page reflects your current organization. {billingOrgId && ( - + {switchOrgMutation.isError && ( + + Switching failed. Try again or switch from the sidebar. + )} - + )} From 7a5a8ec3c2b78893bcfeb70329b369964da470e9 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Mon, 25 May 2026 18:51:08 -0700 Subject: [PATCH 3/4] isolate billing switch pending and error state --- .../components/sections/PlanUsageSettings.tsx | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx index 6a721be46..caa860c4f 100644 --- a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx @@ -54,6 +54,11 @@ export function PlanUsageSettings() { const switchOrgMutation = useSwitchOrgMutation(); const billingUrl = getBillingUrl(cloudRegion); + const [billingSwitch, setBillingSwitch] = useState<{ + pending: boolean; + error: boolean; + }>({ pending: false, error: false }); + async function openBillingPage(orgId: string | null): Promise { if (orgId && orgId !== currentOrgId) { try { @@ -67,8 +72,15 @@ export function PlanUsageSettings() { } async function switchToBillingOrg(orgId: string): Promise { - await switchOrgMutation.mutateAsync(orgId); - await fetchSeat({ autoProvision: true }); + setBillingSwitch({ pending: true, error: false }); + try { + await switchOrgMutation.mutateAsync(orgId); + await fetchSeat({ autoProvision: true }); + setBillingSwitch({ pending: false, error: false }); + } catch (err) { + log.warn("Failed to switch to billing org", err); + setBillingSwitch({ pending: false, error: true }); + } } const redirectFullUrl = redirectUrl ? (getPostHogUrl(redirectUrl, cloudRegion) ?? billingUrl) @@ -193,18 +205,18 @@ export function PlanUsageSettings() { - {switchOrgMutation.isError && ( + {billingSwitch.error && ( Switching failed. Try again or switch from the sidebar. From ae6c12a559dd125812b04f9ba17dcea53c8ccdb6 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 26 May 2026 09:16:49 -0700 Subject: [PATCH 4/4] address Jonathan's review on plan usage switch --- .../components/sections/PlanUsageSettings.tsx | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx index caa860c4f..e36c1460f 100644 --- a/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/PlanUsageSettings.tsx @@ -54,15 +54,15 @@ export function PlanUsageSettings() { const switchOrgMutation = useSwitchOrgMutation(); const billingUrl = getBillingUrl(cloudRegion); - const [billingSwitch, setBillingSwitch] = useState<{ - pending: boolean; - error: boolean; - }>({ pending: false, error: false }); + async function switchOrgAndRefreshSeat(orgId: string): Promise { + await switchOrgMutation.mutateAsync(orgId); + await fetchSeat({ autoProvision: true }); + } async function openBillingPage(orgId: string | null): Promise { if (orgId && orgId !== currentOrgId) { try { - await switchOrgMutation.mutateAsync(orgId); + await switchOrgAndRefreshSeat(orgId); } catch (err) { log.warn("Failed to switch org before opening billing", err); return; @@ -72,14 +72,10 @@ export function PlanUsageSettings() { } async function switchToBillingOrg(orgId: string): Promise { - setBillingSwitch({ pending: true, error: false }); try { - await switchOrgMutation.mutateAsync(orgId); - await fetchSeat({ autoProvision: true }); - setBillingSwitch({ pending: false, error: false }); + await switchOrgAndRefreshSeat(orgId); } catch (err) { log.warn("Failed to switch to billing org", err); - setBillingSwitch({ pending: false, error: true }); } } const redirectFullUrl = redirectUrl @@ -205,18 +201,18 @@ export function PlanUsageSettings() { - {billingSwitch.error && ( + {switchOrgMutation.isError && ( Switching failed. Try again or switch from the sidebar.