/** * 倉庫對話框元件 * 重構後:加入驗證邏輯與業務類型支援 */ import { useEffect, useState } from "react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/Components/ui/dialog"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/Components/ui/alert-dialog"; import { Input } from "@/Components/ui/input"; import { Label } from "@/Components/ui/label"; import { Textarea } from "@/Components/ui/textarea"; import { Button } from "@/Components/ui/button"; import { Trash2 } from "lucide-react"; import { Warehouse, WarehouseType } from "@/types/warehouse"; import { validateWarehouse } from "@/utils/validation"; import { toast } from "sonner"; import { SearchableSelect } from "@/Components/ui/searchable-select"; interface TransitWarehouseOption { id: string; name: string; license_plate?: string; driver_name?: string; } interface WarehouseDialogProps { open: boolean; onOpenChange: (open: boolean) => void; warehouse: Warehouse | null; onSave: (warehouse: Omit) => void; onDelete?: (warehouseId: string) => void; transitWarehouses?: TransitWarehouseOption[]; } const WAREHOUSE_TYPE_OPTIONS: { label: string; value: WarehouseType }[] = [ { label: "標準倉 (總倉)", value: "standard" }, { label: "生產倉 (廚房/加工)", value: "production" }, { label: "門市倉 (前台销售)", value: "retail" }, { label: "販賣機 (IoT設備)", value: "vending" }, { label: "在途倉 (物流車)", value: "transit" }, { label: "瑕疵倉 (報廢/檢驗)", value: "quarantine" }, ]; export default function WarehouseDialog({ open, onOpenChange, warehouse, onSave, onDelete, transitWarehouses = [], }: WarehouseDialogProps) { const [formData, setFormData] = useState<{ code: string; name: string; address: string; description: string; type: WarehouseType; license_plate: string; driver_name: string; default_transit_warehouse_id: string | null; }>({ code: "", name: "", address: "", description: "", type: "standard", license_plate: "", driver_name: "", default_transit_warehouse_id: null, }); const [showDeleteDialog, setShowDeleteDialog] = useState(false); useEffect(() => { if (warehouse) { setFormData({ code: warehouse.code, name: warehouse.name, address: warehouse.address || "", description: warehouse.description || "", type: warehouse.type || "standard", license_plate: warehouse.license_plate || "", driver_name: warehouse.driver_name || "", default_transit_warehouse_id: warehouse.default_transit_warehouse_id ? String(warehouse.default_transit_warehouse_id) : null, }); } else { setFormData({ code: "", name: "", address: "", description: "", type: "standard", license_plate: "", driver_name: "", default_transit_warehouse_id: null, }); } }, [warehouse, open]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const validation = validateWarehouse(formData); if (!validation.isValid) { toast.error(validation.error); return; } onSave(formData); }; const handleDelete = () => { if (warehouse && onDelete) { onDelete(warehouse.id); setShowDeleteDialog(false); onOpenChange(false); } }; return ( <> {warehouse ? "編輯倉庫" : "新增倉庫"} {warehouse ? "修改倉庫資訊" : "建立新的倉庫資訊"}
{/* 區塊 A:基本資訊 */}

基本資訊

{/* 倉庫編號 */}
setFormData({ ...formData, code: e.target.value })} placeholder="請輸入倉庫編號" required className="h-9" />
{/* 倉庫類型 */}
setFormData({ ...formData, type: val as WarehouseType })} options={WAREHOUSE_TYPE_OPTIONS} placeholder="選擇倉庫類型" className="h-9" showSearch={false} />
{/* 倉庫名稱 */}
setFormData({ ...formData, name: e.target.value })} placeholder="例:中央倉庫" required className="h-9" />
{/* 移動倉專屬資訊 */} {formData.type === 'transit' && (

車輛資訊 (在途倉)

setFormData({ ...formData, license_plate: e.target.value })} placeholder="例:ABC-1234" className="h-9 bg-white" />
setFormData({ ...formData, driver_name: e.target.value })} placeholder="例:王小明" className="h-9 bg-white" />
)} {/* 預設在途倉設定(僅非 transit 類型顯示) */} {formData.type !== 'transit' && transitWarehouses.length > 0 && (

調撥配送設定

從此倉庫建立調撥單時,系統將自動帶入此在途倉作為配送中繼倉

setFormData({ ...formData, default_transit_warehouse_id: val || null })} options={[ { label: "不指定", value: "" }, ...transitWarehouses.map((tw) => ({ label: `${tw.name}${tw.license_plate ? ` (${tw.license_plate})` : ''}`, value: tw.id, })), ]} placeholder="選擇預設在途倉" className="h-9 bg-white" />
)} {/* 區塊 B:位置 */}

位置與描述

{/* 倉庫地址 */}
setFormData({ ...formData, address: e.target.value })} placeholder="例:台北市信義區信義路五段7號" required className="h-9" />
{/* 備註說明 */}