From e18d5219f5a90557d52ac79189720af7831ea358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yusuf=20=C4=B0pek?= Date: Sat, 11 Apr 2026 12:53:02 +0300 Subject: [PATCH] feat(billing): add trial eligibility logic and update billing overview --- .../settings/settings-page-client.tsx | 19 ++++++++++++++++++- app/api/billing/route.ts | 1 + lib/billing.ts | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/(dashboard)/settings/settings-page-client.tsx b/app/(dashboard)/settings/settings-page-client.tsx index a407cef..27b9a12 100644 --- a/app/(dashboard)/settings/settings-page-client.tsx +++ b/app/(dashboard)/settings/settings-page-client.tsx @@ -44,6 +44,7 @@ interface BillingOverview { hasActiveSubscription: boolean; hasActiveTrial: boolean; hasBillingAccess: boolean; + isTrialEligible: boolean; priceId: string | null; currentPeriodEnd: string | null; cancelAtPeriodEnd: boolean; @@ -332,6 +333,18 @@ export default function SettingsPage({ billingOnly = false }: { billingOnly?: bo ) : ( <> + {!billing.subscription.hasActiveSubscription + && !billing.subscription.hasActiveTrial + && billing.subscription.isTrialEligible + && billing.checkoutAvailable ? ( +
+

Start your 7-day free trial

+

+ Get full access to all features — no charge until the trial ends. Cancel anytime. +

+
+ ) : null} +

Current plan

@@ -344,7 +357,9 @@ export default function SettingsPage({ billingOnly = false }: { billingOnly?: bo : 'Paid account with workspace creation unlocked.' : billing.subscription.hasActiveTrial ? 'Trial access is active.' - : 'Billing access has ended.'} + : billing.subscription.isTrialEligible + ? 'You haven\'t started your free trial yet.' + : 'Billing access has ended.'}

Redirecting... + ) : billing.subscription.isTrialEligible ? ( + 'Start Free Trial' ) : ( 'Upgrade with Stripe' )} diff --git a/app/api/billing/route.ts b/app/api/billing/route.ts index 63e03fc..76ea3a5 100644 --- a/app/api/billing/route.ts +++ b/app/api/billing/route.ts @@ -27,6 +27,7 @@ export async function GET() { hasActiveSubscription: billing.subscription.hasActiveSubscription, hasActiveTrial: billing.subscription.hasActiveTrial, hasBillingAccess: billing.subscription.hasBillingAccess, + isTrialEligible: billing.subscription.isTrialEligible, priceId: billing.subscription.stripePriceId, currentPeriodEnd: billing.subscription.currentPeriodEnd?.toISOString() ?? null, cancelAtPeriodEnd: billing.subscription.cancelAtPeriodEnd ?? false, diff --git a/lib/billing.ts b/lib/billing.ts index 608b83b..b8e28a1 100644 --- a/lib/billing.ts +++ b/lib/billing.ts @@ -180,6 +180,7 @@ export async function getWorkspaceCreationEligibility(userId: string) { select: { subscriptionStatus: true, trialEndsAt: true, + billingTrialConsumedAt: true, stripeCustomerId: true, stripeSubscriptionId: true, stripePriceId: true, @@ -251,6 +252,7 @@ export async function getWorkspaceCreationEligibility(userId: string) { hasActiveSubscription: hasActiveSubscription(user.subscriptionStatus), hasActiveTrial: hasActiveTrial(user.trialEndsAt), hasBillingAccess: billingAccess, + isTrialEligible: !user.billingTrialConsumedAt, stripeCustomerId: user.stripeCustomerId, stripeSubscriptionId: user.stripeSubscriptionId, stripePriceId: user.stripePriceId,