import React, { useState, useMemo } from "react"; import { Box, Paper, Typography, Button, TextField, InputAdornment, IconButton, Chip, Menu, MenuItem, ListItemIcon, ListItemText, Tooltip, Card, CardContent, CardMedia, CardActions, Grid, ToggleButton, ToggleButtonGroup, FormControl, InputLabel, Select, Dialog, DialogTitle, DialogContent, DialogActions, Alert, Skeleton, } from "@mui/material"; import { Add as AddIcon, Search as SearchIcon, Clear as ClearIcon, ViewList as ViewListIcon, ViewModule as ViewModuleIcon, MoreVert as MoreVertIcon, Edit as EditIcon, Delete as DeleteIcon, Inventory as InventoryIcon, FilterList as FilterListIcon, Image as ImageIcon, } from "@mui/icons-material"; import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid"; import { useArticles, useDeleteArticle, useCategoryTree } from "../hooks"; import { useWarehouseNavigation } from "../hooks/useWarehouseNavigation"; import { ArticleDto, formatCurrency } from "../types"; type ViewMode = "list" | "grid"; export default function ArticlesPage() { const [viewMode, setViewMode] = useState("list"); const [search, setSearch] = useState(""); const [categoryId, setCategoryId] = useState(""); const [showInactive, setShowInactive] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [articleToDelete, setArticleToDelete] = useState( null, ); const [menuAnchor, setMenuAnchor] = useState(null); const [menuArticle, setMenuArticle] = useState(null); const nav = useWarehouseNavigation(); const { data: articles, isLoading, error, } = useArticles({ categoryId: categoryId || undefined, search: search || undefined, isActive: showInactive ? undefined : true, }); const { data: categoryTree } = useCategoryTree(); const deleteMutation = useDeleteArticle(); // Flatten category tree for select const flatCategories = useMemo(() => { const result: { id: number; name: string; level: number }[] = []; const flatten = (categories: typeof categoryTree, level = 0) => { if (!categories) return; for (const cat of categories) { result.push({ id: cat.id, name: cat.name, level }); if (cat.children) flatten(cat.children, level + 1); } }; flatten(categoryTree); return result; }, [categoryTree]); const handleMenuOpen = ( event: React.MouseEvent, article: ArticleDto, ) => { event.stopPropagation(); setMenuAnchor(event.currentTarget); setMenuArticle(article); }; const handleMenuClose = () => { setMenuAnchor(null); setMenuArticle(null); }; const handleEdit = () => { if (menuArticle) { nav.goToEditArticle(menuArticle.id); } handleMenuClose(); }; const handleDeleteClick = () => { setArticleToDelete(menuArticle); setDeleteDialogOpen(true); handleMenuClose(); }; const handleDeleteConfirm = async () => { if (articleToDelete) { await deleteMutation.mutateAsync(articleToDelete.id); setDeleteDialogOpen(false); setArticleToDelete(null); } }; const handleViewStock = () => { if (menuArticle) { nav.goToArticle(menuArticle.id); } handleMenuClose(); }; const columns: GridColDef[] = [ { field: "hasImage", headerName: "", width: 60, sortable: false, renderCell: (params: GridRenderCellParams) => ( {params.row.hasImage ? ( {params.row.description} ) : ( )} ), }, { field: "code", headerName: "Codice", width: 120, renderCell: (params: GridRenderCellParams) => ( {params.value} ), }, { field: "description", headerName: "Descrizione", flex: 1, minWidth: 200, }, { field: "categoryName", headerName: "Categoria", width: 150, }, { field: "unitOfMeasure", headerName: "U.M.", width: 80, align: "center", }, { field: "weightedAverageCost", headerName: "Costo Medio", width: 120, align: "right", renderCell: (params: GridRenderCellParams) => formatCurrency(params.value || 0), }, { field: "isActive", headerName: "Stato", width: 100, renderCell: (params: GridRenderCellParams) => ( ), }, { field: "actions", headerName: "", width: 60, sortable: false, renderCell: (params: GridRenderCellParams) => ( handleMenuOpen(e, params.row)}> ), }, ]; if (error) { return ( Errore nel caricamento degli articoli: {(error as Error).message} ); } return ( {/* Header */} Anagrafica Articoli {/* Filters */} setSearch(e.target.value)} InputProps={{ startAdornment: ( ), endAdornment: search && ( setSearch("")}> ), }} /> Categoria value && setViewMode(value)} size="small" > {/* Content */} {viewMode === "list" ? ( nav.goToArticle(params.row.id)} disableRowSelectionOnClick sx={{ "& .MuiDataGrid-row:hover": { cursor: "pointer", }, }} /> ) : ( {isLoading ? ( Array.from({ length: 8 }).map((_, i) => ( )) ) : articles?.length === 0 ? ( Nessun articolo trovato ) : ( articles?.map((article) => ( nav.goToArticle(article.id)} > {article.hasImage ? ( ) : ( )} {article.code} {article.description} {article.categoryName && ( )} handleMenuOpen(e, article)} sx={{ ml: "auto" }} > )) )} )} {/* Context Menu */} Modifica Visualizza Giacenze Elimina {/* Delete Confirmation Dialog */} setDeleteDialogOpen(false)} > Conferma Eliminazione Sei sicuro di voler eliminare l'articolo{" "} {articleToDelete?.code} - {articleToDelete?.description} ? Questa azione non può essere annullata. ); }