mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
12 changed files with 258 additions and 144 deletions
@ -0,0 +1,12 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { RouterModule, Routes } from '@angular/router'; |
||||
|
|
||||
|
import { PricingPageComponent } from './pricing-page.component'; |
||||
|
|
||||
|
const routes: Routes = [{ path: '', component: PricingPageComponent }]; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [RouterModule.forChild(routes)], |
||||
|
exports: [RouterModule] |
||||
|
}) |
||||
|
export class PricingPageRoutingModule {} |
@ -0,0 +1,53 @@ |
|||||
|
import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; |
||||
|
import { baseCurrency } from '@ghostfolio/helper'; |
||||
|
import { Subject } from 'rxjs'; |
||||
|
import { User } from '@ghostfolio/api/app/user/interfaces/user.interface'; |
||||
|
import { takeUntil } from 'rxjs/operators'; |
||||
|
import { DataService } from '@ghostfolio/client/services/data.service'; |
||||
|
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'gf-pricing-page', |
||||
|
templateUrl: './pricing-page.html', |
||||
|
styleUrls: ['./pricing-page.scss'] |
||||
|
}) |
||||
|
export class PricingPageComponent implements OnInit { |
||||
|
public baseCurrency = baseCurrency; |
||||
|
public isLoggedIn: boolean; |
||||
|
public user: User; |
||||
|
|
||||
|
private unsubscribeSubject = new Subject<void>(); |
||||
|
|
||||
|
/** |
||||
|
* @constructor |
||||
|
*/ |
||||
|
public constructor( |
||||
|
private cd: ChangeDetectorRef, |
||||
|
private dataService: DataService, |
||||
|
private tokenStorageService: TokenStorageService |
||||
|
) {} |
||||
|
|
||||
|
/** |
||||
|
* Initializes the controller |
||||
|
*/ |
||||
|
public ngOnInit() { |
||||
|
this.isLoggedIn = !!this.tokenStorageService.getToken(); |
||||
|
|
||||
|
if (this.isLoggedIn) |
||||
|
this.tokenStorageService |
||||
|
.onChangeHasToken() |
||||
|
.pipe(takeUntil(this.unsubscribeSubject)) |
||||
|
.subscribe(() => { |
||||
|
this.dataService.fetchUser().subscribe((user) => { |
||||
|
this.user = user; |
||||
|
|
||||
|
this.cd.markForCheck(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.unsubscribeSubject.next(); |
||||
|
this.unsubscribeSubject.complete(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,102 @@ |
|||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col"> |
||||
|
<h3 class="d-flex justify-content-center mb-3" i18n>Pricing Plans</h3> |
||||
|
<div class="row"> |
||||
|
<div class="col-xs-12 col-md-6"> |
||||
|
<mat-card class="mb-3"> |
||||
|
<h4 i18n>Open Source</h4> |
||||
|
<p>Host your <strong>Ghostfolio</strong> instance by yourself.</p> |
||||
|
<ul class="list-unstyled mb-3"> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Portfolio Performance</span> |
||||
|
</li> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Portfolio Summary</span> |
||||
|
</li> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Unlimited Transactions</span> |
||||
|
</li> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Advanced Insights</span> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<p class="h5 text-right"> |
||||
|
<span>Free</span> |
||||
|
</p> |
||||
|
</mat-card> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6"> |
||||
|
<mat-card |
||||
|
class="mb-3" |
||||
|
[ngClass]="{ 'active': user?.subscription?.type === 'Trial' }" |
||||
|
> |
||||
|
<h4 class="align-items-center d-flex" i18n> |
||||
|
Diamond |
||||
|
<ion-icon |
||||
|
class="ml-1 text-muted" |
||||
|
name="diamond-outline" |
||||
|
></ion-icon> |
||||
|
</h4> |
||||
|
<p> |
||||
|
Get a fully managed <strong>Ghostfolio</strong> cloud offering. |
||||
|
</p> |
||||
|
<ul class="list-unstyled mb-3"> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Portfolio Performance</span> |
||||
|
</li> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Portfolio Summary</span> |
||||
|
</li> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Unlimited Transactions</span> |
||||
|
</li> |
||||
|
<li class="align-items-center d-flex mb-1"> |
||||
|
<ion-icon |
||||
|
class="mr-1 text-muted" |
||||
|
name="checkmark-circle-outline" |
||||
|
></ion-icon> |
||||
|
<span>Advanced Insights</span> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<p class="h5 text-right"> |
||||
|
<span class="font-weight-normal" |
||||
|
>{{ user?.settings.baseCurrency || baseCurrency }} |
||||
|
<strong>2.99</strong> |
||||
|
<del class="ml-1 text-muted">3.99</del> / Month</span |
||||
|
> |
||||
|
</p> |
||||
|
</mat-card> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,15 @@ |
|||||
|
import { CommonModule } from '@angular/common'; |
||||
|
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
||||
|
import { MatCardModule } from '@angular/material/card'; |
||||
|
|
||||
|
import { PricingPageRoutingModule } from './pricing-page-routing.module'; |
||||
|
import { PricingPageComponent } from './pricing-page.component'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [PricingPageComponent], |
||||
|
exports: [], |
||||
|
imports: [CommonModule, MatCardModule, PricingPageRoutingModule], |
||||
|
providers: [], |
||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA] |
||||
|
}) |
||||
|
export class PricingPageModule {} |
@ -0,0 +1,14 @@ |
|||||
|
:host { |
||||
|
color: rgb(var(--dark-primary-text)); |
||||
|
display: block; |
||||
|
|
||||
|
.mat-card { |
||||
|
&.active { |
||||
|
border-color: rgba(var(--palette-primary-500), 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
:host-context(.is-dark-theme) { |
||||
|
color: rgb(var(--light-primary-text)); |
||||
|
} |
Loading…
Reference in new issue