feat: add DCB User Service API - Authentication system with KEYCLOAK - Modular architecture with services for each feature
This commit is contained in:
parent
3bb7d21a7f
commit
0a7f1c6aa0
@ -1,10 +1,5 @@
|
|||||||
import { Routes } from '@angular/router'
|
import { Routes } from '@angular/router'
|
||||||
import { SignIn } from '@/app/modules/auth/sign-in'
|
import { SignIn } from '@/app/modules/auth/sign-in'
|
||||||
import { SignUp } from '@/app/modules/auth/sign-up'
|
|
||||||
import { ResetPassword } from '@/app/modules/auth/reset-password'
|
|
||||||
import { NewPassword } from '@/app/modules/auth/new-password'
|
|
||||||
import { TwoFactor } from '@/app/modules/auth/two-factor'
|
|
||||||
import { LockScreen } from '@/app/modules/auth/lock-screen'
|
|
||||||
|
|
||||||
export const Auth_ROUTES: Routes = [
|
export const Auth_ROUTES: Routes = [
|
||||||
{
|
{
|
||||||
@ -12,29 +7,4 @@ export const Auth_ROUTES: Routes = [
|
|||||||
component: SignIn,
|
component: SignIn,
|
||||||
data: { title: 'Sign In' },
|
data: { title: 'Sign In' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'auth/sign-up',
|
|
||||||
component: SignUp,
|
|
||||||
data: { title: 'Sign Up' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'auth/reset-password',
|
|
||||||
component: ResetPassword,
|
|
||||||
data: { title: 'Reset Password' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'auth/new-password',
|
|
||||||
component: NewPassword,
|
|
||||||
data: { title: 'New Password' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'auth/two-factor',
|
|
||||||
component: TwoFactor,
|
|
||||||
data: { title: 'Two Factor' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'auth/lock-screen',
|
|
||||||
component: LockScreen,
|
|
||||||
data: { title: 'Lock Screen' },
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,88 +0,0 @@
|
|||||||
import { Component } from '@angular/core'
|
|
||||||
import { appName, credits, currentYear } from '@/app/constants'
|
|
||||||
import { RouterLink } from '@angular/router'
|
|
||||||
import { AppLogo } from '@app/components/app-logo'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-lock-screen',
|
|
||||||
imports: [RouterLink, AppLogo],
|
|
||||||
template: `
|
|
||||||
<div class="auth-box overflow-hidden align-items-center d-flex">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-xxl-4 col-md-6 col-sm-8">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="auth-brand mb-4">
|
|
||||||
<app-app-logo />
|
|
||||||
<p class="text-muted w-lg-75 mt-3">
|
|
||||||
This screen is locked. Enter your password to continue
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center mb-4">
|
|
||||||
<img
|
|
||||||
src="assets/images/users/user-2.jpg"
|
|
||||||
class="rounded-circle img-thumbnail avatar-xxl mb-2"
|
|
||||||
alt="thumbnail"
|
|
||||||
/>
|
|
||||||
<span>
|
|
||||||
<h5 class="my-0 fw-semibold">Maxine Kennedy</h5>
|
|
||||||
<h6 class="my-0 text-muted">Admin Head</h6>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="userPassword" class="form-label"
|
|
||||||
>Password <span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
id="userPassword"
|
|
||||||
placeholder="••••••••"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-grid">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary fw-semibold py-2"
|
|
||||||
>
|
|
||||||
Unlock
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p class="text-muted text-center mt-4 mb-0">
|
|
||||||
Not you? Return to
|
|
||||||
<a
|
|
||||||
routerLink="/auth/sign-in"
|
|
||||||
class="text-decoration-underline link-offset-3 fw-semibold"
|
|
||||||
>Sign in</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="text-center text-muted mt-4 mb-0">
|
|
||||||
© {{ currentYear }} {{ appName }}. Tous droits réservés. — Développé par
|
|
||||||
<span class="fw-semibold">{{ credits.name }}</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: ``,
|
|
||||||
})
|
|
||||||
export class LockScreen {
|
|
||||||
protected readonly appName = appName
|
|
||||||
protected readonly currentYear = currentYear
|
|
||||||
protected readonly credits = credits
|
|
||||||
}
|
|
||||||
@ -1,163 +0,0 @@
|
|||||||
import { Component } from '@angular/core'
|
|
||||||
import { appName, credits, currentYear } from '@/app/constants'
|
|
||||||
import { RouterLink } from '@angular/router'
|
|
||||||
import { PasswordStrengthBar } from '@app/components/password-strength-bar'
|
|
||||||
import { FormsModule } from '@angular/forms'
|
|
||||||
import { AppLogo } from '@app/components/app-logo'
|
|
||||||
import { NgOtpInputModule } from 'ng-otp-input'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-new-password',
|
|
||||||
imports: [
|
|
||||||
RouterLink,
|
|
||||||
PasswordStrengthBar,
|
|
||||||
FormsModule,
|
|
||||||
AppLogo,
|
|
||||||
NgOtpInputModule,
|
|
||||||
],
|
|
||||||
template: `
|
|
||||||
<div class="auth-box overflow-hidden align-items-center d-flex">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-xxl-4 col-md-6 col-sm-8">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="auth-brand mb-4">
|
|
||||||
<app-app-logo />
|
|
||||||
<p class="text-muted mt-3">
|
|
||||||
We've emailed you a 6-digit verification code. Please enter
|
|
||||||
it below to confirm your email address
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="userEmail" class="form-label"
|
|
||||||
>Email address <span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
class="form-control"
|
|
||||||
id="userEmail"
|
|
||||||
placeholder="you@example.com"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label"
|
|
||||||
>Enter your 6-digit code
|
|
||||||
<span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<ng-otp-input
|
|
||||||
[config]="{
|
|
||||||
length: 6,
|
|
||||||
allowNumbersOnly: true,
|
|
||||||
inputClass: 'form-control text-center',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</ng-otp-input>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3" data-password="bar">
|
|
||||||
<label for="userPassword" class="form-label"
|
|
||||||
>Password <span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
name="password"
|
|
||||||
[(ngModel)]="password"
|
|
||||||
class="form-control"
|
|
||||||
id="userPassword"
|
|
||||||
placeholder="••••••••"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<app-password-strength-bar [password]="password" />
|
|
||||||
<div class="password-bar my-2"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="userNewPassword" class="form-label"
|
|
||||||
>Confirm New Password
|
|
||||||
<span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
id="userNewPassword"
|
|
||||||
placeholder="••••••••"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
class="form-check-input form-check-input-light fs-14"
|
|
||||||
type="checkbox"
|
|
||||||
id="termAndPolicy"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="termAndPolicy"
|
|
||||||
>Agree the Terms & Policy</label
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-grid">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary fw-semibold py-2"
|
|
||||||
>
|
|
||||||
Update Password
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p class="mt-4 text-muted text-center mb-4">
|
|
||||||
Don’t have a code?
|
|
||||||
<a
|
|
||||||
href="javascript:void(0);"
|
|
||||||
class="text-decoration-underline link-offset-2 fw-semibold"
|
|
||||||
>Resend</a
|
|
||||||
>
|
|
||||||
or
|
|
||||||
<a
|
|
||||||
href="javascript:void(0);"
|
|
||||||
class="text-decoration-underline link-offset-2 fw-semibold"
|
|
||||||
>Call Us</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p class="text-muted text-center mb-0">
|
|
||||||
Return to
|
|
||||||
<a
|
|
||||||
routerLink="/auth/sign-in"
|
|
||||||
class="text-decoration-underline link-offset-3 fw-semibold"
|
|
||||||
>Sign in</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="text-center text-muted mt-4 mb-0">
|
|
||||||
© {{ currentYear }} {{ appName }}. Tous droits réservés. — Développé par
|
|
||||||
<span class="fw-semibold">{{ credits.name }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: ``,
|
|
||||||
})
|
|
||||||
export class NewPassword {
|
|
||||||
password: string = ''
|
|
||||||
protected readonly appName = appName
|
|
||||||
protected readonly currentYear = currentYear
|
|
||||||
protected readonly credits = credits
|
|
||||||
}
|
|
||||||
@ -1,190 +0,0 @@
|
|||||||
import { Component, inject } from '@angular/core'
|
|
||||||
import { RouterLink } from '@angular/router'
|
|
||||||
import { FormsModule } from '@angular/forms'
|
|
||||||
import { AppLogo } from '@app/components/app-logo'
|
|
||||||
import { UsersService } from '../users/services/users.service'
|
|
||||||
import { credits, currentYear } from '@/app/constants'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-reset-password',
|
|
||||||
imports: [RouterLink, AppLogo, FormsModule],
|
|
||||||
template: `
|
|
||||||
<div class="auth-box overflow-hidden align-items-center d-flex">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-xxl-4 col-md-6 col-sm-8">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="auth-brand mb-4">
|
|
||||||
<app-app-logo />
|
|
||||||
<p class="text-muted w-lg-75 mt-3">
|
|
||||||
Entrez votre adresse email et nous vous enverrons un lien pour réinitialiser votre mot de passe.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Message de succès -->
|
|
||||||
<div *ngIf="successMessage" class="alert alert-success">
|
|
||||||
{{ successMessage }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Message d'erreur -->
|
|
||||||
<div *ngIf="errorMessage" class="alert alert-danger">
|
|
||||||
{{ errorMessage }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form (ngSubmit)="onSubmit()" #resetForm="ngForm">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="userEmail" class="form-label">
|
|
||||||
Adresse email <span class="text-danger">*</span>
|
|
||||||
</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
class="form-control"
|
|
||||||
id="userEmail"
|
|
||||||
placeholder="vous@exemple.com"
|
|
||||||
[(ngModel)]="email"
|
|
||||||
name="email"
|
|
||||||
required
|
|
||||||
email
|
|
||||||
[disabled]="loading"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
class="form-check-input form-check-input-light fs-14"
|
|
||||||
type="checkbox"
|
|
||||||
id="termAndPolicy"
|
|
||||||
[(ngModel)]="termsAccepted"
|
|
||||||
name="termsAccepted"
|
|
||||||
required
|
|
||||||
[disabled]="loading"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="termAndPolicy">
|
|
||||||
J'accepte les Conditions Générales d'Utilisation
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-grid">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary fw-semibold py-2"
|
|
||||||
[disabled]="loading || !resetForm.form.valid"
|
|
||||||
>
|
|
||||||
<span *ngIf="loading" class="spinner-border spinner-border-sm me-2"></span>
|
|
||||||
{{ loading ? 'Envoi en cours...' : 'Envoyer la demande' }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p class="text-muted text-center mt-4 mb-0">
|
|
||||||
Retour à
|
|
||||||
<a
|
|
||||||
routerLink="/auth/sign-in"
|
|
||||||
class="text-decoration-underline link-offset-3 fw-semibold"
|
|
||||||
>
|
|
||||||
Connexion
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="text-center text-muted mt-4 mb-0">
|
|
||||||
© {{ currentYear }} Simple — par
|
|
||||||
<span class="fw-semibold">{{ credits.name }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: [`
|
|
||||||
.auth-box {
|
|
||||||
min-height: 100vh;
|
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
border: none;
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class ResetPassword {
|
|
||||||
private usersService = inject(UsersService)
|
|
||||||
|
|
||||||
email = ''
|
|
||||||
termsAccepted = false
|
|
||||||
loading = false
|
|
||||||
successMessage = ''
|
|
||||||
errorMessage = ''
|
|
||||||
|
|
||||||
protected readonly currentYear = currentYear
|
|
||||||
protected readonly credits = credits
|
|
||||||
|
|
||||||
onSubmit() {
|
|
||||||
if (!this.email || !this.termsAccepted) {
|
|
||||||
this.errorMessage = 'Veuillez remplir tous les champs obligatoires et accepter les conditions.';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
this.successMessage = '';
|
|
||||||
this.errorMessage = '';
|
|
||||||
|
|
||||||
// Simulation d'envoi d'email de réinitialisation
|
|
||||||
// Note: Cette fonctionnalité nécessite un backend configuré pour envoyer des emails
|
|
||||||
this.usersService.findUserByEmail(this.email).subscribe({
|
|
||||||
next: (users) => {
|
|
||||||
this.loading = false;
|
|
||||||
|
|
||||||
if (users && users.length > 0) {
|
|
||||||
// Si l'utilisateur existe, afficher un message de succès
|
|
||||||
this.successMessage = 'Un lien de réinitialisation a été envoyé à votre adresse email.';
|
|
||||||
this.errorMessage = '';
|
|
||||||
|
|
||||||
// Ici, vous devriez normalement appeler un service backend
|
|
||||||
// qui envoie un email de réinitialisation
|
|
||||||
console.log('Email de réinitialisation envoyé à:', this.email);
|
|
||||||
} else {
|
|
||||||
this.errorMessage = 'Aucun utilisateur trouvé avec cette adresse email.';
|
|
||||||
this.successMessage = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
this.loading = false;
|
|
||||||
this.errorMessage = 'Une erreur est survenue lors de la recherche de l\'utilisateur.';
|
|
||||||
this.successMessage = '';
|
|
||||||
console.error('Error finding user:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alternative: Réinitialisation directe du mot de passe
|
|
||||||
resetPasswordDirectly(userId: string) {
|
|
||||||
const newPassword = prompt('Nouveau mot de passe:');
|
|
||||||
if (newPassword && newPassword.length >= 8) {
|
|
||||||
const resetDto = {
|
|
||||||
userId: userId,
|
|
||||||
newPassword: newPassword,
|
|
||||||
temporary: false
|
|
||||||
};
|
|
||||||
|
|
||||||
this.usersService.resetPassword(resetDto).subscribe({
|
|
||||||
next: () => {
|
|
||||||
alert('Mot de passe réinitialisé avec succès');
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
console.error('Error resetting password:', error);
|
|
||||||
alert('Erreur lors de la réinitialisation du mot de passe');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (newPassword) {
|
|
||||||
alert('Le mot de passe doit contenir au moins 8 caractères');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -112,15 +112,6 @@ import { appName, credits, currentYear } from '@/app/constants';
|
|||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p class="text-muted text-center mt-4 mb-0">
|
|
||||||
New here?
|
|
||||||
<a
|
|
||||||
routerLink="/auth/sign-up"
|
|
||||||
class="text-decoration-underline link-offset-3 fw-semibold"
|
|
||||||
>
|
|
||||||
Create an account
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,124 +0,0 @@
|
|||||||
import { Component } from '@angular/core'
|
|
||||||
import { appName, credits, currentYear } from '@/app/constants'
|
|
||||||
import { RouterLink } from '@angular/router'
|
|
||||||
import { AppLogo } from '@app/components/app-logo'
|
|
||||||
import { PasswordStrengthBar } from '@app/components/password-strength-bar'
|
|
||||||
import { FormsModule } from '@angular/forms'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-sign-up',
|
|
||||||
imports: [RouterLink, AppLogo, FormsModule, PasswordStrengthBar],
|
|
||||||
template: `
|
|
||||||
<div class="auth-box overflow-hidden align-items-center d-flex">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-xxl-4 col-md-6 col-sm-8">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="auth-brand mb-4">
|
|
||||||
<app-app-logo />
|
|
||||||
<p class="text-muted w-lg-75 mt-3">
|
|
||||||
Let’s get you started. Create your account by entering your
|
|
||||||
details below.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="userName" class="form-label"
|
|
||||||
>Name <span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
id="userName"
|
|
||||||
placeholder="Damian D."
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="userEmail" class="form-label"
|
|
||||||
>Email address <span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
class="form-control"
|
|
||||||
id="userEmail"
|
|
||||||
placeholder="you@example.com"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3" data-password="bar">
|
|
||||||
<label for="userPassword" class="form-label"
|
|
||||||
>Password <span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
name="password"
|
|
||||||
class="form-control"
|
|
||||||
id="userPassword"
|
|
||||||
placeholder="••••••••"
|
|
||||||
required
|
|
||||||
[(ngModel)]="password"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<app-password-strength-bar [password]="password" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
class="form-check-input form-check-input-light fs-14 mt-0"
|
|
||||||
type="checkbox"
|
|
||||||
id="termAndPolicy"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="termAndPolicy"
|
|
||||||
>Agree the Terms & Policy</label
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-grid">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary fw-semibold py-2"
|
|
||||||
>
|
|
||||||
Create Account
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p class="text-muted text-center mt-4 mb-0">
|
|
||||||
Already have an account?
|
|
||||||
<a
|
|
||||||
routerLink="/auth/sign-in"
|
|
||||||
class="text-decoration-underline link-offset-3 fw-semibold"
|
|
||||||
>Login</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="text-center text-muted mt-4 mb-0">
|
|
||||||
© {{ currentYear }} {{ appName }}. Tous droits réservés. — Développé par
|
|
||||||
<span class="fw-semibold">{{ credits.name }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: ``,
|
|
||||||
})
|
|
||||||
export class SignUp {
|
|
||||||
password: string = ''
|
|
||||||
protected readonly appName = appName
|
|
||||||
protected readonly currentYear = currentYear
|
|
||||||
protected readonly credits = credits
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
import { Component } from '@angular/core'
|
|
||||||
import { AppLogo } from '@app/components/app-logo'
|
|
||||||
import { NgOtpInputComponent } from 'ng-otp-input'
|
|
||||||
import { RouterLink } from '@angular/router'
|
|
||||||
import { appName, credits, currentYear } from '@/app/constants'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-two-factor',
|
|
||||||
imports: [AppLogo, NgOtpInputComponent, RouterLink],
|
|
||||||
template: `
|
|
||||||
<div class="auth-box overflow-hidden align-items-center d-flex">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-xxl-4 col-md-6 col-sm-8">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="auth-brand mb-4">
|
|
||||||
<app-app-logo />
|
|
||||||
<p class="text-muted w-lg-75 mt-3">
|
|
||||||
We've emailed you a 6-digit verification code we sent to
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center mb-4">
|
|
||||||
<div class="fw-bold fs-4">+ (12) ******6789</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<label class="form-label"
|
|
||||||
>Enter your 6-digit code
|
|
||||||
<span class="text-danger">*</span></label
|
|
||||||
>
|
|
||||||
<ngx-otp-input
|
|
||||||
[config]="{
|
|
||||||
length: 6,
|
|
||||||
allowNumbersOnly: true,
|
|
||||||
inputClass: 'form-control text-center mb-3',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
</ngx-otp-input>
|
|
||||||
|
|
||||||
<div class="d-grid">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary fw-semibold py-2"
|
|
||||||
>
|
|
||||||
Confirm
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p class="mt-4 text-muted text-center mb-4">
|
|
||||||
Don’t have a code?
|
|
||||||
<a
|
|
||||||
href="javascript:void(0);"
|
|
||||||
class="text-decoration-underline link-offset-2 fw-semibold"
|
|
||||||
>Resend</a
|
|
||||||
>
|
|
||||||
or
|
|
||||||
<a
|
|
||||||
href="javascript:void(0);"
|
|
||||||
class="text-decoration-underline link-offset-2 fw-semibold"
|
|
||||||
>Call Us</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
<p class="text-muted text-center mb-0">
|
|
||||||
Return to
|
|
||||||
<a
|
|
||||||
routerLink="/auth/sign-in"
|
|
||||||
class="text-decoration-underline link-offset-3 fw-semibold"
|
|
||||||
>Sign in</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="text-center text-muted mt-4 mb-0">
|
|
||||||
© {{ currentYear }} {{ appName }}. Tous droits réservés. — Développé par
|
|
||||||
<span class="fw-semibold">{{ credits.name }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: ``,
|
|
||||||
})
|
|
||||||
export class TwoFactor {
|
|
||||||
protected readonly appName = appName
|
|
||||||
protected readonly currentYear = currentYear
|
|
||||||
protected readonly credits = credits
|
|
||||||
}
|
|
||||||
@ -6,7 +6,11 @@ import { MerchantsHistory } from './history/history';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-merchants',
|
selector: 'app-merchants',
|
||||||
imports: [PageTitle, MerchantsList, MerchantsConfig, MerchantsHistory],
|
imports: [PageTitle,
|
||||||
|
//MerchantsList,
|
||||||
|
//MerchantsConfig,
|
||||||
|
//MerchantsHistory
|
||||||
|
],
|
||||||
templateUrl: './merchants.html',
|
templateUrl: './merchants.html',
|
||||||
})
|
})
|
||||||
export class Merchants {
|
export class Merchants {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { InputTouchspin } from '@/app/modules/components/input-touchspin';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-config',
|
selector: 'app-config',
|
||||||
imports: [FormsModule, UiCard, InputFields, CheckboxesAndRadios, InputTouchspin],
|
//imports: [FormsModule, UiCard, InputFields, CheckboxesAndRadios, InputTouchspin],
|
||||||
templateUrl: './config.html',
|
templateUrl: './config.html',
|
||||||
})
|
})
|
||||||
export class OperatorsConfig {
|
export class OperatorsConfig {
|
||||||
|
|||||||
@ -278,8 +278,8 @@
|
|||||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
Affichage de {{ (filters.page! - 1) * filters.limit! + 1 }} à
|
Affichage de {{ (filters.page! - 1) * filters.limit! + 1 }} à
|
||||||
{{ (filters.page! * filters.limit!) > (paginatedData?.total || 0) ? (paginatedData?.total || 0) : (filters.page! * filters.limit!) }}
|
{{ (filters.page! * filters.limit!) > (paginatedData.total || 0) ? (paginatedData.total || 0) : (filters.page! * filters.limit!) }}
|
||||||
sur {{ paginatedData?.total || 0 }} transactions
|
sur {{ paginatedData.total || 0 }} transactions
|
||||||
</div>
|
</div>
|
||||||
<nav>
|
<nav>
|
||||||
<ngb-pagination
|
<ngb-pagination
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user