@@ -23,7 +23,13 @@ export type Tier = {
2323 cta ?: "get-started" | "buy" | "contact" ;
2424} ;
2525
26- function TierCTAButton ( { tier } : { tier : Tier } ) {
26+ const BUSINESS_PLAN_TYPES = new Set ( [ "business" , "business-yearly" ] ) ;
27+
28+ function isBusinessPlan ( planType : string ) {
29+ return BUSINESS_PLAN_TYPES . has ( planType ) ;
30+ }
31+
32+ function TierCTAButton ( { tier, frequency } : { tier : Tier ; frequency : Frequency } ) {
2733 const { data : session } = useSession ( ) ;
2834 let text =
2935 tier . cta === "get-started"
@@ -38,10 +44,11 @@ function TierCTAButton({ tier }: { tier: Tier }) {
3844 if ( session . planType === "free" ) {
3945 text = "Buy now" ;
4046 } else {
41- text =
42- session . planType === tier . id
43- ? "Manage subscription"
44- : "Update subscription" ;
47+ const isCurrentPlan =
48+ tier . id === "business"
49+ ? isBusinessPlan ( session . planType ?? "" )
50+ : session . planType === tier . id ;
51+ text = isCurrentPlan ? "Manage subscription" : "Update subscription" ;
4552 }
4653 }
4754
@@ -68,9 +75,6 @@ function TierCTAButton({ tier }: { tier: Tier }) {
6875 }
6976
7077 track ( "Signup" , { tier : tier . id } ) ;
71- // ... rest of analytic logic kept simple for brevity in replacement,
72- // in real implementation we keep the existing logic.
73- // Re-injecting existing analytics logic below to ensure no regression.
7478 if ( ! session ) {
7579 Sentry . captureEvent ( {
7680 message : "click-pricing-signup" ,
@@ -90,9 +94,16 @@ function TierCTAButton({ tier }: { tier: Tier }) {
9094 track ( "click-pricing-buy-now" , { tier : tier . id } ) ;
9195 e . preventDefault ( ) ;
9296 e . stopPropagation ( ) ;
93- await authClient . checkout ( { slug : tier . id } ) ;
97+ const checkoutSlug = frequency === "year" && tier . id === "business"
98+ ? "business-yearly"
99+ : tier . id ;
100+ await authClient . checkout ( { slug : checkoutSlug } ) ;
94101 } else {
95- if ( session . planType === tier . id ) {
102+ const isCurrentPlan =
103+ tier . id === "business"
104+ ? isBusinessPlan ( session . planType ?? "" )
105+ : session . planType === tier . id ;
106+ if ( isCurrentPlan ) {
96107 Sentry . captureEvent ( {
97108 message : "click-pricing-manage-subscription" ,
98109 level : "info" ,
@@ -208,6 +219,28 @@ export function Tiers({
208219 < span className = "text-3xl font-bold text-stone-900" >
209220 { tier . price }
210221 </ span >
222+ ) : frequency === "year" ? (
223+ < div >
224+ < div className = "flex items-baseline gap-2" >
225+ < span className = "text-4xl font-bold text-stone-900" >
226+ ${ Math . round ( tier . price . year / 12 ) }
227+ </ span >
228+ < span className = "text-sm font-medium text-stone-400" >
229+ /month
230+ </ span >
231+ </ div >
232+ < div className = "mt-1.5 flex items-center gap-2" >
233+ < span className = "text-sm text-stone-400 line-through decoration-stone-400" >
234+ ${ tier . price . month } /mo
235+ </ span >
236+ < span className = "rounded-md bg-green-100 px-1.5 py-0.5 text-xs font-semibold text-green-700" >
237+ now -50%
238+ </ span >
239+ </ div >
240+ < p className = "mt-1 text-xs text-stone-400" >
241+ ${ tier . price . year . toLocaleString ( ) } billed yearly
242+ </ p >
243+ </ div >
211244 ) : (
212245 < div className = "flex items-baseline gap-1" >
213246 < span className = "text-4xl font-bold text-stone-900" >
@@ -227,7 +260,7 @@ export function Tiers({
227260
228261 { /* CTA */ }
229262 < div className = "mb-6" >
230- < TierCTAButton tier = { tier } />
263+ < TierCTAButton tier = { tier } frequency = { frequency } />
231264 </ div >
232265
233266 { /* Features */ }
0 commit comments