diff --git a/apps/web/components/header.tsx b/apps/web/components/header.tsx
index bee5d90f..14853f71 100644
--- a/apps/web/components/header.tsx
+++ b/apps/web/components/header.tsx
@@ -15,7 +15,6 @@ import {
LifeBuoy,
LayoutGrid,
ChevronRight,
- Zap,
} from "lucide-react"
import { Button } from "@ui/components/button"
import { cn } from "@lib/utils"
@@ -360,7 +359,7 @@ export function Header({ onAddMemory, onOpenSearch }: HeaderProps) {
className="gap-2.5 rounded-lg px-2.5 py-2 text-sm font-medium text-white/85 hover:bg-white/[0.06] focus:bg-white/[0.06] focus:text-white cursor-pointer"
>
-
+
Upgrade
@@ -445,7 +444,7 @@ export function Header({ onAddMemory, onOpenSearch }: HeaderProps) {
)}
>
-
+
Upgrade
diff --git a/apps/web/components/settings/billing.tsx b/apps/web/components/settings/billing.tsx
index 4836ee03..5961b81a 100644
--- a/apps/web/components/settings/billing.tsx
+++ b/apps/web/components/settings/billing.tsx
@@ -15,6 +15,7 @@ import { useCustomer } from "autumn-js/react"
import {
Check,
Coins,
+ ArrowRight,
ExternalLink,
LoaderIcon,
Plus,
@@ -65,13 +66,17 @@ type AutoTopupsResponse =
| { ok: false; reason: string; message?: string }
type PlanCardDefinition = {
- id: "free" | "pro"
+ id: "free" | "pro" | "scale" | "enterprise"
name: string
price: string
period: string
credits: string
+ productId: "api_free" | "api_pro" | "api_scale" | "api_enterprise"
description: string
+ includesFrom?: string
features: string[]
+ highlight?: boolean
+ isContactSales?: boolean
}
const PLAN_CARDS: PlanCardDefinition[] = [
@@ -81,6 +86,7 @@ const PLAN_CARDS: PlanCardDefinition[] = [
price: "$0",
period: "",
credits: "$5",
+ productId: "api_free",
description: "Try supermemory with no commitment",
features: [
"Pay-as-you-go after $5 runs out",
@@ -94,6 +100,7 @@ const PLAN_CARDS: PlanCardDefinition[] = [
price: "$19",
period: "/mo",
credits: "$20",
+ productId: "api_pro",
description: "For people building with AI memory",
features: [
"Auto top-up when balance runs low",
@@ -103,6 +110,48 @@ const PLAN_CARDS: PlanCardDefinition[] = [
},
]
+const ADVANCED_PLAN_CARDS: PlanCardDefinition[] = [
+ {
+ id: "scale",
+ name: "Scale",
+ price: "$399",
+ period: "/mo",
+ credits: "$600",
+ productId: "api_scale",
+ description: "For teams and production workloads",
+ includesFrom: "Pro",
+ features: [
+ "Auto top-up & spend caps",
+ "Gmail, S3 & Web Crawler connectors",
+ "Dedicated support",
+ ],
+ highlight: true,
+ },
+ {
+ id: "enterprise",
+ name: "Enterprise",
+ price: "Custom",
+ period: "",
+ credits: "Unlimited",
+ productId: "api_enterprise",
+ description: "Custom deployments with dedicated engineering",
+ includesFrom: "Scale",
+ features: [
+ "Custom metering & billing",
+ "Custom integrations & SSO",
+ "Forward-deployed engineer",
+ ],
+ isContactSales: true,
+ },
+]
+
+const PLAN_RANK: Record = {
+ free: 0,
+ pro: 1,
+ scale: 2,
+ enterprise: 3,
+}
+
function SectionTitle({
children,
aside,
@@ -157,10 +206,24 @@ function PlanCard({
className={cn(
"relative flex min-h-[416px] flex-col overflow-hidden rounded-[14px] border p-5",
"shadow-[inset_2.42px_2.42px_4.263px_rgba(11,15,21,0.7)]",
- "border-white/[0.08] bg-[#14161A]",
+ plan.highlight
+ ? "border-[#0B65C9] bg-[#14161A] shadow-[inset_2.42px_2.42px_4.263px_rgba(11,15,21,0.7),0_0_0_1px_rgba(11,101,201,0.72)]"
+ : "border-white/[0.08] bg-[#14161A]",
)}
>
-
+ {plan.highlight ? (
+
+
+ Most popular
+
+
+ ) : null}
+
{plan.name}
@@ -187,25 +250,68 @@ function PlanCard({
{plan.description}
-
-
-
-
- {plan.credits}
-
-
- of usage included
-
+ {plan.isContactSales ? null : (
+
+
+
+
+ {plan.credits}
+
+
+ of usage included
+
+
-
+ )}
-
+ {plan.includesFrom ? (
+
+
+
+ Everything in {plan.includesFrom}, plus
+
+
+
+ ) : null}
+
+
{plan.features.map((feature) => (
-
-
+
{feature}
))}
@@ -349,6 +455,7 @@ export default function Billing() {
const [isCancelling, setIsCancelling] = useState(false)
const [isCancelDialogOpen, setIsCancelDialogOpen] = useState(false)
const [isCreditsDialogOpen, setIsCreditsDialogOpen] = useState(false)
+ const [showOtherPlans, setShowOtherPlans] = useState(false)
const [topUpAmount, setTopUpAmount] = useState(25)
const [customTopUpAmount, setCustomTopUpAmount] = useState("")
const [topUpPendingAmount, setTopUpPendingAmount] = useState(
@@ -446,11 +553,11 @@ export default function Billing() {
const planDisplayNames = PLAN_DISPLAY_NAMES
- const handleUpgrade = async () => {
+ const handleUpgrade = async (planId: "api_pro" | "api_scale") => {
setIsUpgrading(true)
try {
const result = await autumn.attach({
- planId: "api_pro",
+ planId,
successUrl: `${window.location.origin}/settings#billing`,
})
if ((result as { paymentUrl?: string })?.paymentUrl) {
@@ -604,6 +711,10 @@ export default function Billing() {
}
const getPlanCardAction = (plan: PlanCardDefinition) => {
+ const disabled = isUpgrading || isCheckingStatus || autumn.isLoading
+ const isCurrentPlan = plan.id === currentPlan
+ const isIncludedPlan = PLAN_RANK[currentPlan] > PLAN_RANK[plan.id]
+
if (plan.id === "free") {
return (
+ {showOtherPlans ? (
+
+ {ADVANCED_PLAN_CARDS.map((plan) => (
+
+ ))}
+
+ ) : (
+
+
setShowOtherPlans(true)}
+ className={cn(
+ dmSans125ClassName(),
+ "inline-flex h-9 items-center justify-center gap-2 rounded-full border border-white/[0.08] bg-white/[0.02] px-4 text-[13px] font-semibold text-[#A3A3A3] transition-colors hover:border-[#0B65C9]/60 hover:bg-[#061B38] hover:text-[#FAFAFA]",
+ )}
+ >
+ See other plans
+
+
+
+ )}