- {hasPaidPlan ? (
- <>
-
-
-
- {planDisplayNames[currentPlan]} plan
-
-
- ACTIVE
-
-
-
- Expanded memory with connections and more
-
-
-
- {/* Plan usage (unified) */}
-
-
-
- Plan usage
-
-
- {planUsagePct < 1 && planUsagePct > 0
- ? "< 1"
- : Math.round(planUsagePct)}
- % used
-
-
-
-
80
- ? "#ef4444"
- : "linear-gradient(to right, #4BA0FA 80%, #002757 100%)",
- }}
- title={`$${formatUsd(usdSpent)} of $${formatUsd(usdIncluded)} used`}
- />
-
-
- {daysRemaining !== null
- ? `Resets in ${daysRemaining} day${daysRemaining !== 1 ? "s" : ""}`
- : ""}
-
-
-
-
-
- {cancellablePlanId && (
-
- )}
-
- >
- ) : (
- <>
-
-
- Free Plan
-
-
- You are on basic plan
-
-
-
- {/* Plan usage (unified) */}
-
-
-
- Plan usage
-
-
- {planUsagePct < 1 && planUsagePct > 0
- ? "< 1"
- : Math.round(planUsagePct)}
- % used
-
-
-
-
80 ? "#ef4444" : "#0054AD",
- }}
- title={`$${formatUsd(usdSpent)} of $${formatUsd(usdIncluded)} used`}
- />
-
-
- {daysRemaining !== null
- ? `Resets in ${daysRemaining} day${daysRemaining !== 1 ? "s" : ""}`
- : ""}
-
-
-
-
-
-
- >
- )}
-
-
-
-
-
- Delete Account
-
-
-
+
+
Team members
+ {(org?.members?.length ?? 0) > 0 && (
+
- Permanently delete all your data and cancel any active
- subscriptions
-
-
- {/* Modal inset highlight */}
-
-
-
-
+
+
+
+ {(name.charAt(0) || "U").toUpperCase()}
+
+
+
+
+
+ {name}
+
+ {isYou && (
+
+ You
+
+ )}
+
+ {m.user?.email && (
+
+ {m.user.email}
+
+ )}
+
+
+
+ )
+ })}
+
+ ) : (
+
+
+
+
+
+
+ Just you for now
+
+
+ Invite teammates from your organization settings.
+
+
+
+ )}
diff --git a/apps/web/components/settings/billing.tsx b/apps/web/components/settings/billing.tsx
new file mode 100644
index 00000000..aca23307
--- /dev/null
+++ b/apps/web/components/settings/billing.tsx
@@ -0,0 +1,579 @@
+"use client"
+
+import { dmSans125ClassName } from "@/lib/fonts"
+import { cn } from "@lib/utils"
+import { PLAN_DISPLAY_NAMES, useTokenUsage } from "@/hooks/use-token-usage"
+import {
+ Dialog,
+ DialogContent,
+ DialogTrigger,
+ DialogClose,
+} from "@ui/components/dialog"
+import { useCustomer } from "autumn-js/react"
+import { Check, X, LoaderIcon, Settings } from "lucide-react"
+import { useState } from "react"
+import { toast } from "sonner"
+
+function SectionTitle({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ )
+}
+
+function SettingsCard({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ )
+}
+
+function PlanComparisonCard({
+ name,
+ price,
+ period,
+ description,
+ credits,
+ features,
+ highlight,
+}: {
+ name: string
+ price: string
+ period: string
+ description: string
+ credits: string
+ features: string[]
+ highlight: boolean
+}) {
+ return (
+
+
+
+ {name}
+
+ {highlight && (
+
+ RECOMMENDED
+
+ )}
+
+
+
+
+ {price}
+
+ {period && (
+
+ {period}
+
+ )}
+
+
+
+ {description}
+
+
+
+
+
+ {credits}
+
+
+ of usage included
+
+
+
+
+
+ {features.map((text) => (
+ -
+
+ {text}
+
+ ))}
+
+
+ )
+}
+
+export default function Billing() {
+ const autumn = useCustomer()
+ const [isUpgrading, setIsUpgrading] = useState(false)
+ const [isCancelling, setIsCancelling] = useState(false)
+ const [isCancelDialogOpen, setIsCancelDialogOpen] = useState(false)
+
+ const {
+ usdIncluded,
+ usdSpent,
+ planUsagePct,
+ currentPlan,
+ hasPaidPlan,
+ isLoading: isCheckingStatus,
+ daysRemaining,
+ } = useTokenUsage(autumn)
+
+ const formatUsd = (n: number) =>
+ n.toLocaleString(undefined, {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ })
+
+ const planDisplayNames = PLAN_DISPLAY_NAMES
+
+ const handleUpgrade = async () => {
+ setIsUpgrading(true)
+ try {
+ const result = await autumn.attach({
+ planId: "api_pro",
+ successUrl: `${window.location.origin}/settings#billing`,
+ })
+ if (result?.paymentUrl) {
+ window.open(result.paymentUrl, "_self")
+ return
+ }
+ autumn.refetch?.()
+ } catch (error) {
+ console.error(error)
+ toast.error("Failed to start checkout. Please try again.")
+ } finally {
+ setIsUpgrading(false)
+ }
+ }
+
+ const cancellablePlanId =
+ currentPlan === "pro" || currentPlan === "scale"
+ ? (`api_${currentPlan}` as const)
+ : null
+
+ const handleCancelSubscription = async () => {
+ if (!cancellablePlanId) return
+ setIsCancelling(true)
+ try {
+ await autumn.updateSubscription({
+ planId: cancellablePlanId,
+ cancelAction: "cancel_end_of_cycle",
+ })
+ autumn.refetch?.()
+ setIsCancelDialogOpen(false)
+ toast.success(
+ `Subscription cancelled. ${planDisplayNames[currentPlan]} features remain active until the end of your billing period.`,
+ )
+ } catch (error) {
+ console.error(error)
+ toast.error("Failed to cancel subscription. Please try again.")
+ } finally {
+ setIsCancelling(false)
+ }
+ }
+
+ return (
+
+
+ Billing & Subscription
+
+
+ {hasPaidPlan ? (
+ <>
+
+
+
+ {planDisplayNames[currentPlan]} plan
+
+
+ ACTIVE
+
+
+
+ Expanded memory with connections and more
+
+
+
+
+
+
+ Plan usage
+
+
+ {planUsagePct < 1 && planUsagePct > 0
+ ? "< 1"
+ : Math.round(planUsagePct)}
+ % used
+
+
+
+
80
+ ? "#ef4444"
+ : "linear-gradient(to right, #4BA0FA 80%, #002757 100%)",
+ }}
+ title={`$${formatUsd(usdSpent)} of $${formatUsd(usdIncluded)} used`}
+ />
+
+
+ {daysRemaining !== null
+ ? `Resets in ${daysRemaining} day${daysRemaining !== 1 ? "s" : ""}`
+ : ""}
+
+
+
+
+
+ {cancellablePlanId && (
+
+ )}
+
+ >
+ ) : (
+ <>
+
+
+ Free Plan
+
+
+ You are on basic plan
+
+
+
+
+
+
+ Plan usage
+
+
+ {planUsagePct < 1 && planUsagePct > 0
+ ? "< 1"
+ : Math.round(planUsagePct)}
+ % used
+
+
+
+
80 ? "#ef4444" : "#0054AD",
+ }}
+ title={`$${formatUsd(usdSpent)} of $${formatUsd(usdIncluded)} used`}
+ />
+
+
+ {daysRemaining !== null
+ ? `Resets in ${daysRemaining} day${daysRemaining !== 1 ? "s" : ""}`
+ : ""}
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+ )
+}
diff --git a/apps/web/components/settings/connections-mcp.tsx b/apps/web/components/settings/connections-mcp.tsx
index 06603e9d..3f149753 100644
--- a/apps/web/components/settings/connections-mcp.tsx
+++ b/apps/web/components/settings/connections-mcp.tsx
@@ -559,7 +559,7 @@ export default function ConnectionsMCP() {
const isLoading = autumn.isLoading
return (
-
+
{/* Supermemory Connections Section */}
}>
diff --git a/apps/web/components/settings/integrations.tsx b/apps/web/components/settings/integrations.tsx
index de72ad16..125cec90 100644
--- a/apps/web/components/settings/integrations.tsx
+++ b/apps/web/components/settings/integrations.tsx
@@ -259,7 +259,7 @@ export default function Integrations() {
}
return (
-
+
Integrations
diff --git a/apps/web/components/settings/support.tsx b/apps/web/components/settings/support.tsx
index f5f7508d..921759ef 100644
--- a/apps/web/components/settings/support.tsx
+++ b/apps/web/components/settings/support.tsx
@@ -103,7 +103,7 @@ export default function Support() {
}
return (
-
+
{/* Support & Help Section */}