Files
sam-react-prod/src/components/production/WorkerScreen/MaterialInputModal.tsx

244 lines
7.9 KiB
TypeScript
Raw Normal View History

'use client';
/**
*
*
* :
* - FIFO (1 , 2 , 3+ )
* - (BOM )
* - / ( )
*/
import { useState } from 'react';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Checkbox } from '@/components/ui/checkbox';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import type { WorkOrder } from '../ProductionDashboard/types';
import type { MaterialInput } from './types';
// Mock 자재 데이터
const MOCK_MATERIALS: MaterialInput[] = [
{
id: '1',
materialCode: 'KD-RM-001',
materialName: 'SPHC-SD 1.6T',
unit: 'KG',
currentStock: 500,
fifoRank: 1,
},
{
id: '2',
materialCode: 'KD-RM-002',
materialName: 'EGI 1.55T',
unit: 'KG',
currentStock: 350,
fifoRank: 2,
},
{
id: '3',
materialCode: 'KD-SM-001',
materialName: '볼트 M6x20',
unit: 'EA',
currentStock: 1200,
fifoRank: 3,
},
];
interface MaterialInputModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
order: WorkOrder | null;
onComplete?: () => void;
isCompletionFlow?: boolean;
onSaveMaterials?: (orderId: string, materials: MaterialInput[]) => void;
savedMaterials?: MaterialInput[];
}
export function MaterialInputModal({
open,
onOpenChange,
order,
onComplete,
isCompletionFlow = false,
onSaveMaterials,
}: MaterialInputModalProps) {
const [selectedMaterials, setSelectedMaterials] = useState<Set<string>>(new Set());
const [materials] = useState<MaterialInput[]>(MOCK_MATERIALS);
const handleToggleMaterial = (materialId: string) => {
setSelectedMaterials((prev) => {
const next = new Set(prev);
if (next.has(materialId)) {
next.delete(materialId);
} else {
next.add(materialId);
}
return next;
});
};
// 투입 등록
const handleSubmit = () => {
if (!order) return;
const selectedMaterialList = materials.filter((m) => selectedMaterials.has(m.id));
console.log('[자재투입] 저장:', order.id, selectedMaterialList);
if (onSaveMaterials) {
onSaveMaterials(order.id, selectedMaterialList);
}
resetAndClose();
if (isCompletionFlow && onComplete) {
onComplete();
}
};
// 취소
const handleCancel = () => {
resetAndClose();
};
const resetAndClose = () => {
setSelectedMaterials(new Set());
onOpenChange(false);
};
if (!order) return null;
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl p-0 gap-0">
{/* 헤더 */}
<DialogHeader className="p-6 pb-4">
<DialogTitle className="text-xl font-semibold"> </DialogTitle>
</DialogHeader>
<div className="px-6 pb-6 space-y-6">
{/* FIFO 순위 설명 */}
<div className="flex items-center gap-4 p-4 bg-gray-50 rounded-lg">
<span className="text-sm font-medium text-gray-700">FIFO :</span>
<div className="flex items-center gap-4">
<span className="flex items-center gap-1.5">
<Badge className="bg-gray-900 hover:bg-gray-900 text-white rounded-full w-6 h-6 flex items-center justify-center p-0 text-xs">
1
</Badge>
<span className="text-sm text-gray-600"></span>
</span>
<span className="flex items-center gap-1.5">
<Badge className="bg-gray-900 hover:bg-gray-900 text-white rounded-full w-6 h-6 flex items-center justify-center p-0 text-xs">
2
</Badge>
<span className="text-sm text-gray-600"></span>
</span>
<span className="flex items-center gap-1.5">
<Badge className="bg-gray-900 hover:bg-gray-900 text-white rounded-full w-6 h-6 flex items-center justify-center p-0 text-xs">
3+
</Badge>
<span className="text-sm text-gray-600"></span>
</span>
</div>
</div>
{/* 자재 선택 섹션 */}
<div>
<h3 className="text-sm font-medium text-gray-900 mb-3">
(BOM )
</h3>
{materials.length === 0 ? (
<div className="border rounded-lg">
<Table>
<TableHeader>
<TableRow className="bg-gray-50">
<TableHead className="text-center"></TableHead>
<TableHead className="text-center"></TableHead>
<TableHead className="text-center"></TableHead>
<TableHead className="text-center"></TableHead>
<TableHead className="text-center"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell colSpan={5} className="text-center py-12 text-gray-500">
.
</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
) : (
<div className="border rounded-lg overflow-hidden">
<Table>
<TableHeader>
<TableRow className="bg-gray-50">
<TableHead className="text-center font-medium"></TableHead>
<TableHead className="text-center font-medium"></TableHead>
<TableHead className="text-center font-medium"></TableHead>
<TableHead className="text-center font-medium"></TableHead>
<TableHead className="text-center font-medium"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{materials.map((material) => (
<TableRow key={material.id}>
<TableCell className="text-center font-medium">
{material.materialCode}
</TableCell>
<TableCell className="text-center">{material.materialName}</TableCell>
<TableCell className="text-center">{material.unit}</TableCell>
<TableCell className="text-center">
{material.currentStock.toLocaleString()}
</TableCell>
<TableCell className="text-center">
<Checkbox
checked={selectedMaterials.has(material.id)}
onCheckedChange={() => handleToggleMaterial(material.id)}
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
)}
</div>
{/* 버튼 영역 */}
<div className="flex gap-3">
<Button
variant="outline"
onClick={handleCancel}
className="flex-1 py-6 text-base font-medium"
>
</Button>
<Button
onClick={handleSubmit}
disabled={selectedMaterials.size === 0}
className="flex-1 py-6 text-base font-medium bg-gray-400 hover:bg-gray-500 disabled:bg-gray-300"
>
</Button>
</div>
</div>
</DialogContent>
</Dialog>
);
}