"use client"; import { useState, useEffect, useCallback } from "react"; import type { Article, ArticleFamily } from "@/src/types/article"; import type { Stabilimento, Magazzino } from "@/src/types/stabilimento"; import type { GiacenzePerArticolo } from "@/src/types/giacenza"; import type { TipoMovimento } from "@/src/types/movimento"; import ArticleCard from "./ArticleCard"; import ArticleModal from "./ArticleModal"; import MovimentoModal from "./MovimentoModal"; import StabilimentoMagazzinoSelector from "./StabilimentoMagazzinoSelector"; export default function ArticlesList() { const [articles, setArticles] = useState([]); const [families, setFamilies] = useState([]); const [giacenze, setGiacenze] = useState({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [search, setSearch] = useState(""); const [showModal, setShowModal] = useState(false); const [editingArticle, setEditingArticle] = useState
(null); const [showMovimentoModal, setShowMovimentoModal] = useState(false); const [movimentoArticle, setMovimentoArticle] = useState
(null); const [movimentoTipo, setMovimentoTipo] = useState("carico"); const [selectedStabilimento, setSelectedStabilimento] = useState(null); const [selectedMagazzino, setSelectedMagazzino] = useState(null); const fetchArticles = useCallback(async () => { setLoading(true); setError(null); try { const res = await fetch("/api/articoli"); if (!res.ok) throw new Error("Errore nel caricamento"); const data = await res.json(); setArticles(data.articles); setFamilies(data.families); } catch (err) { setError(err instanceof Error ? err.message : "Errore sconosciuto"); } finally { setLoading(false); } }, []); const fetchGiacenze = useCallback(async () => { if (!selectedStabilimento) { setGiacenze({}); return; } try { const params = new URLSearchParams(); if (selectedMagazzino) { params.set("magazzinoId", selectedMagazzino.id.toString()); } else { params.set("stabilimentoId", selectedStabilimento.id.toString()); } const res = await fetch(`/api/giacenze?${params}`); if (!res.ok) throw new Error("Errore caricamento giacenze"); const data = await res.json(); setGiacenze(data.giacenze); } catch (err) { console.error("Errore giacenze:", err); setGiacenze({}); } }, [selectedStabilimento, selectedMagazzino]); useEffect(() => { fetchArticles(); }, [fetchArticles]); useEffect(() => { fetchGiacenze(); }, [fetchGiacenze]); const handleSelectionChange = ({ stabilimento, magazzino }: { stabilimento: Stabilimento | null; magazzino: Magazzino | null }) => { setSelectedStabilimento(stabilimento); setSelectedMagazzino(magazzino); }; const handleEdit = (article: Article) => { setEditingArticle(article); setShowModal(true); }; const handleDelete = (deleted: Article) => { setArticles((prev) => prev.filter((a) => a.id !== deleted.id)); }; const handleSave = (saved: Article) => { if (editingArticle) { setArticles((prev) => prev.map((a) => (a.id === saved.id ? saved : a))); } else { setArticles((prev) => [saved, ...prev]); } setShowModal(false); setEditingArticle(null); fetchGiacenze(); }; const handleMovimento = (article: Article, tipo: TipoMovimento) => { setMovimentoArticle(article); setMovimentoTipo(tipo); setShowMovimentoModal(true); }; const handleMovimentoSuccess = () => { setShowMovimentoModal(false); setMovimentoArticle(null); fetchArticles(); fetchGiacenze(); }; const filteredArticles = articles.filter((article) => { if (!search) return true; const searchLower = search.toLowerCase(); return ( article.descrizione?.toLowerCase().includes(searchLower) || article.codice?.toLowerCase().includes(searchLower) || article.barcode?.toLowerCase().includes(searchLower) ); }); const sottoScorta = articles.filter((a) => a.quantita < a.quantita_minima).length; const magazzinoNome = selectedMagazzino?.descrizione || (selectedStabilimento ? `${selectedStabilimento.descrizione}` : undefined); return (
{/* Header */}

Articoli

{articles.length} articoli {sottoScorta > 0 && ({sottoScorta} sotto scorta)}

{/* Selettore Stabilimento/Magazzino */}
{/* Ricerca */}
setSearch(e.target.value)} placeholder="Cerca articoli..." className="w-full pl-9 pr-3 py-2 text-sm rounded-lg bg-zinc-900 border border-zinc-800 text-white placeholder-zinc-500 focus:outline-none focus:border-blue-500" />
{/* Lista articoli */}
{loading ? (
Caricamento...
) : error ? (

{error}

) : filteredArticles.length === 0 ? (
{search ? "Nessun articolo trovato" : "Nessun articolo"}
) : ( filteredArticles.map((article) => ( )) )}
{/* Modal Articolo */} {showModal && ( { setShowModal(false); setEditingArticle(null); }} onSave={handleSave} /> )} {/* Modal Movimento */} {showMovimentoModal && movimentoArticle && ( { setShowMovimentoModal(false); setMovimentoArticle(null); }} onSuccess={handleMovimentoSuccess} /> )}
); }