diff --git a/apps/webapp/app/components/billing/v2/UpgradePrompt.tsx b/apps/webapp/app/components/billing/v2/UpgradePrompt.tsx index 05752c614..c9939e097 100644 --- a/apps/webapp/app/components/billing/v2/UpgradePrompt.tsx +++ b/apps/webapp/app/components/billing/v2/UpgradePrompt.tsx @@ -1,20 +1,20 @@ import { ExclamationCircleIcon } from "@heroicons/react/20/solid"; -import { ArrowUpCircleIcon } from "@heroicons/react/24/outline"; import tileBgPath from "~/assets/images/error-banner-tile@2x.png"; -import { MatchedOrganization } from "~/hooks/useOrganizations"; +import { MatchedOrganization, useOrganization } from "~/hooks/useOrganizations"; import { useCurrentPlan } from "~/routes/_app.orgs.$organizationSlug/route"; -import { formatNumberCompact } from "~/utils/numberFormatter"; +import { v3BillingPath } from "~/utils/pathBuilder"; import { LinkButton } from "../../primitives/Buttons"; import { Icon } from "../../primitives/Icon"; import { Paragraph } from "../../primitives/Paragraph"; -type UpgradePromptProps = { - runsEnabled: boolean; - runCountCap: number; - planPath: string; -}; +export function UpgradePrompt() { + const organization = useOrganization(); + const plan = useCurrentPlan(); + + if (!plan || !plan.v3Usage.hasExceededFreeTier) { + return null; + } -export function UpgradePrompt({ runsEnabled, runCountCap, planPath }: UpgradePromptProps) { return (
- {runsEnabled - ? `You have exceeded the monthly ${formatNumberCompact(runCountCap)} runs - limit` - : `No runs are executing because you have exceeded the free limit`} + You have exceeded the monthly $ + {(plan.v3Subscription?.plan?.limits.includedUsage ?? 500) / 100} free credits.
Upgrade @@ -43,19 +40,6 @@ export function UpgradePrompt({ runsEnabled, runCountCap, planPath }: UpgradePro export function useShowUpgradePrompt(organization?: MatchedOrganization) { const currentPlan = useCurrentPlan(); - const shouldShow = - organization !== undefined && - currentPlan !== undefined && - currentPlan.usage.exceededRunCount && - currentPlan.usage.runCountCap !== undefined; - - if (!shouldShow) { - return { shouldShow }; - } - - return { - shouldShow, - runCountCap: currentPlan.usage.runCountCap!, - runsEnabled: organization.runsEnabled, - }; + const shouldShow = currentPlan?.v3Usage.hasExceededFreeTier === true; + return { shouldShow }; } diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index ab7a64f0a..5e5765333 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -104,7 +104,6 @@ type SideMenuProps = { export function SideMenu({ user, project, organization, organizations }: SideMenuProps) { const borderRef = useRef(null); const [showHeaderDivider, setShowHeaderDivider] = useState(false); - const { isManagedCloud } = useFeatures(); const currentPlan = useCurrentPlan(); useEffect(() => { @@ -308,17 +307,12 @@ export function SideMenu({ user, project, organization, organizations }: SideMen } /> - {currentPlan && - !currentPlan.v3Subscription?.isPaying && - currentPlan.v3Subscription.plan && - currentPlan.v3Usage && ( - - )} + {currentPlan?.v3Subscription?.isPaying === false && ( + + )} diff --git a/apps/webapp/app/components/primitives/PageHeader.tsx b/apps/webapp/app/components/primitives/PageHeader.tsx index 46861105b..82a8e4ee7 100644 --- a/apps/webapp/app/components/primitives/PageHeader.tsx +++ b/apps/webapp/app/components/primitives/PageHeader.tsx @@ -1,7 +1,6 @@ import { ArrowUpRightIcon } from "@heroicons/react/20/solid"; import { Link, useNavigation } from "@remix-run/react"; import { useOptionalOrganization } from "~/hooks/useOrganizations"; -import { useOptionalProject } from "~/hooks/useProject"; import { cn } from "~/utils/cn"; import { plansPath } from "~/utils/pathBuilder"; import { UpgradePrompt, useShowUpgradePrompt } from "../billing/v2/UpgradePrompt"; @@ -23,7 +22,6 @@ export function NavBar({ children }: WithChildren) { const showUpgradePrompt = useShowUpgradePrompt(organization); const navigation = useNavigation(); const isLoading = navigation.state === "loading" || navigation.state === "submitting"; - const project = useOptionalProject(); return (
@@ -31,13 +29,7 @@ export function NavBar({ children }: WithChildren) {
{children}
- {showUpgradePrompt.shouldShow && organization && ( - - )} + {showUpgradePrompt.shouldShow && organization && } ); } diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug/route.tsx index 8e4cad794..a22ea2a34 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug/route.tsx @@ -27,16 +27,9 @@ export function useCurrentPlan(matches?: UIMatch[]) { matches, }); - const result = data?.currentPlan - ? { - ...data.currentPlan, - v3Usage: data.usage, - } - : undefined; + console.log(data?.currentPlan); - console.log("useCurrentPlan", result); - - return result; + return data?.currentPlan; } export const loader = async ({ request, params }: LoaderFunctionArgs) => { @@ -66,18 +59,24 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { tomorrow.setDate(tomorrow.getDate() + 1); const usage = await getUsage(organization.id, { from: firstDayOfMonth, to: tomorrow }); + let hasExceededFreeTier = false; + let usagePercentage = 0; + if (plan?.v3Subscription && !plan.v3Subscription.isPaying && plan.v3Subscription.plan && usage) { + hasExceededFreeTier = usage.cents > plan.v3Subscription.plan.limits.includedUsage; + usagePercentage = usage.cents / plan.v3Subscription.plan.limits.includedUsage; + } + return typedjson({ organizations, organization, project, isImpersonating: !!impersonationId, - currentPlan: plan, - usage, + currentPlan: { ...plan, v3Usage: { ...usage, hasExceededFreeTier, usagePercentage } }, }); }; export default function Organization() { - const { organization, project, organizations, isImpersonating, usage } = + const { organization, project, organizations, isImpersonating } = useTypedLoaderData(); const user = useUser();