Browse Source

Feature/add account registration page (#141)

* Add account registration page

* Update changelog
pull/144/head
Thomas 3 years ago
committed by GitHub
parent
commit
026a5011d4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CHANGELOG.md
  2. 11
      apps/client/src/app/app-routing.module.ts
  3. 14
      apps/client/src/app/app.component.html
  4. 2
      apps/client/src/app/app.component.scss
  5. 18
      apps/client/src/app/app.component.ts
  6. 2
      apps/client/src/app/app.module.ts
  7. 95
      apps/client/src/app/components/header/header.component.html
  8. 2
      apps/client/src/app/components/header/header.component.ts
  9. 2
      apps/client/src/app/components/header/header.module.ts
  10. 2
      apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts
  11. 0
      apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html
  12. 0
      apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.module.ts
  13. 0
      apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.scss
  14. 7
      apps/client/src/app/core/auth.guard.ts
  15. 6
      apps/client/src/app/pages/landing/landing-page-routing.module.ts
  16. 44
      apps/client/src/app/pages/landing/landing-page.component.ts
  17. 16
      apps/client/src/app/pages/landing/landing-page.html
  18. 25
      apps/client/src/app/pages/landing/landing-page.module.ts
  19. 0
      apps/client/src/app/pages/landing/landing-page.scss
  20. 8
      apps/client/src/app/pages/pricing/pricing-page.html
  21. 15
      apps/client/src/app/pages/register/register-page-routing.module.ts
  22. 98
      apps/client/src/app/pages/register/register-page.component.ts
  23. 30
      apps/client/src/app/pages/register/register-page.html
  24. 14
      apps/client/src/app/pages/register/register-page.module.ts
  25. 3
      apps/client/src/app/pages/register/register-page.scss
  26. 2
      apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.component.ts
  27. 0
      apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html
  28. 2
      apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.module.ts
  29. 0
      apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.scss
  30. 6
      apps/client/src/app/services/token-storage.service.ts
  31. 12
      apps/client/src/assets/sitemap.xml
  32. 4
      apps/client/src/styles.scss

4
CHANGELOG.md

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Added a dedicated page for the account registration
### Changed
- Changed the buttons to links (`<a>`) on the tools page

11
apps/client/src/app/app-routing.module.ts

@ -45,6 +45,13 @@ const routes: Routes = [
(m) => m.PricingPageModule
)
},
{
path: 'register',
loadChildren: () =>
import('./pages/register/register-page.module').then(
(m) => m.RegisterPageModule
)
},
{
path: 'resources',
loadChildren: () =>
@ -55,7 +62,9 @@ const routes: Routes = [
{
path: 'start',
loadChildren: () =>
import('./pages/login/login-page.module').then((m) => m.LoginPageModule)
import('./pages/landing/landing-page.module').then(
(m) => m.LandingPageModule
)
},
{
path: 'tools',

14
apps/client/src/app/app.component.html

@ -12,13 +12,15 @@
<div *ngIf="canCreateAccount" class="container create-account-container">
<div class="row mb-5">
<div class="col-md-6 offset-md-3">
<div
class="create-account-box p-2 text-center"
(click)="onCreateAccount()"
<a [routerLink]="['/']">
<mat-card
class="create-account-box p-2 text-center"
(click)="onCreateAccount()"
>
<div class="mt-1" i18n>You are using the Live Demo.</div>
<button mat-button color="primary" i18n>Create Account</button>
</mat-card></a
>
<div class="mt-1" i18n>You are using the Live Demo.</div>
<button mat-button color="primary" i18n>Create Account</button>
</div>
</div>
</div>
</div>

2
apps/client/src/app/app.component.scss

@ -5,8 +5,6 @@
padding: 5rem 0;
.create-account-box {
border: 1px solid rgba(var(--palette-primary-500), 1);
border-radius: 0.25rem;
cursor: pointer;
font-size: 90%;

18
apps/client/src/app/app.component.ts

@ -68,17 +68,12 @@ export class AppComponent implements OnDestroy, OnInit {
this.userService.stateChanged
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((state) => {
if (state?.user) {
this.user = state.user;
this.canCreateAccount = hasPermission(
this.user.permissions,
permissions.createUserAccount
);
} else if (!this.tokenStorageService.getToken()) {
// User has not been logged in
this.user = null;
}
this.user = state.user;
this.canCreateAccount = hasPermission(
this.user?.permissions,
permissions.createUserAccount
);
this.changeDetectorRef.markForCheck();
});
@ -86,7 +81,6 @@ export class AppComponent implements OnDestroy, OnInit {
public onCreateAccount() {
this.tokenStorageService.signOut();
window.location.reload();
}
public onSignOut() {

2
apps/client/src/app/app.module.ts

@ -2,6 +2,7 @@ import { Platform } from '@angular/cdk/platform';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import {
DateAdapter,
MAT_DATE_FORMATS,
@ -34,6 +35,7 @@ import { LanguageService } from './core/language.service';
HttpClientModule,
MarkdownModule.forRoot(),
MatButtonModule,
MatCardModule,
MaterialCssVarsModule.forRoot({
darkThemeClass: 'is-dark-theme',
isAutoContrast: true,

95
apps/client/src/app/components/header/header.component.html

@ -8,9 +8,11 @@
class="d-none d-sm-block"
i18n
mat-flat-button
[color]="
currentRoute === 'home' || currentRoute === 'zen' ? 'primary' : null
"
[ngClass]="{
'font-weight-bold': currentRoute === 'home' || currentRoute === 'zen',
'text-decoration-underline':
currentRoute === 'home' || currentRoute === 'zen'
}"
[routerLink]="['/']"
>Overview</a
>
@ -19,13 +21,16 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="
currentRoute === 'analysis' ||
currentRoute === 'report' ||
currentRoute === 'tools'
? 'primary'
: null
"
[ngClass]="{
'font-weight-bold':
currentRoute === 'analysis' ||
currentRoute === 'report' ||
currentRoute === 'tools',
'text-decoration-underline':
currentRoute === 'analysis' ||
currentRoute === 'report' ||
currentRoute === 'tools'
}"
[routerLink]="['/tools']"
>Tools</a
>
@ -33,7 +38,10 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'transactions' ? 'primary' : null"
[ngClass]="{
'font-weight-bold': currentRoute === 'transactions',
'text-decoration-underline': currentRoute === 'transactions'
}"
[routerLink]="['/transactions']"
>Transactions</a
>
@ -41,7 +49,10 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'accounts' ? 'primary' : null"
[ngClass]="{
'font-weight-bold': currentRoute === 'accounts',
'text-decoration-underline': currentRoute === 'accounts'
}"
[routerLink]="['/accounts']"
>Accounts</a
>
@ -50,7 +61,10 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'admin' ? 'primary' : null"
[ngClass]="{
'font-weight-bold': currentRoute === 'admin',
'text-decoration-underline': currentRoute === 'admin'
}"
[routerLink]="['/admin']"
>Admin Control</a
>
@ -58,7 +72,10 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'resources' ? 'primary' : null"
[ngClass]="{
'font-weight-bold': currentRoute === 'resources',
'text-decoration-underline': currentRoute === 'resources'
}"
[routerLink]="['/resources']"
>Resources</a
>
@ -67,7 +84,10 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'pricing' ? 'primary' : null"
[ngClass]="{
'font-weight-bold': currentRoute === 'pricing',
'text-decoration-underline': currentRoute === 'pricing'
}"
[routerLink]="['/pricing']"
>Pricing</a
>
@ -75,7 +95,10 @@
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'about' ? 'primary' : null"
[ngClass]="{
'font-weight-bold': currentRoute === 'about',
'text-decoration-underline': currentRoute === 'about'
}"
[routerLink]="['/about']"
>About</a
>
@ -227,27 +250,43 @@
</a>
<span class="spacer"></span>
<a
*ngIf="hasPermissionForSubscription"
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[color]="currentRoute === 'pricing' ? 'primary' : null"
[routerLink]="['/pricing']"
>Pricing</a
[ngClass]="{
'font-weight-bold': currentRoute === 'about',
'text-decoration-underline': currentRoute === 'about'
}"
[routerLink]="['/about']"
>About</a
>
<a
class="d-none d-sm-block mx-1"
*ngIf="hasPermissionForSubscription"
i18n
mat-flat-button
[color]="currentRoute === 'about' ? 'primary' : null"
[routerLink]="['/about']"
>About</a
[ngClass]="{
'font-weight-bold': currentRoute === 'pricing',
'text-decoration-underline': currentRoute === 'pricing'
}"
[routerLink]="['/pricing']"
>Pricing</a
>
<a
class="d-none d-sm-block mx-1"
class="d-none d-sm-block mx-1 no-min-width px-1"
href="https://github.com/ghostfolio/ghostfolio"
mat-flat-button
>GitHub</a
>
<button i18n mat-flat-button (click)="openLoginDialog()">Sign in</button>
><ion-icon name="logo-github"></ion-icon
></a>
<button class="mx-1" i18n mat-flat-button (click)="openLoginDialog()">
Sign In
</button>
<a
class="d-none d-sm-block"
color="primary"
i18n
mat-flat-button
[routerLink]="['/register']"
>Get Started
</a>
</ng-container>
</mat-toolbar>

