feat: 체크리스트 이미지 미리보기 기능 구현

- 체크리스트 섹션에 이미지 썸네일 미리보기 추가 (16x16)
- 대시보드 상단 체크리스트 카드에 이미지 미리보기 기능 추가
- 이미지 클릭 시 전체 화면 모달로 확대 보기
- 백엔드 image_url 컬럼을 TEXT 타입으로 변경하여 Base64 이미지 지원
- 파일 업로드를 이미지만 지원하도록 단순화 (file_url, file_name 제거)
- 422 validation 오류 해결 및 상세 로깅 추가
- 체크리스트 렌더링 누락 문제 해결
This commit is contained in:
hyungi
2025-09-23 07:49:54 +09:00
parent 5c9ea92fb8
commit f80995c1ec
22 changed files with 2635 additions and 930 deletions

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>분류 센터 - Todo Project</title>
<title>INDEX - Todo 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">
<style>
@@ -172,7 +172,7 @@
<i class="fas fa-arrow-left text-xl"></i>
</button>
<i class="fas fa-inbox text-2xl text-purple-500 mr-3"></i>
<h1 class="text-xl font-semibold text-gray-800">분류 센터</h1>
<h1 class="text-xl font-semibold text-gray-800">INDEX</h1>
<span class="ml-3 px-2 py-1 bg-red-100 text-red-800 text-sm rounded-full" id="pendingCount">0</span>
</div>
@@ -288,7 +288,8 @@
</div>
<!-- JavaScript -->
<script src="static/js/auth.js"></script>
<script src="static/js/api.js?v=2"></script>
<script src="static/js/auth.js?v=2"></script>
<script>
let pendingItems = [];
let selectedItems = [];
@@ -303,53 +304,9 @@
// 분류 대기 항목 로드
function loadPendingItems() {
// 임시 데이터
pendingItems = [
{
id: 1,
type: 'upload',
content: '회의실 화이트보드 사진',
photo: '/static/images/sample1.jpg',
created_at: '2024-01-20T10:30:00Z',
source: '직접 업로드',
suggested: 'todo',
confidence: 0.85,
tags: ['업무', '회의', '계획']
},
{
id: 2,
type: 'mail',
content: '긴급: 내일까지 월말 보고서 제출 요청',
sender: 'manager@company.com',
created_at: '2024-01-20T14:15:00Z',
source: '시놀로지 메일플러스',
suggested: 'calendar',
confidence: 0.95,
tags: ['긴급', '업무', '마감']
},
{
id: 3,
type: 'upload',
content: '마트에서 살 것들 메모',
photo: '/static/images/sample2.jpg',
created_at: '2024-01-20T16:45:00Z',
source: '직접 업로드',
suggested: 'checklist',
confidence: 0.90,
tags: ['개인', '쇼핑', '생활']
},
{
id: 4,
type: 'mail',
content: '프로젝트 킥오프 미팅 일정 조율',
sender: 'team@company.com',
created_at: '2024-01-20T09:20:00Z',
source: '시놀로지 메일플러스',
suggested: 'todo',
confidence: 0.75,
tags: ['업무', '미팅', '프로젝트']
}
];
// 분류되지 않은 항목들을 API에서 가져와야 함
// 현재는 빈 배열로 설정 (분류 기능 미구현)
pendingItems = [];
renderItems();
}
@@ -435,7 +392,7 @@
</span>
<span class="ml-2 text-xs text-purple-600">(${Math.round(item.confidence * 100)}% 확신)</span>
</div>
<button onclick="acceptSuggestion(${item.id}, '${item.suggested}')"
<button onclick="acceptSuggestion('${item.id}', '${item.suggested}')"
class="text-xs bg-purple-600 text-white px-3 py-1 rounded-full hover:bg-purple-700">
적용
</button>
@@ -447,15 +404,15 @@
<!-- 분류 버튼들 -->
<div class="mt-6 flex flex-wrap gap-3 justify-center">
<button onclick="classifyItem(${item.id}, 'todo')" class="classify-btn todo">
<button onclick="classifyItem('${item.id}', 'todo')" class="classify-btn todo">
<i class="fas fa-calendar-day mr-2"></i>Todo
<div class="text-xs opacity-75">시작 날짜</div>
</button>
<button onclick="classifyItem(${item.id}, 'calendar')" class="classify-btn calendar">
<button onclick="classifyItem('${item.id}', 'calendar')" class="classify-btn calendar">
<i class="fas fa-calendar-times mr-2"></i>캘린더
<div class="text-xs opacity-75">마감 기한</div>
</button>
<button onclick="classifyItem(${item.id}, 'checklist')" class="classify-btn checklist">
<button onclick="classifyItem('${item.id}', 'checklist')" class="classify-btn checklist">
<i class="fas fa-check-square mr-2"></i>체크리스트
<div class="text-xs opacity-75">기한 없음</div>
</button>
@@ -596,7 +553,10 @@
}
function formatDate(dateString) {
if (!dateString) return '날짜 없음';
const date = new Date(dateString);
if (isNaN(date.getTime())) return '날짜 없음';
const now = new Date();
const diffTime = now - date;
const diffHours = Math.floor(diffTime / (1000 * 60 * 60));