mirror of
https://github.com/bitwarden/browser
synced 2026-02-20 03:13:55 +00:00
[PM-30908]Correct Premium subscription status handling (#18475)
* Implement the required changes * Fix the family plan creation for expired sub * Resolve the pr comments * resolve the resubscribe issue * Removed redirectOnCompletion: true from the resubscribe * Display the Change payment method dialog on the subscription page * adjust the page reload time * revert payment method open in subscription page * Enable cancel premium see the subscription page * Revert the removal of hasPremiumPersonally * remove extra space * Add can view subscription * Use the canViewSubscription * Resolve the tab default to premium * use the subscription Instead of hasPremium * Revert the changes on user-subscription * Use the flag to redirect to subscription page * revert the canViewSubscription change * resolve the route issue with premium * Change the path to * Revert the previous iteration changes * Fix the build error
This commit is contained in:
committed by
jaasen-livefront
parent
b801f1c710
commit
a377312759
@@ -4,6 +4,8 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||
import { BitwardenSubscriptionResponse } from "@bitwarden/common/billing/models/response/bitwarden-subscription.response";
|
||||
import { SubscriptionCadence } from "@bitwarden/common/billing/types/subscription-pricing-tier";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { Maybe } from "@bitwarden/pricing";
|
||||
import { BitwardenSubscription } from "@bitwarden/subscription";
|
||||
|
||||
import {
|
||||
@@ -23,11 +25,18 @@ export class AccountBillingClient {
|
||||
return this.apiService.send("GET", path, null, true, true);
|
||||
};
|
||||
|
||||
getSubscription = async (): Promise<BitwardenSubscription> => {
|
||||
getSubscription = async (): Promise<Maybe<BitwardenSubscription>> => {
|
||||
const path = `${this.endpoint}/subscription`;
|
||||
const json = await this.apiService.send("GET", path, null, true, true);
|
||||
const response = new BitwardenSubscriptionResponse(json);
|
||||
return response.toDomain();
|
||||
try {
|
||||
const json = await this.apiService.send("GET", path, null, true, true);
|
||||
const response = new BitwardenSubscriptionResponse(json);
|
||||
return response.toDomain();
|
||||
} catch (error: any) {
|
||||
if (error instanceof ErrorResponse && error.statusCode === 404) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
purchaseSubscription = async (
|
||||
|
||||
@@ -19,7 +19,7 @@ const routes: Routes = [
|
||||
component: SubscriptionComponent,
|
||||
data: { titleId: "subscription" },
|
||||
children: [
|
||||
{ path: "", pathMatch: "full", redirectTo: "premium" },
|
||||
{ path: "", pathMatch: "full", redirectTo: "user-subscription" },
|
||||
...featureFlaggedRoute({
|
||||
defaultComponent: UserSubscriptionComponent,
|
||||
flaggedComponent: AccountSubscriptionComponent,
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Observable, switchMap } from "rxjs";
|
||||
import { combineLatest, from, map, Observable, switchMap } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
import { AccountBillingClient } from "../clients/account-billing.client";
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
templateUrl: "subscription.component.html",
|
||||
standalone: false,
|
||||
providers: [AccountBillingClient],
|
||||
})
|
||||
export class SubscriptionComponent implements OnInit {
|
||||
hasPremium$: Observable<boolean>;
|
||||
@@ -21,9 +26,21 @@ export class SubscriptionComponent implements OnInit {
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||
accountService: AccountService,
|
||||
configService: ConfigService,
|
||||
private accountBillingClient: AccountBillingClient,
|
||||
) {
|
||||
this.hasPremium$ = accountService.activeAccount$.pipe(
|
||||
switchMap((account) => billingAccountProfileStateService.hasPremiumPersonally$(account.id)),
|
||||
this.hasPremium$ = combineLatest([
|
||||
configService.getFeatureFlag$(FeatureFlag.PM29594_UpdateIndividualSubscriptionPage),
|
||||
accountService.activeAccount$,
|
||||
]).pipe(
|
||||
switchMap(([isFeatureFlagEnabled, account]) => {
|
||||
if (isFeatureFlagEnabled) {
|
||||
return from(accountBillingClient.getSubscription()).pipe(
|
||||
map((subscription) => !!subscription),
|
||||
);
|
||||
}
|
||||
return billingAccountProfileStateService.hasPremiumPersonally$(account.id);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ import {
|
||||
AdjustAccountSubscriptionStorageDialogComponent,
|
||||
AdjustAccountSubscriptionStorageDialogParams,
|
||||
} from "@bitwarden/web-vault/app/billing/individual/subscription/adjust-account-subscription-storage-dialog.component";
|
||||
import {
|
||||
UnifiedUpgradeDialogComponent,
|
||||
UnifiedUpgradeDialogStatus,
|
||||
UnifiedUpgradeDialogStep,
|
||||
} from "@bitwarden/web-vault/app/billing/individual/upgrade/unified-upgrade-dialog/unified-upgrade-dialog.component";
|
||||
import {
|
||||
OffboardingSurveyDialogResultType,
|
||||
openOffboardingSurvey,
|
||||
@@ -93,10 +98,11 @@ export class AccountSubscriptionComponent {
|
||||
if (!this.account()) {
|
||||
return await redirectToPremiumPage();
|
||||
}
|
||||
if (!this.hasPremiumPersonally()) {
|
||||
const subscription = await this.accountBillingClient.getSubscription();
|
||||
if (!subscription) {
|
||||
return await redirectToPremiumPage();
|
||||
}
|
||||
return await this.accountBillingClient.getSubscription();
|
||||
return subscription;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -106,6 +112,7 @@ export class AccountSubscriptionComponent {
|
||||
const subscription = this.subscription.value();
|
||||
if (subscription) {
|
||||
return (
|
||||
subscription.status === SubscriptionStatuses.Incomplete ||
|
||||
subscription.status === SubscriptionStatuses.IncompleteExpired ||
|
||||
subscription.status === SubscriptionStatuses.Canceled ||
|
||||
subscription.status === SubscriptionStatuses.Unpaid
|
||||
@@ -230,6 +237,27 @@ export class AccountSubscriptionComponent {
|
||||
case SubscriptionCardActions.UpdatePayment:
|
||||
await this.router.navigate(["../payment-details"], { relativeTo: this.activatedRoute });
|
||||
break;
|
||||
case SubscriptionCardActions.Resubscribe: {
|
||||
const account = this.account();
|
||||
if (!account) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dialogRef = UnifiedUpgradeDialogComponent.open(this.dialogService, {
|
||||
data: {
|
||||
account,
|
||||
initialStep: UnifiedUpgradeDialogStep.Payment,
|
||||
selectedPlan: PersonalSubscriptionPricingTierIds.Premium,
|
||||
},
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(dialogRef.closed);
|
||||
|
||||
if (result?.status === UnifiedUpgradeDialogStatus.UpgradedToPremium) {
|
||||
this.subscription.reload();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SubscriptionCardActions.UpgradePlan:
|
||||
await this.openUpgradeDialog();
|
||||
break;
|
||||
|
||||
@@ -3338,6 +3338,15 @@
|
||||
"reinstated": {
|
||||
"message": "The subscription has been reinstated."
|
||||
},
|
||||
"resubscribe": {
|
||||
"message": "Resubscribe"
|
||||
},
|
||||
"yourSubscriptionIsExpired": {
|
||||
"message": "Your subscription is expired"
|
||||
},
|
||||
"yourSubscriptionIsCanceled": {
|
||||
"message": "Your subscription is canceled"
|
||||
},
|
||||
"cancelConfirmation": {
|
||||
"message": "Are you sure you want to cancel? You will lose access to all of this subscription's features at the end of this billing cycle."
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user