Merge pull request 'feat(auth): move recover password page to modal' (!196) from 1 into main
Reviewed-on: #196 Reviewed-by: Phan Huy Tran <ptran@noreply.localhost>
This commit is contained in:
commit
4f2e7fe712
5 changed files with 212 additions and 176 deletions
|
@ -5,8 +5,8 @@
|
|||
</main>
|
||||
<app-footer></app-footer>
|
||||
|
||||
Auth Forms Overlay -->
|
||||
@if (showLogin() || showRegister()) {
|
||||
<!-- Auth Forms Overlay -->
|
||||
@if (showLogin() || showRegister() || showRecoverPassword()) {
|
||||
<div
|
||||
class="fixed inset-0 bg-black/50 z-40"
|
||||
(click)="hideAuthForms()"
|
||||
|
@ -18,7 +18,11 @@
|
|||
<div class="fixed inset-0 flex items-center justify-center z-50 p-4" role="presentation">
|
||||
<div class="relative" role="dialog" aria-modal="true">
|
||||
@if (showLogin()) {
|
||||
<app-login (switchForm)="showRegisterForm()" (closeDialog)="hideAuthForms()"></app-login>
|
||||
<app-login
|
||||
(switchForm)="showRegisterForm()"
|
||||
(closeDialog)="hideAuthForms()"
|
||||
(forgotPassword)="showRecoverPasswordForm()"
|
||||
></app-login>
|
||||
}
|
||||
@if (showRegister()) {
|
||||
<app-register
|
||||
|
@ -26,6 +30,12 @@
|
|||
(closeDialog)="hideAuthForms()"
|
||||
></app-register>
|
||||
}
|
||||
@if (showRecoverPassword()) {
|
||||
<app-recover-password
|
||||
(closeDialog)="hideAuthForms()"
|
||||
(switchToLogin)="showLoginForm()"
|
||||
></app-recover-password>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -4,16 +4,25 @@ import { NavbarComponent } from './shared/components/navbar/navbar.component';
|
|||
import { FooterComponent } from './shared/components/footer/footer.component';
|
||||
import { LoginComponent } from './feature/auth/login/login.component';
|
||||
import { RegisterComponent } from './feature/auth/register/register.component';
|
||||
import { RecoverPasswordComponent } from './feature/auth/recover-password/recover-password.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet, NavbarComponent, FooterComponent, LoginComponent, RegisterComponent],
|
||||
imports: [
|
||||
RouterOutlet,
|
||||
NavbarComponent,
|
||||
FooterComponent,
|
||||
LoginComponent,
|
||||
RegisterComponent,
|
||||
RecoverPasswordComponent,
|
||||
],
|
||||
templateUrl: './app.component.html',
|
||||
})
|
||||
export class AppComponent {
|
||||
showLogin = signal(false);
|
||||
showRegister = signal(false);
|
||||
showRecoverPassword = signal(false);
|
||||
|
||||
@HostListener('document:keydown.escape')
|
||||
handleEscapeKey() {
|
||||
|
@ -23,18 +32,28 @@ export class AppComponent {
|
|||
showLoginForm() {
|
||||
this.showLogin.set(true);
|
||||
this.showRegister.set(false);
|
||||
this.showRecoverPassword.set(false);
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
showRegisterForm() {
|
||||
this.showRegister.set(true);
|
||||
this.showLogin.set(false);
|
||||
this.showRecoverPassword.set(false);
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
showRecoverPasswordForm() {
|
||||
this.showRecoverPassword.set(true);
|
||||
this.showLogin.set(false);
|
||||
this.showRegister.set(false);
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
hideAuthForms() {
|
||||
this.showLogin.set(false);
|
||||
this.showRegister.set(false);
|
||||
this.showRecoverPassword.set(false);
|
||||
document.body.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ export class LoginComponent {
|
|||
isLoading = signal(false);
|
||||
@Output() switchForm = new EventEmitter<void>();
|
||||
@Output() closeDialog = new EventEmitter<void>();
|
||||
@Output() forgotPassword = new EventEmitter<void>();
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
|
@ -65,7 +66,6 @@ export class LoginComponent {
|
|||
}
|
||||
|
||||
switchToForgotPassword() {
|
||||
this.closeDialog.emit();
|
||||
this.router.navigate(['/recover-password']);
|
||||
this.forgotPassword.emit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<div class="min-h-screen bg-deep-blue flex items-center justify-center">
|
||||
<div class="modal-card max-w-md w-full bg-deep-blue rounded-lg shadow-xl p-6 relative">
|
||||
<button
|
||||
(click)="closeDialog.emit()"
|
||||
|
@ -160,13 +159,12 @@
|
|||
|
||||
<div class="mt-6 text-center">
|
||||
<p class="text-sm text-text-secondary">
|
||||
<a
|
||||
routerLink="/"
|
||||
<button
|
||||
(click)="goBackToLogin()"
|
||||
class="font-medium text-emerald hover:text-emerald-light transition-all duration-200"
|
||||
>
|
||||
Zurück zur Startseite
|
||||
</a>
|
||||
Zurück zum Login
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { Component, EventEmitter, Output, signal } from '@angular/core';
|
||||
import { Component, EventEmitter, Output, signal, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||
import { AuthService } from '@service/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-recover-password',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule],
|
||||
imports: [CommonModule, ReactiveFormsModule, RouterModule],
|
||||
templateUrl: './recover-password.component.html',
|
||||
})
|
||||
export class RecoverPasswordComponent {
|
||||
export class RecoverPasswordComponent implements OnInit {
|
||||
emailForm: FormGroup;
|
||||
resetPasswordForm: FormGroup;
|
||||
errorMessage = signal('');
|
||||
|
@ -20,6 +20,7 @@ export class RecoverPasswordComponent {
|
|||
isResetMode = signal(false);
|
||||
|
||||
@Output() closeDialog = new EventEmitter<void>();
|
||||
@Output() switchToLogin = new EventEmitter<void>();
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
|
@ -40,8 +41,11 @@ export class RecoverPasswordComponent {
|
|||
validators: this.passwordMatchValidator,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Check if we're in reset mode
|
||||
ngOnInit(): void {
|
||||
// Check if we're in reset mode via URL parameters
|
||||
// This is still needed for direct access via URLs with token
|
||||
this.route.queryParamMap.subscribe((params) => {
|
||||
const token = params.get('token');
|
||||
if (token) {
|
||||
|
@ -111,7 +115,8 @@ export class RecoverPasswordComponent {
|
|||
'Dein Passwort wurde erfolgreich zurückgesetzt. Du kannst dich jetzt anmelden.'
|
||||
);
|
||||
setTimeout(() => {
|
||||
this.router.navigate([''], { queryParams: { login: true } });
|
||||
this.closeDialog.emit();
|
||||
this.switchToLogin.emit();
|
||||
}, 3000);
|
||||
},
|
||||
error: (err) => {
|
||||
|
@ -122,4 +127,8 @@ export class RecoverPasswordComponent {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
goBackToLogin(): void {
|
||||
this.switchToLogin.emit();
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue