refactor: [작업자화면] 목업 데이터 제거, API 데이터만 표시
- MOCK_ITEMS, MOCK_SIDEBAR_ORDERS 등 목업 데이터 정의 삭제 (~200줄) - 사이드바/작업목록에서 목업 병합 로직 제거 - 데이터 없을 때 빈 상태 메시지 표시
This commit is contained in:
@@ -82,173 +82,6 @@ const InspectionReportModal = dynamic(
|
||||
() => import('../WorkOrders/documents').then(mod => ({ default: mod.InspectionReportModal })),
|
||||
);
|
||||
|
||||
// ===== 목업 데이터 =====
|
||||
const MOCK_ITEMS: Record<ProcessTab, WorkItemData[]> = {
|
||||
screen: [
|
||||
{
|
||||
id: 'mock-s1', itemNo: 1, itemCode: 'KWWS03', itemName: '와이어', floor: '1층', code: 'FSS-01',
|
||||
width: 8260, height: 8350, quantity: 2, processType: 'screen',
|
||||
cuttingInfo: { width: 1210, sheets: 8 },
|
||||
steps: [
|
||||
{ id: 's1-1', name: '자재투입', isMaterialInput: true, isCompleted: true },
|
||||
{ id: 's1-2', name: '절단', isMaterialInput: false, isCompleted: true },
|
||||
{ id: 's1-3', name: '미싱', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 's1-4', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 's1-5', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
materialInputs: [
|
||||
{ id: 'm1', lotNo: 'LOT-2026-001', itemName: '스크린 원단 A', quantity: 500, unit: 'm' },
|
||||
{ id: 'm2', lotNo: 'LOT-2026-002', itemName: '와이어 B', quantity: 120, unit: 'EA' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mock-s2', itemNo: 2, itemCode: 'KWWS05', itemName: '메쉬', floor: '2층', code: 'FSS-03',
|
||||
width: 6400, height: 5200, quantity: 4, processType: 'screen',
|
||||
cuttingInfo: { width: 1600, sheets: 4 },
|
||||
steps: [
|
||||
{ id: 's2-1', name: '자재투입', isMaterialInput: true, isCompleted: false },
|
||||
{ id: 's2-2', name: '절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 's2-3', name: '미싱', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 's2-4', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 's2-5', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mock-s3', itemNo: 3, itemCode: 'KWWS08', itemName: '와이어(광폭)', floor: '3층', code: 'FSS-05',
|
||||
width: 12000, height: 4500, quantity: 1, processType: 'screen',
|
||||
cuttingInfo: { width: 2400, sheets: 5 },
|
||||
steps: [
|
||||
{ id: 's3-1', name: '자재투입', isMaterialInput: true, isCompleted: true },
|
||||
{ id: 's3-2', name: '절단', isMaterialInput: false, isCompleted: true },
|
||||
{ id: 's3-3', name: '미싱', isMaterialInput: false, isCompleted: true },
|
||||
{ id: 's3-4', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 's3-5', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
materialInputs: [
|
||||
{ id: 'm3', lotNo: 'LOT-2026-005', itemName: '광폭 원단', quantity: 300, unit: 'm' },
|
||||
],
|
||||
},
|
||||
],
|
||||
slat: [
|
||||
{
|
||||
id: 'mock-l1', itemNo: 1, itemCode: 'KQTS01', itemName: '슬랫코일', floor: '1층', code: 'FSS-01',
|
||||
width: 8260, height: 8350, quantity: 2, processType: 'slat',
|
||||
slatInfo: { length: 3910, slatCount: 40, jointBar: 4, glassQty: 2 },
|
||||
steps: [
|
||||
{ id: 'l1-1', name: '자재투입', isMaterialInput: true, isCompleted: true },
|
||||
{ id: 'l1-2', name: '포밍/절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'l1-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 'l1-4', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
materialInputs: [
|
||||
{ id: 'm4', lotNo: 'LOT-2026-010', itemName: '슬랫 코일 A', quantity: 200, unit: 'kg' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mock-l2', itemNo: 2, itemCode: 'KQTS03', itemName: '슬랫코일(광폭)', floor: '2층', code: 'FSS-02',
|
||||
width: 10500, height: 6200, quantity: 3, processType: 'slat',
|
||||
slatInfo: { length: 5200, slatCount: 55, jointBar: 6, glassQty: 3 },
|
||||
steps: [
|
||||
{ id: 'l2-1', name: '자재투입', isMaterialInput: true, isCompleted: false },
|
||||
{ id: 'l2-2', name: '포밍/절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'l2-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 'l2-4', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
},
|
||||
],
|
||||
bending: [
|
||||
{
|
||||
id: 'mock-b1', itemNo: 1, itemCode: 'KWWS03', itemName: '가이드레일', floor: '1층', code: 'FSS-01',
|
||||
width: 0, height: 0, quantity: 6, processType: 'bending',
|
||||
bendingInfo: {
|
||||
common: {
|
||||
kind: '혼합형 120X70', type: '혼합형',
|
||||
lengthQuantities: [{ length: 4000, quantity: 6 }, { length: 3000, quantity: 6 }],
|
||||
},
|
||||
detailParts: [
|
||||
{ partName: '엘바', material: 'EGI 1.6T', barcyInfo: '16 I 75' },
|
||||
{ partName: '하장바', material: 'EGI 1.6T', barcyInfo: '16|75|16|75|16(A각)' },
|
||||
],
|
||||
},
|
||||
steps: [
|
||||
{ id: 'b1-1', name: '자재투입', isMaterialInput: true, isCompleted: true },
|
||||
{ id: 'b1-2', name: '절단', isMaterialInput: false, isCompleted: true },
|
||||
{ id: 'b1-3', name: '절곡', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'b1-4', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// 절곡 재공품 전용 목업 데이터 (토글로 전환)
|
||||
const MOCK_ITEMS_BENDING_WIP: WorkItemData[] = [
|
||||
{
|
||||
id: 'mock-bw1', itemNo: 1, itemCode: 'KWWS03', itemName: '케이스 - 전면부', floor: '-', code: '-',
|
||||
width: 0, height: 0, quantity: 6, processType: 'bending',
|
||||
isWip: true,
|
||||
wipInfo: { specification: 'EGI 1.55T (W576)', lengthQuantity: '4,000mm X 6개' },
|
||||
steps: [
|
||||
{ id: 'bw1-1', name: '자재투입', isMaterialInput: true, isCompleted: false },
|
||||
{ id: 'bw1-2', name: '절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'bw1-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mock-bw2', itemNo: 2, itemCode: 'KWWS04', itemName: '케이스 - 후면부', floor: '-', code: '-',
|
||||
width: 0, height: 0, quantity: 4, processType: 'bending',
|
||||
isWip: true,
|
||||
wipInfo: { specification: 'EGI 1.55T (W576)', lengthQuantity: '3,500mm X 4개' },
|
||||
steps: [
|
||||
{ id: 'bw2-1', name: '자재투입', isMaterialInput: true, isCompleted: false },
|
||||
{ id: 'bw2-2', name: '절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'bw2-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mock-bw3', itemNo: 3, itemCode: 'KWWS05', itemName: '하단마감재', floor: '-', code: '-',
|
||||
width: 0, height: 0, quantity: 10, processType: 'bending',
|
||||
isWip: true,
|
||||
wipInfo: { specification: 'EGI 1.2T (W400)', lengthQuantity: '2,800mm X 10개' },
|
||||
steps: [
|
||||
{ id: 'bw3-1', name: '자재투입', isMaterialInput: true, isCompleted: false },
|
||||
{ id: 'bw3-2', name: '절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'bw3-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// 슬랫 조인트바 전용 목업 데이터 (토글로 전환)
|
||||
const MOCK_ITEMS_SLAT_JOINTBAR: WorkItemData[] = [
|
||||
{
|
||||
id: 'mock-jb1', itemNo: 1, itemCode: 'KQJB01', itemName: '조인트바 A', floor: '1층', code: 'FSS-01',
|
||||
width: 0, height: 0, quantity: 8, processType: 'slat',
|
||||
isJointBar: true,
|
||||
slatJointBarInfo: { specification: 'EGI 1.6T', length: 3910, quantity: 8 },
|
||||
steps: [
|
||||
{ id: 'jb1-1', name: '자재투입', isMaterialInput: true, isCompleted: true },
|
||||
{ id: 'jb1-2', name: '포밍/절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'jb1-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 'jb1-4', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
materialInputs: [
|
||||
{ id: 'mjb1', lotNo: 'LOT-2026-020', itemName: '조인트바 코일', quantity: 100, unit: 'kg' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'mock-jb2', itemNo: 2, itemCode: 'KQJB02', itemName: '조인트바 B', floor: '2층', code: 'FSS-02',
|
||||
width: 0, height: 0, quantity: 12, processType: 'slat',
|
||||
isJointBar: true,
|
||||
slatJointBarInfo: { specification: 'EGI 1.6T', length: 5200, quantity: 12 },
|
||||
steps: [
|
||||
{ id: 'jb2-1', name: '자재투입', isMaterialInput: true, isCompleted: false },
|
||||
{ id: 'jb2-2', name: '포밍/절단', isMaterialInput: false, isCompleted: false },
|
||||
{ id: 'jb2-3', name: '중간검사', isMaterialInput: false, isInspection: true, isCompleted: false },
|
||||
{ id: 'jb2-4', name: '포장완료', isMaterialInput: false, isCompleted: false },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// 사이드바 작업지시 목업 데이터
|
||||
interface SidebarOrder {
|
||||
id: string;
|
||||
siteName: string;
|
||||
@@ -259,28 +92,6 @@ interface SidebarOrder {
|
||||
subType?: 'slat' | 'jointbar' | 'bending' | 'wip';
|
||||
}
|
||||
|
||||
// 스크린: subType 없음 / 슬랫: slat|jointbar / 절곡: bending|wip
|
||||
const MOCK_SIDEBAR_ORDERS: Record<ProcessTab, SidebarOrder[]> = {
|
||||
screen: [
|
||||
{ id: 'order-s1', siteName: '현장명', date: '2024-09-24', quantity: 7, shutterCount: 5, priority: 'urgent' },
|
||||
{ id: 'order-s2', siteName: '현장명', date: '2024-09-24', quantity: 7, shutterCount: 5, priority: 'priority' },
|
||||
{ id: 'order-s3', siteName: '현장명', date: '2024-09-24', quantity: 7, shutterCount: 5, priority: 'normal' },
|
||||
{ id: 'order-s4', siteName: '현장명', date: '2024-09-24', quantity: 7, shutterCount: 5, priority: 'normal' },
|
||||
],
|
||||
slat: [
|
||||
{ id: 'order-l1', siteName: '현장명A', date: '2024-09-24', quantity: 7, shutterCount: 5, priority: 'urgent', subType: 'slat' },
|
||||
{ id: 'order-l2', siteName: '현장명B', date: '2024-09-24', quantity: 3, shutterCount: 2, priority: 'priority', subType: 'jointbar' },
|
||||
{ id: 'order-l3', siteName: '현장명C', date: '2024-09-24', quantity: 5, shutterCount: 4, priority: 'normal', subType: 'slat' },
|
||||
{ id: 'order-l4', siteName: '현장명D', date: '2024-09-24', quantity: 4, shutterCount: 3, priority: 'normal', subType: 'jointbar' },
|
||||
],
|
||||
bending: [
|
||||
{ id: 'order-b1', siteName: '현장명A', date: '2024-09-24', quantity: 7, shutterCount: 5, priority: 'urgent', subType: 'bending' },
|
||||
{ id: 'order-b2', siteName: '현장명B', date: '2024-09-24', quantity: 3, shutterCount: 2, priority: 'priority', subType: 'wip' },
|
||||
{ id: 'order-b3', siteName: '현장명C', date: '2024-09-24', quantity: 5, shutterCount: 4, priority: 'normal', subType: 'bending' },
|
||||
{ id: 'order-b4', siteName: '현장명D', date: '2024-09-24', quantity: 4, shutterCount: 3, priority: 'normal', subType: 'wip' },
|
||||
],
|
||||
};
|
||||
|
||||
const SUB_TYPE_TAGS: Record<string, { label: string; className: string }> = {
|
||||
slat: { label: '슬랫', className: 'bg-blue-100 text-blue-700' },
|
||||
jointbar: { label: '조인트바', className: 'bg-purple-100 text-purple-700' },
|
||||
@@ -563,7 +374,7 @@ export default function WorkerScreen() {
|
||||
useEffect(() => {
|
||||
if (isLoading) return;
|
||||
|
||||
const allOrders: SidebarOrder[] = [...apiSidebarOrders, ...MOCK_SIDEBAR_ORDERS[activeProcessTabKey]];
|
||||
const allOrders: SidebarOrder[] = [...apiSidebarOrders];
|
||||
|
||||
// 현재 선택이 유효하면 자동 전환하지 않음 (데이터 새로고침 시 선택 유지)
|
||||
if (selectedSidebarOrderId && allOrders.some((o) => o.id === selectedSidebarOrderId)) {
|
||||
@@ -784,27 +595,7 @@ export default function WorkerScreen() {
|
||||
});
|
||||
}
|
||||
|
||||
// 목업 데이터 합치기 (API 데이터 뒤에 번호 이어서)
|
||||
// 절곡 탭에서 재공품 서브모드면 WIP 전용 목업 사용
|
||||
// 슬랫 탭에서 조인트바 서브모드면 조인트바 전용 목업 사용
|
||||
const baseMockItems = (activeProcessTabKey === 'bending' && bendingSubMode === 'wip')
|
||||
? MOCK_ITEMS_BENDING_WIP
|
||||
: (activeProcessTabKey === 'slat' && slatSubMode === 'jointbar')
|
||||
? MOCK_ITEMS_SLAT_JOINTBAR
|
||||
: MOCK_ITEMS[activeProcessTabKey];
|
||||
const mockItems = baseMockItems.map((item, i) => ({
|
||||
...item,
|
||||
itemNo: apiItems.length + i + 1,
|
||||
steps: item.steps.map((step) => {
|
||||
const stepKey = `${item.id}-${step.name}`;
|
||||
return {
|
||||
...step,
|
||||
isCompleted: stepCompletionMap[stepKey] ?? step.isCompleted,
|
||||
};
|
||||
}),
|
||||
}));
|
||||
|
||||
return [...apiItems, ...mockItems];
|
||||
return apiItems;
|
||||
}, [filteredWorkOrders, selectedSidebarOrderId, activeProcessTabKey, stepCompletionMap, bendingSubMode, slatSubMode, activeProcessSteps, inputMaterialsMap, stepProgressMap]);
|
||||
|
||||
// ===== 검사 범위(scope) 기반 검사 단계 활성화/비활성화 =====
|
||||
@@ -956,21 +747,7 @@ export default function WorkerScreen() {
|
||||
};
|
||||
}
|
||||
|
||||
// 2. 목업 사이드바에서 찾기
|
||||
const mockOrder = MOCK_SIDEBAR_ORDERS[activeProcessTabKey].find((o) => o.id === selectedSidebarOrderId);
|
||||
if (mockOrder) {
|
||||
return {
|
||||
orderDate: mockOrder.date,
|
||||
salesOrderNo: 'SO-2024-0001',
|
||||
siteName: mockOrder.siteName,
|
||||
client: '-',
|
||||
salesManager: '-',
|
||||
managerPhone: '-',
|
||||
shippingDate: '-',
|
||||
};
|
||||
}
|
||||
|
||||
// 3. 폴백: 첫 번째 작업
|
||||
// 2. 폴백: 첫 번째 작업
|
||||
const first = filteredWorkOrders[0];
|
||||
if (!first) return null;
|
||||
return {
|
||||
@@ -1427,9 +1204,6 @@ export default function WorkerScreen() {
|
||||
toast.error('검사 데이터 저장 중 오류가 발생했습니다.');
|
||||
}
|
||||
} else if (inspectionStepName) {
|
||||
// 목업 데이터는 메모리만 저장 + 로컬 완료 처리
|
||||
setStepCompletionMap((prev) => ({ ...prev, [buildStepKey(inspectionStepName)]: true }));
|
||||
toast.success('중간검사가 완료되었습니다.');
|
||||
}
|
||||
}, [selectedOrder, workItems, getInspectionProcessType, inspectionStepName]);
|
||||
|
||||
@@ -1666,27 +1440,8 @@ export default function WorkerScreen() {
|
||||
</Card>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{(() => {
|
||||
const apiCount = workItems.filter((i) => !i.id.startsWith('mock-')).length;
|
||||
return apiCount > 0 ? (
|
||||
<span className="text-[10px] font-semibold text-blue-600 bg-blue-50 px-2 py-0.5 rounded inline-block">
|
||||
실제 데이터 ({apiCount}건)
|
||||
</span>
|
||||
) : null;
|
||||
})()}
|
||||
{scopedWorkItems.map((item, index) => {
|
||||
const isFirstMock = item.id.startsWith('mock-') &&
|
||||
(index === 0 || !scopedWorkItems[index - 1]?.id.startsWith('mock-'));
|
||||
return (
|
||||
<div key={item.id}>
|
||||
{isFirstMock && (
|
||||
<div className="mb-3 pt-1 space-y-2">
|
||||
{scopedWorkItems.some((i) => !i.id.startsWith('mock-')) && <div className="border-t border-dashed border-gray-300" />}
|
||||
<span className="text-[10px] font-semibold text-orange-600 bg-orange-50 px-2 py-0.5 rounded inline-block">
|
||||
목업 데이터
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{scopedWorkItems.map((item) => (
|
||||
<div key={item.id}>
|
||||
<WorkItemCard
|
||||
item={item}
|
||||
onStepClick={handleStepClick}
|
||||
@@ -1694,9 +1449,8 @@ export default function WorkerScreen() {
|
||||
onDeleteMaterial={handleDeleteMaterial}
|
||||
onInspectionClick={handleInspectionClick}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -1863,8 +1617,6 @@ function SidebarContent({
|
||||
onSelectOrder,
|
||||
apiOrders,
|
||||
}: SidebarContentProps) {
|
||||
const mockOrders = MOCK_SIDEBAR_ORDERS[tab];
|
||||
|
||||
const renderOrders = (orders: SidebarOrder[]) => (
|
||||
<>
|
||||
{PRIORITY_GROUPS.map((group) => {
|
||||
@@ -1914,29 +1666,10 @@ function SidebarContent({
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-sm font-semibold text-gray-900">수주 목록</h3>
|
||||
|
||||
{/* API 실제 데이터 */}
|
||||
{apiOrders.length > 0 && (
|
||||
<div className="space-y-2">
|
||||
<span className="text-[10px] font-semibold text-blue-600 bg-blue-50 px-2 py-0.5 rounded">
|
||||
실제 데이터 ({apiOrders.length}건)
|
||||
</span>
|
||||
{renderOrders(apiOrders)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 구분선 */}
|
||||
{apiOrders.length > 0 && mockOrders.length > 0 && (
|
||||
<div className="border-t border-dashed border-gray-300 my-1" />
|
||||
)}
|
||||
|
||||
{/* 목업 데이터 */}
|
||||
{mockOrders.length > 0 && (
|
||||
<div className="space-y-2">
|
||||
<span className="text-[10px] font-semibold text-orange-600 bg-orange-50 px-2 py-0.5 rounded">
|
||||
목업 데이터
|
||||
</span>
|
||||
{renderOrders(mockOrders)}
|
||||
</div>
|
||||
{apiOrders.length > 0 ? (
|
||||
renderOrders(apiOrders)
|
||||
) : (
|
||||
<p className="text-xs text-gray-400 text-center py-4">수주 데이터가 없습니다.</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user