diff --git a/app/admin/utilisateurs/[id]/page.tsx b/app/admin/utilisateurs/[id]/page.tsx new file mode 100644 index 0000000..b2bd093 --- /dev/null +++ b/app/admin/utilisateurs/[id]/page.tsx @@ -0,0 +1,262 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { useRouter, useParams } from 'next/navigation'; +import { adminService } from '@/services/admin.service'; +import { User } from '@/types'; +import { ArrowLeft, Mail, Phone, MapPin, Calendar, Award, Ticket, CheckCircle, Clock } from 'lucide-react'; +import toast from 'react-hot-toast'; + +export default function UserDetailsPage() { + const router = useRouter(); + const params = useParams(); + const userId = params.id as string; + + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + loadUserDetails(); + }, [userId]); + + const loadUserDetails = async () => { + try { + setLoading(true); + setError(null); + const userData = await adminService.getUserById(userId); + setUser(userData); + } catch (err: any) { + setError(err.message || 'Erreur lors du chargement des détails'); + toast.error('Erreur lors du chargement des détails de l\'utilisateur'); + } finally { + setLoading(false); + } + }; + + const getRoleBadgeColor = (role: string) => { + switch (role) { + case 'ADMIN': + return 'bg-red-100 text-red-800'; + case 'EMPLOYEE': + return 'bg-blue-100 text-blue-800'; + case 'CLIENT': + return 'bg-green-100 text-green-800'; + default: + return 'bg-gray-100 text-gray-800'; + } + }; + + if (loading) { + return ( +
+
+
+
+
+
+ ); + } + + if (error || !user) { + return ( +
+
+ {error || 'Utilisateur non trouvé'} +
+ +
+ ); + } + + return ( +
+ {/* Header */} +
+ +
+
+

+ {user.firstName} {user.lastName} +

+

Détails de l'utilisateur

+
+ + {user.role} + +
+
+ +
+ {/* Informations principales */} +
+ {/* Informations de contact */} +
+

Informations de contact

+
+
+ +
+

Email

+

{user.email}

+
+
+ {user.phone && ( +
+ +
+

Téléphone

+

{user.phone}

+
+
+ )} + {(user.address || user.city || user.postalCode) && ( +
+ +
+

Adresse

+

+ {user.address && <>{user.address}
} + {user.postalCode && user.city && `${user.postalCode} ${user.city}`} +

+
+
+ )} +
+
+ + {/* Informations personnelles */} + {(user.dateOfBirth || user.gender) && ( +
+

Informations personnelles

+
+ {user.dateOfBirth && ( +
+

Date de naissance

+

+ {new Date(user.dateOfBirth).toLocaleDateString('fr-FR', { + day: 'numeric', + month: 'long', + year: 'numeric' + })} +

+
+ )} + {user.gender && ( +
+

Genre

+

+ {user.gender === 'MALE' ? 'Homme' : + user.gender === 'FEMALE' ? 'Femme' : + user.gender === 'OTHER' ? 'Autre' : 'Non spécifié'} +

+
+ )} +
+
+ )} + + {/* Statistiques de tickets */} + {user.role === 'CLIENT' && ( +
+

Activité des tickets

+
+
+ +

{user.ticketsCount || 0}

+

Total tickets

+
+
+ +

{user.pendingTickets || 0}

+

En attente

+
+
+ +

{user.claimedTickets || 0}

+

Réclamés

+
+
+
+ )} +
+ + {/* Sidebar */} +
+ {/* Statut du compte */} +
+

Statut du compte

+
+
+

Vérification email

+ + {user.isVerified ? ( + <> + + Vérifié + + ) : ( + <> + + Non vérifié + + )} + +
+
+

Membre depuis

+
+ + + {new Date(user.createdAt).toLocaleDateString('fr-FR', { + day: 'numeric', + month: 'long', + year: 'numeric' + })} + +
+
+
+
+ + {/* Actions rapides */} +
+

Actions

+
+ + {user.role === 'CLIENT' && ( + + )} +
+
+
+
+
+ ); +} diff --git a/services/admin.service.ts b/services/admin.service.ts index 014cdfb..a0b95bf 100644 --- a/services/admin.service.ts +++ b/services/admin.service.ts @@ -96,6 +96,36 @@ export const adminService = { // ==================== GESTION DES UTILISATEURS ==================== + /** + * Récupérer un utilisateur par ID + */ + getUserById: async (userId: string): Promise => { + const response = await api.get>( + `${API_ENDPOINTS.USERS}/${userId}` + ); + + // Convert snake_case to camelCase + const user = response.data; + return { + id: user.id, + email: user.email, + firstName: user.first_name || user.firstName, + lastName: user.last_name || user.lastName, + phone: user.phone, + address: user.address, + city: user.city, + postalCode: user.postal_code || user.postalCode, + role: user.role, + isVerified: user.is_verified !== undefined ? user.is_verified : user.isVerified, + createdAt: user.created_at || user.createdAt, + ticketsCount: user.tickets_count || user.ticketsCount || 0, + pendingTickets: user.pending_tickets || user.pendingTickets || 0, + claimedTickets: user.claimed_tickets || user.claimedTickets || 0, + dateOfBirth: user.date_of_birth || user.dateOfBirth, + gender: user.gender, + } as User; + }, + /** * Récupérer tous les utilisateurs (paginé) */