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>
223 lines
5.7 KiB
TypeScript
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(); |