diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index ef35d97..c4ad87b 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -1,75 +1,35 @@ -
-
- Your Company -

- Sign in to your account -

-
+
+ + +

Login

-
-
- @if (invalidCredentials) { -
-

- Invalid Credentials -

-
- } -
- -
+ + + {{ errorMessages["email"] }} + Email -
-
- -
-
- -
-
+ + + {{ errorMessages["password"] }} + Password -
-
- -
- + + -
-
-
+ +
+
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 5faad83..11435df 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -1,12 +1,31 @@ import { Component } from '@angular/core'; -import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; import PocketBase from 'pocketbase'; import { environment } from '../../environments/environment'; import { Router } from '@angular/router'; +import { MatCardModule } from '@angular/material/card'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule, MatLabel } from '@angular/material/input'; +import { MatButton, MatButtonModule } from '@angular/material/button'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import {MatDividerModule} from '@angular/material/divider'; @Component({ selector: 'app-login', - imports: [ReactiveFormsModule], + imports: [ + ReactiveFormsModule, + MatCardModule, + MatInputModule, + MatLabel, + MatFormFieldModule, + MatButtonModule, + MatDividerModule, + ], templateUrl: './login.component.html', styleUrl: './login.component.css', }) @@ -14,21 +33,69 @@ export class LoginComponent { public loginForm!: FormGroup; public invalidCredentials = false; private pb = new PocketBase(environment.POCKETBASE); + public errorMessages: Record = {}; - constructor(private router: Router) {} + constructor( + private router: Router, + private snackBar: MatSnackBar, + ) { } + + private validationErrorMessages: Record = { + required: 'This field is required', + }; + + updateErrorMessages(): void { + this.errorMessages = {}; + + Object.keys(this.loginForm.controls).forEach((field) => { + const control = this.loginForm.get(field); + + if (control && control.errors) { + this.errorMessages[field] = Object.keys(control.errors) + .map( + (errorKey) => + this.validationErrorMessages[errorKey] || + `Unknown error: ${errorKey}`, + ) + .join(' '); + } + }); + } ngOnInit(): void { this.loginForm = new FormGroup({ - email: new FormControl(''), - password: new FormControl(''), + email: new FormControl('', Validators.required), + password: new FormControl('', Validators.required), }); if (this.pb.authStore.isValid) { this.router.navigate(['dashboard']); } + + this.loginForm.valueChanges.subscribe(() => { + this.updateErrorMessages(); + }); + } + + loginWithAuthentik() { + this.pb.collection('users').authWithOAuth2({ provider: 'oidc' }) + .then(() => { + this.router.navigate(['dashboard']); + }) + .catch(() => { + this.invalidCredentials = true; + const error = this.snackBar.open('Invalid Credentials'); + setTimeout(() => { + error.dismiss(); + }, 5000); + }); } submit() { + if (!this.loginForm.valid) { + this.updateErrorMessages(); + } + this.pb .collection('users') .authWithPassword( @@ -40,6 +107,10 @@ export class LoginComponent { }) .catch(() => { this.invalidCredentials = true; + const error = this.snackBar.open('Invalid Credentials'); + setTimeout(() => { + error.dismiss(); + }, 5000); }); } } diff --git a/src/styles.scss b/src/styles.scss index 5ef6f19..b1a863c 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -15,6 +15,8 @@ html { @apply underline text-blue-500 cursor-pointer; } + + html, body { height: 100%;