Skip to content

Commit d708ac4

Browse files
icecrasher321waleedlatif1
authored andcommitted
fix(billing): should allow restoring subscription (#1728)
* fix(already-cancelled-sub): UI should allow restoring subscription * restore functionality fixed * fix
1 parent 33ac828 commit d708ac4

File tree

2 files changed

+192
-269
lines changed

2 files changed

+192
-269
lines changed

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/components/subscription/components/cancel-subscription/cancel-subscription.tsx

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
'use client'
22

33
import { useEffect, useState } from 'react'
4-
import { useQueryClient } from '@tanstack/react-query'
54
import {
6-
Button,
7-
Modal,
8-
ModalContent,
9-
ModalDescription,
10-
ModalFooter,
11-
ModalHeader,
12-
ModalTitle,
13-
} from '@/components/emcn'
5+
AlertDialog,
6+
AlertDialogAction,
7+
AlertDialogCancel,
8+
AlertDialogContent,
9+
AlertDialogDescription,
10+
AlertDialogFooter,
11+
AlertDialogHeader,
12+
AlertDialogTitle,
13+
} from '@/components/ui/alert-dialog'
14+
import { Button } from '@/components/ui/button'
1415
import { useSession, useSubscription } from '@/lib/auth-client'
1516
import { createLogger } from '@/lib/logs/console/logger'
16-
import { getSubscriptionStatus } from '@/lib/subscription/helpers'
1717
import { getBaseUrl } from '@/lib/urls/utils'
1818
import { cn } from '@/lib/utils'
19-
import { organizationKeys, useOrganizations } from '@/hooks/queries/organization'
20-
import { subscriptionKeys, useSubscriptionData } from '@/hooks/queries/subscription'
19+
import { useOrganizationStore } from '@/stores/organization'
20+
import { useSubscriptionStore } from '@/stores/subscription/store'
2121

2222
const logger = createLogger('CancelSubscription')
2323

@@ -40,11 +40,9 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
4040

4141
const { data: session } = useSession()
4242
const betterAuthSubscription = useSubscription()
43-
const { data: orgsData } = useOrganizations()
44-
const { data: subData } = useSubscriptionData()
45-
const queryClient = useQueryClient()
46-
const activeOrganization = orgsData?.activeOrganization
47-
const currentSubscriptionStatus = getSubscriptionStatus(subData?.data)
43+
const { activeOrganization, loadOrganizationSubscription, refreshOrganization } =
44+
useOrganizationStore()
45+
const { getSubscriptionStatus, refresh } = useSubscriptionStore()
4846