2
apps/client/src/app/components/header/header.component.ts

@ -8,7 +8,7 @@ import {
} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { LoginWithAccessTokenDialog } from '@ghostfolio/client/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.component';
import { LoginWithAccessTokenDialog } from '@ghostfolio/client/components/login-with-access-token-dialog/login-with-access-token-dialog.component';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';

2
apps/client/src/app/components/header/header.module.ts

@ -4,7 +4,7 @@ import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterModule } from '@angular/router';
import { LoginWithAccessTokenDialogModule } from '@ghostfolio/client/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.module';
import { LoginWithAccessTokenDialogModule } from '@ghostfolio/client/components/login-with-access-token-dialog/login-with-access-token-dialog.module';
import { GfLogoModule } from '../logo/logo.module';
import { HeaderComponent } from './header.component';

2
apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.component.ts → apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts

@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'login-with-access-token-dialog',
selector: 'gf-login-with-access-token-dialog',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./login-with-access-token-dialog.scss'],
templateUrl: 'login-with-access-token-dialog.html'

0
apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.html → apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html

0
apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.module.ts → apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.module.ts

0
apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.scss → apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.scss

7
apps/client/src/app/core/auth.guard.ts

@ -14,7 +14,12 @@ import { UserService } from '../services/user/user.service';
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
private static PUBLIC_PAGE_ROUTES = ['/about', '/pricing', '/resources'];
private static PUBLIC_PAGE_ROUTES = [
'/about',
'/pricing',
'/register',
'/resources'
];
constructor(
private router: Router,

6
apps/client/src/app/pages/login/login-page-routing.module.ts → apps/client/src/app/pages/landing/landing-page-routing.module.ts

@ -2,14 +2,14 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { LoginPageComponent } from './login-page.component';
import { LandingPageComponent } from './landing-page.component';
const routes: Routes = [
{ path: '', component: LoginPageComponent, canActivate: [AuthGuard] }
{ path: '', component: LandingPageComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LoginPageRoutingModule {}
export class LandingPageRoutingModule {}

44
apps/client/src/app/pages/login/login-page.component.ts → apps/client/src/app/pages/landing/landing-page.component.ts

@ -1,21 +1,17 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { LineChartItem } from '@ghostfolio/client/components/line-chart/interfaces/line-chart.interface';
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';
import { takeUntil } from 'rxjs/operators';
import { ShowAccessTokenDialog } from './show-access-token-dialog/show-access-token-dialog.component';
@Component({
selector: 'gf-login-page',
templateUrl: './login-page.html',
styleUrls: ['./login-page.scss']
selector: 'gf-landing-page',
templateUrl: './landing-page.html',
styleUrls: ['./landing-page.scss']
})
export class LoginPageComponent implements OnDestroy, OnInit {
export class LandingPageComponent implements OnDestroy, OnInit {
public currentYear = format(new Date(), 'yyyy');
public demoAuthToken: string;
public historicalDataItems: LineChartItem[];
@ -28,7 +24,6 @@ export class LoginPageComponent implements OnDestroy, OnInit {
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private dialog: MatDialog,
private router: Router,
private tokenStorageService: TokenStorageService
) {}
@ -46,15 +41,6 @@ export class LoginPageComponent implements OnDestroy, OnInit {
});
}
public async createAccount() {
this.dataService
.postUser()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ accessToken, authToken }) => {
this.openShowAccessTokenDialog(accessToken, authToken);
});
}
public initializeLineChart() {
this.historicalDataItems = [
{
@ -268,28 +254,6 @@ export class LoginPageComponent implements OnDestroy, OnInit {
];
}
public openShowAccessTokenDialog(
accessToken: string,
authToken: string
): void {
const dialogRef = this.dialog.open(ShowAccessTokenDialog, {
data: {
accessToken,
authToken
},
disableClose: true,
width: '30rem'
});
dialogRef.afterClosed().subscribe((data) => {
if (data?.authToken) {
this.tokenStorageService.saveToken(authToken);
this.router.navigate(['/']);
}
});
}
public setToken(aToken: string) {
this.tokenStorageService.saveToken(aToken);

16
apps/client/src/app/pages/login/login-page.html → apps/client/src/app/pages/landing/landing-page.html

@ -13,16 +13,16 @@
class="align-items-center col d-flex justify-content-center position-relative"
>
<div class="py-5 text-center">
<button
<a
class="d-inline-block"
color="primary"
i18n
mat-flat-button
[disabled]="!demoAuthToken"
(click)="createAccount()"
[routerLink]="['/register']"
>
Create Account
</button>
Get Started
</a>
<div class="d-inline-block mx-3 text-muted" i18n>or</div>
<button
class="d-inline-block"
@ -135,15 +135,15 @@
Join now or check out the example account
</p>
<div class="py-2 text-center">
<button
<a
color="primary"
i18n
mat-flat-button
[disabled]="!demoAuthToken"
(click)="createAccount()"
[routerLink]="['/register']"
>
Create Account
</button>
Get Started
</a>
<div class="d-inline-block mx-3 text-muted" i18n>or</div>
<button
class="d-inline-block"

25
apps/client/src/app/pages/landing/landing-page.module.ts

@ -0,0 +1,25 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
import { GfLineChartModule } from '@ghostfolio/client/components/line-chart/line-chart.module';
import { GfLogoModule } from '@ghostfolio/client/components/logo/logo.module';
import { LandingPageRoutingModule } from './landing-page-routing.module';
import { LandingPageComponent } from './landing-page.component';
@NgModule({
declarations: [LandingPageComponent],
exports: [],
imports: [
CommonModule,
GfLineChartModule,
GfLogoModule,
LandingPageRoutingModule,
MatButtonModule,
RouterModule
],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class LandingPageModule {}

0
apps/client/src/app/pages/login/login-page.scss → apps/client/src/app/pages/landing/landing-page.scss

8
apps/client/src/app/pages/pricing/pricing-page.html

@ -1,7 +1,9 @@
<div class="container">
<div class="row">
<div class="col">
<h3 class="d-flex justify-content-center mb-3" i18n>Pricing Plans</h3>
<h3 class="d-flex justify-content-center mb-3 text-center" i18n>
Pricing Plans
</h3>
<mat-card class="mb-4">
<mat-card-content>
<p>
@ -188,8 +190,8 @@
</div>
<div *ngIf="!user" class="row">
<div class="col mt-3 text-center">
<a color="primary" i18n mat-flat-button [routerLink]="['/start']">
Create Account
<a color="primary" i18n mat-flat-button [routerLink]="['/register']">
Get Started
</a>
<p class="text-muted"><small>It's free</small></p>
</div>

15
apps/client/src/app/pages/register/register-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 { RegisterPageComponent } from './register-page.component';
const routes: Routes = [
{ path: '', component: RegisterPageComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RegisterPageRoutingModule {}

98
apps/client/src/app/pages/register/register-page.component.ts

@ -0,0 +1,98 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { LineChartItem } from '@ghostfolio/client/components/line-chart/interfaces/line-chart.interface';
import { DataService } from '@ghostfolio/client/services/data.service';
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { format } from 'date-fns';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ShowAccessTokenDialog } from './show-access-token-dialog/show-access-token-dialog.component';
@Component({
selector: 'gf-register-page',
templateUrl: './register-page.html',
styleUrls: ['./register-page.scss']
})
export class RegisterPageComponent implements OnDestroy, OnInit {
public currentYear = format(new Date(), 'yyyy');
public demoAuthToken: string;
public hasPermissionForSocialLogin: boolean;
public historicalDataItems: LineChartItem[];
private unsubscribeSubject = new Subject<void>();
/**
* @constructor
*/
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private dialog: MatDialog,
private router: Router,
private tokenStorageService: TokenStorageService
) {
this.tokenStorageService.signOut();
}
/**
* Initializes the controller
*/
public ngOnInit() {
this.dataService
.fetchInfo()
.subscribe(({ demoAuthToken, globalPermissions }) => {
this.demoAuthToken = demoAuthToken;
this.hasPermissionForSocialLogin = hasPermission(
globalPermissions,
permissions.enableSocialLogin
);
this.changeDetectorRef.markForCheck();
});
}
public async createAccount() {
this.dataService
.postUser()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ accessToken, authToken }) => {
this.openShowAccessTokenDialog(accessToken, authToken);
});
}
public openShowAccessTokenDialog(
accessToken: string,
authToken: string
): void {
const dialogRef = this.dialog.open(ShowAccessTokenDialog, {
data: {
accessToken,
authToken
},
disableClose: true,
width: '30rem'
});
dialogRef.afterClosed().subscribe((data) => {
if (data?.authToken) {
this.tokenStorageService.saveToken(authToken);
this.router.navigate(['/']);
}
});
}
public setToken(aToken: string) {
this.tokenStorageService.saveToken(aToken);
this.router.navigate(['/']);
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
}

30
apps/client/src/app/pages/register/register-page.html

@ -0,0 +1,30 @@
<div class="container">
<div class="row">
<div class="col">
<h3 class="d-flex justify-content-center mb-3 text-center" i18n>
Create your Ghostfolio account
</h3>
<mat-card class="mb-4">
<mat-card-content class="text-center">
<button
class="d-inline-block"
color="primary"
i18n
mat-flat-button
[disabled]="!demoAuthToken"
(click)="createAccount()"
>
Create Account
</button>
<ng-container *ngIf="hasPermissionForSocialLogin">
<div class="my-3 text-muted" i18n>or</div>
<a color="accent" href="/api/auth/google" mat-flat-button
><ion-icon class="mr-1" name="logo-google"></ion-icon
><span i18n>Continue with Google</span></a
>
</ng-container>
</mat-card-content>
</mat-card>
</div>
</div>
</div>

14
apps/client/src/app/pages/login/login-page.module.ts → apps/client/src/app/pages/register/register-page.module.ts

@ -1,27 +1,27 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { RouterModule } from '@angular/router';
import { GfLineChartModule } from '@ghostfolio/client/components/line-chart/line-chart.module';
import { GfLogoModule } from '@ghostfolio/client/components/logo/logo.module';
import { LoginPageRoutingModule } from './login-page-routing.module';
import { LoginPageComponent } from './login-page.component';
import { RegisterPageRoutingModule } from './register-page-routing.module';
import { RegisterPageComponent } from './register-page.component';
import { ShowAccessTokenDialogModule } from './show-access-token-dialog/show-access-token-dialog.module';
@NgModule({
declarations: [LoginPageComponent],
declarations: [RegisterPageComponent],
exports: [],
imports: [
CommonModule,
GfLineChartModule,
GfLogoModule,
LoginPageRoutingModule,
MatButtonModule,
MatCardModule,
RegisterPageRoutingModule,
RouterModule,
ShowAccessTokenDialogModule
],
providers: [],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class LoginPageModule {}
export class RegisterPageModule {}

3
apps/client/src/app/pages/register/register-page.scss

@ -0,0 +1,3 @@
:host {
display: block;
}

2
apps/client/src/app/pages/login/show-access-token-dialog/show-access-token-dialog.component.ts → apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.component.ts

@ -7,7 +7,7 @@ import {
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'show-access-token-dialog',
selector: 'gf-show-access-token-dialog',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./show-access-token-dialog.scss'],
templateUrl: 'show-access-token-dialog.html'

0
apps/client/src/app/pages/login/show-access-token-dialog/show-access-token-dialog.html → apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html

2
apps/client/src/app/pages/login/show-access-token-dialog/show-access-token-dialog.module.ts → apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.module.ts

@ -1,5 +1,5 @@
import { ClipboardModule } from '@angular/cdk/clipboard';
import { CdkTextareaAutosize, TextFieldModule } from '@angular/cdk/text-field';
import { TextFieldModule } from '@angular/cdk/text-field';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

0
apps/client/src/app/pages/login/show-access-token-dialog/show-access-token-dialog.scss → apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.scss

6
apps/client/src/app/services/token-storage.service.ts

@ -1,12 +1,14 @@
import { Injectable } from '@angular/core';
import { UserService } from './user/user.service';
const TOKEN_KEY = 'auth-token';
@Injectable({
providedIn: 'root'
})
export class TokenStorageService {
public constructor() {}
public constructor(private userService: UserService) {}
public getToken(): string {
return window.localStorage.getItem(TOKEN_KEY);
@ -22,6 +24,8 @@ export class TokenStorageService {
window.localStorage.clear();
this.userService.remove();
if (utmSource) {
window.localStorage.setItem('utm_source', utmSource);
}

12
apps/client/src/assets/sitemap.xml

@ -6,18 +6,22 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://ghostfol.io</loc>
<lastmod>2021-05-14T20:24:46+00:00</lastmod>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/about</loc>
<lastmod>2021-05-14T20:24:46+00:00</lastmod>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pricing</loc>
<lastmod>2021-05-14T20:24:46+00:00</lastmod>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/register</loc>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/resources</loc>
<lastmod>2021-05-14T20:24:46+00:00</lastmod>
<lastmod>2021-06-03T00:00:00+00:00</lastmod>
</url>
</urlset>

4
apps/client/src/styles.scss

@ -153,3 +153,7 @@ ngx-skeleton-loader {
.no-min-width {
min-width: unset !important;
}
.text-decoration-underline {
text-decoration: underline !important;
}

Loading…
Cancel
Save