更新:優化配方詳情彈窗 UI 與一般修正
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/Components/ui/dialog";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/Components/ui/table";
|
||||
import { Badge } from "@/Components/ui/badge";
|
||||
import { Loader2, Package, Calendar, Clock, BookOpen } from "lucide-react";
|
||||
|
||||
interface RecipeDetailModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
recipe: any | null; // Detailed recipe object with items
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function RecipeDetailModal({ isOpen, onClose, recipe, isLoading }: RecipeDetailModalProps) {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onClose}>
|
||||
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto p-0 gap-0">
|
||||
<DialogHeader className="p-6 pb-4 border-b pr-12">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<DialogTitle className="text-xl font-bold text-gray-900">
|
||||
配方明細
|
||||
</DialogTitle>
|
||||
{recipe && (
|
||||
<Badge variant={recipe.is_active ? "default" : "secondary"} className="text-xs font-normal">
|
||||
{recipe.is_active ? "啟用中" : "已停用"}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 現代化元數據條 */}
|
||||
{recipe && (
|
||||
<div className="flex flex-wrap items-center gap-6 pt-2 text-sm text-gray-500">
|
||||
<div className="flex items-center gap-2">
|
||||
<BookOpen className="w-4 h-4 text-gray-400" />
|
||||
<span className="font-medium text-gray-700">{recipe.code}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-4 h-4 text-gray-400" />
|
||||
<span>建立於 {new Date(recipe.created_at).toLocaleDateString()}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock className="w-4 h-4 text-gray-400" />
|
||||
<span>更新於 {new Date(recipe.updated_at).toLocaleDateString()}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</DialogHeader>
|
||||
|
||||
<div className="bg-gray-50/50 p-6 min-h-[300px]">
|
||||
{isLoading ? (
|
||||
<div className="flex justify-center items-center py-12">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-primary-main" />
|
||||
</div>
|
||||
) : recipe ? (
|
||||
<div className="space-y-6">
|
||||
{/* 基本資訊區塊 */}
|
||||
<div className="border rounded-md overflow-hidden bg-white shadow-sm">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="bg-gray-50/50 hover:bg-gray-50/50">
|
||||
<TableHead className="w-[150px]">欄位</TableHead>
|
||||
<TableHead>內容</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell className="font-medium text-gray-700">配方名稱</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium">{recipe.name}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className="font-medium text-gray-700">對應成品</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{recipe.product?.name || '-'}</span>
|
||||
<span className="text-gray-400 text-xs bg-gray-100 px-1.5 py-0.5 rounded">{recipe.product?.code}</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell className="font-medium text-gray-700">標準產量</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium">
|
||||
{Number(recipe.yield_quantity).toLocaleString()} {recipe.product?.base_unit?.name || '份'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{recipe.description && (
|
||||
<TableRow>
|
||||
<TableCell className="font-medium text-gray-700 align-top pt-3">備註說明</TableCell>
|
||||
<TableCell className="text-gray-600 leading-relaxed py-3">
|
||||
{recipe.description}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{/* BOM 表格區塊 */}
|
||||
<div>
|
||||
<h3 className="text-sm font-bold text-gray-900 flex items-center gap-2 px-1 mb-3">
|
||||
<Package className="w-4 h-4 text-primary-main" />
|
||||
原物料清單 (BOM)
|
||||
</h3>
|
||||
<div className="border rounded-md overflow-hidden bg-white shadow-sm">
|
||||
<Table>
|
||||
<TableHeader className="bg-gray-50/50">
|
||||
<TableRow>
|
||||
<TableHead>原物料名稱 / 料號</TableHead>
|
||||
<TableHead className="text-right">標準用量</TableHead>
|
||||
<TableHead>單位</TableHead>
|
||||
<TableHead>備註</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{recipe.items?.length > 0 ? (
|
||||
recipe.items.map((item: any, index: number) => (
|
||||
<TableRow key={index} className="hover:bg-gray-50/50">
|
||||
<TableCell className="font-medium">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-gray-900">{item.product?.name || 'Unknown'}</span>
|
||||
<span className="text-xs text-gray-400">{item.product?.code}</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-right font-medium text-gray-900">
|
||||
{Number(item.quantity).toLocaleString()}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-600">
|
||||
{item.unit?.name || '-'}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-500 text-sm">
|
||||
{item.remark || '-'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="h-24 text-center text-gray-500">
|
||||
此配方尚未設定原物料
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="py-12 text-center text-gray-500">無法載入配方資料</div>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user