From b2186978673e5223e5d10c7b1dfdc0326acf00a3 Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Tue, 21 Jan 2025 14:10:39 +0100 Subject: [PATCH 1/2] feat(login): update login form with material design elements --- src/app/login/login.component.html | 92 ++++++------------------------ src/app/login/login.component.ts | 50 ++++++++++++++-- 2 files changed, 64 insertions(+), 78 deletions(-) diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index ef35d97..4706676 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -1,75 +1,21 @@ -
-
- 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..8f9c5ab 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -1,12 +1,17 @@ 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'; @Component({ selector: 'app-login', - imports: [ReactiveFormsModule], + imports: [ReactiveFormsModule, MatCardModule, MatInputModule, MatLabel, MatFormFieldModule, MatButtonModule], templateUrl: './login.component.html', styleUrl: './login.component.css', }) @@ -14,21 +19,52 @@ 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(); + }); } submit() { + if (!this.loginForm.valid) { + this.updateErrorMessages(); + } + this.pb .collection('users') .authWithPassword( @@ -40,6 +76,10 @@ export class LoginComponent { }) .catch(() => { this.invalidCredentials = true; + const error = this.snackBar.open('Invalid Credentials'); + setTimeout(() => { + error.dismiss(); + }, 5000); }); } } From cb658a77210499a2d731d4448f4030f01c5fc160 Mon Sep 17 00:00:00 2001 From: Jan Klattenhoff Date: Tue, 21 Jan 2025 14:48:09 +0100 Subject: [PATCH 2/2] feat(login): add Authentik login button and functionality --- src/app/login/login.component.html | 20 +++++++++++++--- src/app/login/login.component.ts | 37 +++++++++++++++++++++++++++--- src/styles.scss | 2 ++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 4706676..c4ad87b 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -7,14 +7,28 @@ {{ errorMessages["email"] }} Email - + {{ errorMessages["password"] }} Password - + - + + + diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 8f9c5ab..11435df 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -1,5 +1,10 @@ import { Component } from '@angular/core'; -import { FormControl, FormGroup, ReactiveFormsModule, Validators } 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'; @@ -8,10 +13,19 @@ 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, MatCardModule, MatInputModule, MatLabel, MatFormFieldModule, MatButtonModule], + imports: [ + ReactiveFormsModule, + MatCardModule, + MatInputModule, + MatLabel, + MatFormFieldModule, + MatButtonModule, + MatDividerModule, + ], templateUrl: './login.component.html', styleUrl: './login.component.css', }) @@ -21,7 +35,10 @@ export class LoginComponent { private pb = new PocketBase(environment.POCKETBASE); public errorMessages: Record = {}; - constructor(private router: Router, private snackBar: MatSnackBar) { } + constructor( + private router: Router, + private snackBar: MatSnackBar, + ) { } private validationErrorMessages: Record = { required: 'This field is required', @@ -60,6 +77,20 @@ export class LoginComponent { }); } + 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(); 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%;