'use client'; import React, { useState, useEffect, useRef } from 'react'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { Button } from 'primereact/button'; import { InputText } from 'primereact/inputtext'; import { Card } from 'primereact/card'; import { Dialog } from 'primereact/dialog'; import { Toast } from 'primereact/toast'; import { Toolbar } from 'primereact/toolbar'; import { Tag } from 'primereact/tag'; import { ConfirmDialog } from 'primereact/confirmdialog'; import { InputTextarea } from 'primereact/inputtextarea'; import { Dropdown } from 'primereact/dropdown'; import clientService from '../../../services/clientService'; import chantierService from '../../../services/chantierService'; import type { Client } from '../../../types/btp'; import RoleProtectedPage from '@/components/RoleProtectedPage'; import { ActionButtonGroup, ViewButton, EditButton, DeleteButton, ActionButton } from '../../../components/ui/ActionButton'; const ClientsPageContent = () => { const [clients, setClients] = useState([]); const [loading, setLoading] = useState(true); const [globalFilter, setGlobalFilter] = useState(''); const [selectedClients, setSelectedClients] = useState([]); const [clientDialog, setClientDialog] = useState(false); const [deleteClientDialog, setDeleteClientDialog] = useState(false); const [deleteClientsDialog, setDeleteClientsDialog] = useState(false); const [chantiersDialog, setChantiersDialog] = useState(false); const [selectedClientChantiers, setSelectedClientChantiers] = useState([]); const [currentClient, setCurrentClient] = useState(null); const [client, setClient] = useState({ id: '', nom: '', prenom: '', entreprise: '', email: '', telephone: '', adresse: '', codePostal: '', ville: '', numeroTVA: '', siret: '', actif: true, dateCreation: new Date().toISOString(), dateModification: new Date().toISOString() }); const [submitted, setSubmitted] = useState(false); const toast = useRef(null); const dt = useRef>(null); const typesClient = [ { label: 'Particulier', value: 'PARTICULIER' }, { label: 'Professionnel', value: 'PROFESSIONNEL' } ]; useEffect(() => { loadClients(); }, []); const loadClients = async () => { try { setLoading(true); const data = await clientService.getAll(); setClients(data); } catch (error) { console.error('Erreur lors du chargement des clients:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les clients', life: 3000 }); } finally { setLoading(false); } }; const openNew = () => { setClient({ id: '', nom: '', prenom: '', entreprise: '', email: '', telephone: '', adresse: '', codePostal: '', ville: '', numeroTVA: '', siret: '', actif: true, dateCreation: new Date().toISOString(), dateModification: new Date().toISOString() }); setSubmitted(false); setClientDialog(true); }; const hideDialog = () => { setSubmitted(false); setClientDialog(false); }; const hideDeleteClientDialog = () => { setDeleteClientDialog(false); }; const hideDeleteClientsDialog = () => { setDeleteClientsDialog(false); }; const saveClient = async () => { setSubmitted(true); if (client.nom.trim() && client.prenom.trim()) { try { let updatedClients = [...clients]; if (client.id) { // Mise à jour const updatedClient = await clientService.update(client.id, client); const index = clients.findIndex(c => c.id === client.id); updatedClients[index] = updatedClient; toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Client mis à jour', life: 3000 }); } else { // Création const newClient = await clientService.create(client); updatedClients.push(newClient); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Client créé', life: 3000 }); } setClients(updatedClients); setClientDialog(false); setClient({ id: '', nom: '', prenom: '', entreprise: '', email: '', telephone: '', adresse: '', codePostal: '', ville: '', numeroTVA: '', siret: '', actif: true, dateCreation: new Date().toISOString(), dateModification: new Date().toISOString() }); } catch (error: any) { console.error('Erreur lors de la sauvegarde:', error); // Extraire le message d'erreur du backend let errorMessage = 'Impossible de sauvegarder le client'; if (error.response?.data?.message) { errorMessage = error.response.data.message; } else if (error.response?.data?.error) { errorMessage = error.response.data.error; } else if (error.response?.data) { errorMessage = JSON.stringify(error.response.data); } else if (error.response?.status === 400) { errorMessage = 'Données invalides. Vérifiez que tous les champs obligatoires sont remplis correctement.'; } toast.current?.show({ severity: 'error', summary: 'Erreur', detail: errorMessage, life: 5000 }); } } }; const editClient = (client: Client) => { setClient({ ...client }); setClientDialog(true); }; const confirmDeleteClient = (client: Client) => { setClient(client); setDeleteClientDialog(true); }; const deleteClient = async () => { try { await clientService.delete(client.id); let updatedClients = clients.filter(c => c.id !== client.id); setClients(updatedClients); setDeleteClientDialog(false); setClient({ id: '', nom: '', prenom: '', entreprise: '', email: '', telephone: '', adresse: '', codePostal: '', ville: '', numeroTVA: '', siret: '', actif: true, dateCreation: new Date().toISOString(), dateModification: new Date().toISOString() }); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Client supprimé', life: 3000 }); } catch (error) { console.error('Erreur lors de la suppression:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de supprimer le client', life: 3000 }); } }; const confirmDeleteSelected = () => { setDeleteClientsDialog(true); }; const deleteSelectedClients = async () => { try { await Promise.all(selectedClients.map(c => clientService.delete(c.id))); let updatedClients = clients.filter(c => !selectedClients.includes(c)); setClients(updatedClients); setDeleteClientsDialog(false); setSelectedClients([]); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Clients supprimés', life: 3000 }); } catch (error) { console.error('Erreur lors de la suppression:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de supprimer les clients', life: 3000 }); } }; const exportCSV = () => { dt.current?.exportCSV(); }; const voirChantiersClient = async (client: Client) => { try { setCurrentClient(client); const chantiers = await chantierService.getByClient(client.id!); setSelectedClientChantiers(chantiers || []); // Si pas de chantiers, afficher seulement un message informatif sans ouvrir le dialog if (!chantiers || chantiers.length === 0) { toast.current?.show({ severity: 'info', summary: 'Information', detail: `Le client ${client.nom} n'a pas encore de chantiers`, life: 4000 }); return; // Sortir sans ouvrir le dialog } // Ouvrir le dialog seulement s'il y a des chantiers à afficher setChantiersDialog(true); } catch (error: any) { console.error('Erreur lors du chargement des chantiers:', error); // Si c'est une erreur réseau ou serveur, afficher un message approprié let errorMessage = 'Erreur technique lors du chargement des chantiers'; if (error.code === 'NETWORK_ERROR' || error.message?.includes('Network Error')) { errorMessage = 'Impossible de contacter le serveur. Vérifiez votre connexion.'; } else if (error.response?.status === 500) { errorMessage = 'Erreur interne du serveur lors de la récupération des chantiers'; } toast.current?.show({ severity: 'error', summary: 'Erreur', detail: errorMessage, life: 4000 }); // En cas d'erreur technique, ne pas ouvrir le dialog non plus } }; const onInputChange = (e: React.ChangeEvent, name: string) => { const val = (e.target && e.target.value) || ''; let _client = { ...client }; (_client as any)[name] = val; setClient(_client); }; const onDropdownChange = (e: any, name: string) => { let _client = { ...client }; (_client as any)[name] = e.value; setClient(_client); }; const leftToolbarTemplate = () => { return (
); }; const rightToolbarTemplate = () => { return (