From 2ed7ba8808334d593dde684f4ac3235aeedfb2cd Mon Sep 17 00:00:00 2001 From: MaheshtheDev <38828053+MaheshtheDev@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:47:00 +0000 Subject: fix: past due pending users improvements (#572) --- apps/web/components/views/billing.tsx | 62 +++++++++++++++++++++++-------- apps/web/components/views/profile.tsx | 69 ++++++++++++++++++++++++++--------- packages/lib/queries.ts | 28 ++++++++++---- 3 files changed, 120 insertions(+), 39 deletions(-) diff --git a/apps/web/components/views/billing.tsx b/apps/web/components/views/billing.tsx index d6d85884..f3ef2605 100644 --- a/apps/web/components/views/billing.tsx +++ b/apps/web/components/views/billing.tsx @@ -7,7 +7,7 @@ import { import { Button } from "@ui/components/button" import { HeadingH3Bold } from "@ui/text/heading/heading-h3-bold" import { useCustomer } from "autumn-js/react" -import { CheckCircle, LoaderIcon, X } from "lucide-react" +import { AlertTriangle, CheckCircle, LoaderIcon, X } from "lucide-react" import { motion } from "motion/react" import Link from "next/link" import { useEffect, useState } from "react" @@ -24,11 +24,16 @@ export function BillingView() { const { data: status = { - consumer_pro: null, + consumer_pro: { allowed: false, status: null }, }, isLoading: isCheckingStatus, } = fetchSubscriptionStatus(autumn, !autumn.isLoading) + const proStatus = status.consumer_pro + const proProductStatus = proStatus?.status + const isPastDue = proProductStatus === "past_due" + const hasProProduct = proProductStatus !== null + const { data: memoriesCheck } = fetchMemoriesFeature( autumn, !autumn.isLoading && !isCheckingStatus, @@ -37,7 +42,10 @@ export function BillingView() { const memoriesUsed = memoriesCheck?.usage ?? 0 const memoriesLimit = memoriesCheck?.included_usage ?? 0 - const { data: connectionsCheck } = fetchConnectionsFeature(autumn, !autumn.isLoading && !isCheckingStatus) + const { data: connectionsCheck } = fetchConnectionsFeature( + autumn, + !autumn.isLoading && !isCheckingStatus, + ) const connectionsUsed = connectionsCheck?.usage ?? 0 @@ -66,8 +74,6 @@ export function BillingView() { }) } - const isPro = status.consumer_pro - if (user?.isAnonymous) { return ( Pro Plan - - Active - + {isPastDue ? ( + + Past Due + + ) : ( + + Active + + )}

- You're enjoying expanded memory capacity with supermemory Pro! + {isPastDue + ? "Your payment is past due. Please update your payment method to restore access." + : "You're enjoying expanded memory capacity with supermemory Pro!"}

+ {isPastDue && ( +
+ +
+

+ Payment Required +

+

+ Your payment method failed or payment is past due. Update your + payment information to restore access to all Pro features. +

+
+
+ )} + {/* Current Usage */}

Current Usage

Memories - - Unlimited - + Unlimited
@@ -132,8 +159,13 @@ export function BillingView() {
-
) diff --git a/apps/web/components/views/profile.tsx b/apps/web/components/views/profile.tsx index e4db2171..c60f4310 100644 --- a/apps/web/components/views/profile.tsx +++ b/apps/web/components/views/profile.tsx @@ -10,7 +10,14 @@ import { Button } from "@repo/ui/components/button" import { Skeleton } from "@repo/ui/components/skeleton" import { HeadingH3Bold } from "@repo/ui/text/heading/heading-h3-bold" import { useCustomer } from "autumn-js/react" -import { CheckCircle, CreditCard, LoaderIcon, User, X } from "lucide-react" +import { + AlertTriangle, + CheckCircle, + CreditCard, + LoaderIcon, + User, + X, +} from "lucide-react" import { motion } from "motion/react" import Link from "next/link" import { useState } from "react" @@ -23,12 +30,16 @@ export function ProfileView() { const { data: status = { - consumer_pro: null, + consumer_pro: { allowed: false, status: null }, }, isLoading: isCheckingStatus, } = fetchSubscriptionStatus(autumn, !autumn.isLoading) - const isPro = status.consumer_pro + const proStatus = status.consumer_pro + const isPro = proStatus?.allowed ?? false + const proProductStatus = proStatus?.status + const isPastDue = proProductStatus === "past_due" + const hasProProduct = proProductStatus !== null const { data: memoriesCheck } = fetchMemoriesFeature( autumn, @@ -176,24 +187,43 @@ export function ProfileView() {
- {isPro ? "Pro Plan" : "Free Plan"} - {isPro && ( + {hasProProduct ? "Pro Plan" : "Free Plan"} + {isPastDue ? ( + + Past Due + + ) : isPro ? ( Active - )} + ) : null}

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

+ {isPastDue && ( +
+ +
+

+ Payment Required +

+

+ Your payment is past due. Please update your payment method to + restore access to Pro features. +

+
+
+ )} + {/* Usage Stats */}
Memories - {isPro ? ( + {hasProProduct ? ( Unlimited ) : ( )}
- {!isPro && ( + {!hasProProduct && (
= memoriesLimit - ? "bg-red-500" - : isPro - ? "bg-green-500" - : "bg-blue-500" + memoriesUsed >= memoriesLimit ? "bg-red-500" : "bg-blue-500" }`} style={{ width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`, @@ -221,7 +247,7 @@ export function ProfileView() { )}
- {isPro && ( + {hasProProduct && (
Connections @@ -232,7 +258,16 @@ export function ProfileView() { {/* Billing Actions */}
- {isPro ? ( + {isPastDue ? ( + + ) : hasProProduct ? (