// User Types export interface User { id: string; email: string; firstName: string; lastName: string; phone?: string; address?: string; city?: string; postalCode?: string; gender?: 'MALE' | 'FEMALE' | 'OTHER' | 'NOT_SPECIFIED'; dateOfBirth?: string; role: 'CLIENT' | 'EMPLOYEE' | 'ADMIN'; isVerified: boolean; isActive: boolean; createdAt: string; updatedAt?: string; // Ticket statistics (populated in getUserById) ticketsCount?: number; pendingTickets?: number; claimedTickets?: number; } // Auth Types export interface LoginCredentials { email: string; password: string; } export interface RegisterData { email: string; password: string; confirmPassword: string; firstName: string; lastName: string; phone?: string; captchaToken?: string; } export interface AuthResponse { user: User; token: string; } // Ticket Types export type TicketStatus = 'PENDING' | 'REJECTED' | 'CLAIMED'; export interface Ticket { id: string; code: string; userId?: string; prizeId?: string; status: TicketStatus; playedAt?: string; claimedAt?: string; validatedAt?: string; validatedBy?: string; rejectionReason?: string; createdAt?: string; updatedAt?: string; prize?: Prize; user?: User; } // Prize Types export type PrizeType = | 'INFUSEUR' | 'THE_SIGNATURE' | 'COFFRET_DECOUVERTE' | 'COFFRET_PRESTIGE' | 'THE_GRATUIT' | 'GRAND_PRIZE' | 'PHYSICAL' | 'DISCOUNT'; export interface Prize { id: string; name: string; type: PrizeType; description: string; value: string; probability: number; stock: number; // Stock restant initialStock?: number; // Stock initial (généré) ticketsUsed?: number; // Nombre de tickets utilisés isActive: boolean; imageUrl?: string; createdAt: string; updatedAt?: string; } export interface CreatePrizeData { name: string; type: PrizeType; description: string; value: string; probability: number; stock: number; } export interface UpdatePrizeData { name?: string; description?: string; value?: string; probability?: number; stock?: number; isActive?: boolean; } // Game Types export interface PlayGameRequest { ticketCode: string; } export interface PlayGameResponse { success: boolean; ticket: Ticket; prize: Prize; message: string; } // Statistics Types export interface GameStatistics { totalTickets: number; claimedTickets: number; pendingTickets: number; rejectedTickets: number; prizeDistribution: { [key in PrizeType]: number; }; totalParticipants: number; claimRate: number; } // API Response Types export interface ApiResponse { success: boolean; data?: T; message?: string; error?: string; } export interface PaginatedResponse { data: T[]; total: number; page: number; limit: number; totalPages: number; stats?: { pending: number; claimed: number; rejected: number; }; } // Form Validation Types export interface ValidationError { field: string; message: string; } // Navigation Types export interface NavItem { label: string; href: string; icon?: string; roles?: User['role'][]; } // Admin Types export interface CreateEmployeeData { email: string; password: string; firstName: string; lastName: string; } export interface UpdateUserData { role?: 'CLIENT' | 'EMPLOYEE' | 'ADMIN'; isVerified?: boolean; isActive?: boolean; firstName?: string; lastName?: string; } export interface AdminStatistics { users: { total: number; clients: number; activeClients: number; inactiveClients: number; employees: number; admins: number; verifiedEmails: number; }; tickets: { total: number; distributed: number; // Tickets fournis/distribués used: number; // Tickets utilisés en temps réel pending: number; rejected: number; claimed: number; }; prizes: { total: number; active: number; totalStock: number; distributed: number; byCategory?: PrizeDistribution[]; // Répartition des lots par catégorie }; demographics?: DemographicStatistics; // Statistiques démographiques } // Répartition des lots par catégorie export interface PrizeDistribution { prizeId: string; prizeName: string; prizeType: PrizeType; count: number; percentage: number; } // Statistiques démographiques des participants export interface DemographicStatistics { gender?: { male: number; female: number; other: number; notSpecified: number; }; ageRanges?: { range: string; // ex: "18-25", "26-35", etc. count: number; percentage: number; }[]; locations?: { city: string; postalCode?: string; count: number; percentage: number; }[]; topCities?: { city: string; count: number; percentage: number; }[]; }