Files
btpxpress-frontend/services/fournisseurService.ts
dahoud e15d717a40 Fix: Correction critique de la boucle OAuth - Empêcher les échanges multiples du code
PROBLÈME RÉSOLU:
- Erreur "Code already used" répétée dans les logs Keycloak
- Boucle infinie de tentatives d'échange du code d'autorisation OAuth
- Utilisateurs bloqués à la connexion

CORRECTIONS APPLIQUÉES:
1. Ajout de useRef pour protéger contre les exécutions multiples
   - hasExchanged.current: Flag pour prévenir les réexécutions
   - isProcessing.current: Protection pendant le traitement

2. Modification des dépendances useEffect
   - AVANT: [searchParams, router] → exécution à chaque changement
   - APRÈS: [] → exécution unique au montage du composant

3. Amélioration du logging
   - Console logs pour debug OAuth flow
   - Messages emoji pour faciliter le suivi

4. Nettoyage de l'URL
   - window.history.replaceState() pour retirer les paramètres OAuth
   - Évite les re-renders causés par les paramètres dans l'URL

5. Gestion d'erreurs améliorée
   - Capture des erreurs JSON du serveur
   - Messages d'erreur plus explicites

FICHIERS AJOUTÉS:
- app/(main)/aide/* - 4 pages du module Aide (documentation, tutoriels, support)
- app/(main)/messages/* - 4 pages du module Messages (inbox, envoyés, archives)
- app/auth/callback/page.tsx.backup - Sauvegarde avant modification

IMPACT:
 Un seul échange de code par authentification
 Plus d'erreur "Code already used"
 Connexion fluide et sans boucle
 Logs propres et lisibles

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 23:45:33 +00:00

223 lines
5.7 KiB
TypeScript

import { apiService } from './api';
export interface Fournisseur {
id: string;
nom: string;
contact: string;
telephone: string;
email: string;
adresse: string;
ville: string;
codePostal: string;
pays: string;
siret?: string;
tva?: string;
conditionsPaiement: string;
delaiLivraison: number;
note?: string;
actif: boolean;
dateCreation: string;
dateModification: string;
}
export interface CreateFournisseurRequest {
nom: string;
contact: string;
telephone: string;
email: string;
adresse: string;
ville: string;
codePostal: string;
pays: string;
siret?: string;
tva?: string;
conditionsPaiement: string;
delaiLivraison: number;
note?: string;
}
export interface UpdateFournisseurRequest {
nom?: string;
contact?: string;
telephone?: string;
email?: string;
adresse?: string;
ville?: string;
codePostal?: string;
pays?: string;
siret?: string;
tva?: string;
conditionsPaiement?: string;
delaiLivraison?: number;
note?: string;
actif?: boolean;
}
export class FournisseurService {
/**
* Récupère tous les fournisseurs
*/
async getAllFournisseurs(): Promise<Fournisseur[]> {
try {
const response = await apiService.get('/fournisseurs');
return response.data;
} catch (error) {
console.error('Erreur lors de la récupération des fournisseurs:', error);
return this.getMockFournisseurs();
}
}
/**
* Récupère un fournisseur par ID
*/
async getFournisseurById(id: string): Promise<Fournisseur> {
try {
const response = await apiService.get(`/fournisseurs/${id}`);
return response.data;
} catch (error) {
console.error('Erreur lors de la récupération du fournisseur:', error);
throw error;
}
}
/**
* Crée un nouveau fournisseur
*/
async createFournisseur(fournisseurData: CreateFournisseurRequest): Promise<Fournisseur> {
try {
const response = await apiService.post('/fournisseurs', fournisseurData);
return response.data;
} catch (error) {
console.error('Erreur lors de la création du fournisseur:', error);
throw error;
}
}
/**
* Met à jour un fournisseur existant
*/
async updateFournisseur(id: string, fournisseurData: UpdateFournisseurRequest): Promise<Fournisseur> {
try {
const response = await apiService.put(`/fournisseurs/${id}`, fournisseurData);
return response.data;
} catch (error) {
console.error('Erreur lors de la mise à jour du fournisseur:', error);
throw error;
}
}
/**
* Supprime un fournisseur (soft delete)
*/
async deleteFournisseur(id: string): Promise<void> {
try {
await apiService.delete(`/fournisseurs/${id}`);
} catch (error) {
console.error('Erreur lors de la suppression du fournisseur:', error);
throw error;
}
}
/**
* Recherche des fournisseurs par nom
*/
async searchFournisseurs(searchTerm: string): Promise<Fournisseur[]> {
try {
const response = await apiService.get(`/fournisseurs/search?q=${encodeURIComponent(searchTerm)}`);
return response.data;
} catch (error) {
console.error('Erreur lors de la recherche des fournisseurs:', error);
return [];
}
}
/**
* Récupère les statistiques des fournisseurs
*/
async getFournisseurStats(): Promise<{
total: number;
actifs: number;
inactifs: number;
parPays: Record<string, number>;
}> {
try {
const response = await apiService.get('/fournisseurs/stats');
return response.data;
} catch (error) {
console.error('Erreur lors de la récupération des statistiques:', error);
return {
total: 0,
actifs: 0,
inactifs: 0,
parPays: {}
};
}
}
/**
* Données mockées pour les fournisseurs
*/
private getMockFournisseurs(): Fournisseur[] {
return [
{
id: 'fourn-1',
nom: 'Matériaux BTP Pro',
contact: 'Jean Dupont',
telephone: '01 23 45 67 89',
email: 'contact@materiaux-btp-pro.fr',
adresse: '123 Rue de la Construction',
ville: 'Paris',
codePostal: '75001',
pays: 'France',
siret: '12345678901234',
tva: 'FR12345678901',
conditionsPaiement: '30 jours',
delaiLivraison: 7,
note: 'Fournisseur fiable pour les gros volumes',
actif: true,
dateCreation: '2024-01-15T00:00:00Z',
dateModification: '2024-01-15T00:00:00Z'
},
{
id: 'fourn-2',
nom: 'Outillage Express',
contact: 'Marie Martin',
telephone: '02 34 56 78 90',
email: 'contact@outillage-express.fr',
adresse: '456 Avenue des Outils',
ville: 'Lyon',
codePostal: '69001',
pays: 'France',
siret: '23456789012345',
tva: 'FR23456789012',
conditionsPaiement: '45 jours',
delaiLivraison: 5,
note: 'Spécialisé dans les outils de précision',
actif: true,
dateCreation: '2024-02-01T00:00:00Z',
dateModification: '2024-02-01T00:00:00Z'
},
{
id: 'fourn-3',
nom: 'Engins Chantier SARL',
contact: 'Pierre Durand',
telephone: '03 45 67 89 01',
email: 'contact@engins-chantier.fr',
adresse: '789 Boulevard des Engins',
ville: 'Marseille',
codePostal: '13001',
pays: 'France',
siret: '34567890123456',
tva: 'FR34567890123',
conditionsPaiement: '60 jours',
delaiLivraison: 14,
note: 'Location et vente d\'engins de chantier',
actif: true,
dateCreation: '2024-02-15T00:00:00Z',
dateModification: '2024-02-15T00:00:00Z'
}
];
}
}
export const fournisseurService = new FournisseurService();