feat: 수신함 UI 간소화 및 용어 개선 - 프로젝트 필터만 유지
🎯 UI Simplification: - 필터링 간소화: 4개 필터 → 1개 (프로젝트만) - 레이아웃 최적화: grid-cols-4 → max-w-md - 불필요한 상태/읽음상태/검색 필터 제거 📝 Terminology Improvements: - '부적합 목록' → '신고 목록' - '새로 등록된 부적합 사항' → '새로 등록된 신고 사항' - '새로운 부적합이 등록되면' → '새로운 신고가 등록되면' - 함수 주석: '부적합 필터링/정렬' → '신고 필터링/정렬' ⚡ Code Optimization: - filterIssues() 함수 간소화 - 불필요한 DOM 요소 및 이벤트 핸들러 제거 - 프로젝트 필드명 수정: project.name → project.project_name 🎨 Enhanced UX: - 깔끔하고 직관적인 필터 인터페이스 - 사용자 친화적인 용어 사용 - 집중도 높은 단순한 레이아웃 🔧 Fixed Issues: - 프로젝트 정보 표시 오류 해결 (필드명 불일치) - 관리함/폐기함 페이지도 동일 오류 수정 - 프로젝트 로딩 디버깅 로그 추가 Expected Result: ✨ 간결하고 사용하기 쉬운 수신함 인터페이스 ✨ 올바른 프로젝트 정보 표시 ✨ 일관성 있는 용어 사용으로 사용자 혼란 방지
This commit is contained in:
@@ -134,7 +134,7 @@
|
||||
<i class="fas fa-inbox text-blue-500 mr-3"></i>
|
||||
수신함
|
||||
</h1>
|
||||
<p class="text-gray-600 mt-1">새로 등록된 부적합 사항을 확인하고 처리하세요</p>
|
||||
<p class="text-gray-600 mt-1">새로 등록된 신고 사항을 확인하고 처리하세요</p>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<button onclick="markAllAsRead()" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors">
|
||||
@@ -189,9 +189,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 필터 및 검색 -->
|
||||
<!-- 필터 -->
|
||||
<div class="bg-white rounded-xl shadow-sm p-6 mb-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<div class="max-w-md">
|
||||
<!-- 프로젝트 필터 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">📁 프로젝트</label>
|
||||
@@ -199,43 +199,14 @@
|
||||
<option value="">전체 프로젝트</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 상태 필터 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">📋 상태</label>
|
||||
<select id="statusFilter" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" onchange="filterIssues()">
|
||||
<option value="">전체 상태</option>
|
||||
<option value="new">새 부적합</option>
|
||||
<option value="processing">처리 중</option>
|
||||
<option value="pending">대기 중</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 읽음 상태 필터 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">👁️ 읽음 상태</label>
|
||||
<select id="readStatusFilter" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" onchange="filterIssues()">
|
||||
<option value="">전체</option>
|
||||
<option value="unread">읽지 않음</option>
|
||||
<option value="read">읽음</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 검색 -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">🔍 검색</label>
|
||||
<input type="text" id="searchInput" placeholder="설명 또는 등록자 검색..."
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
onkeyup="filterIssues()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 부적합 목록 -->
|
||||
<!-- 신고 목록 -->
|
||||
<div class="bg-white rounded-xl shadow-sm">
|
||||
<div class="p-6 border-b border-gray-200">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-lg font-semibold text-gray-800">부적합 목록</h2>
|
||||
<h2 class="text-lg font-semibold text-gray-800">신고 목록</h2>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-sm text-gray-500">정렬:</span>
|
||||
<select id="sortOrder" class="text-sm border border-gray-300 rounded px-2 py-1" onchange="sortIssues()">
|
||||
@@ -256,7 +227,7 @@
|
||||
<div id="emptyState" class="hidden p-12 text-center">
|
||||
<i class="fas fa-inbox text-6xl text-gray-300 mb-4"></i>
|
||||
<h3 class="text-lg font-medium text-gray-900 mb-2">수신함이 비어있습니다</h3>
|
||||
<p class="text-gray-500">새로운 부적합이 등록되면 여기에 표시됩니다.</p>
|
||||
<p class="text-gray-500">새로운 신고가 등록되면 여기에 표시됩니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
@@ -550,6 +521,7 @@
|
||||
|
||||
// 프로젝트 로드
|
||||
async function loadProjects() {
|
||||
console.log('🔄 프로젝트 로드 시작');
|
||||
try {
|
||||
const response = await fetch('/api/projects/', {
|
||||
headers: {
|
||||
@@ -558,12 +530,18 @@
|
||||
}
|
||||
});
|
||||
|
||||
console.log('📡 프로젝트 API 응답 상태:', response.status);
|
||||
|
||||
if (response.ok) {
|
||||
projects = await response.json();
|
||||
console.log('✅ 프로젝트 로드 성공:', projects.length, '개');
|
||||
console.log('📋 프로젝트 목록:', projects);
|
||||
updateProjectFilter();
|
||||
} else {
|
||||
console.error('❌ 프로젝트 API 응답 실패:', response.status, response.statusText);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('프로젝트 로드 실패:', error);
|
||||
console.error('❌ 프로젝트 로드 실패:', error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,7 +553,7 @@
|
||||
projects.forEach(project => {
|
||||
const option = document.createElement('option');
|
||||
option.value = project.id;
|
||||
option.textContent = project.name;
|
||||
option.textContent = project.project_name;
|
||||
projectFilter.appendChild(option);
|
||||
});
|
||||
}
|
||||
@@ -621,30 +599,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 부적합 필터링
|
||||
// 신고 필터링
|
||||
function filterIssues() {
|
||||
const projectFilter = document.getElementById('projectFilter').value;
|
||||
const statusFilter = document.getElementById('statusFilter').value;
|
||||
const readStatusFilter = document.getElementById('readStatusFilter').value;
|
||||
const searchInput = document.getElementById('searchInput').value.toLowerCase();
|
||||
|
||||
filteredIssues = issues.filter(issue => {
|
||||
// 프로젝트 필터
|
||||
if (projectFilter && issue.project_id != projectFilter) return false;
|
||||
|
||||
// 상태 필터
|
||||
if (statusFilter && issue.status !== statusFilter) return false;
|
||||
|
||||
// 읽음 상태 필터
|
||||
if (readStatusFilter === 'read' && !readStatus.has(issue.id)) return false;
|
||||
if (readStatusFilter === 'unread' && readStatus.has(issue.id)) return false;
|
||||
|
||||
// 검색 필터
|
||||
if (searchInput) {
|
||||
const searchText = `${issue.description} ${issue.reporter?.username || ''}`.toLowerCase();
|
||||
if (!searchText.includes(searchInput)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -652,7 +614,7 @@
|
||||
displayIssues();
|
||||
}
|
||||
|
||||
// 부적합 정렬
|
||||
// 신고 정렬
|
||||
function sortIssues() {
|
||||
const sortOrder = document.getElementById('sortOrder').value;
|
||||
|
||||
@@ -702,7 +664,7 @@
|
||||
<div class="flex items-center space-x-3 mb-2">
|
||||
${isUnread ? '<div class="w-2 h-2 bg-blue-500 rounded-full"></div>' : '<div class="w-2 h-2"></div>'}
|
||||
<span class="badge badge-new">검토 대기</span>
|
||||
${project ? `<span class="text-sm text-gray-500">${project.name}</span>` : ''}
|
||||
${project ? `<span class="text-sm text-gray-500">${project.project_name}</span>` : ''}
|
||||
<span class="text-sm text-gray-400">${timeAgo}</span>
|
||||
</div>
|
||||
|
||||
@@ -878,7 +840,7 @@
|
||||
const project = projects.find(p => p.id === issue.project_id);
|
||||
originalInfo.innerHTML = `
|
||||
<div class="space-y-2">
|
||||
<div><strong>프로젝트:</strong> ${project ? project.name : '미지정'}</div>
|
||||
<div><strong>프로젝트:</strong> ${project ? project.project_name : '미지정'}</div>
|
||||
<div><strong>카테고리:</strong> ${getCategoryText(issue.category)}</div>
|
||||
<div><strong>설명:</strong> ${issue.description}</div>
|
||||
<div><strong>등록자:</strong> ${issue.reporter?.username || '알 수 없음'}</div>
|
||||
@@ -892,7 +854,7 @@
|
||||
projects.forEach(project => {
|
||||
const option = document.createElement('option');
|
||||
option.value = project.id;
|
||||
option.textContent = project.name;
|
||||
option.textContent = project.project_name;
|
||||
if (project.id === issue.project_id) {
|
||||
option.selected = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user