@@ -4,7 +4,7 @@ import { useState } from 'react'
44import { AuthField , AuthFormMessage , AuthSelect , AuthTag } from '@sim/auth-ui'
55import { useRouter } from 'next/navigation'
66import type { AwsMarketplaceClaim } from '@/lib/api/contracts/aws-marketplace'
7- import { client , useSession } from '@/lib/auth/client'
7+ import { useSession } from '@/lib/auth/client'
88import {
99 AWS_MARKETPLACE_ONBOARDING_PATH ,
1010 type AwsMarketplaceOnboardingError ,
@@ -15,6 +15,7 @@ import { InviteLayout, InviteStatusCard } from '@/app/invite/components'
1515import {
1616 useAwsMarketplaceClaim ,
1717 useLinkAwsMarketplaceLicense ,
18+ useRegisterAwsMarketplaceLicenseToAccount ,
1819} from '@/hooks/queries/aws-marketplace'
1920
2021const RESTART_FROM_AWS =
@@ -64,6 +65,7 @@ export function AwsMarketplaceOnboarding({
6465 const viewerId = session ?. user ?. id ?? null
6566 const claimQuery = useAwsMarketplaceClaim ( registrationError ? null : viewerId )
6667 const linkLicense = useLinkAwsMarketplaceLicense ( )
68+ const registerToAccount = useRegisterAwsMarketplaceLicenseToAccount ( )
6769 const returnHome = { label : 'Return to Home' , onClick : ( ) => router . push ( '/' ) }
6870
6971 if ( registrationError ) {
@@ -122,6 +124,19 @@ export function AwsMarketplaceOnboarding({
122124 )
123125 }
124126
127+ if ( registerToAccount . isSuccess ) {
128+ return (
129+ < InviteLayout >
130+ < InviteStatusCard
131+ type = 'success'
132+ title = 'Subscription registered'
133+ description = 'Our team will set up your Enterprise workspace and email you when it is ready.'
134+ actions = { [ { label : 'Go to Sim' , onClick : ( ) => router . push ( APP_ENTRY_PATH ) } ] }
135+ />
136+ </ InviteLayout >
137+ )
138+ }
139+
125140 if ( claimQuery . isPending ) {
126141 return (
127142 < InviteLayout >
@@ -157,50 +172,52 @@ export function AwsMarketplaceOnboarding({
157172 )
158173 }
159174
160- if ( claim . organizations . length === 0 ) {
161- return (
162- < InviteLayout >
163- < InviteStatusCard
164- type = 'warning'
165- title = 'No organization to link'
166- description = 'Only an owner or admin of a Sim organization can link this subscription. Sign in with that account in this browser.'
167- actions = { [
168- {
169- label : 'Sign in with a different account' ,
170- onClick : async ( ) => {
171- await client . signOut ( )
172- router . push ( authLink ( '/login' ) )
173- } ,
174- } ,
175- returnHome ,
176- ] }
177- />
178- </ InviteLayout >
179- )
180- }
181-
175+ const pending = linkLicense . isPending || registerToAccount . isPending
182176 return (
183177 < LinkLicenseCard
184178 claim = { claim }
179+ pending = { pending }
185180 linking = { linkLicense . isPending }
186- error = { linkLicense . error ?. message ?? null }
187- onLink = { ( organizationId ) =>
181+ registering = { registerToAccount . isPending }
182+ error = { ( linkLicense . error ?? registerToAccount . error ) ?. message ?? null }
183+ onLink = { ( organizationId ) => {
184+ registerToAccount . reset ( )
188185 linkLicense . mutate ( { licenseId : claim . license . id , organizationId } )
189- }
186+ } }
187+ onRegister = { ( ) => {
188+ linkLicense . reset ( )
189+ registerToAccount . mutate ( { licenseId : claim . license . id } )
190+ } }
190191 onCancel = { returnHome . onClick }
191192 />
192193 )
193194}
194195
195196interface LinkLicenseCardProps {
196197 claim : Extract < AwsMarketplaceClaim , { status : 'ready' } >
198+ pending : boolean
197199 linking : boolean
200+ registering : boolean
198201 error : string | null
199202 onLink : ( organizationId : string ) => void
203+ onRegister : ( ) => void
200204 onCancel : ( ) => void
201205}
202206
203- function LinkLicenseCard ( { claim, linking, error, onLink, onCancel } : LinkLicenseCardProps ) {
207+ /**
208+ * Links the license to an organization the viewer administers, or registers it to their
209+ * account when they administer none or would rather not pick one.
210+ */
211+ function LinkLicenseCard ( {
212+ claim,
213+ pending,
214+ linking,
215+ registering,
216+ error,
217+ onLink,
218+ onRegister,
219+ onCancel,
220+ } : LinkLicenseCardProps ) {
204221 const { license, organizations } = claim
205222 const [ selectedOrganizationId , setSelectedOrganizationId ] = useState < string > ( )
206223 const linkedOrganization = organizations . find ( ( org ) => org . id === license . organizationId )
@@ -218,12 +235,28 @@ function LinkLicenseCard({ claim, linking, error, onLink, onCancel }: LinkLicens
218235 } ,
219236 ]
220237
238+ const hasOrganizations = organizations . length > 0
239+ const registerAction = {
240+ label : hasOrganizations ? 'Register to my account instead' : 'Register to my account' ,
241+ onClick : onRegister ,
242+ disabled : pending ,
243+ loading : registering ,
244+ }
245+
221246 return (
222247 < InviteLayout >
223248 < InviteStatusCard
224249 type = 'invitation'
225- title = 'Link your AWS Marketplace subscription'
226- description = 'Choose the organization this subscription is for. Our team will finish setting up your plan after you link it.'
250+ title = {
251+ hasOrganizations
252+ ? 'Link your AWS Marketplace subscription'
253+ : 'Set up your AWS Marketplace subscription'
254+ }
255+ description = {
256+ hasOrganizations
257+ ? 'Choose the organization this subscription is for, or register it to your account. Our team will finish setting up your plan.'
258+ : 'Register this subscription to your account. Our team will set up your Enterprise workspace and email you.'
259+ }
227260 details = {
228261 < div className = 'au:w-full au:space-y-4' >
229262 < dl className = 'au:w-full au:space-y-2 au:text-sm au:tabular-nums' >
@@ -240,26 +273,33 @@ function LinkLicenseCard({ claim, linking, error, onLink, onCancel }: LinkLicens
240273 </ dd >
241274 </ div >
242275 </ dl >
243- < AuthField htmlFor = 'aws-marketplace-organization' label = 'Organization' >
244- < AuthSelect
245- id = 'aws-marketplace-organization'
246- options = { organizations . map ( ( org ) => ( { label : org . name , value : org . id } ) ) }
247- value = { organizationId }
248- onChange = { setSelectedOrganizationId }
249- placeholder = 'Select an organization'
250- fullWidth
251- />
252- </ AuthField >
276+ { hasOrganizations && (
277+ < AuthField htmlFor = 'aws-marketplace-organization' label = 'Organization' >
278+ < AuthSelect
279+ id = 'aws-marketplace-organization'
280+ options = { organizations . map ( ( org ) => ( { label : org . name , value : org . id } ) ) }
281+ value = { organizationId }
282+ onChange = { setSelectedOrganizationId }
283+ placeholder = 'Select an organization'
284+ fullWidth
285+ />
286+ </ AuthField >
287+ ) }
253288 { error && < AuthFormMessage type = 'error' > { error } </ AuthFormMessage > }
254289 </ div >
255290 }
256291 actions = { [
257- {
258- label : 'Link subscription' ,
259- onClick : ( ) => organizationId && onLink ( organizationId ) ,
260- disabled : ! organizationId || linking ,
261- loading : linking ,
262- } ,
292+ ...( hasOrganizations
293+ ? [
294+ {
295+ label : 'Link subscription' ,
296+ onClick : ( ) => organizationId && onLink ( organizationId ) ,
297+ disabled : ! organizationId || pending ,
298+ loading : linking ,
299+ } ,
300+ ]
301+ : [ ] ) ,
302+ registerAction ,
263303 { label : 'Not now' , onClick : onCancel } ,
264304 ] }
265305 />
0 commit comments