feat: 공정관리 페이지 및 컴포넌트 추가

- 공정관리 목록/상세/등록/수정 페이지 구현
- ProcessListClient, ProcessDetail, ProcessForm 컴포넌트 추가
- ProcessWorkLogPreviewModal, RuleModal 추가
- MobileCard 공통 컴포넌트 추가
- WorkLogModal.tsx 개선
- .gitignore 업데이트

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2025-12-26 15:48:08 +09:00
parent 41ef0bdd86
commit f0c0de2ecd
14 changed files with 1801 additions and 18 deletions

View File

@@ -0,0 +1,86 @@
/**
* 공정 수정 페이지
*/
'use client';
import { use } from 'react';
import { notFound } from 'next/navigation';
import { ProcessForm } from '@/components/process-management';
import type { Process } from '@/types/process';
// Mock 데이터
const mockProcesses: Process[] = [
{
id: '1',
processCode: 'P-004',
processName: '재고(포밍)',
description: '철판을 포밍하여 절곡 부품(반제품) 생산 후 재고 입고',
processType: '생산',
department: '포밍생산부서',
workLogTemplate: '재고생산 작업일지',
classificationRules: [],
requiredWorkers: 2,
workSteps: ['포밍', '검사', '포장'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-15',
},
{
id: '2',
processCode: 'P-003',
processName: '슬랫',
description: '슬랫 코일 절단 및 성형',
processType: '생산',
department: '슬랫생산부서',
classificationRules: [],
requiredWorkers: 3,
workSteps: ['절단', '성형', '검사'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-10',
},
{
id: '3',
processCode: 'P-002',
processName: '절곡',
description: '가이드레일, 케이스, 하단마감재 제작',
processType: '생산',
department: '절곡생산부서',
classificationRules: [],
requiredWorkers: 4,
workSteps: ['절단', '절곡', '용접', '검사'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-08',
},
{
id: '4',
processCode: 'P-001',
processName: '스크린',
description: '방화스크린 원단 가공 및 조립',
processType: '생산',
department: '스크린생산부서',
classificationRules: [],
requiredWorkers: 3,
workSteps: ['원단가공', '조립', '검사', '포장'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-05',
},
];
export default function EditProcessPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = use(params);
const process = mockProcesses.find((p) => p.id === id);
if (!process) {
notFound();
}
return <ProcessForm mode="edit" initialData={process} />;
}

View File

@@ -0,0 +1,114 @@
/**
* 공정 상세 페이지
*/
import { Suspense } from 'react';
import { notFound } from 'next/navigation';
import { ProcessDetail } from '@/components/process-management';
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
import type { Process } from '@/types/process';
// Mock 데이터
const mockProcesses: Process[] = [
{
id: '1',
processCode: 'P-004',
processName: '재고(포밍)',
description: '철판을 포밍하여 절곡 부품(반제품) 생산 후 재고 입고',
processType: '생산',
department: '포밍생산부서',
workLogTemplate: '재고생산 작업일지',
classificationRules: [],
requiredWorkers: 2,
workSteps: ['포밍', '검사', '포장'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-15',
},
{
id: '2',
processCode: 'P-003',
processName: '슬랫',
description: '슬랫 코일 절단 및 성형',
processType: '생산',
department: '슬랫생산부서',
classificationRules: [],
requiredWorkers: 3,
workSteps: ['절단', '성형', '검사'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-10',
},
{
id: '3',
processCode: 'P-002',
processName: '절곡',
description: '가이드레일, 케이스, 하단마감재 제작',
processType: '생산',
department: '절곡생산부서',
classificationRules: [],
requiredWorkers: 4,
workSteps: ['절단', '절곡', '용접', '검사'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-08',
},
{
id: '4',
processCode: 'P-001',
processName: '스크린',
description: '방화스크린 원단 가공 및 조립',
processType: '생산',
department: '스크린생산부서',
classificationRules: [],
requiredWorkers: 3,
workSteps: ['원단가공', '조립', '검사', '포장'],
status: '사용중',
createdAt: '2025-01-01',
updatedAt: '2025-01-05',
},
];
async function getProcessById(id: string): Promise<Process | null> {
const process = mockProcesses.find((p) => p.id === id);
return process || null;
}
export default async function ProcessDetailPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const process = await getProcessById(id);
if (!process) {
notFound();
}
return (
<Suspense fallback={<ContentLoadingSpinner text="공정 정보를 불러오는 중..." />}>
<ProcessDetail process={process} />
</Suspense>
);
}
export async function generateMetadata({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const process = await getProcessById(id);
if (!process) {
return {
title: '공정을 찾을 수 없습니다',
};
}
return {
title: `${process.processName} - 공정 상세`,
description: `${process.processCode} 공정 정보`,
};
}

View File

@@ -0,0 +1,11 @@
/**
* 공정 등록 페이지
*/
'use client';
import { ProcessForm } from '@/components/process-management';
export default function CreateProcessPage() {
return <ProcessForm mode="create" />;
}

View File

@@ -0,0 +1,21 @@
/**
* 공정 목록 페이지
*/
import { Suspense } from 'react';
import ProcessListClient from '@/components/process-management/ProcessListClient';
import { ContentLoadingSpinner } from '@/components/ui/loading-spinner';
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: '공정 목록',
description: '공정 관리 - 생산 공정 목록 조회 및 관리',
};
export default function ProcessManagementPage() {
return (
<Suspense fallback={<ContentLoadingSpinner text="공정 목록을 불러오는 중..." />}>
<ProcessListClient />
</Suspense>
);
}