From 99fd62d5f10c835a746662cefb5a066b3883ed16 Mon Sep 17 00:00:00 2001 From: MaheshtheDev <38828053+MaheshtheDev@users.noreply.github.com> Date: Sun, 7 Sep 2025 16:54:58 +0000 Subject: [PATCH] fix: billing page (#416) --- apps/web/components/views/profile.tsx | 381 ++++++++++++++------------ 1 file changed, 208 insertions(+), 173 deletions(-) diff --git a/apps/web/components/views/profile.tsx b/apps/web/components/views/profile.tsx index b19706f78..dfe7e3a84 100644 --- a/apps/web/components/views/profile.tsx +++ b/apps/web/components/views/profile.tsx @@ -2,11 +2,6 @@ import { authClient } from "@lib/auth" import { useAuth } from "@lib/auth-context" -import { - fetchConnectionsFeature, - fetchMemoriesFeature, - fetchSubscriptionStatus, -} from "@lib/queries" import { Button } from "@repo/ui/components/button" import { HeadingH3Bold } from "@repo/ui/text/heading/heading-h3-bold" import { useCustomer } from "autumn-js/react" @@ -20,34 +15,57 @@ import { } from "lucide-react" import { motion } from "motion/react" import Link from "next/link" -import { usePathname, useRouter } from "next/navigation" -import { useState } from "react" +import { useRouter } from "next/navigation" +import { useEffect, useState } from "react" import { analytics } from "@/lib/analytics" export function ProfileView() { const router = useRouter() - const pathname = usePathname() - const { user: session, org } = useAuth() - const organizations = org - const autumn = useCustomer() + const { user: session } = useAuth() + const { + customer, + isLoading: isCustomerLoading, + openBillingPortal, + attach, + } = useCustomer() const [isLoading, setIsLoading] = useState(false) + const [billingData, setBillingData] = useState<{ + isPro: boolean + memoriesUsed: number + memoriesLimit: number + connectionsUsed: number + connectionsLimit: number + }>({ + isPro: false, + memoriesUsed: 0, + memoriesLimit: 0, + connectionsUsed: 0, + connectionsLimit: 0, + }) - const { data: memoriesCheck } = fetchMemoriesFeature(autumn as any) - const memoriesUsed = memoriesCheck?.usage ?? 0 - const memoriesLimit = memoriesCheck?.included_usage ?? 0 - - const { data: connectionsCheck } = fetchConnectionsFeature(autumn as any) - const connectionsUsed = connectionsCheck?.usage ?? 0 - - // Fetch subscription status with React Query - const { - data: status = { - consumer_pro: null, - }, - isLoading: isCheckingStatus, - } = fetchSubscriptionStatus(autumn as any) + useEffect(() => { + if (!isCustomerLoading) { + const memoriesFeature = customer?.features?.memories ?? { + usage: 0, + included_usage: 0, + } + const connectionsFeature = customer?.features?.connections ?? { + usage: 0, + included_usage: 0, + } - const isPro = status.consumer_pro + setBillingData({ + isPro: + customer?.products?.some( + (product) => product.id === "consumer_pro", + ) ?? false, + memoriesUsed: memoriesFeature?.usage ?? 0, + memoriesLimit: memoriesFeature?.included_usage ?? 0, + connectionsUsed: connectionsFeature?.usage ?? 0, + connectionsLimit: connectionsFeature?.included_usage ?? 0, + }) + } + }, [isCustomerLoading, customer]) const handleLogout = () => { analytics.userSignedOut() @@ -58,7 +76,7 @@ export function ProfileView() { const handleUpgrade = async () => { setIsLoading(true) try { - await autumn.attach({ + await attach({ productId: "consumer_pro", successUrl: "https://app.supermemory.ai/", }) @@ -71,7 +89,7 @@ export function ProfileView() { // Handle manage billing const handleManageBilling = async () => { - await autumn.openBillingPortal({ + await openBillingPortal({ returnUrl: "https://app.supermemory.ai", }) } @@ -117,160 +135,177 @@ export function ProfileView() { - {/* Billing Section */} -
-
-
- -
-
- - {isPro ? "Pro Plan" : "Free Plan"} - {isPro && ( - - Active - - )} - -

- {isPro ? "Expanded memory capacity" : "Basic plan"} -

-
+ {isCustomerLoading ? ( +
+ + Loading...
+ ) : ( + <> + {/* Billing Section */} +
+
+
+ +
+
+ + {billingData.isPro ? "Pro Plan" : "Free Plan"} + {billingData.isPro && ( + + Active + + )} + +

+ {billingData.isPro + ? "Expanded memory capacity" + : "Basic plan"} +

+
+
- {/* Usage Stats */} -
-
- Memories - = memoriesLimit ? "text-red-400" : "text-white/90"}`} - > - {memoriesUsed} / {memoriesLimit} - -
-
-
= memoriesLimit - ? "bg-red-500" - : isPro - ? "bg-green-500" - : "bg-blue-500" - }`} - style={{ - width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`, - }} - /> -
-
+ {/* Usage Stats */} +
+
+ Memories + = billingData.memoriesLimit ? "text-red-400" : "text-white/90"}`} + > + {billingData.memoriesUsed} / {billingData.memoriesLimit} + +
+
+
= billingData.memoriesLimit + ? "bg-red-500" + : billingData.isPro + ? "bg-green-500" + : "bg-blue-500" + }`} + style={{ + width: `${Math.min((billingData.memoriesUsed / billingData.memoriesLimit) * 100, 100)}%`, + }} + /> +
+
+ + {billingData.isPro && ( +
+ Connections + + {billingData.connectionsUsed} / 10 + +
+ )} - {isPro && ( -
- Connections - - {connectionsUsed} / 10 - + {/* Billing Actions */} +
+ {billingData.isPro ? ( + + + + ) : ( + + + + )} +
- )} - {/* Billing Actions */} -
- {isPro ? ( - - - - ) : ( - - - - )} -
-
+ {/* Plan Comparison - Only show for free users */} + {!billingData.isPro && ( +
+ + Upgrade to Pro + - {/* Plan Comparison - Only show for free users */} - {!isPro && ( -
- - Upgrade to Pro - +
+ {/* Free Plan */} +
+

+ Free Plan +

+
    +
  • + + 200 memories +
  • +
  • + + No connections +
  • +
  • + + Basic search +
  • +
+
-
- {/* Free Plan */} -
-

- Free Plan -

-
    -
  • - - 200 memories -
  • -
  • - - No connections -
  • -
  • - - Basic search -
  • -
-
+ {/* Pro Plan */} +
+

+ Pro Plan + + Recommended + +

+
    +
  • + + 5000 memories +
  • +
  • + + 10 connections +
  • +
  • + + Advanced search +
  • +
  • + + Priority support +
  • +
+
+
- {/* Pro Plan */} -
-

- Pro Plan - - Recommended - -

-
    -
  • - - 5000 memories -
  • -
  • - - 10 connections -
  • -
  • - - Advanced search -
  • -
  • - - Priority support -
  • -
+

+ $15/month (only for first 100 users) • Cancel anytime. No + questions asked. +

-
- -

- $15/month (only for first 100 users) • Cancel anytime. No questions - asked. -

-
+ )} + )}