/** * 新增安全庫存對話框(兩步驟) */ import { useState } from "react"; import { Search, ChevronRight, ChevronLeft } from "lucide-react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription, } from "@/Components/ui/dialog"; import { Button } from "@/Components/ui/button"; import { Input } from "@/Components/ui/input"; import { Label } from "@/Components/ui/label"; import { Checkbox } from "@/Components/ui/checkbox"; import { SafetyStockSetting, Product } from "@/types/warehouse"; import { toast } from "sonner"; import { Badge } from "@/Components/ui/badge"; interface AddSafetyStockDialogProps { open: boolean; onOpenChange: (open: boolean) => void; warehouseId: string; existingSettings: SafetyStockSetting[]; availableProducts: Product[]; onAdd: (settings: SafetyStockSetting[]) => void; } export default function AddSafetyStockDialog({ open, onOpenChange, warehouseId, existingSettings, availableProducts, onAdd, }: AddSafetyStockDialogProps) { const [step, setStep] = useState<1 | 2>(1); const [searchTerm, setSearchTerm] = useState(""); const [selectedProducts, setSelectedProducts] = useState>(new Set()); const [productQuantities, setProductQuantities] = useState>(new Map()); // 重置對話框 const resetDialog = () => { setStep(1); setSearchTerm(""); setSelectedProducts(new Set()); setProductQuantities(new Map()); }; // 關閉對話框 const handleClose = () => { resetDialog(); onOpenChange(false); }; // 已設定的商品 ID const existingProductIds = new Set(existingSettings.map((s) => s.productId)); // 可選擇的商品(排除已設定的) const selectableProducts = availableProducts.filter( (p) => !existingProductIds.has(p.id) ); // 篩選後的商品 const filteredProducts = selectableProducts.filter( (p) => p.name.toLowerCase().includes(searchTerm.toLowerCase()) || p.type.includes(searchTerm) ); // 切換商品選擇 const toggleProduct = (productId: string) => { const newSet = new Set(selectedProducts); if (newSet.has(productId)) { newSet.delete(productId); // 同時移除數量設定 const newQuantities = new Map(productQuantities); newQuantities.delete(productId); setProductQuantities(newQuantities); } else { newSet.add(productId); // 預設數量 const newQuantities = new Map(productQuantities); if (!newQuantities.has(productId)) { newQuantities.set(productId, 10); } setProductQuantities(newQuantities); } setSelectedProducts(newSet); }; // 更新商品安全庫存量 const updateQuantity = (productId: string, value: number) => { const newQuantities = new Map(productQuantities); newQuantities.set(productId, value); // 允許為 0 setProductQuantities(newQuantities); }; // 前往步驟 2 const goToStep2 = () => { if (selectedProducts.size === 0) { toast.error("請至少選擇一個商品"); return; } setStep(2); }; // 提交 const handleSubmit = () => { // 驗證所有商品都已輸入數量 const missingQuantity = Array.from(selectedProducts).some( (productId) => !productQuantities.has(productId) || (productQuantities.get(productId) ?? -1) < 0 ); if (missingQuantity) { toast.error("請為所有商品設定安全庫存量"); return; } // 創建安全庫存設定 const newSettings: SafetyStockSetting[] = Array.from(selectedProducts).map((productId) => { const product = availableProducts.find((p) => p.id === productId)!; return { id: `ss-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, warehouseId, productId, productName: product.name, productType: product.type, safetyStock: productQuantities.get(productId) || 0, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; }); onAdd(newSettings); // toast.success(`成功新增 ${newSettings.length} 項安全庫存設定`); // 父組件已處理 handleClose(); }; return ( 新增安全庫存 - 步驟 {step}/2 請選擇商品並設定安全庫存量。 {step === 1 ? ( // 步驟 1:選擇商品
setSearchTerm(e.target.value)} className="pl-10 button-outlined-primary" />
{filteredProducts.length === 0 ? (
{selectableProducts.length === 0 ? "所有商品都已設定安全庫存" : "無符合條件的商品"}
) : (
{filteredProducts.map((product) => { const isSelected = selectedProducts.has(product.id); return (
toggleProduct(product.id)} > toggleProduct(product.id)} />
{product.name}
{product.type}
); })}
)}
已選擇 {selectedProducts.size} 項商品
) : ( // 步驟 2:設定安全庫存量

為每個商品設定安全庫存量(共 {selectedProducts.size} 項)

{Array.from(selectedProducts).map((productId) => { const product = availableProducts.find((p) => p.id === productId)!; const quantity = productQuantities.get(productId) || 0; return (
{product.name} {product.type}
updateQuantity(productId, parseFloat(e.target.value) || 0) } placeholder="請輸入數量" className="flex-1 button-outlined-primary" /> {product.unit || '個'}
); })}
)} {step === 1 ? ( <> ) : ( <> )}
); }