diff --git a/CHANGELOG.md b/CHANGELOG.md index d59b10ff7..d62be1524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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` diff --git a/apps/client/src/app/app-routing.module.ts b/apps/client/src/app/app-routing.module.ts index 50cbe072d..ebe39892e 100644 --- a/apps/client/src/app/app-routing.module.ts +++ b/apps/client/src/app/app-routing.module.ts @@ -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: () => diff --git a/apps/client/src/app/core/auth.guard.ts b/apps/client/src/app/core/auth.guard.ts index 6bfc35225..5ae210acf 100644 --- a/apps/client/src/app/core/auth.guard.ts +++ b/apps/client/src/app/core/auth.guard.ts @@ -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((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 ( diff --git a/apps/client/src/app/core/auth.interceptor.ts b/apps/client/src/app/core/auth.interceptor.ts index 6bd3a0412..481f83b71 100644 --- a/apps/client/src/app/core/auth.interceptor.ts +++ b/apps/client/src/app/core/auth.interceptor.ts @@ -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 ) {} diff --git a/apps/client/src/app/pages/account/account-page.html b/apps/client/src/app/pages/account/account-page.html index 68800ce30..1fc13f105 100644 --- a/apps/client/src/app/pages/account/account-page.html +++ b/apps/client/src/app/pages/account/account-page.html @@ -12,7 +12,10 @@
Alias
{{ user.alias }}
-
+
Membership
diff --git a/apps/client/src/app/pages/demo/demo-page-routing.module.ts b/apps/client/src/app/pages/demo/demo-page-routing.module.ts new file mode 100644 index 000000000..8d817447e --- /dev/null +++ b/apps/client/src/app/pages/demo/demo-page-routing.module.ts @@ -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 {} diff --git a/apps/client/src/app/pages/demo/demo-page.component.ts b/apps/client/src/app/pages/demo/demo-page.component.ts new file mode 100644 index 000000000..dce634a7d --- /dev/null +++ b/apps/client/src/app/pages/demo/demo-page.component.ts @@ -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(); + + 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(); + } +} diff --git a/apps/client/src/app/pages/demo/demo-page.html b/apps/client/src/app/pages/demo/demo-page.html new file mode 100644 index 000000000..e69de29bb diff --git a/apps/client/src/app/pages/demo/demo-page.module.ts b/apps/client/src/app/pages/demo/demo-page.module.ts new file mode 100644 index 000000000..5465c93cd --- /dev/null +++ b/apps/client/src/app/pages/demo/demo-page.module.ts @@ -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 {} diff --git a/apps/client/src/app/pages/landing/landing-page.component.ts b/apps/client/src/app/pages/landing/landing-page.component.ts index d3c3b54b7..26f27d991 100644 --- a/apps/client/src/app/pages/landing/landing-page.component.ts +++ b/apps/client/src/app/pages/landing/landing-page.component.ts @@ -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(); - 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(); diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html index 1b5beed46..dc330a800 100644 --- a/apps/client/src/app/pages/landing/landing-page.html +++ b/apps/client/src/app/pages/landing/landing-page.html @@ -31,20 +31,19 @@ color="primary" i18n mat-flat-button - [disabled]="!demoAuthToken" [routerLink]="['/register']" > Get Started
or
- + Live Demo +
@@ -163,24 +162,18 @@ Join now or check out the example account

- + Get Started
or
- + Live Demo +