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 { 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 = [
|
||||
{
|
||||
@ -12,29 +7,4 @@ export const Auth_ROUTES: Routes = [
|
||||
component: SignIn,
|
||||
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>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
@ -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({
|
||||
selector: 'app-merchants',
|
||||
imports: [PageTitle, MerchantsList, MerchantsConfig, MerchantsHistory],
|
||||
imports: [PageTitle,
|
||||
//MerchantsList,
|
||||
//MerchantsConfig,
|
||||
//MerchantsHistory
|
||||
],
|
||||
templateUrl: './merchants.html',
|
||||
})
|
||||
export class Merchants {
|
||||
|
||||
@ -7,7 +7,7 @@ import { InputTouchspin } from '@/app/modules/components/input-touchspin';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config',
|
||||
imports: [FormsModule, UiCard, InputFields, CheckboxesAndRadios, InputTouchspin],
|
||||
//imports: [FormsModule, UiCard, InputFields, CheckboxesAndRadios, InputTouchspin],
|
||||
templateUrl: './config.html',
|
||||
})
|
||||
export class OperatorsConfig {
|
||||
|
||||
@ -278,8 +278,8 @@
|
||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||
<div class="text-muted">
|
||||
Affichage de {{ (filters.page! - 1) * filters.limit! + 1 }} à
|
||||
{{ (filters.page! * filters.limit!) > (paginatedData?.total || 0) ? (paginatedData?.total || 0) : (filters.page! * filters.limit!) }}
|
||||
sur {{ paginatedData?.total || 0 }} transactions
|
||||
{{ (filters.page! * filters.limit!) > (paginatedData.total || 0) ? (paginatedData.total || 0) : (filters.page! * filters.limit!) }}
|
||||
sur {{ paginatedData.total || 0 }} transactions
|
||||
</div>
|
||||
<nav>
|
||||
<ngb-pagination
|
||||
|
||||
Loading…
Reference in New Issue
Block a user