Skip to content

Commit 1b70348

Browse files
fix(billing): keep the upgrade intent through workspace creation
A first-time visitor to /upgrade has no workspace to resolve, so /workspace creates one — and then hardcoded a redirect to home, silently dropping the upgrade intent. Route both exits through one destination helper so the created workspace lands on the plan picker with its reason intact.
1 parent 58d682b commit 1b70348

1 file changed

Lines changed: 19 additions & 21 deletions

File tree

apps/sim/app/workspace/page.tsx

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ export default function WorkspacePage() {
120120

121121
if (isWorkspacesLoading || workspacesError || !data) return
122122

123+
const urlParams = new URLSearchParams(window.location.search)
124+
const redirectWorkflowId = urlParams.get('redirect_workflow')
125+
const redirectTarget = urlParams.get('redirect')
126+
const rawReason = urlParams.get(UPGRADE_REASON_PARAM)
127+
128+
// `?redirect=upgrade` is how a caller that cannot know a workspace id — a
129+
// self-hosted deployment, an email — reaches the plan picker. It has to
130+
// survive workspace creation too: a first-time visitor has no workspace to
131+
// resolve, and dropping the intent lands them on home with no explanation.
132+
const destinationFor = (id: string) =>
133+
redirectTarget === 'upgrade'
134+
? buildUpgradeHref(id, isUpgradeReason(rawReason) ? rawReason : undefined)
135+
: `/workspace/${id}/home`
136+
123137
const { workspaces, lastActiveWorkspaceId, creationPolicy } = data
124138

125139
if (workspaces.length === 0) {
@@ -140,16 +154,12 @@ export default function WorkspacePage() {
140154
return
141155
}
142156
hasRedirectedRef.current = true
143-
handleNoWorkspaces(router, () => setRecoveryFailed(true))
157+
handleNoWorkspaces(router, () => setRecoveryFailed(true), destinationFor)
144158
return
145159
}
146160

147161
hasRedirectedRef.current = true
148162

149-
const urlParams = new URLSearchParams(window.location.search)
150-
const redirectWorkflowId = urlParams.get('redirect_workflow')
151-
const redirectTarget = urlParams.get('redirect')
152-
153163
const localRecentId = WorkspaceRecencyStorage.getMostRecent()
154164
const findWorkspace = (id: string | null) =>
155165
id ? workspaces.find((w) => w.id === id) : undefined
@@ -162,21 +172,8 @@ export default function WorkspacePage() {
162172
return
163173
}
164174

165-
// `?redirect=upgrade` is how a caller that cannot know a workspace id — a
166-
// self-hosted deployment, an email — reaches the plan picker.
167-
if (redirectTarget === 'upgrade') {
168-
const rawReason = urlParams.get(UPGRADE_REASON_PARAM)
169-
const href = buildUpgradeHref(
170-
targetWorkspace.id,
171-
isUpgradeReason(rawReason) ? rawReason : undefined
172-
)
173-
logger.info(`Redirecting to upgrade: ${targetWorkspace.id}`)
174-
router.replace(href)
175-
return
176-
}
177-
178175
logger.info(`Redirecting to workspace: ${targetWorkspace.id}`)
179-
router.replace(`/workspace/${targetWorkspace.id}/home`)
176+
router.replace(destinationFor(targetWorkspace.id))
180177
}, [session, isSessionPending, sessionError, isWorkspacesLoading, workspacesError, data, router])
181178

182179
const blockedPolicy =
@@ -261,7 +258,8 @@ async function handleWorkflowRedirect(
261258

262259
async function handleNoWorkspaces(
263260
router: ReturnType<typeof useRouter>,
264-
onUnrecoverable: () => void
261+
onUnrecoverable: () => void,
262+
destinationFor: (workspaceId: string) => string
265263
): Promise<void> {
266264
logger.warn('No workspaces found, creating default workspace')
267265
try {
@@ -271,7 +269,7 @@ async function handleNoWorkspaces(
271269
if (data.workspace?.id) {
272270
logger.info(`Created default workspace: ${data.workspace.id}`)
273271
sessionStorage.removeItem(WORKSPACE_RACE_RETRY_KEY)
274-
router.replace(`/workspace/${data.workspace.id}/home`)
272+
router.replace(destinationFor(data.workspace.id))
275273
return
276274
}
277275
logger.error('Failed to create default workspace')

0 commit comments

Comments
 (0)