Feature/align pricing page with subscription model (#135)

* Align pricing page with subscription model

* Update changelog
pull/130/head
Thomas 4 years ago
parent fbd9392b8c
commit 6062bdbeab

@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Moved the tools to a sub path (`/tools`)
- Extended the pricing page
- Extended the pricing page and aligned with the subscription model
## 1.9.0 - 01.06.2021

@ -4,9 +4,10 @@ import { locale } from '@ghostfolio/common/config';
import { resetHours } from '@ghostfolio/common/helper';
import { User as IUser, UserWithSettings } from '@ghostfolio/common/interfaces';
import { getPermissions, permissions } from '@ghostfolio/common/permissions';
import { SubscriptionType } from '@ghostfolio/common/types/subscription.type';
import { Injectable } from '@nestjs/common';
import { Currency, Prisma, Provider, User, ViewMode } from '@prisma/client';
import { add } from 'date-fns';
import { add, isBefore } from 'date-fns';
const crypto = require('crypto');
@ -24,7 +25,8 @@ export class UserService {
alias,
id,
role,
Settings
Settings,
subscription
}: UserWithSettings): Promise<IUser> {
const access = await this.prisma.access.findMany({
include: {
@ -43,6 +45,7 @@ export class UserService {
return {
alias,
id,
subscription,
access: access.map((accessItem) => {
return {
alias: accessItem.User.alias,
@ -54,11 +57,7 @@ export class UserService {
settings: {
locale,
baseCurrency: Settings?.currency ?? UserService.DEFAULT_CURRENCY,
viewMode: Settings.viewMode ?? ViewMode.DEFAULT
},
subscription: {
expiresAt: resetHours(add(new Date(), { days: 7 })),
type: 'Premium'
viewMode: Settings?.viewMode ?? ViewMode.DEFAULT
}
};
}
@ -66,26 +65,49 @@ export class UserService {
public async user(
userWhereUniqueInput: Prisma.UserWhereUniqueInput
): Promise<UserWithSettings | null> {
const user = await this.prisma.user.findUnique({
include: { Account: true, Settings: true },
const userFromDatabase = await this.prisma.user.findUnique({
include: { Account: true, Settings: true, Subscription: true },
where: userWhereUniqueInput
});
if (user?.Settings) {
if (!user.Settings.currency) {
const user: UserWithSettings = userFromDatabase;
if (userFromDatabase?.Settings) {
if (!userFromDatabase.Settings.currency) {
// Set default currency if needed
user.Settings.currency = UserService.DEFAULT_CURRENCY;
userFromDatabase.Settings.currency = UserService.DEFAULT_CURRENCY;
}
} else if (user) {
} else if (userFromDatabase) {
// Set default settings if needed
user.Settings = {
userFromDatabase.Settings = {
currency: UserService.DEFAULT_CURRENCY,
updatedAt: new Date(),
userId: user?.id,
userId: userFromDatabase?.id,
viewMode: ViewMode.DEFAULT
};
}
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
if (userFromDatabase?.Subscription?.length > 0) {
const latestSubscription = userFromDatabase.Subscription.reduce(
(a, b) => {
return new Date(a.expiresAt) > new Date(b.expiresAt) ? a : b;
}
);
user.subscription = {
expiresAt: latestSubscription.expiresAt,
type: isBefore(new Date(), latestSubscription.expiresAt)
? SubscriptionType.Premium
: SubscriptionType.Basic
};
} else {
user.subscription = {
type: SubscriptionType.Basic
};
}
}
return user;
}

@ -18,7 +18,6 @@ export class AccountPageComponent implements OnDestroy, OnInit {
public baseCurrency: Currency;
public currencies: Currency[] = [];
public defaultDateFormat = DEFAULT_DATE_FORMAT;
public hasPermissionForSubscription: boolean;
public hasPermissionToUpdateUserSettings: boolean;
public user: User;
@ -35,13 +34,8 @@ export class AccountPageComponent implements OnDestroy, OnInit {
this.dataService
.fetchInfo()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ currencies, globalPermissions }) => {
.subscribe(({ currencies }) => {
this.currencies = currencies;
this.hasPermissionForSubscription = hasPermission(
globalPermissions,
permissions.enableSubscription
);
});
this.userService.stateChanged

@ -15,13 +15,13 @@
<div class="w-50" i18n>Alias</div>
<div class="w-50">{{ user.alias }}</div>
</div>
<div *ngIf="hasPermissionForSubscription" class="d-flex py-1">
<div *ngIf="user?.subscription" class="d-flex py-1">
<div class="w-50" i18n>Membership</div>
<div class="w-50">
<div class="align-items-center d-flex mb-1">
{{ user?.subscription?.type }}
{{ user.subscription.type }}
</div>
<div>
<div *ngIf="user.subscription.expiresAt">
Valid until {{ user.subscription.expiresAt | date:
defaultDateFormat }}
</div>

@ -1,6 +1,11 @@
import { SubscriptionType } from '@ghostfolio/common/types/subscription.type';
import { Account, Settings, User } from '@prisma/client';
export type UserWithSettings = User & {
Account: Account[];
Settings: Settings;
subscription?: {
expiresAt?: Date;
type: SubscriptionType;
};
};

@ -0,0 +1,4 @@
export enum SubscriptionType {
Basic = 'Basic',
Premium = 'Premium'
}

@ -99,21 +99,33 @@ model Settings {
userId String @id
}
model Subscription {
createdAt DateTime @default(now())
expiresAt DateTime
id String @default(uuid())
updatedAt DateTime @updatedAt
User User @relation(fields: [userId], references: [id])
userId String
@@id([id, userId])
}
model User {
Access Access[] @relation("accessGet")
AccessGive Access[] @relation(name: "accessGive")
Access Access[] @relation("accessGet")
AccessGive Access[] @relation(name: "accessGive")
accessToken String?
Account Account[]
alias String?
Analytics Analytics?
createdAt DateTime @default(now())
id String @id @default(uuid())
createdAt DateTime @default(now())
id String @id @default(uuid())
Order Order[]
provider Provider?
role Role @default(USER)
role Role @default(USER)
Settings Settings?
Subscription Subscription[]
thirdPartyId String?
updatedAt DateTime @updatedAt
updatedAt DateTime @updatedAt
}
enum AccountType {

Loading…
Cancel
Save