@@ -20,9 +20,6 @@ export default function PricingTable({
2020 const [ isAnnual , setIsAnnual ] = useState ( false ) ;
2121 const { products, isLoading, error, refetch } = usePricingTable ( { productDetails } ) ;
2222
23- const [ hobbyPro , setHobbyPro ] = useState < 'hobby' | 'pro' > ( 'pro' ) ;
24- const [ scaleBuddy , setScaleBuddy ] = useState < 'scale' | 'buddy' > ( 'buddy' ) ;
25-
2623 const summary =
2724 "All plans include unlimited team members, full analytics, and priority support." ;
2825
@@ -92,15 +89,6 @@ export default function PricingTable({
9289 return true ;
9390 } ;
9491
95- const freePlan = products ?. find ( p => p . id === 'free' && intervalFilter ( p ) ) ;
96- const hobbyPlan = products ?. find ( p => p . id === 'hobby' && intervalFilter ( p ) ) ;
97- const proPlan = products ?. find ( p => p . id === 'pro' && intervalFilter ( p ) ) ;
98- const scalePlan = products ?. find ( p => p . id === 'scale' && intervalFilter ( p ) ) ;
99- const buddyPlan = products ?. find ( p => p . id === 'buddy' && intervalFilter ( p ) ) ;
100-
101- const showHobbyProToggle = ! ! hobbyPlan && ! ! proPlan ;
102- const showScaleBuddyToggle = ! ! scalePlan && ! ! buddyPlan ;
103-
10492 return (
10593 < section className = { cn ( "root" ) }
10694 aria-labelledby = "pricing-table-title"
@@ -148,232 +136,26 @@ export default function PricingTable({
148136 setIsAnnualToggle = { setIsAnnual }
149137 multiInterval = { multiInterval }
150138 >
151- { freePlan && (
152- < div className = "mb-6 pt-[46px]" >
139+ { products
140+ . filter ( ( p ) => p . id !== 'free' && intervalFilter ( p ) )
141+ . map ( ( plan ) => (
153142 < PricingCard
154- key = { freePlan . id }
155- productId = { freePlan . id }
143+ key = { plan . id }
144+ productId = { plan . id }
156145 buttonProps = { {
157146 disabled :
158- freePlan . scenario === "active" ||
159- freePlan . scenario === "scheduled" ,
147+ plan . scenario === "active" ||
148+ plan . scenario === "scheduled" ,
160149 onClick : async ( ) => {
161150 await attach ( {
162- productId : freePlan . id ,
151+ productId : plan . id ,
163152 dialog : AttachDialog ,
164153 } ) ;
165154 } ,
166- "aria-label" : freePlan . display ?. recommend_text ? `Select recommended plan: ${ freePlan . display ?. name } ` : `Select plan: ${ freePlan . display ?. name } `
155+ "aria-label" : plan . display ?. recommend_text ? `Select recommended plan: ${ plan . display ?. name } ` : `Select plan: ${ plan . display ?. name } `
167156 } }
168157 />
169- </ div >
170- ) }
171-
172- { ( hobbyPlan || proPlan ) && (
173- < div className = "mb-6" >
174- { showHobbyProToggle && (
175- < div className = "flex items-center justify-center gap-2 mb-4" >
176- < button
177- type = "button"
178- className = { cn (
179- "px-4 py-1 rounded-full border text-sm font-medium transition" ,
180- hobbyPro === 'hobby' ? 'bg-primary text-primary-foreground' : 'bg-secondary text-foreground'
181- ) }
182- onClick = { ( ) => setHobbyPro ( 'hobby' ) }
183- aria-pressed = { hobbyPro === 'hobby' }
184- >
185- Hobby
186- </ button >
187- < button
188- type = "button"
189- className = { cn (
190- "px-4 py-1 rounded-full border text-sm font-medium transition" ,
191- hobbyPro === 'pro' ? 'bg-primary text-primary-foreground' : 'bg-secondary text-foreground'
192- ) }
193- onClick = { ( ) => setHobbyPro ( 'pro' ) }
194- aria-pressed = { hobbyPro === 'pro' }
195- >
196- Pro
197- </ button >
198- </ div >
199- ) }
200- { ( ! showHobbyProToggle && hobbyPlan ) && (
201- < PricingCard
202- key = { hobbyPlan . id }
203- productId = { hobbyPlan . id }
204- buttonProps = { {
205- disabled :
206- hobbyPlan . scenario === "active" ||
207- hobbyPlan . scenario === "scheduled" ,
208- onClick : async ( ) => {
209- await attach ( {
210- productId : hobbyPlan . id ,
211- dialog : AttachDialog ,
212- } ) ;
213- } ,
214- "aria-label" : hobbyPlan . display ?. recommend_text ? `Select recommended plan: ${ hobbyPlan . display ?. name } ` : `Select plan: ${ hobbyPlan . display ?. name } `
215- } }
216- />
217- ) }
218- { ( ! showHobbyProToggle && proPlan ) && (
219- < PricingCard
220- key = { proPlan . id }
221- productId = { proPlan . id }
222- buttonProps = { {
223- disabled :
224- proPlan . scenario === "active" ||
225- proPlan . scenario === "scheduled" ,
226- onClick : async ( ) => {
227- await attach ( {
228- productId : proPlan . id ,
229- dialog : AttachDialog ,
230- } ) ;
231- } ,
232- "aria-label" : proPlan . display ?. recommend_text ? `Select recommended plan: ${ proPlan . display ?. name } ` : `Select plan: ${ proPlan . display ?. name } `
233- } }
234- />
235- ) }
236- { showHobbyProToggle && hobbyPro === 'hobby' && hobbyPlan && (
237- < PricingCard
238- key = { hobbyPlan . id }
239- productId = { hobbyPlan . id }
240- buttonProps = { {
241- disabled :
242- hobbyPlan . scenario === "active" ||
243- hobbyPlan . scenario === "scheduled" ,
244- onClick : async ( ) => {
245- await attach ( {
246- productId : hobbyPlan . id ,
247- dialog : AttachDialog ,
248- } ) ;
249- } ,
250- "aria-label" : hobbyPlan . display ?. recommend_text ? `Select recommended plan: ${ hobbyPlan . display ?. name } ` : `Select plan: ${ hobbyPlan . display ?. name } `
251- } }
252- />
253- ) }
254- { showHobbyProToggle && hobbyPro === 'pro' && proPlan && (
255- < PricingCard
256- key = { proPlan . id }
257- productId = { proPlan . id }
258- buttonProps = { {
259- disabled :
260- proPlan . scenario === "active" ||
261- proPlan . scenario === "scheduled" ,
262- onClick : async ( ) => {
263- await attach ( {
264- productId : proPlan . id ,
265- dialog : AttachDialog ,
266- } ) ;
267- } ,
268- "aria-label" : proPlan . display ?. recommend_text ? `Select recommended plan: ${ proPlan . display ?. name } ` : `Select plan: ${ proPlan . display ?. name } `
269- } }
270- />
271- ) }
272- </ div >
273- ) }
274-
275- { ( scalePlan || buddyPlan ) && (
276- < div >
277- { showScaleBuddyToggle && (
278- < div className = "flex items-center justify-center gap-2 mb-4" >
279- < button
280- type = "button"
281- className = { cn (
282- "px-4 py-1 rounded-full border text-sm font-medium transition" ,
283- scaleBuddy === 'scale' ? 'bg-primary text-primary-foreground' : 'bg-secondary text-foreground'
284- ) }
285- onClick = { ( ) => setScaleBuddy ( 'scale' ) }
286- aria-pressed = { scaleBuddy === 'scale' }
287- >
288- Scale
289- </ button >
290- < button
291- type = "button"
292- className = { cn (
293- "px-4 py-1 rounded-full border text-sm font-medium transition" ,
294- scaleBuddy === 'buddy' ? 'bg-primary text-primary-foreground' : 'bg-secondary text-foreground'
295- ) }
296- onClick = { ( ) => setScaleBuddy ( 'buddy' ) }
297- aria-pressed = { scaleBuddy === 'buddy' }
298- >
299- Buddy
300- </ button >
301- </ div >
302- ) }
303- { ( ! showScaleBuddyToggle && scalePlan ) && (
304- < PricingCard
305- key = { scalePlan . id }
306- productId = { scalePlan . id }
307- buttonProps = { {
308- disabled :
309- scalePlan . scenario === "active" ||
310- scalePlan . scenario === "scheduled" ,
311- onClick : async ( ) => {
312- await attach ( {
313- productId : scalePlan . id ,
314- dialog : AttachDialog ,
315- } ) ;
316- } ,
317- "aria-label" : scalePlan . display ?. recommend_text ? `Select recommended plan: ${ scalePlan . display ?. name } ` : `Select plan: ${ scalePlan . display ?. name } `
318- } }
319- />
320- ) }
321- { ( ! showScaleBuddyToggle && buddyPlan ) && (
322- < PricingCard
323- key = { buddyPlan . id }
324- productId = { buddyPlan . id }
325- buttonProps = { {
326- disabled :
327- buddyPlan . scenario === "active" ||
328- buddyPlan . scenario === "scheduled" ,
329- onClick : async ( ) => {
330- await attach ( {
331- productId : buddyPlan . id ,
332- dialog : AttachDialog ,
333- } ) ;
334- } ,
335- "aria-label" : buddyPlan . display ?. recommend_text ? `Select recommended plan: ${ buddyPlan . display ?. name } ` : `Select plan: ${ buddyPlan . display ?. name } `
336- } }
337- />
338- ) }
339- { showScaleBuddyToggle && scaleBuddy === 'scale' && scalePlan && (
340- < PricingCard
341- key = { scalePlan . id }
342- productId = { scalePlan . id }
343- buttonProps = { {
344- disabled :
345- scalePlan . scenario === "active" ||
346- scalePlan . scenario === "scheduled" ,
347- onClick : async ( ) => {
348- await attach ( {
349- productId : scalePlan . id ,
350- dialog : AttachDialog ,
351- } ) ;
352- } ,
353- "aria-label" : scalePlan . display ?. recommend_text ? `Select recommended plan: ${ scalePlan . display ?. name } ` : `Select plan: ${ scalePlan . display ?. name } `
354- } }
355- />
356- ) }
357- { showScaleBuddyToggle && scaleBuddy === 'buddy' && buddyPlan && (
358- < PricingCard
359- key = { buddyPlan . id }
360- productId = { buddyPlan . id }
361- buttonProps = { {
362- disabled :
363- buddyPlan . scenario === "active" ||
364- buddyPlan . scenario === "scheduled" ,
365- onClick : async ( ) => {
366- await attach ( {
367- productId : buddyPlan . id ,
368- dialog : AttachDialog ,
369- } ) ;
370- } ,
371- "aria-label" : buddyPlan . display ?. recommend_text ? `Select recommended plan: ${ buddyPlan . display ?. name } ` : `Select plan: ${ buddyPlan . display ?. name } `
372- } }
373- />
374- ) }
375- </ div >
376- ) }
158+ ) ) }
377159 </ PricingTableContainer >
378160 ) }
379161 </ section >
@@ -494,7 +276,6 @@ export const PricingCard = ({
494276 }
495277 : product . items [ 0 ] . display ;
496278
497- // Determine support level based on plan id
498279 let supportLevel : { display : { primary_text : string } } | null = null ;
499280 switch ( product . id ) {
500281 case 'free' :
@@ -514,7 +295,6 @@ export const PricingCard = ({
514295 supportLevel = null ;
515296 }
516297
517- // Add extra features for higher plans
518298 const extraFeatures : { display : { primary_text : string } } [ ] =
519299 [ 'scale' , 'buddy' ] . includes ( product . id )
520300 ? [
@@ -523,7 +303,6 @@ export const PricingCard = ({
523303 ]
524304 : [ ] ;
525305
526- // Add support feature as the last item if supportLevel exists
527306 const featureItems = product . properties ?. is_free
528307 ? ( supportLevel ? [ ...product . items , ...extraFeatures , supportLevel ] : [ ...product . items , ...extraFeatures ] )
529308 : ( supportLevel ? [ ...product . items . slice ( 1 ) , ...extraFeatures , supportLevel ] : [ ...product . items . slice ( 1 ) , ...extraFeatures ] ) ;
@@ -599,7 +378,6 @@ export const PricingCard = ({
599378 ) ;
600379} ;
601380
602- // Pricing Feature List
603381export const PricingFeatureList = ( {
604382 items,
605383 showIcon = true ,
@@ -663,7 +441,6 @@ export const PricingFeatureList = ({
663441 ) ;
664442} ;
665443
666- // Pricing Card Button
667444export interface PricingCardButtonProps extends React . ComponentProps < "button" > {
668445 recommended ?: boolean ;
669446 buttonUrl ?: string ;
@@ -716,8 +493,7 @@ export const PricingCardButton = React.forwardRef<
716493 ) ;
717494} ) ;
718495PricingCardButton . displayName = "PricingCardButton" ;
719-
720- // Annual Switch
496+
721497export const AnnualSwitch = ( {
722498 isAnnualToggle,
723499 setIsAnnualToggle,
0 commit comments