- - -
- -
-
- -
- - - - - +
+
+

TK Project

+

프로젝트를 선택하여 관리를 시작하세요

+
+ +
+
+
+ +
-
-
- 12 - 전체 프로젝트 -
-
- 8 - 진행중 -
-
- 3 - 제작중 -
-
- 1 - 지연 + + +
- -
-
-
-
-

ABC 공장 배관공사

- TK-2024-015 -
-
- 제작중 - 75% -
-
- -
-
- 고객사 - ABC 케미칼 -
-
- 납기일 - 2024-03-30 -
-
- 납품방식 - 현장납품 -
-
- 담당 PM - 이PM -
-
- -
-
-
-
-
-
설계
-
구매
-
제작
-
검사
-
납품
-
-
- -
- - -
+ +
+
+ 12 + 전체 프로젝트
- -
-
-
-

DEF 플랜트 배관 설치

- TK-2024-016 -
-
- 계획 - 25% -
-
- -
-
- 고객사 - DEF 화학 -
-
- 납기일 - 2024-04-15 -
-
- 납품방식 - 공장인도 -
-
- 담당 PM - 박PM -
-
- -
-
-
-
-
-
설계
-
구매
-
제작
-
검사
-
납품
-
-
- -
- - -
+
+ 8 + 진행중
- -
-
-
-

GHI 정유 공장 개보수

- TK-2024-017 -
-
- 진행중 - 60% -
-
- -
-
- 고객사 - GHI 정유 / 한국엔지니어링 -
-
- 납기일 - 2024-05-20 -
-
- 납품방식 - 부분납품 -
-
- 담당 PM - 최PM -
-
- -
-
-
-
-
-
설계
-
구매
-
제작
-
검사
-
납품
-
-
- -
- - -
+
+ 3 + 제작중
- -
-
-
-

JKL 화학 공장 신설

