Skip to content

Commit e66c800

Browse files
refactor(clerk-js,types): Update subscriptions listing UI (#5847)
Co-authored-by: Bryce Kalow <bryce@clerk.dev>
1 parent c792f37 commit e66c800

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+223
-110
lines changed

.changeset/smooth-signs-type.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@clerk/localizations': patch
3+
'@clerk/clerk-js': patch
4+
'@clerk/types': patch
5+
---
6+
7+
Update SubscriptionsList UI to be rendered within ProfileSections within UserProfile and OrganizationProfile.

integration/tests/pricing-table.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl
113113

114114
await u.po.userProfile.waitForMounted();
115115
await u.po.userProfile.switchToBillingTab();
116-
await u.po.page.getByRole('button', { name: 'View all plans' }).click();
116+
await u.po.page.getByRole('button', { name: 'Switch plans' }).click();
117117
await u.po.pricingTable.waitForMounted();
118118
await expect(u.po.page.getByRole('heading', { name: 'Pro' })).toBeVisible();
119119
});

packages/clerk-js/bundlewatch.config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
{ "path": "./dist/pricingTable*.js", "maxSize": "4.02KB" },
2424
{ "path": "./dist/checkout*.js", "maxSize": "5.79KB" },
2525
{ "path": "./dist/paymentSources*.js", "maxSize": "9.06KB" },
26-
{ "path": "./dist/up-billing-page*.js", "maxSize": "2.4KB" },
27-
{ "path": "./dist/op-billing-page*.js", "maxSize": "2.4KB" },
26+
{ "path": "./dist/up-billing-page*.js", "maxSize": "2.5KB" },
27+
{ "path": "./dist/op-billing-page*.js", "maxSize": "2.5KB" },
2828
{ "path": "./dist/sessionTasks*.js", "maxSize": "1KB" }
2929
]
3030
}

