@@ -35,8 +35,10 @@ const PricingTableSkeleton = () => (
3535
3636export default function PricingTable ( {
3737 productDetails,
38+ selectedPlan,
3839} : {
3940 productDetails ?: ProductDetails [ ] ;
41+ selectedPlan ?: string | null ;
4042} ) {
4143 const { attach } = useCustomer ( ) ;
4244 const [ isAnnual , setIsAnnual ] = useState ( false ) ;
@@ -158,6 +160,7 @@ export default function PricingTable({
158160 isAnnualToggle = { isAnnual }
159161 multiInterval = { multiInterval }
160162 products = { products }
163+ selectedPlan = { selectedPlan }
161164 setIsAnnualToggle = { setIsAnnual }
162165 >
163166 { products
@@ -177,6 +180,7 @@ export default function PricingTable({
177180 ? `Select recommended plan: ${ plan . display ?. name } `
178181 : `Select plan: ${ plan . display ?. name } ` ,
179182 } }
183+ isSelected = { selectedPlan === plan . id }
180184 key = { plan . id }
181185 productId = { plan . id }
182186 />
@@ -192,13 +196,15 @@ const PricingTableContext = createContext<{
192196 setIsAnnualToggle : ( isAnnual : boolean ) => void ;
193197 products : Product [ ] ;
194198 showFeatures : boolean ;
199+ selectedPlan ?: string | null ;
195200} > ( {
196201 isAnnualToggle : false ,
197202 setIsAnnualToggle : ( ) => {
198203 throw new Error ( 'setIsAnnualToggle is not implemented' ) ;
199204 } ,
200205 products : [ ] ,
201206 showFeatures : true ,
207+ selectedPlan : null ,
202208} ) ;
203209
204210export const usePricingTableContext = ( componentName : string ) => {
@@ -219,6 +225,7 @@ export const PricingTableContainer = ({
219225 isAnnualToggle,
220226 setIsAnnualToggle,
221227 multiInterval,
228+ selectedPlan,
222229} : {
223230 children ?: React . ReactNode ;
224231 products ?: Product [ ] ;
@@ -227,6 +234,7 @@ export const PricingTableContainer = ({
227234 isAnnualToggle : boolean ;
228235 setIsAnnualToggle : ( isAnnual : boolean ) => void ;
229236 multiInterval : boolean ;
237+ selectedPlan ?: string | null ;
230238} ) => {
231239 if ( ! products ) {
232240 throw new Error ( 'products is required in <PricingTable />' ) ;
@@ -239,7 +247,13 @@ export const PricingTableContainer = ({
239247 const hasRecommended = products ?. some ( ( p ) => p . display ?. recommend_text ) ;
240248 return (
241249 < PricingTableContext . Provider
242- value = { { isAnnualToggle, setIsAnnualToggle, products, showFeatures } }
250+ value = { {
251+ isAnnualToggle,
252+ setIsAnnualToggle,
253+ products,
254+ showFeatures,
255+ selectedPlan,
256+ } }
243257 >
244258 < div
245259 className = { cn ( 'flex flex-col items-center' , hasRecommended && '!py-10' ) }
@@ -275,12 +289,14 @@ interface PricingCardProps {
275289 className ?: string ;
276290 onButtonClick ?: ( event : React . MouseEvent < HTMLButtonElement > ) => void ;
277291 buttonProps ?: React . ComponentProps < 'button' > ;
292+ isSelected ?: boolean ;
278293}
279294
280295export const PricingCard = ( {
281296 productId,
282297 className,
283298 buttonProps,
299+ isSelected = false ,
284300} : PricingCardProps ) => {
285301 const { products, showFeatures } = usePricingTableContext ( 'PricingCard' ) ;
286302
@@ -292,8 +308,17 @@ export const PricingCard = ({
292308
293309 const { name, display : productDisplay } = product ;
294310
295- const { buttonText } = getPricingTableContent ( product ) ;
311+ const { buttonText : defaultButtonText } = getPricingTableContent ( product ) ;
296312 const isRecommended = ! ! productDisplay ?. recommend_text ;
313+ const { selectedPlan } = usePricingTableContext ( 'PricingCard' ) ;
314+
315+ // Customize button text for selected plans
316+ const buttonText =
317+ selectedPlan === productId ? (
318+ < span className = "font-semibold" > Complete Purchase →</ span >
319+ ) : (
320+ defaultButtonText
321+ ) ;
297322 const mainPriceDisplay = product . properties ?. is_free
298323 ? {
299324 primary_text : 'Free' ,
@@ -345,6 +370,7 @@ export const PricingCard = ({
345370 'relative h-full w-full max-w-xl rounded-lg border py-6 text-foreground shadow-sm transition-all duration-300' ,
346371 isRecommended &&
347372 'lg:-translate-y-6 animate-recommended-glow border-primary bg-secondary/40 lg:h-[calc(100%+48px)] lg:shadow-lg dark:shadow-zinc-800/80' ,
373+ isSelected && 'border-primary bg-primary/5 ring-2 ring-primary/20' ,
348374 className
349375 ) }
350376 >
@@ -360,9 +386,16 @@ export const PricingCard = ({
360386 < div className = "h-full" >
361387 < div className = "flex flex-col" >
362388 < div className = "pb-4" >
363- < h2 className = "truncate px-6 font-semibold text-2xl" >
364- { productDisplay ?. name || name }
365- </ h2 >
389+ < div className = "flex items-center justify-between px-6" >
390+ < h2 className = "truncate font-semibold text-2xl" >
391+ { productDisplay ?. name || name }
392+ </ h2 >
393+ { isSelected && (
394+ < div className = "ml-2 rounded-full bg-primary px-3 py-1 font-medium text-primary-foreground text-xs" >
395+ Selected
396+ </ div >
397+ ) }
398+ </ div >
366399 { productDisplay ?. description && (
367400 < div className = "h-8 px-6 text-muted-foreground text-sm" >
368401 < p className = "line-clamp-2" > { productDisplay ?. description } </ p >
@@ -376,7 +409,7 @@ export const PricingCard = ({
376409 < div className = "flex flex-col gap-1" >
377410 < div className = "flex items-center gap-2" >
378411 < span className = "text-muted-foreground text-xs line-through" >
379- $10.00
412+ $9.99
380413 </ span >
381414 < span className = "font-medium text-green-600" >
382415 $2.00
0 commit comments