first commit

This commit is contained in:
2025-12-30 15:03:19 +08:00
commit c735c36009
902 changed files with 83591 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
/**
* 驗收頁面 - Mobile-first RWD
*/
import { ArrowLeft } from "lucide-react";
import { Button } from "./ui/button";
import { InspectionOrderInfo } from "./inspection/InspectionOrderInfo";
import { InspectionTable } from "./inspection/InspectionTable";
import { InspectionAmountSummary } from "./inspection/InspectionAmountSummary";
import { InspectionAutoActions } from "./inspection/InspectionAutoActions";
import { InspectionActionBar } from "./inspection/InspectionActionBar";
import { StatusProgressBar } from "./purchase-order/StatusProgressBar";
import type { PurchaseOrder, PurchaseOrderItem } from "../types/purchase-order";
import { useInspection } from "../hooks/useInspection";
interface InspectionPageProps {
order?: PurchaseOrder;
onComplete: (orderId: string, items: PurchaseOrderItem[]) => void;
onCancel: () => void;
}
export default function InspectionPage({
order,
onComplete,
onCancel,
}: InspectionPageProps) {
const {
inspectionItems,
statistics,
updateReceivedQuantity,
updateIssueNote,
} = useInspection({ order });
const handleComplete = () => {
if (!order) return;
// 更新商品數量(使用實際收到的數量)
const updatedItems: PurchaseOrderItem[] = inspectionItems.map((item) => ({
productId: item.productId,
productName: item.productName,
quantity: item.receivedQuantity,
unit: item.unit,
unitPrice: item.unitPrice,
previousPrice: item.previousPrice,
subtotal: item.receivedQuantity * item.unitPrice,
}));
onComplete(order.id, updatedItems);
};
if (!order) {
return (
<div className="p-4 md:p-6">
<div className="text-center text-muted-foreground"></div>
</div>
);
}
const hasIssues = statistics.shortageItems > 0;
const actualAmount = inspectionItems.reduce(
(sum, item) => sum + item.receivedQuantity * item.unitPrice,
0
);
return (
<div className="min-h-screen bg-background pb-24 md:pb-0">
{/* Header */}
<div className="sticky top-0 z-20 bg-background border-b-2 border-border p-4 md:p-6">
<div className="max-w-6xl mx-auto">
{/* 返回按鈕 - 手機版和桌面版都顯示 */}
<div className="flex items-center gap-2 mb-4">
<Button
variant="outline"
size="sm"
onClick={onCancel}
className="gap-2 button-outlined-primary"
>
<ArrowLeft className="h-4 w-4" />
<span className="hidden sm:inline"></span>
</Button>
</div>
<div>
<h1></h1>
<p className="body-sm text-muted-foreground mt-1">
</p>
</div>
</div>
</div>
{/* Main Content */}
<div className="max-w-6xl mx-auto px-4 md:px-6 py-6 space-y-6">
{/* Level 1: 訂單資訊卡片 */}
<InspectionOrderInfo order={order} hasIssues={hasIssues} />
{/* Level 2: 商品驗收 */}
<InspectionTable
items={inspectionItems}
onReceivedQuantityChange={updateReceivedQuantity}
onIssueNoteChange={updateIssueNote}
/>
{/* Level 3: 金額統計 */}
<InspectionAmountSummary
originalAmount={order.totalAmount}
actualAmount={actualAmount}
/>
{/* Level 4: 驗收後自動執行(收合狀態) */}
<InspectionAutoActions />
{/* 操作按鈕 */}
<InspectionActionBar onCancel={onCancel} onComplete={handleComplete} />
</div>
</div>
);
}