import React, { useState } from 'react'; import { Typography, Box, Card, CardContent, Button, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Alert, CircularProgress, Snackbar, IconButton, Chip, Grid, List, ListItem, ListItemText, ListItemSecondaryAction, Divider, Menu, MenuItem } from '@mui/material'; import { Add, Assignment, Edit, Delete, MoreVert, Visibility, CheckCircle, Warning } from '@mui/icons-material'; import { createJob, updateProject, deleteProject } from '../api'; import Toast from './Toast'; function ProjectManager({ projects, selectedProject, setSelectedProject, onProjectsChange }) { const [dialogOpen, setDialogOpen] = useState(false); const [editDialogOpen, setEditDialogOpen] = useState(false); const [detailDialogOpen, setDetailDialogOpen] = useState(false); const [editingProject, setEditingProject] = useState(null); const [projectCode, setProjectCode] = useState(''); const [projectName, setProjectName] = useState(''); const [loading, setLoading] = useState(false); const [toast, setToast] = useState({ open: false, message: '', type: 'info' }); const [menuAnchor, setMenuAnchor] = useState(null); const [selectedProjectForMenu, setSelectedProjectForMenu] = useState(null); const handleCreateProject = async () => { if (!projectCode.trim() || !projectName.trim()) { setToast({ open: true, message: '프로젝트 코드와 이름을 모두 입력해주세요.', type: 'warning' }); return; } setLoading(true); try { const data = { official_project_code: projectCode.trim(), project_name: projectName.trim(), design_project_code: projectCode.trim(), is_code_matched: true, status: 'active' }; const response = await createJob(data); const result = response.data; if (result && result.job) { onProjectsChange(); setSelectedProject(result.job); setDialogOpen(false); setProjectCode(''); setProjectName(''); setToast({ open: true, message: '프로젝트가 성공적으로 생성되었습니다.', type: 'success' }); } else { setToast({ open: true, message: result.message || '프로젝트 생성에 실패했습니다.', type: 'error' }); } } catch (error) { console.error('프로젝트 생성 실패:', error); setToast({ open: true, message: '네트워크 오류가 발생했습니다. 백엔드 서버가 실행 중인지 확인해주세요.', type: 'error' }); } finally { setLoading(false); } }; const handleEditProject = async () => { if (!editingProject || !editingProject.project_name.trim()) { setToast({ open: true, message: '프로젝트명을 입력해주세요.', type: 'warning' }); return; } setLoading(true); try { const response = await updateProject(editingProject.id, { project_name: editingProject.project_name.trim(), status: editingProject.status }); if (response.data && response.data.success) { onProjectsChange(); setEditDialogOpen(false); setEditingProject(null); setToast({ open: true, message: '프로젝트가 성공적으로 수정되었습니다.', type: 'success' }); } else { setToast({ open: true, message: response.data?.message || '프로젝트 수정에 실패했습니다.', type: 'error' }); } } catch (error) { console.error('프로젝트 수정 실패:', error); setToast({ open: true, message: '프로젝트 수정 중 오류가 발생했습니다.', type: 'error' }); } finally { setLoading(false); } }; const handleDeleteProject = async (project) => { if (!window.confirm(`정말로 프로젝트 "${project.project_name}"을 삭제하시겠습니까?`)) { return; } setLoading(true); try { const response = await deleteProject(project.id); if (response.data && response.data.success) { onProjectsChange(); if (selectedProject?.id === project.id) { setSelectedProject(null); } setToast({ open: true, message: '프로젝트가 성공적으로 삭제되었습니다.', type: 'success' }); } else { setToast({ open: true, message: response.data?.message || '프로젝트 삭제에 실패했습니다.', type: 'error' }); } } catch (error) { console.error('프로젝트 삭제 실패:', error); setToast({ open: true, message: '프로젝트 삭제 중 오류가 발생했습니다.', type: 'error' }); } finally { setLoading(false); } }; const handleOpenMenu = (event, project) => { setMenuAnchor(event.currentTarget); setSelectedProjectForMenu(project); }; const handleCloseMenu = () => { setMenuAnchor(null); setSelectedProjectForMenu(null); }; const handleEditClick = () => { setEditingProject({ ...selectedProjectForMenu }); setEditDialogOpen(true); handleCloseMenu(); }; const handleDetailClick = () => { setDetailDialogOpen(true); handleCloseMenu(); }; const handleCloseDialog = () => { setDialogOpen(false); setProjectCode(''); setProjectName(''); }; const handleCloseEditDialog = () => { setEditDialogOpen(false); setEditingProject(null); }; const getStatusColor = (status) => { switch (status) { case 'active': return 'success'; case 'inactive': return 'warning'; case 'completed': return 'info'; default: return 'default'; } }; const getStatusIcon = (status) => { switch (status) { case 'active': return ; case 'inactive': return ; default: return ; } }; return ( 🗂️ 프로젝트 관리 {/* 전역 Toast */} setToast({ open: false, message: '', type: 'info' })} /> {projects.length === 0 ? ( 프로젝트가 없습니다 새 프로젝트를 생성하여 시작하세요! ) : ( {projects.map((project) => ( setSelectedProject(project)} > {project.project_name || project.official_project_code} 코드: {project.official_project_code} 생성일: {new Date(project.created_at).toLocaleDateString()} { e.stopPropagation(); handleOpenMenu(e, project); }} > ))} )} {/* 프로젝트 메뉴 */} 상세 보기 수정 { handleDeleteProject(selectedProjectForMenu); handleCloseMenu(); }} sx={{ color: 'error.main' }} > 삭제 {/* 새 프로젝트 생성 다이얼로그 */} 새 프로젝트 생성 setProjectCode(e.target.value)} sx={{ mb: 2 }} /> setProjectName(e.target.value)} /> {/* 프로젝트 수정 다이얼로그 */} 프로젝트 수정 setEditingProject({ ...editingProject, project_name: e.target.value })} sx={{ mb: 2 }} /> setEditingProject({ ...editingProject, status: e.target.value })} > 활성 비활성 완료 {/* 프로젝트 상세 보기 다이얼로그 */} setDetailDialogOpen(false)} maxWidth="md" fullWidth> 프로젝트 상세 정보 {selectedProjectForMenu && ( 프로젝트 코드 {selectedProjectForMenu.official_project_code} 프로젝트명 {selectedProjectForMenu.project_name} 상태 생성일 {new Date(selectedProjectForMenu.created_at).toLocaleString()} 설계 프로젝트 코드 {selectedProjectForMenu.design_project_code || '-'} 코드 매칭 )} ); } export default ProjectManager;