11import { useClerk } from '@clerk/shared/react' ;
2- import type { __internal_PlanDetailsProps , CommercePlanResource , CommerceSubscriptionPlanPeriod } from '@clerk/types' ;
2+ import type {
3+ __internal_PlanDetailsProps ,
4+ ClerkAPIResponseError ,
5+ CommercePlanResource ,
6+ CommerceSubscriptionPlanPeriod ,
7+ } from '@clerk/types' ;
38import * as React from 'react' ;
49import { useMemo , useState } from 'react' ;
510import useSWR from 'swr' ;
611
12+ import { Alert } from '@/ui/elements/Alert' ;
713import { Avatar } from '@/ui/elements/Avatar' ;
814import { Drawer } from '@/ui/elements/Drawer' ;
915import { Switch } from '@/ui/elements/Switch' ;
1016
1117import { SubscriberTypeContext } from '../../contexts' ;
12- import { Box , Col , descriptors , Flex , Heading , localizationKeys , Span , Spinner , Text } from '../../customizables' ;
18+ import {
19+ Box ,
20+ Col ,
21+ descriptors ,
22+ Flex ,
23+ Heading ,
24+ localizationKeys ,
25+ Span ,
26+ Spinner ,
27+ Text ,
28+ useLocalizations ,
29+ } from '../../customizables' ;
1330
1431export const PlanDetails = ( props : __internal_PlanDetailsProps ) => {
1532 return (
@@ -19,6 +36,39 @@ export const PlanDetails = (props: __internal_PlanDetailsProps) => {
1936 ) ;
2037} ;
2138
39+ const BodyFiller = ( { children } : { children : React . ReactNode } ) => {
40+ return (
41+ < Drawer . Body
42+ sx = { t => ( {
43+ display : 'flex' ,
44+ flexDirection : 'column' ,
45+ alignItems : 'center' ,
46+ justifyContent : 'center' ,
47+ flex : 1 ,
48+ overflowY : 'auto' ,
49+ padding : t . space . $4 ,
50+ gap : t . space . $4 ,
51+ } ) }
52+ >
53+ { children }
54+ </ Drawer . Body >
55+ ) ;
56+ } ;
57+
58+ const PlanDetailsError = ( { error } : { error : ClerkAPIResponseError } ) => {
59+ const { translateError } = useLocalizations ( ) ;
60+ return (
61+ < BodyFiller >
62+ < Alert
63+ variant = 'danger'
64+ colorScheme = 'danger'
65+ >
66+ { translateError ( error . errors [ 0 ] ) }
67+ </ Alert >
68+ </ BodyFiller >
69+ ) ;
70+ } ;
71+
2272const PlanDetailsInternal = ( {
2373 planId,
2474 plan : initialPlan ,
@@ -27,29 +77,34 @@ const PlanDetailsInternal = ({
2777 const clerk = useClerk ( ) ;
2878 const [ planPeriod , setPlanPeriod ] = useState < CommerceSubscriptionPlanPeriod > ( initialPlanPeriod ) ;
2979
30- const { data : plan , isLoading } = useSWR (
80+ const {
81+ data : plan ,
82+ isLoading,
83+ error,
84+ } = useSWR < CommercePlanResource , ClerkAPIResponseError > (
3185 planId || initialPlan ? { type : 'plan' , id : planId || initialPlan ?. id } : null ,
3286 // @ts -expect-error we are handling it above
3387 ( ) => clerk . billing . getPlan ( { id : planId || initialPlan ?. id } ) ,
3488 {
3589 fallbackData : initialPlan ,
90+ revalidateOnFocus : false ,
91+ shouldRetryOnError : false ,
92+ keepPreviousData : true ,
3693 } ,
3794 ) ;
3895
3996 if ( isLoading && ! initialPlan ) {
4097 return (
41- < Flex
42- justify = 'center'
43- align = 'center'
44- sx = { {
45- height : '100%' ,
46- } }
47- >
98+ < BodyFiller >
4899 < Spinner />
49- </ Flex >
100+ </ BodyFiller >
50101 ) ;
51102 }
52103
104+ if ( ! plan && error ) {
105+ return < PlanDetailsError error = { error } /> ;
106+ }
107+
53108 if ( ! plan ) {
54109 return null ;
55110 }
0 commit comments