feat(WEB): 입력 컴포넌트 공통화 및 UI 개선
- 숫자/통화/전화번호/사업자번호 등 특수 입력 컴포넌트 추가 - MobileCard 컴포넌트 통합 (ListMobileCard 제거) - IntegratedListTemplateV2 페이지네이션 버그 수정 (NaN 이슈) - IntegratedDetailTemplate 타이틀 중복 수정 - 문서 시스템 컴포넌트 추가 - 헤더 벨 아이콘 포커스 스타일 개선 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,12 +79,116 @@ function transformToWorkerScreenFormat(api: WorkOrderApiItem): WorkOrder {
|
||||
};
|
||||
}
|
||||
|
||||
// ===== 목 데이터 (API 연동 전 UI 확인용) =====
|
||||
const USE_MOCK_DATA = false; // API 연동 시 false로 변경
|
||||
|
||||
const MOCK_WORK_ORDERS: WorkOrder[] = [
|
||||
{
|
||||
id: '1',
|
||||
orderNo: 'KD-WO-260121-01',
|
||||
productName: '스크린 셔터 (표준형)',
|
||||
processCode: 'P-001',
|
||||
processName: '스크린',
|
||||
client: '삼성물산(주)',
|
||||
projectName: '강남 타워 신축현장',
|
||||
assignees: ['홍길동'],
|
||||
quantity: 50,
|
||||
dueDate: '2026-01-25',
|
||||
priority: 1,
|
||||
status: 'inProgress',
|
||||
isUrgent: true,
|
||||
isDelayed: false,
|
||||
instruction: '1층 우선 생산',
|
||||
createdAt: '2026-01-20T09:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
orderNo: 'KD-WO-260121-02',
|
||||
productName: '슬랫 (알루미늄)',
|
||||
processCode: 'P-002',
|
||||
processName: '슬랫',
|
||||
client: '현대건설(주)',
|
||||
projectName: '판교 테크노밸리 2단지',
|
||||
assignees: ['홍길동', '김철수'],
|
||||
quantity: 120,
|
||||
dueDate: '2026-01-22',
|
||||
priority: 2,
|
||||
status: 'waiting',
|
||||
isUrgent: false,
|
||||
isDelayed: true,
|
||||
delayDays: 1,
|
||||
instruction: '색상 샘플 확인 후 작업',
|
||||
createdAt: '2026-01-19T14:30:00Z',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
orderNo: 'KD-WO-260121-03',
|
||||
productName: '절곡판 (스틸)',
|
||||
processCode: 'P-003',
|
||||
processName: '절곡',
|
||||
client: 'GS건설(주)',
|
||||
projectName: '마포 래미안 재건축',
|
||||
assignees: ['홍길동'],
|
||||
quantity: 30,
|
||||
dueDate: '2026-01-28',
|
||||
priority: 3,
|
||||
status: 'waiting',
|
||||
isUrgent: false,
|
||||
isDelayed: false,
|
||||
createdAt: '2026-01-21T08:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
orderNo: 'KD-WO-260120-01',
|
||||
productName: '스크린 셔터 (고급형)',
|
||||
processCode: 'P-001',
|
||||
processName: '스크린',
|
||||
client: '롯데건설(주)',
|
||||
projectName: '잠실 롯데캐슬',
|
||||
assignees: ['홍길동'],
|
||||
quantity: 80,
|
||||
dueDate: '2026-01-23',
|
||||
priority: 1,
|
||||
status: 'inProgress',
|
||||
isUrgent: true,
|
||||
isDelayed: false,
|
||||
instruction: '긴급 납품 요청',
|
||||
createdAt: '2026-01-20T10:00:00Z',
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
orderNo: 'KD-WO-260119-02',
|
||||
productName: '슬랫 (목재)',
|
||||
processCode: 'P-002',
|
||||
processName: '슬랫',
|
||||
client: '대우건설(주)',
|
||||
projectName: '송도 센트럴파크',
|
||||
assignees: ['홍길동', '박영희'],
|
||||
quantity: 200,
|
||||
dueDate: '2026-01-30',
|
||||
priority: 4,
|
||||
status: 'waiting',
|
||||
isUrgent: false,
|
||||
isDelayed: false,
|
||||
createdAt: '2026-01-19T11:00:00Z',
|
||||
},
|
||||
];
|
||||
|
||||
// ===== 내 작업 목록 조회 =====
|
||||
export async function getMyWorkOrders(): Promise<{
|
||||
success: boolean;
|
||||
data: WorkOrder[];
|
||||
error?: string;
|
||||
}> {
|
||||
// 목 데이터 사용 시
|
||||
if (USE_MOCK_DATA) {
|
||||
console.log('[WorkerScreenActions] Using MOCK data');
|
||||
return {
|
||||
success: true,
|
||||
data: MOCK_WORK_ORDERS,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
// 작업 대기 + 작업중 상태만 조회 (완료 제외)
|
||||
const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/work-orders?per_page=100&assigned_to_me=1`;
|
||||
@@ -148,6 +252,13 @@ export async function completeWorkOrder(
|
||||
id: string,
|
||||
materials?: { materialId: number; quantity: number; lotNo?: string }[]
|
||||
): Promise<{ success: boolean; lotNo?: string; error?: string }> {
|
||||
// 목 데이터 사용 시
|
||||
if (USE_MOCK_DATA) {
|
||||
console.log('[WorkerScreenActions] MOCK complete work order:', id, materials);
|
||||
const lotNo = `KD-SA-${new Date().toISOString().slice(2, 10).replace(/-/g, '')}-01`;
|
||||
return { success: true, lotNo };
|
||||
}
|
||||
|
||||
try {
|
||||
// 상태를 completed로 변경
|
||||
const { response, error } = await serverFetch(
|
||||
@@ -205,6 +316,15 @@ export interface MaterialForInput {
|
||||
fifoRank: number;
|
||||
}
|
||||
|
||||
// 목 자재 데이터
|
||||
const MOCK_MATERIALS: MaterialForInput[] = [
|
||||
{ id: 1, materialCode: 'MAT-001', materialName: '알루미늄 판재 (T1.2)', unit: 'EA', currentStock: 150, fifoRank: 1 },
|
||||
{ id: 2, materialCode: 'MAT-002', materialName: '스테인레스 볼트 M6', unit: 'EA', currentStock: 500, fifoRank: 1 },
|
||||
{ id: 3, materialCode: 'MAT-003', materialName: '방음재 (폴리우레탄)', unit: 'M', currentStock: 80, fifoRank: 2 },
|
||||
{ id: 4, materialCode: 'MAT-004', materialName: '실리콘 씰링재', unit: 'EA', currentStock: 45, fifoRank: 1 },
|
||||
{ id: 5, materialCode: 'MAT-005', materialName: '스프링 (φ8)', unit: 'EA', currentStock: 200, fifoRank: 3 },
|
||||
];
|
||||
|
||||
export async function getMaterialsForWorkOrder(
|
||||
workOrderId: string
|
||||
): Promise<{
|
||||
@@ -212,6 +332,15 @@ export async function getMaterialsForWorkOrder(
|
||||
data: MaterialForInput[];
|
||||
error?: string;
|
||||
}> {
|
||||
// 목 데이터 사용 시
|
||||
if (USE_MOCK_DATA) {
|
||||
console.log('[WorkerScreenActions] MOCK materials for work order:', workOrderId);
|
||||
return {
|
||||
success: true,
|
||||
data: MOCK_MATERIALS,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
// 작업지시 BOM 기준 자재 목록 조회
|
||||
const url = `${process.env.NEXT_PUBLIC_API_URL}/api/v1/work-orders/${workOrderId}/materials`;
|
||||
@@ -285,6 +414,12 @@ export async function registerMaterialInput(
|
||||
workOrderId: string,
|
||||
materialIds: number[]
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
// 목 데이터 사용 시
|
||||
if (USE_MOCK_DATA) {
|
||||
console.log('[WorkerScreenActions] MOCK register material input:', workOrderId, materialIds);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
try {
|
||||
const { response, error } = await serverFetch(
|
||||
`${process.env.NEXT_PUBLIC_API_URL}/api/v1/work-orders/${workOrderId}/material-inputs`,
|
||||
@@ -331,6 +466,12 @@ export async function reportIssue(
|
||||
priority?: 'low' | 'medium' | 'high';
|
||||
}
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
// 목 데이터 사용 시
|
||||
if (USE_MOCK_DATA) {
|
||||
console.log('[WorkerScreenActions] MOCK report issue:', workOrderId, data);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
try {
|
||||
const { response, error } = await serverFetch(
|
||||
`${process.env.NEXT_PUBLIC_API_URL}/api/v1/work-orders/${workOrderId}/issues`,
|
||||
|
||||
Reference in New Issue
Block a user