feat: add Master Admin application functionality
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
import { ChangeDetectorRef, Component, inject } from '@angular/core';
|
||||
import { FormBuilder, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||
import { AuthService } from '../../../../core/services/auth/auth.service';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { catchError, finalize, of, switchMap, tap } from 'rxjs';
|
||||
import { AppContextService } from '../../../../core/services/context/app-context.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
standalone: true,
|
||||
imports: [RouterModule, ReactiveFormsModule],
|
||||
|
||||
templateUrl: './login.html',
|
||||
styleUrl: './login.scss'
|
||||
})
|
||||
export class Login {
|
||||
private readonly formBuilder = inject(FormBuilder);
|
||||
private readonly cdr = inject(ChangeDetectorRef);
|
||||
private readonly fallbackRoute = '/dashboards/crm';
|
||||
|
||||
public readonly adminLoginForm = this.formBuilder.nonNullable.group({
|
||||
username: ['', [Validators.required, Validators.email]],
|
||||
password: ['', Validators.required],
|
||||
rememberMe: [false]
|
||||
});
|
||||
public isSubmitting = false;
|
||||
public loginError = '';
|
||||
public visibilityMap: Record<string, boolean> = {
|
||||
Angular: false
|
||||
};
|
||||
public iconMap: Record<string, string> = {
|
||||
Angular: 'fe fe-eye-off'
|
||||
};
|
||||
|
||||
constructor(
|
||||
public authservice: AuthService,
|
||||
private appContextService: AppContextService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private toastr: ToastrService
|
||||
) { }
|
||||
|
||||
login() {
|
||||
this.loginError = '';
|
||||
|
||||
if (this.adminLoginForm.invalid) {
|
||||
this.adminLoginForm.markAllAsTouched();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isSubmitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isSubmitting = true;
|
||||
|
||||
const { username, password, rememberMe } = this.adminLoginForm.getRawValue();
|
||||
|
||||
this.authservice.login({ email: username, password }, !!rememberMe)
|
||||
.pipe(
|
||||
switchMap(() =>
|
||||
this.appContextService.ensureMenuInitialized(true).pipe(
|
||||
catchError(() => {
|
||||
this.authservice.logout();
|
||||
this.loginError = 'Unable to load application context.';
|
||||
return of(null);
|
||||
})
|
||||
)
|
||||
),
|
||||
finalize(() => {
|
||||
this.isSubmitting = false;
|
||||
this.cdr.detectChanges();
|
||||
})
|
||||
)
|
||||
.subscribe({
|
||||
next: () => {
|
||||
if (this.loginError) {
|
||||
this.toastr.error(this.loginError);
|
||||
return;
|
||||
}
|
||||
|
||||
void this.router.navigateByUrl(this.getSafeReturnUrl());
|
||||
this.toastr.success('Login successful', username);
|
||||
},
|
||||
error: (error) => {
|
||||
this.loginError =
|
||||
error?.error?.detail ||
|
||||
error?.error?.message ||
|
||||
'Invalid email or password';
|
||||
|
||||
this.toastr.error(this.loginError);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleVisibility(tab: string): void {
|
||||
this.visibilityMap[tab] = !this.visibilityMap[tab];
|
||||
this.iconMap[tab] = this.visibilityMap[tab] ? 'fe fe-eye' : 'fe fe-eye-off';
|
||||
}
|
||||
|
||||
private getSafeReturnUrl(): string {
|
||||
const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl')?.trim() ?? '';
|
||||
if (!returnUrl) {
|
||||
return this.fallbackRoute;
|
||||
}
|
||||
|
||||
const lowerReturnUrl = returnUrl.toLowerCase();
|
||||
const isSafeInternalUrl =
|
||||
returnUrl.startsWith('/') &&
|
||||
!returnUrl.startsWith('//') &&
|
||||
!returnUrl.includes('\\') &&
|
||||
!lowerReturnUrl.includes('http://') &&
|
||||
!lowerReturnUrl.includes('https://');
|
||||
|
||||
return isSafeInternalUrl ? returnUrl : this.fallbackRoute;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user