'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 { InputNumber } from 'primereact/inputnumber'; import { Dropdown } from 'primereact/dropdown'; import { InputTextarea } from 'primereact/inputtextarea'; import { confirmDialog } from 'primereact/confirmdialog'; import { ConfirmDialog } from 'primereact/confirmdialog'; interface StockItem { id: string; nom: string; reference: string; description: string; categorie: string; unite: string; quantiteStock: number; seuilAlerte: number; prixUnitaire: number; fournisseur: string; emplacement: string; dateAjout: Date; dateModification: Date; actif: boolean; } interface StockMovement { id: string; articleId: string; type: 'ENTREE' | 'SORTIE'; quantite: number; motif: string; chantier?: string; utilisateur: string; date: Date; } const StockPage = () => { const [stockItems, setStockItems] = useState([]); const [selectedItems, setSelectedItems] = useState([]); const [loading, setLoading] = useState(true); const [globalFilter, setGlobalFilter] = useState(''); const [itemDialog, setItemDialog] = useState(false); const [movementDialog, setMovementDialog] = useState(false); const [deleteItemDialog, setDeleteItemDialog] = useState(false); const [item, setItem] = useState({ id: '', nom: '', reference: '', description: '', categorie: '', unite: 'unité', quantiteStock: 0, seuilAlerte: 10, prixUnitaire: 0, fournisseur: '', emplacement: '', dateAjout: new Date(), dateModification: new Date(), actif: true }); const [movement, setMovement] = useState({ id: '', articleId: '', type: 'ENTREE', quantite: 0, motif: '', chantier: '', utilisateur: 'Admin', date: new Date() }); const [submitted, setSubmitted] = useState(false); const toast = useRef(null); const dt = useRef>(null); const categories = [ { label: 'Matériaux', value: 'materiaux' }, { label: 'Outillage', value: 'outillage' }, { label: 'Équipement', value: 'equipement' }, { label: 'Consommables', value: 'consommables' }, { label: 'Sécurité', value: 'securite' } ]; const unites = [ { label: 'Unité', value: 'unité' }, { label: 'Mètre', value: 'm' }, { label: 'Mètre carré', value: 'm²' }, { label: 'Mètre cube', value: 'm³' }, { label: 'Kilogramme', value: 'kg' }, { label: 'Tonne', value: 't' }, { label: 'Litre', value: 'l' }, { label: 'Boîte', value: 'boîte' }, { label: 'Sac', value: 'sac' }, { label: 'Palette', value: 'palette' } ]; 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 typesMovement = [ { label: 'Entrée', value: 'ENTREE' }, { label: 'Sortie', value: 'SORTIE' } ]; useEffect(() => { // Simuler le chargement des données loadStockItems(); }, []); const loadStockItems = async () => { try { setLoading(true); // Simulation de données const mockData: StockItem[] = [ { id: '1', nom: 'Ciment Portland', reference: 'CIM-001', description: 'Ciment Portland 32.5 pour béton', categorie: 'materiaux', unite: 'sac', quantiteStock: 150, seuilAlerte: 20, prixUnitaire: 8.50, fournisseur: 'Lafarge', emplacement: 'entrepot-a', dateAjout: new Date('2024-01-15'), dateModification: new Date('2024-01-15'), actif: true }, { id: '2', nom: 'Perceuse électrique', reference: 'OUT-002', description: 'Perceuse électrique 850W', categorie: 'outillage', unite: 'unité', quantiteStock: 5, seuilAlerte: 2, prixUnitaire: 120.00, fournisseur: 'Bosch', emplacement: 'magasin', dateAjout: new Date('2024-02-01'), dateModification: new Date('2024-02-01'), actif: true }, { id: '3', nom: 'Casque de sécurité', reference: 'SEC-003', description: 'Casque de sécurité blanc', categorie: 'securite', unite: 'unité', quantiteStock: 8, seuilAlerte: 5, prixUnitaire: 25.00, fournisseur: 'Protecta', emplacement: 'bureau', dateAjout: new Date('2024-03-01'), dateModification: new Date('2024-03-01'), actif: true } ]; setStockItems(mockData); } catch (error) { console.error('Erreur lors du chargement du stock:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les articles', life: 3000 }); } finally { setLoading(false); } }; const openNew = () => { setItem({ id: '', nom: '', reference: '', description: '', categorie: '', unite: 'unité', quantiteStock: 0, seuilAlerte: 10, prixUnitaire: 0, fournisseur: '', emplacement: '', dateAjout: new Date(), dateModification: new Date(), actif: true }); setSubmitted(false); setItemDialog(true); }; const openMovement = (item: StockItem) => { setMovement({ id: '', articleId: item.id, type: 'ENTREE', quantite: 0, motif: '', chantier: '', utilisateur: 'Admin', date: new Date() }); setSubmitted(false); setMovementDialog(true); }; const hideDialog = () => { setSubmitted(false); setItemDialog(false); }; const hideMovementDialog = () => { setSubmitted(false); setMovementDialog(false); }; const hideDeleteItemDialog = () => { setDeleteItemDialog(false); }; const saveItem = () => { setSubmitted(true); if (item.nom.trim() && item.reference.trim() && item.categorie) { let updatedItems = [...stockItems]; if (item.id) { // Mise à jour const index = stockItems.findIndex(i => i.id === item.id); updatedItems[index] = { ...item, dateModification: new Date() }; toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Article mis à jour', life: 3000 }); } else { // Création const newItem = { ...item, id: Date.now().toString(), dateAjout: new Date(), dateModification: new Date() }; updatedItems.push(newItem); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Article créé', life: 3000 }); } setStockItems(updatedItems); setItemDialog(false); setItem({ id: '', nom: '', reference: '', description: '', categorie: '', unite: 'unité', quantiteStock: 0, seuilAlerte: 10, prixUnitaire: 0, fournisseur: '', emplacement: '', dateAjout: new Date(), dateModification: new Date(), actif: true }); } }; const saveMovement = () => { setSubmitted(true); if (movement.quantite > 0 && movement.motif.trim()) { const targetItem = stockItems.find(i => i.id === movement.articleId); if (targetItem) { const newQuantity = movement.type === 'ENTREE' ? targetItem.quantiteStock + movement.quantite : targetItem.quantiteStock - movement.quantite; if (newQuantity < 0) { toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Stock insuffisant', life: 3000 }); return; } const updatedItems = stockItems.map(item => item.id === movement.articleId ? { ...item, quantiteStock: newQuantity, dateModification: new Date() } : item ); setStockItems(updatedItems); setMovementDialog(false); toast.current?.show({ severity: 'success', summary: 'Succès', detail: `Mouvement de stock ${movement.type === 'ENTREE' ? 'entrée' : 'sortie'} enregistré`, life: 3000 }); } } }; const editItem = (item: StockItem) => { setItem({ ...item }); setItemDialog(true); }; const confirmDeleteItem = (item: StockItem) => { setItem(item); setDeleteItemDialog(true); }; const deleteItem = () => { const updatedItems = stockItems.filter(i => i.id !== item.id); setStockItems(updatedItems); setDeleteItemDialog(false); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Article supprimé', life: 3000 }); }; const exportCSV = () => { dt.current?.exportCSV(); }; const onInputChange = (e: React.ChangeEvent, name: string) => { const val = (e.target && e.target.value) || ''; let _item = { ...item }; (_item as any)[name] = val; setItem(_item); }; const onNumberChange = (e: any, name: string) => { let _item = { ...item }; (_item as any)[name] = e.value; setItem(_item); }; const onDropdownChange = (e: any, name: string) => { let _item = { ...item }; (_item as any)[name] = e.value; setItem(_item); }; const onMovementInputChange = (e: React.ChangeEvent, name: string) => { const val = (e.target && e.target.value) || ''; let _movement = { ...movement }; (_movement as any)[name] = val; setMovement(_movement); }; const onMovementNumberChange = (e: any, name: string) => { let _movement = { ...movement }; (_movement as any)[name] = e.value; setMovement(_movement); }; const onMovementDropdownChange = (e: any, name: string) => { let _movement = { ...movement }; (_movement as any)[name] = e.value; setMovement(_movement); }; const leftToolbarTemplate = () => { return (
); }; const rightToolbarTemplate = () => { return (