const { useState, useEffect } = React; function Project() { // 상태 관리 const [projects, setProjects] = useState([]); const [filteredProjects, setFilteredProjects] = useState([]); const [isLoading, setIsLoading] = useState(false); const [currentUser, setCurrentUser] = useState('사용자'); const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage] = useState(10); // 모달 상태 const [showProjectModal, setShowProjectModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false); const [currentProjectIdx, setCurrentProjectIdx] = useState(null); // 필터 상태 const [filters, setFilters] = useState({ status: '진행', search: '', manager: 'my' }); // UI 상태 const [showFilters, setShowFilters] = useState(false); const [showColumnDropdown, setShowColumnDropdown] = useState(false); const [visibleColumns, setVisibleColumns] = useState({ serial: false, plant: false, line: false, package: false, staff: false, process: false, expire: false, delivery: false, design: false, electric: false, program: false, budgetDue: false, budget: false, jasmin: false }); // 프로젝트 폼 상태 const [projectForm, setProjectForm] = useState({ idx: 0, name: '', process: '', sdate: '', edate: '', ddate: '', odate: '', userManager: '', status: '진행', memo: '' }); // 통계 상태 const [statusCounts, setStatusCounts] = useState({ 진행: 0, 완료: 0, 대기: 0, 중단: 0 }); // 컴포넌트 마운트시 초기화 useEffect(() => { getCurrentUser(); loadProjects(); }, []); // 필터 변경시 프로젝트 목록 새로 로드 useEffect(() => { loadProjects(); }, [filters.status, filters.manager]); // 검색어 변경시 필터링 useEffect(() => { filterData(); }, [filters.search, projects]); // 현재 사용자 정보 가져오기 const getCurrentUser = async () => { try { const response = await fetch('/Common/GetCurrentUser'); const data = await response.json(); if (data.Success && data.Data) { const userName = data.Data.userName || data.Data.name || '사용자'; setCurrentUser(userName); } } catch (error) { console.error('Error getting current user:', error); } }; // 프로젝트 목록 로드 const loadProjects = async () => { setIsLoading(true); try { const response = await fetch(`/Project/GetProjects?status=${filters.status}&userFilter=${filters.manager}`); const data = await response.json(); if (data.Success) { const projectData = data.Data || []; setProjects(projectData); setFilteredProjects(projectData); updateStatusCounts(projectData); if (data.CurrentUser) { setCurrentUser(data.CurrentUser); } } else { console.error('Error:', data.Message); showNotification('데이터를 불러오는데 실패했습니다.', 'error'); } } catch (error) { console.error('Error:', error); showNotification('데이터를 불러오는데 실패했습니다.', 'error'); } finally { setIsLoading(false); } }; // 상태별 카운트 업데이트 const updateStatusCounts = (projectData) => { const counts = { 진행: 0, 완료: 0, 대기: 0, 중단: 0 }; projectData.forEach(project => { const status = project.상태 || '진행'; counts[status] = (counts[status] || 0) + 1; }); setStatusCounts(counts); }; // 데이터 필터링 const filterData = () => { if (!filters.search.trim()) { setFilteredProjects(projects); setCurrentPage(1); return; } const searchTerm = filters.search.toLowerCase(); const filtered = projects.filter(project => { return (project.프로젝트명 && project.프로젝트명.toLowerCase().includes(searchTerm)) || (project.프로젝트공정 && project.프로젝트공정.toLowerCase().includes(searchTerm)) || (project.자산번호 && project.자산번호.toLowerCase().includes(searchTerm)) || (project.장비모델 && project.장비모델.toLowerCase().includes(searchTerm)) || (project.시리얼번호 && project.시리얼번호.toLowerCase().includes(searchTerm)) || (project.프로젝트관리자 && project.프로젝트관리자.toLowerCase().includes(searchTerm)) || (project.설계담당 && project.설계담당.toLowerCase().includes(searchTerm)) || (project.전장담당 && project.전장담당.toLowerCase().includes(searchTerm)) || (project.프로그램담당 && project.프로그램담당.toLowerCase().includes(searchTerm)); }); setFilteredProjects(filtered); setCurrentPage(1); }; // 프로젝트 추가 모달 표시 const showAddProjectModal = () => { setCurrentProjectIdx(null); setProjectForm({ idx: 0, name: '', process: '', sdate: '', edate: '', ddate: '', odate: '', userManager: '', status: '진행', memo: '' }); setShowProjectModal(true); }; // 프로젝트 편집 const editProject = async (idx) => { setCurrentProjectIdx(idx); setIsLoading(true); try { const response = await fetch(`/Project/GetProject?id=${idx}`); const data = await response.json(); if (data.Success && data.Data) { const project = data.Data; setProjectForm({ idx: project.idx, name: project.프로젝트명 || '', process: project.프로젝트공정 || '', sdate: project.시작일 || '', edate: project.완료일 || '', ddate: project.만료일 || '', odate: project.출고일 || '', userManager: project.프로젝트관리자 || '', status: project.상태 || '진행', memo: project.memo || '' }); setShowProjectModal(true); } else { showNotification('프로젝트 정보를 불러오는데 실패했습니다: ' + data.Message, 'error'); } } catch (error) { console.error('Error:', error); showNotification('프로젝트 정보를 불러오는데 실패했습니다.', 'error'); } finally { setIsLoading(false); } }; // 프로젝트 저장 (추가/수정) const saveProject = async (e) => { e.preventDefault(); setIsLoading(true); const projectData = { ...projectForm, idx: currentProjectIdx ? parseInt(projectForm.idx) : 0, sdate: projectForm.sdate || null, edate: projectForm.edate || null, ddate: projectForm.ddate || null, odate: projectForm.odate || null }; const url = currentProjectIdx ? '/Project/UpdateProject' : '/Project/CreateProject'; const method = currentProjectIdx ? 'PUT' : 'POST'; try { const response = await fetch(url, { method: method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(projectData) }); const data = await response.json(); if (data.Success) { showNotification(data.Message || (currentProjectIdx ? '프로젝트가 수정되었습니다.' : '프로젝트가 추가되었습니다.'), 'success'); setShowProjectModal(false); loadProjects(); } else { showNotification('오류: ' + data.Message, 'error'); } } catch (error) { console.error('Error:', error); showNotification('저장 중 오류가 발생했습니다.', 'error'); } finally { setIsLoading(false); } }; // 프로젝트 삭제 const deleteProject = async () => { if (!currentProjectIdx) return; setIsLoading(true); try { const response = await fetch(`/Project/DeleteProject?id=${currentProjectIdx}`, { method: 'DELETE' }); const data = await response.json(); if (data.Success) { showNotification(data.Message || '프로젝트가 삭제되었습니다.', 'success'); setShowDeleteModal(false); setShowProjectModal(false); loadProjects(); } else { showNotification('오류: ' + data.Message, 'error'); } } catch (error) { console.error('Error:', error); showNotification('삭제 중 오류가 발생했습니다.', 'error'); } finally { setIsLoading(false); } }; // 필터 초기화 const clearFilters = () => { setFilters({ status: '진행', search: '', manager: 'my' }); }; // 엑셀 다운로드 const exportToExcel = () => { if (filteredProjects.length === 0) { showNotification('내보낼 데이터가 없습니다.', 'warning'); return; } const headers = ['상태', '자산번호', '장비모델', '시리얼번호', '우선순위', '요청국가', '요청공장', '요청라인', '요청부서패키지', '요청자', '프로젝트공정', '시작일', '완료일', '만료일', '출고일', '프로젝트명', '프로젝트관리자', '설계담당', '전장담당', '프로그램담당', '예산만기일', '예산', '웹관리번호']; const csvContent = [ headers.join(','), ...filteredProjects.map(project => [ project.상태 || '', project.자산번호 || '', project.장비모델 || '', project.시리얼번호 || '', project.우선순위 || '', project.요청국가 || '', project.요청공장 || '', project.요청라인 || '', project.요청부서패키지 || '', project.요청자 || '', project.프로젝트공정 || '', project.시작일 || '', project.완료일 || '', project.만료일 || '', project.출고일 || '', project.프로젝트명 || '', project.프로젝트관리자 || '', project.설계담당 || '', project.전장담당 || '', project.프로그램담당 || '', project.예산만기일 || '', project.예산 || '', project.웹관리번호 || '' ].join(',')) ].join('\n'); const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); const url = URL.createObjectURL(blob); link.setAttribute('href', url); link.setAttribute('download', `프로젝트목록_${new Date().toISOString().split('T')[0]}.csv`); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; // 유틸리티 함수들 const getStatusClass = (status) => { switch(status) { case '진행': return 'bg-blue-500/20 text-blue-300'; case '완료': return 'bg-green-500/20 text-green-300'; case '대기': return 'bg-yellow-500/20 text-yellow-300'; case '중단': return 'bg-red-500/20 text-red-300'; default: return 'bg-gray-500/20 text-gray-300'; } }; const formatDateToMonthDay = (dateString) => { if (!dateString) return ''; try { const date = new Date(dateString); if (isNaN(date.getTime())) return dateString; const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${month}-${day}`; } catch (error) { return dateString; } }; // 알림 표시 함수 const showNotification = (message, type = 'info') => { const colors = { info: 'bg-blue-500/90 backdrop-blur-sm', success: 'bg-green-500/90 backdrop-blur-sm', warning: 'bg-yellow-500/90 backdrop-blur-sm', error: 'bg-red-500/90 backdrop-blur-sm' }; const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 ${colors[type]} text-white px-4 py-3 rounded-lg z-50 transition-all duration-300 transform translate-x-0 opacity-100 shadow-lg border border-white/20`; notification.innerHTML = `
| 상태 | 프로젝트명 | 자산번호 | 장비모델 | 우선순위 | 요청국가 | 프로젝트관리자 | 시작일 | 완료일 | {visibleColumns.serial &&시리얼번호 | } {visibleColumns.plant &&요청공장 | } {visibleColumns.line &&요청라인 | } {visibleColumns.package &&요청부서패키지 | } {visibleColumns.staff &&요청자 | } {visibleColumns.process &&프로젝트공정 | } {visibleColumns.expire &&만료일 | } {visibleColumns.delivery &&출고일 | } {visibleColumns.design &&설계담당 | } {visibleColumns.electric &&전장담당 | } {visibleColumns.program &&프로그램담당 | } {visibleColumns.budgetDue &&예산만기일 | } {visibleColumns.budget &&예산 | } {visibleColumns.jasmin &&웹관리번호 | }
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
데이터를 불러오는 중...
|
||||||||||||||||||||||
| 데이터가 없습니다. | ||||||||||||||||||||||
| {project.상태 || '진행'} | {project.프로젝트명 || ''} | {project.자산번호 || ''} | {project.장비모델 || ''} | {project.우선순위 || ''} | {project.요청국가 || ''} | {project.프로젝트관리자 || ''} | {formatDateToMonthDay(project.시작일)} | {formatDateToMonthDay(project.완료일)} | {visibleColumns.serial &&{project.시리얼번호 || ''} | } {visibleColumns.plant &&{project.요청공장 || ''} | } {visibleColumns.line &&{project.요청라인 || ''} | } {visibleColumns.package &&{project.요청부서패키지 || ''} | } {visibleColumns.staff &&{project.요청자 || ''} | } {visibleColumns.process &&{project.프로젝트공정 || ''} | } {visibleColumns.expire &&{formatDateToMonthDay(project.만료일)} | } {visibleColumns.delivery &&{formatDateToMonthDay(project.출고일)} | } {visibleColumns.design &&{project.설계담당 || ''} | } {visibleColumns.electric &&{project.전장담당 || ''} | } {visibleColumns.program &&{project.프로그램담당 || ''} | } {visibleColumns.budgetDue &&{formatDateToMonthDay(project.예산만기일)} | } {visibleColumns.budget &&{project.예산 || ''} | } {visibleColumns.jasmin && ({project.웹관리번호 ? ( {project.웹관리번호} ) : ''} | )}
선택한 프로젝트를 삭제하시겠습니까?
이 작업은 되돌릴 수 없습니다.