1
0
Fork 0
mirror of https://codeberg.org/beerbrawl/beerbrawl.git synced 2024-09-23 05:40:51 +02:00

feat(#8): frontend/components: add component for user self-registration

Signed-off-by: Christoph Heiss <e11907069@student.tuwien.ac.at>
This commit is contained in:
Christoph Heiss 2024-05-10 18:50:03 +02:00
parent e9977652d3
commit 29284b32e9
Signed by: c8h4
GPG key ID: 73D5E7FDEE3DE49A
7 changed files with 156 additions and 12 deletions

View file

@ -4,10 +4,12 @@ import { HomeComponent } from './components/home/home.component';
import { LoginDialogComponent } from './components/login/login-dialog.component';
import { AuthGuard } from './guards/auth.guard';
import { MessageComponent } from './components/message/message.component';
import { RegisterComponent } from './components/register/register.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'login', component: LoginDialogComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'message', canActivate: mapToCanActivate([AuthGuard]), component: MessageComponent },
];

View file

@ -9,23 +9,17 @@ import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component';
import { HomeComponent } from './components/home/home.component';
import { LoginDialogComponent } from './components/login/login-dialog.component';
import { RegisterComponent } from './components/register/register.component';
import { MessageComponent } from './components/message/message.component';
import { httpInterceptorProviders } from './interceptors';
import { MatToolbar } from '@angular/material/toolbar';
import { MatIcon } from '@angular/material/icon';
import { MatButton, MatIconButton } from '@angular/material/button';
import { MatTooltip } from '@angular/material/tooltip';
import {
MatCard,
MatCardActions,
MatCardContent,
MatCardHeader,
MatCardModule,
MatCardTitle,
} from '@angular/material/card';
import { MatCardModule } from '@angular/material/card';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatDialogModule, MatDialogTitle } from '@angular/material/dialog';
import { MatFormField, MatFormFieldModule } from '@angular/material/form-field';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInput } from '@angular/material/input';
@NgModule({
@ -36,6 +30,7 @@ import { MatInput } from '@angular/material/input';
HomeComponent,
LoginDialogComponent,
MessageComponent,
RegisterComponent,
],
imports: [
BrowserModule,

View file

@ -25,13 +25,22 @@
</button>
} @else {
<button
mat-flat-button
data-cy="open-login-dialog-button"
(click)="openLoginService.openLoginDialog()"
mat-icon-button
aria-label="Login"
[matTooltip]="'Login'"
>
<mat-icon>login</mat-icon>
Login <mat-icon>login</mat-icon>
</button>
<button
mat-flat-button
color="primary"
[routerLink]="'/register'"
aria-label="Register"
[matTooltip]="'Go to register page'"
>
Register <mat-icon>person_add</mat-icon>
</button>
}
</div>

View file

@ -0,0 +1,40 @@
<h2 class="title">Registration</h2>
<div class="content">
<form class="form" [formGroup]="form" (ngSubmit)="registerUser()">
<mat-form-field appearance="outline">
<mat-label>Username</mat-label>
<input
matInput
type="text"
name="username"
formControlName="username"
aria-describedby="usernameHelp"
min="3"
/>
@if (form.controls.username?.errors?.required) {
<mat-error>A username is required!</mat-error>
} @else if (form.controls.username?.errors?.minlength) {
<mat-error>Username must be at least 3 characters long!</mat-error>
}
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Password</mat-label>
<input matInput type="password" name="password" min="8" formControlName="password" />
@if (form.controls.password?.errors?.required) {
<mat-error>A password is required!</mat-error>
} @else if (form.controls.password?.errors?.minlength) {
<mat-error>Password must be at least 8 characters long!</mat-error>
}
</mat-form-field>
<button
data-cy="register-button"
type="button"
(click)="registerUser()"
mat-raised-button
color="primary"
>
Register
</button>
</form>
</div>

View file

@ -0,0 +1,12 @@
.title {
margin-top: 1em;
text-align: center;
}
.form {
display: flex;
flex-direction: column;
gap: 1rem;
margin: 0 auto;
max-width: 400px;
}

View file

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

View file

@ -0,0 +1,64 @@
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { AuthRequest } from 'src/app/dtos/auth-request';
import { MatSnackBar } from '@angular/material/snack-bar';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrl: './register.component.scss',
})
export class RegisterComponent {
form = new FormGroup({
username: new FormControl('', [Validators.required, Validators.minLength(3)]),
password: new FormControl('', [Validators.required, Validators.minLength(8)]),
});
constructor(
private authService: AuthService,
private router: Router,
private snackBar: MatSnackBar,
) {}
/**
* Form validation will start after the method is called, additionally an
* registation request will be sent.
*/
registerUser() {
if (this.form.valid) {
const authRequest: AuthRequest = new AuthRequest(
this.form.controls.username.value!,
this.form.controls.password.value!,
);
this.sendAuthRequest(authRequest);
} else {
console.log('Invalid input', this.form);
}
}
/**
* Send authentication data to the authService. If the registration was
* successfully, the user will be forwarded to the home page.
*
* @param authRequest authentication data from the user login form
*/
private sendAuthRequest(authRequest: AuthRequest) {
console.log('Trying to register user: ' + authRequest.username);
this.authService.registerUser(authRequest).subscribe({
next: () => {
console.log(`Successfully registered with username: ${authRequest.username}`);
this.snackBar.open(`Successfully registered new user '${authRequest.username}'`, 'Close', {
duration: 3000,
});
this.router.navigate(['/']);
},
error: error => {
console.log('Could not register new user due to:');
console.log(error.error);
this.snackBar.open(error.error, 'Close', { duration: 5000 });
},
});
}
}