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();