UI優化: 全系統狀態標籤 (StatusBadge) 統一化重構完成 (Phase 3 & 4)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { Badge } from "@/Components/ui/badge";
|
||||
import { StatusBadge, StatusVariant } from "@/Components/shared/StatusBadge";
|
||||
|
||||
export type GoodsReceiptStatus = 'processing' | 'completed' | 'cancelled';
|
||||
|
||||
export const GOODS_RECEIPT_STATUS_CONFIG: Record<string, { label: string; variant: "default" | "secondary" | "destructive" | "outline" | "success" | "warning" }> = {
|
||||
processing: { label: "處理中", variant: "warning" },
|
||||
export const GOODS_RECEIPT_STATUS_CONFIG: Record<string, { label: string; variant: StatusVariant }> = {
|
||||
processing: { label: "處理中", variant: "info" },
|
||||
completed: { label: "已完成", variant: "success" },
|
||||
cancelled: { label: "已取消", variant: "destructive" },
|
||||
};
|
||||
@@ -19,28 +19,9 @@ export default function GoodsReceiptStatusBadge({
|
||||
}: GoodsReceiptStatusBadgeProps) {
|
||||
const config = GOODS_RECEIPT_STATUS_CONFIG[status] || { label: "未知", variant: "outline" };
|
||||
|
||||
// Apply custom styling based on variant mapping if not using standard badge variants
|
||||
let badgeClass = "";
|
||||
switch (config.variant) {
|
||||
case "success":
|
||||
badgeClass = "bg-green-100 text-green-800 hover:bg-green-200 border-green-200";
|
||||
break;
|
||||
case "warning":
|
||||
badgeClass = "bg-yellow-100 text-yellow-800 hover:bg-yellow-200 border-yellow-200";
|
||||
break;
|
||||
case "destructive":
|
||||
badgeClass = "bg-red-100 text-red-800 hover:bg-red-200 border-red-200";
|
||||
break;
|
||||
default:
|
||||
badgeClass = "bg-gray-100 text-gray-800 hover:bg-gray-200 border-gray-200";
|
||||
}
|
||||
|
||||
return (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={`${className} font-medium px-2.5 py-0.5 rounded-full border ${badgeClass}`}
|
||||
>
|
||||
<StatusBadge variant={config.variant} className={className}>
|
||||
{config.label}
|
||||
</Badge>
|
||||
</StatusBadge>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
import { AlertTriangle, Edit, ChevronDown, ChevronRight, CheckCircle, Package } from "lucide-react";
|
||||
import { Edit, ChevronDown, ChevronRight, Package } from "lucide-react";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -14,14 +14,14 @@ import {
|
||||
TableRow,
|
||||
} from "@/Components/ui/table";
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import { Badge } from "@/Components/ui/badge";
|
||||
import { StatusBadge } from "@/Components/shared/StatusBadge";
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "@/Components/ui/collapsible";
|
||||
import { WarehouseInventory, SafetyStockSetting } from "@/types/warehouse";
|
||||
import { calculateProductTotalStock, getSafetyStockStatus } from "@/utils/inventory";
|
||||
import { getSafetyStockStatus } from "@/utils/inventory";
|
||||
import { formatDate } from "@/utils/format";
|
||||
|
||||
export type InventoryItemWithId = WarehouseInventory & { inventoryId: string };
|
||||
@@ -74,31 +74,28 @@ export default function InventoryTable({
|
||||
|
||||
// 獲取狀態徽章
|
||||
const getStatusBadge = (status: string) => {
|
||||
switch (status) {
|
||||
case "正常":
|
||||
return (
|
||||
<Badge className="bg-green-100 text-green-700 border-green-300">
|
||||
<CheckCircle className="mr-1 h-3 w-3" />
|
||||
正常
|
||||
</Badge>
|
||||
);
|
||||
case "接近":
|
||||
return (
|
||||
<Badge className="bg-yellow-100 text-yellow-700 border-yellow-300">
|
||||
<AlertTriangle className="mr-1 h-3 w-3" />
|
||||
接近
|
||||
</Badge>
|
||||
);
|
||||
case "低於":
|
||||
return (
|
||||
<Badge className="bg-red-100 text-red-700 border-red-300">
|
||||
<AlertTriangle className="mr-1 h-3 w-3" />
|
||||
低於
|
||||
</Badge>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
if (status === '正常') {
|
||||
return (
|
||||
<StatusBadge variant="success">
|
||||
庫存充足
|
||||
</StatusBadge>
|
||||
);
|
||||
}
|
||||
if (status === '接近') {
|
||||
return (
|
||||
<StatusBadge variant="warning">
|
||||
低於安全存量
|
||||
</StatusBadge>
|
||||
);
|
||||
}
|
||||
if (status === '低於') {
|
||||
return (
|
||||
<StatusBadge variant="destructive">
|
||||
嚴重短缺
|
||||
</StatusBadge>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -108,12 +105,12 @@ export default function InventoryTable({
|
||||
(sum, item) => sum + item.quantity,
|
||||
0
|
||||
);
|
||||
|
||||
|
||||
// 計算安全庫存狀態
|
||||
const status = group.safetySetting
|
||||
? getSafetyStockStatus(totalQuantity, group.safetySetting.safetyStock)
|
||||
: null;
|
||||
|
||||
|
||||
const isLowStock = status === "低於";
|
||||
const isExpanded = expandedProducts.has(group.productId);
|
||||
const hasInventory = group.items.length > 0;
|
||||
@@ -127,10 +124,9 @@ export default function InventoryTable({
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
{/* 商品標題 - 可點擊折疊 */}
|
||||
<CollapsibleTrigger asChild>
|
||||
<div
|
||||
className={`px-4 py-3 border-b cursor-pointer hover:bg-gray-100 transition-colors ${
|
||||
isLowStock ? "bg-red-50" : "bg-gray-50"
|
||||
}`}
|
||||
<div
|
||||
className={`px-4 py-3 border-b cursor-pointer hover:bg-gray-100 transition-colors ${isLowStock ? "bg-red-50" : "bg-gray-50"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -164,9 +160,9 @@ export default function InventoryTable({
|
||||
</>
|
||||
)}
|
||||
{!group.safetySetting && (
|
||||
<Badge variant="outline" className="text-gray-500">
|
||||
<StatusBadge variant="neutral">
|
||||
未設定
|
||||
</Badge>
|
||||
</StatusBadge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user