Feature/refactor demo account as route (#1058)
* Refactor demo account as route * Update changelog
This commit is contained in:
parent
c6b9e0aa5b
commit
35e039748f
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
|
||||
- Improved the label of the (symbol) search
|
||||
- Refactored the demo account as a route (`/demo`)
|
||||
- Upgraded `nestjs` from version `8.2.3` to `8.4.7`
|
||||
- Upgraded `prisma` from version `3.14.0` to `3.15.2`
|
||||
- Upgraded `yahoo-finance2` from version `2.3.2` to `2.3.3`
|
||||
|
@ -59,6 +59,11 @@ const routes: Routes = [
|
||||
'./pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.module'
|
||||
).then((m) => m.HalloGhostfolioPageModule)
|
||||
},
|
||||
{
|
||||
path: 'demo',
|
||||
loadChildren: () =>
|
||||
import('./pages/demo/demo-page.module').then((m) => m.DemoPageModule)
|
||||
},
|
||||
{
|
||||
path: 'en/blog/2021/07/hello-ghostfolio',
|
||||
loadChildren: () =>
|
||||
|
@ -5,13 +5,12 @@ import {
|
||||
Router,
|
||||
RouterStateSnapshot
|
||||
} from '@angular/router';
|
||||
import { SettingsStorageService } from '@ghostfolio/client/services/settings-storage.service';
|
||||
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
||||
import { ViewMode } from '@prisma/client';
|
||||
import { EMPTY } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
import { SettingsStorageService } from '../services/settings-storage.service';
|
||||
import { UserService } from '../services/user/user.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthGuard implements CanActivate {
|
||||
private static PUBLIC_PAGE_ROUTES = [
|
||||
@ -20,6 +19,7 @@ export class AuthGuard implements CanActivate {
|
||||
'/about/privacy-policy',
|
||||
'/blog',
|
||||
'/de/blog',
|
||||
'/demo',
|
||||
'/en/blog',
|
||||
'/features',
|
||||
'/p',
|
||||
@ -35,11 +35,10 @@ export class AuthGuard implements CanActivate {
|
||||
) {}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
if (route.queryParams?.utm_source) {
|
||||
this.settingsStorageService.setSetting(
|
||||
'utm_source',
|
||||
route.queryParams?.utm_source
|
||||
);
|
||||
const utmSource = route.queryParams?.utm_source;
|
||||
|
||||
if (utmSource) {
|
||||
this.settingsStorageService.setSetting('utm_source', utmSource);
|
||||
}
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
@ -47,7 +46,10 @@ export class AuthGuard implements CanActivate {
|
||||
.get()
|
||||
.pipe(
|
||||
catchError(() => {
|
||||
if (route.queryParams?.utm_source) {
|
||||
if (utmSource === 'ios') {
|
||||
this.router.navigate(['/demo']);
|
||||
resolve(false);
|
||||
} else if (utmSource === 'trusted-web-activity') {
|
||||
this.router.navigate(['/register']);
|
||||
resolve(false);
|
||||
} else if (
|
||||
|
@ -5,7 +5,6 @@ import {
|
||||
HttpRequest
|
||||
} from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ImpersonationStorageService } from '../services/impersonation-storage.service';
|
||||
@ -18,7 +17,6 @@ const TOKEN_HEADER_KEY = 'Authorization';
|
||||
export class AuthInterceptor implements HttpInterceptor {
|
||||
public constructor(
|
||||
private impersonationStorageService: ImpersonationStorageService,
|
||||
private router: Router,
|
||||
private tokenStorageService: TokenStorageService
|
||||
) {}
|
||||
|
||||
|
@ -12,7 +12,10 @@
|
||||
<div class="pr-1 w-50" i18n>Alias</div>
|
||||
<div class="pl-1 w-50">{{ user.alias }}</div>
|
||||
</div>
|
||||
<div *ngIf="user?.subscription" class="d-flex py-1">
|
||||
<div
|
||||
*ngIf="hasPermissionToUpdateUserSettings && user?.subscription"
|
||||
class="d-flex py-1"
|
||||
>
|
||||
<div class="pr-1 w-50" i18n>Membership</div>
|
||||
<div class="pl-1 w-50">
|
||||
<div class="align-items-center d-flex mb-1">
|
||||
|
15
apps/client/src/app/pages/demo/demo-page-routing.module.ts
Normal file
15
apps/client/src/app/pages/demo/demo-page-routing.module.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
|
||||
|
||||
import { DemoPageComponent } from './demo-page.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: DemoPageComponent, canActivate: [AuthGuard] }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DemoPageRoutingModule {}
|
44
apps/client/src/app/pages/demo/demo-page.component.ts
Normal file
44
apps/client/src/app/pages/demo/demo-page.component.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
||||
import { InfoItem } from '@ghostfolio/common/interfaces';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
host: { class: 'page' },
|
||||
selector: 'gf-demo-page',
|
||||
templateUrl: './demo-page.html'
|
||||
})
|
||||
export class DemoPageComponent implements OnDestroy {
|
||||
public info: InfoItem;
|
||||
|
||||
private unsubscribeSubject = new Subject<void>();
|
||||
|
||||
public constructor(
|
||||
private dataService: DataService,
|
||||
private router: Router,
|
||||
private tokenStorageService: TokenStorageService
|
||||
) {
|
||||
this.info = this.dataService.fetchInfo();
|
||||
}
|
||||
|
||||
public ngOnInit() {
|
||||
const hasToken = this.tokenStorageService.getToken()?.length > 0;
|
||||
|
||||
if (hasToken) {
|
||||
alert(
|
||||
'As you are already logged in, you cannot access the demo account.'
|
||||
);
|
||||
} else {
|
||||
this.tokenStorageService.saveToken(this.info.demoAuthToken, true);
|
||||
}
|
||||
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.unsubscribeSubject.next();
|
||||
this.unsubscribeSubject.complete();
|
||||
}
|
||||
}
|
0
apps/client/src/app/pages/demo/demo-page.html
Normal file
0
apps/client/src/app/pages/demo/demo-page.html
Normal file
12
apps/client/src/app/pages/demo/demo-page.module.ts
Normal file
12
apps/client/src/app/pages/demo/demo-page.module.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
|
||||
import { DemoPageRoutingModule } from './demo-page-routing.module';
|
||||
import { DemoPageComponent } from './demo-page.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [DemoPageComponent],
|
||||
imports: [CommonModule, DemoPageRoutingModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class DemoPageModule {}
|
@ -1,7 +1,4 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
|
||||
import { format } from 'date-fns';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@ -39,23 +36,9 @@ export class LandingPageComponent implements OnDestroy, OnInit {
|
||||
|
||||
private unsubscribeSubject = new Subject<void>();
|
||||
|
||||
public constructor(
|
||||
private dataService: DataService,
|
||||
private router: Router,
|
||||
private tokenStorageService: TokenStorageService
|
||||
) {}
|
||||
public constructor() {}
|
||||
|
||||
public ngOnInit() {
|
||||
const { demoAuthToken } = this.dataService.fetchInfo();
|
||||
|
||||
this.demoAuthToken = demoAuthToken;
|
||||
}
|
||||
|
||||
public setToken(aToken: string) {
|
||||
this.tokenStorageService.saveToken(aToken, true);
|
||||
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
public ngOnInit() {}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.unsubscribeSubject.next();
|
||||
|
@ -31,20 +31,19 @@
|
||||
color="primary"
|
||||
i18n
|
||||
mat-flat-button
|
||||
[disabled]="!demoAuthToken"
|
||||
[routerLink]="['/register']"
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
<div class="d-inline-block mx-3 text-muted" i18n>or</div>
|
||||
<button
|
||||
<a
|
||||
class="d-inline-block"
|
||||
i18n
|
||||
mat-stroked-button
|
||||
[disabled]="!demoAuthToken"
|
||||
(click)="setToken(demoAuthToken)"
|
||||
[routerLink]="['/demo']"
|
||||
>
|
||||
<span i18n>Live Demo</span>
|
||||
</button>
|
||||
Live Demo
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -163,24 +162,18 @@
|
||||
Join now or check out the example account
|
||||
</p>
|
||||
<div class="py-2 text-center">
|
||||
<a
|
||||
color="primary"
|
||||
i18n
|
||||
mat-flat-button
|
||||
[disabled]="!demoAuthToken"
|
||||
[routerLink]="['/register']"
|
||||
>
|
||||
<a color="primary" i18n mat-flat-button [routerLink]="['/register']">
|
||||
Get Started
|
||||
</a>
|
||||
<div class="d-inline-block mx-3 text-muted" i18n>or</div>
|
||||
<button
|
||||
<a
|
||||
class="d-inline-block"
|
||||
i18n
|
||||
mat-stroked-button
|
||||
[disabled]="!demoAuthToken"
|
||||
(click)="setToken(demoAuthToken)"
|
||||
[routerLink]="['/demo']"
|
||||
>
|
||||
<span i18n>Live Demo</span>
|
||||
</button>
|
||||
Live Demo
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user