- Correction des erreurs TypeScript dans userService.ts et workflowTester.ts - Ajout des propriétés manquantes aux objets User mockés - Conversion des dates de string vers objets Date - Correction des appels asynchrones et des types incompatibles - Ajout de dynamic rendering pour résoudre les erreurs useSearchParams - Enveloppement de useSearchParams dans Suspense boundary - Configuration de force-dynamic au niveau du layout principal Build réussi: 126 pages générées avec succès 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
145 lines
3.9 KiB
TypeScript
145 lines
3.9 KiB
TypeScript
import { clientService } from './api';
|
|
import { Client } from '../types/btp';
|
|
|
|
type ClientFormData = Partial<Client>;
|
|
|
|
class ClientService {
|
|
private readonly basePath = '/api/clients';
|
|
|
|
/**
|
|
* Récupérer tous les clients
|
|
*/
|
|
async getAll(): Promise<Client[]> {
|
|
return await clientService.getAll();
|
|
}
|
|
|
|
/**
|
|
* Récupérer un client par ID
|
|
*/
|
|
async getById(id: string): Promise<Client> {
|
|
return await clientService.getById(id);
|
|
}
|
|
|
|
/**
|
|
* Créer un nouveau client
|
|
*/
|
|
async create(client: ClientFormData): Promise<Client> {
|
|
return await clientService.create(client as Partial<Client>);
|
|
}
|
|
|
|
/**
|
|
* Modifier un client existant
|
|
*/
|
|
async update(id: string, client: ClientFormData): Promise<Client> {
|
|
return await clientService.update(id, client as Partial<Client>);
|
|
}
|
|
|
|
/**
|
|
* Supprimer un client
|
|
*/
|
|
async delete(id: string): Promise<void> {
|
|
await clientService.delete(id);
|
|
}
|
|
|
|
/**
|
|
* Rechercher des clients
|
|
*/
|
|
async search(query: string): Promise<Client[]> {
|
|
return await clientService.searchByNom(query);
|
|
}
|
|
|
|
/**
|
|
* Récupérer les chantiers d'un client
|
|
*/
|
|
async getChantiers(clientId: string): Promise<any[]> {
|
|
// Utiliser le service chantier pour récupérer les chantiers par client
|
|
const { chantierService } = await import('./api');
|
|
return await chantierService.getByClient(clientId);
|
|
}
|
|
|
|
/**
|
|
* Valider les données d'un client
|
|
*/
|
|
validateClient(client: ClientFormData): string[] {
|
|
const errors: string[] = [];
|
|
|
|
if (!client.nom || client.nom.trim().length === 0) {
|
|
errors.push('Le nom est obligatoire');
|
|
}
|
|
|
|
if (!client.prenom || client.prenom.trim().length === 0) {
|
|
errors.push('Le prénom est obligatoire');
|
|
}
|
|
|
|
if (client.email && !this.isValidEmail(client.email)) {
|
|
errors.push('L\'email n\'est pas valide');
|
|
}
|
|
|
|
if (client.telephone && !this.isValidPhoneNumber(client.telephone)) {
|
|
errors.push('Le numéro de téléphone n\'est pas valide');
|
|
}
|
|
|
|
return errors;
|
|
}
|
|
|
|
/**
|
|
* Valider une adresse email
|
|
*/
|
|
private isValidEmail(email: string): boolean {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
return emailRegex.test(email);
|
|
}
|
|
|
|
/**
|
|
* Valider un numéro de téléphone
|
|
*/
|
|
private isValidPhoneNumber(phone: string): boolean {
|
|
const phoneRegex = /^(?:(?:\+|00)33|0)\s*[1-9](?:[\s.-]*\d{2}){4}$/;
|
|
return phoneRegex.test(phone);
|
|
}
|
|
|
|
/**
|
|
* Formater le nom complet d'un client
|
|
*/
|
|
formatFullName(client: Client): string {
|
|
let fullName = `${client.prenom} ${client.nom}`;
|
|
if (client.entreprise) {
|
|
fullName += ` - ${client.entreprise}`;
|
|
}
|
|
return fullName;
|
|
}
|
|
|
|
/**
|
|
* Exporter les clients au format CSV
|
|
*/
|
|
async exportToCsv(): Promise<Blob> {
|
|
const clients = await this.getAll();
|
|
|
|
const headers = [
|
|
'ID', 'Prénom', 'Nom', 'Entreprise', 'Email', 'Téléphone',
|
|
'Adresse', 'Ville', 'Code Postal', 'Pays', 'Type', 'Actif'
|
|
];
|
|
|
|
const csvContent = [
|
|
headers.join(';'),
|
|
...clients.map(c => [
|
|
c.id || '',
|
|
c.prenom || '',
|
|
c.nom || '',
|
|
(c as any).entreprise || '',
|
|
c.email || '',
|
|
c.telephone || '',
|
|
c.adresse || '',
|
|
(c as any).ville || '',
|
|
(c as any).codePostal || '',
|
|
(c as any).pays || '',
|
|
(c as any).typeClient || '',
|
|
c.actif ? 'Oui' : 'Non'
|
|
].join(';'))
|
|
].join('\n');
|
|
|
|
return new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
}
|
|
}
|
|
|
|
export default new ClientService(); |