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(); @Output() openCreateModal = new EventEmitter(); @Output() openResetPasswordModal = new EventEmitter(); @Output() openDeleteUserModal = new EventEmitter(); // 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; } }