Skip to content

Commit ff16e58

Browse files
refactor(clerk-js): Add loading state to <PaymentSources /> component (#5879)
1 parent 51ccfc6 commit ff16e58

File tree

2 files changed

+52
-34
lines changed

2 files changed

+52
-34
lines changed

.changeset/two-keys-act.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
---
4+
5+
Add loading state to `<PaymentSources />` component.

packages/clerk-js/src/ui/components/PaymentSources/PaymentSources.tsx

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Fragment, useMemo, useRef } from 'react';
66
import { RemoveResourceForm } from '../../common';
77
import { useSubscriberTypeContext } from '../../contexts';
88
import { localizationKeys } from '../../customizables';
9-
import { ProfileSection, ThreeDotsMenu, useCardState } from '../../elements';
9+
import { FullHeightLoader, ProfileSection, ThreeDotsMenu, useCardState, withCardStateProvider } from '../../elements';
1010
import { Action } from '../../elements/Action';
1111
import { useActionContext } from '../../elements/Action/ActionRoot';
1212
import { useFetch } from '../../hooks';
@@ -83,25 +83,29 @@ const RemoveScreen = ({
8383
);
8484
};
8585

86-
export const PaymentSources = () => {
86+
export const PaymentSources = withCardStateProvider(() => {
8787
const clerk = useClerk();
8888
const subscriberType = useSubscriberTypeContext();
8989

9090
const resource = subscriberType === 'org' ? clerk?.organization : clerk.user;
9191

92-
const { data, revalidate } = useFetch(
92+
const { data, revalidate, isLoading } = useFetch(
9393
resource?.getPaymentSources,
9494
{},
9595
undefined,
9696
`commerce-payment-sources-${resource?.id}`,
9797
);
98-
const { data: paymentSources } = data || { data: [] };
98+
const { data: paymentSources = [] } = data || {};
9999

100100
const sortedPaymentSources = useMemo(
101101
() => paymentSources.sort((a, b) => (a.isDefault && !b.isDefault ? -1 : 1)),
102102
[paymentSources],
103103
);
104104

105+
if (!resource) {
106+
return null;
107+
}
108+
105109
return (
106110
<ProfileSection.Root
107111
title={localizationKeys('userProfile.billingPage.paymentSourcesSection.title')}
@@ -115,43 +119,52 @@ export const PaymentSources = () => {
115119
})}
116120
>
117121
<Action.Root>
118-
<ProfileSection.ItemList id='paymentSources'>
119-
{sortedPaymentSources.map(paymentSource => (
120-
<Fragment key={paymentSource.id}>
121-
<ProfileSection.Item id='paymentSources'>
122-
<PaymentSourceRow paymentSource={paymentSource} />
123-
<PaymentSourceMenu
124-
paymentSource={paymentSource}
125-
revalidate={revalidate}
122+
<ProfileSection.ItemList
123+
id='paymentSources'
124+
disableAnimation
125+
>
126+
{isLoading ? (
127+
<FullHeightLoader />
128+
) : (
129+
<>
130+
{sortedPaymentSources.map(paymentSource => (
131+
<Fragment key={paymentSource.id}>
132+
<ProfileSection.Item id='paymentSources'>
133+
<PaymentSourceRow paymentSource={paymentSource} />
134+
<PaymentSourceMenu
135+
paymentSource={paymentSource}
136+
revalidate={revalidate}
137+
/>
138+
</ProfileSection.Item>
139+
140+
<Action.Open value={`remove-${paymentSource.id}`}>
141+
<Action.Card variant='destructive'>
142+
<RemoveScreen
143+
paymentSource={paymentSource}
144+
revalidate={revalidate}
145+
/>
146+
</Action.Card>
147+
</Action.Open>
148+
</Fragment>
149+
))}
150+
<Action.Trigger value='add'>
151+
<ProfileSection.ArrowButton
152+
id='paymentSources'
153+
localizationKey={localizationKeys('userProfile.billingPage.paymentSourcesSection.add')}
126154
/>
127-
</ProfileSection.Item>
128-
129-
<Action.Open value={`remove-${paymentSource.id}`}>
130-
<Action.Card variant='destructive'>
131-
<RemoveScreen
132-
paymentSource={paymentSource}
133-
revalidate={revalidate}
134-
/>
155+
</Action.Trigger>
156+
<Action.Open value='add'>
157+
<Action.Card>
158+
<AddScreen onSuccess={revalidate} />
135159
</Action.Card>
136160
</Action.Open>
137-
</Fragment>
138-
))}
139-
<Action.Trigger value='add'>
140-
<ProfileSection.ArrowButton
141-
id='paymentSources'
142-
localizationKey={localizationKeys('userProfile.billingPage.paymentSourcesSection.add')}
143-
/>
144-
</Action.Trigger>
145-
<Action.Open value='add'>
146-
<Action.Card>
147-
<AddScreen onSuccess={revalidate} />
148-
</Action.Card>
149-
</Action.Open>
161+
</>
162+
)}
150163
</ProfileSection.ItemList>
151164
</Action.Root>
152165
</ProfileSection.Root>
153166
);
154-
};
167+
});
155168

156169
const PaymentSourceMenu = ({
157170
paymentSource,

0 commit comments

Comments
 (0)