New Version frontend
This commit is contained in:
commit
656a2a5068
@ -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,
|
||||||
|
@ -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',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<p>bot-settings works!</p>
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
1
frontend/src/app/Views/profile/profile.component.html
Normal file
1
frontend/src/app/Views/profile/profile.component.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<p>profile works!</p>
|
25
frontend/src/app/Views/profile/profile.component.spec.ts
Normal file
25
frontend/src/app/Views/profile/profile.component.spec.ts
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
12
frontend/src/app/Views/profile/profile.component.ts
Normal file
12
frontend/src/app/Views/profile/profile.component.ts
Normal 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 {}
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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']);
|
||||||
|
@ -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({
|
||||||
|
@ -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'
|
||||||
|
@ -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],
|
||||||
|
Loading…
Reference in New Issue
Block a user