From 7ca88702a9f6eb22847b16662f7a56449780d9ed Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Thu, 9 Jul 2026 22:52:23 +0700 Subject: [PATCH] Task/improve type safety in user account membership component (#7286) * fix(client): resolve type errors * feat(client): enforce encapsulation * fix(client): remove unused variable * feat(client): enforce immutability * feat(client): replace constructor based DI with inject functions --- .../user-account-membership.component.ts | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts index bdf2c3eb6..74ee2f64a 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts @@ -3,7 +3,6 @@ import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { getDateFormatString } from '@ghostfolio/common/helper'; import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card'; import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; @@ -14,7 +13,8 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - DestroyRef + DestroyRef, + inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; @@ -40,29 +40,29 @@ import { catchError } from 'rxjs/operators'; templateUrl: './user-account-membership.html' }) export class GfUserAccountMembershipComponent { - public baseCurrency: string; - public coupon: number; - public couponId: string; - public defaultDateFormat: string; - public durationExtension: StringValue; - public hasPermissionForSubscription: boolean; - public hasPermissionToCreateApiKey: boolean; - public hasPermissionToUpdateUserSettings: boolean; - public price: number; - public priceId: string; - public routerLinkPricing = publicRoutes.pricing.routerLink; - public trySubscriptionMail = + protected readonly baseCurrency: string; + protected coupon: number | undefined; + protected defaultDateFormat: string; + protected durationExtension: StringValue | undefined; + protected readonly hasPermissionForSubscription: boolean; + protected hasPermissionToCreateApiKey: boolean; + protected hasPermissionToUpdateUserSettings: boolean; + protected price: number; + protected readonly trySubscriptionMail = 'mailto:hi@ghostfol.io?subject=Ghostfolio Premium Trial&body=Hello%0D%0DI am interested in Ghostfolio Premium. Can you please send me a coupon code to try it for some time?%0D%0DKind regards'; - public user: User; - - public constructor( - private changeDetectorRef: ChangeDetectorRef, - private dataService: DataService, - private destroyRef: DestroyRef, - private notificationService: NotificationService, - private snackBar: MatSnackBar, - private userService: UserService - ) { + protected user: User; + + private couponId: string | undefined; + private priceId: string; + + private readonly changeDetectorRef = inject(ChangeDetectorRef); + private readonly dataService = inject(DataService); + private readonly destroyRef = inject(DestroyRef); + private readonly notificationService = inject(NotificationService); + private readonly snackBar = inject(MatSnackBar); + private readonly userService = inject(UserService); + + public constructor() { const { baseCurrency, globalPermissions } = this.dataService.fetchInfo(); this.baseCurrency = baseCurrency; @@ -104,7 +104,7 @@ export class GfUserAccountMembershipComponent { }); } - public onCheckout() { + protected onCheckout() { this.dataService .createStripeCheckoutSession({ couponId: this.couponId, @@ -125,7 +125,7 @@ export class GfUserAccountMembershipComponent { }); } - public onGenerateApiKey() { + protected onGenerateApiKey() { this.notificationService.confirm({ confirmFn: () => { this.dataService @@ -158,7 +158,7 @@ export class GfUserAccountMembershipComponent { }); } - public onRedeemCoupon() { + protected onRedeemCoupon() { this.notificationService.prompt({ confirmFn: (value) => { const couponCode = value?.trim();