import { api } from './api'; import { AdminStatistics, Ticket, User, Prize, CreatePrizeData, UpdatePrizeData, CreateEmployeeData, UpdateUserData, ApiResponse, PaginatedResponse } from '@/types'; const API_ENDPOINTS = { STATISTICS: '/admin/statistics', TICKETS: '/admin/tickets', USERS: '/admin/users', PRIZES: '/admin/prizes', EMPLOYEES: '/admin/employees', }; export const adminService = { // ==================== STATISTIQUES ==================== /** * Récupérer les statistiques globales */ getStatistics: async (): Promise => { const response = await api.get>( API_ENDPOINTS.STATISTICS ); return response.data!; }, // ==================== GESTION DES PRIX ==================== /** * Récupérer tous les prix */ getAllPrizes: async (): Promise => { const response = await api.get>( API_ENDPOINTS.PRIZES ); // Transformer snake_case en camelCase const prizes = response.data?.map((prize: any) => ({ id: prize.id, name: prize.name, type: prize.type, description: prize.description, value: prize.value, probability: prize.probability, stock: prize.stock, initialStock: prize.initial_stock || prize.initialStock, ticketsUsed: prize.tickets_used || prize.ticketsUsed || 0, isActive: prize.is_active !== undefined ? prize.is_active : prize.isActive, imageUrl: prize.image_url || prize.imageUrl, createdAt: prize.created_at || prize.createdAt, updatedAt: prize.updated_at || prize.updatedAt, })) || []; return prizes; }, /** * Créer un nouveau prix */ createPrize: async (data: CreatePrizeData): Promise => { const response = await api.post>( API_ENDPOINTS.PRIZES, data ); return response.data!; }, /** * Modifier un prix */ updatePrize: async (prizeId: string, data: UpdatePrizeData): Promise => { const response = await api.put>( `${API_ENDPOINTS.PRIZES}/${prizeId}`, data ); return response.data!; }, /** * Supprimer (désactiver) un prix */ deletePrize: async (prizeId: string): Promise => { await api.delete>( `${API_ENDPOINTS.PRIZES}/${prizeId}` ); }, // ==================== GESTION DES UTILISATEURS ==================== /** * Récupérer tous les utilisateurs (paginé) */ getAllUsers: async ( page = 1, limit = 20, filters?: { role?: string; } ): Promise> => { const params = new URLSearchParams({ page: page.toString(), limit: limit.toString(), ...(filters?.role && { role: filters.role }), }); const response = await api.get( `${API_ENDPOINTS.USERS}?${params}` ); // Adapter la réponse du backend au format attendu par le frontend // Backend: { success: true, data: { users: [...], pagination: {...} } } // Frontend attend: { data: [...], total, page, limit, totalPages } if (response.data && response.data.users) { // Convertir snake_case en camelCase pour chaque utilisateur const users = response.data.users.map((user: any) => ({ 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, })); return { data: users, total: response.data.pagination.total, page: response.data.pagination.page, limit: response.data.pagination.limit, totalPages: response.data.pagination.totalPages, }; } // Fallback si la structure est différente return response.data || { data: [], total: 0, page: 1, limit: 20, totalPages: 0 }; }, /** * Créer un nouvel employé */ createEmployee: async (data: CreateEmployeeData): Promise => { const response = await api.post>( API_ENDPOINTS.EMPLOYEES, data ); return response.data!; }, /** * Modifier un utilisateur */ updateUser: async (userId: string, data: UpdateUserData): Promise => { const response = await api.put>( `${API_ENDPOINTS.USERS}/${userId}`, data ); return response.data!; }, /** * Supprimer un utilisateur */ deleteUser: async (userId: string): Promise => { await api.delete>( `${API_ENDPOINTS.USERS}/${userId}` ); }, // ==================== GESTION DES TICKETS ==================== /** * Récupérer tous les tickets (paginé avec filtres) */ getAllTickets: async ( page = 1, limit = 20, filters?: { status?: string; userId?: string; prizeType?: string; } ): Promise> => { const params = new URLSearchParams(); params.append('page', page.toString()); params.append('limit', limit.toString()); if (filters?.status) { params.append('status', filters.status); } if (filters?.userId) { params.append('userId', filters.userId); } if (filters?.prizeType) { params.append('prizeType', filters.prizeType); } const url = `${API_ENDPOINTS.TICKETS}?${params}`; console.log('🔍 Frontend - URL appelée:', url); console.log('🔍 Frontend - Filters:', filters); const response = await api.get(url); // Transformer les données du backend (format plat) en format attendu par le frontend const transformTicket = (ticket: any): Ticket => ({ id: ticket.id, code: ticket.code, status: ticket.status, playedAt: ticket.played_at || ticket.playedAt, claimedAt: ticket.claimed_at || ticket.claimedAt, validatedAt: ticket.validated_at || ticket.validatedAt, createdAt: ticket.created_at || ticket.createdAt, // Transformer les données utilisateur user: ticket.user_email ? { email: ticket.user_email, firstName: ticket.user_name?.split(' ')[0] || '', lastName: ticket.user_name?.split(' ').slice(1).join(' ') || '', } as any : undefined, // Transformer les données prize prize: ticket.prize_name ? { name: ticket.prize_name, type: ticket.prize_type, value: ticket.prize_value || '0', } as any : undefined, }); // Gérer différents formats de réponse de l'API if (response.data && response.data.data) { return { data: response.data.data.map(transformTicket), total: response.data.total, page: response.data.page, limit: response.data.limit, totalPages: response.data.totalPages, }; } else if (response.data && Array.isArray(response.data)) { return { data: response.data.map(transformTicket), total: response.total || response.data.length, page: response.page || page, limit: response.limit || limit, totalPages: response.totalPages || 1, }; } else if (Array.isArray(response)) { return { data: response.map(transformTicket), total: response.length, page: page, limit: limit, totalPages: 1, }; } return response as PaginatedResponse; }, };