feat: 관리함 완료됨 탭 UI 개선 - 카드 형식으로 변경

 새로운 기능:
- 완료됨 탭을 테이블에서 카드 형식으로 완전 변경
- 완료 시 입력한 모든 정보를 포괄적으로 표시
- 3단 구조로 정보 체계화 (기본정보 | 관리정보 | 완료정보)

🎨 UI/UX 개선:
- 진행 중 탭과 일관된 카드 디자인 적용
- 녹색 테마로 완료 상태 시각화
- 반응형 3단 그리드 레이아웃
- HEIC 완료 사진 다운로드 지원

📋 포함된 완료 정보:
- 완료 사진 (HEIC 지원)
- 완료 코멘트
- 완료 신청일
- 해결방안, 담당부서/담당자
- 원인부서, 관리 코멘트
- 원본 업로드 사진

🔧 기술적 개선:
- getDepartmentText() 함수 추가 (부서 코드 한글 변환)
- 레거시 테이블 헤더 함수 정리
- 카드 기반 통합 렌더링 시스템
This commit is contained in:
Hyungi Ahn
2025-10-26 14:23:28 +09:00
parent e7b51f80a0
commit fd0579805c

View File

@@ -665,25 +665,9 @@
</div>
<div class="collapse-content" id="${groupId}">
${currentTab === 'in_progress' ?
// 진행 중: 카드 형식
`<div class="space-y-4 mt-4">
${issues.map(issue => createIssueRow(issue)).join('')}
</div>` :
// 완료됨: 테이블 형식
`<div class="issue-table-container">
<table class="issue-table">
<thead>
<tr>
${createTableHeader()}
</tr>
</thead>
<tbody>
${issues.map(issue => createIssueRow(issue)).join('')}
</tbody>
</table>
</div>`
}
<div class="space-y-4 mt-4">
${issues.map(issue => createIssueRow(issue)).join('')}
</div>
</div>
</div>
`;
@@ -945,27 +929,124 @@
// 완료됨 행 생성 (입력 여부 표시)
function createCompletedRow(issue, project) {
// 완료 날짜 포맷팅
const completedDate = issue.completed_at ? new Date(issue.completed_at).toLocaleDateString('ko-KR') : '미완료';
return `
<tr data-issue-id="${issue.id}" class="cursor-pointer hover:bg-blue-50" onclick="openIssueDetailModal(${issue.id})">
<td class="col-no font-medium">
<span class="inline-flex items-center space-x-1">
<span class="text-lg font-bold bg-gradient-to-r from-green-600 to-green-800 bg-clip-text text-transparent">No.${issue.project_sequence_no || '-'}</span>
<div class="w-1.5 h-1.5 bg-green-500 rounded-full"></div>
</span>
</td>
<td class="col-project">${project ? project.project_name : '-'}</td>
<td class="col-content">${getStatusIcon(issue.final_description || issue.description)}</td>
<td class="col-cause">${getStatusIcon(getCategoryText(issue.final_category || issue.category))}</td>
<td class="col-solution">${getStatusIcon(issue.solution)}</td>
<td class="col-department">${getStatusIcon(issue.responsible_department)}</td>
<td class="col-person">${getStatusIcon(issue.responsible_person)}</td>
<td class="col-date">${getStatusIcon(issue.expected_completion_date)}</td>
<td class="col-confirmer">${getReporterNames(issue)}</td>
<td class="col-department">${getStatusIcon(issue.cause_department)}</td>
<td class="col-comment">${getStatusIcon(issue.management_comment)}</td>
<td class="col-photos">${getPhotoStatusIcon(issue.photo_path, issue.photo_path2)}</td>
<td class="col-completion">${getStatusIcon(issue.completion_photo_path)}</td>
</tr>
<div class="issue-card bg-white border border-gray-200 rounded-xl p-6 mb-4 shadow-sm hover:shadow-md transition-shadow" data-issue-id="${issue.id}">
<!-- 카드 헤더 -->
<div class="flex items-center justify-between mb-4">
<div class="flex flex-col space-y-1">
<div class="flex items-center space-x-3">
<div class="flex items-center space-x-2">
<span class="text-xl font-bold bg-gradient-to-r from-green-600 to-green-800 bg-clip-text text-transparent">No.${issue.project_sequence_no || '-'}</span>
<div class="w-2 h-2 bg-green-500 rounded-full"></div>
</div>
<span class="text-sm text-gray-600">${project ? project.project_name : '프로젝트 미지정'}</span>
<!-- 완료 상태 표시 -->
<div class="flex items-center space-x-2 bg-gradient-to-r from-green-500 to-green-600 text-white px-3 py-1 rounded-full shadow-sm">
<div class="w-1.5 h-1.5 bg-white rounded-full"></div>
<span class="text-xs font-bold">완료됨</span>
<i class="fas fa-check-circle text-xs"></i>
</div>
<span class="text-xs text-gray-500">완료일: ${completedDate}</span>
</div>
<div class="bg-green-50 px-3 py-2 rounded-lg border-l-4 border-green-400">
<h3 class="text-lg font-bold text-green-900">${getIssueTitle(issue)}</h3>
</div>
</div>
<div class="flex space-x-2">
<button onclick="openIssueDetailModal(${issue.id})" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors">
<i class="fas fa-eye mr-1"></i>상세보기
</button>
</div>
</div>
<!-- 카드 본문 -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-4">
<!-- 기본 정보 -->
<div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
<h4 class="font-semibold text-gray-800 mb-3 flex items-center">
<i class="fas fa-info-circle text-blue-500 mr-2"></i>
기본 정보
</h4>
<div class="space-y-2 text-sm">
<div class="bg-gray-50 p-2 rounded border-l-4 border-gray-400">
<p class="text-gray-600 italic">${getIssueDetail(issue)}</p>
</div>
<div><span class="font-medium text-gray-700">원인분류:</span> <span class="text-gray-900">${getCategoryText(issue.final_category || issue.category) || '-'}</span></div>
<div><span class="font-medium text-gray-700">확인자:</span> <span class="text-gray-900">${getReporterNames(issue) || '-'}</span></div>
</div>
</div>
<!-- 관리 정보 -->
<div class="bg-blue-50 p-4 rounded-lg border border-blue-200">
<h4 class="font-semibold text-blue-800 mb-3 flex items-center">
<i class="fas fa-cogs text-blue-500 mr-2"></i>
관리 정보
</h4>
<div class="space-y-2 text-sm">
<div><span class="font-medium text-blue-700">해결방안:</span> <span class="text-blue-900">${issue.solution || '-'}</span></div>
<div><span class="font-medium text-blue-700">담당부서:</span> <span class="text-blue-900">${getDepartmentText(issue.responsible_department) || '-'}</span></div>
<div><span class="font-medium text-blue-700">담당자:</span> <span class="text-blue-900">${issue.responsible_person || '-'}</span></div>
<div><span class="font-medium text-blue-700">원인부서:</span> <span class="text-blue-900">${getDepartmentText(issue.cause_department) || '-'}</span></div>
<div><span class="font-medium text-blue-700">관리 코멘트:</span> <span class="text-blue-900">${issue.management_comment || '-'}</span></div>
</div>
</div>
<!-- 완료 정보 -->
<div class="bg-green-50 p-4 rounded-lg border border-green-200">
<h4 class="font-semibold text-green-800 mb-3 flex items-center">
<i class="fas fa-check-circle text-green-500 mr-2"></i>
완료 정보
</h4>
<div class="space-y-3">
<!-- 완료 사진 -->
<div>
<label class="text-xs text-green-600 font-medium">완료 사진</label>
${issue.completion_photo_path ?
(issue.completion_photo_path.toLowerCase().endsWith('.heic') ?
`<div class="mt-1 flex items-center space-x-2">
<div class="w-16 h-16 bg-green-100 rounded-lg flex items-center justify-center border border-green-200">
<i class="fas fa-image text-green-500"></i>
</div>
<a href="${issue.completion_photo_path}" download class="text-xs text-blue-500 hover:text-blue-700 underline">HEIC 다운로드</a>
</div>` :
`<div class="mt-1">
<img src="${issue.completion_photo_path}" class="w-16 h-16 object-cover rounded-lg cursor-pointer border-2 border-green-200 hover:border-green-400 transition-colors" onclick="openPhotoModal('${issue.completion_photo_path}')" alt="완료 사진">
</div>`
) :
'<p class="text-xs text-gray-500 mt-1">완료 사진 없음</p>'
}
</div>
<!-- 완료 코멘트 -->
<div>
<label class="text-xs text-green-600 font-medium">완료 코멘트</label>
<p class="text-xs text-green-800 mt-1 p-2 bg-white rounded border">${issue.completion_comment || '코멘트 없음'}</p>
</div>
<!-- 완료 신청일 -->
${issue.completion_requested_at ? `
<div>
<label class="text-xs text-green-600 font-medium">완료 신청일</label>
<p class="text-xs text-green-800 mt-1">${new Date(issue.completion_requested_at).toLocaleString('ko-KR')}</p>
</div>
` : ''}
</div>
</div>
</div>
<!-- 하단 사진 영역 -->
<div class="mt-4 pt-4 border-t border-gray-200">
<h4 class="font-semibold text-gray-800 mb-2 flex items-center">
<i class="fas fa-camera text-gray-500 mr-2"></i>
업로드 사진
</h4>
<div class="flex gap-2">
${issue.photo_path ? `<img src="${issue.photo_path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${issue.photo_path}')" alt="업로드 사진 1">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>'}
${issue.photo_path2 ? `<img src="${issue.photo_path2}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${issue.photo_path2}')" alt="업로드 사진 2">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>'}
</div>
</div>
</div>
`;
}
@@ -988,51 +1069,10 @@
}
}
// 테이블 헤더 생성 함수
// 테이블 헤더 생성 함수 (더 이상 사용하지 않음 - 모든 탭이 카드 형식으로 변경됨)
function createTableHeader() {
if (currentTab === 'in_progress') {
// 진행 중 탭 헤더
return `
<th class="col-no">
<span class="inline-flex items-center space-x-1">
<span class="font-bold bg-gradient-to-r from-blue-600 to-blue-800 bg-clip-text text-transparent">No.</span>
<div class="w-1.5 h-1.5 bg-blue-500 rounded-full"></div>
</span>
</th>
<th class="col-project">프로젝트</th>
<th class="col-content">내용</th>
<th class="col-cause">원인</th>
<th class="col-solution">해결방안</th>
<th class="col-department">담당부서</th>
<th class="col-person">담당자</th>
<th class="col-date">조치예상일</th>
<th class="col-completion">완료 확인</th>
<th class="col-photos">업로드 사진</th>
<th class="col-actions">작업</th>
`;
} else {
// 완료됨 탭 헤더
return `
<th class="col-no">
<span class="inline-flex items-center space-x-1">
<span class="font-bold bg-gradient-to-r from-green-600 to-green-800 bg-clip-text text-transparent">No.</span>
<div class="w-1.5 h-1.5 bg-green-500 rounded-full"></div>
</span>
</th>
<th class="col-project">프로젝트</th>
<th class="col-content">내용</th>
<th class="col-cause">원인</th>
<th class="col-solution">해결방안</th>
<th class="col-department">담당부서</th>
<th class="col-person">담당자</th>
<th class="col-date">조치예상일</th>
<th class="col-confirmer">확인자</th>
<th class="col-department">원인부서</th>
<th class="col-comment">의견</th>
<th class="col-photos">업로드 사진</th>
<th class="col-completion">완료 사진</th>
`;
}
// 레거시 함수 - 더 이상 사용되지 않음
return '';
}
// 편집 가능한 필드 생성 함수
@@ -1076,6 +1116,18 @@
];
}
// 부서 코드를 한글로 변환
function getDepartmentText(departmentCode) {
const departments = {
'production': '생산',
'quality': '품질',
'purchasing': '구매',
'design': '설계',
'sales': '영업'
};
return departments[departmentCode] || departmentCode;
}
// 날짜 그룹 토글 함수
function toggleDateGroup(groupId) {
const content = document.getElementById(groupId);