Files
star-erp/source-code/ERP(B-ba)-廠商管理/src/components/VendorManagement/VendorDetail.tsx
2025-12-30 15:03:19 +08:00

192 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 廠商詳細資訊頁面
*/
import { useState } from "react";
import { Phone, Mail, Plus, ArrowLeft } from "lucide-react";
import { Label } from "../ui/label";
import { Button } from "../ui/button";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "../ui/alert-dialog";
import SupplyProductList from "./SupplyProductList";
import AddSupplyProductDialog from "./AddSupplyProductDialog";
import EditSupplyProductDialog from "./EditSupplyProductDialog";
import type { Supplier, SupplyProduct } from "../../types/vendor";
import type { Product } from "../../types/product";
interface VendorDetailProps {
supplier: Supplier;
products: Product[];
onBack: () => void;
onAddSupplyProduct: (supplierId: string, productId: string, lastPrice?: number) => void;
onUpdateSupplyProduct: (supplierId: string, productId: string, lastPrice?: number) => void;
onRemoveSupplyProduct: (supplierId: string, productId: string) => void;
}
export default function VendorDetail({
supplier,
products,
onBack,
onAddSupplyProduct,
onUpdateSupplyProduct,
onRemoveSupplyProduct,
}: VendorDetailProps) {
const [showAddDialog, setShowAddDialog] = useState(false);
const [showEditDialog, setShowEditDialog] = useState(false);
const [showRemoveDialog, setShowRemoveDialog] = useState(false);
const [selectedProduct, setSelectedProduct] = useState<SupplyProduct | null>(null);
const handleAddProduct = (productId: string, lastPrice?: number) => {
onAddSupplyProduct(supplier.id, productId, lastPrice);
setShowAddDialog(false);
};
const handleEditProduct = (product: SupplyProduct) => {
setSelectedProduct(product);
setShowEditDialog(true);
};
const handleUpdateProduct = (productId: string, lastPrice?: number) => {
onUpdateSupplyProduct(supplier.id, productId, lastPrice);
setShowEditDialog(false);
setSelectedProduct(null);
};
const handleRemoveProduct = (product: SupplyProduct) => {
setSelectedProduct(product);
setShowRemoveDialog(true);
};
const handleConfirmRemove = () => {
if (selectedProduct) {
onRemoveSupplyProduct(supplier.id, selectedProduct.productId);
}
setShowRemoveDialog(false);
setSelectedProduct(null);
};
return (
<div className="p-6">
{/* 返回按鈕 */}
<div className="mb-6">
<Button
variant="outline"
onClick={onBack}
className="gap-2 button-outlined-primary mb-6"
>
<ArrowLeft className="h-4 w-4" />
</Button>
<h1></h1>
<p className="body-sm text-muted-foreground mt-2">
</p>
</div>
{/* 基本資料 */}
<div className="bg-card rounded-lg border border-border p-6 mb-6">
<h3 className="mb-4"></h3>
<div className="grid grid-cols-2 gap-6">
<div>
<Label className="text-muted-foreground text-xs"></Label>
<p className="mt-1">{supplier.name}</p>
</div>
<div>
<Label className="text-muted-foreground text-xs"></Label>
<p className="mt-1">{supplier.contact || "-"}</p>
</div>
<div>
<Label className="text-muted-foreground text-xs"></Label>
<p className="mt-1 flex items-center gap-2">
<Phone className="h-3 w-3 text-muted-foreground" />
{supplier.phone || "-"}
</p>
</div>
<div>
<Label className="text-muted-foreground text-xs">Email</Label>
<p className="mt-1 flex items-center gap-2">
<Mail className="h-3 w-3 text-muted-foreground" />
{supplier.email || "-"}
</p>
</div>
</div>
</div>
{/* 供貨商品列表 */}
<div className="bg-card rounded-lg border border-border p-6">
<div className="flex items-center justify-between mb-4">
<h3></h3>
<Button
onClick={() => setShowAddDialog(true)}
className="gap-2 button-filled-primary"
size="sm"
>
<Plus className="h-4 w-4" />
</Button>
</div>
<SupplyProductList
products={supplier.supplyProducts}
onEdit={handleEditProduct}
onRemove={handleRemoveProduct}
/>
</div>
{/* 新增供貨商品對話框 */}
<AddSupplyProductDialog
open={showAddDialog}
products={products}
existingSupplyProducts={supplier.supplyProducts}
onClose={() => setShowAddDialog(false)}
onAdd={handleAddProduct}
/>
{/* 編輯供貨商品對話框 */}
<EditSupplyProductDialog
open={showEditDialog}
product={selectedProduct}
onClose={() => {
setShowEditDialog(false);
setSelectedProduct(null);
}}
onSave={handleUpdateProduct}
/>
{/* 取消供貨確認對話框 */}
<AlertDialog open={showRemoveDialog} onOpenChange={setShowRemoveDialog}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
{selectedProduct?.productName}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel
size="sm"
className="gap-2 button-outlined-primary"
>
</AlertDialogCancel>
<AlertDialogAction
size="sm"
className="gap-2 button-filled-error"
onClick={handleConfirmRemove}
>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
);
}