packages/clerk-js/src/ui/components/Checkout/CheckoutForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { useCheckoutContext } from '../../contexts';
1414
import { Box, Button, Col, descriptors, Form, localizationKeys, Text } from '../../customizables';
1515
import { Alert, Drawer, LineItems, SegmentedControl, Select, SelectButton, SelectOptionList } from '../../elements';
1616
import { useFetch } from '../../hooks';
17-
import { ArrowUpDown } from '../../icons';
17+
import { ChevronUpDown } from '../../icons';
1818
import { animations } from '../../styledSystem';
1919
import { handleError } from '../../utils';
2020
import { AddPaymentSource, PaymentSourceRow } from '../PaymentSources';
@@ -309,7 +309,7 @@ const ExistingPaymentSourceForm = ({
309309
value={selectedPaymentSource?.id}
310310
/>
311311
<SelectButton
312-
icon={ArrowUpDown}
312+
icon={ChevronUpDown}
313313
sx={t => ({
314314
justifyContent: 'space-between',
315315
backgroundColor: t.colors.$colorBackground,

packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationBillingPage.tsx

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import {
66
SubscriberTypeContext,
77
useSubscriptions,
88
} from '../../contexts';
9-
import { Button, Col, descriptors, Flex, localizationKeys } from '../../customizables';
9+
import { Col, descriptors, Flex, localizationKeys } from '../../customizables';
1010
import {
1111
Alert,
1212
Card,
1313
Header,
14+
ProfileSection,
1415
Tab,
1516
TabPanel,
1617
TabPanels,
@@ -20,6 +21,7 @@ import {
2021
withCardStateProvider,
2122
} from '../../elements';
2223
import { useTabState } from '../../hooks/useTabState';
24+
import { ArrowsUpDown } from '../../icons';
2325
import { useRouter } from '../../router';
2426
import { InvoicesList } from '../Invoices';
2527
import { PaymentSources } from '../PaymentSources';
@@ -53,7 +55,7 @@ const OrganizationBillingPageInternal = withCardStateProvider(() => {
5355
>
5456
<Header.Root>
5557
<Header.Title
56-
localizationKey={localizationKeys('userProfile.billingPage.title')}
58+
localizationKey={localizationKeys('organizationProfile.billingPage.title')}
5759
textVariant='h2'
5860
/>
5961
</Header.Root>
@@ -68,56 +70,70 @@ const OrganizationBillingPageInternal = withCardStateProvider(() => {
6870
<Tab
6971
localizationKey={
7072
subscriptions.data.length > 0
71-
? localizationKeys('userProfile.billingPage.start.headerTitle__subscriptions')
72-
: localizationKeys('userProfile.billingPage.start.headerTitle__plans')
73+
? localizationKeys('organizationProfile.billingPage.start.headerTitle__subscriptions')
74+
: localizationKeys('organizationProfile.billingPage.start.headerTitle__plans')
7375
}
7476
/>
75-
<Tab localizationKey={localizationKeys('userProfile.billingPage.start.headerTitle__invoices')} />
77+
<Tab localizationKey={localizationKeys('organizationProfile.billingPage.start.headerTitle__invoices')} />
7678
</TabsList>
7779
<TabPanels>
7880
<TabPanel sx={{ width: '100%', flexDirection: 'column' }}>
79-
<Flex
80-
sx={{ width: '100%', flexDirection: 'column' }}
81-
gap={4}
82-
>
83-
{subscriptions.data.length > 0 ? (
84-
<>
81+
{subscriptions.data.length > 0 ? (
82+
<Flex
83+
sx={{ width: '100%', flexDirection: 'column' }}
84+
gap={4}
85+
>
86+
<ProfileSection.Root
87+
id='subscriptionsList'
88+
title={localizationKeys('organizationProfile.billingPage.subscriptionsListSection.title')}
89+
centered={false}
90+
sx={t => ({
91+
borderTop: 'none',
92+
paddingTop: t.space.$1,
93+
})}
94+
>
8595
<Protect condition={has => !has({ permission: 'org:sys_billing:manage' })}>
8696
<Alert
8797
variant='info'
8898
colorScheme='info'
89-
title={localizationKeys('organizationProfile.billingPage.alerts.noPemissionsToManageBilling')}
99+
title={localizationKeys('organizationProfile.billingPage.alerts.noPermissionsToManageBilling')}
90100
/>
91101
</Protect>
92102
<SubscriptionsList />
93-
<Button
94-
localizationKey='View all plans'
95-
hasArrow
96-
variant='ghost'
97-
onClick={() => navigate('plans')}
98-
sx={{
99-
width: 'fit-content',
100-
}}
103+
<ProfileSection.ArrowButton
104+
id='subscriptionsList'
105+
textLocalizationKey={localizationKeys(
106+
'organizationProfile.billingPage.subscriptionsListSection.actionLabel__switchPlan',
107+
)}
108+
sx={[
109+
t => ({
110+
justifyContent: 'start',
111+
height: t.sizes.$8,
112+
}),
113+
]}
114+
leftIcon={ArrowsUpDown}
115+
leftIconSx={t => ({ width: t.sizes.$4, height: t.sizes.$4 })}
116+
onClick={() => void navigate('plans')}
101117
/>
102-
<Protect condition={has => has({ permission: 'org:sys_billing:manage' })}>
103-
<PaymentSources />
104-
</Protect>
105-
</>
106-
) : (
107-
<>
108-
<Protect condition={has => !has({ permission: 'org:sys_billing:manage' })}>
109-
<Alert
110-
variant='info'
111-
colorScheme='info'
112-
title={localizationKeys('organizationProfile.billingPage.alerts.noPemissionsToManageBilling')}
113-
/>
114-
</Protect>
115-
<PricingTableContext.Provider value={{ componentName: 'PricingTable', mode: 'modal' }}>
116-
<PricingTable />
117-
</PricingTableContext.Provider>
118-
</>
119-
)}
120-
</Flex>
118+
</ProfileSection.Root>
119+
<Protect condition={has => has({ permission: 'org:sys_billing:manage' })}>
120+
<PaymentSources />
121+
</Protect>
122+
</Flex>
123+
) : (
124+
<>
125+
<Protect condition={has => !has({ permission: 'org:sys_billing:manage' })}>
126+
<Alert
127+
variant='info'
128+
colorScheme='info'
129+
title={localizationKeys('organizationProfile.billingPage.alerts.noPermissionsToManageBilling')}
130+
/>
131+
</Protect>
132+
<PricingTableContext.Provider value={{ componentName: 'PricingTable', mode: 'modal' }}>
133+
<PricingTable />
134+
</PricingTableContext.Provider>
135+
</>
136+
)}
121137
</TabPanel>
122138
<TabPanel sx={{ width: '100%' }}>
123139
<InvoicesContextProvider>

packages/clerk-js/src/ui/components/OrganizationProfile/OrganizationPlansPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const OrganizationPlansPageInternal = () => {
3636
<Alert
3737
variant='info'
3838
colorScheme='info'
39-
title={localizationKeys('organizationProfile.billingPage.alerts.noPemissionsToManageBilling')}
39+
title={localizationKeys('organizationProfile.billingPage.alerts.noPermissionsToManageBilling')}
4040
/>
4141
</Protect>
4242
<PricingTableContext.Provider value={{ componentName: 'PricingTable', mode: 'modal' }}>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export const PaymentSources = () => {
102102
<ProfileSection.Root
103103
title={localizationKeys('userProfile.billingPage.paymentSourcesSection.title')}
104104
centered={false}
105-
id='profile'
105+
id='paymentSources'
106106
sx={t => ({
107107
flex: 1,
108108
borderTopWidth: t.borderWidths.$normal,

packages/clerk-js/src/ui/components/UserProfile/BillingPage.tsx

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import {
55
SubscriberTypeContext,
66
useSubscriptions,
77
} from '../../contexts';
8-
import { Button, Col, descriptors, Flex, localizationKeys } from '../../customizables';
8+
import { Col, descriptors, localizationKeys } from '../../customizables';
99
import {
1010
Card,
1111
Header,
12+
ProfileSection,
1213
Tab,
1314
TabPanel,
1415
TabPanels,
@@ -18,6 +19,7 @@ import {
1819
withCardStateProvider,
1920
} from '../../elements';
2021
import { useTabState } from '../../hooks/useTabState';
22+
import { ArrowsUpDown } from '../../icons';
2123
import { useRouter } from '../../router';
2224
import { InvoicesList } from '../Invoices';
2325
import { PaymentSources } from '../PaymentSources';
@@ -77,22 +79,38 @@ const BillingPageInternal = withCardStateProvider(() => {
7779
<TabPanels>
7880
<TabPanel sx={_ => ({ width: '100%', flexDirection: 'column' })}>
7981
{subscriptions.data.length > 0 ? (
80-
<Flex
81-
sx={{ width: '100%', flexDirection: 'column' }}
82-
gap={4}
83-
>
84-
<SubscriptionsList />
85-
<Button
86-
localizationKey='View all plans'
87-
hasArrow
88-
variant='ghost'
89-
onClick={() => navigate('plans')}
90-
sx={{
91-
width: 'fit-content',
92-
}}
93-
/>
82+
<>
83+
<ProfileSection.Root
84+
id='subscriptionsList'
85+
title={localizationKeys('userProfile.billingPage.subscriptionsListSection.title')}
86+
centered={false}
87+
sx={t => ({
88+
borderTop: 'none',
89+
paddingTop: t.space.$1,
90+
})}
91+
>
92+
<SubscriptionsList />
93+
<ProfileSection.ArrowButton
94+
id='subscriptionsList'
95+
textLocalizationKey={localizationKeys(
96+
'userProfile.billingPage.subscriptionsListSection.actionLabel__switchPlan',
97+
)}
98+
sx={[
99+
t => ({
100+
justifyContent: 'start',
101+
height: t.sizes.$8,
102+
}),
103+
]}
104+
leftIcon={ArrowsUpDown}
105+
leftIconSx={t => ({
106+
width: t.sizes.$4,
107+
height: t.sizes.$4,
108+
})}
109+
onClick={() => void navigate('plans')}
110+
/>
111+
</ProfileSection.Root>
94112
<PaymentSources />
95-
</Flex>
113+
</>
96114
) : (
97115
<PricingTableContext.Provider value={{ componentName: 'PricingTable', mode: 'modal' }}>
98116
<PricingTable />

packages/clerk-js/src/ui/elements/PhoneInput/PhoneInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { forwardRef, memo, useEffect, useMemo, useRef } from 'react';
33

44
import { descriptors, Flex, Icon, Input, Text } from '../../customizables';
55
import { Select, SelectButton, SelectOptionList } from '../../elements';
6-
import { ArrowUpDown, Check } from '../../icons';
6+
import { Check, ChevronUpDown } from '../../icons';
77
import { common, type PropsOfComponent } from '../../styledSystem';
88
import type { FeedbackType } from '../../utils';
99
import { mergeRefs } from '../../utils';
@@ -128,7 +128,7 @@ const PhoneInputBase = forwardRef<HTMLInputElement, PhoneInputProps & { feedback
128128
})}
129129
hoverAsFocus
130130
isDisabled={rest.isDisabled}
131-
icon={ArrowUpDown}
131+
icon={ChevronUpDown}
132132
iconSx={t => ({
133133
color: rest.isDisabled ? t.colors.$neutralAlpha300 : t.colors.$neutralAlpha500,
134134
})}
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)