@@ -47,7 +47,7 @@ export function UpsellWrapper({
47
47
}
48
48
49
49
return (
50
- < div className = { cn ( "relative flex-1" , className ) } >
50
+ < div className = { cn ( "relative flex-1 flex flex-col " , className ) } >
51
51
{ /* Background content - blurred and non-interactive */ }
52
52
< div className = "absolute inset-0 overflow-hidden" >
53
53
< div className = "pointer-events-none select-none opacity-60 blur-[1px]" >
@@ -59,84 +59,109 @@ export function UpsellWrapper({
59
59
< div className = "absolute inset-0 bg-gradient-to-b from-muted/20 via-muted/30 to-background" />
60
60
61
61
{ /* Upsell content */ }
62
- < div className = "relative z-10 flex items-center justify-center p-16" >
63
- < Card className = "w-full max-w-2xl border-2 shadow-2xl" >
64
- < CardHeader className = "space-y-4 text-center" >
65
- < div className = "mx-auto flex h-16 w-16 items-center justify-center rounded-full border-2 bg-muted" >
66
- < LockIcon className = "h-8 w-8 text-muted-foreground" />
67
- </ div >
62
+ < div className = "relative z-10 flex items-center justify-center grow py-20 px-6" >
63
+ < UpsellContent
64
+ benefits = { benefits }
65
+ currentPlan = { currentPlan }
66
+ featureDescription = { featureDescription }
67
+ featureName = { featureName }
68
+ requiredPlan = { requiredPlan }
69
+ teamSlug = { teamSlug }
70
+ />
71
+ </ div >
72
+ </ div >
73
+ ) ;
74
+ }
68
75
69
- < div className = "space-y-2" >
70
- < TeamPlanBadge
71
- plan = "scale"
72
- postfix = " Feature"
73
- teamSlug = { teamSlug }
74
- />
75
- < CardTitle className = "font-bold text-2xl text-foreground md:text-3xl" >
76
- Unlock { featureName }
77
- </ CardTitle >
78
- < CardDescription className = "mx-auto max-w-md text-base text-muted-foreground" >
79
- { featureDescription }
80
- </ CardDescription >
81
- </ div >
82
- </ CardHeader >
76
+ export function UpsellContent ( props : {
77
+ teamSlug : string ;
78
+ featureName : string ;
79
+ featureDescription : string ;
80
+ requiredPlan : Team [ "billingPlan" ] ;
81
+ currentPlan : Team [ "billingPlan" ] ;
82
+ benefits ?: {
83
+ description : string ;
84
+ status : "available" | "soon" ;
85
+ } [ ] ;
86
+ } ) {
87
+ return (
88
+ < Card className = "w-full max-w-xl border shadow-2xl" >
89
+ < CardHeader className = "space-y-4 text-center" >
90
+ < div className = "mx-auto flex p-4 items-center justify-center rounded-full border bg-card" >
91
+ < LockIcon className = "size-8 text-muted-foreground" />
92
+ </ div >
83
93
84
- < CardContent className = "space-y-6" >
85
- { benefits . length > 0 && (
86
- < div className = "space-y-3" >
87
- < h4 className = "font-semibold text-muted-foreground text-sm uppercase tracking-wide" >
88
- What you'll get:
89
- </ h4 >
90
- < div className = "grid gap-2" >
91
- { benefits . map ( ( benefit ) => (
92
- < div
93
- className = "flex items-center gap-3"
94
- key = { benefit . description }
95
- >
96
- < div className = "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-accent" >
97
- < SparklesIcon className = "h-3 w-3 text-success-text" />
98
- </ div >
99
- < span className = "text-sm" > { benefit . description } </ span >
100
- { benefit . status === "soon" && (
101
- < Badge className = "text-xs" variant = "secondary" >
102
- Coming Soon
103
- </ Badge >
104
- ) }
105
- </ div >
106
- ) ) }
107
- </ div >
108
- </ div >
109
- ) }
94
+ < div className = "space-y-4" >
95
+ < TeamPlanBadge
96
+ plan = { props . requiredPlan }
97
+ postfix = " Feature"
98
+ teamSlug = { props . teamSlug }
99
+ />
100
+ < div className = "space-y-1" >
101
+ < CardTitle className = "font-bold text-2xl text-foreground md:text-3xl" >
102
+ Unlock { props . featureName }
103
+ </ CardTitle >
104
+ < CardDescription className = "mx-auto max-w-md text-base text-muted-foreground" >
105
+ { props . featureDescription }
106
+ </ CardDescription >
107
+ </ div >
108
+ </ div >
109
+ </ CardHeader >
110
110
111
- < div className = "flex flex-col gap-3 pt-4 sm:flex-row" >
112
- < Button asChild className = "flex-1 py-3 font-semibold" size = "lg" >
113
- < Link
114
- href = { `/team/${ teamSlug } /~/settings/billing?showPlans=true&highlight=${ requiredPlan } ` }
115
- >
116
- < CrownIcon className = "mr-2 h-4 w-4" />
117
- Upgrade to{ " " }
118
- < span className = "ml-1 capitalize" > { requiredPlan } </ span >
119
- </ Link >
120
- </ Button >
121
- < Button asChild className = "md:flex-1" size = "lg" variant = "outline" >
122
- < Link
123
- href = { `/team/${ teamSlug } /~/settings/billing?showPlans=true` }
111
+ < CardContent className = "space-y-6" >
112
+ { props . benefits && props . benefits . length > 0 && (
113
+ < div className = "space-y-3" >
114
+ < h4 className = "font-semibold text-muted-foreground text-sm uppercase tracking-wide" >
115
+ What you'll get:
116
+ </ h4 >
117
+ < div className = "grid gap-2" >
118
+ { props . benefits . map ( ( benefit ) => (
119
+ < div
120
+ className = "flex items-center gap-3"
121
+ key = { benefit . description }
124
122
>
125
- View All Plans
126
- </ Link >
127
- </ Button >
123
+ < div className = "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-accent" >
124
+ < SparklesIcon className = "h-3 w-3 text-success-text" />
125
+ </ div >
126
+ < span className = "text-sm" > { benefit . description } </ span >
127
+ { benefit . status === "soon" && (
128
+ < Badge className = "text-xs" variant = "secondary" >
129
+ Coming Soon
130
+ </ Badge >
131
+ ) }
132
+ </ div >
133
+ ) ) }
128
134
</ div >
135
+ </ div >
136
+ ) }
129
137
130
- < div className = "pt-2 text-center" >
131
- < p className = "text-muted-foreground text-xs" >
132
- You are currently on the{ " " }
133
- < span className = "font-medium capitalize" > { currentPlan } </ span > { " " }
134
- plan.
135
- </ p >
136
- </ div >
137
- </ CardContent >
138
- </ Card >
139
- </ div >
140
- </ div >
138
+ < div className = "flex flex-col gap-3 pt-4 sm:flex-row" >
139
+ < Button asChild className = "flex-1 py-3 font-semibold" size = "lg" >
140
+ < Link
141
+ href = { `/team/${ props . teamSlug } /~/settings/billing?showPlans=true&highlight=${ props . requiredPlan } ` }
142
+ >
143
+ < CrownIcon className = "mr-2 h-4 w-4" />
144
+ Upgrade to{ " " }
145
+ < span className = "ml-1 capitalize" > { props . requiredPlan } </ span >
146
+ </ Link >
147
+ </ Button >
148
+ < Button asChild className = "md:flex-1" size = "lg" variant = "outline" >
149
+ < Link
150
+ href = { `/team/${ props . teamSlug } /~/settings/billing?showPlans=true` }
151
+ >
152
+ View All Plans
153
+ </ Link >
154
+ </ Button >
155
+ </ div >
156
+
157
+ < div className = "pt-2 text-center" >
158
+ < p className = "text-muted-foreground text-xs" >
159
+ You are currently on the{ " " }
160
+ < span className = "font-medium capitalize" > { props . currentPlan } </ span > { " " }
161
+ plan.
162
+ </ p >
163
+ </ div >
164
+ </ CardContent >
165
+ </ Card >
141
166
) ;
142
167
}
0 commit comments