mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
32 changed files with 323 additions and 121 deletions
@ -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,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 {} |
@ -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(); |
||||
|
} |
||||
|
} |
@ -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> |
@ -1,27 +1,27 @@ |
|||||
import { CommonModule } from '@angular/common'; |
import { CommonModule } from '@angular/common'; |
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
||||
import { MatButtonModule } from '@angular/material/button'; |
import { MatButtonModule } from '@angular/material/button'; |
||||
|
import { MatCardModule } from '@angular/material/card'; |
||||
import { RouterModule } from '@angular/router'; |
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 { GfLogoModule } from '@ghostfolio/client/components/logo/logo.module'; |
||||
|
|
||||
import { LoginPageRoutingModule } from './login-page-routing.module'; |
import { RegisterPageRoutingModule } from './register-page-routing.module'; |
||||
import { LoginPageComponent } from './login-page.component'; |
import { RegisterPageComponent } from './register-page.component'; |
||||
import { ShowAccessTokenDialogModule } from './show-access-token-dialog/show-access-token-dialog.module'; |
import { ShowAccessTokenDialogModule } from './show-access-token-dialog/show-access-token-dialog.module'; |
||||
|
|
||||
@NgModule({ |
@NgModule({ |
||||
declarations: [LoginPageComponent], |
declarations: [RegisterPageComponent], |
||||
exports: [], |
exports: [], |
||||
imports: [ |
imports: [ |
||||
CommonModule, |
CommonModule, |
||||
GfLineChartModule, |
|
||||
GfLogoModule, |
GfLogoModule, |
||||
LoginPageRoutingModule, |
|
||||
MatButtonModule, |
MatButtonModule, |
||||
|
MatCardModule, |
||||
|
RegisterPageRoutingModule, |
||||
RouterModule, |
RouterModule, |
||||
ShowAccessTokenDialogModule |
ShowAccessTokenDialogModule |
||||
], |
], |
||||
providers: [], |
providers: [], |
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA] |
schemas: [CUSTOM_ELEMENTS_SCHEMA] |
||||
}) |
}) |
||||
export class LoginPageModule {} |
export class RegisterPageModule {} |
@ -0,0 +1,3 @@ |
|||||
|
:host { |
||||
|
display: block; |
||||
|
} |
@ -1,5 +1,5 @@ |
|||||
import { ClipboardModule } from '@angular/cdk/clipboard'; |
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 { CommonModule } from '@angular/common'; |
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; |
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; |
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; |
Loading…
Reference in new issue