/** * 倉庫管理主元件 * 重構後:職責更清晰,邏輯更模組化 */ import { useState } from "react"; import { Plus, ArrowRightLeft } from "lucide-react"; import { Button } from "./ui/button"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "./ui/alert-dialog"; import { toast } from "sonner@2.0.3"; import WarehouseDialog from "./WarehouseDialog"; import TransferOrderDialog, { TransferOrder } from "./TransferOrderDialog"; import SearchToolbar from "./shared/SearchToolbar"; import WarehouseFilter from "./warehouse/WarehouseFilter"; import WarehouseCard from "./warehouse/WarehouseCard"; import WarehouseEmptyState from "./warehouse/WarehouseEmptyState"; import { Warehouse, WarehouseInventory, Store, SafetyStockSetting } from "../types/warehouse"; import { useWarehouseFilter } from "../hooks/useWarehouseFilter"; import { calculateWarehouseStats, hasWarehouseWarning } from "../utils/inventory"; import { generateId, getCurrentDate, generateOrderNumber } from "../utils/format"; export type { Warehouse, WarehouseInventory }; interface WarehouseManagementProps { onNavigateToInventory: (warehouseId: string) => void; inventories: WarehouseInventory[]; onUpdateInventories: (inventories: WarehouseInventory[]) => void; safetyStockSettings: SafetyStockSetting[]; } export default function WarehouseManagement({ onNavigateToInventory, inventories, onUpdateInventories, safetyStockSettings, }: WarehouseManagementProps) { // 門市列表(Mock 資料) const [stores] = useState([ { id: "store-1", name: "信義門市", address: "台北市信義區信義路五段10號", }, { id: "store-2", name: "敦化門市", address: "台北市大安區敦化南路一段100號", }, { id: "store-3", name: "南京門市", address: "台北市松山區南京東路三段256號", }, ]); // 倉庫狀態 const [warehouses, setWarehouses] = useState([ { id: "1", name: "中央倉庫", address: "台北市信義區信義路五段7號", manager: "張經理", phone: "02-1234-5678", description: "主要原物料儲存倉庫", createdAt: "2025-11-01", type: "中央倉庫", }, { id: "2", name: "門市冷藏庫", address: "台北市大安區敦化南路一段100號", manager: "李主管", phone: "02-8765-4321", description: "門市專用冷藏倉庫", createdAt: "2025-11-10", type: "門市", storeId: "store-2", storeName: "敦化門市", }, ]); // 篩選狀態 const [searchTerm, setSearchTerm] = useState(""); const [typeFilter, setTypeFilter] = useState("all"); // 對話框狀態 const [isDialogOpen, setIsDialogOpen] = useState(false); const [editingWarehouse, setEditingWarehouse] = useState(null); const [transferOrderDialogOpen, setTransferOrderDialogOpen] = useState(false); const [editingTransferOrder, setEditingTransferOrder] = useState(null); const [transferOrders, setTransferOrders] = useState([]); // 使用篩選 Hook const filteredWarehouses = useWarehouseFilter(warehouses, searchTerm, typeFilter); // 倉庫操作處理函式 const handleAddWarehouse = () => { setEditingWarehouse(null); setIsDialogOpen(true); }; const handleEditWarehouse = (warehouse: Warehouse) => { setEditingWarehouse(warehouse); setIsDialogOpen(true); }; const handleSaveWarehouse = (warehouse: Omit) => { if (editingWarehouse) { setWarehouses( warehouses.map((w) => w.id === editingWarehouse.id ? { ...w, ...warehouse } : w ) ); toast.success("倉庫資料已更新"); } else { const newWarehouse: Warehouse = { id: generateId(), ...warehouse, createdAt: getCurrentDate(), }; setWarehouses([...warehouses, newWarehouse]); toast.success("倉庫已新增"); } setIsDialogOpen(false); setEditingWarehouse(null); }; const handleDeleteWarehouse = (id: string) => { setWarehouses(warehouses.filter((w) => w.id !== id)); onUpdateInventories( inventories.filter((inv) => inv.warehouseId !== id) ); toast.success("倉庫已刪除"); }; // 撥補單操作處理函式 const handleAddTransferOrder = () => { setEditingTransferOrder(null); setTransferOrderDialogOpen(true); }; const handleSaveTransferOrder = ( orderData: Omit ) => { const newOrder: TransferOrder = { id: generateId(), orderNumber: generateOrderNumber(), ...orderData, createdAt: getCurrentDate(), }; setTransferOrders([...transferOrders, newOrder]); // 更新庫存 const updatedInventories = [...inventories]; // 尋找來源倉庫庫存 const sourceIndex = updatedInventories.findIndex( (inv) => inv.warehouseId === orderData.sourceWarehouseId && inv.productId === orderData.productId && inv.batchNumber === orderData.batchNumber ); if (sourceIndex !== -1) { // 減少來源倉庫數量 updatedInventories[sourceIndex] = { ...updatedInventories[sourceIndex], quantity: updatedInventories[sourceIndex].quantity - orderData.quantity, }; // 尋找或建立目標倉庫庫存 const targetIndex = updatedInventories.findIndex( (inv) => inv.warehouseId === orderData.targetWarehouseId && inv.productId === orderData.productId && inv.batchNumber === orderData.batchNumber ); if (targetIndex !== -1) { // 更新既有目標倉庫數量 updatedInventories[targetIndex] = { ...updatedInventories[targetIndex], quantity: updatedInventories[targetIndex].quantity + orderData.quantity, }; } else { // 建立新的目標倉庫庫存項目 const sourceItem = updatedInventories[sourceIndex]; updatedInventories.push({ warehouseId: orderData.targetWarehouseId, productId: orderData.productId, productName: orderData.productName, quantity: orderData.quantity, batchNumber: orderData.batchNumber, expiryDate: sourceItem.expiryDate, }); } onUpdateInventories(updatedInventories); } toast.success(`撥補單 ${newOrder.orderNumber} 已新增並完成庫存調整`); setTransferOrderDialogOpen(false); }; return (
{/* 頁面標題 */}

倉庫管理

管理倉庫資訊與庫存配置

{/* 工具列 */}
{/* 搜尋框 */} {/* 類別篩選 */}
{/* 操作按鈕 */}
{/* 倉庫卡片列表 */} {filteredWarehouses.length === 0 ? ( ) : (
{filteredWarehouses.map((warehouse) => ( ))}
)} {/* 倉庫對話框 */} {/* 撥補單對話框 */}
); }