WIP login

pull/1/head
Max Ehrlicher-Schmidt 4 years ago
parent 4438d166e4
commit cc193b6ae0

@ -1,9 +1,9 @@
<div id="page-wrapper">
<mat-toolbar id="navbar">
<button mat-icon-button (click)="sidenav.toggle()">
<button mat-icon-button (click)="sidenav.toggle()" *ngIf="loggedIn">
<mat-icon>menu</mat-icon>
</button>
<span>Flotte</span>
<span>fLotte</span>
<button mat-icon-button [matMenuTriggerFor]="menu" id="menu-trigger-button">
<mat-icon>more_vert</mat-icon>
</button>
@ -16,6 +16,7 @@
<mat-slide-toggle
(change)="changeTheme($event)"
[checked]="darkThemeIsActive"
color="primary"
>Dark Mode</mat-slide-toggle
>
</div>

@ -1,5 +1,6 @@
import { Component, Renderer2 } from '@angular/core';
import { ColorThemeService } from './services/colorTheme.service';
import { AuthService } from './services/auth.service';
@Component({
selector: 'app-root',
@ -7,16 +8,19 @@ import { ColorThemeService } from './services/colorTheme.service';
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
title = 'flotte-frontend';
title = 'fLotte-fRontend';
darkThemeIsActive: boolean = false;
loggedIn = false;
constructor(
private renderer: Renderer2,
private themeService: ColorThemeService
private themeService: ColorThemeService,
private authService: AuthService
) {
this.renderer.addClass(document.body, 'mat-app-background'); //so the background color changes dependent on current theme
this.themeService.load();
this.darkThemeIsActive = this.themeService.currentActive() === 'dark-theme';
this.authService.loggedIn.subscribe((value) => (this.loggedIn = value));
}
changeTheme(event) {

@ -1,5 +1,7 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
// Angular Material Components
import {MatToolbarModule} from '@angular/material/toolbar';
@ -11,6 +13,9 @@ import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatIconModule} from '@angular/material/icon';
import {MatSidenavModule} from '@angular/material/sidenav';
import {MatListModule} from '@angular/material/list';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import { AppRoutingModule } from './app-routing.module';
@ -29,8 +34,11 @@ import { BikesComponent } from './pages/bikes/bikes.component';
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
MatToolbarModule,
MatButtonModule,
MatTableModule,
@ -39,7 +47,10 @@ import { BikesComponent } from './pages/bikes/bikes.component';
MatSlideToggleModule,
MatIconModule,
MatSidenavModule,
MatListModule
MatListModule,
MatFormFieldModule,
MatProgressSpinnerModule,
MatProgressBarModule
],
providers: [],
bootstrap: [AppComponent]

@ -0,0 +1,5 @@
export class User {
email: string;
requestToken: string;
refreshToken: string;
}

@ -1 +1,38 @@
<p>login works!</p>
<div id="login-form">
<h1>fLotte Login</h1>
<mat-form-field>
<mat-label>E-Mail-Adresse eingeben</mat-label>
<input matInput placeholder="fLotte@beispiel.de" [formControl]="email" />
<mat-error *ngIf="email.hasError('required')">
Bitte geben Sie eine E-Mail-Adresse ein.
</mat-error>
<mat-error *ngIf="email.hasError('email')">
Bitte geben Sie eine valide E-Mail-Adresse ein.
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Passwort eingeben</mat-label>
<input
matInput
[type]="hide ? 'password' : 'text'"
[formControl]="password"
/>
<mat-error *ngIf="password.hasError('required')">
Bitte geben Sie Ihr Passwort ein.
</mat-error>
<button
mat-icon-button
matSuffix
(click)="hide = !hide"
[attr.aria-label]="'Hide password'"
[attr.aria-pressed]="hide"
>
<mat-icon>{{ hide ? "visibility_off" : "visibility" }}</mat-icon>
</button>
</mat-form-field>
<mat-progress-bar mode="indeterminate" id="loading-bar" *ngIf="loading"></mat-progress-bar>
<button mat-stroked-button color="primary" (click)="login()">
Login
</button>
</div>

@ -0,0 +1,16 @@
#login-form {
height: 100%;
display: flex;
flex-direction: column;
max-width: 32em;
min-width: 5em;
margin: auto;
margin-top: 3em;
padding: 1em;
.mat-form-field {
margin: 0.5em 0;
}
#loading-bar {
margin-bottom: 1em;
}
}

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
import {FormControl, Validators} from '@angular/forms';
import {AuthService} from '../../services/auth.service';
@Component({
selector: 'app-login',
@ -6,10 +8,20 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
constructor() { }
email = new FormControl('', [Validators.required, Validators.email]);
password = new FormControl('', [Validators.required]);
hide = true;
loading = false;
constructor(private authService: AuthService) { }
ngOnInit(): void {
}
login() {
if (this.email.invalid || this.password.invalid) {
return;
}
this.authService.login(this.email.value, this.password.value).subscribe();
}
}

@ -0,0 +1,49 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class AuthService {
public loggedIn: BehaviorSubject<boolean>;
constructor(private http: HttpClient) {
this.loggedIn = new BehaviorSubject<boolean>(false);
this.checkIfUserIsLoggedIn();
}
private checkIfUserIsLoggedIn(): void {
this.loggedIn.next(!!this.requestToken);
}
public get requestToken(): string {
return localStorage.getItem('requestToken');
}
public get refreshToken(): string {
return localStorage.getItem('refreshToken');
}
login(email: string, password: string) {
return this.http
.post<any>(`${environment.authUrl}/login`, { email, password })
.pipe(
map((response) => {
// store request and refresh token in local storage to keep user logged in between page refreshes
localStorage.setItem('requestToken', response.request_token);
localStorage.setItem('refreshToken', response.refresh_token);
this.checkIfUserIsLoggedIn();
})
);
}
logout() {
// remove token from local storage to log user out
localStorage.removeItem('requestToken');
localStorage.removeItem('refreshToken');
this.checkIfUserIsLoggedIn();
}
}

@ -3,7 +3,9 @@
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
production: false,
apiUrl: "http://localhost:4000",
authUrl: "http://localhost:8080"
};
/*

@ -3,3 +3,17 @@
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
h1 {
display: block;
padding-bottom: 5px;
position: relative;
}
h1:before {
content: "";
position: absolute;
width: 5rem;
height: 1px;
bottom: 0;
border-bottom: 3px solid #7fc600;
}
Loading…
Cancel
Save