From dc0ce471aa471b31578d6f3acd63969c8446f516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A0=EB=B3=91=EC=B2=A0?= Date: Thu, 5 Feb 2026 23:04:53 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat(WEB):=20=ED=92=88=EC=A7=88=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=EA=B8=B0=EB=8A=A5=20=EB=8C=80=ED=8F=AD=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=20=EB=B0=8F=20=EA=B2=80=EC=82=AC=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 품질검사관리: - InspectionCreate 생성 폼 대폭 개선 (+269줄) - InspectionDetail 상세 페이지 확장 (+424줄) - InspectionReportModal 검사성적서 모달 기능 강화 - InspectionReportDocument 문서 구조 개선 - ProductInspectionInputModal 제품검사 입력 모달 신규 추가 - types, mockData, actions 확장 자재입고: - ReceivingDetail 수입검사 연동 기능 추가 - ImportInspectionInputModal 수입검사 입력 모달 신규 추가 Co-Authored-By: Claude Opus 4.5 --- .../ImportInspectionInputModal.tsx | 366 +++++++++++++ .../ReceivingManagement/ReceivingDetail.tsx | 43 +- .../InspectionManagement/InspectionCreate.tsx | 269 +++++++--- .../InspectionManagement/InspectionDetail.tsx | 424 ++++++++++----- .../ProductInspectionInputModal.tsx | 485 ++++++++++++++++++ .../quality/InspectionManagement/actions.ts | 4 + .../documents/InspectionReportDocument.tsx | 81 +-- .../documents/InspectionReportModal.tsx | 150 +++++- .../quality/InspectionManagement/mockData.ts | 172 ++++++- .../quality/InspectionManagement/types.ts | 50 +- 10 files changed, 1748 insertions(+), 296 deletions(-) create mode 100644 src/components/material/ReceivingManagement/ImportInspectionInputModal.tsx create mode 100644 src/components/quality/InspectionManagement/ProductInspectionInputModal.tsx diff --git a/src/components/material/ReceivingManagement/ImportInspectionInputModal.tsx b/src/components/material/ReceivingManagement/ImportInspectionInputModal.tsx new file mode 100644 index 00000000..1bce8f10 --- /dev/null +++ b/src/components/material/ReceivingManagement/ImportInspectionInputModal.tsx @@ -0,0 +1,366 @@ +'use client'; + +/** + * 수입검사 입력 모달 + * + * 작업자 화면 중간검사 모달 양식 참고 + * 기획서: 스크린샷 2026-02-05 오후 9.58.16 + */ + +import { useState, useEffect } from 'react'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { cn } from '@/lib/utils'; + +// 시료 탭 타입 +type SampleTab = 'N1' | 'N2' | 'N3'; + +// 검사 결과 데이터 타입 +export interface ImportInspectionData { + sampleTab: SampleTab; + productName: string; + specification: string; + // 겉모양 + appearanceStatus: 'ok' | 'ng' | null; + // 치수 + thickness: number | null; + width: number | null; + length: number | null; + // 판정 + judgment: 'pass' | 'fail' | null; + // 물성치 + tensileStrength: number | null; // 인장강도 (270 이상) + elongation: number | null; // 연신율 (36 이상) + zincCoating: number | null; // 아연의 최소 부착량 (17 이상) + // 내용 + content: string; +} + +interface ImportInspectionInputModalProps { + open: boolean; + onOpenChange: (open: boolean) => void; + productName?: string; + specification?: string; + onComplete: (data: ImportInspectionData) => void; +} + +// OK/NG 버튼 컴포넌트 +function OkNgToggle({ + value, + onChange, +}: { + value: 'ok' | 'ng' | null; + onChange: (v: 'ok' | 'ng') => void; +}) { + return ( +
+ + +
+ ); +} + +// 적합/부적합 버튼 컴포넌트 +function JudgmentToggle({ + value, + onChange, +}: { + value: 'pass' | 'fail' | null; + onChange: (v: 'pass' | 'fail') => void; +}) { + return ( +
+ + +
+ ); +} + +export function ImportInspectionInputModal({ + open, + onOpenChange, + productName = '', + specification = '', + onComplete, +}: ImportInspectionInputModalProps) { + const [formData, setFormData] = useState({ + sampleTab: 'N1', + productName, + specification, + appearanceStatus: 'ok', + thickness: 1.55, + width: 1219, + length: 480, + judgment: 'pass', + tensileStrength: null, + elongation: null, + zincCoating: null, + content: '', + }); + + useEffect(() => { + if (open) { + // 모달 열릴 때 초기화 - 기본값 적합 상태 + setFormData({ + sampleTab: 'N1', + productName, + specification, + appearanceStatus: 'ok', + thickness: 1.55, + width: 1219, + length: 480, + judgment: 'pass', + tensileStrength: null, + elongation: null, + zincCoating: null, + content: '', + }); + } + }, [open, productName, specification]); + + const handleComplete = () => { + onComplete(formData); + onOpenChange(false); + }; + + const handleCancel = () => { + onOpenChange(false); + }; + + // 숫자 입력 핸들러 + const handleNumberChange = ( + key: keyof ImportInspectionData, + value: string + ) => { + const num = value === '' ? null : parseFloat(value); + setFormData((prev) => ({ ...prev, [key]: num })); + }; + + const sampleTabs: SampleTab[] = ['N1', 'N2', 'N3']; + + return ( + + + + + 수입검사 + + + +
+ {/* 제품명 */} +
+ + +
+ + {/* 규격 */} +
+ + +
+ + {/* 시료 탭: N1, N2, N3 */} +
+ {sampleTabs.map((tab) => ( + + ))} +
+ + {/* 겉모양: OK/NG */} +
+ + setFormData((prev) => ({ ...prev, appearanceStatus: v }))} + /> +
+ + {/* 두께 / 너비 */} +
+
+ + handleNumberChange('thickness', e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+
+ + handleNumberChange('width', e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+
+ + {/* 길이 */} +
+ + handleNumberChange('length', e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+ + {/* 판정: 적합/부적합 */} +
+ + setFormData((prev) => ({ ...prev, judgment: v }))} + /> +
+ + {/* 인장강도 / 연신율 */} +
+
+ + handleNumberChange('tensileStrength', e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+
+ + handleNumberChange('elongation', e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+
+ + {/* 아연의 최소 부착량 */} +
+ + handleNumberChange('zincCoating', e.target.value)} + className="bg-gray-800 border-gray-700 text-white" + /> +
+ + {/* 내용 */} +
+ +