From 1907a3c93b09a54842e29dd8608d0f86f78752c1 Mon Sep 17 00:00:00 2001 From: Owen Date: Tue, 9 Jun 2026 10:33:14 -0700 Subject: [PATCH] Link to primary org only when you can see billing --- src/app/[orgId]/layout.tsx | 41 +++++++++++++++--------- src/components/SubscriptionViolation.tsx | 37 ++++++++++++--------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/app/[orgId]/layout.tsx b/src/app/[orgId]/layout.tsx index fe0077427..f85cbd03e 100644 --- a/src/app/[orgId]/layout.tsx +++ b/src/app/[orgId]/layout.tsx @@ -21,7 +21,6 @@ import { Layout } from "@app/components/Layout"; import ApplyInternalRedirect from "@app/components/ApplyInternalRedirect"; import SubscriptionViolation from "@app/components/SubscriptionViolation"; - export default async function OrgLayout(props: { children: React.ReactNode; params: Promise<{ orgId: string }>; @@ -42,6 +41,26 @@ export default async function OrgLayout(props: { redirect(`/`); } + let orgs: ListUserOrgsResponse["orgs"] = []; + try { + const getOrgs = cache(async () => + internal.get>( + `/user/${user.userId}/orgs`, + await authCookieHeader() + ) + ); + const res = await getOrgs(); + if (res && res.data.data.orgs) { + orgs = res.data.data.orgs; + } + } catch (e) {} + + const primaryOrg = orgs.find((org) => org.isPrimaryOrg); + const canViewPrimaryBilling = Boolean(primaryOrg?.isOwner); + const primaryOrgBillingHref = primaryOrg + ? `/${primaryOrg.orgId}/settings/billing` + : null; + let accessRes: CheckOrgUserAccessResponse | null = null; try { const checkOrgAccess = cache(() => @@ -58,19 +77,6 @@ export default async function OrgLayout(props: { if (!accessRes?.allowed) { // For non-admin users, show the member resources portal - let orgs: ListUserOrgsResponse["orgs"] = []; - try { - const getOrgs = cache(async () => - internal.get>( - `/user/${user.userId}/orgs`, - await authCookieHeader() - ) - ); - const res = await getOrgs(); - if (res && res.data.data.orgs) { - orgs = res.data.data.orgs; - } - } catch (e) {} return ( @@ -110,7 +116,12 @@ export default async function OrgLayout(props: { > {props.children} - {build === "saas" && } + {build === "saas" && ( + + )} diff --git a/src/components/SubscriptionViolation.tsx b/src/components/SubscriptionViolation.tsx index 4ec1c4fda..aa3095562 100644 --- a/src/components/SubscriptionViolation.tsx +++ b/src/components/SubscriptionViolation.tsx @@ -4,20 +4,23 @@ import { Button } from "@app/components/ui/button"; import { useSubscriptionStatusContext } from "@app/hooks/useSubscriptionStatusContext"; import { useState } from "react"; import Link from "next/link"; -import { useParams } from "next/navigation"; import { useTranslations } from "next-intl"; -export default function SubscriptionViolation() { +interface SubscriptionViolationProps { + billingHref?: string | null; + canViewBilling?: boolean; +} + +export default function SubscriptionViolation({ + billingHref, + canViewBilling = false +}: SubscriptionViolationProps) { const context = useSubscriptionStatusContext(); const [isDismissed, setIsDismissed] = useState(false); - const params = useParams(); - const orgId = params?.orgId as string | undefined; const t = useTranslations(); if (!context?.limitsExceeded || isDismissed) return null; - const billingHref = orgId ? `/${orgId}/settings/billing` : "/"; - return (
@@ -25,16 +28,18 @@ export default function SubscriptionViolation() { {t("subscriptionViolationMessage")}

- + {canViewBilling && billingHref && ( + + )}