'use client'; import React, { useState, useEffect, useRef } from 'react'; import { Card } from 'primereact/card'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { Button } from 'primereact/button'; import { Tag } from 'primereact/tag'; import { Dialog } from 'primereact/dialog'; import { InputText } from 'primereact/inputtext'; import { InputNumber } from 'primereact/inputnumber'; import { Toast } from 'primereact/toast'; import { Divider } from 'primereact/divider'; import { Badge } from 'primereact/badge'; import { ProgressBar } from 'primereact/progressbar'; import { Dropdown } from 'primereact/dropdown'; import { Calendar } from 'primereact/calendar'; import { InputTextarea } from 'primereact/inputtextarea'; import { Knob } from 'primereact/knob'; import { Toolbar } from 'primereact/toolbar'; import { Checkbox } from 'primereact/checkbox'; import { Chart } from 'primereact/chart'; import { ActionButtonGroup, ViewButton, EditButton, DeleteButton, ActionButton } from '../../../../components/ui/ActionButton'; // Types pour l'inventaire interface InventoryItem { id: string; reference: string; nom: string; categorie: string; unite: string; stockTheorique: number; stockReel: number; ecart: number; valeurStock: number; emplacement: string; dateInventaire: Date; auditeur: string; statut: 'OK' | 'ECART' | 'MANQUANT' | 'EXCEDENT'; } interface InventorySession { id: string; nom: string; dateDebut: Date; dateFin?: Date; statut: 'PLANIFIE' | 'EN_COURS' | 'TERMINE'; emplacements: string[]; categories: string[]; auditeur: string; commentaires: string; } /** * Page Inventaire Matériel BTP Express * Gestion complète stocks, maintenances et alertes matériel */ const InventairePage = () => { const [inventoryItems, setInventoryItems] = useState([]); const [sessions, setSessions] = useState([]); const [selectedItems, setSelectedItems] = useState([]); const [loading, setLoading] = useState(true); const [inventaireDialog, setInventaireDialog] = useState(false); const [maintenanceDialog, setMaintenanceDialog] = useState(false); const [alertesDialog, setAlertesDialog] = useState(false); const [selectedMateriel, setSelectedMateriel] = useState(null); const [nouvelleQuantite, setNouvelleQuantite] = useState(0); const [commentaireInventaire, setCommentaireInventaire] = useState(''); const [dateMaintenance, setDateMaintenance] = useState(null); const [typeMaintenance, setTypeMaintenance] = useState(''); const [descriptionMaintenance, setDescriptionMaintenance] = useState(''); const [alertes, setAlertes] = useState([]); const [metriques, setMetriques] = useState({}); const [globalFilter, setGlobalFilter] = useState(''); const [sessionDialog, setSessionDialog] = useState(false); const [inventoryDialog, setInventoryDialog] = useState(false); const [selectedSession, setSelectedSession] = useState(null); const [showStats, setShowStats] = useState(false); const [submitted, setSubmitted] = useState(false); const toast = useRef(null); const dt = useRef>(null); const [newSession, setNewSession] = useState({ id: '', nom: '', dateDebut: new Date(), statut: 'PLANIFIE', emplacements: [], categories: [], auditeur: '', commentaires: '' }); const emplacements = [ { label: 'Entrepôt A', value: 'entrepot-a' }, { label: 'Entrepôt B', value: 'entrepot-b' }, { label: 'Magasin', value: 'magasin' }, { label: 'Chantier Mobile', value: 'chantier-mobile' }, { label: 'Bureau', value: 'bureau' } ]; const categories = [ { label: 'Matériaux', value: 'materiaux' }, { label: 'Outillage', value: 'outillage' }, { label: 'Équipement', value: 'equipement' }, { label: 'Consommables', value: 'consommables' }, { label: 'Sécurité', value: 'securite' } ]; useEffect(() => { loadInventoryData(); }, []); const loadInventoryData = async () => { try { setLoading(true); // Données mockées const mockInventoryItems: InventoryItem[] = [ { id: '1', reference: 'CIM-001', nom: 'Ciment Portland', categorie: 'materiaux', unite: 'sac', stockTheorique: 150, stockReel: 148, ecart: -2, valeurStock: 1258.00, emplacement: 'entrepot-a', dateInventaire: new Date(), auditeur: 'Jean Dupont', statut: 'ECART' }, { id: '2', reference: 'OUT-002', nom: 'Perceuse électrique', categorie: 'outillage', unite: 'unité', stockTheorique: 5, stockReel: 5, ecart: 0, valeurStock: 600.00, emplacement: 'magasin', dateInventaire: new Date(), auditeur: 'Marie Martin', statut: 'OK' }, { id: '3', reference: 'SEC-003', nom: 'Casque de sécurité', categorie: 'securite', unite: 'unité', stockTheorique: 8, stockReel: 10, ecart: 2, valeurStock: 250.00, emplacement: 'bureau', dateInventaire: new Date(), auditeur: 'Pierre Durand', statut: 'EXCEDENT' } ]; const mockSessions: InventorySession[] = [ { id: '1', nom: 'Inventaire Mensuel Janvier 2024', dateDebut: new Date('2024-01-15'), dateFin: new Date('2024-01-17'), statut: 'TERMINE', emplacements: ['entrepot-a', 'magasin'], categories: ['materiaux', 'outillage'], auditeur: 'Équipe Inventaire', commentaires: 'Inventaire mensuel standard' }, { id: '2', nom: 'Inventaire Sécurité', dateDebut: new Date(), statut: 'EN_COURS', emplacements: ['bureau'], categories: ['securite'], auditeur: 'Pierre Durand', commentaires: 'Contrôle EPI obligatoire' } ]; setInventoryItems(mockInventoryItems); setSessions(mockSessions); } catch (error) { console.error('Erreur lors du chargement:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les données d\'inventaire', life: 3000 }); } finally { setLoading(false); } }; const openNewSession = () => { setNewSession({ id: '', nom: '', dateDebut: new Date(), statut: 'PLANIFIE', emplacements: [], categories: [], auditeur: '', commentaires: '' }); setSubmitted(false); setSessionDialog(true); }; const saveSession = () => { setSubmitted(true); if (newSession.nom.trim() && newSession.auditeur.trim()) { const session = { ...newSession, id: Date.now().toString() }; setSessions([...sessions, session]); setSessionDialog(false); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Session d\'inventaire créée', life: 3000 }); } }; const startInventory = (session: InventorySession) => { const updatedSessions = sessions.map(s => s.id === session.id ? { ...s, statut: 'EN_COURS' as const } : s ); setSessions(updatedSessions); toast.current?.show({ severity: 'info', summary: 'Inventaire démarré', detail: `Session "${session.nom}" en cours`, life: 3000 }); }; const finishInventory = (session: InventorySession) => { const updatedSessions = sessions.map(s => s.id === session.id ? { ...s, statut: 'TERMINE' as const, dateFin: new Date() } : s ); setSessions(updatedSessions); toast.current?.show({ severity: 'success', summary: 'Inventaire terminé', detail: `Session "${session.nom}" terminée`, life: 3000 }); }; const exportCSV = () => { dt.current?.exportCSV(); }; const generateReport = () => { const totalItems = inventoryItems.length; const itemsWithIssues = inventoryItems.filter(item => item.statut !== 'OK').length; const totalValue = inventoryItems.reduce((sum, item) => sum + item.valeurStock, 0); toast.current?.show({ severity: 'info', summary: 'Rapport généré', detail: `${totalItems} articles, ${itemsWithIssues} écarts, Valeur: ${totalValue.toFixed(2)}€`, life: 5000 }); setShowStats(true); }; const leftToolbarTemplate = () => { return (
); }; const rightToolbarTemplate = () => { return (