// TK Project Demo - Main JavaScript // 전역 변수 let currentPage = 'project-registration'; let currentUser = { name: '김그룹장', role: '생산팀', avatar: '김' }; // 하드코딩된 데이터 const demoData = { projects: [ { jobNo: 'TK-2024-015', name: 'ABC 공장 배관공사', client: 'ABC 케미칼', contractAmount: '150,000,000', orderDate: '2024-01-15', deliveryDate: '2024-03-30', deliveryMethod: '현장납품', productionType: '자체제작', status: '승인완료' } ], processChart: { design: { progress: 100, status: '완료', dueDate: '2024-02-15', responsible: '박설계' }, procurement: { progress: 85, status: '진행중', dueDate: '2024-02-28', responsible: '김구매' }, production: { progress: 60, status: '진행중', dueDate: '2024-03-20', responsible: '이생산' }, inspection: { progress: 0, status: '대기', dueDate: '2024-03-25', responsible: '최품질' }, delivery: { progress: 0, status: '대기', dueDate: '2024-03-30', responsible: '박PM' } }, schedules: [ { date: '09/20', type: '외주출고', title: '도장 작업 출고', memo: 'A구역 파이프 20본, B구역 밸브 5개\n업체: 대한도장\n연락처: 010-1234-5678', responsible: '김구매', urgency: 'urgent' }, { date: '09/22', type: '검사일정', title: '압력시험', memo: '시험압력: 15bar, 30분간 유지\n검사자: 최품질, 이생산', responsible: '최품질', urgency: 'normal' } ], deliveries: [ { item: '파이프 4인치 x 50EA', date: '입고완료 - 09/10', status: 'completed' }, { item: '밸브 2인치 x 10EA', date: '입고예정 - 09/16', status: 'warning' }, { item: '엘보 4인치 x 20EA', date: '지연 - 09/12 → 09/18', status: 'delayed' } ], followUps: [ { priority: '긴급', title: '밸브 A 납기 지연 대응', description: '주 공급업체 생산 지연으로 대체 업체 검토 필요', responsible: '김구매', registeredDate: '09/10', expectedResolution: '09/17', status: '진행중', level: 'high' }, { priority: '높음', title: '용접 검사 일정 조정', description: '고객사 일정 변경으로 검사일 재조정 필요', responsible: '최품질', registeredDate: '09/12', expectedResolution: '09/20', status: '검토중', level: 'medium' } ], purchaseOrders: [ { poNumber: 'PO-2024-0156', project: 'TK-2024-015', item: '스테인리스 파이프 4인치 SCH40', qty: 50, unit: 'EA', supplier: '대한파이프', orderDate: '2024-09-01', expectedDate: '2024-09-15', buyer: '김구매', status: 'pending' }, { poNumber: 'PO-2024-0157', project: 'TK-2024-015', item: '게이트밸브 2인치 150LB', qty: 10, unit: 'EA', supplier: '코리아밸브', orderDate: '2024-09-05', expectedDate: '2024-09-16', buyer: '김구매', status: 'inspecting' } ], materials: [ { item: '파이프 4인치 SCH40', required: 50, status: 'available', location: 'A-3-상단', availableQty: 45, lastUpdate: '2024-09-14 09:00' }, { item: '엘보 4인치 150LB', required: 20, status: 'ordered', currentStage: '구매 진행 중', expectedDate: '2024-09-18', availableQty: 0 }, { item: '플랜지 4인치 150LB', required: 15, status: 'not-requested', currentStage: '설계팀 구매 요청 대기', availableQty: 0, note: '설계 변경으로 사양 확정 대기' }, { item: '밸브 2인치 150LB', required: 5, status: 'ready', location: 'B-2-중단', availableQty: 5, note: '인수 대기 중' } ], issues: [ { time: '14:30', type: '자재부족', description: '엘보 4인치 10EA 부족으로 작업 중단', urgency: '높음', solution: '구매팀에 긴급 요청, 대체재 검토', responsible: '김그룹장', photos: ['issue_001.jpg'] }, { time: '10:15', type: '품질이슈', description: '용접부 기공 발견, 재작업 필요', urgency: '보통', solution: '해당 부위 그라인딩 후 재용접', responsible: '이용접사', photos: ['quality_001.jpg'] } ] }; // DOM이 로드되면 초기화 document.addEventListener('DOMContentLoaded', function() { initializeApp(); setupEventListeners(); showPage(currentPage); }); // 앱 초기화 function initializeApp() { console.log('TK Project Demo 초기화 중...'); // 사용자 정보 업데이트 updateUserInfo(); // 데이터 로드 loadDemoData(); console.log('TK Project Demo 초기화 완료'); } // 이벤트 리스너 설정 function setupEventListeners() { // 네비게이션 클릭 이벤트 document.querySelectorAll('.nav-item').forEach(item => { item.addEventListener('click', function(e) { e.preventDefault(); const pageId = this.getAttribute('onclick').match(/'([^']+)'/)[1]; showPage(pageId); }); }); // 진행률 슬라이더 이벤트 const progressSlider = document.querySelector('.progress-slider'); if (progressSlider) { progressSlider.addEventListener('input', function() { const value = this.value; const display = document.querySelector('.progress-value'); if (display) { display.textContent = value + '%'; } }); } // 버튼 클릭 이벤트 setupButtonEvents(); // 폼 이벤트 setupFormEvents(); } // 버튼 이벤트 설정 function setupButtonEvents() { // 프로젝트 승인 버튼 const approveBtn = document.querySelector('.btn-primary'); if (approveBtn && approveBtn.textContent.includes('프로젝트 승인')) { approveBtn.addEventListener('click', function() { showNotification('프로젝트가 성공적으로 승인되었습니다!', 'success'); }); } // 검수 시작 버튼 document.querySelectorAll('.btn').forEach(btn => { if (btn.textContent.includes('검수 시작')) { btn.addEventListener('click', function() { showNotification('검수 프로세스를 시작합니다.', 'info'); // 버튼 상태 변경 this.textContent = '🔄 검수 진행중'; this.classList.remove('btn-primary'); this.classList.add('btn-warning'); }); } if (btn.textContent.includes('인수 처리')) { btn.addEventListener('click', function() { showNotification('자재 인수가 완료되었습니다.', 'success'); this.textContent = '✅ 인수완료'; this.classList.remove('btn-primary'); this.classList.add('btn-success'); this.disabled = true; }); } if (btn.textContent.includes('데일리 체크에 기록')) { btn.addEventListener('click', function() { showNotification('데일리 체크에 이슈가 등록되었습니다.', 'warning'); }); } }); // 선반 클릭 이벤트 document.querySelectorAll('.shelf.available').forEach(shelf => { shelf.addEventListener('click', function() { // 기존 선택 해제 document.querySelectorAll('.shelf').forEach(s => s.classList.remove('selected')); // 현재 선택 this.classList.add('selected'); // 선택된 위치 업데이트 const locationDisplay = document.querySelector('.selected-location .location'); if (locationDisplay) { locationDisplay.textContent = this.textContent + '-중단'; } showNotification(`${this.textContent} 선반이 선택되었습니다.`, 'info'); }); }); } // 폼 이벤트 설정 function setupFormEvents() { // BOM 조회 버튼 const bomSearchBtn = document.querySelector('.search-input .btn-primary'); if (bomSearchBtn && bomSearchBtn.textContent.includes('BOM 조회')) { bomSearchBtn.addEventListener('click', function() { const input = document.querySelector('.search-input .form-input'); const jobNo = input.value || 'TK-2024-015'; showNotification(`${jobNo} 프로젝트의 BOM 정보를 조회했습니다.`, 'success'); // 자재 리스트 업데이트 (이미 하드코딩되어 있음) animateElements('.material-item'); }); } } // 페이지 표시 function showPage(pageId) { // 모든 페이지 숨기기 document.querySelectorAll('.page').forEach(page => { page.classList.remove('active'); }); // 모든 네비게이션 아이템 비활성화 document.querySelectorAll('.nav-item').forEach(item => { item.classList.remove('active'); }); // 선택된 페이지 표시 const targetPage = document.getElementById(pageId); if (targetPage) { targetPage.classList.add('active'); targetPage.classList.add('fade-in'); // 네비게이션 아이템 활성화 const navItem = document.querySelector(`[onclick*="${pageId}"]`); if (navItem) { navItem.classList.add('active'); } currentPage = pageId; // 페이지별 초기화 initializePage(pageId); } } // 페이지별 초기화 function initializePage(pageId) { switch (pageId) { case 'project-registration': initializeProjectRegistration(); break; case 'production-meeting': initializeProductionMeeting(); break; case 'incoming-inspection': initializeIncomingInspection(); break; case 'production-work': initializeProductionWork(); break; } } // 프로젝트 등록 페이지 초기화 function initializeProjectRegistration() { console.log('프로젝트 등록 페이지 초기화'); // 폼 이벤트 리스너 설정 setupProjectForm(); // Job No. 미리보기 업데이트 updateJobNoPreview(); // 요청 리스트 애니메이션 animateElements('.request-item'); } // 프로젝트 폼 설정 function setupProjectForm() { const form = document.querySelector('.project-form'); if (!form) return; // 폼 제출 이벤트 form.addEventListener('submit', function(e) { e.preventDefault(); handleProjectSubmission(); }); // 입력 필드 변경시 Job No. 미리보기 업데이트 const inputs = form.querySelectorAll('input, select'); inputs.forEach(input => { input.addEventListener('input', updateJobNoPreview); }); } // 프로젝트 제출 처리 function handleProjectSubmission() { const form = document.querySelector('.project-form'); const formData = new FormData(form); // 입력값 검증 const projectName = document.getElementById('project-name').value; const endUser = document.getElementById('end-user').value; const deliveryDate = document.getElementById('delivery-date').value; const deliveryMethod = document.getElementById('delivery-method').value; if (!projectName || !endUser || !deliveryDate || !deliveryMethod) { showNotification('필수 항목을 모두 입력해주세요.', 'warning'); return; } // 제출 버튼 상태 변경 const submitBtn = document.getElementById('submit-btn'); const originalText = submitBtn.textContent; submitBtn.textContent = '📤 요청 중...'; submitBtn.disabled = true; // 가상 제출 처리 (2초 후 완료) setTimeout(() => { // 새로운 Job No. 생성 const newJobNo = generateJobNo(); // 성공 메시지 showNotification(`프로젝트 등록 요청이 완료되었습니다! (예상 Job No: ${newJobNo})`, 'success'); // 요청 리스트에 새 항목 추가 addNewRequestToList(projectName, endUser, deliveryDate, deliveryMethod); // 폼 초기화 clearForm(); // 버튼 복원 submitBtn.textContent = originalText; submitBtn.disabled = false; }, 2000); } // Job No. 생성 function generateJobNo() { const year = new Date().getFullYear(); const randomNum = Math.floor(Math.random() * 900) + 100; // 100-999 return `TK-${year}-${randomNum}`; } // Job No. 미리보기 업데이트 function updateJobNoPreview() { const projectName = document.getElementById('project-name')?.value; const previewElement = document.getElementById('preview-job-no'); if (!previewElement) return; if (projectName && projectName.length > 0) { const year = new Date().getFullYear(); const nextNum = String(Math.floor(Math.random() * 900) + 100); previewElement.textContent = `TK-${year}-${nextNum}`; previewElement.style.color = 'var(--dt-primary)'; } else { previewElement.textContent = 'TK-2024-XXX'; previewElement.style.color = 'var(--dt-gray-500)'; } } // 새 요청을 리스트에 추가 function addNewRequestToList(projectName, endUser, deliveryDate, deliveryMethod) { const requestList = document.querySelector('.request-list'); if (!requestList) return; const epcCustomer = document.getElementById('epc-customer')?.value; const customerText = epcCustomer ? `${endUser} / ${epcCustomer}` : endUser; const newItem = document.createElement('div'); newItem.className = 'request-item status-pending'; newItem.innerHTML = `