Merge remote-tracking branch 'origin/main'

This commit is contained in:
Administrator 2022-03-28 18:09:45 +02:00
commit e27e2175b5
13 changed files with 144 additions and 50 deletions

View File

@ -7,7 +7,7 @@ import {
} from '@angular/common/http'; } from '@angular/common/http';
import { TokenStorageService } from '../Services/token.service'; import { TokenStorageService } from '../Services/token.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
const TOKEN_HEADER_KEY = 'Authorization'; // for Spring Boot back-end const TOKEN_HEADER_KEY = 'Authorization';
@Injectable() @Injectable()
export class AuthInterceptor implements HttpInterceptor { export class AuthInterceptor implements HttpInterceptor {
constructor(private token: TokenStorageService) {} constructor(private token: TokenStorageService) {}

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { HelperService } from './helper.service';
describe('HelperService', () => {
let service: HelperService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(HelperService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,10 @@
import { Injectable } from '@angular/core';
import { Stock } from '../Models/stock.model';
@Injectable({
providedIn: 'root'
})
export class HelperService {
constructor() { }
}

View File

@ -0,0 +1,6 @@
export class Stock {
count = 0;
price = 0;
symbol = '';
time = '';
}

View File

@ -11,18 +11,19 @@ const httpOptions = {
}) })
export class AuthService { export class AuthService {
constructor(private http: HttpClient) {} constructor(private http: HttpClient) {}
login(username: string, password: string): Observable<any> { login(email: string, password: string): Observable<any> {
return this.http.post(AUTH_API + '/login', { return this.http.post(AUTH_API + '/login', {
username, email,
password, password,
}); });
} }
register(username: string, password: string): Observable<any> { register(email: string, username: string, password: string): Observable<any> {
return this.http.post( return this.http.post(
AUTH_API + '/register', AUTH_API + '/register',
{ {
username, email,
password, password,
username,
}, },
httpOptions httpOptions
); );

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs'; import { delay, Observable } from 'rxjs';
import { TokenStorageService } from './token.service'; import { TokenStorageService } from './token.service';
const API_URL = 'https://aktienbot.flokaiser.com/api/'; const API_URL = 'https://aktienbot.flokaiser.com/api/';
@Injectable({ @Injectable({
@ -12,26 +12,32 @@ export class DataService {
private tokenStorage: TokenStorageService private tokenStorage: TokenStorageService
) {} ) {}
headers = new HttpHeaders({ public getStockData(): Observable<any> {
'Content-Type': 'application/json', return this.http.get(API_URL + 'portfolio', {
Authorization: 'Bearer ' + this.tokenStorage.getToken(), headers: new HttpHeaders({
}); 'Content-Type': 'application/json',
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
async getStockData() { }),
await this.http responseType: 'text',
.get(API_URL + 'portfolio', { });
headers: this.headers,
responseType: 'text',
})
.subscribe((data) => {
console.log(data);
return data;
});
} }
getKeywords(): Observable<any> { public getTransactionData(): Observable<any> {
return this.http.get(API_URL + 'transactions', {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
}),
responseType: 'text',
});
}
public getKeywords(): Observable<any> {
return this.http.get(API_URL + 'keywords', { return this.http.get(API_URL + 'keywords', {
headers: this.headers, headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
}),
responseType: 'text', responseType: 'text',
}); });
} }

View File

@ -64,7 +64,39 @@
<div class="heading fix-right-side"> <div class="heading fix-right-side">
<div class="vertical-center">Transaktionen</div> <div class="vertical-center">Transaktionen</div>
</div> </div>
<mat-card class="placeholder"></mat-card> <div class="stockTable">
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>Count</th>
<td mat-cell *matCellDef="let element">{{ element.position }}</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Pirce</th>
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef>Symbol</th>
<td mat-cell *matCellDef="let element">{{ element.weight }}</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef>Time</th>
<td mat-cell *matCellDef="let element">{{ element.symbol }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
</div> </div>
</mat-grid-tile> </mat-grid-tile>
</mat-grid-list> </mat-grid-list>

View File

@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { throwToolbarMixedModesError } from '@angular/material/toolbar'; import { throwToolbarMixedModesError } from '@angular/material/toolbar';
import { DataService } from 'src/app/Services/data.service'; import { DataService } from 'src/app/Services/data.service';
import { TokenStorageService } from 'src/app/Services/token.service';
export interface PeriodicElement { export interface PeriodicElement {
name: string; name: string;
@ -49,11 +50,15 @@ const ELEMENT_DATA: PeriodicElement[] = [
}) })
export class DashboardComponent implements OnInit { export class DashboardComponent implements OnInit {
constructor(private dataService: DataService) {} constructor(private dataService: DataService) {}
ngOnInit() {
//TODO avoid using ngOnInit() like this this.dataService.getStockData().subscribe((response: any) => {
//TODO fix server problems console.log(response);
async ngOnInit() { //TODO map data on array for display
const data = await this.dataService.getStockData(); });
this.dataService.getTransactionData().subscribe((response: any) => {
console.log(response);
//TODO map data on array for display
});
} }
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol']; displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];

View File

@ -14,21 +14,21 @@
class="backgorund" class="backgorund"
> >
<div class="form-group"> <div class="form-group">
<label for="username">Username</label> <label for="email">Email</label>
<input <input
type="text" type="email"
class="form-control" class="form-control"
name="username" name="email"
[(ngModel)]="form.username" [(ngModel)]="form.email"
required required
#username="ngModel" email
#email="ngModel"
/> />
<div <div class="alert-danger" *ngIf="email.errors && f.submitted">
class="alert alert-danger" <div *ngIf="email.errors?.['required']">Email is required</div>
role="alert" <div *ngIf="email.errors?.['email']">
*ngIf="username.errors && f.submitted" Email must be a valid email address
> </div>
Username is required!
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -10,7 +10,7 @@ import { Router } from '@angular/router';
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
form: any = { form: any = {
username: null, email: null,
password: null, password: null,
}; };
isLoggedIn = false; isLoggedIn = false;
@ -29,7 +29,7 @@ export class LoginComponent implements OnInit {
private router: Router private router: Router
) {} ) {}
//ngOnInit() checks if a //ngOnInit() checks if a user is logged in
ngOnInit(): void { ngOnInit(): void {
this.tokenStorage.signOut(); this.tokenStorage.signOut();
if (this.tokenStorage.getToken()) { if (this.tokenStorage.getToken()) {
@ -39,15 +39,15 @@ export class LoginComponent implements OnInit {
//onSubmit() saves valuable information in session storage //onSubmit() saves valuable information in session storage
onSubmit(): void { onSubmit(): void {
const { username, password } = this.form; const { email, password } = this.form;
this.authService.login(username, password).subscribe( this.authService.login(email, password).subscribe(
(data) => { (data) => {
this.tokenStorage.saveToken(data.data.token); this.tokenStorage.saveToken(data.data.token);
this.tokenStorage.saveUser(data.data); this.tokenStorage.saveUser(data.data);
this.isLoginFailed = false; this.isLoginFailed = false;
this.isLoggedIn = true; this.isLoggedIn = true;
this.accountName = username; this.accountName = email;
this.router.navigate(['']); this.router.navigate(['']);
}, },
(err) => { (err) => {

View File

@ -35,6 +35,24 @@
</div> </div>
</div> </div>
</div> </div>
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
class="form-control"
name="email"
[(ngModel)]="form.email"
required
email
#email="ngModel"
/>
<div class="alert-danger" *ngIf="email.errors && f.submitted">
<div *ngIf="email.errors?.['required']">Email is required</div>
<div *ngIf="email.errors?.['email']">
Email must be a valid email address
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="password">Password</label> <label for="password">Password</label>
<input <input

View File

@ -9,8 +9,9 @@ import { AuthService } from '../../Services/auth.service';
}) })
export class RegisterComponent implements OnInit { export class RegisterComponent implements OnInit {
form: any = { form: any = {
username: null, email: null,
password: null, password: null,
username: null,
}; };
isSuccessful = false; isSuccessful = false;
isSignUpFailed = false; isSignUpFailed = false;
@ -23,8 +24,8 @@ export class RegisterComponent implements OnInit {
constructor(private authService: AuthService, private router: Router) {} constructor(private authService: AuthService, private router: Router) {}
ngOnInit(): void {} ngOnInit(): void {}
onSubmit(): void { onSubmit(): void {
const { username, password } = this.form; const { email, username, password } = this.form;
this.authService.register(username, password).subscribe( this.authService.register(email, username, password).subscribe(
(data) => { (data) => {
this.isSuccessful = true; this.isSuccessful = true;
this.isSignUpFailed = false; this.isSignUpFailed = false;

View File

@ -5,7 +5,6 @@
<title>Aktienbot</title> <title>Aktienbot</title>
<base href="/" /> <base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="frontend/Aktienbot/src/favicon.ico" />
<link rel="preconnect" href="https://fonts.gstatic.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" />
<link <link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"