New Version frontend

This commit is contained in:
kevinpauer 2022-03-26 16:34:29 +01:00
commit 656a2a5068
21 changed files with 205 additions and 30 deletions

View File

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

View File

@ -1,22 +1,38 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
const API_URL = 'http://localhost:8080/api/test/'; import { TokenStorageService } from './token.service';
const API_URL = 'https://aktienbot.flokaiser.com/api/';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class DataService { export class DataService {
constructor(private http: HttpClient) {} constructor(
// getPublicContent(): Observable<any> { private http: HttpClient,
// return this.http.get(API_URL + 'all', { responseType: 'text' }); private tokenStorage: TokenStorageService
// } ) {}
// getUserBoard(): Observable<any> {
// return this.http.get(API_URL + 'user', { responseType: 'text' }); headers = new HttpHeaders({
// } 'Content-Type': 'application/json',
// getModeratorBoard(): Observable<any> { Authorization: 'Bearer ' + this.tokenStorage.getToken(),
// return this.http.get(API_URL + 'mod', { responseType: 'text' }); });
// }
// getAdminBoard(): Observable<any> { async getStockData() {
// return this.http.get(API_URL + 'admin', { responseType: 'text' }); await this.http
// } .get(API_URL + 'portfolio', {
headers: this.headers,
responseType: 'text',
})
.subscribe((data) => {
console.log(data);
return data;
});
}
getKeywords(): Observable<any> {
return this.http.get(API_URL + 'keywords', {
headers: this.headers,
responseType: 'text',
});
}
} }

View File

