feat: 프로젝트별 작업 분포 Production Report 스타일 완성

 주요 기능
- 프로젝트별 → 작업유형별 데이터 취합 및 표시
- Production Report 스타일 테이블 구현
- 연차/휴무 별도 처리 (주말 제외, 녹색 테마)
- Job No. 정확한 표시 (중복 제거)

🔧 API 개선
- recent-work API에 job_no 필드 추가
- MySQL 쿼리 결과 처리 수정 (results[0] 사용)
- Projects 테이블 대소문자 조인 문제 해결

🎨 UI/UX 개선
- 탭 기반 분석 인터페이스
- 색상 팔레트 개선 (파란색/녹색/노란색 계열)
- 텍스트 방향 수정 (가로 표시)
- 프로젝트별 합계 행 추가

📊 계산 로직
- 공수: 시간 ÷ 8
- 부하율: (개별 시간 ÷ 전체 시간) × 100%
- 인건비: 공수 × 350,000원
- 주말 연차 자동 제외
This commit is contained in:
Hyungi Ahn
2025-11-04 17:52:24 +09:00
parent de427c457b
commit 26f9a4dea2
4 changed files with 828 additions and 76 deletions

View File

@@ -609,6 +609,152 @@ body {
color: var(--gray-600);
}
/* ========== Production Report 테이블 ========== */
.production-report-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
background: var(--white);
border: 2px solid #000;
}
.production-report-table th {
background: #4472C4;
color: var(--white);
font-weight: 600;
padding: 1rem 0.75rem;
text-align: center;
border: 1px solid #000;
vertical-align: middle;
line-height: 1.3;
}
.production-report-table td {
padding: 0.75rem;
border: 1px solid #000;
text-align: center;
vertical-align: middle;
}
/* 프로젝트명 (Job No.) 스타일 */
.production-report-table .project-name {
background: #5D9CEC;
color: var(--white);
font-weight: 600;
text-align: center;
writing-mode: horizontal-tb;
text-orientation: mixed;
width: 150px;
min-width: 150px;
padding: 0.5rem;
line-height: 1.3;
}
/* 작업 내용 스타일 */
.production-report-table .work-content {
background: var(--white);
color: var(--gray-800);
font-weight: 500;
text-align: center;
}
/* 공수 스타일 */
.production-report-table .man-days {
background: var(--white);
color: var(--gray-800);
font-weight: 600;
text-align: center;
}
/* 부하율 스타일 */
.production-report-table .load-rate {
background: var(--white);
color: var(--gray-800);
font-weight: 600;
text-align: center;
}
/* 인건비 스타일 */
.production-report-table .labor-cost {
background: var(--white);
color: var(--gray-800);
font-weight: 600;
text-align: center;
}
/* 합계 행 스타일 */
.production-report-table .total-row {
background: #FFF3CD !important;
font-weight: 700;
border-top: 2px solid #F39C12;
}
.production-report-table .total-row td {
background: #FFF3CD !important;
color: #856404;
font-weight: 700;
}
/* 프로젝트 그룹 스타일 */
.production-report-table .project-group {
border-top: 2px solid #000;
}
.production-report-table .project-group:first-child {
border-top: none;
}
/* 연차/휴무 스타일 */
.production-report-table .vacation-project {
background: #E8F5E8 !important;
border-top: 3px solid #4CAF50 !important;
}
.production-report-table .vacation-project .project-name {
background: #4CAF50 !important;
color: var(--white) !important;
font-weight: 700;
text-align: center;
font-size: 1rem;
writing-mode: horizontal-tb !important;
text-orientation: mixed !important;
}
.production-report-table .vacation-project .work-content {
background: #E8F5E8 !important;
color: #2E7D32 !important;
font-weight: 600;
text-align: center;
}
.production-report-table .vacation-project td {
background: #E8F5E8 !important;
color: #2E7D32 !important;
font-weight: 500;
}
.production-report-table .vacation-project .man-days,
.production-report-table .vacation-project .load-rate,
.production-report-table .vacation-project .labor-cost {
background: #E8F5E8 !important;
color: #2E7D32 !important;
font-weight: 600;
}
/* 프로젝트별 합계 행 스타일 */
.production-report-table .project-subtotal {
background: #E8F4FD !important;
font-weight: 600;
border-bottom: 2px solid #5D9CEC;
}
.production-report-table .project-subtotal td {
background: #E8F4FD !important;
color: #2E5BBA;
font-weight: 600;
border-bottom: 2px solid #5D9CEC;
}
.work-report-table .input-hours {
font-weight: 600;
color: var(--success);
@@ -720,6 +866,66 @@ body {
transform: none;
}
/* ========== 탭 네비게이션 ========== */
.tab-navigation {
background: var(--white);
border-radius: var(--radius-xl);
padding: var(--space-6);
box-shadow: var(--shadow-lg);
border: 1px solid var(--gray-200);
margin-bottom: var(--space-8);
}
.tab-buttons {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--space-4);
}
.tab-button {
background: var(--gray-50);
border: 2px solid var(--gray-200);
border-radius: var(--radius-lg);
padding: var(--space-4) var(--space-6);
font-size: 0.9rem;
font-weight: 600;
color: var(--gray-700);
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
text-align: center;
}
.tab-button:hover {
background: var(--gray-100);
border-color: var(--primary);
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
.tab-button.active {
background: var(--gradient-primary);
border-color: var(--primary);
color: var(--white);
box-shadow: var(--shadow-lg);
}
.tab-button .icon {
font-size: 1.2rem;
}
/* ========== 탭 컨텐츠 ========== */
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.chart-title {
font-size: 1.5rem;
font-weight: 700;
@@ -986,6 +1192,16 @@ body {
font-size: 0.85rem;
}
.tab-buttons {
grid-template-columns: 1fr;
gap: var(--space-3);
}
.tab-button {
padding: var(--space-3) var(--space-4);
font-size: 0.85rem;
}
.result-card {
padding: var(--space-4);
}