feat(billing): add trial eligibility logic and update billing overview

This commit is contained in:
Yusuf İpek
2026-04-11 12:53:02 +03:00
parent faa902a604
commit e18d5219f5
3 changed files with 21 additions and 1 deletions
@@ -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
</div>
) : (
<>
{!billing.subscription.hasActiveSubscription
&& !billing.subscription.hasActiveTrial
&& billing.subscription.isTrialEligible
&& billing.checkoutAvailable ? (
<div className="rounded-md border border-primary/30 bg-primary/5 p-4 space-y-2">
<p className="text-sm font-semibold">Start your 7-day free trial</p>
<p className="text-sm text-muted-foreground">
Get full access to all features no charge until the trial ends. Cancel anytime.
</p>
</div>
) : null}
<div className="flex items-center justify-between rounded-lg border p-4">
<div>
<p className="text-sm font-medium">Current plan</p>
@@ -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.'}
</p>
</div>
<Badge
@@ -420,6 +435,8 @@ export default function SettingsPage({ billingOnly = false }: { billingOnly?: bo
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
Redirecting...
</>
) : billing.subscription.isTrialEligible ? (
'Start Free Trial'
) : (
'Upgrade with Stripe'
)}
+1
View File
@@ -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,
+2
View File
@@ -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,