@ -0,0 +1 @@
<p>bot-settings works!</p>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BotSettingsComponent } from './bot-settings.component';
describe('BotSettingsComponent', () => {
let component: BotSettingsComponent;
let fixture: ComponentFixture<BotSettingsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ BotSettingsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(BotSettingsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-bot-settings',
templateUrl: './bot-settings.component.html',
styleUrls: ['./bot-settings.component.scss']
})
export class BotSettingsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -9,6 +9,7 @@
mat-icon-button mat-icon-button
class="add-icon" class="add-icon"
aria-label="Example icon-button with heart icon" aria-label="Example icon-button with heart icon"
[disableRipple]="true"
> >
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
</button> </button>

View File

@ -47,7 +47,8 @@
.add-icon { .add-icon {
transform: scale(2); transform: scale(2);
padding-top: 1%; margin-top: 2%;
outline: none !important;
} }
.right-side { .right-side {

View File

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { throwToolbarMixedModesError } from '@angular/material/toolbar';
import { DataService } from 'src/app/Services/data.service';
export interface PeriodicElement { export interface PeriodicElement {
name: string; name: string;
@ -46,9 +48,13 @@ const ELEMENT_DATA: PeriodicElement[] = [
styleUrls: ['./dashboard.component.scss'], styleUrls: ['./dashboard.component.scss'],
}) })
export class DashboardComponent implements OnInit { export class DashboardComponent implements OnInit {
constructor() {} constructor(private dataService: DataService) {}
ngOnInit(): void {} //TODO avoid using ngOnInit() like this
//TODO fix server problems
async ngOnInit() {
const data = await this.dataService.getStockData();
}
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol']; displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
dataSource = ELEMENT_DATA; dataSource = ELEMENT_DATA;

View File

@ -5,7 +5,22 @@
mat-icon-button mat-icon-button
class="example-icon favorite-icon" class="example-icon favorite-icon"
aria-label="Example icon-button with heart icon" aria-label="Example icon-button with heart icon"
[matMenuTriggerFor]="menu"
> >
<mat-icon>settings</mat-icon> <mat-icon>settings</mat-icon>
</button> </button>
<mat-menu #menu="matMenu">
<button mat-menu-item routerLink="/profile">
<mat-icon>account_circle</mat-icon>
<span>Profile</span>
</button>
<button mat-menu-item routerLink="/settings">
<mat-icon>ballot</mat-icon>
<span>Bot Settings</span>
</button>
<button mat-menu-item (click)="logout()">
<mat-icon>logout</mat-icon>
<span>Logout</span>
</button>
</mat-menu>
</mat-toolbar> </mat-toolbar>

View File

@ -1,15 +1,22 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { TokenStorageService } from 'src/app/Services/token.service';
@Component({ @Component({
selector: 'app-header', selector: 'app-header',
templateUrl: './header.component.html', templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'] styleUrls: ['./header.component.scss'],
}) })
export class HeaderComponent implements OnInit { export class HeaderComponent implements OnInit {
/**
* @param {TokenStorageService} privatetokenStorage
*/
constructor(private tokenStorage: TokenStorageService) {}
constructor() { } ngOnInit(): void {}
ngOnInit(): void { //logout() clears session storage; All user data is eradicated from it and page is reloaded
logout() {
this.tokenStorage.signOut();
location.reload();
} }
} }

View File

@ -18,29 +18,36 @@ export class LoginComponent implements OnInit {
errorMessage = ''; errorMessage = '';
accountName = ''; accountName = '';
/**
* @param {AuthService} privateauthService
* @param {TokenStorageService} privatetokenStorage
* @param {Router} privaterouter
*/
constructor( constructor(
private authService: AuthService, private authService: AuthService,
private tokenStorage: TokenStorageService, private tokenStorage: TokenStorageService,
private router: Router private router: Router
) {} ) {}
//ngOnInit() checks if a
ngOnInit(): void { ngOnInit(): void {
this.tokenStorage.signOut(); this.tokenStorage.signOut();
if (this.tokenStorage.getToken()) { if (this.tokenStorage.getToken()) {
this.isLoggedIn = true; this.isLoggedIn = true;
} }
} }
//onSubmit() saves valuable information in session storage
onSubmit(): void { onSubmit(): void {
const { username, password } = this.form; const { username, password } = this.form;
console.log(username, password);
this.authService.login(username, password).subscribe( this.authService.login(username, password).subscribe(
(data) => { (data) => {
this.tokenStorage.saveToken(data.accessToken); this.tokenStorage.saveToken(data.data.token);
this.tokenStorage.saveUser(data); this.tokenStorage.saveUser(data.data);
this.isLoginFailed = false; this.isLoginFailed = false;
this.isLoggedIn = true; this.isLoggedIn = true;
this.accountName = username; this.accountName = username;
console.log(this.isLoggedIn);
this.router.navigate(['']); this.router.navigate(['']);
}, },
(err) => { (err) => {
@ -49,6 +56,8 @@ export class LoginComponent implements OnInit {
} }
); );
} }
//reloadPage() reloads the page
reloadPage(): void { reloadPage(): void {
window.location.reload(); window.location.reload();
} }

View File

@ -0,0 +1 @@
<p>profile works!</p>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ProfileComponent } from './profile.component';
describe('ProfileComponent', () => {
let component: ProfileComponent;
let fixture: ComponentFixture<ProfileComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ProfileComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,12 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss'],
})
export class ProfileComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
}

View File

@ -53,6 +53,23 @@
</div> </div>
</div> </div>
</div> </div>
<div class="form-group">
<label for="password">Confirm Password</label>
<input
type="password"
class="form-control"
name="passwordRepeat"
[(ngModel)]="form.password"
required
minlength="6"
#passwordRepeat="ngModel"
/>
<div class="alert-danger" *ngIf="password.errors && f.submitted">
<div *ngIf="passwordRepeat.errors?.['required']">
Confirmation is required
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<button class="btn btn-primary btn-block">Sign Up</button> <button class="btn btn-primary btn-block">Sign Up</button>
</div> </div>

View File

@ -15,13 +15,17 @@ export class RegisterComponent implements OnInit {
isSuccessful = false; isSuccessful = false;
isSignUpFailed = false; isSignUpFailed = false;
errorMessage = ''; errorMessage = '';
/**
* @param {AuthService} privateauthService
* @param {Router} privaterouter
*/
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 { username, password } = this.form;
this.authService.register(username, password).subscribe( this.authService.register(username, password).subscribe(
(data) => { (data) => {
console.log(data);
this.isSuccessful = true; this.isSuccessful = true;
this.isSignUpFailed = false; this.isSignUpFailed = false;
this.router.navigate(['/login']); this.router.navigate(['/login']);

View File

@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './Views/dashboard/dashboard.component'; import { DashboardComponent } from './Views/dashboard/dashboard.component';
import { LoginComponent } from './Views/login/login.component'; import { LoginComponent } from './Views/login/login.component';
import { ProfileComponent } from './Views/profile/profile.component';
import { RegisterComponent } from './Views/register/register.component'; import { RegisterComponent } from './Views/register/register.component';
const routes: Routes = [ const routes: Routes = [
@ -17,6 +18,14 @@ const routes: Routes = [
path: 'register', path: 'register',
component: RegisterComponent, component: RegisterComponent,
}, },
{
path: 'profile',
component: ProfileComponent,
},
{
path: 'settings',
component: ProfileComponent,
},
]; ];
@NgModule({ @NgModule({

View File

@ -13,8 +13,8 @@ export class AppComponent {
* Application title. * Application title.
*/ */
title = 'Aktienbot'; title = 'Aktienbot';
showHeader = false;
showHeader = false;
isLoggedIn = false; isLoggedIn = false;
/** /**
@ -26,6 +26,7 @@ export class AppComponent {
private router: Router, private router: Router,
private tokenStorage: TokenStorageService private tokenStorage: TokenStorageService
) { ) {
//check if it is login or registration page, header should not show there
this.router.events this.router.events
.pipe(filter((event) => event instanceof NavigationEnd)) .pipe(filter((event) => event instanceof NavigationEnd))
.subscribe((event) => { .subscribe((event) => {
@ -33,11 +34,15 @@ export class AppComponent {
(event as NavigationEnd).url === '/login' || (event as NavigationEnd).url === '/login' ||
(event as NavigationEnd).url === '/register' (event as NavigationEnd).url === '/register'
); );
//check if token already exists from past login
if (this.tokenStorage.getToken()) { if (this.tokenStorage.getToken()) {
this.isLoggedIn = true; this.isLoggedIn = true;
} else { } else {
this.isLoggedIn = false; this.isLoggedIn = false;
} }
//prevent user from accessing dashboard if not logged in
if ( if (
this.isLoggedIn === false && this.isLoggedIn === false &&
(event as NavigationEnd).url != '/register' (event as NavigationEnd).url != '/register'

View File

@ -9,6 +9,7 @@ import { MatButtonModule } from '@angular/material/button';
import { MatGridListModule } from '@angular/material/grid-list'; import { MatGridListModule } from '@angular/material/grid-list';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { MatTableModule } from '@angular/material/table'; import { MatTableModule } from '@angular/material/table';
import { MatMenuModule } from '@angular/material/menu';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
@ -17,6 +18,8 @@ import { HeaderComponent } from './Views/header/header.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DashboardComponent } from './Views/dashboard/dashboard.component'; import { DashboardComponent } from './Views/dashboard/dashboard.component';
import { RegisterComponent } from './Views/register/register.component'; import { RegisterComponent } from './Views/register/register.component';
import { ProfileComponent } from './Views/profile/profile.component';
import { BotSettingsComponent } from './Views/bot-settings/bot-settings.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -25,6 +28,8 @@ import { RegisterComponent } from './Views/register/register.component';
HeaderComponent, HeaderComponent,
DashboardComponent, DashboardComponent,
RegisterComponent, RegisterComponent,
ProfileComponent,
BotSettingsComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -38,6 +43,7 @@ import { RegisterComponent } from './Views/register/register.component';
MatTableModule, MatTableModule,
FormsModule, FormsModule,
HttpClientModule, HttpClientModule,
MatMenuModule,
], ],
providers: [], providers: [],
bootstrap: [AppComponent], bootstrap: [AppComponent],