- TK-2024-012 -
-
- 완료 - 100% -
-
- -
-
- 고객사 - JKL 화학 -
-
- 납기일 - 2024-02-28 -
-
- 납품방식 - 현장납품 -
-
- 담당 PM - 김PM -
-
- -
-
-
-
-
-
설계
-
구매
-
제작
-
검사
-
납품
-
-
- -
- - -
+
+ 1 + 지연
diff --git a/demo/scripts/main.js b/demo/scripts/main.js index a96899c..b31ec8d 100644 --- a/demo/scripts/main.js +++ b/demo/scripts/main.js @@ -359,146 +359,211 @@ function initializePage(pageId) { function initializeProjectManagement() { console.log('프로젝트 관리 페이지 초기화'); - // 프로젝트 카드 애니메이션 - animateElements('.project-card'); + // 드롭다운 외부 클릭 이벤트 설정 + setupDropdownOutsideClick(); - // 필터 버튼 이벤트 설정 - setupProjectFilters(); - - // 검색 기능 설정 - setupProjectSearch(); + // 애니메이션 효과 + animateElements('.project-selector-header'); + animateElements('.project-dropdown-container'); + animateElements('.project-stats-simple'); } -// 프로젝트 필터 설정 -function setupProjectFilters() { - const filterButtons = document.querySelectorAll('.filter-btn'); - - filterButtons.forEach(btn => { - btn.addEventListener('click', function() { - // 활성 버튼 변경 - filterButtons.forEach(b => b.classList.remove('active')); - this.classList.add('active'); - - // 필터 적용 - const filter = this.getAttribute('data-filter'); - filterProjects(filter); - }); +// 드롭다운 외부 클릭 설정 +function setupDropdownOutsideClick() { + document.addEventListener('click', function(e) { + const dropdown = document.querySelector('.project-dropdown'); + const dropdownMenu = document.getElementById('project-dropdown-menu'); + const dropdownDisplay = document.querySelector('.dropdown-display'); + + if (!dropdown.contains(e.target)) { + dropdownMenu.classList.remove('active'); + dropdownDisplay.classList.remove('active'); + } }); } -// 프로젝트 검색 설정 -function setupProjectSearch() { - const searchInput = document.querySelector('.search-input'); - const searchBtn = document.querySelector('.search-btn'); +// 프로젝트 드롭다운 토글 +function toggleProjectDropdown() { + const dropdownMenu = document.getElementById('project-dropdown-menu'); + const dropdownDisplay = document.querySelector('.dropdown-display'); - if (searchInput && searchBtn) { - searchBtn.addEventListener('click', performSearch); - searchInput.addEventListener('keypress', function(e) { - if (e.key === 'Enter') { - performSearch(); + dropdownMenu.classList.toggle('active'); + dropdownDisplay.classList.toggle('active'); + + // 검색 입력창에 포커스 + if (dropdownMenu.classList.contains('active')) { + setTimeout(() => { + const searchInput = document.querySelector('.dropdown-search-input'); + if (searchInput) { + searchInput.focus(); } - }); + }, 100); } } -// 검색 실행 -function performSearch() { - const searchInput = document.querySelector('.search-input'); - const query = searchInput.value.toLowerCase().trim(); +// 드롭다운에서 프로젝트 선택 +function selectProjectFromDropdown(jobNo) { + const projectData = getProjectData(jobNo); + if (!projectData) return; - if (!query) { - showAllProjects(); + // 드롭다운 닫기 + const dropdownMenu = document.getElementById('project-dropdown-menu'); + const dropdownDisplay = document.querySelector('.dropdown-display'); + dropdownMenu.classList.remove('active'); + dropdownDisplay.classList.remove('active'); + + // 선택된 프로젝트 텍스트 업데이트 + const selectedText = document.getElementById('selected-project-text'); + selectedText.textContent = `${projectData.name} (${jobNo})`; + + // 프로젝트 정보 카드 표시 + showProjectInfo(projectData); + + // 전역 변수 업데이트 + selectedProject = jobNo; + + // 세션 스토리지에 저장 + sessionStorage.setItem('selectedProject', JSON.stringify(projectData)); + + showNotification(`${projectData.name} 프로젝트가 선택되었습니다.`, 'success'); +} + +// 프로젝트 데이터 가져오기 +function getProjectData(jobNo) { + const projectsData = { + 'TK-2024-015': { + jobNo: 'TK-2024-015', + name: 'ABC 공장 배관공사', + customer: 'ABC 케미칼', + deadline: '2024-03-30', + delivery: '현장납품', + pm: '이PM', + status: '제작중', + statusClass: 'status-production', + progress: '75%' + }, + 'TK-2024-016': { + jobNo: 'TK-2024-016', + name: 'DEF 플랜트 배관 설치', + customer: 'DEF 화학', + deadline: '2024-04-15', + delivery: '공장인도', + pm: '박PM', + status: '계획', + statusClass: 'status-planning', + progress: '25%' + }, + 'TK-2024-017': { + jobNo: 'TK-2024-017', + name: 'GHI 정유 공장 개보수', + customer: 'GHI 정유 / 한국엔지니어링', + deadline: '2024-05-20', + delivery: '부분납품', + pm: '최PM', + status: '진행중', + statusClass: 'status-in-progress', + progress: '60%' + }, + 'TK-2024-012': { + jobNo: 'TK-2024-012', + name: 'JKL 화학 공장 신설', + customer: 'JKL 화학', + deadline: '2024-02-28', + delivery: '현장납품', + pm: '김PM', + status: '완료', + statusClass: 'status-completed', + progress: '100%' + } + }; + + return projectsData[jobNo]; +} + +// 프로젝트 정보 표시 +function showProjectInfo(projectData) { + const infoContainer = document.getElementById('selected-project-info'); + + // 정보 업데이트 + document.getElementById('info-project-title').textContent = projectData.name; + document.getElementById('info-job-no').textContent = projectData.jobNo; + document.getElementById('info-customer').textContent = projectData.customer; + document.getElementById('info-deadline').textContent = projectData.deadline; + document.getElementById('info-delivery').textContent = projectData.delivery; + document.getElementById('info-pm').textContent = projectData.pm; + document.getElementById('info-progress').textContent = projectData.progress; + + // 상태 배지 업데이트 + const statusBadge = document.getElementById('info-status'); + statusBadge.textContent = projectData.status; + statusBadge.className = `status-badge ${projectData.statusClass}`; + + // 버튼 상태 업데이트 + updateActionButtons(projectData); + + // 정보 카드 표시 + infoContainer.style.display = 'block'; +} + +// 액션 버튼 상태 업데이트 +function updateActionButtons(projectData) { + const buttons = { + meeting: document.getElementById('btn-production-meeting'), + inspection: document.getElementById('btn-incoming-inspection'), + work: document.getElementById('btn-production-work') + }; + + // 모든 버튼 활성화 + Object.values(buttons).forEach(btn => { + btn.classList.remove('disabled'); + btn.style.opacity = '1'; + btn.style.pointerEvents = 'auto'; + }); + + // 상태에 따른 버튼 비활성화 + switch (projectData.statusClass) { + case 'status-planning': + buttons.meeting.classList.add('disabled'); + buttons.meeting.style.opacity = '0.5'; + buttons.meeting.style.pointerEvents = 'none'; + break; + case 'status-completed': + buttons.meeting.textContent = '🏭 생산회의록 (완료)'; + buttons.inspection.textContent = '📦 입고 검수 (완료)'; + buttons.work.textContent = '🔧 생산팀 작업 (완료)'; + break; + } +} + +// 드롭다운 프로젝트 필터링 +function filterProjects(query) { + const options = document.querySelectorAll('.dropdown-option'); + const searchQuery = query.toLowerCase().trim(); + + options.forEach(option => { + const title = option.querySelector('.option-title').textContent.toLowerCase(); + const jobNo = option.querySelector('.option-job-no').textContent.toLowerCase(); + const customer = option.querySelector('.option-customer').textContent.toLowerCase(); + + if (!searchQuery || + title.includes(searchQuery) || + jobNo.includes(searchQuery) || + customer.includes(searchQuery)) { + option.style.display = 'block'; + } else { + option.style.display = 'none'; + } + }); +} + +// 프로젝트 세부 관리로 이동 +function goToProjectDetail() { + if (!selectedProject) { + showNotification('프로젝트를 먼저 선택해주세요.', 'warning'); return; } - const projectCards = document.querySelectorAll('.project-card'); - let visibleCount = 0; - - projectCards.forEach(card => { - const title = card.querySelector('h3').textContent.toLowerCase(); - const jobNo = card.querySelector('.job-no').textContent.toLowerCase(); - const customer = card.querySelector('.info-value').textContent.toLowerCase(); - - if (title.includes(query) || jobNo.includes(query) || customer.includes(query)) { - card.style.display = 'block'; - visibleCount++; - } else { - card.style.display = 'none'; - } - }); - - showNotification(`${visibleCount}개의 프로젝트를 찾았습니다.`, 'info'); -} - -// 프로젝트 필터링 -function filterProjects(filter) { - const projectCards = document.querySelectorAll('.project-card'); - let visibleCount = 0; - - projectCards.forEach(card => { - if (filter === 'all') { - card.style.display = 'block'; - visibleCount++; - } else { - const hasStatus = card.classList.contains(`status-${filter}`); - if (hasStatus) { - card.style.display = 'block'; - visibleCount++; - } else { - card.style.display = 'none'; - } - } - }); - - // 통계 업데이트 - updateProjectStats(filter, visibleCount); -} - -// 모든 프로젝트 표시 -function showAllProjects() { - const projectCards = document.querySelectorAll('.project-card'); - projectCards.forEach(card => { - card.style.display = 'block'; - }); -} - -// 프로젝트 통계 업데이트 -function updateProjectStats(filter, count) { - const filterName = { - 'all': '전체', - 'planning': '계획', - 'in-progress': '진행중', - 'production': '제작중', - 'completed': '완료' - }; - - showNotification(`${filterName[filter]} 프로젝트: ${count}개`, 'info'); -} - -// 프로젝트 선택 -function selectProject(jobNo) { - selectedProject = jobNo; - - // 프로젝트 정보 저장 - const projectCard = document.querySelector(`[data-job-no="${jobNo}"]`); - if (projectCard) { - const projectName = projectCard.querySelector('h3').textContent; - const customer = projectCard.querySelector('.info-value').textContent; - - // 세션 스토리지에 저장 - sessionStorage.setItem('selectedProject', JSON.stringify({ - jobNo: jobNo, - name: projectName, - customer: customer - })); - - showNotification(`${projectName} (${jobNo}) 프로젝트가 선택되었습니다.`, 'success'); - - // 프로젝트 세부 관리 페이지로 이동 (현재는 알림만) - setTimeout(() => { - showNotification('프로젝트 세부 관리 기능은 추후 구현 예정입니다.', 'info'); - }, 1000); - } + showNotification('프로젝트 세부 관리 페이지는 추후 구현 예정입니다.', 'info'); } // 프로젝트 등록 페이지 초기화 @@ -921,5 +986,9 @@ window.hideModal = hideModal; window.showNotification = showNotification; window.clearForm = clearForm; window.selectProject = selectProject; +window.toggleProjectDropdown = toggleProjectDropdown; +window.selectProjectFromDropdown = selectProjectFromDropdown; +window.filterProjects = filterProjects; +window.goToProjectDetail = goToProjectDetail; console.log('TK Project Demo JavaScript 로드 완료'); diff --git a/demo/styles/devonthink.css b/demo/styles/devonthink.css index a735702..ae67aff 100644 --- a/demo/styles/devonthink.css +++ b/demo/styles/devonthink.css @@ -590,197 +590,240 @@ body { } } -/* 프로젝트 관리 컨테이너 */ -.project-management-container { +/* 프로젝트 선택기 컨테이너 */ +.project-selector-container { display: flex; flex-direction: column; - gap: 24px; -} - -/* 프로젝트 필터 */ -.project-filters { - background-color: white; - border-radius: 8px; - box-shadow: var(--dt-shadow); - border: 1px solid var(--dt-gray-200); - padding: 24px; - display: flex; - justify-content: space-between; align-items: center; - flex-wrap: wrap; - gap: 20px; + justify-content: center; + min-height: 80vh; + padding: 40px 20px; + gap: 40px; } -.filter-section { - display: flex; - align-items: center; - gap: 20px; - flex-wrap: wrap; -} - -.search-box { - display: flex; - align-items: center; - gap: 8px; -} - -.search-input { - padding: 8px 12px; - border: 1px solid var(--dt-gray-300); - border-radius: 6px; - font-size: 14px; - width: 300px; - background-color: white; -} - -.search-btn { - padding: 8px 12px; - border: none; - background-color: var(--dt-primary); - color: white; - border-radius: 6px; - cursor: pointer; - font-size: 14px; -} - -.filter-buttons { - display: flex; - gap: 8px; -} - -.filter-btn { - padding: 6px 16px; - border: 1px solid var(--dt-gray-300); - background-color: white; - color: var(--dt-gray-700); - border-radius: 20px; - font-size: 12px; - font-weight: 600; - cursor: pointer; - transition: all 0.2s ease; -} - -.filter-btn:hover { - background-color: var(--dt-gray-50); -} - -.filter-btn.active { - background-color: var(--dt-primary); - color: white; - border-color: var(--dt-primary); -} - -.project-stats { - display: flex; - gap: 24px; -} - -.stat-item { +/* 프로젝트 선택기 헤더 */ +.project-selector-header { text-align: center; } -.stat-number { - display: block; - font-size: 24px; - font-weight: 700; - color: var(--dt-primary); - line-height: 1; +.project-selector-header h1 { + font-size: 48px; + font-weight: 300; + color: var(--dt-gray-800); + margin-bottom: 16px; + letter-spacing: -1px; } -.stat-label { - font-size: 12px; +.selector-description { + font-size: 18px; color: var(--dt-gray-600); - font-weight: 500; + font-weight: 400; } -/* 프로젝트 리스트 */ -.project-list { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); - gap: 24px; +/* 프로젝트 선택기 메인 */ +.project-selector-main { + display: flex; + flex-direction: column; + align-items: center; + gap: 32px; + width: 100%; + max-width: 600px; } -@media (max-width: 800px) { - .project-list { - grid-template-columns: 1fr; - } +/* 프로젝트 드롭다운 컨테이너 */ +.project-dropdown-container { + width: 100%; + position: relative; } -/* 프로젝트 카드 */ -.project-card { +/* 프로젝트 드롭다운 */ +.project-dropdown { + position: relative; + width: 100%; +} + +.dropdown-display { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; background-color: white; - border-radius: 12px; - box-shadow: var(--dt-shadow); - border: 1px solid var(--dt-gray-200); - padding: 24px; - transition: all 0.2s ease; + border: 2px solid var(--dt-gray-200); + border-radius: 50px; cursor: pointer; + transition: all 0.2s ease; + box-shadow: var(--dt-shadow); + font-size: 16px; } -.project-card:hover { - transform: translateY(-2px); +.dropdown-display:hover { + border-color: var(--dt-primary); box-shadow: var(--dt-shadow-lg); } -.project-card.status-production { - border-left: 4px solid var(--dt-primary); +.dropdown-display.active { + border-color: var(--dt-primary); + border-radius: 20px 20px 0 0; } -.project-card.status-planning { - border-left: 4px solid var(--dt-gray-400); +.dropdown-text { + color: var(--dt-gray-700); + font-weight: 500; } -.project-card.status-in-progress { - border-left: 4px solid var(--dt-warning); +.dropdown-arrow { + color: var(--dt-gray-500); + font-size: 12px; + transition: transform 0.2s ease; } -.project-card.status-completed { - border-left: 4px solid var(--dt-success); +.dropdown-display.active .dropdown-arrow { + transform: rotate(180deg); } -.project-header { +/* 드롭다운 메뉴 */ +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + right: 0; + background-color: white; + border: 2px solid var(--dt-primary); + border-top: none; + border-radius: 0 0 20px 20px; + box-shadow: var(--dt-shadow-lg); + z-index: 1000; + display: none; + max-height: 400px; + overflow: hidden; +} + +.dropdown-menu.active { + display: block; +} + +/* 드롭다운 검색 */ +.dropdown-search { + padding: 16px; + border-bottom: 1px solid var(--dt-gray-200); +} + +.dropdown-search-input { + width: 100%; + padding: 12px 16px; + border: 1px solid var(--dt-gray-300); + border-radius: 8px; + font-size: 14px; + background-color: var(--dt-gray-50); +} + +.dropdown-search-input:focus { + outline: none; + border-color: var(--dt-primary); + background-color: white; +} + +/* 드롭다운 옵션들 */ +.dropdown-options { + max-height: 300px; + overflow-y: auto; +} + +.dropdown-option { + padding: 16px 20px; + cursor: pointer; + transition: background-color 0.2s ease; + border-bottom: 1px solid var(--dt-gray-100); +} + +.dropdown-option:hover { + background-color: var(--dt-gray-50); +} + +.dropdown-option:last-child { + border-bottom: none; +} + +.option-main { display: flex; justify-content: space-between; - align-items: flex-start; - margin-bottom: 20px; + align-items: center; + margin-bottom: 8px; } -.project-title h3 { - font-size: 18px; +.option-title { + font-size: 16px; font-weight: 600; color: var(--dt-gray-800); - margin-bottom: 4px; } -.project-title .job-no { +.option-job-no { font-size: 12px; font-weight: 700; color: var(--dt-primary); font-family: 'Monaco', 'Menlo', monospace; } -.project-status { +.option-details { display: flex; + justify-content: space-between; align-items: center; - gap: 8px; } -.progress-text { +.option-customer { font-size: 14px; - font-weight: 600; color: var(--dt-gray-600); } -/* 프로젝트 정보 */ -.project-info { - margin-bottom: 20px; +.option-status { + font-size: 11px; + font-weight: 600; + padding: 4px 8px; + border-radius: 12px; +} + +/* 선택된 프로젝트 정보 */ +.selected-project-info { + width: 100%; + animation: fadeInUp 0.3s ease; +} + +.project-info-card { + background-color: white; + border-radius: 16px; + box-shadow: var(--dt-shadow-lg); + border: 1px solid var(--dt-gray-200); + padding: 32px; + text-align: center; +} + +.project-info-header { + margin-bottom: 24px; +} + +.project-info-header h3 { + font-size: 24px; + font-weight: 600; + color: var(--dt-gray-800); + margin-bottom: 8px; +} + +.info-job-no { + font-size: 14px; + font-weight: 700; + color: var(--dt-primary); + font-family: 'Monaco', 'Menlo', monospace; +} + +.project-info-details { + margin-bottom: 32px; } .info-row { display: flex; justify-content: space-between; align-items: center; - padding: 6px 0; + padding: 12px 0; border-bottom: 1px solid var(--dt-gray-100); } @@ -789,114 +832,104 @@ body { } .info-label { - font-size: 12px; + font-size: 14px; color: var(--dt-gray-600); font-weight: 500; } .info-value { - font-size: 13px; + font-size: 14px; color: var(--dt-gray-800); font-weight: 600; -} - -/* 프로젝트 진행률 */ -.project-progress { - margin-bottom: 20px; -} - -.progress-stages { display: flex; - justify-content: space-between; - margin-top: 12px; -} - -.stage { - font-size: 11px; - font-weight: 600; - color: var(--dt-gray-500); - text-align: center; - flex: 1; - position: relative; -} - -.stage.completed { - color: var(--dt-success); -} - -.stage.active { - color: var(--dt-primary); -} - -.stage::after { - content: ''; - position: absolute; - top: -8px; - left: 50%; - transform: translateX(-50%); - width: 8px; - height: 8px; - border-radius: 50%; - background-color: var(--dt-gray-300); -} - -.stage.completed::after { - background-color: var(--dt-success); -} - -.stage.active::after { - background-color: var(--dt-primary); + align-items: center; + gap: 8px; } /* 프로젝트 액션 */ .project-actions { - display: flex; - gap: 8px; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; } .project-actions .btn { - flex: 1; - font-size: 12px; - padding: 8px 12px; + font-size: 14px; + padding: 12px 16px; + border-radius: 8px; } -.btn.disabled { - opacity: 0.5; - cursor: not-allowed; - pointer-events: none; +/* 간단한 프로젝트 통계 */ +.project-stats-simple { + display: flex; + gap: 32px; + justify-content: center; +} + +.stat-item { + text-align: center; +} + +.stat-number { + display: block; + font-size: 28px; + font-weight: 700; + color: var(--dt-primary); + line-height: 1; + margin-bottom: 4px; +} + +.stat-label { + font-size: 12px; + color: var(--dt-gray-600); + font-weight: 500; +} + +/* 애니메이션 */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } } /* 반응형 디자인 */ @media (max-width: 768px) { - .project-filters { - flex-direction: column; - align-items: stretch; + .project-selector-header h1 { + font-size: 36px; } - .filter-section { - justify-content: center; + .selector-description { + font-size: 16px; } - .search-input { - width: 100%; - max-width: 300px; + .project-selector-main { + max-width: 100%; } - .project-stats { - justify-content: center; + .dropdown-display { + padding: 14px 18px; + font-size: 15px; } - .project-card { - padding: 20px; - } - - .project-header { - flex-direction: column; - gap: 12px; + .project-info-card { + padding: 24px; } .project-actions { - flex-direction: column; + grid-template-columns: 1fr; + } + + .project-stats-simple { + gap: 24px; + } + + .stat-number { + font-size: 24px; } }