diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/confirm-create-bounty-modal.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/confirm-create-bounty-modal.tsx
index 3fed6e92ca6..2f29f5a000e 100644
--- a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/confirm-create-bounty-modal.tsx
+++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/confirm-create-bounty-modal.tsx
@@ -1,4 +1,5 @@
import { getBountyRewardDescription } from "@/lib/partners/get-bounty-reward-description";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import useGroups from "@/lib/swr/use-groups";
import { usePartnersCountByGroupIds } from "@/lib/swr/use-partners-count-by-groupids";
@@ -176,7 +177,11 @@ function ConfirmCreateBountyModal({
),
diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-upgrade-cta.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-upgrade-cta.tsx
index 23f183a2c7a..538668a6204 100644
--- a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-upgrade-cta.tsx
+++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners-upgrade-cta.tsx
@@ -1,5 +1,6 @@
"use client";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import useWorkspace from "@/lib/swr/use-workspace";
import { buttonVariants } from "@dub/ui";
@@ -22,7 +23,10 @@ export function PartnersUpgradeCTA({
if (!canManageProgram || isLegacyBusinessPlan({ plan, payoutsLimit })) {
return {
cta: "Upgrade plan",
- href: `/${slug}/upgrade`,
+ href: getBillingUpgradePathForFeature({
+ slug,
+ feature: "partners",
+ }),
};
} else {
return {
diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/analytics/conversion-tracking-toggle.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/analytics/conversion-tracking-toggle.tsx
index e9b8355aa7e..5f91d78afff 100644
--- a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/analytics/conversion-tracking-toggle.tsx
+++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/analytics/conversion-tracking-toggle.tsx
@@ -1,6 +1,7 @@
"use client";
import { clientAccessCheck } from "@/lib/client-access-check";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import useWorkspace from "@/lib/swr/use-workspace";
import {
@@ -84,7 +85,10 @@ export function ConversionTrackingToggle() {
) : (
permissionsError || (
diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx
index 130b6258d19..63a663ce611 100644
--- a/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx
+++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/settings/billing/plan-usage.tsx
@@ -1,6 +1,7 @@
"use client";
import { MEGA_WORKSPACE_LINKS_LIMIT } from "@/lib/constants/misc";
+import { getBillingUpgradePath, getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import useGroupsCount from "@/lib/swr/use-groups-count";
import usePartnersCount from "@/lib/swr/use-partners-count";
import useTagsCount from "@/lib/swr/use-tags-count";
@@ -32,6 +33,7 @@ import {
capitalize,
cn,
getFirstAndLastDay,
+ getNextPlan,
INFINITY_NUMBER,
isLegacyBusinessPlan,
nFormatter,
@@ -66,6 +68,7 @@ export default function PlanUsage() {
usersLimit,
billingCycleStart,
} = useWorkspace();
+ const nextPlan = getNextPlan(plan);
const { data: tags } = useTagsCount();
const { users } = useWorkspaceUsers();
@@ -174,7 +177,16 @@ export default function PlanUsage() {
{plan !== "enterprise" && (
-
+
);
diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/links/page-client.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/links/page-client.tsx
index 11f233a9256..74e9a1a206e 100644
--- a/apps/web/app/app.dub.co/(dashboard)/[slug]/links/page-client.tsx
+++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/links/page-client.tsx
@@ -7,6 +7,7 @@ import {
} from "@/lib/swr/use-folder-permissions";
import useLinks from "@/lib/swr/use-links";
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import { useWorkspaceStore } from "@/lib/swr/use-workspace-store";
import { FolderDropdown } from "@/ui/folders/folder-dropdown";
import {
@@ -412,7 +413,14 @@ function ImportOption({
}
>
diff --git a/apps/web/lib/billing/upgrade-url.ts b/apps/web/lib/billing/upgrade-url.ts
new file mode 100644
index 00000000000..9b77408c543
--- /dev/null
+++ b/apps/web/lib/billing/upgrade-url.ts
@@ -0,0 +1,66 @@
+type UpgradeRecommendation = {
+ plan: string;
+ planTier?: number;
+};
+
+const FEATURE_RECOMMENDATIONS: Record = {
+ pro: {
+ plan: "pro",
+ },
+ business: {
+ plan: "business",
+ },
+ advanced: {
+ plan: "advanced",
+ },
+ partners: {
+ plan: "advanced",
+ planTier: 2,
+ },
+};
+
+export function getBillingUpgradePath({
+ slug,
+ recommendation,
+ showPartnersUpgradeModal,
+}: {
+ slug?: string;
+ recommendation?: UpgradeRecommendation;
+ showPartnersUpgradeModal?: boolean;
+}) {
+ if (!slug) {
+ return "https://dub.co/pricing";
+ }
+
+ const queryParams = new URLSearchParams();
+
+ if (recommendation) {
+ queryParams.set("plan", recommendation.plan);
+ if (recommendation.planTier && recommendation.planTier > 1) {
+ queryParams.set("planTier", recommendation.planTier.toString());
+ }
+ }
+
+ if (showPartnersUpgradeModal) {
+ queryParams.set("showPartnersUpgradeModal", "true");
+ }
+
+ const query = queryParams.toString();
+ return `/${slug}/settings/billing/upgrade${query ? `?${query}` : ""}`;
+}
+
+export function getBillingUpgradePathForFeature({
+ slug,
+ feature,
+ showPartnersUpgradeModal,
+}: {
+ slug?: string;
+ feature: keyof typeof FEATURE_RECOMMENDATIONS;
+ showPartnersUpgradeModal?: boolean;
+}) {
+ return getBillingUpgradePath({
+ slug,
+ recommendation: FEATURE_RECOMMENDATIONS[feature],
+ showPartnersUpgradeModal,
+ });
+}
diff --git a/apps/web/lib/integrations/segment/ui/set-write-key.tsx b/apps/web/lib/integrations/segment/ui/set-write-key.tsx
index bfd22d07e60..1c2b2d65abd 100644
--- a/apps/web/lib/integrations/segment/ui/set-write-key.tsx
+++ b/apps/web/lib/integrations/segment/ui/set-write-key.tsx
@@ -1,6 +1,7 @@
"use client";
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { SegmentIntegrationCredentials } from "@/lib/types";
import { Lock } from "@/ui/shared/icons";
import { Button, Tooltip, TooltipContent } from "@dub/ui";
@@ -50,7 +51,10 @@ export function SetWriteKey({
);
diff --git a/apps/web/ui/analytics/analytics-loading-spinner.tsx b/apps/web/ui/analytics/analytics-loading-spinner.tsx
index 6bc0f9107a5..117321e08b1 100644
--- a/apps/web/ui/analytics/analytics-loading-spinner.tsx
+++ b/apps/web/ui/analytics/analytics-loading-spinner.tsx
@@ -1,4 +1,5 @@
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import { LoadingSpinner } from "@dub/ui";
import { Lock } from "lucide-react";
import Link from "next/link";
@@ -18,7 +19,12 @@ export function AnalyticsLoadingSpinner() {
{nextPlan.name} plan required to view more analytics
diff --git a/apps/web/ui/analytics/chart-section.tsx b/apps/web/ui/analytics/chart-section.tsx
index b145cb07058..e32aeaf7328 100644
--- a/apps/web/ui/analytics/chart-section.tsx
+++ b/apps/web/ui/analytics/chart-section.tsx
@@ -1,5 +1,6 @@
import { EventType } from "@/lib/analytics/types";
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import {
BlurImage,
buttonVariants,
@@ -182,7 +183,10 @@ function ConversionTrackingPaywall() {
)
}
diff --git a/apps/web/ui/analytics/events/index.tsx b/apps/web/ui/analytics/events/index.tsx
index c078af30350..1e10ab52c94 100644
--- a/apps/web/ui/analytics/events/index.tsx
+++ b/apps/web/ui/analytics/events/index.tsx
@@ -1,6 +1,7 @@
"use client";
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import EmptyState from "@/ui/shared/empty-state";
import { Menu3 } from "@dub/ui/icons";
import { cn } from "@dub/utils";
@@ -59,7 +60,10 @@ function EventsTableContainer() {
description={`Want more data on your link ${selectedTab === "clicks" ? "clicks & QR code scans" : selectedTab}? Upgrade to our Business Plan to get a detailed, real-time stream of events in your workspace.`}
learnMore="https://d.to/events"
buttonText="Upgrade to Business"
- buttonLink={`/${slug}/upgrade`}
+ buttonLink={getBillingUpgradePathForFeature({
+ slug,
+ feature: "business",
+ })}
/>
}
/>
diff --git a/apps/web/ui/analytics/toggle.tsx b/apps/web/ui/analytics/toggle.tsx
index d4a65f18519..6ef6d21ec50 100644
--- a/apps/web/ui/analytics/toggle.tsx
+++ b/apps/web/ui/analytics/toggle.tsx
@@ -5,6 +5,7 @@ import {
import { validDateRangeForPlan } from "@/lib/analytics/utils";
import { getStartEndDates } from "@/lib/analytics/utils/get-start-end-dates";
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import {
BlurImage,
Button,
@@ -322,7 +323,12 @@ function UpgradeTooltip({
);
}
diff --git a/apps/web/ui/customers/customers-table/customers-table.tsx b/apps/web/ui/customers/customers-table/customers-table.tsx
index b45270ae335..7f312c88ff1 100644
--- a/apps/web/ui/customers/customers-table/customers-table.tsx
+++ b/apps/web/ui/customers/customers-table/customers-table.tsx
@@ -1,6 +1,7 @@
"use client";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import useCustomersCount from "@/lib/swr/use-customers-count";
import useWorkspace from "@/lib/swr/use-workspace";
import { CustomerProps } from "@/lib/types";
@@ -482,7 +483,10 @@ export function CustomersTable({
window.open(`/${slug}/upgrade`)}
+ onClick={() =>
+ window.open(
+ getBillingUpgradePathForFeature({
+ slug,
+ feature: "pro",
+ }),
+ )
+ }
/>
);
}
diff --git a/apps/web/ui/folders/add-folder-form.tsx b/apps/web/ui/folders/add-folder-form.tsx
index ac392a3e459..77eef923e09 100644
--- a/apps/web/ui/folders/add-folder-form.tsx
+++ b/apps/web/ui/folders/add-folder-form.tsx
@@ -1,4 +1,5 @@
import { FOLDER_WORKSPACE_ACCESS } from "@/lib/folder/constants";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import useWorkspace from "@/lib/swr/use-workspace";
import { FolderAccessLevel, FolderSummary } from "@/lib/types";
@@ -173,7 +174,10 @@ export const AddFolderForm = ({ onSuccess, onCancel }: AddFolderFormProps) => {
}
diff --git a/apps/web/ui/folders/edit-folder-sheet.tsx b/apps/web/ui/folders/edit-folder-sheet.tsx
index 761d9b5de62..d2bc76d8973 100644
--- a/apps/web/ui/folders/edit-folder-sheet.tsx
+++ b/apps/web/ui/folders/edit-folder-sheet.tsx
@@ -3,6 +3,7 @@ import {
FOLDER_USER_ROLE,
FOLDER_WORKSPACE_ACCESS,
} from "@/lib/folder/constants";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import {
useCheckFolderPermission,
@@ -164,7 +165,10 @@ const EditFolderSheetContent = ({
}
@@ -192,7 +196,10 @@ const EditFolderSheetContent = ({
>
}
className="border-none"
- learnMoreHref={`/${slug}/upgrade`}
+ learnMoreHref={getBillingUpgradePathForFeature({
+ slug,
+ feature: "business",
+ })}
learnMoreText="Upgrade to Business"
/>
) : (
diff --git a/apps/web/ui/folders/folder-dropdown.tsx b/apps/web/ui/folders/folder-dropdown.tsx
index 8455c418e1b..7aef2c56ee9 100644
--- a/apps/web/ui/folders/folder-dropdown.tsx
+++ b/apps/web/ui/folders/folder-dropdown.tsx
@@ -1,6 +1,7 @@
"use client";
import { unsortedLinks } from "@/lib/folder/constants";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import useCurrentFolderId from "@/lib/swr/use-current-folder-id";
import useFolder from "@/lib/swr/use-folder";
@@ -158,7 +159,10 @@ export const FolderDropdown = ({
) : undefined,
},
@@ -269,7 +273,10 @@ export const FolderDropdown = ({
) : undefined
}
diff --git a/apps/web/ui/layout/sidebar/sidebar-usage.tsx b/apps/web/ui/layout/sidebar/sidebar-usage.tsx
index c6d2a252fbc..1fc44c062e4 100644
--- a/apps/web/ui/layout/sidebar/sidebar-usage.tsx
+++ b/apps/web/ui/layout/sidebar/sidebar-usage.tsx
@@ -1,6 +1,7 @@
"use client";
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import ManageSubscriptionButton from "@/ui/workspaces/manage-subscription-button";
import { AnimatedSizeContainer, buttonVariants, Icon } from "@dub/ui";
import { CursorRays, Hyperlink } from "@dub/ui/icons";
@@ -136,7 +137,14 @@ function UsageInner() {
/>
) : (warning || plan === "free") && plan !== "enterprise" ? (
{needsUpgrade ? (
{
)
diff --git a/apps/web/ui/links/link-builder/link-preview.tsx b/apps/web/ui/links/link-builder/link-preview.tsx
index 1adbc5cfca8..ce6c8ac5ee8 100644
--- a/apps/web/ui/links/link-builder/link-preview.tsx
+++ b/apps/web/ui/links/link-builder/link-preview.tsx
@@ -1,4 +1,5 @@
import useWorkspace from "@/lib/swr/use-workspace";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import {
LinkFormData,
useLinkBuilderContext,
@@ -120,7 +121,10 @@ export const LinkPreview = memo(() => {
) : undefined
diff --git a/apps/web/ui/links/links-toolbar.tsx b/apps/web/ui/links/links-toolbar.tsx
index 58ea0fd033d..b081658d611 100644
--- a/apps/web/ui/links/links-toolbar.tsx
+++ b/apps/web/ui/links/links-toolbar.tsx
@@ -1,4 +1,5 @@
import { getPlanCapabilities } from "@/lib/plan-capabilities";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { useFolderPermissions } from "@/lib/swr/use-folder-permissions";
import useWorkspace from "@/lib/swr/use-workspace";
import {
@@ -123,7 +124,10 @@ export const LinksToolbar = memo(
) : undefined,
keyboardShortcut: "m",
@@ -136,7 +140,10 @@ export const LinksToolbar = memo(
),
diff --git a/apps/web/ui/links/short-link-input.tsx b/apps/web/ui/links/short-link-input.tsx
index 290dfa2ef43..0de863a112e 100644
--- a/apps/web/ui/links/short-link-input.tsx
+++ b/apps/web/ui/links/short-link-input.tsx
@@ -1,5 +1,6 @@
"use client";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import useWorkspace from "@/lib/swr/use-workspace";
import { LinkProps } from "@/lib/types";
import { DOMAINS_MAX_PAGE_SIZE } from "@/lib/zod/schemas/domains";
@@ -365,7 +366,12 @@ export const ShortLinkInput = forwardRef
(
{error.split(`Upgrade to ${nextPlan.name}`)[0]}
Upgrade to {nextPlan.name}
diff --git a/apps/web/ui/modals/add-edit-domain-modal.tsx b/apps/web/ui/modals/add-edit-domain-modal.tsx
index aaa59d92f31..2f7d2da115c 100644
--- a/apps/web/ui/modals/add-edit-domain-modal.tsx
+++ b/apps/web/ui/modals/add-edit-domain-modal.tsx
@@ -1,9 +1,10 @@
import { clientAccessCheck } from "@/lib/client-access-check";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import useWorkspace from "@/lib/swr/use-workspace";
import { DomainProps } from "@/lib/types";
import { AddEditDomainForm } from "@/ui/domains/add-edit-domain-form";
import { Button, ButtonProps, Modal, TooltipContent } from "@dub/ui";
-import { capitalize, pluralize } from "@dub/utils";
+import { capitalize, getNextPlan, pluralize } from "@dub/utils";
import {
Dispatch,
SetStateAction,
@@ -54,6 +55,7 @@ function AddDomainButton({
buttonProps?: Partial;
}) {
const { slug, plan, role, domainsLimit, exceededDomains } = useWorkspace();
+ const nextPlan = getNextPlan(plan);
const permissionsError = clientAccessCheck({
action: "domains.write",
@@ -69,7 +71,14 @@ function AddDomainButton({
) : (
permissionsError || undefined
diff --git a/apps/web/ui/modals/add-edit-tag-modal.tsx b/apps/web/ui/modals/add-edit-tag-modal.tsx
index 42234ecbd15..f62d1c1d7ed 100644
--- a/apps/web/ui/modals/add-edit-tag-modal.tsx
+++ b/apps/web/ui/modals/add-edit-tag-modal.tsx
@@ -1,4 +1,5 @@
import { clientAccessCheck } from "@/lib/client-access-check";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import { mutatePrefix } from "@/lib/swr/mutate";
import useTags from "@/lib/swr/use-tags";
import useWorkspace from "@/lib/swr/use-workspace";
@@ -16,7 +17,7 @@ import {
useKeyboardShortcut,
useMediaQuery,
} from "@dub/ui";
-import { capitalize, cn, pluralize } from "@dub/utils";
+import { capitalize, cn, getNextPlan, pluralize } from "@dub/utils";
import {
Dispatch,
FormEvent,
@@ -207,6 +208,7 @@ function AddTagButton({
setShowAddEditTagModal: Dispatch>;
}) {
const { slug, plan, tagsLimit, role } = useWorkspace();
+ const nextPlan = getNextPlan(plan);
const { tags } = useTags();
const exceededTags = tags && tagsLimit && tags.length >= tagsLimit;
@@ -231,7 +233,14 @@ function AddTagButton({
) : (
permissionsError || undefined
diff --git a/apps/web/ui/modals/add-folder-modal.tsx b/apps/web/ui/modals/add-folder-modal.tsx
index 8a6913efe0f..431d0d8a250 100644
--- a/apps/web/ui/modals/add-folder-modal.tsx
+++ b/apps/web/ui/modals/add-folder-modal.tsx
@@ -1,4 +1,5 @@
import { clientAccessCheck } from "@/lib/client-access-check";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import useWorkspace from "@/lib/swr/use-workspace";
import { FolderSummary } from "@/lib/types";
import { Button, Modal, TooltipContent, useKeyboardShortcut } from "@dub/ui";
@@ -62,7 +63,10 @@ function AddFolderButton({
) : (
permissionsError || undefined
diff --git a/apps/web/ui/modals/link-builder/index.tsx b/apps/web/ui/modals/link-builder/index.tsx
index 923fb436e06..4a5f37b4312 100644
--- a/apps/web/ui/modals/link-builder/index.tsx
+++ b/apps/web/ui/modals/link-builder/index.tsx
@@ -1,6 +1,7 @@
"use client";
import { clientAccessCheck } from "@/lib/client-access-check";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import useWorkspace from "@/lib/swr/use-workspace";
import { ExpandedLinkProps } from "@/lib/types";
import { LinkBuilderDestinationUrlInput } from "@/ui/links/link-builder/controls/link-builder-destination-url-input";
@@ -263,7 +264,7 @@ export function CreateLinkButton({
}: {
setShowLinkBuilder: Dispatch>;
} & CreateLinkButtonProps) {
- const { slug, role, exceededLinks } = useWorkspace();
+ const { slug, role, exceededLinks, nextPlan } = useWorkspace();
const permissionsError = clientAccessCheck({
action: "links.write",
@@ -312,7 +313,14 @@ export function CreateLinkButton({
) : (
permissionsError || undefined
diff --git a/apps/web/ui/modals/link-qr-modal.tsx b/apps/web/ui/modals/link-qr-modal.tsx
index b898c636bab..8b058db791a 100644
--- a/apps/web/ui/modals/link-qr-modal.tsx
+++ b/apps/web/ui/modals/link-qr-modal.tsx
@@ -1,4 +1,5 @@
import { getQRAsCanvas, getQRAsSVGDataUri, getQRData } from "@/lib/qr";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import useDomain from "@/lib/swr/use-domain";
import useWorkspace from "@/lib/swr/use-workspace";
import { QRLinkProps } from "@/lib/types";
@@ -256,7 +257,10 @@ function LinkQRModalInner({
) : undefined
diff --git a/apps/web/ui/modals/manage-usage-modal.tsx b/apps/web/ui/modals/manage-usage-modal.tsx
index 52b6793ef07..a03dfdbaab3 100644
--- a/apps/web/ui/modals/manage-usage-modal.tsx
+++ b/apps/web/ui/modals/manage-usage-modal.tsx
@@ -1,4 +1,5 @@
import { clientAccessCheck } from "@/lib/client-access-check";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import useWorkspace from "@/lib/swr/use-workspace";
import { CursorRays, Hyperlink, Modal, Slider, ToggleGroup } from "@dub/ui";
import {
@@ -242,7 +243,13 @@ function ManageUsageModalContent({ type }: ManageUsageModalProps) {
1 ? suggestedPlanTier : undefined,
+ },
+ })}
className="text-content-subtle hover:text-content-default block text-xs font-medium underline underline-offset-2"
>
View all plans
diff --git a/apps/web/ui/partners/confirm-payouts-sheet.tsx b/apps/web/ui/partners/confirm-payouts-sheet.tsx
index 194c759c38a..7cf50b3137b 100644
--- a/apps/web/ui/partners/confirm-payouts-sheet.tsx
+++ b/apps/web/ui/partners/confirm-payouts-sheet.tsx
@@ -8,6 +8,7 @@ import {
INVOICE_MIN_PAYOUT_AMOUNT_CENTS,
} from "@/lib/constants/payouts";
import { exceededLimitError } from "@/lib/exceeded-limit-error";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { calculatePayoutFeeWithWaiver } from "@/lib/partners/calculate-payout-fee-with-waiver";
import {
CUTOFF_PERIOD,
@@ -806,7 +807,10 @@ function ConfirmPayoutsSheetContent() {
type: "payouts",
})}
cta="Upgrade"
- href={`/${slug}/settings/billing/upgrade`}
+ href={getBillingUpgradePathForFeature({
+ slug,
+ feature: "partners",
+ })}
/>
) : amount && amount < INVOICE_MIN_PAYOUT_AMOUNT_CENTS ? (
"Your payout total is less than the minimum invoice amount of $10."
diff --git a/apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx b/apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx
index 25fb525d84c..f95a0d5a5f5 100644
--- a/apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx
+++ b/apps/web/ui/partners/rewards/add-edit-reward-sheet.tsx
@@ -5,6 +5,7 @@ import { createRewardAction } from "@/lib/actions/partners/create-reward";
import { deleteRewardAction } from "@/lib/actions/partners/delete-reward";
import { updateRewardAction } from "@/lib/actions/partners/update-reward";
import { constructRewardAmount } from "@/lib/api/sales/construct-reward-amount";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import { handleMoneyInputChange, handleMoneyKeyDown } from "@/lib/form-utils";
import { getPlanCapabilities } from "@/lib/plan-capabilities";
import useGroup from "@/lib/swr/use-group";
@@ -604,7 +605,11 @@ function RewardSheetContent({
) : undefined
diff --git a/apps/web/ui/shared/upgrade-required-toast.tsx b/apps/web/ui/shared/upgrade-required-toast.tsx
index 21cb85230e4..79c7794932a 100644
--- a/apps/web/ui/shared/upgrade-required-toast.tsx
+++ b/apps/web/ui/shared/upgrade-required-toast.tsx
@@ -1,5 +1,6 @@
"use client";
+import { getBillingUpgradePath } from "@/lib/billing/upgrade-url";
import useWorkspace from "@/lib/swr/use-workspace";
import { capitalize } from "@dub/utils";
import { Crown } from "lucide-react";
@@ -26,7 +27,14 @@ export const UpgradeRequiredToast = ({
? `Upgrade to ${capitalize(planToUpgradeTo)}`
: "Contact support";
- const defaultCtaUrl = slug ? `/${slug}/upgrade` : "https://dub.co/pricing";
+ const defaultCtaUrl = getBillingUpgradePath({
+ slug,
+ recommendation: planToUpgradeTo
+ ? {
+ plan: planToUpgradeTo.toLowerCase(),
+ }
+ : undefined,
+ });
return (
diff --git a/apps/web/ui/workspaces/create-workspace-button.tsx b/apps/web/ui/workspaces/create-workspace-button.tsx
index 989698c931c..44195797e18 100644
--- a/apps/web/ui/workspaces/create-workspace-button.tsx
+++ b/apps/web/ui/workspaces/create-workspace-button.tsx
@@ -1,5 +1,6 @@
"use client";
+import { getBillingUpgradePathForFeature } from "@/lib/billing/upgrade-url";
import useWorkspaces from "@/lib/swr/use-workspaces";
import { ModalContext } from "@/ui/modals/modal-provider";
import { Button, TooltipContent } from "@dub/ui";
@@ -21,7 +22,10 @@ export default function CreateWorkspaceButton() {
cta="Upgrade to Pro"
href={
freeWorkspaces
- ? `/${freeWorkspaces[0].slug}/upgrade`
+ ? getBillingUpgradePathForFeature({
+ slug: freeWorkspaces[0].slug,
+ feature: "pro",
+ })
: "https://dub.co/pricing"
}
/>