first commit
This commit is contained in:
723
source-code/ERP(A-b)-倉庫管理/src/App.tsx
Normal file
723
source-code/ERP(A-b)-倉庫管理/src/App.tsx
Normal file
@@ -0,0 +1,723 @@
|
||||
import { useState } from "react";
|
||||
import NavigationSidebar from "./components/NavigationSidebar";
|
||||
import WarehouseManagement from "./components/WarehouseManagement";
|
||||
import WarehouseInventoryPage from "./components/WarehouseInventoryPage";
|
||||
import AddInventoryPage from "./components/AddInventoryPage";
|
||||
import EditInventoryPage from "./components/EditInventoryPage";
|
||||
import SafetyStockPage from "./components/SafetyStockPage";
|
||||
import { Toaster } from "./components/ui/sonner";
|
||||
import { WarehouseInventory, Warehouse, InventoryTransaction, InboundItem, InboundReason, SafetyStockSetting } from "./types/warehouse";
|
||||
import { toast } from "sonner@2.0.3";
|
||||
import { generateId } from "./utils/format";
|
||||
|
||||
interface PageState {
|
||||
page: string;
|
||||
params?: {
|
||||
warehouseId?: string;
|
||||
inventoryId?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const [currentPage, setCurrentPage] = useState<PageState>({
|
||||
page: "warehouse-management",
|
||||
});
|
||||
|
||||
// Shared inventory state
|
||||
const [inventories, setInventories] = useState<WarehouseInventory[]>([
|
||||
// ===== 中央倉(id=1)- 原物料庫存 =====
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "101",
|
||||
productName: "二砂糖",
|
||||
quantity: 50,
|
||||
batchNumber: "SG20251201",
|
||||
expiryDate: "2026-12-01",
|
||||
lastInboundDate: "2025-12-01",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "101",
|
||||
productName: "二砂糖",
|
||||
quantity: 45,
|
||||
batchNumber: "SG20251115",
|
||||
expiryDate: "2026-11-15",
|
||||
lastInboundDate: "2025-11-15",
|
||||
lastOutboundDate: "2025-12-08",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "102",
|
||||
productName: "黑糖",
|
||||
quantity: 30,
|
||||
batchNumber: "BS20251205",
|
||||
expiryDate: "2026-06-05",
|
||||
lastInboundDate: "2025-12-05",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "103",
|
||||
productName: "冰糖",
|
||||
quantity: 25,
|
||||
batchNumber: "RS20251203",
|
||||
expiryDate: "2026-12-03",
|
||||
lastInboundDate: "2025-12-03",
|
||||
lastOutboundDate: "2025-12-07",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "104",
|
||||
productName: "奶精粉",
|
||||
quantity: 18,
|
||||
batchNumber: "CR20251208",
|
||||
expiryDate: "2026-03-08",
|
||||
lastInboundDate: "2025-12-08",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "105",
|
||||
productName: "鮮奶油",
|
||||
quantity: 12,
|
||||
batchNumber: "FC20251210",
|
||||
expiryDate: "2025-12-25",
|
||||
lastInboundDate: "2025-12-10",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "106",
|
||||
productName: "紅豆(生)",
|
||||
quantity: 40,
|
||||
batchNumber: "RBR20251202",
|
||||
expiryDate: "2026-06-02",
|
||||
lastInboundDate: "2025-12-02",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "107",
|
||||
productName: "綠豆(生)",
|
||||
quantity: 35,
|
||||
batchNumber: "GBR20251204",
|
||||
expiryDate: "2026-06-04",
|
||||
lastInboundDate: "2025-12-04",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "108",
|
||||
productName: "芋頭(生)",
|
||||
quantity: 28,
|
||||
batchNumber: "TR20251206",
|
||||
expiryDate: "2026-01-06",
|
||||
lastInboundDate: "2025-12-06",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "109",
|
||||
productName: "地瓜(生)",
|
||||
quantity: 32,
|
||||
batchNumber: "SPR20251207",
|
||||
expiryDate: "2026-01-07",
|
||||
lastInboundDate: "2025-12-07",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "110",
|
||||
productName: "仙草乾",
|
||||
quantity: 20,
|
||||
batchNumber: "GD20251205",
|
||||
expiryDate: "2026-12-05",
|
||||
lastInboundDate: "2025-12-05",
|
||||
lastOutboundDate: "2025-12-08",
|
||||
},
|
||||
|
||||
// ===== 中央倉(id=1)- 半成品庫存 =====
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "1",
|
||||
productName: "粉粿原漿",
|
||||
quantity: 25,
|
||||
batchNumber: "PG20251201",
|
||||
expiryDate: "2025-12-15",
|
||||
lastInboundDate: "2025-12-01",
|
||||
lastOutboundDate: "2025-12-08",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "1",
|
||||
productName: "粉粿原漿",
|
||||
quantity: 30,
|
||||
batchNumber: "PG20251128",
|
||||
expiryDate: "2025-12-12",
|
||||
lastInboundDate: "2025-11-28",
|
||||
lastOutboundDate: "2025-12-06",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "2",
|
||||
productName: "黑糖粉圓(未加糖)",
|
||||
quantity: 8,
|
||||
batchNumber: "BT20251203",
|
||||
expiryDate: "2025-12-10",
|
||||
lastInboundDate: "2025-12-03",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "2",
|
||||
productName: "黑糖粉圓(未加糖)",
|
||||
quantity: 15,
|
||||
batchNumber: "BT20251130",
|
||||
expiryDate: "2025-12-07",
|
||||
lastInboundDate: "2025-11-30",
|
||||
lastOutboundDate: "2025-12-05",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "3",
|
||||
productName: "熟紅豆(未加糖)",
|
||||
quantity: 12,
|
||||
batchNumber: "RB20251205",
|
||||
expiryDate: "2025-12-12",
|
||||
lastInboundDate: "2025-12-05",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "3",
|
||||
productName: "熟紅豆(未加糖)",
|
||||
quantity: 18,
|
||||
batchNumber: "RB20251202",
|
||||
expiryDate: "2025-12-09",
|
||||
lastInboundDate: "2025-12-02",
|
||||
lastOutboundDate: "2025-12-07",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "4",
|
||||
productName: "熟綠豆(未加糖)",
|
||||
quantity: 10,
|
||||
batchNumber: "GB20251204",
|
||||
expiryDate: "2025-12-11",
|
||||
lastInboundDate: "2025-12-04",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "4",
|
||||
productName: "熟綠豆(未加糖)",
|
||||
quantity: 14,
|
||||
batchNumber: "GB20251201",
|
||||
expiryDate: "2025-12-08",
|
||||
lastInboundDate: "2025-12-01",
|
||||
lastOutboundDate: "2025-12-06",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "5",
|
||||
productName: "芋頭泥(無調味)",
|
||||
quantity: 20,
|
||||
batchNumber: "TM20251206",
|
||||
expiryDate: "2025-12-20",
|
||||
lastInboundDate: "2025-12-06",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "5",
|
||||
productName: "芋頭泥(無調味)",
|
||||
quantity: 25,
|
||||
batchNumber: "TM20251203",
|
||||
expiryDate: "2025-12-17",
|
||||
lastInboundDate: "2025-12-03",
|
||||
lastOutboundDate: "2025-12-08",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "6",
|
||||
productName: "地瓜泥(無調味)",
|
||||
quantity: 18,
|
||||
batchNumber: "SM20251207",
|
||||
expiryDate: "2025-12-21",
|
||||
lastInboundDate: "2025-12-07",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "6",
|
||||
productName: "地瓜泥(無調味)",
|
||||
quantity: 22,
|
||||
batchNumber: "SM20251204",
|
||||
expiryDate: "2025-12-18",
|
||||
lastInboundDate: "2025-12-04",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "7",
|
||||
productName: "仙草原凍(整塊)",
|
||||
quantity: 16,
|
||||
batchNumber: "GJ20251208",
|
||||
expiryDate: "2025-12-22",
|
||||
lastInboundDate: "2025-12-08",
|
||||
lastOutboundDate: "2025-12-10",
|
||||
},
|
||||
{
|
||||
warehouseId: "1",
|
||||
productId: "7",
|
||||
productName: "仙草原凍(整塊)",
|
||||
quantity: 20,
|
||||
batchNumber: "GJ20251205",
|
||||
expiryDate: "2025-12-19",
|
||||
lastInboundDate: "2025-12-05",
|
||||
lastOutboundDate: "2025-12-09",
|
||||
},
|
||||
|
||||
// ===== 門市冷藏庫(id=2)- 半成品庫存 =====
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "1",
|
||||
productName: "粉粿原漿",
|
||||
quantity: 8,
|
||||
batchNumber: "PG20251209",
|
||||
expiryDate: "2025-12-16",
|
||||
lastInboundDate: "2025-12-09",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "2",
|
||||
productName: "黑糖粉圓(未加糖)",
|
||||
quantity: 6,
|
||||
batchNumber: "BT20251208",
|
||||
expiryDate: "2025-12-13",
|
||||
lastInboundDate: "2025-12-08",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "3",
|
||||
productName: "熟紅豆(未加糖)",
|
||||
quantity: 5,
|
||||
batchNumber: "RB20251209",
|
||||
expiryDate: "2025-12-14",
|
||||
lastInboundDate: "2025-12-09",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "4",
|
||||
productName: "熟綠豆(未加糖)",
|
||||
quantity: 4,
|
||||
batchNumber: "GB20251210",
|
||||
expiryDate: "2025-12-15",
|
||||
lastInboundDate: "2025-12-10",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "5",
|
||||
productName: "芋頭泥(無調味)",
|
||||
quantity: 10,
|
||||
batchNumber: "TM20251210",
|
||||
expiryDate: "2025-12-24",
|
||||
lastInboundDate: "2025-12-10",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "6",
|
||||
productName: "地瓜泥(無調味)",
|
||||
quantity: 9,
|
||||
batchNumber: "SM20251209",
|
||||
expiryDate: "2025-12-23",
|
||||
lastInboundDate: "2025-12-09",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
{
|
||||
warehouseId: "2",
|
||||
productId: "7",
|
||||
productName: "仙草原凍(整塊)",
|
||||
quantity: 7,
|
||||
batchNumber: "GJ20251210",
|
||||
expiryDate: "2025-12-24",
|
||||
lastInboundDate: "2025-12-10",
|
||||
lastOutboundDate: "2025-12-11",
|
||||
},
|
||||
]);
|
||||
|
||||
const [warehouses] = useState([
|
||||
{
|
||||
id: "1",
|
||||
name: "中央倉",
|
||||
address: "台北市信義區信義路五段7號",
|
||||
manager: "張經理",
|
||||
phone: "02-1234-5678",
|
||||
description: "主要原物料儲存倉庫",
|
||||
createdAt: "2025-11-01",
|
||||
type: "中央倉庫" as const,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "門市冷藏庫",
|
||||
address: "台北市大安區敦化南路一段100號",
|
||||
manager: "李主管",
|
||||
phone: "02-8765-4321",
|
||||
description: "門市專用冷藏倉庫",
|
||||
createdAt: "2025-11-10",
|
||||
type: "門市" as const,
|
||||
},
|
||||
]);
|
||||
|
||||
// Shared inventory transactions state
|
||||
const [transactions, setTransactions] = useState<InventoryTransaction[]>([]);
|
||||
|
||||
// Safety stock settings state
|
||||
const [safetyStockSettings, setSafetyStockSettings] = useState<SafetyStockSetting[]>([]);
|
||||
|
||||
const handleNavigate = (path: string, params?: { warehouseId?: string }) => {
|
||||
setCurrentPage({ page: path, params });
|
||||
};
|
||||
|
||||
const handleNavigateToInventory = (warehouseId: string) => {
|
||||
setCurrentPage({ page: "warehouse-inventory", params: { warehouseId } });
|
||||
};
|
||||
|
||||
const handleBackFromInventory = () => {
|
||||
setCurrentPage({ page: "warehouse-management" });
|
||||
};
|
||||
|
||||
const handleSaveInventory = (
|
||||
warehouseId: string,
|
||||
updatedInventories: WarehouseInventory[]
|
||||
) => {
|
||||
// Remove old inventories for this warehouse
|
||||
const otherInventories = inventories.filter(
|
||||
(inv) => inv.warehouseId !== warehouseId
|
||||
);
|
||||
// Add updated inventories
|
||||
setInventories([...otherInventories, ...updatedInventories]);
|
||||
};
|
||||
|
||||
const handleNavigateToEditInventory = (warehouseId: string, inventoryId: string) => {
|
||||
setCurrentPage({ page: "edit-inventory", params: { warehouseId, inventoryId } });
|
||||
};
|
||||
|
||||
const handleBackFromEditInventory = (warehouseId: string) => {
|
||||
setCurrentPage({ page: "warehouse-inventory", params: { warehouseId } });
|
||||
};
|
||||
|
||||
const handleUpdateInventory = (
|
||||
warehouseId: string,
|
||||
updatedInventory: WarehouseInventory & { inventoryId: string }
|
||||
) => {
|
||||
// 從 inventoryId 解析出索引
|
||||
const inventoryIdParts = updatedInventory.inventoryId.split('-');
|
||||
const index = parseInt(inventoryIdParts[inventoryIdParts.length - 1], 10);
|
||||
|
||||
// 找出該倉庫的所有庫存及其索引
|
||||
const warehouseInventories = inventories.filter((inv) => inv.warehouseId === warehouseId);
|
||||
const otherInventories = inventories.filter((inv) => inv.warehouseId !== warehouseId);
|
||||
|
||||
// 更新特定索引的庫存項目
|
||||
const updatedWarehouseInventories = warehouseInventories.map((inv, idx) => {
|
||||
return idx === index ? updatedInventory : inv;
|
||||
});
|
||||
|
||||
setInventories([...otherInventories, ...updatedWarehouseInventories]);
|
||||
handleBackFromEditInventory(warehouseId);
|
||||
};
|
||||
|
||||
const handleDeleteInventory = (warehouseId: string, inventoryId: string) => {
|
||||
// 從 inventoryId 解析出索引
|
||||
const inventoryIdParts = inventoryId.split('-');
|
||||
const index = parseInt(inventoryIdParts[inventoryIdParts.length - 1], 10);
|
||||
|
||||
// 找出該倉庫的所有庫存
|
||||
const warehouseInventories = inventories.filter((inv) => inv.warehouseId === warehouseId);
|
||||
const otherInventories = inventories.filter((inv) => inv.warehouseId !== warehouseId);
|
||||
|
||||
// 刪除特定索引的庫存項目
|
||||
const updatedWarehouseInventories = warehouseInventories.filter((_, idx) => idx !== index);
|
||||
|
||||
setInventories([...otherInventories, ...updatedWarehouseInventories]);
|
||||
handleBackFromEditInventory(warehouseId);
|
||||
};
|
||||
|
||||
const handleNavigateToAddInventory = (warehouseId: string) => {
|
||||
setCurrentPage({ page: "add-inventory", params: { warehouseId } });
|
||||
};
|
||||
|
||||
const handleBackFromAddInventory = (warehouseId: string) => {
|
||||
setCurrentPage({ page: "warehouse-inventory", params: { warehouseId } });
|
||||
};
|
||||
|
||||
const handleNavigateToSafetyStock = (warehouseId: string) => {
|
||||
setCurrentPage({ page: "safety-stock", params: { warehouseId } });
|
||||
};
|
||||
|
||||
const handleBackFromSafetyStock = (warehouseId: string) => {
|
||||
setCurrentPage({ page: "warehouse-inventory", params: { warehouseId } });
|
||||
};
|
||||
|
||||
const handleSaveSafetyStockSettings = (
|
||||
warehouseId: string,
|
||||
settings: SafetyStockSetting[]
|
||||
) => {
|
||||
// 移除該倉庫舊的設定
|
||||
const otherSettings = safetyStockSettings.filter(
|
||||
(s) => s.warehouseId !== warehouseId
|
||||
);
|
||||
// 添加新的設定
|
||||
setSafetyStockSettings([...otherSettings, ...settings]);
|
||||
};
|
||||
|
||||
const handleSaveInbound = (
|
||||
warehouseId: string,
|
||||
data: {
|
||||
inboundDate: string;
|
||||
reason: InboundReason;
|
||||
notes: string;
|
||||
items: InboundItem[];
|
||||
}
|
||||
) => {
|
||||
const now = new Date().toISOString();
|
||||
const warehouse = warehouses.find((w) => w.id === warehouseId);
|
||||
const warehouseName = warehouse?.name || "";
|
||||
|
||||
const currentInventories = inventories.filter((inv) => inv.warehouseId === warehouseId);
|
||||
const updatedInventories = [...currentInventories];
|
||||
|
||||
// 處理每一筆入庫明細
|
||||
data.items.forEach((inboundItem) => {
|
||||
// 檢查是否已存在相同商品和批號的庫存
|
||||
const existingIndex = updatedInventories.findIndex(
|
||||
(item) =>
|
||||
item.productId === inboundItem.productId &&
|
||||
item.batchNumber === inboundItem.batchNumber
|
||||
);
|
||||
|
||||
if (existingIndex !== -1) {
|
||||
// 更新既有庫存數量
|
||||
updatedInventories[existingIndex] = {
|
||||
...updatedInventories[existingIndex],
|
||||
quantity: updatedInventories[existingIndex].quantity + inboundItem.quantity,
|
||||
lastInboundDate: data.inboundDate,
|
||||
};
|
||||
} else {
|
||||
// 新增庫存項目
|
||||
const newItem: WarehouseInventory = {
|
||||
warehouseId,
|
||||
productId: inboundItem.productId,
|
||||
productName: inboundItem.productName,
|
||||
quantity: inboundItem.quantity,
|
||||
batchNumber: inboundItem.batchNumber,
|
||||
expiryDate: inboundItem.expiryDate,
|
||||
lastInboundDate: data.inboundDate,
|
||||
};
|
||||
updatedInventories.push(newItem);
|
||||
}
|
||||
|
||||
// 建立庫存異動記錄
|
||||
const transaction: InventoryTransaction = {
|
||||
id: generateId(),
|
||||
warehouseId,
|
||||
warehouseName,
|
||||
productId: inboundItem.productId,
|
||||
productName: inboundItem.productName,
|
||||
batchNumber: inboundItem.batchNumber,
|
||||
quantity: inboundItem.quantity,
|
||||
transactionType: "手動入庫",
|
||||
reason: data.reason,
|
||||
notes: data.notes,
|
||||
expiryDate: inboundItem.expiryDate,
|
||||
operatorName: "系統使用者",
|
||||
createdAt: now,
|
||||
};
|
||||
setTransactions([...transactions, transaction]);
|
||||
});
|
||||
|
||||
// 更新庫存
|
||||
handleSaveInventory(warehouseId, updatedInventories);
|
||||
|
||||
const totalInboundQty = data.items.reduce((sum, item) => sum + item.quantity, 0);
|
||||
toast.success(`入庫成功!共 ${data.items.length} 項商品,總數量 ${totalInboundQty}`);
|
||||
|
||||
// 返回庫存管理頁面
|
||||
handleBackFromAddInventory(warehouseId);
|
||||
};
|
||||
|
||||
const renderPage = () => {
|
||||
switch (currentPage.page) {
|
||||
case "warehouse-management":
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
case "warehouse-inventory": {
|
||||
const warehouseId = currentPage.params?.warehouseId;
|
||||
const warehouse = warehouses.find((w) => w.id === warehouseId);
|
||||
if (!warehouse) {
|
||||
// Fallback to warehouse management if warehouse not found
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<WarehouseInventoryPage
|
||||
warehouseId={warehouse.id}
|
||||
warehouseName={warehouse.name}
|
||||
inventories={inventories.filter(
|
||||
(inv) => inv.warehouseId === warehouse.id
|
||||
)}
|
||||
safetyStockSettings={safetyStockSettings.filter(
|
||||
(s) => s.warehouseId === warehouse.id
|
||||
)}
|
||||
onBack={handleBackFromInventory}
|
||||
onNavigateToAddInventory={() => handleNavigateToAddInventory(warehouse.id)}
|
||||
onNavigateToEditInventory={(inventoryId) =>
|
||||
handleNavigateToEditInventory(warehouse.id, inventoryId)
|
||||
}
|
||||
onNavigateToSafetyStock={() => handleNavigateToSafetyStock(warehouse.id)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "add-inventory": {
|
||||
const warehouseId = currentPage.params?.warehouseId;
|
||||
const warehouse = warehouses.find((w) => w.id === warehouseId);
|
||||
if (!warehouse) {
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<AddInventoryPage
|
||||
warehouseId={warehouse.id}
|
||||
warehouseName={warehouse.name}
|
||||
onBack={() => handleBackFromAddInventory(warehouse.id)}
|
||||
onSave={(data) => handleSaveInbound(warehouse.id, data)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "edit-inventory": {
|
||||
const warehouseId = currentPage.params?.warehouseId;
|
||||
const inventoryId = currentPage.params?.inventoryId;
|
||||
const warehouse = warehouses.find((w) => w.id === warehouseId);
|
||||
|
||||
if (!warehouse || !inventoryId) {
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 找出對應的庫存項目
|
||||
const warehouseInventories = inventories.filter((inv) => inv.warehouseId === warehouseId);
|
||||
const inventoryIdParts = inventoryId.split('-');
|
||||
const index = parseInt(inventoryIdParts[inventoryIdParts.length - 1], 10);
|
||||
const inventory = warehouseInventories[index];
|
||||
|
||||
if (!inventory) {
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EditInventoryPage
|
||||
inventory={{ ...inventory, inventoryId }}
|
||||
warehouseName={warehouse.name}
|
||||
onBack={() => handleBackFromEditInventory(warehouse.id)}
|
||||
onSave={(updatedInventory) => handleUpdateInventory(warehouse.id, updatedInventory)}
|
||||
onDelete={(invId) => handleDeleteInventory(warehouse.id, invId)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "safety-stock": {
|
||||
const warehouseId = currentPage.params?.warehouseId;
|
||||
const warehouse = warehouses.find((w) => w.id === warehouseId);
|
||||
|
||||
if (!warehouse) {
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// 找出該倉庫的所有庫存
|
||||
const warehouseInventories = inventories.filter((inv) => inv.warehouseId === warehouseId);
|
||||
|
||||
return (
|
||||
<SafetyStockPage
|
||||
warehouseId={warehouse.id}
|
||||
warehouseName={warehouse.name}
|
||||
safetyStockSettings={safetyStockSettings.filter((s) => s.warehouseId === warehouseId)}
|
||||
inventories={warehouseInventories}
|
||||
onBack={() => handleBackFromSafetyStock(warehouse.id)}
|
||||
onSave={(settings) => handleSaveSafetyStockSettings(warehouse.id, settings)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
// Default to warehouse management
|
||||
return (
|
||||
<WarehouseManagement
|
||||
onNavigateToInventory={handleNavigateToInventory}
|
||||
inventories={inventories}
|
||||
onUpdateInventories={setInventories}
|
||||
safetyStockSettings={safetyStockSettings}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen bg-background">
|
||||
{/* Sidebar Navigation */}
|
||||
<NavigationSidebar
|
||||
currentPath={currentPage.page}
|
||||
onNavigate={handleNavigate}
|
||||
/>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="flex-1 overflow-auto">
|
||||
{renderPage()}
|
||||
</main>
|
||||
|
||||
<Toaster />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user