the-tip-top-frontend/types/index.ts
soufiane f20cf40fff feat: redesign admin panel with blanc cassé theme
- Update sidebar and header with off-white (#faf8f5) background
- Add ticket stats endpoint integration for global counts
- Redesign tirages page with animation and improved layout
- Add red accent color for admin avatar
- Update various button styles and remove unnecessary elements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 19:43:14 +01:00

246 lines
4.7 KiB
TypeScript

// 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<T> {
success: boolean;
data?: T;
message?: string;
error?: string;
}
export interface PaginatedResponse<T> {
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;
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;
}[];
}