125 lines
3.4 KiB
TypeScript
125 lines
3.4 KiB
TypeScript
import { apiClient } from '@/services/api/client';
|
|
import { User, PaginatedResponse } from '@/types/api';
|
|
import { userSchema } from '@/schemas/apiSchemas';
|
|
|
|
/**
|
|
* Service pour la gestion des profils utilisateurs
|
|
* Aligné avec /api/v1/users backend
|
|
*/
|
|
export const userService = {
|
|
/**
|
|
* Récupère le profil d'un utilisateur par son ID
|
|
*/
|
|
getProfile: async (id: string) => {
|
|
const response = await apiClient.get<User>(`/users/${id}`, {
|
|
validateSchema: userSchema,
|
|
} as any);
|
|
return { profile: response.data };
|
|
},
|
|
|
|
/**
|
|
* Récupère le profil d'un utilisateur par son nom d'utilisateur
|
|
*/
|
|
getProfileByUsername: async (username: string) => {
|
|
const response = await apiClient.get<User>(
|
|
`/users/by-username/${username}`,
|
|
{
|
|
validateSchema: userSchema,
|
|
} as any,
|
|
);
|
|
return { profile: response.data };
|
|
},
|
|
|
|
/**
|
|
* Met à jour le profil de l'utilisateur
|
|
*/
|
|
updateProfile: async (id: string, data: any) => {
|
|
const response = await apiClient.put<User>(`/users/${id}`, data, {
|
|
validateSchema: userSchema,
|
|
} as any);
|
|
return { profile: response.data };
|
|
},
|
|
|
|
/**
|
|
* Récupère le taux de complétion du profil
|
|
*/
|
|
getProfileCompletion: async (id: string) => {
|
|
const response = await apiClient.get<{
|
|
completion_percentage: number;
|
|
missing_fields: string[];
|
|
}>(`/users/${id}/completion`);
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* Liste les utilisateurs avec pagination et recherche
|
|
*/
|
|
list: async (params?: {
|
|
page?: number;
|
|
limit?: number;
|
|
search?: string;
|
|
role?: string;
|
|
}) => {
|
|
const response = await apiClient.get<PaginatedResponse<User>>('/users', {
|
|
params: {
|
|
page: params?.page,
|
|
limit: params?.limit,
|
|
query: params?.search,
|
|
role: params?.role,
|
|
},
|
|
// Backend uses 'list' instead of 'items' for the root array
|
|
// We'll need a wrapper or handle it in the schema if we want strict validation
|
|
// For now, we manually map to satisfy the PaginatedResponse interface
|
|
});
|
|
|
|
// apiClient unwrap le format { success, data }
|
|
// Pour les listes, le backend retourne souvent { list: [], pagination: {} }
|
|
// Mais PaginatedResponse attend { items: [], ... }
|
|
const data = response.data as any;
|
|
const items = data.list || data.items || [];
|
|
|
|
return {
|
|
users: items,
|
|
pagination: data.pagination || {
|
|
total: data.total || items.length,
|
|
page: data.page || params?.page || 1,
|
|
limit: data.limit || params?.limit || 10,
|
|
total_pages: data.total_pages || 1,
|
|
},
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Supprime un utilisateur (soft delete)
|
|
*/
|
|
deleteUser: async (id: string) => {
|
|
await apiClient.delete(`/users/${id}`);
|
|
},
|
|
|
|
/**
|
|
* Récupère les paramètres de l'utilisateur connecté
|
|
*/
|
|
getSettings: async () => {
|
|
const response = await apiClient.get<any>('/users/settings');
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* Met à jour les paramètres de l'utilisateur connecté
|
|
*/
|
|
updateSettings: async (data: any) => {
|
|
const response = await apiClient.put<any>('/users/settings', data);
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* Exporte les données de l'utilisateur (GDPR)
|
|
*/
|
|
exportData: async () => {
|
|
// Cette route déclenche un téléchargement de fichier
|
|
window.open(
|
|
`${import.meta.env.VITE_API_URL || ''}/api/v1/users/me/export`,
|
|
'_blank',
|
|
);
|
|
},
|
|
};
|