veza/apps/web/src/services/userService.ts

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',
);
},
};