feat: SWG 가스켓 전체 구성 정보 표시 개선
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
- H/F/I/O SS304/GRAPHITE/CS/CS 패턴에서 4개 구성요소 모두 표시 - 기존 SS304 + GRAPHITE → SS304/GRAPHITE/CS/CS로 완전한 구성 표시 - 외부링/필러/내부링/추가구성 모든 정보 포함 - 구매수량 계산 모달에서 정확한 재질 정보 확인 가능
This commit is contained in:
388
frontend/src/pages/ProjectsPage.jsx
Normal file
388
frontend/src/pages/ProjectsPage.jsx
Normal file
@@ -0,0 +1,388 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
const ProjectsPage = ({ user }) => {
|
||||
const [projects, setProjects] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [showCreateForm, setShowCreateForm] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// 실제로는 API에서 프로젝트 데이터를 가져올 예정
|
||||
// 현재는 더미 데이터 사용
|
||||
setTimeout(() => {
|
||||
setProjects([
|
||||
{
|
||||
id: 1,
|
||||
name: '냉동기 시스템 개발',
|
||||
type: '냉동기',
|
||||
status: '진행중',
|
||||
startDate: '2024-01-15',
|
||||
endDate: '2024-06-30',
|
||||
deliveryMethod: 'FOB',
|
||||
progress: 65,
|
||||
manager: '김철수'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'BOG 처리 시스템',
|
||||
type: 'BOG',
|
||||
status: '계획',
|
||||
startDate: '2024-02-01',
|
||||
endDate: '2024-08-15',
|
||||
deliveryMethod: 'CIF',
|
||||
progress: 15,
|
||||
manager: '이영희'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '다이아프람 펌프 제작',
|
||||
type: '다이아프람',
|
||||
status: '완료',
|
||||
startDate: '2023-10-01',
|
||||
endDate: '2024-01-31',
|
||||
deliveryMethod: 'FOB',
|
||||
progress: 100,
|
||||
manager: '박민수'
|
||||
}
|
||||
]);
|
||||
setLoading(false);
|
||||
}, 1000);
|
||||
}, []);
|
||||
|
||||
const getStatusColor = (status) => {
|
||||
const colors = {
|
||||
'계획': '#ed8936',
|
||||
'진행중': '#48bb78',
|
||||
'완료': '#38b2ac',
|
||||
'보류': '#e53e3e'
|
||||
};
|
||||
return colors[status] || '#718096';
|
||||
};
|
||||
|
||||
const getProgressColor = (progress) => {
|
||||
if (progress >= 80) return '#48bb78';
|
||||
if (progress >= 50) return '#ed8936';
|
||||
return '#e53e3e';
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
minHeight: '400px',
|
||||
fontSize: '16px',
|
||||
color: '#718096'
|
||||
}}>
|
||||
프로젝트 목록을 불러오는 중...
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
padding: '32px',
|
||||
background: '#f7fafc',
|
||||
minHeight: '100vh'
|
||||
}}>
|
||||
<div style={{ maxWidth: '1200px', margin: '0 auto' }}>
|
||||
{/* 헤더 */}
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginBottom: '32px'
|
||||
}}>
|
||||
<div>
|
||||
<h1 style={{
|
||||
fontSize: '28px',
|
||||
fontWeight: '700',
|
||||
color: '#2d3748',
|
||||
margin: '0 0 8px 0'
|
||||
}}>
|
||||
📋 프로젝트 관리
|
||||
</h1>
|
||||
<p style={{
|
||||
color: '#718096',
|
||||
fontSize: '16px',
|
||||
margin: '0'
|
||||
}}>
|
||||
전체 프로젝트를 관리하고 진행 상황을 확인하세요.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => setShowCreateForm(true)}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
cursor: 'pointer',
|
||||
fontSize: '14px',
|
||||
fontWeight: '600',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
transition: 'transform 0.2s ease'
|
||||
}}
|
||||
onMouseEnter={(e) => e.target.style.transform = 'translateY(-1px)'}
|
||||
onMouseLeave={(e) => e.target.style.transform = 'translateY(0)'}
|
||||
>
|
||||
<span>➕</span>
|
||||
새 프로젝트
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 프로젝트 통계 */}
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
||||
gap: '16px',
|
||||
marginBottom: '32px'
|
||||
}}>
|
||||
{[
|
||||
{ label: '전체', count: projects.length, color: '#667eea' },
|
||||
{ label: '진행중', count: projects.filter(p => p.status === '진행중').length, color: '#48bb78' },
|
||||
{ label: '완료', count: projects.filter(p => p.status === '완료').length, color: '#38b2ac' },
|
||||
{ label: '계획', count: projects.filter(p => p.status === '계획').length, color: '#ed8936' }
|
||||
].map((stat, index) => (
|
||||
<div key={index} style={{
|
||||
background: 'white',
|
||||
padding: '20px',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid #e2e8f0',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
<div style={{
|
||||
fontSize: '24px',
|
||||
fontWeight: '700',
|
||||
color: stat.color,
|
||||
marginBottom: '4px'
|
||||
}}>
|
||||
{stat.count}
|
||||
</div>
|
||||
<div style={{
|
||||
fontSize: '14px',
|
||||
color: '#718096'
|
||||
}}>
|
||||
{stat.label}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 프로젝트 목록 */}
|
||||
<div style={{
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid #e2e8f0',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<div style={{
|
||||
padding: '20px 24px',
|
||||
borderBottom: '1px solid #e2e8f0',
|
||||
background: '#f7fafc'
|
||||
}}>
|
||||
<h3 style={{
|
||||
margin: '0',
|
||||
fontSize: '16px',
|
||||
fontWeight: '600',
|
||||
color: '#2d3748'
|
||||
}}>
|
||||
프로젝트 목록 ({projects.length}개)
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div style={{ overflowX: 'auto' }}>
|
||||
<table style={{
|
||||
width: '100%',
|
||||
borderCollapse: 'collapse'
|
||||
}}>
|
||||
<thead>
|
||||
<tr style={{ background: '#f7fafc' }}>
|
||||
{['프로젝트명', '유형', '상태', '수주일', '납기일', '납품방법', '진행률', '담당자'].map(header => (
|
||||
<th key={header} style={{
|
||||
padding: '12px 16px',
|
||||
textAlign: 'left',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
color: '#4a5568',
|
||||
borderBottom: '1px solid #e2e8f0'
|
||||
}}>
|
||||
{header}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{projects.map(project => (
|
||||
<tr key={project.id} style={{
|
||||
borderBottom: '1px solid #e2e8f0',
|
||||
transition: 'background 0.2s ease'
|
||||
}}
|
||||
onMouseEnter={(e) => e.currentTarget.style.background = '#f7fafc'}
|
||||
onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
|
||||
<td style={{ padding: '16px', fontWeight: '600', color: '#2d3748' }}>
|
||||
{project.name}
|
||||
</td>
|
||||
<td style={{ padding: '16px' }}>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
background: '#edf2f7',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '500',
|
||||
color: '#4a5568'
|
||||
}}>
|
||||
{project.type}
|
||||
</span>
|
||||
</td>
|
||||
<td style={{ padding: '16px' }}>
|
||||
<span style={{
|
||||
padding: '4px 8px',
|
||||
background: getStatusColor(project.status) + '20',
|
||||
color: getStatusColor(project.status),
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600'
|
||||
}}>
|
||||
{project.status}
|
||||
</span>
|
||||
</td>
|
||||
<td style={{ padding: '16px', color: '#4a5568' }}>
|
||||
{project.startDate}
|
||||
</td>
|
||||
<td style={{ padding: '16px', color: '#4a5568' }}>
|
||||
{project.endDate}
|
||||
</td>
|
||||
<td style={{ padding: '16px', color: '#4a5568' }}>
|
||||
{project.deliveryMethod}
|
||||
</td>
|
||||
<td style={{ padding: '16px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<div style={{
|
||||
flex: 1,
|
||||
height: '6px',
|
||||
background: '#e2e8f0',
|
||||
borderRadius: '3px',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<div style={{
|
||||
width: `${project.progress}%`,
|
||||
height: '100%',
|
||||
background: getProgressColor(project.progress),
|
||||
transition: 'width 0.3s ease'
|
||||
}} />
|
||||
</div>
|
||||
<span style={{
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
color: getProgressColor(project.progress),
|
||||
minWidth: '35px'
|
||||
}}>
|
||||
{project.progress}%
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td style={{ padding: '16px', color: '#4a5568' }}>
|
||||
{project.manager}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 프로젝트가 없을 때 */}
|
||||
{projects.length === 0 && (
|
||||
<div style={{
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid #e2e8f0',
|
||||
padding: '60px 40px',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
<div style={{ fontSize: '48px', marginBottom: '16px' }}>📋</div>
|
||||
<h3 style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: '600',
|
||||
color: '#2d3748',
|
||||
margin: '0 0 8px 0'
|
||||
}}>
|
||||
등록된 프로젝트가 없습니다
|
||||
</h3>
|
||||
<p style={{
|
||||
color: '#718096',
|
||||
margin: '0 0 24px 0'
|
||||
}}>
|
||||
첫 번째 프로젝트를 등록해보세요.
|
||||
</p>
|
||||
<button
|
||||
onClick={() => setShowCreateForm(true)}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
cursor: 'pointer',
|
||||
fontSize: '14px',
|
||||
fontWeight: '600'
|
||||
}}
|
||||
>
|
||||
새 프로젝트 등록
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 프로젝트 생성 폼 모달 (향후 구현) */}
|
||||
{showCreateForm && (
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
background: 'rgba(0, 0, 0, 0.5)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
zIndex: 1000
|
||||
}}>
|
||||
<div style={{
|
||||
background: 'white',
|
||||
borderRadius: '12px',
|
||||
padding: '32px',
|
||||
maxWidth: '500px',
|
||||
width: '90%',
|
||||
maxHeight: '90vh',
|
||||
overflow: 'auto'
|
||||
}}>
|
||||
<h3 style={{ margin: '0 0 16px 0' }}>새 프로젝트 등록</h3>
|
||||
<p style={{ color: '#718096', margin: '0 0 24px 0' }}>
|
||||
이 기능은 곧 구현될 예정입니다.
|
||||
</p>
|
||||
<button
|
||||
onClick={() => setShowCreateForm(false)}
|
||||
style={{
|
||||
padding: '8px 16px',
|
||||
background: '#e2e8f0',
|
||||
border: 'none',
|
||||
borderRadius: '6px',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProjectsPage;
|
||||
Reference in New Issue
Block a user