Files
M-Project/frontend/debug-data.html
hyungi b024a178d0 feat: 목록 관리 및 보고서 페이지 개선
- 목록 관리 페이지에 고급 필터링 시스템 추가
  - 프로젝트별, 검토상태별, 날짜별 필터링
  - 검토 완료/필요 항목 시각적 구분 및 정렬
  - 해결 시간 입력 + 확인 버튼으로 검토 완료 처리

- 부적합 조회 페이지에 동일한 필터링 기능 적용
  - 검토 상태에 따른 카드 스타일링 (음영 처리)
  - JavaScript 템플릿 리터럴 오류 수정

- 보고서 페이지 프로젝트별 분석 기능 추가
  - 프로젝트 선택 드롭다운 추가
  - 총 작업 공수를 프로젝트별 일일공수 데이터로 계산
  - 부적합 처리 시간, 카테고리 분석, 상세 목록 모두 프로젝트별 필터링
  - localStorage 키 이름 통일 (daily-work-data)
2025-10-24 10:13:32 +09:00

159 lines
8.9 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>데이터 디버그 - M Project</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="/static/js/api.js?v=20250917"></script>
</head>
<body class="bg-gray-50">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<div class="bg-white rounded-xl shadow-sm p-6">
<h1 class="text-2xl font-bold text-gray-800 mb-6">
<i class="fas fa-bug text-red-500 mr-2"></i>데이터 디버그
</h1>
<div class="space-y-6">
<button
onclick="debugData()"
class="w-full bg-blue-500 text-white py-3 px-4 rounded-lg hover:bg-blue-600 transition-colors font-medium"
>
<i class="fas fa-search mr-2"></i>데이터 상태 확인
</button>
<div id="results" class="space-y-4">
<!-- 결과가 여기에 표시됩니다 -->
</div>
</div>
</div>
</div>
<script>
async function debugData() {
const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = '<div class="text-center py-4"><i class="fas fa-spinner fa-spin text-2xl"></i></div>';
try {
// 1. 프로젝트 데이터 확인
const projects = JSON.parse(localStorage.getItem('work-report-projects') || '[]');
// 2. 부적합 사항 데이터 확인 (API)
let apiIssues = [];
try {
apiIssues = await IssuesAPI.getAll();
} catch (error) {
console.error('API 조회 실패:', error);
}
// 3. 부적합 사항 데이터 확인 (localStorage)
const localIssues = JSON.parse(localStorage.getItem('work-report-issues') || '[]');
// 4. 일일 공수 데이터 확인
const dailyWork = JSON.parse(localStorage.getItem('daily-work-data') || '[]');
// 결과 표시
resultsDiv.innerHTML = `
<div class="space-y-6">
<!-- 프로젝트 데이터 -->
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="font-bold text-blue-800 mb-3">📁 프로젝트 데이터 (${projects.length}개)</h3>
<div class="space-y-2">
${projects.map(p => `
<div class="bg-white p-3 rounded border">
<div class="font-medium">ID: ${p.id}</div>
<div>Job No: ${p.jobNo}</div>
<div>이름: ${p.projectName}</div>
<div>활성: ${p.isActive ? '✅' : '❌'}</div>
</div>
`).join('')}
</div>
</div>
<!-- API 부적합 사항 -->
<div class="bg-green-50 p-4 rounded-lg">
<h3 class="font-bold text-green-800 mb-3">🔗 API 부적합 사항 (${apiIssues.length}개)</h3>
<div class="space-y-2 max-h-60 overflow-y-auto">
${apiIssues.map(issue => `
<div class="bg-white p-3 rounded border text-sm">
<div><strong>ID:</strong> ${issue.id}</div>
<div><strong>project_id:</strong> ${issue.project_id || 'null'}</div>
<div><strong>project_name:</strong> ${issue.project_name || 'null'}</div>
<div><strong>설명:</strong> ${issue.description?.substring(0, 50)}...</div>
<div><strong>카테고리:</strong> ${issue.category}</div>
</div>
`).join('')}
</div>
</div>
<!-- localStorage 부적합 사항 -->
<div class="bg-yellow-50 p-4 rounded-lg">
<h3 class="font-bold text-yellow-800 mb-3">💾 localStorage 부적합 사항 (${localIssues.length}개)</h3>
<div class="space-y-2 max-h-60 overflow-y-auto">
${localIssues.map(issue => `
<div class="bg-white p-3 rounded border text-sm">
<div><strong>ID:</strong> ${issue.id}</div>
<div><strong>project_id:</strong> ${issue.project_id || 'null'}</div>
<div><strong>projectId:</strong> ${issue.projectId || 'null'}</div>
<div><strong>project_name:</strong> ${issue.project_name || 'null'}</div>
<div><strong>projectName:</strong> ${issue.projectName || 'null'}</div>
<div><strong>설명:</strong> ${issue.description?.substring(0, 50)}...</div>
</div>
`).join('')}
</div>
</div>
<!-- 일일 공수 데이터 -->
<div class="bg-purple-50 p-4 rounded-lg">
<h3 class="font-bold text-purple-800 mb-3">⏰ 일일 공수 데이터 (${dailyWork.length}개)</h3>
<div class="space-y-2 max-h-60 overflow-y-auto">
${dailyWork.map(day => `
<div class="bg-white p-3 rounded border text-sm">
<div><strong>날짜:</strong> ${day.date}</div>
<div><strong>총 시간:</strong> ${day.totalHours}시간</div>
<div><strong>프로젝트들:</strong></div>
${day.projects?.map(p => `
<div class="ml-4 text-xs">
- ID: ${p.projectId}, 이름: ${p.projectName}, 시간: ${p.hours}
</div>
`).join('') || '<div class="ml-4 text-xs text-red-500">프로젝트 데이터 없음</div>'}
</div>
`).join('')}
</div>
</div>
<!-- 필터링 테스트 -->
<div class="bg-red-50 p-4 rounded-lg">
<h3 class="font-bold text-red-800 mb-3">🔍 필터링 테스트</h3>
<div class="space-y-2">
${projects.map(project => {
const matchingApiIssues = apiIssues.filter(issue => issue.project_id == project.id);
const matchingLocalIssues = localIssues.filter(issue => issue.project_id == project.id || issue.projectId == project.id);
return `
<div class="bg-white p-3 rounded border">
<div class="font-medium">${project.jobNo} - ${project.projectName} (ID: ${project.id})</div>
<div class="text-sm">API 매칭: ${matchingApiIssues.length}개</div>
<div class="text-sm">localStorage 매칭: ${matchingLocalIssues.length}개</div>
</div>
`;
}).join('')}
</div>
</div>
</div>
`;
} catch (error) {
resultsDiv.innerHTML = `
<div class="bg-red-50 p-4 rounded-lg">
<h3 class="font-bold text-red-800 mb-3">❌ 오류 발생</h3>
<pre class="text-sm">${error.message}</pre>
</div>
`;
}
}
</script>
</body>
</html>