4947
// Clear error after 3 seconds
5048
useEffect(() => {
@@ -68,7 +66,7 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
6866
setError(null)
6967

7068
try {
71-
const subscriptionStatus = currentSubscriptionStatus
69+
const subscriptionStatus = getSubscriptionStatus()
7270
const activeOrgId = activeOrganization?.id
7371

7472
let referenceId = session.user.id
@@ -77,7 +75,8 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
7775
if (subscriptionStatus.isTeam && activeOrgId) {
7876
referenceId = activeOrgId
7977
// Get subscription ID for team/enterprise
80-
subscriptionId = subData?.data?.id
78+
const orgSubscription = useOrganizationStore.getState().subscriptionData
79+
subscriptionId = orgSubscription?.id
8180
}
8281

8382
logger.info('Canceling subscription', {
@@ -125,7 +124,7 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
125124
setError(null)
126125

127126
try {
128-
const subscriptionStatus = currentSubscriptionStatus
127+
const subscriptionStatus = getSubscriptionStatus()
129128
const activeOrgId = activeOrganization?.id
130129

131130
if (isCancelAtPeriodEnd) {
@@ -137,8 +136,9 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
137136
let subscriptionId: string | undefined
138137

139138
if ((subscriptionStatus.isTeam || subscriptionStatus.isEnterprise) && activeOrgId) {
139+
const orgSubscription = useOrganizationStore.getState().subscriptionData
140140
referenceId = activeOrgId
141-
subscriptionId = subData?.data?.id
141+
subscriptionId = orgSubscription?.id
142142
} else {
143143
// For personal subscriptions, use user ID and let better-auth find the subscription
144144
referenceId = session.user.id
@@ -158,12 +158,10 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
158158
logger.info('Subscription restored successfully', result)
159159
}
160160

161-
// Invalidate queries to refresh data
162-
await queryClient.invalidateQueries({ queryKey: subscriptionKeys.user() })
161+
await refresh()
163162
if (activeOrgId) {
164-
await queryClient.invalidateQueries({ queryKey: organizationKeys.detail(activeOrgId) })
165-
await queryClient.invalidateQueries({ queryKey: organizationKeys.billing(activeOrgId) })
166-
await queryClient.invalidateQueries({ queryKey: organizationKeys.lists() })
163+
await loadOrganizationSubscription(activeOrgId)
164+
await refreshOrganization().catch(() => {})
167165
}
168166

169167
setIsDialogOpen(false)
@@ -225,33 +223,37 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
225223
onClick={() => setIsDialogOpen(true)}
226224
disabled={isLoading}
227225
className={cn(
228-
'h-8 rounded-[8px] font-medium text-xs',
229-
error && 'border-red-500 text-red-500 dark:border-red-500 dark:text-red-500'
226+
'h-8 rounded-[8px] font-medium text-xs transition-all duration-200',
227+
error
228+
? 'border-red-500 text-red-500 dark:border-red-500 dark:text-red-500'
229+
: isCancelAtPeriodEnd
230+
? 'text-muted-foreground hover:border-green-500 hover:bg-green-500 hover:text-white dark:hover:border-green-500 dark:hover:bg-green-500'
231+
: 'text-muted-foreground hover:border-red-500 hover:bg-red-500 hover:text-white dark:hover:border-red-500 dark:hover:bg-red-500'
230232
)}
231233
>
232234
{error ? 'Error' : isCancelAtPeriodEnd ? 'Restore' : 'Manage'}
233235
</Button>
234236
</div>
235237

236-
<Modal open={isDialogOpen} onOpenChange={setIsDialogOpen}>
237-
<ModalContent>
238-
<ModalHeader>
239-
<ModalTitle>
238+
<AlertDialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
239+
<AlertDialogContent>
240+
<AlertDialogHeader>
241+
<AlertDialogTitle>
240242
{isCancelAtPeriodEnd ? 'Restore' : 'Cancel'} {subscription.plan} subscription?
241-
</ModalTitle>
242-
<ModalDescription>
243+
</AlertDialogTitle>
244+
<AlertDialogDescription>
243245
{isCancelAtPeriodEnd
244246
? 'Your subscription is set to cancel at the end of the billing period. Would you like to keep your subscription active?'
245247
: `You'll be redirected to Stripe to manage your subscription. You'll keep access until ${formatDate(
246248
periodEndDate
247249
)}, then downgrade to free plan.`}{' '}
248250
{!isCancelAtPeriodEnd && (
249-
<span className='text-[var(--text-error)] dark:text-[var(--text-error)]'>
251+
<span className='text-red-500 dark:text-red-500'>
250252
This action cannot be undone.
251253
</span>
252254
)}
253-
</ModalDescription>
254-
</ModalHeader>
255+
</AlertDialogDescription>
256+
</AlertDialogHeader>
255257

256258
{!isCancelAtPeriodEnd && (
257259
<div className='py-2'>
@@ -266,42 +268,41 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
266268
</div>
267269
)}
268270

269-
<ModalFooter>
270-
<Button
271-
variant='outline'
272-
className='h-[32px] px-[12px]'
271+
<AlertDialogFooter className='flex'>
272+
<AlertDialogCancel
273+
className='h-9 w-full rounded-[8px]'
273274
onClick={isCancelAtPeriodEnd ? () => setIsDialogOpen(false) : handleKeep}
274275
disabled={isLoading}
275276
>
276277
{isCancelAtPeriodEnd ? 'Cancel' : 'Keep Subscription'}
277-
</Button>
278+
</AlertDialogCancel>
278279

279280
{(() => {
280-
const subscriptionStatus = currentSubscriptionStatus
281+
const subscriptionStatus = getSubscriptionStatus()
281282
if (subscriptionStatus.isPaid && isCancelAtPeriodEnd) {
282283
return (
283-
<Button
284+
<AlertDialogAction
284285
onClick={handleKeep}
285-
className='h-[32px] bg-green-500 px-[12px] text-white hover:bg-green-600 dark:bg-green-500 dark:hover:bg-green-600'
286+
className='h-9 w-full rounded-[8px] bg-green-500 text-white transition-all duration-200 hover:bg-green-600 dark:bg-green-500 dark:hover:bg-green-600'
286287
disabled={isLoading}
287288
>
288289
{isLoading ? 'Restoring...' : 'Restore Subscription'}
289-
</Button>
290+
</AlertDialogAction>
290291
)
291292
}
292293
return (
293-
<Button
294+
<AlertDialogAction
294295
onClick={handleCancel}
295-
className='h-[32px] bg-[var(--text-error)] px-[12px] text-[var(--white)] hover:bg-[var(--text-error)] hover:text-[var(--white)] dark:bg-[var(--text-error)] dark:text-[var(--white)] hover:dark:bg-[var(--text-error)] dark:hover:text-[var(--white)]'
296+
className='h-9 w-full rounded-[8px] bg-red-500 text-white transition-all duration-200 hover:bg-red-600 dark:bg-red-500 dark:hover:bg-red-600'
296297
disabled={isLoading}
297298
>
298299
{isLoading ? 'Redirecting...' : 'Continue'}
299-
</Button>
300+
</AlertDialogAction>
300301
)
301302
})()}
302-
</ModalFooter>
303-
</ModalContent>
304-
</Modal>
303+
</AlertDialogFooter>
304+
</AlertDialogContent>
305+
</AlertDialog>
305306
</>
306307
)
307308
}

0 commit comments

Comments
 (0)