From bfa9cf362394d9327941d688769bceb764d822c6 Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:17:24 +0100 Subject: [PATCH] [PM-15545][Defect] Update trial initiation UI for new flow via trial/send-verification-email endpoint (#12256) * Add the on trial payment option on new UI * Rename variables correctly * Resolve the isTrialPaymentOptional and use observable * use firstValueFrom and remove subscribe * Resolve the selected plantype * Changes for free Org --- .../complete-trial-initiation.component.html | 11 ++- .../complete-trial-initiation.component.ts | 84 ++++++++++++++++++- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html index 9400e512c3..416d400426 100644 --- a/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html +++ b/apps/web/src/app/auth/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html @@ -23,12 +23,17 @@ bitButton buttonType="primary" [disabled]="orgInfoFormGroup.controls.name.invalid" - (click)="conditionallyCreateOrganization()" + [loading]="loading && (trialPaymentOptional$ | async)" + (click)="orgNameEntrySubmit()" > - {{ "next" | i18n }} + {{ (trialPaymentOptional$ | async) ? ("startTrial" | i18n) : ("next" | i18n) }} - + (); protected readonly SubscriptionProduct = SubscriptionProduct; protected readonly ProductType = ProductType; + protected trialPaymentOptional$ = this.configService.getFeatureFlag$( + FeatureFlag.TrialPaymentOptional, + ); constructor( protected router: Router, @@ -90,6 +105,7 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { private registrationFinishService: RegistrationFinishService, private validationService: ValidationService, private loginStrategyService: LoginStrategyServiceAbstraction, + private configService: ConfigService, ) {} async ngOnInit(): Promise { @@ -119,6 +135,7 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { this.product = this.validProducts.includes(product) ? product : ProductType.PasswordManager; const productTierParam = parseInt(qParams.productTier) as ProductTierType; + this.productTierValue = productTierParam; /** Only show the trial stepper for a subset of types */ const showPasswordManagerStepper = this.stepperProductTypes.includes(productTierParam); @@ -185,6 +202,16 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { } } + async orgNameEntrySubmit(): Promise { + const isTrialPaymentOptional = await firstValueFrom(this.trialPaymentOptional$); + + if (isTrialPaymentOptional) { + await this.createOrganizationOnTrial(); + } else { + await this.conditionallyCreateOrganization(); + } + } + /** Update local details from organization created event */ createdOrganization(event: OrganizationCreatedEvent) { this.orgId = event.organizationId; @@ -192,11 +219,62 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { this.verticalStepper.next(); } + /** create an organization on trial without payment method */ + async createOrganizationOnTrial() { + this.loading = true; + let trialInitiationPath: InitiationPath = "Password Manager trial from marketing website"; + let plan: PlanInformation = { + type: this.getPlanType(), + passwordManagerSeats: 1, + }; + + if (this.product === ProductType.SecretsManager) { + trialInitiationPath = "Secrets Manager trial from marketing website"; + plan = { + ...plan, + subscribeToSecretsManager: true, + isFromSecretsManagerTrial: true, + secretsManagerSeats: 1, + }; + } + + const organization: OrganizationInformation = { + name: this.orgInfoFormGroup.value.name, + billingEmail: this.orgInfoFormGroup.value.billingEmail, + initiationPath: trialInitiationPath, + }; + + const response = await this.organizationBillingService.purchaseSubscriptionNoPaymentMethod({ + organization, + plan, + }); + + this.orgId = response?.id; + this.billingSubLabel = response.name.toString(); + this.loading = false; + this.verticalStepper.next(); + } + /** Move the user to the previous step */ previousStep() { this.verticalStepper.previous(); } + getPlanType() { + switch (this.productTier) { + case ProductTierType.Teams: + return PlanType.TeamsAnnually; + case ProductTierType.Enterprise: + return PlanType.EnterpriseAnnually; + case ProductTierType.Families: + return PlanType.FamiliesAnnually; + case ProductTierType.Free: + return PlanType.Free; + default: + return PlanType.EnterpriseAnnually; + } + } + get isSecretsManagerFree() { return this.product === ProductType.SecretsManager && this.productTier === ProductTierType.Free; }