'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 { Dialog } from 'primereact/dialog'; import { InputText } from 'primereact/inputtext'; import { InputNumber } from 'primereact/inputnumber'; import { Dropdown } from 'primereact/dropdown'; import { Calendar } from 'primereact/calendar'; import { InputTextarea } from 'primereact/inputtextarea'; import { Toast } from 'primereact/toast'; import { Toolbar } from 'primereact/toolbar'; import { ConfirmDialog } from 'primereact/confirmdialog'; import { Tag } from 'primereact/tag'; import { FilterMatchMode } from 'primereact/api'; import { materielService } from '../../../services/api'; import { Materiel, TypeMateriel, StatutMateriel } from '../../../types/btp'; import { formatDate, formatCurrency } from '../../../utils/formatters'; const MaterielsPage = () => { const [materiels, setMateriels] = useState([]); const [materiel, setMateriel] = useState>({}); const [selectedMateriels, setSelectedMateriels] = useState([]); const [materielDialog, setMaterielDialog] = useState(false); const [loading, setLoading] = useState(true); const [globalFilter, setGlobalFilter] = useState(''); const [submitted, setSubmitted] = useState(false); const toast = useRef(null); const dt = useRef>(null); const typeOptions = Object.values(TypeMateriel).map(type => ({ label: type.replace('_', ' '), value: type })); const statutOptions = Object.values(StatutMateriel).map(statut => ({ label: statut.replace('_', ' '), value: statut })); useEffect(() => { loadMateriels(); }, []); const loadMateriels = async () => { try { setLoading(true); const data = await materielService.getAll(); setMateriels(data); } catch (error) { console.error('Erreur lors du chargement des matériels:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les matériels', life: 3000 }); } finally { setLoading(false); } }; const openNew = () => { setMateriel({ statut: StatutMateriel.DISPONIBLE, actif: true }); setSubmitted(false); setMaterielDialog(true); }; const hideDialog = () => { setSubmitted(false); setMaterielDialog(false); setMateriel({}); }; const saveMateriel = async () => { setSubmitted(true); if (materiel.nom?.trim()) { try { let savedMateriel: Materiel; if (materiel.id) { savedMateriel = await materielService.update(materiel.id, materiel); const updatedMateriels = materiels.map(m => m.id === materiel.id ? savedMateriel : m ); setMateriels(updatedMateriels); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Matériel mis à jour', life: 3000 }); } else { savedMateriel = await materielService.create(materiel); setMateriels([...materiels, savedMateriel]); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Matériel créé', life: 3000 }); } hideDialog(); } catch (error: any) { toast.current?.show({ severity: 'error', summary: 'Erreur', detail: error?.userMessage || 'Erreur lors de la sauvegarde', life: 3000 }); } } }; const editMateriel = (materiel: Materiel) => { setMateriel({ ...materiel }); setMaterielDialog(true); }; const confirmDeleteSelected = () => { if (selectedMateriels && selectedMateriels.length > 0) { // Implémenter la suppression en lot si nécessaire } }; const deleteMateriel = async (materiel: Materiel) => { try { await materielService.delete(materiel.id); const updatedMateriels = materiels.filter(m => m.id !== materiel.id); setMateriels(updatedMateriels); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Matériel supprimé', life: 3000 }); } catch (error: any) { toast.current?.show({ severity: 'error', summary: 'Erreur', detail: error?.userMessage || 'Erreur lors de la suppression', life: 3000 }); } }; const exportCSV = () => { dt.current?.exportCSV(); }; const onInputChange = (e: React.ChangeEvent, name: string) => { const val = (e.target && e.target.value) || ''; const _materiel = { ...materiel }; (_materiel as any)[name] = val; setMateriel(_materiel); }; const onInputNumberChange = (value: number | null, name: string) => { const _materiel = { ...materiel }; (_materiel as any)[name] = value; setMateriel(_materiel); }; const onDropdownChange = (e: any, name: string) => { const _materiel = { ...materiel }; (_materiel as any)[name] = e.value; setMateriel(_materiel); }; const onDateChange = (e: any, name: string) => { const _materiel = { ...materiel }; (_materiel as any)[name] = e.value; setMateriel(_materiel); }; // Templates pour les colonnes const typeBodyTemplate = (rowData: Materiel) => { return ( ); }; const statutBodyTemplate = (rowData: Materiel) => { return ( ); }; const valeurBodyTemplate = (rowData: Materiel) => { return formatCurrency(rowData.valeurActuelle || rowData.valeurAchat); }; const dateBodyTemplate = (rowData: Materiel) => { return formatDate(rowData.dateAchat); }; const actionBodyTemplate = (rowData: Materiel) => { return (
); }; const getTypeSeverity = (type?: TypeMateriel) => { switch (type) { case TypeMateriel.ENGIN_CHANTIER: return 'danger'; case TypeMateriel.OUTIL_ELECTRIQUE: case TypeMateriel.OUTIL_MANUEL: return 'warning'; case TypeMateriel.EQUIPEMENT_SECURITE: return 'success'; case TypeMateriel.VEHICULE: return 'info'; case TypeMateriel.GRUE: case TypeMateriel.BETONIERE: return 'danger'; default: return 'secondary'; } }; const getStatutSeverity = (statut?: StatutMateriel) => { switch (statut) { case StatutMateriel.DISPONIBLE: return 'success'; case StatutMateriel.UTILISE: return 'warning'; case StatutMateriel.MAINTENANCE: case StatutMateriel.EN_REPARATION: return 'info'; case StatutMateriel.HORS_SERVICE: return 'danger'; case StatutMateriel.RESERVE: return 'secondary'; default: return undefined; } }; const leftToolbarTemplate = () => { return (
); }; const rightToolbarTemplate = () => { return (