feat(WEB): 공정관리/작업지시/작업자화면 기능 강화 및 템플릿 개선
- 공정관리: ProcessDetail/ProcessForm/ProcessList 개선, StepDetail/StepForm 신규 추가 - 작업지시: WorkOrderDetail/Edit/List UI 개선, 작업지시서 문서 추가 - 작업자화면: WorkerScreen 대폭 개선, MaterialInputModal/WorkLogModal 수정, WorkItemCard 신규 - 영업주문: 주문 상세 페이지 개선 - 입고관리: 상세/actions 수정 - 템플릿: IntegratedDetailTemplate/IntegratedListTemplateV2/UniversalListPage 기능 확장 - UI: confirm-dialog 개선 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,31 +4,85 @@
|
||||
* 작업일지 모달
|
||||
*
|
||||
* document-system 통합 버전 (2026-01-22)
|
||||
* 공정별 작업일지 지원 (2026-01-29)
|
||||
* - DocumentViewer 사용
|
||||
* - WorkLogContent로 문서 본문 분리
|
||||
* - 공정 타입에 따라 스크린/슬랫/절곡 작업일지 분기
|
||||
* - processType 미지정 시 기존 WorkLogContent (범용) 사용
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { DocumentViewer } from '@/components/document-system';
|
||||
import { getWorkOrderById } from '../WorkOrders/actions';
|
||||
import type { WorkOrder } from '../WorkOrders/types';
|
||||
import type { WorkOrder, ProcessType } from '../WorkOrders/types';
|
||||
import { WorkLogContent } from './WorkLogContent';
|
||||
import {
|
||||
ScreenWorkLogContent,
|
||||
SlatWorkLogContent,
|
||||
BendingWorkLogContent,
|
||||
} from '../WorkOrders/documents';
|
||||
|
||||
interface WorkLogModalProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
workOrderId: string | null;
|
||||
processType?: ProcessType;
|
||||
}
|
||||
|
||||
export function WorkLogModal({ open, onOpenChange, workOrderId }: WorkLogModalProps) {
|
||||
export function WorkLogModal({ open, onOpenChange, workOrderId, processType }: WorkLogModalProps) {
|
||||
const [order, setOrder] = useState<WorkOrder | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// 목업 WorkOrder 생성
|
||||
const createMockOrder = (id: string, pType?: ProcessType): WorkOrder => ({
|
||||
id,
|
||||
workOrderNo: 'KD-WO-260129-01',
|
||||
lotNo: 'KD-SA-260129-01',
|
||||
processId: 1,
|
||||
processName: pType === 'slat' ? '슬랫' : pType === 'bending' ? '절곡' : '스크린',
|
||||
processCode: pType || 'screen',
|
||||
processType: pType || 'screen',
|
||||
status: 'in_progress',
|
||||
client: '(주)경동',
|
||||
projectName: '서울 강남 현장',
|
||||
dueDate: '2026-02-05',
|
||||
assignee: '홍길동',
|
||||
assignees: [{ id: '1', name: '홍길동', isPrimary: true }],
|
||||
orderDate: '2026-01-20',
|
||||
scheduledDate: '2026-01-29',
|
||||
shipmentDate: '2026-02-05',
|
||||
salesOrderDate: '2026-01-15',
|
||||
isAssigned: true,
|
||||
isStarted: true,
|
||||
priority: 3,
|
||||
priorityLabel: '긴급',
|
||||
shutterCount: 12,
|
||||
department: '생산부',
|
||||
items: [
|
||||
{ id: '1', no: 1, status: 'in_progress', productName: '와이어 스크린', floorCode: '1층/FSS-01', specification: '8,260 X 8,350', quantity: 2, unit: 'EA' },
|
||||
{ id: '2', no: 2, status: 'waiting', productName: '메쉬 스크린', floorCode: '2층/FSS-03', specification: '6,400 X 5,200', quantity: 4, unit: 'EA' },
|
||||
{ id: '3', no: 3, status: 'completed', productName: '광폭 와이어', floorCode: '3층/FSS-05', specification: '12,000 X 4,500', quantity: 1, unit: 'EA' },
|
||||
],
|
||||
currentStep: { key: 'cutting', label: '절단', order: 2 },
|
||||
completedSteps: ['material_input'],
|
||||
totalProgress: 25,
|
||||
issues: [],
|
||||
memo: '',
|
||||
createdAt: '2026-01-20T09:00:00',
|
||||
updatedAt: '2026-01-29T14:00:00',
|
||||
});
|
||||
|
||||
// 모달 열릴 때 데이터 fetch
|
||||
useEffect(() => {
|
||||
if (open && workOrderId) {
|
||||
// 목업 ID인 경우 API 호출 생략
|
||||
if (workOrderId.startsWith('mock-')) {
|
||||
setOrder(createMockOrder(workOrderId, processType));
|
||||
setError(null);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
@@ -51,13 +105,32 @@ export function WorkLogModal({ open, onOpenChange, workOrderId }: WorkLogModalPr
|
||||
setOrder(null);
|
||||
setError(null);
|
||||
}
|
||||
}, [open, workOrderId]);
|
||||
}, [open, workOrderId, processType]);
|
||||
|
||||
if (!workOrderId) return null;
|
||||
|
||||
// 로딩/에러 상태는 DocumentViewer 내부에서 처리
|
||||
const subtitle = order ? `${order.processName} 생산부서` : undefined;
|
||||
|
||||
// 공정 타입에 따라 콘텐츠 분기
|
||||
const renderContent = () => {
|
||||
if (!order) return null;
|
||||
|
||||
// processType prop 또는 order의 processType 사용
|
||||
const type = processType || order.processType;
|
||||
|
||||
switch (type) {
|
||||
case 'screen':
|
||||
return <ScreenWorkLogContent data={order} />;
|
||||
case 'slat':
|
||||
return <SlatWorkLogContent data={order} />;
|
||||
case 'bending':
|
||||
return <BendingWorkLogContent data={order} />;
|
||||
default:
|
||||
return <WorkLogContent data={order} />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DocumentViewer
|
||||
title="작업일지"
|
||||
@@ -75,7 +148,7 @@ export function WorkLogModal({ open, onOpenChange, workOrderId }: WorkLogModalPr
|
||||
<p className="text-muted-foreground">{error || '데이터를 불러올 수 없습니다.'}</p>
|
||||
</div>
|
||||
) : (
|
||||
<WorkLogContent data={order} />
|
||||
renderContent()
|
||||
)}
|
||||
</DocumentViewer>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user