dcb-backoffice/src/app/modules/users/list/list.ts

258 lines
7.5 KiB
TypeScript

import { Component, inject, OnInit, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgIcon } from '@ng-icons/core';
import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap';
import { UsersService } from '../services/users.service';
import { UserResponse } from '../models/user';
import { UiCard } from '@app/components/ui-card';
@Component({
selector: 'app-users-list',
standalone: true,
imports: [
CommonModule,
FormsModule,
NgIcon,
UiCard,
NgbPaginationModule
],
templateUrl: './list.html',
})
export class UsersList implements OnInit {
private usersService = inject(UsersService);
private cdRef = inject(ChangeDetectorRef);
@Output() userSelected = new EventEmitter<string>();
@Output() openCreateModal = new EventEmitter<void>();
@Output() openResetPasswordModal = new EventEmitter<string>();
@Output() openDeleteUserModal = new EventEmitter<string>();
// Données
allUsers: UserResponse[] = [];
filteredUsers: UserResponse[] = [];
displayedUsers: UserResponse[] = [];
// États
loading = false;
error = '';
// Recherche et filtres
searchTerm = '';
statusFilter: 'all' | 'enabled' | 'disabled' = 'all';
emailVerifiedFilter: 'all' | 'verified' | 'not-verified' = 'all';
// Pagination
currentPage = 1;
itemsPerPage = 10;
totalItems = 0;
totalPages = 0;
// Tri
sortField: keyof UserResponse = 'username';
sortDirection: 'asc' | 'desc' = 'asc';
ngOnInit() {
this.loadUsers();
}
loadUsers() {
this.loading = true;
this.error = '';
this.usersService.findAllUsers().subscribe({
next: (response) => {
this.allUsers = response.data;
this.applyFiltersAndPagination();
this.loading = false;
this.cdRef.detectChanges();
},
error: (error) => {
this.error = 'Erreur lors du chargement des utilisateurs';
this.loading = false;
this.cdRef.detectChanges();
console.error('Error loading users:', error);
}
});
}
// Recherche et filtres
onSearch() {
this.currentPage = 1;
this.applyFiltersAndPagination();
}
onClearFilters() {
this.searchTerm = '';
this.statusFilter = 'all';
this.emailVerifiedFilter = 'all';
this.currentPage = 1;
this.applyFiltersAndPagination();
}
applyFiltersAndPagination() {
// Appliquer les filtres
this.filteredUsers = this.allUsers.filter(user => {
// Filtre de recherche
const matchesSearch = !this.searchTerm ||
user.username.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
user.email.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
user.firstName?.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
user.lastName?.toLowerCase().includes(this.searchTerm.toLowerCase());
// Filtre par statut
const matchesStatus = this.statusFilter === 'all' ||
(this.statusFilter === 'enabled' && user.enabled) ||
(this.statusFilter === 'disabled' && !user.enabled);
// Filtre par email vérifié
const matchesEmailVerified = this.emailVerifiedFilter === 'all' ||
(this.emailVerifiedFilter === 'verified' && user.emailVerified) ||
(this.emailVerifiedFilter === 'not-verified' && !user.emailVerified);
return matchesSearch && matchesStatus && matchesEmailVerified;
});
// Appliquer le tri
this.filteredUsers.sort((a, b) => {
const aValue = a[this.sortField];
const bValue = b[this.sortField];
if (aValue === bValue) return 0;
let comparison = 0;
if (typeof aValue === 'string' && typeof bValue === 'string') {
comparison = aValue.localeCompare(bValue);
} else if (typeof aValue === 'number' && typeof bValue === 'number') {
comparison = aValue - bValue;
} else if (typeof aValue === 'boolean' && typeof bValue === 'boolean') {
comparison = (aValue === bValue) ? 0 : aValue ? -1 : 1;
}
return this.sortDirection === 'asc' ? comparison : -comparison;
});
// Calculer la pagination
this.totalItems = this.filteredUsers.length;
this.totalPages = Math.ceil(this.totalItems / this.itemsPerPage);
// Appliquer la pagination
const startIndex = (this.currentPage - 1) * this.itemsPerPage;
const endIndex = startIndex + this.itemsPerPage;
this.displayedUsers = this.filteredUsers.slice(startIndex, endIndex);
}
// Tri
sort(field: keyof UserResponse) {
if (this.sortField === field) {
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
} else {
this.sortField = field;
this.sortDirection = 'asc';
}
this.applyFiltersAndPagination();
}
getSortIcon(field: keyof UserResponse): string {
if (this.sortField !== field) return 'lucideArrowUpDown';
return this.sortDirection === 'asc' ? 'lucideArrowUp' : 'lucideArrowDown';
}
// Pagination
onPageChange(page: number) {
this.currentPage = page;
this.applyFiltersAndPagination();
}
getStartIndex(): number {
return (this.currentPage - 1) * this.itemsPerPage + 1;
}
getEndIndex(): number {
return Math.min(this.currentPage * this.itemsPerPage, this.totalItems);
}
// Actions
viewUserProfile(userId: string) {
this.userSelected.emit(userId);
}
// Méthode pour réinitialiser le mot de passe
resetPassword(user: UserResponse) {
this.openResetPasswordModal.emit(user.id);
}
// Méthode pour ouvrir le modal de suppression
deleteUser(user: UserResponse) {
this.openDeleteUserModal.emit(user.id);
}
enableUser(user: UserResponse) {
this.usersService.enableUser(user.id).subscribe({
next: () => {
user.enabled = true;
this.applyFiltersAndPagination();
this.cdRef.detectChanges();
},
error: (error) => {
console.error('Error enabling user:', error);
alert('Erreur lors de l\'activation de l\'utilisateur');
}
});
}
disableUser(user: UserResponse) {
this.usersService.disableUser(user.id).subscribe({
next: () => {
user.enabled = false;
this.applyFiltersAndPagination();
this.cdRef.detectChanges();
},
error: (error) => {
console.error('Error disabling user:', error);
alert('Erreur lors de la désactivation de l\'utilisateur');
}
});
}
// Utilitaires d'affichage
getStatusBadgeClass(user: UserResponse): string {
if (!user.enabled) return 'badge bg-danger';
if (!user.emailVerified) return 'badge bg-warning';
return 'badge bg-success';
}
getStatusText(user: UserResponse): string {
if (!user.enabled) return 'Désactivé';
if (!user.emailVerified) return 'Email non vérifié';
return 'Actif';
}
getRoleBadgeClass(role: string): string {
switch (role) {
case 'admin': return 'bg-danger';
case 'merchant': return 'bg-success';
case 'support': return 'bg-info';
case 'user': return 'bg-secondary';
default: return 'bg-secondary';
}
}
formatTimestamp(timestamp: number): string {
return new Date(timestamp).toLocaleDateString('fr-FR');
}
getUserInitials(user: UserResponse): string {
return (user.firstName?.charAt(0) || '') + (user.lastName?.charAt(0) || '') || 'U';
}
getUserDisplayName(user: UserResponse): string {
if (user.firstName && user.lastName) {
return `${user.firstName} ${user.lastName}`;
}
return user.username;
}
}