diff --git a/CHANGELOG.md b/CHANGELOG.md
index 88c026b2..72c39a37 100644
--- a/CHANGELOG.md
+++ b/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 (``) on the tools page
diff --git a/apps/client/src/app/app-routing.module.ts b/apps/client/src/app/app-routing.module.ts
index 30338f40..51dcaf4f 100644
--- a/apps/client/src/app/app-routing.module.ts
+++ b/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',
diff --git a/apps/client/src/app/app.component.html b/apps/client/src/app/app.component.html
index 33245fb5..b077b1b1 100644
--- a/apps/client/src/app/app.component.html
+++ b/apps/client/src/app/app.component.html
@@ -12,13 +12,15 @@
-
+
+ You are using the Live Demo.
+
+
-
You are using the Live Demo.
-
-
diff --git a/apps/client/src/app/app.component.scss b/apps/client/src/app/app.component.scss
index 203c56be..e122745d 100644
--- a/apps/client/src/app/app.component.scss
+++ b/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%;
diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts
index 339d4712..c326e2f0 100644
--- a/apps/client/src/app/app.component.ts
+++ b/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.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.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() {
diff --git a/apps/client/src/app/app.module.ts b/apps/client/src/app/app.module.ts
index e02f222f..552013e1 100644
--- a/apps/client/src/app/app.module.ts
+++ b/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,
diff --git a/apps/client/src/app/components/header/header.component.html b/apps/client/src/app/components/header/header.component.html
index ccd6d3df..9d566f7d 100644
--- a/apps/client/src/app/components/header/header.component.html
+++ b/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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -226,28 +249,44 @@
- Pricing
About
Pricing
+ GitHub
-
+ >
+
+ Get Started
+
diff --git a/apps/client/src/app/components/header/header.component.ts b/apps/client/src/app/components/header/header.component.ts
index c8936c0f..5ce1ca87 100644
--- a/apps/client/src/app/components/header/header.component.ts
+++ b/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';
diff --git a/apps/client/src/app/components/header/header.module.ts b/apps/client/src/app/components/header/header.module.ts
index b1cdbd24..41873f65 100644
--- a/apps/client/src/app/components/header/header.module.ts
+++ b/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';
diff --git a/apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.component.ts b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts
similarity index 90%
rename from apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.component.ts
rename to apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.component.ts
index add1a42b..51dd143e 100644
--- a/apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.component.ts
+++ b/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'
diff --git a/apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.html b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html
similarity index 100%
rename from apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.html
rename to apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html
diff --git a/apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.module.ts b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.module.ts
similarity index 100%
rename from apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.module.ts
rename to apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.module.ts
diff --git a/apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.scss b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.scss
similarity index 100%
rename from apps/client/src/app/pages/login/login-with-access-token-dialog/login-with-access-token-dialog.scss
rename to apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.scss
diff --git a/apps/client/src/app/core/auth.guard.ts b/apps/client/src/app/core/auth.guard.ts
index fcd5fe04..318e6a82 100644
--- a/apps/client/src/app/core/auth.guard.ts
+++ b/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,
diff --git a/apps/client/src/app/pages/login/login-page-routing.module.ts b/apps/client/src/app/pages/landing/landing-page-routing.module.ts
similarity index 60%
rename from apps/client/src/app/pages/login/login-page-routing.module.ts
rename to apps/client/src/app/pages/landing/landing-page-routing.module.ts
index 63829706..48eb070d 100644
--- a/apps/client/src/app/pages/login/login-page-routing.module.ts
+++ b/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 {}
diff --git a/apps/client/src/app/pages/login/login-page.component.ts b/apps/client/src/app/pages/landing/landing-page.component.ts
similarity index 83%
rename from apps/client/src/app/pages/login/login-page.component.ts
rename to apps/client/src/app/pages/landing/landing-page.component.ts
index ba3ea827..05e51530 100644
--- a/apps/client/src/app/pages/login/login-page.component.ts
+++ b/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);
diff --git a/apps/client/src/app/pages/login/login-page.html b/apps/client/src/app/pages/landing/landing-page.html
similarity index 96%
rename from apps/client/src/app/pages/login/login-page.html
rename to apps/client/src/app/pages/landing/landing-page.html
index 9ce5b0fb..25c83b8a 100644
--- a/apps/client/src/app/pages/login/login-page.html
+++ b/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"
>
-
+ Get Started
+
or