From c33e295ce7b6d18bf8067f6c73d44fec445c8077 Mon Sep 17 00:00:00 2001 From: Owen Date: Sun, 3 May 2026 14:42:43 -0700 Subject: [PATCH] Add a banner showing that you are on a trial --- messages/en-US.json | 3 ++ .../settings/(private)/billing/page.tsx | 15 ++++++++ src/components/DismissableBanner.tsx | 22 ++++++----- src/components/TrialBillingBanner.tsx | 38 +++++++++++++++++++ 4 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 src/components/TrialBillingBanner.tsx diff --git a/messages/en-US.json b/messages/en-US.json index a7b045480..09a2dc180 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -25,6 +25,9 @@ "subscriptionViolationMessage": "You're beyond your limits for your current plan. Correct the problem by removing sites, users, or other resources to stay within your plan.", "trialBannerMessage": "Your trial expires in {countdown}. Upgrade to keep access.", "trialBannerExpired": "Your trial has expired. Upgrade now to restore access.", + "billingTrialBannerTitle": "Free Trial Active", + "billingTrialBannerDescription": "You're currently on a free trial on the business tier. When the trial ends, your account will automatically revert to the Basic tier features and limits. Upgrade anytime to keep access to your current plan's features.", + "billingTrialBannerUpgrade": "Upgrade Now", "trialActive": "Free Trial Active", "trialExpired": "Trial Expired", "trialHasEnded": "Your trial has ended.", diff --git a/src/app/[orgId]/settings/(private)/billing/page.tsx b/src/app/[orgId]/settings/(private)/billing/page.tsx index 778062e8e..068f6ed62 100644 --- a/src/app/[orgId]/settings/(private)/billing/page.tsx +++ b/src/app/[orgId]/settings/(private)/billing/page.tsx @@ -55,6 +55,7 @@ import { tier3LimitSet } from "@server/lib/billing/limitSet"; import { FeatureId } from "@server/lib/billing/features"; +import TrialBillingBanner from "@app/components/TrialBillingBanner"; // Plan tier definitions matching the mockup type PlanId = "basic" | "home" | "team" | "business" | "enterprise"; @@ -805,6 +806,20 @@ export default function BillingPage() { return ( + {/* Trial Banner */} + {isTrial && ( + { + const currentPlan = planOptions.find( + (p) => p.id === currentPlanId + ); + if (currentPlan?.tierType) { + handleStartSubscription(currentPlan.tierType); + } + }} + /> + )} + {/* Subscription Status Alert */} {isProblematicState && statusMessage && ( diff --git a/src/components/DismissableBanner.tsx b/src/components/DismissableBanner.tsx index 289c4ec25..5527f1037 100644 --- a/src/components/DismissableBanner.tsx +++ b/src/components/DismissableBanner.tsx @@ -13,6 +13,7 @@ type DismissableBannerProps = { titleIcon: ReactNode; description: string; children?: ReactNode; + dismissable?: boolean; }; export const DismissableBanner = ({ @@ -21,7 +22,8 @@ export const DismissableBanner = ({ title, titleIcon, description, - children + children, + dismissable = true }: DismissableBannerProps) => { const [isDismissed, setIsDismissed] = useState(true); const t = useTranslations(); @@ -66,19 +68,21 @@ export const DismissableBanner = ({ ); }; - if (isDismissed) { + if (dismissable && isDismissed) { return null; } return ( - + {dismissable && ( + + )}
diff --git a/src/components/TrialBillingBanner.tsx b/src/components/TrialBillingBanner.tsx new file mode 100644 index 000000000..52fcb4873 --- /dev/null +++ b/src/components/TrialBillingBanner.tsx @@ -0,0 +1,38 @@ +"use client"; + +import React from "react"; +import { Button } from "@app/components/ui/button"; +import { ClockIcon, ArrowRight } from "lucide-react"; +import { useTranslations } from "next-intl"; +import DismissableBanner from "./DismissableBanner"; + +type TrialBillingBannerProps = { + onUpgrade: () => void; +}; + +export const TrialBillingBanner = ({ onUpgrade }: TrialBillingBannerProps) => { + const t = useTranslations(); + + return ( + } + description={t("billingTrialBannerDescription")} + dismissable={false} + > + + + ); +}; + +export default TrialBillingBanner;